Skip to content

Commit 12ca3d1

Browse files
Add RP2350B generic/Pimoroni PGA2350 support
Add support for the extra 16 GPIO pins in the menus and core. Clean up Generic RP2350 PSRAM ("none" is valid) and flash (other than 16MB) options. Add extra GPIO<->peripheral connections Add Pimoroni PGA2350 RP2350B-based board
1 parent 70b2735 commit 12ca3d1

File tree

19 files changed

+888
-196
lines changed

19 files changed

+888
-196
lines changed

boards.txt

Lines changed: 473 additions & 135 deletions
Large diffs are not rendered by default.

cores/rp2040/Arduino.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ extern const String emptyString;
130130
// Template which will evaluate at *compile time* to a single 32b number
131131
// with the specified bits set.
132132
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;
133+
constexpr uint64_t __bitset(const int (&a)[N], size_t i = 0U) {
134+
return i < N ? (1LL << a[i]) | __bitset(a, i + 1) : 0;
135135
}
136136
#endif
137137

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

147147
// PSRAM decorator
148148
#define PSRAM __attribute__((section("\".psram\"")))
149+
150+
// General GPIO/ADC layout info
151+
#ifdef PICO_2350B
152+
#define __GPIOCNT 48
153+
#define __FIRSTANALOGGPIO 40
154+
#else
155+
#define __GPIOCNT 30
156+
#define __FIRSTANALOGGPIO 26
157+
#endif

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

cores/rp2040/wiring_analog.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void __clearADCPin(pin_size_t p);
3030

3131
static uint32_t analogScale = 255;
3232
static uint32_t analogFreq = 1000;
33-
static uint32_t pwmInitted = 0;
33+
static uint64_t pwmInitted = 0;
3434
static bool scaleInitted = false;
3535
static bool adcInitted = false;
3636
static uint16_t analogWritePseudoScale = 1;
@@ -79,7 +79,7 @@ extern "C" void analogWriteResolution(int res) {
7979
extern "C" void analogWrite(pin_size_t pin, int val) {
8080
CoreMutex m(&_dacMutex);
8181

82-
if ((pin > 29) || !m) {
82+
if ((pin >= __GPIOCNT) || !m) {
8383
DEBUGCORE("ERROR: Illegal analogWrite pin (%d)\n", pin);
8484
return;
8585
}
@@ -101,12 +101,12 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
101101
}
102102
scaleInitted = true;
103103
}
104-
if (!(pwmInitted & (1 << pwm_gpio_to_slice_num(pin)))) {
104+
if (!(pwmInitted & (1LL << pwm_gpio_to_slice_num(pin)))) {
105105
pwm_config c = pwm_get_default_config();
106106
pwm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / ((float)analogScale * analogFreq));
107107
pwm_config_set_wrap(&c, analogScale - 1);
108108
pwm_init(pwm_gpio_to_slice_num(pin), &c, true);
109-
pwmInitted |= 1 << pwm_gpio_to_slice_num(pin);
109+
pwmInitted |= 1LL << pwm_gpio_to_slice_num(pin);
110110
}
111111

112112
val <<= analogWritePseudoScale;
@@ -125,17 +125,17 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
125125
auto_init_mutex(_adcMutex);
126126
static uint8_t _readBits = 10;
127127
static uint8_t _lastADCMux = 0;
128-
static uint32_t _adcGPIOInit = 0;
128+
static uint64_t _adcGPIOInit = 0;
129129

130130
void __clearADCPin(pin_size_t p) {
131-
_adcGPIOInit &= ~(1 << p);
131+
_adcGPIOInit &= ~(1LL << p);
132132
}
133133

134134
extern "C" int analogRead(pin_size_t pin) {
135135
CoreMutex m(&_adcMutex);
136136

137-
pin_size_t maxPin = max(A0, A3);
138-
pin_size_t minPin = min(A0, A3);
137+
pin_size_t maxPin = __GPIOCNT;
138+
pin_size_t minPin = __FIRSTANALOGGPIO;
139139

140140
if ((pin < minPin) || (pin > maxPin) || !m) {
141141
DEBUGCORE("ERROR: Illegal analogRead pin (%d)\n", pin);
@@ -145,9 +145,9 @@ extern "C" int analogRead(pin_size_t pin) {
145145
adc_init();
146146
adcInitted = true;
147147
}
148-
if (!(_adcGPIOInit & (1 << pin))) {
148+
if (!(_adcGPIOInit & (1LL << pin))) {
149149
adc_gpio_init(pin);
150-
_adcGPIOInit |= 1 << pin;
150+
_adcGPIOInit |= 1LL << pin;
151151
}
152152
if (_lastADCMux != pin) {
153153
adc_select_input(pin - minPin);
@@ -169,7 +169,7 @@ extern "C" float analogReadTemp(float vref) {
169169
_lastADCMux = 0;
170170
adc_set_temp_sensor_enabled(true);
171171
delay(1); // Allow things to settle. Without this, readings can be erratic
172-
adc_select_input(4); // Temperature sensor
172+
adc_select_input(__GPIOCNT - __FIRSTANALOGGPIO); // Temperature sensor
173173
int v = adc_read();
174174
adc_set_temp_sensor_enabled(false);
175175
float t = 27.0f - ((v * vref / 4096.0f) - 0.706f) / 0.001721f; // From the datasheet

cores/rp2040/wiring_digital.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@
2323

2424
extern void __clearADCPin(pin_size_t p);
2525

26-
static PinMode _pm[30];
26+
static PinMode _pm[__GPIOCNT];
2727

2828
extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) __attribute__((weak, alias("__pinMode")));
2929
extern "C" void __pinMode(pin_size_t ulPin, PinMode ulMode) {
30+
if (ulPin >= __GPIOCNT) {
31+
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
32+
return;
33+
}
34+
3035
switch (ulMode) {
3136
case INPUT:
3237
gpio_init(ulPin);
@@ -72,20 +77,16 @@ extern "C" void __pinMode(pin_size_t ulPin, PinMode ulMode) {
7277
return;
7378
}
7479

75-
if (ulPin > 29) {
76-
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
77-
return;
78-
}
7980
_pm[ulPin] = ulMode;
8081

81-
if ((ulPin >= std::min(A0, A3)) && (ulPin <= std::max(A0, A3))) {
82+
if (ulPin >= __FIRSTANALOGGPIO) {
8283
__clearADCPin(ulPin);
8384
}
8485
}
8586

8687
extern "C" void digitalWrite(pin_size_t ulPin, PinStatus ulVal) __attribute__((weak, alias("__digitalWrite")));
8788
extern "C" void __digitalWrite(pin_size_t ulPin, PinStatus ulVal) {
88-
if (ulPin > 29) {
89+
if (ulPin >= __GPIOCNT) {
8990
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
9091
return;
9192
}
@@ -109,7 +110,7 @@ extern "C" void __digitalWrite(pin_size_t ulPin, PinStatus ulVal) {
109110

110111
extern "C" PinStatus digitalRead(pin_size_t ulPin) __attribute__((weak, alias("__digitalRead")));
111112
extern "C" PinStatus __digitalRead(pin_size_t ulPin) {
112-
if (ulPin > 29) {
113+
if (ulPin >= __GPIOCNT) {
113114
DEBUGCORE("ERROR: Illegal pin in digitalRead (%d)\n", ulPin);
114115
return LOW;
115116
}

cores/rp2040/wiring_pulse.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeo
2626
uint64_t start = time_us_64();
2727
uint64_t abort = start + timeout;
2828

29-
if (pin > 29) {
29+
if (pin >= __GPIOCNT) {
3030
DEBUGCORE("ERROR: Illegal pin in pulseIn (%d)\n", pin);
3131
return 0;
3232
}

cores/rp2040/wiring_shift.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
extern "C" uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder) {
2525
uint8_t value = 0;
2626
uint8_t i;
27-
if (dataPin > 29) {
27+
if (dataPin >= __GPIOCNT) {
2828
DEBUGCORE("ERROR: Illegal dataPin in shiftIn (%d)\n", dataPin);
2929
return 0;
3030
}
31-
if (clockPin > 29) {
31+
if (clockPin >= __GPIOCNT) {
3232
DEBUGCORE("ERROR: Illegal clockPin in shiftIn (%d)\n", clockPin);
3333
return 0;
3434
}
@@ -46,11 +46,11 @@ extern "C" uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bit
4646

4747
extern "C" void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val) {
4848
uint8_t i;
49-
if (dataPin > 29) {
49+
if (dataPin >= __GPIOCNT) {
5050
DEBUGCORE("ERROR: Illegal dataPin in shiftOut (%d)\n", dataPin);
5151
return;
5252
}
53-
if (clockPin > 29) {
53+
if (clockPin >= __GPIOCNT) {
5454
DEBUGCORE("ERROR: Illegal clockPin in shiftOut (%d)\n", clockPin);
5555
return;
5656
}

docs/contrib.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,43 @@ code that only runs on this core, use the following define.
8989
~~~ your changes ~~~
9090
#endif
9191
92+
Identifying RP2040, RP2530A, or RP2350B
93+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
94+
95+
To check if a board is an original RP2040
96+
97+
.. code:: cpp
98+
99+
#if defined(PICO_RP2040)
100+
...OG Pico code...
101+
#endif
102+
103+
For RP2350(A or B):
104+
105+
.. code:: cpp
106+
107+
#if defined(PICO_RP2350)
108+
...Pico 2 code...
109+
#endif
110+
111+
For only RP2350A variants (using the compile options, not the onboard ID register):
112+
113+
.. code:: cpp
114+
115+
#if defined(PICO_RP2350) && !defined(PICO_RP2350B)
116+
...RP2350A only code...
117+
#endif
118+
119+
For only RP2350B variants (again, at compile time as identified by the selected board
120+
and not the chip ID register):
121+
122+
.. code:: cpp
123+
124+
#if defined(PICO_RP2350B)
125+
...48-GPIO version code here
126+
#endif
127+
128+
92129
Library Architectures
93130
~~~~~~~~~~~~~~~~~~~~~
94131

@@ -98,3 +135,4 @@ not know your new code is compatible here.
98135

99136
Add ``rp2040`` to ``architectures`` (in ``library.properties``) and
100137
``"rp2040"`` to ``platforms[]`` (in ``library.json``) to let the tools know.
138+
Note that even the RP2350 is identified as ``rp2040`` for this purpose.

libraries/SPI/src/SPI.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,16 @@ void SPIClassRP2040::abortAsync() {
329329

330330

331331
bool SPIClassRP2040::setRX(pin_size_t pin) {
332-
constexpr uint32_t valid[2] = { __bitset({0, 4, 16, 20}) /* SPI0 */,
332+
#ifdef RP2350B
333+
constexpr uint64_t valid[2] = { __bitset({0, 4, 16, 20, 32, 26}) /* SPI0 */,
334+
__bitset({8, 12, 24, 28, 40, 44}) /* SPI1 */
335+
};
336+
#else
337+
constexpr uint64_t valid[2] = { __bitset({0, 4, 16, 20}) /* SPI0 */,
333338
__bitset({8, 12, 24, 28}) /* SPI1 */
334339
};
335-
if ((!_running) && ((1 << pin) & valid[spi_get_index(_spi)])) {
340+
#endif
341+
if ((!_running) && ((1LL << pin) & valid[spi_get_index(_spi)])) {
336342
_RX = pin;
337343
return true;
338344
}
@@ -350,10 +356,16 @@ bool SPIClassRP2040::setRX(pin_size_t pin) {
350356
}
351357

352358
bool SPIClassRP2040::setCS(pin_size_t pin) {
353-
constexpr uint32_t valid[2] = { __bitset({1, 5, 17, 21}) /* SPI0 */,
359+
#ifdef RP2350B
360+
constexpr uint64_t valid[2] = { __bitset({1, 5, 17, 21, 33, 37}) /* SPI0 */,
361+
__bitset({9, 13, 25, 29, 41, 45}) /* SPI1 */
362+
};
363+
#else
364+
constexpr uint64_t valid[2] = { __bitset({1, 5, 17, 21}) /* SPI0 */,
354365
__bitset({9, 13, 25, 29}) /* SPI1 */
355366
};
356-
if ((!_running) && ((1 << pin) & valid[spi_get_index(_spi)])) {
367+
#endif
368+
if ((!_running) && ((1LL << pin) & valid[spi_get_index(_spi)])) {
357369
_CS = pin;
358370
return true;
359371
}
@@ -371,10 +383,16 @@ bool SPIClassRP2040::setCS(pin_size_t pin) {
371383
}
372384

373385
bool SPIClassRP2040::setSCK(pin_size_t pin) {
374-
constexpr uint32_t valid[2] = { __bitset({2, 6, 18, 22}) /* SPI0 */,
386+
#ifdef RP2350B
387+
constexpr uint64_t valid[2] = { __bitset({2, 6, 18, 22, 34, 38}) /* SPI0 */,
388+
__bitset({10, 14, 26, 30, 42, 46}) /* SPI1 */
389+
};
390+
#else
391+
constexpr uint64_t valid[2] = { __bitset({2, 6, 18, 22}) /* SPI0 */,
375392
__bitset({10, 14, 26}) /* SPI1 */
376393
};
377-
if ((!_running) && ((1 << pin) & valid[spi_get_index(_spi)])) {
394+
#endif
395+
if ((!_running) && ((1LL << pin) & valid[spi_get_index(_spi)])) {
378396
_SCK = pin;
379397
return true;
380398
}
@@ -392,10 +410,16 @@ bool SPIClassRP2040::setSCK(pin_size_t pin) {
392410
}
393411

394412
bool SPIClassRP2040::setTX(pin_size_t pin) {
395-
constexpr uint32_t valid[2] = { __bitset({3, 7, 19, 23}) /* SPI0 */,
413+
#ifdef RP2350B
414+
constexpr uint64_t valid[2] = { __bitset({3, 7, 19, 23, 35, 39}) /* SPI0 */,
415+
__bitset({11, 15, 27, 31, 43, 47}) /* SPI1 */
416+
};
417+
#else
418+
constexpr uint64_t valid[2] = { __bitset({3, 7, 19, 23}) /* SPI0 */,
396419
__bitset({11, 15, 27}) /* SPI1 */
397420
};
398-
if ((!_running) && ((1 << pin) & valid[spi_get_index(_spi)])) {
421+
#endif
422+
if ((!_running) && ((1LL << pin) & valid[spi_get_index(_spi)])) {
399423
_TX = pin;
400424
return true;
401425
}

0 commit comments

Comments
 (0)