Compare commits

...
41 Commits
Author SHA1 Message Date
Earle F. Philhower, III 40855c90fb Update version 2022-11-03 08:54:31 -07:00
Earle F. Philhower, III 6570c4856b Fix deadlock in attachInterruptParam (#953)
Thanks to @imwoo90 comment in https://github.com/earlephilhower/arduino-pico/issues/878#issuecomment-1302276196
2022-11-03 08:40:57 -07:00
风飘雨 008c4d62ef Fix SerialPIO bit length, update flyboard2040 pins (#950) 2022-11-03 08:35:40 -07:00
Earle F. Philhower, III 63dfd9ab6b Properly disable Ethernet IRQ, don't drop packets (#951)
Fix #944
2022-11-02 15:27:02 -07:00
Earle F. Philhower, III 9b28fc3e17 Free PIO SM on SerialPIO::end (#949)
Fixes #945
2022-10-31 17:10:59 -07:00
Drzony 6bbaf64daf Async scan + bugfixes (#947)
* Support asynchronous WiFi scan

* Fixed buffer overflow in getChipId

* ESP compatibility fixes

* fixup! ESP compatibility fixes
2022-10-31 17:01:10 -07:00
AngeloGioacchino Del Regno 44eeebbc6f cores/rp2040: _freertos.cpp: Avoid memory leak and unnecessary allocation (#948)
There's a memory leak around the corner: creating the mutex means
that we allocate memory for it, but if we cannot find any free slot in the
FMMap array, we're simply returning a nullptr without ever freeing the
previously allocated memory.

Instead of allocating it out of the free-slot check, do it inside.
While at it, also check if the mutex creation succeeded before assigning
it to a FMMap slot.
2022-10-31 14:29:00 -07:00
Earle F. Philhower, III ec7631096b Update GH actions to non-deprecated versions (#938) 2022-10-27 14:35:52 -07:00
Earle F. Philhower, III 07a1484d72 Add WiFi.channel() reporting (#937)
Also return error conditions when WiFi status is inquired while not
connected.
2022-10-27 13:02:09 -07:00
Earle F. Philhower, III 9503620525 Add WiFi.BSSID() undocumented call (#936)
Using same method as #934 and Infineon wifi-host-driver sources
2022-10-27 09:09:48 -07:00
mecparts e05a3b8ad0 Add a way to return the RSSI value (#934)
See https://forums.raspberrypi.com/viewtopic.php?t=341774
2022-10-27 08:00:59 -07:00
Earle F. Philhower, III 9d0b9bef67 Update version 2022-10-25 08:02:54 -07:00
per1234 0446b732fa Add protocol-explicit upload.tool properties required for pluggable discovery compatibility (#933)
A new flexible and powerful "pluggable discovery" system was added to the Arduino boards platform framework. This system
makes it easy for Arduino boards platform authors to use any arbitrary communication channel between the board and
development tools.

Boards platform configurations that use the old property syntax are automatically translated to the new syntax by
Arduino CLI:

https://arduino.github.io/arduino-cli/latest/platform-specification/#sketch-upload-configuration

> For backward compatibility with IDE 1.8.15 and older the previous syntax is still supported

This translation is only done in platforms that use the old syntax exclusively. If `pluggable_discovery` properties are
defined for the platform then the new pluggable discovery-style `upload.tool.<protocol_name>` properties must be defined
for each board as well.

This platform includes a "UF2 Devices" discovery tool for `uf2conv` protocol ports. This tool now uses the modern
Arduino pluggable discovery system. `pluggable_discovery` properties were added to `platform.txt` in order to configure
the Arduino development tools to use this pluggable discovery tool. The `upload.tool.<protocol_name>` properties in
`boards.txt` were not updated at that time.

Global properties of that name were added to platform.txt, but this approach is not provided for by the Arduino Platform
specification:

https://arduino.github.io/arduino-cli/latest/platform-specification/#sketch-upload-configuration

> A specific upload.tool.<protocol_name> property should be defined for every board in boards.txt:

Those missing properties caused uploads to fail for users of the recent versions of Arduino IDE and Arduino CLI with an
error of the form:

Error during Upload: Property 'upload.tool.<protocol_name>' is undefined

(where `<protocol_name>` is the protocol of the selected port, if any)

It is also important to provide compatibility with versions of Arduino development tools from before the introduction of
the modern pluggable discovery system. For this reason, the old style `<board ID>.upload.tool` properties are retained.
Old versions of the development tools will treat the `<board ID>.upload.tool.<protocol_name>` properties as an unused
arbitrary user defined property with no special significance and the new versions of the development tools will do the
same for the `upload.tool` properties.
2022-10-24 08:50:13 -07:00
Earle F. Philhower, III c3da4ada61 Add basic Pimoroni PGA2040 board definition (#930)
Because the board needs a unique BOOT2.S, add a definition to make it
easier to use.
2022-10-22 10:19:30 -07:00
Earle F. Philhower, III 4fdcc6e5ac Only init PWM on requested pin (#926)
Avoid glitches on other pins, fix #919
2022-10-20 04:56:44 -07:00
Maximilian Gerhardt b82336c8d9 Add W25Q64JV QSPI /4 Boot2 file (#929)
Fixes #927
2022-10-20 04:25:37 -07:00
Earle F. Philhower, III 075958883f Update version 2022-10-16 10:50:29 -07:00
Fredrik Jansson fe632cde4b Increase analogWrite frequency range, bugfixes (#918)
* analogWrite: fix overflow and wrap value (#917)

-avoid overflow when calculating analogScale * analogFreq, perform
the multiplication in floating point.

-use analogScale - 1 to set the PWM wrap value. Wrap is the highest
value the counter reaches, not the counter period.

* analogWrite: increase frequency range (#917)

- increase frequency range to 10 MHz

- decrease the lowest allowed resolution to 2 bits, and the
  minimal analogRange value to 3. This makes 10 MHz output possible
  with system clock frequencies down to 50 MHz.

- allow clkdiv values >= 1.0, was 2.0. This makes it possible to
  manually set frequency and analogRange so that
  frequency * analogRange = system clock frequency.
  This gives the best possible frequency accuracy and
  resolution.
2022-10-16 10:43:49 -07:00
Earle F. Philhower, III 10090b60a9 Rewrite PicoW LWIP interface for stability (#916)
Random crashes, infinite loops, and other lockups were happening to the PicoW
while under high load from multiple clients.

This seems to have been due to two issues:

* The periodic sys_check_timeouts() call from an alarm/IRQ was happening while
  the core was in LWIP code. LWIP is not re-entrant or multi-core/thread safe
  so this is a bad thing. Some calls may not have been locked with a manual
  addition of the LWIPMutex object to hit this.
* The WiFi driver supplies packet data during an interrupt. PBUF work is
  legal in an interrupt, but actually calling netif->input() from an IRQ to
  queue up the Ethernet packet for processing is illegal if LWIP is already
  in progress.
   
Rearchitect the LWIP interface to fix these problems:
* Disable interrupts during malloc/etc. to avoid the possibility of the
  periodic LWIP timeout check interrupting and potentially calling user
  code which did a memory operation
* Wrap all used LWIP calls to note LWIP code will be executing, instead of
  manually eyeballing and adding in protection in user code.
* Remove all user code LWIPMutex blocking, the wrapping takes care of it.
* When an Ethernet packet is received by interrupt and we're in LWIP code,
  just throw the packet away for now. The upper layers can handle retransmit.
  (A possible optimization would be to set the packet aside and add a
  housekeeping portion to the LWIP wrappers to netif->input() them when safe).
* Ignore callbacks during TCP connection teardown when the ClientContext
  passed from LWIP == nullptr
2022-10-15 12:00:35 -07:00
Earle F. Philhower, III a6bdb27178 Use static allocation for IRQ stack (#915)
noInterrupts/interrupts use a stack to allow multiple calls to work
properly.  The original code was using a std::stack which will use
malloc() to allocate entry space.  This seems like a bad idea, and
makes it so it's impossible to disable interrupts for malloc/free,
etc.

Define a fixed stack size and use straight C code to manage the IRQ
stacks.  Slightly more fixed memory requirements, but significantly
lower total RAM requirements and no malloc() dependency.
2022-10-14 13:46:00 -07:00
brtchip-tuannguyen 62ed93f12a Add board BridgeTek IDM2040-7A (#912) 2022-10-13 08:26:11 -07:00
Earle F. Philhower, III e89ce78c79 Fix memory leak in WebServer (#914)
Fixes #908
2022-10-12 11:25:56 -07:00
Earle F. Philhower, III 98c4b921b8 Un-hardcode LED pin in AdvancedWebServer example (#909)
Partial #908
2022-10-11 09:30:41 -07:00
Sabas 86765cebb2 Update VID&PID HunterCatNFC 2040 (#907) 2022-10-11 09:12:56 -07:00
Earle F. Philhower, III 25ceb08f93 Clear LWIP started flag on LWIPIntfDev::end (#905)
When moving between different modes or even WiFi.begin/ends, any setting
of the IPs will fail because the internal flag _started was not cleared.
Clear _started on a ::end call.

Fixes #884
2022-10-09 18:25:24 -07:00
Mücahid Kamber 205983e206 Adds Degz Mizu board (#904) 2022-10-07 15:52:18 -07:00
Earle F. Philhower, III 1e7098c1cb Add OpenOCD/GDB support for IDE 2.0 (#900)
Add (undocumented) support for the debugger in the IDE 2.0.
2022-10-05 12:19:18 -07:00
Earle F. Philhower, III 68ecdfc023 Update README.md 2022-10-05 07:15:50 -07:00
Melopero a9356ceca5 Add Melopero Cookie RP2040 (#899) 2022-10-05 07:10:07 -07:00
Earle F. Philhower, III 69ab736cf8 Update version 2022-10-04 17:14:52 -07:00
Earle F. Philhower, III 3e758dcebb Add TARGET_RP2040 to build defines (#898)
Fixes #896 since it seems the Arduino.cc core defines this constant
2022-10-04 17:04:25 -07:00
Earle F. Philhower, III b249811e28 Support IDE2, detect UF2 volumes (#897)
Allow the IDE to detect UF2 volumes (i.e. when you hold BOOTDEL and
plug in the board).

Allows the IDE2 to properly upload using OTA and serial.

Fixes #890 and others
2022-10-04 16:52:36 -07:00
Earle F. Philhower, III 7f216f35ab Allow double-reset to jump to USB bootloader (#893)
Call `rp2040.enableDoubleResetBootloader()` anywhere in the code to
enable the check.  W/o that call, the checker will be linked in.

See #892

CORE1 doesn't start until well after the C runtime initialization,
so the flag won't be overwritten.

Also increase timeout to 350ms because OTA bootup can be
slow.
2022-10-04 14:04:40 -07:00
Earle F. Philhower, III 029471ecca Drive pin LOW after Tone(period) timeout (#887)
Fixes #886
2022-09-29 13:03:49 -07:00
Earle F. Philhower, III 4cc6c36c37 Fix Serial1/2 debug output mode in CoreMutex (#883)
Fixes #882
2022-09-26 14:19:00 -07:00
Earle F. Philhower, III 0cd5b0ac47 Allow setCTS/RTS(UART_PIN_NOT_DEFINED) (#881)
Fixes #880
2022-09-26 08:13:44 -07:00
Earle F. Philhower, III 939c83127e Fix deadlock during attachInterrupt (#879)
Fixes #878
2022-09-25 10:02:48 -07:00
Tim Boldt 3768aa7e1f Fix typo in HttpClient HTTPS example (#876) 2022-09-24 19:23:56 -07:00
Earle F. Philhower, III 7a85c3917f Allow setting the WiFi region for PicoW (#875)
Fixes #874
2022-09-23 12:22:22 -07:00
Earle F. Philhower, III cd0e83843f Update version 2022-09-21 19:19:24 -07:00
Earle F. Philhower, III 78ce055165 Ensure ArduinoCore API is included in package (#871) 2022-09-21 19:18:53 -07:00
68 changed files with 4951 additions and 753 deletions
+19 -25
View File
@@ -6,6 +6,10 @@ name: Arduino-Pico CI
on:
pull_request:
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
jobs:
@@ -20,7 +24,7 @@ jobs:
- 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
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
@@ -46,10 +50,6 @@ jobs:
./tests/restyle.sh
# If anything changed, GIT should return an error and fail the test
git diff --exit-code
# - name: Check Arduino API copy is clean
# run: |
# git submodule update --init ./ArduinoCore-API
# diff -r ./cores/rp2040/api ./ArduinoCore-API/api
# Build all examples on linux (core and Arduino IDE)
build-linux:
@@ -62,19 +62,17 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_PARITY: custom
mod: 6
rem: ${{ matrix.chunk }}
@@ -92,19 +90,17 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_PARITY: custom
run: |
cd pico-sdk
@@ -120,19 +116,17 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Cache Windows toolchain
id: cache-windows
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketch
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
WINDOWS: 1
BUILD_PARITY: custom
mod: 500
@@ -150,24 +144,22 @@ jobs:
# Single build under macOS to ensure the Mac toolchain is good.
build-mac:
name: Mac
runs-on: macOS-latest
runs-on: macOS-12
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Cache Mac toolchain
id: cache-mac
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketch
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
MACOSX: 1
BUILD_PARITY: custom
mod: 500
@@ -194,19 +186,21 @@ jobs:
git submodule update --init
cd ../..
- name: Cache pip
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
+4 -4
View File
@@ -9,22 +9,22 @@ jobs:
name: Update master JSON file
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true
- name: Cache pip
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install PlatformIO
+2 -2
View File
@@ -15,11 +15,11 @@ jobs:
name: Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Build package JSON
+4
View File
@@ -20,8 +20,10 @@ See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for m
* Adafruit STEMMA Friend RP2040
* Adafruit Trinkey RP2040 QT
* Arduino Nano RP2040 Connect
* BridgeTek IDM2040-7A
* Cytron Maker Pi RP2040
* Cytron Maker Nano RP2040
* Degz Mizu
* DeRuiLab FlyBoard2040 Core
* DFRobot Beetle RP2040
* ElectronicCats Hunter Cat NFC
@@ -34,7 +36,9 @@ See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for m
* Invector Labs Challenger RP2040 SubGHz
* Invector Labs Challenger RP2040 SD/RTC
* Invector Labs RPICO32
* Melopero Cookie RP2040
* Melopero Shake RP2040
* Pimoroni PGA2040
* Seeed XIAO RP2040
* Solder Party RP2040 Stamp
* SparkFun ProMicro RP2040
+3423 -472
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
// Padded and checksummed version of: boot2_w25q64jv.4.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
+57
View File
@@ -0,0 +1,57 @@
/*
CoreMutex for the Raspberry Pi Pico RP2040
Implements a deadlock-safe multicore mutex for sharing things like the
USB or UARTs.
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Arduino.h"
#include "CoreMutex.h"
CoreMutex::CoreMutex(mutex_t *mutex, bool debugEnable) {
_mutex = mutex;
_acquired = false;
if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(mutex);
__freertos_mutex_take(m);
} else {
uint32_t owner;
if (!mutex_try_enter(_mutex, &owner)) {
if (owner == get_core_num()) { // Deadlock!
if (debugEnable) {
DEBUGCORE("CoreMutex - Deadlock detected!\n");
}
return;
}
mutex_enter_blocking(_mutex);
}
}
_acquired = true;
}
CoreMutex::~CoreMutex() {
if (_acquired) {
if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(_mutex);
__freertos_mutex_give(m);
} else {
mutex_exit(_mutex);
}
}
}
+2 -31
View File
@@ -28,37 +28,8 @@
class CoreMutex {
public:
CoreMutex(mutex_t *mutex, bool debugEnable = true) {
_mutex = mutex;
_acquired = false;
if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(mutex);
__freertos_mutex_take(m);
} else {
uint32_t owner;
if (!mutex_try_enter(_mutex, &owner)) {
if (owner == get_core_num()) { // Deadlock!
if (debugEnable) {
DEBUGCORE("CoreMutex - Deadlock detected!\n");
}
return;
}
mutex_enter_blocking(_mutex);
}
}
_acquired = true;
}
~CoreMutex() {
if (_acquired) {
if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(_mutex);
__freertos_mutex_give(m);
} else {
mutex_exit(_mutex);
}
}
}
CoreMutex(mutex_t *mutex, bool debugEnable = true);
~CoreMutex();
operator bool() {
return _acquired;
@@ -1,10 +1,7 @@
/*
WiFiMutex.h - Ensure the timer-driven sys_check_timeouts doesn't
get executed while we're in the user-level TCP stack.
Copyright (c) 2022 Earle F. Philhower, III. All rights reserved.
RP2040 utility class
Implements the API defined by the Arduino WiFiNINA library,
copyright (c) 2018 Arduino SA. All rights reserved.
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,21 +18,16 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <Arduino.h>
#include <hardware/structs/psm.h>
extern "C" volatile bool __inLWIP;
extern "C" void boot_double_tap_check();
class LWIPMutex {
public:
LWIPMutex() {
__inLWIP = true;
_ref++;
// The following check will never actually execute, but it will cause the boot reset
// checker to be linked in as part of the constructors.
void RP2040::enableDoubleResetBootloader() {
if (psm_hw->done == 0) {
boot_double_tap_check();
}
~LWIPMutex() {
if (0 == --_ref) {
__inLWIP = false;
}
}
private:
static int _ref;
};
}
+3 -1
View File
@@ -314,6 +314,8 @@ public:
reboot();
}
static void enableDoubleResetBootloader();
void wdt_begin(uint32_t delay_ms) {
watchdog_enable(delay_ms, 1);
}
@@ -323,7 +325,7 @@ public:
}
const char *getChipID() {
static char id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = { 0 };
static char id[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = { 0 };
if (!id[0]) {
pico_get_unique_board_id_string(id, sizeof(id));
}
+2 -2
View File
@@ -1,5 +1,5 @@
#pragma once
#define ARDUINO_PICO_MAJOR 2
#define ARDUINO_PICO_MINOR 5
#define ARDUINO_PICO_MINOR 6
#define ARDUINO_PICO_REVISION 3
#define ARDUINO_PICO_VERSION_STR "2.5.3"
#define ARDUINO_PICO_VERSION_STR "2.6.3"
+3 -1
View File
@@ -230,7 +230,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) - 5 /* insns in PIO halfbit loop */);
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 7 /* insns in PIO halfbit loop */);
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
@@ -259,9 +259,11 @@ void SerialPIO::end() {
}
if (_tx != NOPIN) {
pio_sm_set_enabled(_txPIO, _txSM, false);
pio_sm_unclaim(_txPIO, _txSM);
}
if (_rx != NOPIN) {
pio_sm_set_enabled(_rxPIO, _rxSM, false);
pio_sm_unclaim(_rxPIO, _rxSM);
_pioSP[pio_get_index(_rxPIO)][_rxSM] = nullptr;
// If no more active, disable the IRQ
auto pioNum = pio_get_index(_rxPIO);
+2 -2
View File
@@ -69,7 +69,7 @@ bool SerialUART::setRTS(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({3, 15, 19}) /* UART0 */,
__bitset({7, 11, 23, 27}) /* UART1 */
};
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1 << pin) & valid[uart_get_index(_uart)]))) {
_rts = pin;
return true;
}
@@ -86,7 +86,7 @@ bool SerialUART::setCTS(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({2, 14, 18}) /* UART0 */,
__bitset({6, 10, 22, 26}) /* UART1 */
};
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1 << pin) & valid[uart_get_index(_uart)]))) {
_cts = pin;
return true;
}
+13 -3
View File
@@ -28,6 +28,7 @@ typedef struct {
pin_size_t pin;
PIO pio;
int sm;
int off;
alarm_id_t alarm;
} Tone;
@@ -38,10 +39,18 @@ auto_init_mutex(_toneMutex);
static PIOProgram _tone2Pgm(&tone2_program);
static std::map<pin_size_t, Tone *> _toneMap;
static inline bool pio_sm_get_enabled(PIO pio, uint sm) {
check_pio_param(pio);
check_sm_param(sm);
return (pio->ctrl & ~(1u << sm)) & (1 << sm);
}
int64_t _stopTonePIO(alarm_id_t id, void *user_data) {
(void) id;
Tone *tone = (Tone *)user_data;
tone->alarm = 0;
digitalWrite(tone->pin, LOW);
pinMode(tone->pin, OUTPUT);
pio_sm_set_enabled(tone->pio, tone->sm, false);
return 0;
}
@@ -72,14 +81,12 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
newTone = new Tone();
newTone->pin = pin;
pinMode(pin, OUTPUT);
int off;
if (!_tone2Pgm.prepare(&newTone->pio, &newTone->sm, &off)) {
if (!_tone2Pgm.prepare(&newTone->pio, &newTone->sm, &newTone->off)) {
DEBUGCORE("ERROR: tone unable to start, out of PIO resources\n");
// ERROR, no free slots
delete newTone;
return;
}
tone2_program_init(newTone->pio, newTone->sm, off, pin);
newTone->alarm = 0;
} else {
newTone = entry->second;
@@ -88,6 +95,9 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
newTone->alarm = 0;
}
}
if (!pio_sm_get_enabled(newTone->pio, newTone->sm)) {
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_set_enabled(newTone->pio, newTone->sm, true);
+7 -2
View File
@@ -38,10 +38,15 @@ extern "C" SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m) {
return _map[i].dst;
}
}
// Make a new mutex
auto fm = __freertos_mutex_create();
for (int i = 0; i < 16; i++) {
if (_map[i].src == nullptr) {
// Make a new mutex
SemaphoreHandle_t fm = __freertos_mutex_create();
if (fm == nullptr) {
return nullptr;
}
_map[i].src = m;
_map[i].dst = fm;
return fm;
+326
View File
@@ -0,0 +1,326 @@
/*
LWIP wrappers to protect against timer-based re-entrancy
Copyright (c) 202s Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pico/mutex.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
#include "lwip/raw.h"
#include "lwip/timeouts.h"
// Global indicator that we're inside an LWIP block
extern "C" {
volatile bool __inLWIP = false;
}
auto_init_recursive_mutex(__mtxLWIP);
class LWIPMutex {
public:
LWIPMutex() {
noInterrupts();
recursive_mutex_enter_blocking(&__mtxLWIP);
__inLWIP = true;
_ref++;
interrupts();
}
~LWIPMutex() {
noInterrupts();
if (0 == --_ref) {
__inLWIP = false;
}
recursive_mutex_exit(&__mtxLWIP);
interrupts();
}
private:
static int _ref;
};
int LWIPMutex::_ref = 0;
extern "C" {
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;
return __real_pbuf_header(p, header_size);
}
extern u8_t __real_pbuf_free(struct pbuf *p);
u8_t __wrap_pbuf_free(struct pbuf *p) {
LWIPMutex m;
return __real_pbuf_free(p);
}
extern struct pbuf *__real_pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type);
struct pbuf *__wrap_pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type) {
LWIPMutex m;
return __real_pbuf_alloc(l, length, type);
}
extern err_t __real_pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
err_t __wrap_pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) {
LWIPMutex m;
return __real_pbuf_take(buf, dataptr, len);
}
extern u16_t __real_pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
u16_t __wrap_pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset) {
LWIPMutex m;
return __real_pbuf_copy_partial(p, dataptr, len, offset);
}
extern void __real_pbuf_ref(struct pbuf *p);
void __wrap_pbuf_ref(struct pbuf *p) {
LWIPMutex m;
__real_pbuf_ref(p);
}
extern u8_t __real_pbuf_get_at(const struct pbuf* p, u16_t offset);
u8_t __wrap_pbuf_get_at(const struct pbuf* p, u16_t offset) {
LWIPMutex m;
return __real_pbuf_get_at(p, offset);
}
extern void *__real_pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset);
void *__wrap_pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset) {
LWIPMutex m;
return __real_pbuf_get_contiguous(p, buffer, bufsize, len, offset);
}
extern void __real_pbuf_cat(struct pbuf *head, struct pbuf *tail);
void __wrap_pbuf_cat(struct pbuf *head, struct pbuf *tail) {
LWIPMutex m;
__real_pbuf_cat(head, tail);
}
extern void __real_tcp_arg(struct tcp_pcb *pcb, void *arg);
void __wrap_tcp_arg(struct tcp_pcb *pcb, void *arg) {
LWIPMutex m;
__real_tcp_arg(pcb, arg);
}
extern struct tcp_pcb *__real_tcp_new(void);
struct tcp_pcb *__wrap_tcp_new(void) {
LWIPMutex m;
return __real_tcp_new();
}
extern err_t __real_tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port);
err_t __wrap_tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) {
LWIPMutex m;
return __real_tcp_bind(pcb, ipaddr, port);
}
extern struct tcp_pcb *__real_tcp_listen(struct tcp_pcb *pcb);
struct tcp_pcb *__wrap_tcp_listen(struct tcp_pcb *pcb) {
LWIPMutex m;
return __real_tcp_listen(pcb);
}
extern struct tcp_pcb *__real_tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
struct tcp_pcb *__wrap_tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) {
LWIPMutex m;
return __real_tcp_listen_with_backlog(pcb, backlog);
}
extern void __real_tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err));
void __wrap_tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)) {
LWIPMutex m;
__real_tcp_accept(pcb, accept);
}
extern err_t __real_tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err));
err_t __wrap_tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)) {
LWIPMutex m;
return __real_tcp_connect(pcb, ipaddr, port, connected);
}
extern err_t __real_tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, u8_t apiflags);
err_t __wrap_tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, u8_t apiflags) {
LWIPMutex m;
return __real_tcp_write(pcb, dataptr, len, apiflags);
}
extern void __real_tcp_sent(struct tcp_pcb *pcb, err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len));
void __wrap_tcp_sent(struct tcp_pcb *pcb, err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len)) {
LWIPMutex m;
__real_tcp_sent(pcb, sent);
}
extern void __real_tcp_recv(struct tcp_pcb *pcb, err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err));
void __wrap_tcp_recv(struct tcp_pcb *pcb, err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)) {
LWIPMutex m;
__real_tcp_recv(pcb, recv);
}
extern void __real_tcp_recved(struct tcp_pcb *pcb, u16_t len);
void __wrap_tcp_recved(struct tcp_pcb *pcb, u16_t len) {
LWIPMutex m;
__real_tcp_recved(pcb, len);
}
extern void __real_tcp_poll(struct tcp_pcb *pcb, err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval);
void __wrap_tcp_poll(struct tcp_pcb *pcb, err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval) {
LWIPMutex m;
__real_tcp_poll(pcb, poll, interval);
}
extern err_t __real_tcp_close(struct tcp_pcb *pcb);
err_t __wrap_tcp_close(struct tcp_pcb *pcb) {
LWIPMutex m;
return __real_tcp_close(pcb);
}
extern void __real_tcp_abort(struct tcp_pcb *pcb);
void __wrap_tcp_abort(struct tcp_pcb *pcb) {
LWIPMutex m;
__real_tcp_abort(pcb);
}
extern void __real_tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, err_t err));
void __wrap_tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, err_t err)) {
LWIPMutex m;
__real_tcp_err(pcb, err);
}
extern err_t __real_tcp_output(struct tcp_pcb *pcb);
err_t __wrap_tcp_output(struct tcp_pcb *pcb) {
LWIPMutex m;
return __real_tcp_output(pcb);
}
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);
}
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);
}
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);
}
extern struct udp_pcb *__real_udp_new(void);
struct udp_pcb *__wrap_udp_new(void) {
LWIPMutex m;
return __real_udp_new();
}
extern void __real_udp_remove(struct udp_pcb *pcb);
void __wrap_udp_remove(struct udp_pcb *pcb) {
LWIPMutex m;
__real_udp_remove(pcb);
}
extern err_t __real_udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port);
err_t __wrap_udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) {
LWIPMutex m;
return __real_udp_bind(pcb, ipaddr, port);
}
extern err_t __real_udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port);
err_t __wrap_udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) {
LWIPMutex m;
return __real_udp_connect(pcb, ipaddr, port);
}
extern err_t __real_udp_disconnect(struct udp_pcb *pcb);
err_t __wrap_udp_disconnect(struct udp_pcb *pcb) {
LWIPMutex m;
return __real_udp_disconnect(pcb);
}
extern err_t __real_udp_send(struct udp_pcb *pcb, struct pbuf *p);
err_t __wrap_udp_send(struct udp_pcb *pcb, struct pbuf *p) {
LWIPMutex m;
return __real_udp_send(pcb, p);
}
extern void __real_udp_recv(struct udp_pcb *pcb, void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port), void *recv_arg);
void __wrap_udp_recv(struct udp_pcb *pcb, void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port), void *recv_arg) {
LWIPMutex m;
__real_udp_recv(pcb, recv, recv_arg);
}
extern err_t __real_udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif);
err_t __wrap_udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) {
LWIPMutex m;
return __real_udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
}
extern void __real_sys_check_timeouts(void);
void __wrap_sys_check_timeouts(void) {
LWIPMutex m;
__real_sys_check_timeouts();
}
extern err_t __real_dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg);
err_t __wrap_dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg) {
LWIPMutex m;
return __real_dns_gethostbyname(hostname, addr, found, callback_arg);
}
extern err_t __real_dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg, u8_t dns_addrtype);
err_t __wrap_dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg, u8_t dns_addrtype) {
LWIPMutex m;
return __real_dns_gethostbyname_addrtype(hostname, addr, found, callback_arg, dns_addrtype);
}
extern struct raw_pcb *__real_raw_new(u8_t proto);
struct raw_pcb *__wrap_raw_new(u8_t proto) {
LWIPMutex m;
return __real_raw_new(proto);
}
extern void __real_raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg);
void __wrap_raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) {
LWIPMutex m;
__real_raw_recv(pcb, recv, recv_arg);
}
extern err_t __real_raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr);
err_t __wrap_raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr) {
LWIPMutex m;
return __real_raw_bind(pcb, ipaddr);
}
extern err_t __real_raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr);
err_t __wrap_raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr) {
LWIPMutex m;
return __real_raw_sendto(pcb, p, ipaddr);
}
extern void __real_raw_remove(struct raw_pcb *pcb);
void __wrap_raw_remove(struct raw_pcb *pcb) {
LWIPMutex m;
__real_raw_remove(pcb);
}
}; // extern "C"
-3
View File
@@ -22,7 +22,6 @@
#include "RP2040USB.h"
#include <pico/stdlib.h>
#include <pico/multicore.h>
#include "LWIPMutex.h"
#include <reent.h>
RP2040 rp2040;
@@ -33,8 +32,6 @@ extern "C" {
mutex_t _pioMutex;
int LWIPMutex::_ref = 0;
extern void setup();
extern void loop();
+53
View File
@@ -0,0 +1,53 @@
/*
Malloc/etc. interrupt locking wrappers
Copyright (c) 2022 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>
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" void *__wrap_malloc(size_t size) {
noInterrupts();
void *rc = __real_malloc(size);
interrupts();
return rc;
}
extern "C" void *__wrap_calloc(size_t count, size_t size) {
noInterrupts();
void *rc = __real_calloc(count, size);
interrupts();
return rc;
}
extern "C" void *__wrap_realloc(void *mem, size_t size) {
noInterrupts();
void *rc = __real_realloc(mem, size);
interrupts();
return rc;
}
extern "C" void __wrap_free(void *mem) {
noInterrupts();
__real_free(mem);
interrupts();
}
@@ -36,7 +36,7 @@
#define CYW43_WL_GPIO_LED_PIN 0
#endif
volatile bool __inLWIP = false;
extern volatile bool __inLWIP;
// note same code
#if PICO_CYW43_ARCH_THREADSAFE_BACKGROUND
@@ -145,7 +145,7 @@ static void gpio_irq_handler(void) {
static void low_priority_irq_handler(void) {
assert(cyw43_core_num == get_core_num());
if (recursive_mutex_try_enter(&cyw43_mutex, NULL)) {
if (recursive_mutex_enter_count(&cyw43_mutex) != 1) {
if (__inLWIP || (recursive_mutex_enter_count(&cyw43_mutex) != 1)) {
low_priority_irq_missed = true;
CYW43_STAT_INC(PENDSV_DISABLED_COUNT);
} else {
@@ -0,0 +1,90 @@
/*
Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
Hacked by EFP3 to allow disabling unless requested
SPDX-License-Identifier: BSD-3-Clause
*/
#include "pico.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
#define PICO_BOOTSEL_VIA_DOUBLE_RESET_TIMEOUT_MS 350
#endif
// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED, Optionally define a pin to use as bootloader activity LED when BOOTSEL mode is entered via reset double tap, type=int, min=0, max=29, group=pico_bootsel_via_double_reset
// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK, Optionally disable either the mass storage interface (bit 0) or the PICOBOOT interface (bit 1) when entering BOOTSEL mode via double reset, type=int, min=0, max=3, default=0, group=pico_bootsel_via_double_reset
#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK
#define PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK 0u
#endif
/** \defgroup pico_bootsel_via_double_reset pico_bootsel_via_double_reset
When the 'pico_bootsel_via_double_reset' library is linked, a function is
injected before main() which will detect when the system has been reset
twice in quick succession, and enter the USB ROM bootloader (BOOTSEL mode)
when this happens. This allows a double tap of a reset button on a
development board to be used to enter the ROM bootloader, provided this
library is always linked.
*/
#if !PICO_NO_BI_BOOTSEL_VIA_DOUBLE_RESET
bi_decl(bi_program_feature("double reset -> BOOTSEL"));
#endif
// Doesn't make any sense for a RAM only binary
#if !PICO_NO_FLASH
static const uint32_t magic_token[] = {
0xf01681de, 0xbd729b29, 0xd359be7a,
};
// Place our marker on the 2nd core's stack...which will not have been touched when this code is executing
static uint32_t *magic_location = (uint32_t*)0x20040000;
//static uint32_t __uninitialized_ram(magic_location)[count_of(magic_token)];
/* Check for double reset and enter BOOTSEL mode if detected
This function is registered to run automatically before main(). The
algorithm is:
1. Check for magic token in memory; enter BOOTSEL mode if found.
2. Initialise that memory with that magic token.
3. Do nothing for a short while (few hundred ms).
4. Clear the magic token.
5. Continue with normal boot.
Resetting the device twice quickly will interrupt step 3, leaving the token
in place so that the second boot will go to the bootloader.
*/
/*static*/ void __attribute__((constructor)) boot_double_tap_check(void) {
for (uint i = 0; i < count_of(magic_token); i++) {
if (magic_location[i] != magic_token[i]) {
// Arm, wait, then disarm and continue booting
for (i = 0; i < count_of(magic_token); i++) {
magic_location[i] = magic_token[i];
}
busy_wait_us(PICO_BOOTSEL_VIA_DOUBLE_RESET_TIMEOUT_MS * 1000);
magic_location[0] = 0;
return;
}
}
// Detected a double reset, so enter USB bootloader
magic_location[0] = 0;
#ifdef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED
const uint32_t led_mask = 1u << PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED;
#else
const uint32_t led_mask = 0u;
#endif
reset_usb_boot(
led_mask,
PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK
);
}
#endif
+14 -17
View File
@@ -28,7 +28,7 @@
static uint32_t analogScale = 255;
static uint32_t analogFreq = 1000;
static bool pwmInitted = false;
static uint32_t pwmInitted = 0;
static bool adcInitted = false;
static uint16_t analogWritePseudoScale = 1;
static uint16_t analogWriteSlowScale = 1;
@@ -42,29 +42,29 @@ extern "C" void analogWriteFreq(uint32_t freq) {
if (freq < 100) {
DEBUGCORE("ERROR: analogWriteFreq too low (%d)\n", freq);
analogFreq = 100;
} else if (freq > 1'000'000) {
} else if (freq > 10'000'000) {
DEBUGCORE("ERROR: analogWriteFreq too high (%d)\n", freq);
analogFreq = 1'000'000;
analogFreq = 10'000'000;
} else {
analogFreq = freq;
}
pwmInitted = false;
pwmInitted = 0;
}
extern "C" void analogWriteRange(uint32_t range) {
if (range == analogScale) {
return;
}
if ((range >= 15) && (range <= 65535)) {
if ((range >= 3) && (range <= 65535)) {
analogScale = range;
pwmInitted = false;
pwmInitted = 0;
} else {
DEBUGCORE("ERROR: analogWriteRange out of range (%d)\n", range);
}
}
extern "C" void analogWriteResolution(int res) {
if ((res >= 4) && (res <= 16)) {
if ((res >= 2) && (res <= 16)) {
analogWriteRange((1 << res) - 1);
} else {
DEBUGCORE("ERROR: analogWriteResolution out of range (%d)\n", res);
@@ -78,29 +78,26 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
DEBUGCORE("ERROR: Illegal analogWrite pin (%d)\n", pin);
return;
}
if (!pwmInitted) {
if (!(pwmInitted & (1 << pin))) {
// For low frequencies, we need to scale the output max value up to achieve lower periods
analogWritePseudoScale = 1;
while (((clock_get_hz(clk_sys) / (float)(analogScale * analogFreq)) > 255.0) && (analogScale < 32678)) {
while (((clock_get_hz(clk_sys) / ((float)analogScale * analogFreq)) > 255.0) && (analogScale < 32678)) {
analogWritePseudoScale++;
analogScale *= 2;
DEBUGCORE("Adjusting analogWrite values PS=%d, scale=%d\n", analogWritePseudoScale, analogScale);
}
// For high frequencies, we need to scale the output max value down to actually hit the frequency target
analogWriteSlowScale = 1;
while (((clock_get_hz(clk_sys) / (float)(analogScale * analogFreq)) < 2.0) && (analogScale > 32)) {
while (((clock_get_hz(clk_sys) / ((float)analogScale * analogFreq)) < 1.0) && (analogScale >= 6)) {
analogWriteSlowScale++;
analogScale /= 2;
DEBUGCORE("Adjusting analogWrite values SS=%d, scale=%d\n", analogWriteSlowScale, analogScale);
}
pwm_config c = pwm_get_default_config();
pwm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / (float)(analogScale * analogFreq));
pwm_config_set_wrap(&c, analogScale);
for (int i = 0; i < 30; i++) {
pwm_init(pwm_gpio_to_slice_num(i), &c, true);
}
pwmInitted = true;
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 << pin;
}
val <<= analogWritePseudoScale;
+25 -14
View File
@@ -22,24 +22,30 @@
#include <CoreMutex.h>
#include <hardware/gpio.h>
#include <hardware/sync.h>
#include <stack>
#include <map>
// Support nested IRQ disable/re-enable
static std::stack<uint32_t> _irqStack[2];
#define maxIRQs 15
static uint32_t _irqStackTop[2] = { 0, 0 };
static uint32_t _irqStack[2][maxIRQs];
extern "C" void interrupts() {
if (_irqStack[get_core_num()].empty()) {
auto core = get_core_num();
if (!_irqStackTop[core]) {
// ERROR
return;
}
auto oldIrqs = _irqStack[get_core_num()].top();
_irqStack[get_core_num()].pop();
restore_interrupts(oldIrqs);
restore_interrupts(_irqStack[core][--_irqStackTop[core]]);
}
extern "C" void noInterrupts() {
_irqStack[get_core_num()].push(save_and_disable_interrupts());
auto core = get_core_num();
if (_irqStackTop[core] == maxIRQs) {
// ERROR
panic("IRQ stack overflow");
}
_irqStack[core][_irqStackTop[core]++] = save_and_disable_interrupts();
}
// Only 1 GPIO IRQ callback for all pins, so we need to look at the pin it's for and
@@ -81,6 +87,15 @@ void _gpioInterruptDispatcher(uint gpio, uint32_t events) {
}
}
// 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()) {
gpio_set_irq_enabled(pin, 0x0f /* all */, false);
_map.erase(pin);
}
}
extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus mode) {
CoreMutex m(&_irqMutex);
if (!m) {
@@ -97,7 +112,7 @@ extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus
default: return; // ERROR
}
noInterrupts();
detachInterrupt(pin);
_detachInterruptInternal(pin);
CBInfo cb(callback);
_map.insert({pin, cb});
gpio_set_irq_enabled_with_callback(pin, events, true, _gpioInterruptDispatcher);
@@ -120,7 +135,7 @@ void attachInterruptParam(pin_size_t pin, voidFuncPtrParam callback, PinStatus m
default: return; // ERROR
}
noInterrupts();
detachInterrupt(pin);
_detachInterruptInternal(pin);
CBInfo cb(callback, param);
_map.insert({pin, cb});
gpio_set_irq_enabled_with_callback(pin, events, true, _gpioInterruptDispatcher);
@@ -134,10 +149,6 @@ extern "C" void detachInterrupt(pin_size_t pin) {
}
noInterrupts();
auto irq = _map.find(pin);
if (irq != _map.end()) {
gpio_set_irq_enabled(pin, 0x0f /* all */, false);
_map.erase(pin);
}
_detachInterruptInternal(pin);
interrupts();
}
+2 -2
View File
@@ -54,9 +54,9 @@ author = u'Earle F. Philhower, III'
# built documents.
#
# The short X.Y version.
version = u'2.5.3'
version = u'2.6.3'
# The full version, including alpha/beta/rc tags.
release = u'2.5.3'
release = u'2.6.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+4 -4
View File
@@ -27,12 +27,12 @@ WiFiClientSecure documentation for more details.
// Error checking is left as an exercise for the reader...
HTTPClient https;
https.setInsecure(); // Use certs, but do not check their authenticity
https.setInsecure(); // Use certs, but do not check their authenticity
if (https.begin("https://my.secure.server/url")) {
if (http.GET() > 0) {
String data = http.getString();
if (https.GET() > 0) {
String data = https.getString();
}
http.end();
https.end();
}
Unlike the ESP8266 and ESP32 ``HTTPClient`` implementations it is not necessary
+7 -18
View File
@@ -65,25 +65,14 @@ Them hit the upload button and your sketch should upload and run.
In some cases the Pico will encounter a hard hang and its USB port will not respond to the auto-reset request. Should this happen, just
follow the initial procedure of holding the BOOTSEL button down while plugging in the Pico to enter the ROM bootloader.
Unable to Upload First Sketch
-----------------------------
If the Arduino IDE has never seen a serial port from a working device (Pico, AVR, or any other serial port), you
may not be able to install using the prior directions because the ``Tools->Port`` menu will be grayed out and
empty. In this case, a special workaround identified by @fjansson in `this issue report <https://github.com/earlephilhower/arduino-pico/issues/688>`_ .
To allow subsequent uploads to automatically work, you will need to manually install a UF2 binary onto the Raspberry Pi Pico one time to
allow it to present a Serial port for the Arduino IDE to detect and save.
Perform the following steps to program a dummy sketch:
1. Open a new, empty sketch (doesn't work with a read-only example sketch).
2. Compile it by pressing the "Verify" checkmark button.
3. Select the ``Sketch -> Export Compiled Binary`` menu. Select a location e.g. the desktop. A folder is created there, containing a file ending in .uf2
4. Copy this file to the Pico's drive, by drag and drop in the Explorer.
The Pico restarts and now now has a serial port. Now the Port menu in Arduino is not gray anymore, select the port there.
After this, normal uploading from the Arduino editor should work.
Uploading the First Sketch
--------------------------
The first time you upload a sketch to a board, you'll need to use the built-in ROM bootloader to handle the upload and not a serial port.
1. Hold the BOOTSEL button while plugging in the board.
2. Select ``Tools->Port->UF2 Board`` from the menu.
3. Upload as normal.
4. After the board boots up, select the new serial port from the ``Tools->Port`` menu.
Windows 7 Driver Notes
----------------------
+9
View File
@@ -70,3 +70,12 @@ int rp2040.getTotalHeap()
Returns the total heap that was available to this program at compile time (i.e.
the Pico RAM size minus things like the ``.data`` and ``.bss`` sections and other
overhead).
Bootloader
----------
void rp2040.enableDoubleResetBootloader()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add a call anywhere in the sketch to ``rp2040.enableDoubleResetBootloader()`` and
the core will check for a double-tap on reset, and if found will start the USB
bootloader.
-2
View File
@@ -40,8 +40,6 @@ Please note that WiFi on the Pico W is a work-in-progress and there are some imp
* Combined STA/AP mode is not supported
* Certain WiFi status values (RSSI, BSSID, etc.) are not available.
* Multicore is supported, but only one core may run ``WiFi`` code.
* FreeRTOS is not yet supported due to the requirement for a very different LWIP implementation. PRs always appreciated!
+2
View File
@@ -54,6 +54,8 @@ SerialPIO KEYWORD2
setFIFOSize KEYWORD2
setPollingMode KEYWORD2
enableDoubleResetBootloader KEYWORD2
OUTPUT_2MA LITERAL1
OUTPUT_4MA LITERAL1
OUTPUT_8MA LITERAL1
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
source [find board/pico-debug.cfg]
+2
View File
@@ -0,0 +1,2 @@
source [find interface/picoprobe.cfg]
source [find target/rp2040.cfg]
+55
View File
@@ -144,4 +144,59 @@
-Wl,--wrap=tanhf
-Wl,--wrap=trunc
-Wl,--wrap=truncf
-Wl,--wrap=__getreent
-Wl,--wrap=malloc
-Wl,--wrap=calloc
-Wl,--wrap=realloc
-Wl,--wrap=free
-Wl,--wrap=pbuf_header
-Wl,--wrap=pbuf_free
-Wl,--wrap=pbuf_alloc
-Wl,--wrap=pbuf_take
-Wl,--wrap=pbuf_copy_partial
-Wl,--wrap=pbuf_ref
-Wl,--wrap=pbuf_get_at
-Wl,--wrap=pbuf_get_contiguous
-Wl,--wrap=pbuf_cat
-Wl,--wrap=tcp_arg
-Wl,--wrap=tcp_new
-Wl,--wrap=tcp_listen
-Wl,--wrap=tcp_listen_with_backlog
-Wl,--wrap=tcp_accept
-Wl,--wrap=tcp_connect
-Wl,--wrap=tcp_write
-Wl,--wrap=tcp_sent
-Wl,--wrap=tcp_recv
-Wl,--wrap=tcp_recved
-Wl,--wrap=tcp_poll
-Wl,--wrap=tcp_close
-Wl,--wrap=tcp_abort
-Wl,--wrap=tcp_err
-Wl,--wrap=tcp_output
-Wl,--wrap=tcp_setprio
-Wl,--wrap=tcp_backlog_delayed
-Wl,--wrap=tcp_backlog_accepted
-Wl,--wrap=udp_new
-Wl,--wrap=udp_remove
-Wl,--wrap=udp_bind
-Wl,--wrap=udp_connect
-Wl,--wrap=udp_disconnect
-Wl,--wrap=udp_send
-Wl,--wrap=udp_recv
-Wl,--wrap=udp_sendto_if
-Wl,--wrap=sys_check_timeouts
-Wl,--wrap=dns_gethostbyname
-Wl,--wrap=dns_gethostbyname_addrtype
-Wl,--wrap=raw_new
-Wl,--wrap=raw_recv
-Wl,--wrap=raw_bind
-Wl,--wrap=raw_sendto
-Wl,--wrap=raw_remove
+1 -1
View File
@@ -110,7 +110,7 @@ void ArduinoOTAClass::begin(bool useMDNS) {
_useMDNS = useMDNS;
if (!_hostname.length()) {
char tmp[15];
char tmp[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 6];
sprintf(tmp, "pico-%s", rp2040.getChipID());
_hostname = tmp;
}
-1
View File
@@ -28,7 +28,6 @@
#include "ESP8266mDNS.h"
#include "LEAmDNS_Priv.h"
#include <LwipIntf.h> // LwipIntf::stateUpCB()
#include <LWIPMutex.h> // LwipIntf::stateUpCB()
#include <lwip/igmp.h>
#include <lwip/prot/dns.h>
@@ -43,9 +43,10 @@ const char *password = STAPSK;
WebServer server(80);
const int led = 13;
const int led = LED_BUILTIN;
void handleRoot() {
static int cnt = 0;
digitalWrite(led, 1);
char temp[400];
int sec = millis() / 1000;
@@ -65,11 +66,13 @@ void handleRoot() {
<body>\
<h1>Hello from the Pico W!</h1>\
<p>Uptime: %02d:%02d:%02d</p>\
<p>Free Memory: %d</p>\
<p>Page Count: %d</p>\
<img src=\"/test.svg\" />\
</body>\
</html>",
hr, min % 60, sec % 60);
hr, min % 60, sec % 60, rp2040.getFreeHeap(), ++cnt);
server.send(200, "text/html", temp);
digitalWrite(led, 0);
}
+4 -1
View File
@@ -280,7 +280,10 @@ void HTTPServer::httpHandleClient() {
}
if (!keepCurrentClient) {
_currentClient = nullptr;
if (_currentClient) {
delete _currentClient;
_currentClient = nullptr;
}
_currentStatus = HC_NONE;
_currentUpload.reset();
}
+1
View File
@@ -42,6 +42,7 @@ gatewayIP KEYWORD2
SSID KEYWORD2
BSSID KEYWORD2
RSSI KEYWORD2
channel KEYWORD2
encryptionType KEYWORD2
beginPacket KEYWORD2
endPacket KEYWORD2
-2
View File
@@ -3,8 +3,6 @@
#include "wl_definitions.h"
#include "wl_types.h"
#include "LWIPMutex.h"
#include "WiFiClass.h"
#include "WiFiClient.h"
#include "WiFiServer.h"
+69 -19
View File
@@ -44,17 +44,20 @@ const char* WiFiClass::firmwareVersion() {
return PICO_SDK_VERSION_STRING;
}
void WiFiClass::mode(_wifiModeESP m) {
void WiFiClass::mode(WiFiMode_t m) {
_calledESP = true;
switch (m) {
case WIFI_OFF:
case WiFiMode_t::WIFI_OFF:
end();
break;
case WIFI_AP:
_modeESP = WIFI_AP;
case WiFiMode_t::WIFI_AP:
_modeESP = WiFiMode_t::WIFI_AP;
break;
case WIFI_STA:
_modeESP = WIFI_STA;
case WiFiMode_t::WIFI_STA:
_modeESP = WiFiMode_t::WIFI_STA;
break;
case WiFiMode_t::WIFI_AP_STA:
_modeESP = WiFiMode_t::WIFI_STA;
break;
}
}
@@ -86,7 +89,7 @@ int WiFiClass::begin(const char* ssid, const char *passphrase) {
_ssid = ssid;
_password = passphrase;
_wifi.setSSID(ssid);
_wifi.setSSID(_ssid.c_str());
_wifi.setPassword(passphrase);
_wifi.setTimeout(_timeout);
_wifi.setSTA();
@@ -123,7 +126,7 @@ uint8_t WiFiClass::beginAP(const char *ssid, const char* passphrase) {
_ssid = ssid;
_password = passphrase;
_wifi.setSSID(ssid);
_wifi.setSSID(_ssid.c_str());
_wifi.setPassword(passphrase);
_wifi.setTimeout(_timeout);
_wifi.setAP();
@@ -234,7 +237,7 @@ const char *WiFiClass::getHostname() {
return: one value of wl_status_t enum
*/
int WiFiClass::disconnect(void) {
int WiFiClass::disconnect(bool wifi_off __unused) {
if (_dhcpServer) {
dhcp_server_deinit(_dhcpServer);
free(_dhcpServer);
@@ -300,7 +303,7 @@ IPAddress WiFiClass::gatewayIP() {
return: ssid string
*/
const char* WiFiClass::SSID() {
const String &WiFiClass::SSID() {
return _ssid;
}
@@ -311,11 +314,33 @@ const char* WiFiClass::SSID() {
return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
*/
uint8_t* WiFiClass::BSSID(uint8_t* bssid) {
// TODO - driver does not return this?!
memset(bssid, 0xee, WL_MAC_ADDR_LENGTH);
#ifndef CYW43_IOCTL_GET_BSSID
#define CYW43_IOCTL_GET_BSSID ( (uint32_t)23 * 2 )
#endif
if (_wifi.connected()) {
cyw43_ioctl(&cyw43_state, CYW43_IOCTL_GET_BSSID, WL_MAC_ADDR_LENGTH, bssid, CYW43_ITF_STA);
} else {
memset(bssid, 0, WL_MAC_ADDR_LENGTH);
}
return bssid;
}
int WiFiClass::channel() {
#ifndef CYW43_IOCTL_GET_CHANNEL
#define CYW43_IOCTL_GET_CHANNEL 0x3a
#endif
int32_t channel;
if (_wifi.connected()) {
cyw43_ioctl(&cyw43_state, CYW43_IOCTL_GET_CHANNEL, sizeof channel, (uint8_t *)&channel, CYW43_ITF_STA);
} else {
channel = -1;
}
return channel;
}
/*
Return the current RSSI /Received Signal Strength in dBm)
associated with the network
@@ -323,8 +348,17 @@ uint8_t* WiFiClass::BSSID(uint8_t* bssid) {
return: signed value
*/
int32_t WiFiClass::RSSI() {
// TODO - driver does not return this?!
return 0;
#ifndef CYW43_IOCTL_GET_RSSI
#define CYW43_IOCTL_GET_RSSI 0xFE
#endif
int32_t rssi;
if (_wifi.connected()) {
cyw43_ioctl(&cyw43_state, CYW43_IOCTL_GET_RSSI, sizeof rssi, (uint8_t *)&rssi, CYW43_ITF_STA);
} else {
rssi = -255;
}
return rssi;
}
/*
@@ -365,7 +399,7 @@ int WiFiClass::_scanCB(void *env, const cyw43_ev_scan_result_t *result) {
return: Number of discovered networks
*/
int8_t WiFiClass::scanNetworks() {
int8_t WiFiClass::scanNetworks(bool async) {
cyw43_wifi_scan_options_t scan_options;
memset(&scan_options, 0, sizeof(scan_options));
_scan.clear();
@@ -378,11 +412,27 @@ int8_t WiFiClass::scanNetworks() {
if (err) {
return 0;
}
uint32_t now = millis();
while (cyw43_wifi_scan_active(&cyw43_state) && (millis() - now < 10000)) {
delay(10);
if (!async) {
uint32_t now = millis();
while (cyw43_wifi_scan_active(&cyw43_state) && (millis() - now < 10000)) {
delay(10);
}
return _scan.size();
} else {
return -1;
}
return _scan.size();
}
int8_t WiFiClass::scanComplete() {
if (cyw43_wifi_scan_active(&cyw43_state)) {
return -1;
} else {
return _scan.size();
}
}
void WiFiClass::scanDelete() {
_scan.clear();
}
/*
+38 -9
View File
@@ -35,7 +35,7 @@
typedef void(*FeedHostProcessorWatchdogFuncPointer)();
typedef enum { WIFI_STA, WIFI_AP, WIFI_OFF } _wifiModeESP; // For ESP8266 compatibility
typedef enum { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 } WiFiMode_t; // For ESP8266 compatibility
class WiFiClass {
public:
@@ -46,7 +46,18 @@ public:
*/
static const char* firmwareVersion();
void mode(_wifiModeESP m); // For ESP8266 compatibility
void mode(WiFiMode_t m); // For ESP8266 compatibility
WiFiMode_t getMode() {
if (_wifiHWInitted) {
if (_apMode) {
return WiFiMode_t::WIFI_AP;
} else {
return WiFiMode_t::WIFI_STA;
}
}
return WiFiMode_t::WIFI_OFF;
};
/* Start WiFi connection for OPEN networks
@@ -138,7 +149,7 @@ public:
}
String softAPSSID() {
return String(SSID());
return SSID();
}
@@ -205,7 +216,7 @@ public:
return: one value of wl_status_t enum
*/
int disconnect(void);
int disconnect(bool wifi_off = false);
void end(void);
@@ -249,7 +260,7 @@ public:
return: ssid string
*/
const char* SSID();
const String &SSID();
/*
Return the current BSSID associated with the network.
@@ -267,6 +278,10 @@ public:
*/
int32_t RSSI();
/* Return the current network channel */
int channel();
/*
Return the Encryption Type associated with the network
@@ -277,9 +292,23 @@ public:
/*
Start scan WiFi networks available
param async: whether to perform asynchronous scan
return: Number of discovered networks
*/
int8_t scanNetworks();
int8_t scanNetworks(bool async = false);
/*
Return number of scanned WiFi networks
return: Number of discovered networks
*/
int8_t scanComplete();
/*
Delete scan results
*/
void scanDelete();
/*
Return the SSID discovered during the network scan.
@@ -353,8 +382,8 @@ public:
private:
int _timeout = 10000;
const char * _ssid = nullptr;
const char * _password = nullptr;
String _ssid;
String _password;
bool _wifiHWInitted = false;
bool _apMode = false;
@@ -367,7 +396,7 @@ private:
// ESP compat
bool _calledESP = false; // Should we behave like the ESP8266 for connect?
_wifiModeESP _modeESP = WIFI_STA;
WiFiMode_t _modeESP = WIFI_STA;
};
extern WiFiClass WiFi;
-2
View File
@@ -130,8 +130,6 @@ int WiFiClient::connect(IPAddress ip, uint16_t port) {
_client = nullptr;
}
LWIPMutex m; // Block the timer sys_check_timeouts call
tcp_pcb* pcb = tcp_new();
if (!pcb) {
return 0;
-5
View File
@@ -56,8 +56,6 @@ void WiFiServer::begin(uint16_t port, uint8_t backlog) {
}
_port = port;
LWIPMutex m; // Block the timer sys_check_timeouts call
tcp_pcb* pcb = tcp_new();
if (!pcb) {
return;
@@ -134,7 +132,6 @@ WiFiClient WiFiServer::accept() {
// pcb can be null when peer has already closed the connection
if (_unclaimed->getPCB()) {
LWIPMutex m; // Block the timer sys_check_timeouts call
// give permission to lwIP to accept one more peer
tcp_backlog_accepted(_unclaimed->getPCB());
}
@@ -162,7 +159,6 @@ void WiFiServer::close() {
if (!_listen_pcb) {
return;
}
LWIPMutex m; // Block the timer sys_check_timeouts call
tcp_close(_listen_pcb);
_listen_pcb = nullptr;
}
@@ -197,7 +193,6 @@ err_t WiFiServer::_accept(tcp_pcb* apcb, err_t err) {
// https://www.nongnu.org/lwip/2_1_x/group__tcp__raw.html#gaeff14f321d1eecd0431611f382fcd338
// increase lwIP's backlog
LWIPMutex m; // Block the timer sys_check_timeouts call
tcp_backlog_delayed(apcb);
_unclaimed = slist_append_tail(_unclaimed, client);
-1
View File
@@ -24,7 +24,6 @@
#include <wl_definitions.h>
struct tcp_pcb;
#include <LWIPMutex.h>
#include <Server.h>
#include <IPAddress.h>
#include <lwip/err.h>
+28 -17
View File
@@ -27,6 +27,8 @@ class WiFiClient;
typedef void (*discard_cb_t)(void*, ClientContext*);
#include <assert.h>
#include "lwip/timeouts.h"
//#include <esp_priv.h>
//#include <coredecls.h>
@@ -36,6 +38,7 @@ template <typename T>
inline void esp_delay(const uint32_t timeout_ms, T&& blocked, const uint32_t intvl_ms) {
const auto start_ms = millis();
while ((((uint32_t)millis() - start_ms) < timeout_ms) && blocked()) {
sys_check_timeouts();
delay(intvl_ms);
}
}
@@ -68,7 +71,6 @@ public:
tcp_recv(_pcb, nullptr);
tcp_err(_pcb, nullptr);
tcp_poll(_pcb, nullptr, 0);
LWIPMutex m; // Block the timer sys_check_timeouts call
tcp_abort(_pcb);
_pcb = nullptr;
}
@@ -84,7 +86,6 @@ public:
tcp_recv(_pcb, nullptr);
tcp_err(_pcb, nullptr);
tcp_poll(_pcb, nullptr, 0);
LWIPMutex m; // Block the timer sys_check_timeouts call
err = tcp_close(_pcb);
if (err != ERR_OK) {
DEBUGV(":tc err %d\r\n", (int) err);
@@ -136,7 +137,6 @@ public:
ip6_addr_assign_zone(ip_2_ip6(addr), IP6_UNKNOWN, netif_default);
}
#endif
LWIPMutex m; // Block the timer sys_check_timeouts call
err_t err = tcp_connect(_pcb, addr, port, &ClientContext::_s_connected);
if (err != ERR_OK) {
return 0;
@@ -162,7 +162,6 @@ public:
}
size_t availableForWrite() const {
LWIPMutex m; // Block the timer sys_check_timeouts call
return _pcb ? tcp_sndbuf(_pcb) : 0;
}
@@ -170,7 +169,6 @@ public:
if (!_pcb) {
return;
}
LWIPMutex m; // Block the timer sys_check_timeouts call
if (nodelay) {
tcp_nagle_disable(_pcb);
} else {
@@ -182,7 +180,6 @@ public:
if (!_pcb) {
return false;
}
LWIPMutex m; // Block the timer sys_check_timeouts call
return tcp_nagle_disabled(_pcb);
}
@@ -300,7 +297,6 @@ public:
if (!_rx_buf) {
return;
}
LWIPMutex m; // Block the timer sys_check_timeouts call
if (_pcb) {
tcp_recved(_pcb, (size_t) _rx_buf->tot_len);
}
@@ -332,7 +328,6 @@ public:
return false;
}
LWIPMutex m; // Block the timer sys_check_timeouts call
// force lwIP to send what can be sent
tcp_output(_pcb);
@@ -517,7 +512,6 @@ protected:
const auto remaining = _datalen - _written;
size_t next_chunk_size;
{
LWIPMutex m; // Block the timer sys_check_timeouts call, just for this call
next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), remaining);
// Potentially reduce transmit size if we are tight on memory, but only if it doesn't return a 0 chunk size
if (next_chunk_size > (size_t)(1 << scale)) {
@@ -571,7 +565,6 @@ protected:
// lwIP's tcp_output doc: "Find out what we can send and send it"
// *with respect to Nagle*
// more info: https://lists.gnu.org/archive/html/lwip-users/2017-11/msg00134.html
LWIPMutex m; // Block the timer sys_check_timeouts call
tcp_output(_pcb);
}
@@ -596,7 +589,6 @@ protected:
void _consume(size_t size) {
ptrdiff_t left = _rx_buf->len - _rx_buf_offset - size;
LWIPMutex m; // Block the timer sys_check_timeouts call
if (left > 0) {
_rx_buf_offset += size;
} else if (!_rx_buf->next) {
@@ -638,7 +630,6 @@ protected:
if (_rx_buf) {
DEBUGV(":rch %d, %d\r\n", _rx_buf->tot_len, pb->tot_len);
LWIPMutex m; // Block the timer sys_check_timeouts call
pbuf_cat(_rx_buf, pb);
} else {
DEBUGV(":rn %d\r\n", pb->tot_len);
@@ -676,24 +667,44 @@ protected:
return ERR_OK;
}
// We may receive a nullptr as arg in the case when an IRQ happens during a shutdown sequence
// In that case, just ignore the CB
static err_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err) {
return reinterpret_cast<ClientContext*>(arg)->_recv(tpcb, pb, err);
if (arg) {
return reinterpret_cast<ClientContext*>(arg)->_recv(tpcb, pb, err);
} else {
return ERR_OK;
}
}
static void _s_error(void *arg, err_t err) {
reinterpret_cast<ClientContext*>(arg)->_error(err);
if (arg) {
reinterpret_cast<ClientContext*>(arg)->_error(err);
}
}
static err_t _s_poll(void *arg, struct tcp_pcb *tpcb) {
return reinterpret_cast<ClientContext*>(arg)->_poll(tpcb);
if (arg) {
return reinterpret_cast<ClientContext*>(arg)->_poll(tpcb);
} else {
return ERR_OK;
}
}
static err_t _s_acked(void *arg, struct tcp_pcb *tpcb, uint16_t len) {
return reinterpret_cast<ClientContext*>(arg)->_acked(tpcb, len);
if (arg) {
return reinterpret_cast<ClientContext*>(arg)->_acked(tpcb, len);
} else {
return ERR_OK;
}
}
static err_t _s_connected(void* arg, struct tcp_pcb *pcb, err_t err) {
return reinterpret_cast<ClientContext*>(arg)->_connected(pcb, err);
if (arg) {
return reinterpret_cast<ClientContext*>(arg)->_connected(pcb, err);
} else {
return ERR_OK;
}
}
private:
+3
View File
@@ -29,6 +29,8 @@ extern "C" {
#include <AddrList.h>
#include <Arduino.h>
#include "lwip/timeouts.h"
//#include <PolledTimeout.h>
#define PBUF_ALIGNER_ADJUST 4
@@ -383,6 +385,7 @@ public:
uint32_t start = millis();
while (((err = trySend(addr, port, /* keep buffer on error */true)) != ERR_OK) && (millis() - start < timeoutMs)) {
delay(1);
sys_check_timeouts();
}
if (err != ERR_OK) {
cancelBuffer(); // get rid of buffer kept on error after timeout
+16 -2
View File
@@ -39,6 +39,7 @@ extern "C" {
netif *CYW43::_netif = nullptr;
extern "C" volatile bool __inLWIP;
CYW43::CYW43(int8_t cs, arduino::SPIClass& spi, int8_t intrpin) {
(void) cs;
@@ -99,7 +100,20 @@ uint16_t CYW43::readFrame(uint8_t* buffer, uint16_t bufsize) {
return 0;
}
// CB from the cyg32_driver
//#define MAXWAIT 16
//static struct pbuf *_pbufWaiting[MAXWAIT];
//static bool _pbufHold(struct pbuf *p) {
// for (int i = 0; i < MAXWAIT; i++) {
// if (!_pbufWaiting[i]) {
// _pbufWaiting[i] = p;
// return true;
// }
// }
// return false;
//}
// CB from the cyw43 driver
extern "C" void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf) {
//cyw43_t *self = (cyw43_t *)cb_data
(void) cb_data;
@@ -114,7 +128,7 @@ extern "C" void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, co
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) {
if (__inLWIP || (netif->input(p, netif) != ERR_OK)) {
pbuf_free(p);
}
CYW43_STAT_INC(PACKET_IN_COUNT);
+2 -6
View File
@@ -26,8 +26,6 @@
// TODO:
// unchain pbufs
#include <LWIPMutex.h>
#include <netif/ethernet.h>
#include <lwip/init.h>
#include <lwip/netif.h>
@@ -176,7 +174,6 @@ int LwipIntfDev<RawDev>::hostByName(const char* aHostname, IPAddress& aResult, i
return 1;
}
LWIPMutex m;
_dns_cb_t cb = { &aResult, this };
#if LWIP_IPV4 && LWIP_IPV6
err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &_dns_found_callback, &cb, LWIP_DNS_ADDRTYPE_DEFAULT);
@@ -230,8 +227,6 @@ int LwipIntfDev<RawDev>::ping(IPAddress host, uint8_t ttl, uint32_t _timeout) {
auto ping_pcb = raw_new(IP_PROTO_ICMP);
ping_pcb->ttl = ttl;
LWIPMutex m;
raw_recv(ping_pcb, _pingCB, this);
raw_bind(ping_pcb, IP_ADDR_ANY);
@@ -256,7 +251,7 @@ int LwipIntfDev<RawDev>::ping(IPAddress host, uint8_t ttl, uint32_t _timeout) {
uint32_t now = millis();
while ((millis() - now < _timeout) && (_ping_ttl < 0)) {
sys_check_timeouts();
delay(10);
delay(1);
}
pbuf_free(p);
raw_remove(ping_pcb);
@@ -408,6 +403,7 @@ void LwipIntfDev<RawDev>::end() {
RawDev::end();
netif_remove(&_netif);
memset(&_netif, 0, sizeof(_netif));
_started = false;
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "framework-arduinopico",
"version": "1.20503.0",
"version": "1.20603.0",
"description": "Arduino Wiring-based Framework (RPi Pico RP2040)",
"keywords": [
"framework",
+6 -1
View File
@@ -72,7 +72,6 @@ cat << EOF > exclude.txt
.travis.yml
package
doc
ArduinoCore-API
EOF
# Also include all files which are ignored by git
git ls-files --other --directory >> exclude.txt
@@ -114,6 +113,12 @@ sed 's/^tools.picoprobe.cmd=.*//g' | \
sed 's/^#tools.picoprobe.cmd=/tools.picoprobe.cmd=/g' | \
sed 's/^tools.picodebug.cmd=.*//g' | \
sed 's/^#tools.picodebug.cmd=/tools.picodebug.cmd=/g' | \
sed 's/^discovery.rp2040.pattern=.*//g' | \
sed 's/^#discovery.rp2040.pattern=/discovery.rp2040.pattern=/g' | \
sed 's/^pluggable_discovery.rp2040.pattern=.*//g' | \
sed 's/^#pluggable_discovery.rp2040.pattern=/pluggable_discovery.rp2040.pattern=/g' | \
sed 's/^tools.uf2conv-network.cmd=.*//g' | \
sed 's/^#tools.uf2conv-network.cmd=/tools.uf2conv-network.cmd=/g' | \
sed "s/version=.*/version=$ver/g" |\
sed -E "s/name=([a-zA-Z0-9\ -]+).*/name=\1($ver)/g"\
> $outdir/platform.txt
+12
View File
@@ -47,12 +47,18 @@
{
"name": "Arduino Nano RP2040 Connect"
},
{
"name": "BridgeTek IDM2040-7A"
},
{
"name": "Cytron Maker Nano RP2040"
},
{
"name": "Cytron Maker Pi RP2040"
},
{
"name": "Degz Mizu"
},
{
"name": "DeRuiLab FlyBoard2040Core"
},
@@ -92,9 +98,15 @@
{
"name": "iLabs RPICO32"
},
{
"name": "Melopero Cookie RP2040"
},
{
"name": "Melopero Shake RP2040"
},
{
"name": "Pimoroni PGA2040"
},
{
"name": "Solder Party RP2040 Stamp"
},
+31 -5
View File
@@ -20,14 +20,14 @@
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
name=Raspberry Pi RP2040 Boards
version=2.5.3
version=2.6.3
runtime.tools.pqt-gcc.path={runtime.platform.path}/system/arm-none-eabi
runtime.tools.pqt-python3.path={runtime.platform.path}/system/python3
runtime.tools.pqt-mklittlefs.path={runtime.platform.path}/system/mklittlefs
runtime.tools.pqt-pioasm.path={runtime.platform.path}/system/pioasm
runtime.tools.pqt-elf2uf2.path={runtime.platform.path}/system/elf2uf2
runtime.tools.pqt-openocd.path={runtime.platform.path}/system/openocd
compiler.path={runtime.tools.pqt-gcc.path}/bin/
compiler.libraries.ldflags=
@@ -42,7 +42,7 @@ compiler.warning_flags.more=-Wall -Werror=return-type -Wno-ignored-qualifiers
compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualifiers
compiler.netdefines=-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 {build.lwipdefs} -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1
compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} -DARDUINO_VARIANT="{build.variant}"
compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} -DARDUINO_VARIANT="{build.variant}" -DTARGET_RP2040
compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt" "-I{runtime.platform.path}/include"
compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect} {build.flags.cmsis}
compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt"
@@ -95,9 +95,14 @@ build.flags.stackprotect=
build.libpico=libpico.a
build.boot2=boot2_generic_03h_4_padded_checksum
build.lwipdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1
build.wificc=-DWIFICC=CYW43_COUNTRY_WORLDWIDE
build.debugscript=picoprobe.tcl
# Allow Pico boards do be auto-discovered by the IDE
discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/discovery.py"
#discovery.rp2040.pattern={runtime.tools.pqt-python3.path}/python3 -I "{runtime.platform.path}/tools/pluggable_discovery.py"
discovery.rp2040.pattern={runtime.platform.path}/system/python3/python3 -I "{runtime.platform.path}/tools/pluggable_discovery.py"
#pluggable_discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/pluggable_discovery.py"
pluggable_discovery.rp2040.pattern="{runtime.platform.path}/system/python3/python3" -I "{runtime.platform.path}/tools/pluggable_discovery.py"
# Compile patterns
@@ -110,7 +115,7 @@ recipe.hooks.sketch.prebuild.pattern="{runtime.tools.pqt-python3.path}/python3"
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {build.flags.optimize} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" -I "{build.path}/core" {compiler.cpp.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {build.flags.optimize} {includes} "{source_file}" -o "{object_file}"
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" -I "{build.path}/core" {compiler.cpp.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {build.flags.optimize} {build.wificc} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
@@ -148,6 +153,19 @@ recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build
recipe.size.regex=^(?:\.boot2|\.text|\.rodata|\.ARM\.extab|\.ARM\.exidx)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.bss|\.ram_vector_table|\.uninitialized_data)\s+([0-9]+).*
# Debugging
debug.executable={build.path}/{build.project_name}.elf
debug.toolchain=gcc
debug.toolchain.path={runtime.tools.pqt-gcc.path}/bin/
debug.toolchain.prefix=arm-none-eabi-
debug.server=openocd
debug.server.openocd.path={runtime.tools.pqt-openocd.path}/bin/openocd
debug.server.openocd.scripts_dir={runtime.tools.pqt-openocd.path}/share/openocd/scripts/
debug.server.openocd.script={runtime.platform.path}/lib/{build.debugscript}
tools.uf2conv.path=
# Because the variable expansion doesn't allow one tool to find another, the following lines
# will point to "{runtime.platform.path}/tools/python3/python3" in GIT and
@@ -162,6 +180,14 @@ tools.uf2conv.upload.params.quiet=
tools.uf2conv.upload.pattern="{cmd}" -I "{runtime.platform.path}/tools/uf2conv.py" --serial "{serial.port}" --family RP2040 --deploy "{build.path}/{build.project_name}.uf2"
tools.uf2conv.upload.network_pattern="{network_cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin"
#tools.uf2conv-network.cmd={runtime.tools.pqt-python3.path}/python3
tools.uf2conv-network.cmd={runtime.platform.path}/system/python3/python3
tools.uf2conv-network.upload.protocol=uf2
tools.uf2conv-network.upload.params.verbose=
tools.uf2conv-network.upload.params.quiet=
tools.uf2conv-network.upload.pattern="{cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{upload.port.address}" -p "{upload.port.properties.port}" "--auth={upload.field.password}" -f "{build.path}/{build.project_name}.bin"
#tools.picoprobe.cmd={runtime.tools.pqt-openocd.path}
tools.picoprobe.cmd={runtime.platform.path}/system/openocd
tools.picoprobe.upload.protocol=picoprobe
-39
View File
@@ -1,39 +0,0 @@
#!/usr/bin/env python3
import time
import subprocess
import uf2conv
boards = False
while True:
l = uf2conv.get_drives()
if (len(l) > 0) and (not boards):
print ("""
{
"eventType": "add",
"port": {
"address": "1",
"label": "Board",
"boardName": "RPI 2040",
"protocol": "uf2",
"protocolLabel": "UF2 Devices",
"prefs": {},
"identificationPrefs": {}
}
}""", flush=True)
boards = True
elif (len(l) == 0) and boards:
print ("""
{
"eventType": "remove",
"port": {
"address": "1",
"label": "Board",
"boardName": "RPI 2040",
"protocol": "uf2",
"protocolLabel": "UF2 Devices",
"prefs": {},
"identificationPrefs": {}
}
}""", flush=True)
boards = False
time.sleep(1)
+54
View File
@@ -0,0 +1,54 @@
{
"build": {
"arduino": {
"earlephilhower": {
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
"usb_vid": "0x2E8A",
"usb_pid": "0x1041"
}
},
"core": "earlephilhower",
"cpu": "cortex-m0plus",
"extra_flags": "-D ARDUINO_BRIDGETEK_IDM2040-7A -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 -DFT8XX_TYPE=BT817 -DDISPLAY_RES=WVGA -DPLATFORM_RP2040",
"f_cpu": "133000000L",
"hwids": [
[
"0x2E8A",
"0x00C0"
],
[
"0x2E8A",
"0x1041"
]
],
"mcu": "rp2040",
"variant": "bridgetek_idm2040-7a"
},
"debug": {
"jlink_device": "RP2040_M0_0",
"openocd_target": "rp2040.cfg",
"svd_path": "rp2040.svd"
},
"frameworks": [
"arduino"
],
"name": "IDM2040-7A",
"upload": {
"maximum_ram_size": 270336,
"maximum_size": 8388608,
"require_upload_port": true,
"native_usb": true,
"use_1200bps_touch": true,
"wait_for_upload_port": false,
"protocol": "picotool",
"protocols": [
"cmsis-dap",
"jlink",
"raspberrypi-swd",
"picotool",
"picoprobe"
]
},
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
"vendor": "BridgeTek"
}
+54
View File
@@ -0,0 +1,54 @@
{
"build": {
"arduino": {
"earlephilhower": {
"boot2_source": "boot2_generic_03h_4_padded_checksum.S",
"usb_vid": "0x2E8A",
"usb_pid": "0x000A"
}
},
"core": "earlephilhower",
"cpu": "cortex-m0plus",
"extra_flags": "-D ARDUINO_DEGZ_MIZU -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
"f_cpu": "133000000L",
"hwids": [
[
"0x2E8A",
"0x00C0"
],
[
"0x2E8A",
"0x000A"
]
],
"mcu": "rp2040",
"variant": "degz_mizu"
},
"debug": {
"jlink_device": "RP2040_M0_0",
"openocd_target": "rp2040.cfg",
"svd_path": "rp2040.svd"
},
"frameworks": [
"arduino"
],
"name": "Mizu",
"upload": {
"maximum_ram_size": 270336,
"maximum_size": 8388608,
"require_upload_port": true,
"native_usb": true,
"use_1200bps_touch": true,
"wait_for_upload_port": false,
"protocol": "picotool",
"protocols": [
"cmsis-dap",
"jlink",
"raspberrypi-swd",
"picotool",
"picoprobe"
]
},
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
"vendor": "Degz"
}
@@ -0,0 +1,54 @@
{
"build": {
"arduino": {
"earlephilhower": {
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
"usb_vid": "0x2E8A",
"usb_pid": "0x1037"
}
},
"core": "earlephilhower",
"cpu": "cortex-m0plus",
"extra_flags": "-D ARDUINO_ELECTRONICCATS_HUNTERCAT_NFC -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500",
"f_cpu": "133000000L",
"hwids": [
[
"0x2E8A",
"0x00C0"
],
[
"0x2E8A",
"0x1037"
]
],
"mcu": "rp2040",
"variant": "electroniccats_huntercat_nfc"
},
"debug": {
"jlink_device": "RP2040_M0_0",
"openocd_target": "rp2040.cfg",
"svd_path": "rp2040.svd"
},
"frameworks": [
"arduino"
],
"name": "HunterCat NFC RP2040",
"upload": {
"maximum_ram_size": 270336,
"maximum_size": 2097152,
"require_upload_port": true,
"native_usb": true,
"use_1200bps_touch": true,
"wait_for_upload_port": false,
"protocol": "picotool",
"protocols": [
"cmsis-dap",
"jlink",
"raspberrypi-swd",
"picotool",
"picoprobe"
]
},
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
"vendor": "ElectronicCats"
}
+1 -1
View File
@@ -2,7 +2,7 @@
"build": {
"arduino": {
"earlephilhower": {
"boot2_source": "boot2_generic_03h_4_padded_checksum.S",
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
"usb_vid": "0x2E8A",
"usb_pid": "0x008A"
}
+54
View File
@@ -0,0 +1,54 @@
{
"build": {
"arduino": {
"earlephilhower": {
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
"usb_vid": "0x2E8A",
"usb_pid": "0x1011"
}
},
"core": "earlephilhower",
"cpu": "cortex-m0plus",
"extra_flags": "-D ARDUINO_MELOPERO_COOKIE_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
"f_cpu": "133000000L",
"hwids": [
[
"0x2E8A",
"0x00C0"
],
[
"0x2E8A",
"0x1011"
]
],
"mcu": "rp2040",
"variant": "melopero_cookie_rp2040"
},
"debug": {
"jlink_device": "RP2040_M0_0",
"openocd_target": "rp2040.cfg",
"svd_path": "rp2040.svd"
},
"frameworks": [
"arduino"
],
"name": "Cookie RP2040",
"upload": {
"maximum_ram_size": 270336,
"maximum_size": 8388608,
"require_upload_port": true,
"native_usb": true,
"use_1200bps_touch": true,
"wait_for_upload_port": false,
"protocol": "picotool",
"protocols": [
"cmsis-dap",
"jlink",
"raspberrypi-swd",
"picotool",
"picoprobe"
]
},
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
"vendor": "Melopero"
}
+54
View File
@@ -0,0 +1,54 @@
{
"build": {
"arduino": {
"earlephilhower": {
"boot2_source": "boot2_w25q64jv_4_padded_checksum.S",
"usb_vid": "0x2E8A",
"usb_pid": "0x1008"
}
},
"core": "earlephilhower",
"cpu": "cortex-m0plus",
"extra_flags": "-D ARDUINO_PIMORONI_PGA2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
"f_cpu": "133000000L",
"hwids": [
[
"0x2E8A",
"0x00C0"
],
[
"0x2E8A",
"0x1008"
]
],
"mcu": "rp2040",
"variant": "pimoroni_pga2040"
},
"debug": {
"jlink_device": "RP2040_M0_0",
"openocd_target": "rp2040.cfg",
"svd_path": "rp2040.svd"
},
"frameworks": [
"arduino"
],
"name": "PGA2040",
"upload": {
"maximum_ram_size": 270336,
"maximum_size": 8388608,
"require_upload_port": true,
"native_usb": true,
"use_1200bps_touch": true,
"wait_for_upload_port": false,
"protocol": "picotool",
"protocols": [
"cmsis-dap",
"jlink",
"raspberrypi-swd",
"picotool",
"picoprobe"
]
},
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
"vendor": "Pimoroni"
}
+1 -1
View File
@@ -97,6 +97,6 @@ target_link_libraries(pico
)
add_custom_command(TARGET pico POST_BUILD
COMMAND ar d libpico.a stdio.c.obj stdio_usb.c.obj stdio_usb_descriptors.c.obj cyw43_arch_threadsafe_background.c.obj
COMMAND ar d libpico.a stdio.c.obj stdio_usb.c.obj stdio_usb_descriptors.c.obj cyw43_arch_threadsafe_background.c.obj pico_malloc.c.obj
COMMAND ar q libpico.a pico-sdk/src/rp2_common/cyw43_driver/cyw43_resource.o
)
+38 -7
View File
@@ -69,7 +69,8 @@ def BuildBoot(name):
for l in [ ("Generic SPI /2", "boot2_generic_03h_2_padded_checksum"), ("Generic SPI /4", "boot2_generic_03h_4_padded_checksum"),
("IS25LP080 QSPI /2", "boot2_is25lp080_2_padded_checksum"), ("IS25LP080 QSPI /4", "boot2_is25lp080_4_padded_checksum"),
("W25Q080 QSPI /2", "boot2_w25q080_2_padded_checksum"), ("W25Q080 QSPI /4", "boot2_w25q080_4_padded_checksum"),
("W25X10CL QSPI /2", "boot2_w25x10cl_2_padded_checksum"), ("W25X10CL QSPI /4", "boot2_w25x10cl_4_padded_checksum") ]:
("W25X10CL QSPI /2", "boot2_w25x10cl_2_padded_checksum"), ("W25X10CL QSPI /4", "boot2_w25x10cl_4_padded_checksum"),
("W25Q64JV QSPI /4", "boot2_w25q64jv_4_padded_checksum") ]:
print("%s.menu.boot2.%s=%s" % (name, l[1], l[0]))
print("%s.menu.boot2.%s.build.boot2=%s" % (name, l[1], l[1]))
@@ -83,6 +84,17 @@ def BuildWithoutUSBStack(name):
print("%s.menu.usbstack.nousb=No USB" % (name))
print('%s.menu.usbstack.nousb.build.usbstack_flags="-DNO_USB -DDISABLE_USB_SERIAL -I{runtime.platform.path}/tools/libpico"' % (name))
def BuildCountry(name):
countries = [ "Worldwide", "Australia", "Austria", "Belgium", "Brazil", "Canada", "Chile", "China", "Colombia", "Czech Republic",
"Denmark", "Estonia", "Finland", "France", "Germany", "Greece", "Hong Kong", "Hungary", "Iceland", "India", "Israel",
"Italy", "Japan", "Kenya", "Latvia", "Liechtenstein", "Lithuania", "Luxembourg", "Malaysia", "Malta", "Mexico",
"Netherlands", "New Zealand", "Nigeria", "Norway", "Peru", "Philippines", "Poland", "Portugal", "Singapore", "Slovakia",
"Slovenia", "South Africa", "South Korea", "Spain", "Sweden", "Switzerland", "Taiwan", "Thailand", "Turkey", "UK", "USA"]
for c in countries:
sane = c.replace(" ", "_").upper()
print("%s.menu.wificountry.%s=%s" % (name, sane.lower(), c))
print("%s.menu.wificountry.%s.build.wificc=-DWIFICC=CYW43_COUNTRY_%s" % (name, sane.lower(), sane))
def BuildIPStack(name):
print("%s.menu.ipstack.ipv4only=IPv4 Only" % (name))
print('%s.menu.ipstack.ipv4only.build.libpico=libpico.a' % (name))
@@ -91,7 +103,7 @@ def BuildIPStack(name):
print('%s.menu.ipstack.ipv4ipv6.build.libpico=libpico-ipv6.a' % (name))
print('%s.menu.ipstack.ipv4ipv6.build.lwipdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1' % (name))
def BuildHeader(name, vendor_name, product_name, vidtouse, pidtouse, vid, pid, pwr, boarddefine, variant, uploadtool, flashsize, ramsize, boot2, extra):
def BuildHeader(name, vendor_name, product_name, vidtouse, pidtouse, vid, pid, pwr, boarddefine, variant, uploadtool, networkuploadtool, flashsize, ramsize, boot2, dbg, extra):
prettyname = vendor_name + " " + product_name
print()
print("# -----------------------------------")
@@ -112,6 +124,9 @@ def BuildHeader(name, vendor_name, product_name, vidtouse, pidtouse, vid, pid, p
print("%s.build.mcu=cortex-m0plus" % (name))
print("%s.build.variant=%s" % (name, variant))
print("%s.upload.tool=%s" % (name, uploadtool))
print("%s.upload.tool.default=%s" % (name, uploadtool))
if networkuploadtool != None:
print("%s.upload.tool.network=%s" % (name, networkuploadtool))
print("%s.upload.maximum_size=%d" % (name, flashsize))
print("%s.upload.maximum_data_size=%d" % (name, ramsize))
print("%s.upload.wait_for_upload_port=true" % (name))
@@ -123,6 +138,7 @@ def BuildHeader(name, vendor_name, product_name, vidtouse, pidtouse, vid, pid, p
print("%s.build.core=rp2040" % (name))
print("%s.build.ldscript=memmap_default.ld" % (name))
print("%s.build.ram_length=%dk" % (name, ramsize / 1024))
print("%s.build.debugscript=%s" % (name, dbg))
print("%s.build.boot2=%s" % (name, boot2))
print("%s.build.vid=%s" % (name, vid))
print("%s.build.pid=%s" % (name, pid))
@@ -151,11 +167,12 @@ def BuildGlobalMenuList():
print("menu.dbgport=Debug Port")
print("menu.dbglvl=Debug Level")
print("menu.boot2=Boot Stage 2")
print("menu.wificountry=WiFi Region")
print("menu.usbstack=USB Stack")
print("menu.ipstack=IP Stack")
def MakeBoard(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, boot2, extra = None):
for a, b, c in [ ["", "", "uf2conv"], ["picoprobe", " (Picoprobe)", "picoprobe"], ["picodebug", " (pico-debug)", "picodebug"]]:
for a, b, c, d in [ ["", "", "uf2conv", "uf2conv-network"], ["picoprobe", " (Picoprobe)", "picoprobe", None], ["picodebug", " (pico-debug)", "picodebug", None]]:
n = name + a
p = product_name + b
fssizelist = [ 0, 64 * 1024, 128 * 1024, 256 * 1024, 512 * 1024 ]
@@ -163,15 +180,17 @@ def MakeBoard(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flash
fssizelist.append(i * 1024 * 1024)
vidtouse = vid;
ramsizekb = 256;
dbg = "picoprobe.tcl"
if a == "picoprobe":
pidtouse = '0x0004'
elif a == "picodebug":
vidtouse = '0x1209'
pidtouse = '0x2488'
ramsizekb = 240;
dbg = "picodebug.tcl"
else:
pidtouse = pid
BuildHeader(n, vendor_name, p, vidtouse, pidtouse, vid, pid, pwr, boarddefine, name, c, flashsizemb * 1024 * 1024, ramsizekb * 1024, boot2, extra)
BuildHeader(n, vendor_name, p, vidtouse, pidtouse, vid, pid, pwr, boarddefine, name, c, d, flashsizemb * 1024 * 1024, ramsizekb * 1024, boot2, dbg, extra)
if name == "generic":
BuildFlashMenu(n, 2*1024*1024, [0, 1*1024*1024])
BuildFlashMenu(n, 4*1024*1024, [0, 2*1024*1024])
@@ -190,6 +209,8 @@ def MakeBoard(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flash
BuildWithoutUSBStack(n)
else:
BuildUSBStack(n)
if name == "rpipicow":
BuildCountry(n)
BuildIPStack(n)
if name == "generic":
BuildBoot(n)
@@ -302,18 +323,24 @@ MakeBoard("adafruit_kb2040", "Adafruit", "KB2040", "0x239a", "0x8105", 250, "ADA
# Arduino
MakeBoard("arduino_nano_connect", "Arduino", "Nano RP2040 Connect", "0x2341", "0x0058", 250, "NANO_RP2040_CONNECT", 16, "boot2_w25q080_2_padded_checksum")
# BridgeTek
MakeBoard("bridgetek_idm2040-7a", "BridgeTek", "IDM2040-7A", "0x2e8a", "0x1041", 250, "BRIDGETEK_IDM2040-7A", 8, "boot2_w25q080_2_padded_checksum", ["FT8XX_TYPE=BT817", "DISPLAY_RES=WVGA", "PLATFORM_RP2040"])
# Cytron
MakeBoard("cytron_maker_nano_rp2040", "Cytron", "Maker Nano RP2040", "0x2e8a", "0x100f", 250, "CYTRON_MAKER_NANO_RP2040", 2, "boot2_w25q080_2_padded_checksum")
MakeBoard("cytron_maker_pi_rp2040", "Cytron", "Maker Pi RP2040", "0x2e8a", "0x1000", 250, "CYTRON_MAKER_PI_RP2040", 2, "boot2_w25q080_2_padded_checksum")
# Degz
MakeBoard("degz_mizu", "Degz", "Mizu", "0x2e8a", "0x000a", 250, "DEGZ_MIZU", 8, "boot2_generic_03h_4_padded_checksum")
# DeRuiLab
MakeBoard("flyboard2040_core", "DeRuiLab", "FlyBoard2040Core", "0x2e8a", "0x008a", 500, "FLYBOARD2040_CORE", 4, "boot2_generic_03h_4_padded_checksum")
MakeBoard("flyboard2040_core", "DeRuiLab", "FlyBoard2040Core", "0x2e8a", "0x008a", 500, "FLYBOARD2040_CORE", 4, "boot2_w25q080_2_padded_checksum")
# DFRobot
MakeBoard("dfrobot_beetle_rp2040", "DFRobot", "Beetle RP2040", "0x3343", "0x4253", 250, "DFROBOT_BEETLE_RP2040", 2, "boot2_w25q080_2_padded_checksum")
# ElectronicCat
MakeBoard("electroniccats_bombercat", "ElectronicCats", "HunterCat NFC RP2040", "0x1209", "0x1209", 500, "ELECTRONICCATS_BOMBERCAT", 2, "boot2_w25q080_2_padded_checksum")
MakeBoard("electroniccats_huntercat_nfc", "ElectronicCats", "HunterCat NFC RP2040", "0x2E8A", "0x1037", 500, "ELECTRONICCATS_HUNTERCAT_NFC", 2, "boot2_w25q080_2_padded_checksum")
# ExtremeElectronics
MakeBoard("extelec_rc2040", "ExtremeElectronics", "RC2040", "0x2e8a", "0xee20", 250, "EXTREMEELEXTRONICS_RC2040", 2, "boot2_w25q080_2_padded_checksum")
@@ -329,9 +356,13 @@ MakeBoard("challenger_2040_sdrtc", "iLabs", "Challenger 2040 SD/RTC", "0x2e8a",
MakeBoard("challenger_2040_nfc", "iLabs", "Challenger 2040 NFC", "0x2e8a", "0x1036", 250, "CHALLENGER_NB_2040_NFC_RP2040", 8, "boot2_w25q080_2_padded_checksum")
MakeBoard("ilabs_rpico32", "iLabs", "RPICO32", "0x2e8a", "0x1010", 250, "ILABS_2040_RPICO32_RP2040", 8, "boot2_w25q080_2_padded_checksum")
# Melopera
# Melopero
MakeBoard("melopero_cookie_rp2040", "Melopero", "Cookie RP2040", "0x2e8a", "0x1011", 250, "MELOPERO_COOKIE_RP2040", 8, "boot2_w25q080_2_padded_checksum")
MakeBoard("melopero_shake_rp2040", "Melopero", "Shake RP2040", "0x2e8a", "0x1005", 250, "MELOPERO_SHAKE_RP2040", 16, "boot2_w25q080_2_padded_checksum")
# Pimoroni
MakeBoard("pimoroni_pga2040", "Pimoroni", "PGA2040", "0x2e8a", "0x1008", 250, "PIMORONI_PGA2040", 8, "boot2_w25q64jv_4_padded_checksum")
# Solder Party
MakeBoard("solderparty_rp2040_stamp", "Solder Party", "RP2040 Stamp", "0x1209", "0xa182", 500, "SOLDERPARTY_RP2040_STAMP", 8, "boot2_generic_03h_4_padded_checksum")
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
import time
import threading
toolspath = os.path.dirname(os.path.realpath(__file__))
try:
sys.path.insert(0, os.path.join(toolspath, ".")) # Add pyserial dir to search path
import uf2conv # If this fails, we can't continue and will bomb below
except ImportError:
sys.stderr.write("uf2conv not found next to this tool.\n")
sys.exit(1)
scannerGo = False
def scanner():
global scannerGo
scannerGo = True
boards = False
while scannerGo:
l = uf2conv.get_drives()
if (len(l) > 0) and scannerGo and not boards:
boards = True
print ("""{
"eventType": "add",
"port": {
"address": "UF2_Board",
"label": "UF2 Board",
"protocol": "uf2conv",
"protocolLabel": "UF2 Devices",
"properties": {
"mac": "ffffffffffff",
"pid" : "0x2e8a",
"vid" : "0x000a"
}
}
}""", flush=True)
elif (len(l) == 0) and scannerGo and boards:
boards = False
print("""{
"eventType": "remove",
"port": {
"address": "UF2_Board",
"protocol": "uf2conv"
}
}""", flush = True)
n = time.time() + 2
while scannerGo and (time.time() < n):
time.sleep(.1)
scannerGo = True
def main():
while True:
cmdline = input()
cmd = cmdline.split()[0]
if cmd == "HELLO":
print(""" {
"eventType": "hello",
"message": "OK",
"protocolVersion": 1
}""", flush = True)
elif cmd == "START":
print("""{
"eventType": "start",
"message": "OK"
}""", flush = True);
elif cmd == "STOP":
scannerGo = False
while not scannerGo:
time.sleep(.1)
print("""{
"eventType": "stop",
"message": "OK"
}""", flush = True)
elif cmd == "QUIT":
scannerGo = False
print("""{
"eventType": "quit",
"message": "OK"
}""", flush = True)
return
elif cmd == "LIST":
l = uf2conv.get_drives()
if len(l) > 0:
print ("""{
"eventType": "list",
"ports": [
{
"address": "UF2_Board",
"label": "UF2 Board",
"protocol": "uf2conv",
"protocolLabel": "UF2 Devices",
"properties": {
"mac": "ffffffffffff",
"pid" : "0x2e8a",
"vid" : "0x000a"
}
}
]
}""", flush=True)
else:
print ("""{
"eventType": "list",
"ports": [ ]
}""", flush=True)
elif cmd == "START_SYNC":
print("""{
"eventType": "start_sync",
"message": "OK"
}""", flush = True)
scannerGo = True
threading.Thread(target = scanner).start()
time.sleep(.5)
main()
@@ -0,0 +1,46 @@
#pragma once
// Pin definitions taken from:
// https://brtchip.com/ic-module/wp-content/uploads/sites/3/2022/07/DS_IDM2040-7A-Revised.pdf
// LEDs
#define PIN_LED (25u)
// Serial
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)
#define PIN_SERIAL2_TX (8u)
#define PIN_SERIAL2_RX (9u)
// SPI
#define PIN_SPI0_MISO (4u)
#define PIN_SPI0_MOSI (3u)
#define PIN_SPI0_SCK (2u)
#define PIN_SPI0_SS (5u)
#define PIN_SPI1_MISO (12u)
#define PIN_SPI1_MOSI (11u)
#define PIN_SPI1_SCK (10u)
#define PIN_SPI1_SS (13u)
// default spi
#define PIN_SD_MOSI PIN_SPI1_MOSI
#define PIN_SD_MISO PIN_SPI1_MISO
#define PIN_SD_SCK PIN_SPI1_SCK
#define PIN_SD_SS PIN_SPI1_SS
#define SDCARD_DETECT 33
// Wire
#define PIN_WIRE0_SDA (4u)
#define PIN_WIRE0_SCL (5u)
#define PIN_WIRE1_SDA (26u)
#define PIN_WIRE1_SCL (27u)
#define SERIAL_HOWMANY (3u)
#define SPI_HOWMANY (2u)
#define WIRE_HOWMANY (2u)
#include "../generic/common.h"
+39
View File
@@ -0,0 +1,39 @@
#pragma once
// Pin definitions taken from:
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
// LEDs
#define PIN_LED (25u)
// Serial
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)
#define PIN_SERIAL2_TX (8u)
#define PIN_SERIAL2_RX (9u)
// SPI
#define PIN_SPI0_MISO (16u)
#define PIN_SPI0_MOSI (7u)
#define PIN_SPI0_SCK (6u)
#define PIN_SPI0_SS (17u)
#define PIN_SPI1_MISO (12u)
#define PIN_SPI1_MOSI (11u)
#define PIN_SPI1_SCK (10u)
#define PIN_SPI1_SS (13u)
// Wire
#define PIN_WIRE0_SDA (4u)
#define PIN_WIRE0_SCL (5u)
#define PIN_WIRE1_SDA (2u)
#define PIN_WIRE1_SCL (3u)
#define SERIAL_HOWMANY (3u)
#define SPI_HOWMANY (2u)
#define WIRE_HOWMANY (2u)
#include "../generic/common.h"
+2 -2
View File
@@ -27,8 +27,8 @@
#define PIN_SPI1_SS (13u)
// Wire
#define PIN_WIRE0_SDA (6u)
#define PIN_WIRE0_SCL (7u)
#define PIN_WIRE0_SDA (16u)
#define PIN_WIRE0_SCL (17u)
#define PIN_WIRE1_SDA (14u)
#define PIN_WIRE1_SCL (15u)
@@ -0,0 +1,40 @@
#pragma once
// Pin definitions taken from:
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
// LEDs
#define PIN_LED (21u)
// Serial
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)
//Serial 2 not pinned out
#define PIN_SERIAL2_TX (31u)
#define PIN_SERIAL2_RX (31u)
// SPI
#define PIN_SPI0_MISO (20u)
#define PIN_SPI0_MOSI (19u)
#define PIN_SPI0_SCK (18u)
#define PIN_SPI0_SS (1u)
#define PIN_SPI1_MISO (28u)
#define PIN_SPI1_MOSI (27u)
#define PIN_SPI1_SCK (26u)
#define PIN_SPI1_SS (29u)
// Wire
#define PIN_WIRE0_SDA (12u)
#define PIN_WIRE0_SCL (13u)
#define PIN_WIRE1_SDA (2u)
#define PIN_WIRE1_SCL (3u)
#define SERIAL_HOWMANY (3u)
#define SPI_HOWMANY (2u)
#define WIRE_HOWMANY (2u)
#include "../generic/common.h"
+5
View File
@@ -0,0 +1,5 @@
#pragma once
// This is a bare board with no real predefined pins, so use generic
#include "../generic/pins_arduino.h"
+5 -1
View File
@@ -20,6 +20,10 @@
#include <pico/cyw43_arch.h>
#ifndef WIFICC
#define WIFICC CYW43_COUNTRY_WORLDWIDE
#endif
extern "C" void initVariant() {
cyw43_arch_init();
cyw43_arch_init_with_country(WIFICC);
}