Skip to content

Commit 317d74d

Browse files
authored
Merge branch 'master' into picoadk-v2
2 parents d2855a8 + b2ec6ec commit 317d74d

File tree

104 files changed

+12039
-717
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+12039
-717
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@
4646
[submodule "cores/rp2040/tlsf"]
4747
path = lib/tlsf
4848
url = https://github.com/earlephilhower/tlsf.git
49+
[submodule "libraries/ESPHost"]
50+
path = libraries/ESPHost
51+
url = https://github.com/Networking-for-Arduino/ESPHost.git

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ The installed tools include a version of OpenOCD (in the pqt-openocd directory)
261261
* [Xoshiro-cpp](https://github.com/Reputeless/Xoshiro-cpp) is copyright (c) 2020 Ryo Suzuki and distributed under the MIT license.
262262
* [FatFS low-level filesystem](http://elm-chan.org/fsw/ff/) code is Copyright (C) 2024, ChaN, all rights reserved.
263263
* [TLSF memory manager for PSRAM from Espressif fork](https://github.com/espressif/tlsf) of [original](https://github.com/mattconte/tlsf) by Matthew Conte is copyright Matthew Conte and licensed under the MIT license.
264+
* [ESPHost library](https://github.com/Networking-for-Arduino/ESPHost) is LGPL licensed by its maintainers.
264265
265266
-Earle F. Philhower, III
266267

boards.txt

Lines changed: 1067 additions & 277 deletions
Large diffs are not rendered by default.

cores/rp2040/Arduino.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,15 @@ extern "C" {
5858
void interrupts();
5959
void noInterrupts();
6060

61+
// Only implemented on some RP2350 boards, not the OG Pico 2
6162
#ifdef RP2350_PSRAM_CS
6263
void *pmalloc(size_t size);
6364
void *pcalloc(size_t count, size_t size);
65+
#else
66+
[[deprecated("This chip does not have PSRAM, pmalloc will always fail")]] void *pmalloc(size_t size);
67+
[[deprecated("This chip does not have PSRAM, pcalloc will always fail")]] void *pcalloc(size_t count, size_t size);
6468
#endif
6569

66-
6770
// AVR compatibility macros...naughty and accesses the HW directly
6871
#define digitalPinToPort(pin) (0)
6972
#define digitalPinToBitMask(pin) (1UL << (pin))
@@ -130,8 +133,8 @@ extern const String emptyString;
130133
// Template which will evaluate at *compile time* to a single 32b number
131134
// with the specified bits set.
132135
template <size_t N>
133-
constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
134-
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
136+
constexpr uint64_t __bitset(const int (&a)[N], size_t i = 0U) {
137+
return i < N ? (1LL << a[i]) | __bitset(a, i + 1) : 0;
135138
}
136139
#endif
137140

@@ -146,3 +149,12 @@ constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
146149

147150
// PSRAM decorator
148151
#define PSRAM __attribute__((section("\".psram\"")))
152+
153+
// General GPIO/ADC layout info
154+
#ifdef PICO_RP2350B
155+
#define __GPIOCNT 48
156+
#define __FIRSTANALOGGPIO 40
157+
#else
158+
#define __GPIOCNT 30
159+
#define __FIRSTANALOGGPIO 26
160+
#endif

cores/rp2040/PIOProgram.cpp

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <Arduino.h>
2222
#include "PIOProgram.h"
2323
#include <map>
24+
#include <hardware/claim.h>
2425

2526
#if defined(PICO_RP2350)
2627
#define PIOS pio0, pio1, pio2
@@ -31,6 +32,8 @@
3132
#endif
3233

3334
static std::map<const pio_program_t *, int> __pioMap[PIOCNT];
35+
static bool __pioAllocated[PIOCNT];
36+
static bool __pioHighGPIO[PIOCNT];
3437
auto_init_mutex(_pioMutex);
3538

3639
PIOProgram::PIOProgram(const pio_program_t *pgm) {
@@ -47,16 +50,30 @@ PIOProgram::~PIOProgram() {
4750
}
4851

4952
// Possibly load into a PIO and allocate a SM
50-
bool PIOProgram::prepare(PIO *pio, int *sm, int *offset) {
53+
bool PIOProgram::prepare(PIO *pio, int *sm, int *offset, int start, int cnt) {
5154
CoreMutex m(&_pioMutex);
5255
PIO pi[PIOCNT] = { PIOS };
5356

57+
#if 0
58+
uint usm;
59+
uint uoff;
60+
auto ret = pio_claim_free_sm_and_add_program_for_gpio_range(_pgm, pio, &usm, &uoff, start, cnt, true);
61+
*sm = usm;
62+
*offset = uoff;
63+
DEBUGV("clain %d\n", ret);
64+
return ret;
65+
#endif
66+
67+
bool needsHigh = (start + cnt) >= 32;
68+
DEBUGV("PIOProgram %p: Searching for high=%d, pins %d-%d\n", _pgm, needsHigh ? 1 : 0, start, start + cnt - 1);
69+
5470
// If it's already loaded into PIO IRAM, try and allocate in that specific PIO
5571
for (int o = 0; o < PIOCNT; o++) {
5672
auto p = __pioMap[o].find(_pgm);
57-
if (p != __pioMap[o].end()) {
73+
if ((p != __pioMap[o].end()) && (__pioHighGPIO[o] == needsHigh)) {
5874
int idx = pio_claim_unused_sm(pi[o], false);
5975
if (idx >= 0) {
76+
DEBUGV("PIOProgram %p: Reusing IMEM ON PIO %p(high=%d) for pins %d-%d\n", _pgm, pi[o], __pioHighGPIO[o] ? 1 : 0, start, start + cnt - 1);
6077
_pio = pi[o];
6178
_sm = idx;
6279
*pio = pi[o];
@@ -69,19 +86,52 @@ bool PIOProgram::prepare(PIO *pio, int *sm, int *offset) {
6986

7087
// Not in any PIO IRAM, so try and add
7188
for (int o = 0; o < PIOCNT; o++) {
72-
if (pio_can_add_program(pi[o], _pgm)) {
73-
int idx = pio_claim_unused_sm(pi[o], false);
74-
if (idx >= 0) {
75-
int off = pio_add_program(pi[o], _pgm);
76-
__pioMap[o].insert({_pgm, off});
77-
_pio = pi[o];
78-
_sm = idx;
79-
*pio = pi[o];
80-
*sm = idx;
81-
*offset = off;
82-
return true;
89+
if (__pioAllocated[o] && (__pioHighGPIO[o] == needsHigh)) {
90+
DEBUGV("PIOProgram: Checking PIO %p\n", pi[o]);
91+
if (pio_can_add_program(pi[o], _pgm)) {
92+
int idx = pio_claim_unused_sm(pi[o], false);
93+
if (idx >= 0) {
94+
DEBUGV("PIOProgram %p: Adding IMEM ON PIO %p(high=%d) for pins %d-%d\n", _pgm, pi[o], __pioHighGPIO[o] ? 1 : 0, start, start + cnt - 1);
95+
int off = pio_add_program(pi[o], _pgm);
96+
__pioMap[o].insert({_pgm, off});
97+
_pio = pi[o];
98+
_sm = idx;
99+
*pio = pi[o];
100+
*sm = idx;
101+
*offset = off;
102+
return true;
103+
} else {
104+
DEBUGV("PIOProgram: can't claim unused SM\n");
105+
}
106+
} else {
107+
DEBUGV("PIOProgram: can't add program\n");
83108
}
109+
} else {
110+
DEBUGV("PIOProgram: Skipping PIO %p, wrong allocated/needhi\n", pi[o]);
111+
}
112+
}
113+
114+
// No existing PIOs can meet, is there an unallocated one we can allocate?
115+
PIO p;
116+
uint idx;
117+
uint off;
118+
auto rc = pio_claim_free_sm_and_add_program_for_gpio_range(_pgm, &p, &idx, &off, start, cnt, true);
119+
if (rc) {
120+
int o = 0;
121+
while (p != pi[o]) {
122+
o++;
84123
}
124+
assert(!__pioAllocated[o]);
125+
__pioAllocated[o] = true;
126+
__pioHighGPIO[o] = needsHigh;
127+
DEBUGV("PIOProgram %p: Allocating new PIO %p(high=%d) for pins %d-%d\n", _pgm, pi[o], __pioHighGPIO[o] ? 1 : 0, start, start + cnt - 1);
128+
__pioMap[o].insert({_pgm, off});
129+
_pio = pi[o];
130+
_sm = idx;
131+
*pio = pi[o];
132+
*sm = idx;
133+
*offset = off;
134+
return true;
85135
}
86136

87137
// Nope, no room either for SMs or INSNs

cores/rp2040/PIOProgram.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class PIOProgram {
2828
PIOProgram(const pio_program_t *pgm);
2929
~PIOProgram();
3030
// Possibly load into a PIO and allocate a SM
31-
bool prepare(PIO *pio, int *sm, int *offset);
31+
bool prepare(PIO *pio, int *sm, int *offset, int gpio_start = 0, int gpio_cnt = 1);
3232

3333
private:
3434
const pio_program_t *_pgm;

cores/rp2040/RP2040Support.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class RP2040 {
253253
}
254254

255255
inline int getUsedPSRAMHeap() {
256-
#if defined(PICO_RP2350)
256+
#if defined(RP2350_PSRAM_CS)
257257
extern size_t __psram_total_used();
258258
return __psram_total_used();
259259
#else
@@ -262,7 +262,7 @@ class RP2040 {
262262
}
263263

264264
inline int getTotalPSRAMHeap() {
265-
#if defined(PICO_RP2350)
265+
#if defined(RP2350_PSRAM_CS)
266266
extern size_t __psram_total_space();
267267
return __psram_total_space();
268268
#else
@@ -290,7 +290,7 @@ class RP2040 {
290290
}
291291

292292
inline size_t getPSRAMSize() {
293-
#if defined(PICO_RP2350)
293+
#if defined(RP2350_PSRAM_CS)
294294
extern size_t __psram_size;
295295
return __psram_size;
296296
#else

cores/rp2040/RP2040Version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pragma once
22
#define ARDUINO_PICO_MAJOR 4
33
#define ARDUINO_PICO_MINOR 0
4-
#define ARDUINO_PICO_REVISION 1
5-
#define ARDUINO_PICO_VERSION_STR "4.0.1"
4+
#define ARDUINO_PICO_REVISION 2
5+
#define ARDUINO_PICO_VERSION_STR "4.0.2"

cores/rp2040/SerialPIO.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static std::map<int, PIOProgram*> _rxMap;
3333
// Duplicate a program and replace the first insn with a "set x, repl"
3434
static pio_program_t *pio_make_uart_prog(int repl, const pio_program_t *pg) {
3535
pio_program_t *p = new pio_program_t;
36+
memcpy(p, pg, sizeof(*p));
3637
p->length = pg->length;
3738
p->origin = pg->origin;
3839
uint16_t *insn = (uint16_t *)malloc(p->length * 2);
@@ -78,9 +79,9 @@ static int _parity(int bits, int data) {
7879

7980
// We need to cache generated SerialPIOs so we can add data to them from
8081
// the shared handler
81-
static SerialPIO *_pioSP[2][4];
82+
static SerialPIO *_pioSP[3][4];
8283
static void __not_in_flash_func(_fifoIRQ)() {
83-
for (int p = 0; p < 2; p++) {
84+
for (int p = 0; p < 3; p++) {
8485
for (int sm = 0; sm < 4; sm++) {
8586
SerialPIO *s = _pioSP[p][sm];
8687
if (s) {
@@ -147,6 +148,21 @@ SerialPIO::~SerialPIO() {
147148
delete[] _queue;
148149
}
149150

151+
static int pio_irq_0(PIO p) {
152+
switch (pio_get_index(p)) {
153+
case 0:
154+
return PIO0_IRQ_0;
155+
case 1:
156+
return PIO1_IRQ_0;
157+
#if defined(PICO_RP2350)
158+
case 2:
159+
return PIO2_IRQ_0;
160+
#endif
161+
default:
162+
return -1;
163+
}
164+
}
165+
150166
void SerialPIO::begin(unsigned long baud, uint16_t config) {
151167
_overflow = false;
152168
_baud = baud;
@@ -193,7 +209,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
193209
_txBits = _bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1/*start bit*/;
194210
_txPgm = _getTxProgram(_txBits);
195211
int off;
196-
if (!_txPgm->prepare(&_txPIO, &_txSM, &off)) {
212+
if (!_txPgm->prepare(&_txPIO, &_txSM, &off, _tx, 1)) {
197213
DEBUGCORE("ERROR: Unable to allocate PIO TX UART, out of PIO resources\n");
198214
// ERROR, no free slots
199215
return;
@@ -221,7 +237,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
221237
_rxBits = 2 * (_bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1) - 1;
222238
_rxPgm = _getRxProgram(_rxBits);
223239
int off;
224-
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off)) {
240+
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off, _rx, 1)) {
225241
DEBUGCORE("ERROR: Unable to allocate PIO RX UART, out of PIO resources\n");
226242
return;
227243
}
@@ -246,7 +262,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
246262
case 2: pio_set_irq0_source_enabled(_rxPIO, pis_sm2_rx_fifo_not_empty, true); break;
247263
case 3: pio_set_irq0_source_enabled(_rxPIO, pis_sm3_rx_fifo_not_empty, true); break;
248264
}
249-
auto irqno = pio_get_index(_rxPIO) == 0 ? PIO0_IRQ_0 : PIO1_IRQ_0;
265+
auto irqno = pio_irq_0(_rxPIO);
250266
irq_set_exclusive_handler(irqno, _fifoIRQ);
251267
irq_set_enabled(irqno, true);
252268

@@ -277,7 +293,7 @@ void SerialPIO::end() {
277293
used = used || !!_pioSP[pioNum][i];
278294
}
279295
if (!used) {
280-
auto irqno = pioNum == 0 ? PIO0_IRQ_0 : PIO1_IRQ_0;
296+
auto irqno = pio_irq_0(_rxPIO);
281297
irq_set_enabled(irqno, false);
282298
}
283299
gpio_set_inover(_rx, 0);

cores/rp2040/SerialUART.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ extern void serialEvent1() __attribute__((weak));
3232
extern void serialEvent2() __attribute__((weak));
3333

3434
bool SerialUART::setRX(pin_size_t pin) {
35-
constexpr uint32_t valid[2] = { __bitset({1, 13, 17, 29}) /* UART0 */,
35+
#ifdef PICO_RP2350B
36+
constexpr uint64_t valid[2] = { __bitset({1, 13, 17, 29, 33, 45}) /* UART0 */,
37+
__bitset({5, 9, 21, 25, 37, 41}) /* UART1 */
38+
};
39+
#else
40+
constexpr uint64_t valid[2] = { __bitset({1, 13, 17, 29}) /* UART0 */,
3641
__bitset({5, 9, 21, 25}) /* UART1 */
3742
};
38-
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
43+
#endif
44+
if ((!_running) && ((1LL << pin) & valid[uart_get_index(_uart)])) {
3945
_rx = pin;
4046
return true;
4147
}
@@ -53,10 +59,16 @@ bool SerialUART::setRX(pin_size_t pin) {
5359
}
5460

5561
bool SerialUART::setTX(pin_size_t pin) {
56-
constexpr uint32_t valid[2] = { __bitset({0, 12, 16, 28}) /* UART0 */,
62+
#ifdef PICO_RP2350B
63+
constexpr uint64_t valid[2] = { __bitset({0, 12, 16, 28, 32, 44}) /* UART0 */,
64+
__bitset({4, 8, 20, 24, 36, 40}) /* UART1 */
65+
};
66+
#else
67+
constexpr uint64_t valid[2] = { __bitset({0, 12, 16, 28}) /* UART0 */,
5768
__bitset({4, 8, 20, 24}) /* UART1 */
5869
};
59-
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
70+
#endif
71+
if ((!_running) && ((1LL << pin) & valid[uart_get_index(_uart)])) {
6072
_tx = pin;
6173
return true;
6274
}
@@ -74,10 +86,16 @@ bool SerialUART::setTX(pin_size_t pin) {
7486
}
7587

7688
bool SerialUART::setRTS(pin_size_t pin) {
77-
constexpr uint32_t valid[2] = { __bitset({3, 15, 19}) /* UART0 */,
89+
#ifdef PICO_RP2350B
90+
constexpr uint64_t valid[2] = { __bitset({3, 15, 19, 31, 35, 47}) /* UART0 */,
91+
__bitset({7, 11, 23, 27, 39, 43}) /* UART1 */
92+
};
93+
#else
94+
constexpr uint64_t valid[2] = { __bitset({3, 15, 19}) /* UART0 */,
7895
__bitset({7, 11, 23, 27}) /* UART1 */
7996
};
80-
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1 << pin) & valid[uart_get_index(_uart)]))) {
97+
#endif
98+
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1LL << pin) & valid[uart_get_index(_uart)]))) {
8199
_rts = pin;
82100
return true;
83101
}
@@ -95,10 +113,16 @@ bool SerialUART::setRTS(pin_size_t pin) {
95113
}
96114

97115
bool SerialUART::setCTS(pin_size_t pin) {
98-
constexpr uint32_t valid[2] = { __bitset({2, 14, 18}) /* UART0 */,
116+
#ifdef PICO_RP2350B
117+
constexpr uint64_t valid[2] = { __bitset({2, 14, 18, 30, 34, 46}) /* UART0 */,
118+
__bitset({6, 10, 22, 26, 38, 42}) /* UART1 */
119+
};
120+
#else
121+
constexpr uint64_t valid[2] = { __bitset({2, 14, 18}) /* UART0 */,
99122
__bitset({6, 10, 22, 26}) /* UART1 */
100123
};
101-
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1 << pin) & valid[uart_get_index(_uart)]))) {
124+
#endif
125+
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1LL << pin) & valid[uart_get_index(_uart)]))) {
102126
_cts = pin;
103127
return true;
104128
}

0 commit comments

Comments
 (0)