boards/arm/rp23xx: Add support for the Pimoroni Pico Plus 2 W.

The Pimoroni Pico Plus 2 W is a Pico form-factor board built around the
RP2350B, the 80-pin part with 48 GPIOs, carrying 16MB of flash, 8MB of PSRAM
and a Raspberry Pi RM2 module for 2.4GHz WiFi.  The RM2 houses an Infineon
CYW43439, wired to the same pins the Raspberry Pi Pico W uses: GPIO 23 for
power enable, 24 for the shared gSPI data and interrupt line, 25 for chip
select and 29 for the clock.

Three configurations are provided: nsh and usbnsh without the wireless chip,
and wifi, which brings up wlan0 in station mode with WAPI, a DHCP client and
ping.  The CYW43439 firmware and CLM blob are linked in from the pico-sdk at
build time, as on the Pico W; CONFIG_CYW43439_FIRMWARE_BIN_PATH selects the
file and the board documentation covers converting it out of the C header that
pico-sdk 2.x ships in place of the binary.  rp23xx_firmware.c is placed in the
common source directory so that a future board with the same chip can reuse
it, and unlike rp2040 the blob is staged for the CMake build as well.

Two board details are worth calling out:

  - The only LED is wired to GPIO 0 of the CYW43439 rather than to a pin of
    the RP2350, so driving it means an iovar request over the gSPI bus.  That
    works for CONFIG_USERLED but not for CONFIG_ARCH_LEDS, whose
    board_autoled_on() is called from interrupt handlers and from assertion
    handling, so a build selecting CONFIG_ARCH_LEDS is rejected with an
    explicit message.  The LED also only responds once wlan0 has been brought
    up, because that is when the chip's firmware is downloaded.

  - The BOOT button is also wired to GPIO 45, so it can be read as an ordinary
    user button once NuttX is running.  Its internal pull-up is enabled
    deliberately: erratum RP2350-E9 means a floating Bank 0 input on RP2350 A2
    leaks enough current to settle around 2.2V, which the internal pull-down
    cannot overcome.

Tested on the board with a Raspberry Pi Debug Probe: nsh and wifi boot on
UART0, wlan0 reports the MAC read from the chip, wapi scan lists access
points, and association to a WPA2 network followed by DHCP gives a working
route with ping succeeding to both a literal address and a resolved name.
The LED and the BOOT button were confirmed by hand.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This commit is contained in:
Marco Casaroli 2026-07-25 12:36:03 +02:00
parent bf6de2df0c
commit 7e074b23c9
29 changed files with 3558 additions and 0 deletions

View file

@ -0,0 +1,276 @@
======================
Pimoroni Pico Plus 2 W
======================
.. tags:: chip:rp2350, chip:rp2350b, wifi
The `Pimoroni Pico Plus 2 W <https://shop.pimoroni.com/products/pimoroni-pico-plus-2-w>`_
is a Raspberry Pi Pico form-factor board built around the RP2350B -- the 80-pin
variant of the RP2350 with 48 GPIOs. It adds 16MB of flash, 8MB of PSRAM, a
USB-C connector, a Qw/ST (Qwiic/STEMMA QT) connector, and an Infineon CYW43439
for 2.4GHz WiFi and Bluetooth. The radio is carried on a Raspberry Pi RM2
module, which is where the CYW43439 lives.
.. figure:: pimoroni-pico-plus-2-w.jpg
:align: center
Pimoroni Pico Plus 2 W, front and back (photo: Pimoroni)
Features
========
* RP2350B microcontroller chip (QFN-80 package)
* Dual-core ARM Cortex-M33 processor at up to 150MHz, with FPU and DSP
* Also contains two Hazard3 RISC-V cores, selectable instead of the M33 pair
* 520kB of on-chip SRAM
* 16MB of on-board QSPI flash
* 8MB of on-board QSPI PSRAM (chip select on GPIO 47)
* 48 multi-function GPIO pins, 30 of them on the castellated headers
* 4x UART, 2x SPI, 2x I2C, 8x 12-bit ADC, 24x PWM channels
* 12x Programmable IO (PIO) state machines across 3 PIO blocks
* USB-C, supporting device and host
* Infineon CYW43439 for 2.4GHz WiFi 4 (802.11n) and Bluetooth 5.2
* Qw/ST connector on I2C0
* BOOT and RESET buttons; BOOT is also readable at runtime on GPIO 45
* Battery connector with charging, and VSYS monitoring on GPIO 43
Serial Console
==============
By default the serial console is UART0 on GPIO 0 (TX, pin 1) and GPIO 1
(RX, pin 2), at 115200-8N1.
The board can instead be configured to put the console on the USB-C connector
(the ``usbnsh`` configuration). Note that the RP2350 USB device support is
still marked experimental in NuttX and the CDC/ACM console is known to corrupt
data and stop responding after a handful of commands. Prefer the UART console
for anything that matters.
Wireless Communication
======================
The on-board Infineon CYW43439 is reached over a half-duplex gSPI bus driven by
a PIO state machine, implemented in ``arch/arm/src/rp23xx/rp23xx_cyw43439.c``.
It presents itself as the ``wlan0`` network device and supports 2.4GHz WiFi 4
(802.11n) in station mode. Bluetooth is not supported.
The chip's firmware is not downloaded until ``wlan0`` is brought up, so nothing
on the wireless chip -- including the LED, see below -- responds before that.
CYW43439 firmware
-----------------
The driver links the wireless chip's firmware and CLM blob into the NuttX
binary, so a copy has to be available at build time. ``CONFIG_CYW43439_FIRMWARE_BIN_PATH``
points at it and defaults to::
${PICO_SDK_PATH}/lib/cyw43-driver/firmware/43439A0-7.95.49.00.combined
This is the WiFi firmware padded up to a 256-byte boundary with the CLM blob
appended, and ``CONFIG_CYW43439_FIRMWARE_LEN`` is the *unpadded* length of just
the firmware part (224190 bytes for this release).
pico-sdk 2.x no longer ships that file as a binary -- it only carries the same
bytes as a C array in ``lib/cyw43-driver/firmware/w43439A0_7_95_49_00_combined.h``.
If that is all you have, convert the array back to a binary, for example::
$ python3 -c '
import re, sys
text = open(sys.argv[1]).read()
body = text.split("{", 1)[1].split("};", 1)[0]
data = bytes(int(b, 16) for b in re.findall(r"0x([0-9a-fA-F]{2})", body))
open(sys.argv[2], "wb").write(data)
' ${PICO_SDK_PATH}/lib/cyw43-driver/firmware/w43439A0_7_95_49_00_combined.h \
${PICO_SDK_PATH}/lib/cyw43-driver/firmware/43439A0-7.95.49.00.combined
The header's own ``CYW43_WIFI_FW_LEN`` and ``CYW43_CLM_LEN`` macros tell you the
lengths to expect: 224190 + 984, in a 225240-byte file.
If the file is missing the build still succeeds, but a placeholder is linked in
and the wireless chip will not come up.
User LED
========
**The board's only LED is wired to GPIO 0 of the CYW43439, not to a pin of the
RP2350.** Setting it therefore means an iovar request over the gSPI bus, which
has two consequences:
* The LED does not respond until ``wlan0`` has been brought up, because that is
when the wireless chip's firmware is downloaded. Before that, every write
fails with ``-EIO``.
* Driving the LED blocks, so it cannot be done from interrupt context. That
rules out ``CONFIG_ARCH_LEDS``, whose ``board_autoled_on()`` is called from
interrupt handlers and from assertion handling. This board therefore
supports ``CONFIG_USERLED`` only, and a build with ``CONFIG_ARCH_LEDS``
enabled is rejected with an explicit error.
With ``CONFIG_USERLED`` the LED appears as ``/dev/userleds`` and can be driven
with the ``leds`` example. Board code can also reach it, and the CYW43439's
other two GPIOs, through ``include/rp23xx_extra_gpio.h``:
===== ========= ==============================================================
GPIO Direction Function
===== ========= ==============================================================
0 output On-board LED
1 output Voltage regulator mode: 1 selects PWM (less ripple) over PFM
2 input Non-zero if power is coming from USB or the VBUS pin
===== ========= ==============================================================
Buttons
-------
The board has two physical buttons, BOOT and RESET.
BOOT is also wired to GPIO 45, active low, so once NuttX is running it can be
read as an ordinary user button -- this is the pin pico-sdk calls
``PIMORONI_PICO_PLUS2_W_USER_SW_PIN``. It appears as ``/dev/buttons`` with
``CONFIG_INPUT_BUTTONS``, and is the single button reported by
``board_buttons()``. RESET is not readable as a GPIO.
The internal pull-up is enabled on GPIO 45, and must be: erratum RP2350-E9
means a floating Bank 0 input on RP2350 A2 leaks around 120uA and settles at
roughly 2.2V, which the internal pull-down is far too weak to overcome. The
pull-up is unaffected by the erratum.
Held down while power is applied or while RESET is released, BOOT instead makes
the RP2350 come up in bootloader mode, where it appears as a storage device over
USB; copying a .UF2 file to it replaces the flash contents.
Pin Mapping
===========
The castellated headers follow the Raspberry Pi Pico pinout, with the RP2350B's
extra GPIOs brought out on the two rows of pads inside the headers.
===== ========== =============================================================
Pin Signal Notes
===== ========== =============================================================
1 GPIO0 Default TX for UART0 serial console
2 GPIO1 Default RX for UART0 serial console
3 Ground
4 GPIO2
5 GPIO3
6 GPIO4 Default SDA for I2C0, also on the Qw/ST connector
7 GPIO5 Default SCL for I2C0, also on the Qw/ST connector
8 Ground
9 GPIO6
10 GPIO7
11 GPIO8
12 GPIO9
13 Ground
14 GPIO10
15 GPIO11
16 GPIO12
17 GPIO13
18 Ground
19 GPIO14
20 GPIO15
21 GPIO16 Default RX for SPI0
22 GPIO17 Default CSn for SPI0
23 Ground
24 GPIO18 Default SCK for SPI0
25 GPIO19 Default TX for SPI0
26 GPIO20
27 GPIO21
28 Ground
29 GPIO22
30 Run
31 GPIO26 ADC0
32 GPIO27 ADC1
33 AGND Analog ground
34 GPIO28 ADC2
35 ADC_VREF Analog reference voltage
36 3V3 Power output to peripherals
37 3V3_EN Pull to ground to turn off
38 Ground
39 VSYS +5V supply to the board
40 VBUS Connected to USB +5V
===== ========== =============================================================
Other RP2350B Pins
==================
===== ================================================================
GPIO Function
===== ================================================================
23 Output - CYW43439 power enable (WL_REG_ON)
24 I/O - CYW43439 gSPI data line, doubles as its interrupt request
25 Output - CYW43439 chip select
29 Output - CYW43439 gSPI clock
43 Input - VSYS monitoring, via ADC
45 Input - BOOT button, active low, readable as a user button
47 Output - PSRAM chip select
===== ================================================================
Note that GPIO 23, 24, 25 and 29 are the same pins the Raspberry Pi Pico W uses
for its CYW43439, so the wireless wiring is identical despite the larger
package. Do not use them for anything else.
Installation & Build
====================
For instructions on how to install the build dependencies and create a NuttX
image for this board, consult the main :doc:`RP23XX documentation <../../index>`.
Configurations
==============
All configurations listed below can be configured using the following command
in the ``nuttx`` directory (again, consult the main
:doc:`RP23XX documentation <../../index>`):
.. code:: console
$ ./tools/configure.sh pimoroni-pico-plus-2-w:<configname>
nsh
---
Basic NuttShell configuration, console on UART0 at 115200 bps. The wireless
chip is not enabled, so this configuration has no network and no LED.
usbnsh
------
Basic NuttShell configuration with the console on USB CDC/ACM at 115200 bps.
See the caveat under `Serial Console`_.
wifi
----
NuttShell configuration with the console on UART0 at 115200 bps and the
CYW43439 enabled: ``wlan0`` in station mode, WAPI, DHCP client, DNS client and
``ping``. ``/dev/userleds`` and ``/dev/buttons`` are registered too.
After loading this configuration, set the country code to match your region in
:menuselection:`Device Drivers --> Wireless Device Support --> IEEE 802.11 Device Support`,
and set your network's credentials in
:menuselection:`Application Configuration --> Network Utilities --> Network initialization --> WAPI Configuration`.
Alternatively, leave the built-in credentials alone and associate at runtime:
.. code:: console
nsh> wapi mode wlan0 2
nsh> wapi psk wlan0 "my-passphrase" 3 2
nsh> wapi essid wlan0 my-ssid 1
nsh> renew wlan0
nsh> ifconfig
lo Link encap:Local Loopback at RUNNING mtu 1518
inet addr:127.0.0.1 DRaddr:127.0.0.1 Mask:255.0.0.0
wlan0 Link encap:Ethernet HWaddr 28:cd:c1:ff:d3:be at RUNNING mtu 576
inet addr:192.168.0.118 DRaddr:192.168.0.1 Mask:255.255.255.0
nsh> ping -c 3 8.8.8.8
PING 8.8.8.8 56 bytes of data
56 bytes from 8.8.8.8: icmp_seq=0 time=20.0 ms
56 bytes from 8.8.8.8: icmp_seq=1 time=10.0 ms
56 bytes from 8.8.8.8: icmp_seq=2 time=10.0 ms
3 packets transmitted, 3 received, 0% packet loss, time 3030 ms
rtt min/avg/max/mdev = 10.000/13.333/20.000/4.714 ms
The ``3`` and ``2`` arguments to ``wapi psk`` select WPA_ALG_CCMP and WPA_VER_2;
run ``wapi help`` for the other values. ``wapi scan wlan0`` lists the visible
access points.

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

View file

@ -2266,6 +2266,23 @@ config ARCH_BOARD_PIMORONI_PICO_2_PLUS
---help---
This is a port to the Pimoroni Pico 2 Plus board.
config ARCH_BOARD_PIMORONI_PICO_PLUS_2_W
bool "Pimoroni Pico Plus 2 W"
depends on ARCH_CHIP_RP23XX
select ARCH_HAVE_LEDS
select ARCH_HAVE_BUTTONS
select ARCH_HAVE_IRQBUTTONS
select RP23XX_RP2350B
---help---
This is a port to the Pimoroni Pico Plus 2 W board, which adds an
Infineon CYW43439 WiFi/Bluetooth chip to the Pico Plus 2.
The board's only LED is wired to a GPIO of the CYW43439 rather than
to a pin of the RP2350, so driving it means a transaction on the gSPI
bus. That works for the CONFIG_USERLED interface but not for
CONFIG_ARCH_LEDS, which is called from interrupt context, so
CONFIG_ARCH_LEDS is rejected at build time on this board.
config ARCH_BOARD_WAVESHARE_RP2040_LCD_1_28
bool "Waveshare RP2040 LCD 1.28 board"
depends on ARCH_CHIP_RP2040
@ -3936,6 +3953,7 @@ config ARCH_BOARD
default "raspberrypi-pico-2-rv" if ARCH_BOARD_RASPBERRYPI_PICO_2_RV
default "xiao-rp2350" if ARCH_BOARD_XIAO_RP2350
default "pimoroni-pico-2-plus" if ARCH_BOARD_PIMORONI_PICO_2_PLUS
default "pimoroni-pico-plus-2-w" if ARCH_BOARD_PIMORONI_PICO_PLUS_2_W
default "w5500-evb-pico" if ARCH_BOARD_W5500_EVB_PICO
default "waveshare-rp2040-zero" if ARCH_BOARD_WAVESHARE_RP2040_ZERO
default "rx65n" if ARCH_BOARD_RX65N
@ -4473,6 +4491,9 @@ endif
if ARCH_BOARD_PIMORONI_PICO_2_PLUS
source "boards/arm/rp23xx/pimoroni-pico-2-plus/Kconfig"
endif
if ARCH_BOARD_PIMORONI_PICO_PLUS_2_W
source "boards/arm/rp23xx/pimoroni-pico-plus-2-w/Kconfig"
endif
if ARCH_BOARD_ARDUINO_DUE
source "boards/arm/sam34/arduino-due/Kconfig"
endif

View file

@ -110,6 +110,38 @@ if(CONFIG_ARCH_BOARD_COMMON)
list(APPEND SRCS rp23xx_max6675.c)
endif()
# Firmware blob for the Infineon CYW43439 WiFi chip. rp23xx_firmware.c
# .incbin's it, so it has to be staged somewhere on the include path.
if(CONFIG_IEEE80211_INFINEON_CYW43439)
list(APPEND SRCS rp23xx_firmware.c)
string(REPLACE "\"" "" CYW43439_FIRMWARE_SRC
"${CONFIG_CYW43439_FIRMWARE_BIN_PATH}")
string(CONFIGURE "${CYW43439_FIRMWARE_SRC}" CYW43439_FIRMWARE_SRC)
set(CYW43439_FIRMWARE "${CMAKE_CURRENT_BINARY_DIR}/cyw43439.firmware.image")
if(EXISTS "${CYW43439_FIRMWARE_SRC}")
configure_file("${CYW43439_FIRMWARE_SRC}" "${CYW43439_FIRMWARE}" COPYONLY)
else()
# NuttX built with this dummy will not talk to the wireless chip. It only
# exists so that a tree without a pico-sdk checkout still compiles.
message(
WARNING "cyw43439 firmware not found at ${CYW43439_FIRMWARE_SRC}; "
"the wireless chip will not work. See the board Kconfig help.")
file(WRITE "${CYW43439_FIRMWARE}" "dummy\n")
endif()
set_property(
SOURCE rp23xx_firmware.c
APPEND
PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
set_property(
SOURCE rp23xx_firmware.c
APPEND
PROPERTY OBJECT_DEPENDS "${CYW43439_FIRMWARE}")
endif()
endif()
target_sources(board PRIVATE ${SRCS})
target_compile_options(board PRIVATE ${RP23XXFLAGS})

View file

@ -110,6 +110,13 @@ ifeq ($(CONFIG_SENSORS_MAX6675),y)
CSRCS += rp23xx_max6675.c
endif
# Firmware blob for the Infineon CYW43439 WiFi chip. The board that carries
# the chip stages the blob itself, see its src/Make.defs.
ifeq ($(CONFIG_IEEE80211_INFINEON_CYW43439),y)
CSRCS += rp23xx_firmware.c
endif
DEPPATH += --dep-path src
VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View file

@ -0,0 +1,164 @@
/****************************************************************************
* boards/arm/rp23xx/common/src/rp23xx_firmware.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define _STR(x) #x
#define STR(x) _STR(x)
#define ROUNDED_FIRMWARE_LEN ((CONFIG_CYW43439_FIRMWARE_LEN + 0xff) & ~0xff)
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef CONFIG_IEEE80211_INFINEON_CYW43439
/****************************************************************************
* Character array of NVRAM image
* Generated from cyw943439wlpth_rev1_0.txt
* $ Copyright Broadcom Corporation $
****************************************************************************/
const uint8_t g_cyw43439_nvram_image[] __attribute__((aligned(4))) =
"NVRAMRev=$Rev$" "\x00"
"manfid=0x2d0" "\x00"
"prodid=0x0727" "\x00"
"vendid=0x14e4" "\x00"
"devid=0x43e2" "\x00"
"boardtype=0x0887" "\x00"
"boardrev=0x1100" "\x00"
"boardnum=22" "\x00"
"macaddr=00:A0:50:b5:59:5e" "\x00"
"sromrev=11" "\x00"
"boardflags=0x00404001" "\x00"
"boardflags3=0x04000000" "\x00"
"xtalfreq=37400" "\x00"
"nocrc=1" "\x00"
"ag0=255" "\x00"
"aa2g=1" "\x00"
"ccode=ALL" "\x00"
"pa0itssit=0x20" "\x00"
"extpagain2g=0" "\x00"
"pa2ga0=-168,6649,-778" "\x00"
"AvVmid_c0=0x0,0xc8" "\x00"
"cckpwroffset0=5" "\x00"
"maxp2ga0=84" "\x00"
"txpwrbckof=6" "\x00"
"cckbw202gpo=0" "\x00"
"legofdmbw202gpo=0x66111111" "\x00"
"mcsbw202gpo=0x77711111" "\x00"
"propbw202gpo=0xdd" "\x00"
"ofdmdigfilttype=18" "\x00"
"ofdmdigfilttypebe=18" "\x00"
"papdmode=1" "\x00"
"papdvalidtest=1" "\x00"
"pacalidx2g=45" "\x00"
"papdepsoffset=-30" "\x00"
"papdendidx=58" "\x00"
"ltecxmux=0" "\x00"
"ltecxpadnum=0x0102" "\x00"
"ltecxfnsel=0x44" "\x00"
"ltecxgcigpio=0x01" "\x00"
"il0macaddr=00:90:4c:c5:12:38" "\x00"
"wl0id=0x431b" "\x00"
"deadman_to=0xffffffff" "\x00"
"muxenab=0x100" "\x00"
"spurconfig=0x3" "\x00"
"glitch_based_crsmin=1" "\x00"
"btc_mode=1" "\x00"
"\x00\x00";
const unsigned int g_cyw43439_nvram_len = sizeof(g_cyw43439_nvram_image);
/****************************************************************************
* Include the firmware blob. This assembly code defines the global
* symbol g_cyw43439_firmware_image as the address of this included
* blob. This is similar in effect to the C statement:
* const uint8_t g_cyw43439_firmware_image[] = {...};
* const uint8_t ng_cyw43439_clm_blob_image[] = {...};
****************************************************************************/
/* These are defined as array because the symbols name an actual address
* not a pointer to an address. This is not one of the many cases where
* pointers and arrays are interchangeable in C.
*/
extern const uint8_t g_cyw43439_firmware_image[];
extern const uint8_t g_cyw43439_clm_blob_image[];
extern const unsigned int g_cyw43439_clm_blob_len;
/* This assembly code does the following:
* - Force 16-byte alignment
* - Defines g_cyw43439_firmware_image as a location in memory
* - Copies the firmware image file data to that location.
* - Defines g_cyw43439_firmware_end as the location directly beyond
* that data.
* - Defines g_cyw43439_clm_blob_image as a location within that
* data where the clm_blob begins.
* - Force 4-byte alignment
* - Allocates an integer named g_cyw43439_clm_blob_len that
* contains the length of the clm_blob.
*/
__asm__("\n .balign 16"
"\n .globl g_cyw43439_firmware_image"
"\n .globl g_cyw43439_clm_blob_image"
"\n .globl g_cyw43439_clm_blob_len"
"\n g_cyw43439_firmware_image:"
"\n .incbin \"cyw43439.firmware.image\""
"\n firmware_end:"
"\n g_cyw43439_clm_blob_image=g_cyw43439_firmware_image+"
STR(ROUNDED_FIRMWARE_LEN)
"\n .balign 4"
"\n g_cyw43439_clm_blob_len:"
"\n .word firmware_end-g_cyw43439_clm_blob_image"
"\n");
/****************************************************************************
* Other CYW43439 Firmware global definitions
****************************************************************************/
#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
const unsigned int g_cyw43439_firmware_len = CONFIG_CYW43439_FIRMWARE_LEN;
#endif /* CONFIG_IEEE80211_BROADCOM_FWFILES */
#endif /* CONFIG_IEEE80211_INFINEON_CYW43439 */
/****************************************************************************
* Public Functions
****************************************************************************/
/* This file contributes data only. The section banner is here because
* tools/checkpatch.sh refuses to check a C file without one.
*/

View file

@ -0,0 +1,40 @@
# ##############################################################################
# boards/arm/rp23xx/pimoroni-pico-plus-2-w/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
add_subdirectory(src)
add_custom_target(
nuttx_post_build
DEPENDS nuttx
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Regenerate nuttx.uf2")
# The uf2 command to convert ELF/BIN to UF2
add_custom_command(
TARGET nuttx_post_build
POST_BUILD
COMMAND picotool ARGS uf2 convert --quiet -t elf nuttx nuttx.uf2
COMMAND_EXPAND_LISTS
COMMAND ${CMAKE_COMMAND} -E echo "nuttx.uf2" >>
${CMAKE_BINARY_DIR}/nuttx.manifest
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Regenerate nuttx.uf2")

View file

@ -0,0 +1,54 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if ARCH_BOARD_PIMORONI_PICO_PLUS_2_W
# The board's only LED hangs off a GPIO of the CYW43439, so setting it means a
# transaction on the gSPI bus. board_autoled_on() is called from interrupt
# handlers and from assertion handling, where that is not permissible, so this
# board supports the CONFIG_USERLED interface only. Override the generic
# "default y" so that a fresh configuration does not select something this
# board cannot implement.
config ARCH_LEDS
default n
menuconfig RP23XX_INFINEON_CYW43439
bool "Has Infineon cyw43439 WiFi chip"
depends on IEEE80211_INFINEON_CYW43439
default y
endif
if RP23XX_INFINEON_CYW43439
config CYW43439_FIRMWARE_BIN_PATH
string "Path to Infineon 43439 firmware file"
default "${PICO_SDK_PATH}/lib/cyw43-driver/firmware/43439A0-7.95.49.00.combined"
---help---
This should be a path to a file containing both the cyw43439 firmware and
the CLM blob. The firmware should be padded to a 256 byte boundary and
then the CLM blob should be appended.
If this file is updated, check the CYW43439_FIRMWARE_LEN below to make sure
it reflects the un-padded length of the firmware part.
pico-sdk 2.x no longer ships this blob as a binary, only as the C header
lib/cyw43-driver/firmware/w43439A0_7_95_49_00_combined.h. If that is all
you have, convert the byte array in that header back to a binary and point
this option at the result.
config CYW43439_FIRMWARE_LEN
int "Infineon 43439 firmware length (bytes)"
default 224190
---help---
This is the length of just the base firmware in the firmware file specified
by the "Path to Infineon 43439 firmware file" configuration option.
This length does not include the length of any padding nor the length of
the appended clm_blob. If a clm_blob is present in the firmware file, this
length will be less than the length of the whole file.
endif

View file

@ -0,0 +1,48 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_LEDS is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
# CONFIG_NSH_DISABLE_DATE is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="pimoroni-pico-plus-2-w"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_PIMORONI_PICO_PLUS_2_W=y
CONFIG_ARCH_CHIP="rp23xx"
CONFIG_ARCH_CHIP_RP23XX=y
CONFIG_ARCH_RAMVECTORS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=10450
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_HOST_MACOS=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_READLINE=y
CONFIG_RAM_SIZE=532480
CONFIG_RAM_START=0x20000000
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=9
CONFIG_START_MONTH=2
CONFIG_START_YEAR=2021
CONFIG_SYSLOG_CONSOLE=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y

View file

@ -0,0 +1,52 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_LEDS is not set
# CONFIG_DEV_CONSOLE is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
# CONFIG_NSH_DISABLE_DATE is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_RP23XX_UART0 is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="pimoroni-pico-plus-2-w"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_PIMORONI_PICO_PLUS_2_W=y
CONFIG_ARCH_CHIP="rp23xx"
CONFIG_ARCH_CHIP_RP23XX=y
CONFIG_ARCH_RAMVECTORS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=10450
CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_CDCACM_CONSOLE=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_HOST_MACOS=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_READLINE=y
CONFIG_NSH_USBCONSOLE=y
CONFIG_RAM_SIZE=532480
CONFIG_RAM_START=0x20000000
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=9
CONFIG_START_MONTH=2
CONFIG_START_YEAR=2021
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_USBDEV=y
CONFIG_USBDEV_BUSPOWERED=y

View file

@ -0,0 +1,89 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_LEDS is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
# CONFIG_NSH_DISABLE_DATE is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="pimoroni-pico-plus-2-w"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_PIMORONI_PICO_PLUS_2_W=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="rp23xx"
CONFIG_ARCH_CHIP_RP23XX=y
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_RAMVECTORS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=10450
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_DRIVERS_IEEE80211=y
CONFIG_DRIVERS_WIRELESS=y
CONFIG_EXAMPLES_BUTTONS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_LEDS=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_HOST_MACOS=y
CONFIG_IEEE80211_BROADCOM_DEFAULT_COUNTRY="XX"
CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT=16
CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE=32
CONFIG_IEEE80211_BROADCOM_FULLMAC_GSPI=y
CONFIG_IEEE80211_INFINEON_CYW43439=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INPUT=y
CONFIG_INPUT_BUTTONS=y
CONFIG_INPUT_BUTTONS_LOWER=y
CONFIG_IOB_NBUFFERS=196
CONFIG_IOB_NCHAINS=24
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSCLIENT_RECV_TIMEOUT=3
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETINIT_DHCPC=y
CONFIG_NETINIT_DNS=y
CONFIG_NETINIT_DNSIPADDR=0x08080808
CONFIG_NETINIT_WAPI_PASSPHRASE="-ssid-passphrase-"
CONFIG_NETINIT_WAPI_SSID="-my-ssid-"
CONFIG_NET_BROADCAST=y
CONFIG_NET_ICMP_SOCKET=y
CONFIG_NET_LOOPBACK=y
CONFIG_NET_TCP=y
CONFIG_NET_TCP_DELAYED_ACK=y
CONFIG_NET_UDP=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_READLINE=y
CONFIG_RAM_SIZE=532480
CONFIG_RAM_START=0x20000000
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=9
CONFIG_START_MONTH=2
CONFIG_START_YEAR=2021
CONFIG_SYSLOG_CONSOLE=y
CONFIG_SYSTEM_DHCPC_RENEW=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_PING=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USERLED=y
CONFIG_USERLED_LOWER=y
CONFIG_WIRELESS_WAPI=y
CONFIG_WIRELESS_WAPI_CMDTOOL=y
CONFIG_WQUEUE_NOTIFIER=y

View file

@ -0,0 +1,154 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/include/board.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_BOARD_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_BOARD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "rp23xx_i2cdev.h"
#include "rp23xx_spidev.h"
#include "rp23xx_i2sdev.h"
#include "rp23xx_spisd.h"
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Clocking *****************************************************************/
#define MHZ 1000000
#define BOARD_XOSC_FREQ (12 * MHZ)
#define BOARD_XOSC_STARTUPDELAY 1
#define BOARD_PLL_SYS_FREQ (150 * MHZ)
#define BOARD_PLL_USB_FREQ (48 * MHZ)
#define BOARD_REF_FREQ (12 * MHZ)
#define BOARD_SYS_FREQ (150 * MHZ)
#define BOARD_PERI_FREQ (150 * MHZ)
#define BOARD_USB_FREQ (48 * MHZ)
#define BOARD_ADC_FREQ (48 * MHZ)
#define BOARD_HSTX_FREQ (150 * MHZ)
#define BOARD_UART_BASEFREQ BOARD_PERI_FREQ
#define BOARD_TICK_CLOCK (1 * MHZ)
/* definitions for pico-sdk */
/* GPIO definitions *********************************************************/
#define BOARD_NGPIOOUT 1
#define BOARD_NGPIOIN 1
#define BOARD_NGPIOINT 1
/* LED definitions **********************************************************/
/* The only LED on this board is wired to GPIO 0 of the CYW43439 wireless
* chip, not to a GPIO of the RP2350. Driving it means sending an iovar
* request over the gSPI bus, which can only be done from task context and
* only once the wireless chip has been activated by bringing wlan0 up.
*
* That rules out CONFIG_ARCH_LEDS -- board_autoled_on() is called from
* interrupt handlers and from assertion handling, where a bus transaction
* is not permissible. So this board provides the user LED interface only
* (CONFIG_USERLED) and does not select ARCH_HAVE_LEDS.
*/
/* LED index values for use with board_userled() */
#define BOARD_LED1 0
#define BOARD_NLEDS 1
#define BOARD_LED_GREEN BOARD_LED1
/* LED bits for use with board_userled_all() */
#define BOARD_LED1_BIT (1 << BOARD_LED1)
/* BUTTON definitions *******************************************************/
/* The board has two physical buttons, BOOT and RESET. BOOT is also wired
* to GPIO 45, active low, so once NuttX is running it can be read as an
* ordinary user button. pico-sdk calls that pin the board's USER_SW_PIN.
* RESET is not visible as a GPIO.
*/
#define NUM_BUTTONS 1
#define BUTTON_USER1 0
#define BUTTON_USER1_BIT (1 << BUTTON_USER1)
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: rp23xx_boardearlyinitialize
*
* Description:
*
****************************************************************************/
void rp23xx_boardearlyinitialize(void);
/****************************************************************************
* Name: rp23xx_boardinitialize
*
* Description:
*
****************************************************************************/
void rp23xx_boardinitialize(void);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_BOARD_H */

View file

@ -0,0 +1,139 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/include/rp23xx_extra_gpio.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_EXTRA_GPIO_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_EXTRA_GPIO_H
/****************************************************************************
* These functions control the GPIO pins on the CYW43439 wireless chip, not
* the GPIO pins of the RP2350. The pin assignments for the Pimoroni Pico
* Plus 2 W are:
*
* GPIO 0 - output - controls the onboard LED
* GPIO 1 - output - controls the onboard voltage regulator mode.
* GPIO 2 - input - Reads as non-zero if power supplied by USB or VBUS pin.
*
* These only work once the wireless chip has been activated, which happens
* when the wlan0 network interface is brought up. Until then every access
* fails with -EIO.
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/wireless/ieee80211/bcmf_gpio.h>
#include <nuttx/wireless/ieee80211/bcmf_gspi.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define RP23XX_EXTRA_GPIO_NUM 3 /* Number of extra GPIO pins */
#define RP23XX_EXTRA_GPIO_LED 0 /* Onboard LED */
#define RP23XX_EXTRA_GPIO_VREG 1 /* Voltage regulator mode */
#define RP23XX_EXTRA_GPIO_VBUS 2 /* VBUS present */
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
EXTERN gspi_dev_t *g_cyw43439;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: rp23xx_extra_gpio_put
*
* Description:
* Change the state of a GPIO pin on the CYW43439.
*
* Returned Value:
* OK on success, or a negated errno. -EIO means the wireless chip is not
* running yet, which is the case until wlan0 has been brought up.
*
****************************************************************************/
static inline int rp23xx_extra_gpio_put(uint32_t gpio, bool value)
{
DEBUGASSERT(gpio < RP23XX_EXTRA_GPIO_NUM);
if (g_cyw43439 == NULL)
{
return -EIO;
}
return bcmf_set_gpio(g_cyw43439->priv, gpio, value);
}
/****************************************************************************
* Name: rp23xx_extra_gpio_get
*
* Description:
* Read the state of a GPIO pin on the CYW43439.
*
* Returned Value:
* OK on success, or a negated errno. -EIO means the wireless chip is not
* running yet, which is the case until wlan0 has been brought up.
*
****************************************************************************/
static inline int rp23xx_extra_gpio_get(uint32_t gpio, bool *value)
{
DEBUGASSERT(gpio < RP23XX_EXTRA_GPIO_NUM);
if (g_cyw43439 == NULL)
{
return -EIO;
}
return bcmf_get_gpio(g_cyw43439->priv, gpio, value);
}
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_EXTRA_GPIO_H */

View file

@ -0,0 +1,72 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/include/rp23xx_i2cdev.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_I2CDEV_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_I2CDEV_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_i2cdev_initialize
*
* Description:
* Initialize i2c driver and register the /dev/i2c device.
*
****************************************************************************/
#ifdef CONFIG_RP23XX_I2C_DRIVER
int board_i2cdev_initialize(int bus);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_I2CDEV_H */

View file

@ -0,0 +1,72 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/include/rp23xx_i2sdev.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_I2SDEV_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_I2SDEV_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_i2sdev_initialize
*
* Description:
* Initialize i2s driver and register the /dev/audio/pcm0 device.
*
****************************************************************************/
#ifdef CONFIG_RP23XX_I2S
int board_i2sdev_initialize(int bus);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_I2SDEV_H */

View file

@ -0,0 +1,69 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/include/rp23xx_spidev.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_SPIDEV_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_SPIDEV_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_spidev_initialize
*
* Description:
* Initialize spi driver and register the /dev/spi device.
*
****************************************************************************/
int board_spidev_initialize(int bus);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_SPIDEV_H */

View file

@ -0,0 +1,85 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/include/rp23xx_spisd.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_SPISD_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_SPISD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_spisd_initialize
*
* Description:
* Initialize the SPI-based SD card.
*
****************************************************************************/
#ifdef CONFIG_RP23XX_SPISD
int board_spisd_initialize(int minor, int bus);
#endif
/****************************************************************************
* Name: board_spisd_status
*
* Description:
* Get the status whether SD Card is present or not.
*
****************************************************************************/
#ifdef CONFIG_RP23XX_SPISD
uint8_t board_spisd_status(struct spi_dev_s *dev, uint32_t devid);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_INCLUDE_RP23XX_SPISD_H */

View file

@ -0,0 +1,43 @@
############################################################################
# boards/arm/rp23xx/pimoroni-pico-plus-2-w/scripts/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/tools/rp23xx/Config.mk
include $(TOPDIR)/arch/arm/src/armv8-m/Toolchain.defs
ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y)
LDSCRIPT = memmap_default.ld
else ifeq ($(CONFIG_BOOT_COPYTORAM),y)
LDSCRIPT = memmap_copy_to_ram.ld
else
LDSCRIPT = memmap_no_flash.ld
endif
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
AFLAGS := $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048

View file

@ -0,0 +1,340 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/scripts/memmap_copy_to_ram.ld
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/* Based on GCC ARM embedded samples.
Defines the following symbols for use by code:
__exidx_start
__exidx_end
__etext
__data_start__
__preinit_array_start
__preinit_array_end
__init_array_start
__init_array_end
__fini_array_start
__fini_array_end
__data_end__
__bss_start__
__bss_end__
__end__
end
__HeapLimit
__StackLimit
__StackTop
__stack (== StackTop)
*/
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 16384k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k
SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k
}
ENTRY(_entry_point)
SECTIONS
{
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
and checksummed. It is usually built by the boot_stage2 target
in the Raspberry Pi Pico SDK
*/
.flash_begin : {
__flash_binary_start = .;
} > FLASH
/* The bootrom will enter the image at the point indicated in your
IMAGE_DEF, which is usually the reset handler of your vector table.
The debugger will use the ELF entry point, which is the _entry_point
symbol, and in our case is *different from the bootrom's entry point.*
This is used to go back through the bootrom on debugger launches only,
to perform the same initial flash setup that would be performed on a
cold boot.
*/
.flashtext : {
__logical_binary_start = .;
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.embedded_block))
__embedded_block_end = .;
KEEP (*(.reset))
. = ALIGN(4);
} > FLASH
/* Note the boot2 section is optional, and should be discarded if there is
no reference to it *inside* the binary, as it is not called by the
bootrom. (The bootrom performs a simple best-effort XIP setup and
leaves it to the binary to do anything more sophisticated.) However
there is still a size limit of 256 bytes, to ensure the boot2 can be
stored in boot RAM.
Really this is a "XIP setup function" -- the name boot2 is historic and
refers to its dual-purpose on RP2040, where it also handled vectoring
from the bootrom into the user image.
*/
.boot2 : {
__boot2_start__ = .;
*(.boot2)
__boot2_end__ = .;
} > FLASH
ASSERT(__boot2_end__ - __boot2_start__ <= 256,
"ERROR: Pico second stage bootloader must be no more than 256 bytes in size")
.rodata : {
/* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
. = ALIGN(4);
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
.binary_info :
{
KEEP(*(.binary_info.keep.*))
*(.binary_info.*)
} > FLASH
__binary_info_end = .;
. = ALIGN(4);
/* Vector table goes first in RAM, to avoid large alignment hole */
.ram_vector_table (NOLOAD): {
*(.ram_vector_table)
} > RAM
.uninitialized_data (NOLOAD): {
. = ALIGN(4);
*(.uninitialized_data*)
} > RAM
.text : {
__ram_text_start__ = .;
*(.init)
*(.text*)
*(.fini)
/* Pull all c'tors into .text */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* Followed by destructors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.eh_frame*)
. = ALIGN(4);
__ram_text_end__ = .;
} > RAM AT> FLASH
__ram_text_source__ = LOADADDR(.text);
. = ALIGN(4);
.data : {
__data_start__ = .;
*(vtable)
*(.time_critical*)
. = ALIGN(4);
*(.rodata*)
*(.srodata*)
. = ALIGN(4);
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__mutex_array_start = .);
KEEP(*(SORT(.mutex_array.*)))
KEEP(*(.mutex_array))
PROVIDE_HIDDEN (__mutex_array_end = .);
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.jcr)
. = ALIGN(4);
} > RAM AT> FLASH
.tdata : {
. = ALIGN(4);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
} > RAM AT> FLASH
PROVIDE(__data_end__ = .);
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);
.tbss (NOLOAD) : {
. = ALIGN(4);
__bss_start__ = .;
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
__tls_end = .;
} > RAM
.bss : {
. = ALIGN(4);
__tbss_end = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
PROVIDE(__global_pointer$ = . + 2K);
*(.sbss*)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
} > RAM
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
*(.scratch_x.*)
. = ALIGN(4);
__scratch_x_end__ = .;
} > SCRATCH_X AT > FLASH
__scratch_x_source__ = LOADADDR(.scratch_x);
.scratch_y : {
__scratch_y_start__ = .;
*(.scratch_y.*)
. = ALIGN(4);
__scratch_y_end__ = .;
} > SCRATCH_Y AT > FLASH
__scratch_y_source__ = LOADADDR(.scratch_y);
/* .stack*_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later
*
* stack1 section may be empty/missing if platform_launch_core1 is not used */
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
* stack is not used then all of SCRATCH_X is free.
*/
.stack1_dummy (NOLOAD):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (NOLOAD):
{
KEEP(*(.stack*))
} > SCRATCH_Y
.flash_end : {
KEEP(*(.embedded_end_block*))
PROVIDE(__flash_binary_end = .);
} > FLASH =0xaa
/* stack limit is poorly named, but historically is maximum heap ptr */
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* picolibc and LLVM */
PROVIDE (__heap_start = __end__);
PROVIDE (__heap_end = __HeapLimit);
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
/* llvm-libc */
PROVIDE (_end = __end__);
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
/* todo assert on extra code */
}

View file

@ -0,0 +1,353 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/scripts/memmap_default.ld
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/* Based on GCC ARM embedded samples.
Defines the following symbols for use by code:
__exidx_start
__exidx_end
__etext
__data_start__
__preinit_array_start
__preinit_array_end
__init_array_start
__init_array_end
__fini_array_start
__fini_array_end
__data_end__
__bss_start__
__bss_end__
__end__
end
__HeapLimit
__StackLimit
__StackTop
__stack (== StackTop)
*/
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 16384k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k
SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k
}
ENTRY(_entry_point)
SECTIONS
{
.flash_begin : {
__flash_binary_start = .;
} > FLASH
/* The bootrom will enter the image at the point indicated in your
IMAGE_DEF, which is usually the reset handler of your vector table.
The debugger will use the ELF entry point, which is the _entry_point
symbol, and in our case is *different from the bootrom's entry point.*
This is used to go back through the bootrom on debugger launches only,
to perform the same initial flash setup that would be performed on a
cold boot.
*/
.text : {
__logical_binary_start = .;
_stext = ABSOLUTE(.);
KEEP (*(.vectors))
LONG(0xffffded3)
LONG(0x10210142)
LONG(0x000001ff)
LONG(0x00000000)
LONG(0xab123579)
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.embedded_block))
__embedded_block_end = .;
KEEP (*(.reset))
/* TODO revisit this now memset/memcpy/float in ROM */
/* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
* FLASH ... we will include any thing excluded here in .data below by default */
*(.init)
*libgcc.a:cmse_nonsecure_call.o
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
*(.fini)
/* Pull all c'tors into .text */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* Followed by destructors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.eh_frame*)
. = ALIGN(4);
_etext = ABSOLUTE(.);
} > FLASH
/* Note the boot2 section is optional, and should be discarded if there is
no reference to it *inside* the binary, as it is not called by the
bootrom. (The bootrom performs a simple best-effort XIP setup and
leaves it to the binary to do anything more sophisticated.) However
there is still a size limit of 256 bytes, to ensure the boot2 can be
stored in boot RAM.
Really this is a "XIP setup function" -- the name boot2 is historic and
refers to its dual-purpose on RP2040, where it also handled vectoring
from the bootrom into the user image.
*/
.boot2 : {
__boot2_start__ = .;
*(.boot2)
__boot2_end__ = .;
} > FLASH
ASSERT(__boot2_end__ - __boot2_start__ <= 256,
"ERROR: Pico second stage bootloader must be no more than 256 bytes in size")
.rodata : {
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
*(.srodata*)
. = ALIGN(4);
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
. = ALIGN(4);
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
.binary_info :
{
KEEP(*(.binary_info.keep.*))
*(.binary_info.*)
} > FLASH
_eronly = ABSOLUTE(.);
__binary_info_end = .;
. = ALIGN(4);
.ram_vector_table (NOLOAD): {
*(.ram_vector_table)
} > RAM
.uninitialized_data (NOLOAD): {
. = ALIGN(4);
*(.uninitialized_data*)
} > RAM
.data : {
__data_start__ = .;
_sdata = ABSOLUTE(.);
*(vtable)
*(.time_critical*)
/* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
*(.text*)
. = ALIGN(4);
*(.rodata*)
. = ALIGN(4);
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__mutex_array_start = .);
KEEP(*(SORT(.mutex_array.*)))
KEEP(*(.mutex_array))
PROVIDE_HIDDEN (__mutex_array_end = .);
*(.jcr)
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > RAM AT> FLASH
.tdata : {
_stdata = ABSOLUTE(.);
. = ALIGN(4);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
_etdata = ABSOLUTE(.);
} > RAM AT> FLASH
PROVIDE(__data_end__ = .);
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);
.tbss (NOLOAD) : {
_stbss = ABSOLUTE(.);
. = ALIGN(4);
__bss_start__ = .;
_sbss = ABSOLUTE(.);
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
__tls_end = .;
_etbss = ABSOLUTE(.);
} > RAM
.bss (NOLOAD) : {
. = ALIGN(4);
__tbss_end = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
PROVIDE(__global_pointer$ = . + 2K);
*(.sbss*)
. = ALIGN(4);
__bss_end__ = .;
_ebss = ABSOLUTE(.);
} > RAM
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
} > RAM
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
*(.scratch_x.*)
. = ALIGN(4);
__scratch_x_end__ = .;
} > SCRATCH_X AT > FLASH
__scratch_x_source__ = LOADADDR(.scratch_x);
.scratch_y : {
__scratch_y_start__ = .;
*(.scratch_y.*)
. = ALIGN(4);
__scratch_y_end__ = .;
} > SCRATCH_Y AT > FLASH
__scratch_y_source__ = LOADADDR(.scratch_y);
/* .stack*_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later
*
* stack1 section may be empty/missing if platform_launch_core1 is not used */
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
* stack is not used then all of SCRATCH_X is free.
*/
.stack1_dummy (NOLOAD):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (NOLOAD):
{
KEEP(*(.stack*))
} > SCRATCH_Y
.flash_end : {
KEEP(*(.embedded_end_block*))
PROVIDE(__flash_binary_end = .);
} > FLASH =0xaa
/* stack limit is poorly named, but historically is maximum heap ptr */
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* picolibc and LLVM */
PROVIDE (__heap_start = __end__);
PROVIDE (__heap_end = __HeapLimit);
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
/* llvm-libc */
PROVIDE (_end = __end__);
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
/* todo assert on extra code */
}

View file

@ -0,0 +1,294 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/scripts/memmap_no_flash.ld
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/* Based on GCC ARM embedded samples.
Defines the following symbols for use by code:
__exidx_start
__exidx_end
__etext
__data_start__
__preinit_array_start
__preinit_array_end
__init_array_start
__init_array_end
__fini_array_start
__fini_array_end
__data_end__
__bss_start__
__bss_end__
__end__
end
__HeapLimit
__StackLimit
__StackTop
__stack (== StackTop)
*/
MEMORY
{
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k
SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k
}
ENTRY(_entry_point)
SECTIONS
{
/* Note unlike RP2040, we start the image with a vector table even for
NO_FLASH builds. On Arm, the bootrom expects a VT at the start of the
image by default; on RISC-V, the default is to enter the image at its
lowest address, so an IMAGEDEF item is required to specify the
nondefault entry point. */
.text : {
__logical_binary_start = .;
_stext = ABSOLUTE(.);
/* Vectors require 512-byte alignment on v8-M when >48 IRQs are used,
so we would waste RAM if the vector table were not at the
start. */
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.embedded_block))
__embedded_block_end = .;
__reset_start = .;
KEEP (*(.reset))
__reset_end = .;
*(.time_critical*)
*(.text*)
. = ALIGN(4);
*(.init)
*(.fini)
/* Pull all c'tors into .text */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* Followed by destructors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.eh_frame*)
} > RAM
.rodata : {
. = ALIGN(4);
*(.rodata*)
*(.srodata*)
. = ALIGN(4);
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
. = ALIGN(4);
} > RAM
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > RAM
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > RAM
__exidx_end = .;
/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
.binary_info :
{
KEEP(*(.binary_info.keep.*))
*(.binary_info.*)
} > RAM
__binary_info_end = .;
. = ALIGN(4);
.data : {
__data_start__ = .;
*(vtable)
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__mutex_array_start = .);
KEEP(*(SORT(.mutex_array.*)))
KEEP(*(.mutex_array))
PROVIDE_HIDDEN (__mutex_array_end = .);
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.jcr)
. = ALIGN(4);
} > RAM
.tdata : {
. = ALIGN(4);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
} > RAM
PROVIDE(__data_end__ = .);
.uninitialized_data (NOLOAD): {
. = ALIGN(4);
*(.uninitialized_data*)
} > RAM
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);
_etext = LOADADDR(.data);
.tbss (NOLOAD) : {
. = ALIGN(4);
__bss_start__ = .;
_stbss = ABSOLUTE(.);
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
__tls_end = .;
_etbss = ABSOLUTE(.);
} > RAM
.bss (NOLOAD) : {
. = ALIGN(4);
_sbss = ABSOLUTE(.);
__tbss_end = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
PROVIDE(__global_pointer$ = . + 2K);
*(.sbss*)
. = ALIGN(4);
__bss_end__ = .;
_ebss = ABSOLUTE(.);
} > RAM
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
} > RAM
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
*(.scratch_x.*)
. = ALIGN(4);
__scratch_x_end__ = .;
} > SCRATCH_X
__scratch_x_source__ = LOADADDR(.scratch_x);
.scratch_y : {
__scratch_y_start__ = .;
*(.scratch_y.*)
. = ALIGN(4);
__scratch_y_end__ = .;
} > SCRATCH_Y
__scratch_y_source__ = LOADADDR(.scratch_y);
/* .stack*_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later
*
* stack1 section may be empty/missing if platform_launch_core1 is not used */
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
* stack is not used then all of SCRATCH_X is free.
*/
.stack1_dummy (NOLOAD):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (NOLOAD):
{
KEEP(*(.stack*))
} > SCRATCH_Y
/* stack limit is poorly named, but historically is maximum heap ptr */
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* picolibc and LLVM */
PROVIDE (__heap_start = __end__);
PROVIDE (__heap_end = __HeapLimit);
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
/* llvm-libc */
PROVIDE (_end = __end__);
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
/* todo assert on extra code */
}

View file

@ -0,0 +1,66 @@
# ##############################################################################
# boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
set(SRCS rp23xx_boardinitialize.c rp23xx_bringup.c)
if(CONFIG_DEV_GPIO)
list(APPEND SRCS rp23xx_gpio.c)
endif()
# This board has no LED on an RP2350 pin -- its only LED hangs off the CYW43439,
# and reaching it means a gSPI bus transaction. That rules out
# CONFIG_ARCH_LEDS, whose board_autoled_on() is called from interrupt handlers
# and from assertion handling, so there is no rp23xx_autoleds.c. It also means
# there is no LED at all without the wireless chip. See rp23xx_userleds.c.
if(CONFIG_ARCH_LEDS)
message(
FATAL_ERROR
"CONFIG_ARCH_LEDS is not supported on this board: the LED hangs off the "
"CYW43439 and cannot be driven from interrupt context. "
"Use CONFIG_USERLED instead.")
endif()
if(CONFIG_RP23XX_INFINEON_CYW43439)
list(APPEND SRCS rp23xx_userleds.c)
endif()
if(CONFIG_ARCH_BUTTONS)
list(APPEND SRCS rp23xx_buttons.c)
endif()
# rp23xx_firmware.c, which carries the CYW43439 firmware blob, is built from
# boards/arm/rp23xx/common/src.
target_sources(board PRIVATE ${SRCS})
if(CONFIG_BOOT_RUNFROMFLASH)
set_property(GLOBAL PROPERTY LD_SCRIPT
"${NUTTX_BOARD_DIR}/scripts/memmap_default.ld")
elseif(CONFIG_BOOT_COPYTORAM)
set_property(
GLOBAL PROPERTY LD_SCRIPT
"${NUTTX_BOARD_DIR}/scripts/memmap_copy_to_ram.ld")
else()
set_property(GLOBAL PROPERTY LD_SCRIPT
"${NUTTX_BOARD_DIR}/scripts/memmap_no_flash.ld")
endif()

View file

@ -0,0 +1,95 @@
############################################################################
# boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(TOPDIR)/Make.defs
CSRCS = rp23xx_boardinitialize.c
CSRCS += rp23xx_bringup.c
ifeq ($(CONFIG_DEV_GPIO),y)
CSRCS += rp23xx_gpio.c
endif
# This board has no LED on an RP2350 pin -- its only LED hangs off the
# CYW43439, and reaching it means a gSPI bus transaction. That rules out
# CONFIG_ARCH_LEDS, whose board_autoled_on() is called from interrupt handlers
# and from assertion handling, so there is no rp23xx_autoleds.c. It also
# means there is no LED at all without the wireless chip.
# See src/rp23xx_userleds.c.
ifeq ($(CONFIG_ARCH_LEDS),y)
$(error CONFIG_ARCH_LEDS is not supported on this board: the LED hangs off \
the CYW43439 and cannot be driven from interrupt context. \
Use CONFIG_USERLED instead)
endif
ifeq ($(CONFIG_RP23XX_INFINEON_CYW43439),y)
CSRCS += rp23xx_userleds.c
endif
ifeq ($(CONFIG_ARCH_BUTTONS),y)
CSRCS += rp23xx_buttons.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board
############################################################################
# The rules below stage the cyw43439 blob out of pico_sdk so that the
# .incbin in rp23xx_firmware.c can pick it up.
#
# rp23xx_firmware.c lives in the *common* src directory, which is both on the
# include path (added by common/src/Make.defs) and reachable via VPATH, so the
# blob is staged next to it there. This mirrors what rp2040 does for the
# Raspberry Pi Pico W.
############################################################################
ifeq ($(CONFIG_IEEE80211_INFINEON_CYW43439),y)
FIRMWARE = src$(DELIM)cyw43439.firmware.image
# --- If PICO_SDK_PATH is not defined set a dummy path. --------------------
# See comment below.
ifeq ($(PICO_SDK_PATH),)
PICO_SDK_PATH = /tmp
endif
FIRMWARE_SRC := $(patsubst "%",%,$(CONFIG_CYW43439_FIRMWARE_BIN_PATH))
# --- If the firmware source does not exist create a dummy file. -----------
# NuttX built with the cyw43439 driver will not talk to the wireless
# chip when built with this dummy file. The sole purpose of adding
# this dummy is so the CI build tests will not fail.
$(FIRMWARE_SRC):
$(Q) mkdir -p `dirname $(FIRMWARE_SRC)`
$(Q) echo "dummy" >$(FIRMWARE_SRC)
$(FIRMWARE): $(FIRMWARE_SRC)
$(call CATFILE, $(FIRMWARE), $(FIRMWARE_SRC))
src$(DELIM)rp23xx_firmware.c: $(FIRMWARE)
distclean::
$(call DELFILE, $(FIRMWARE))
endif

View file

@ -0,0 +1,115 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/rp23xx_boardinitialize.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/debug.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "rp23xx_gpio.h"
#ifdef CONFIG_RP23XX_PSRAM
#include "rp23xx_psram.h"
#endif
#ifdef CONFIG_ARCH_BOARD_COMMON
#include "rp23xx_common_initialize.h"
#endif /* CONFIG_ARCH_BOARD_COMMON */
#include "rp23xx_pico.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: rp23xx_boardearlyinitialize
*
* Description:
*
****************************************************************************/
void rp23xx_boardearlyinitialize(void)
{
#ifdef CONFIG_ARCH_BOARD_COMMON
rp23xx_common_earlyinitialize();
#endif
/* --- Place any board specific early initialization here --- */
/* Nothing to do for the LED: it hangs off the CYW43439 wireless chip
* rather than an RP2350 pin, and cannot be touched this early. See
* src/rp23xx_userleds.c.
*/
}
/****************************************************************************
* Name: rp23xx_boardinitialize
*
* Description:
*
****************************************************************************/
void rp23xx_boardinitialize(void)
{
#ifdef CONFIG_ARCH_BOARD_COMMON
rp23xx_common_initialize();
#endif
#ifdef CONFIG_RP23XX_PSRAM
rp23xx_psramconfig();
#endif
/* --- Place any board specific initialization here --- */
}
/****************************************************************************
* Name: board_late_initialize
*
* Description:
* If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
* initialization call will be performed in the boot-up sequence to a
* function called board_late_initialize(). board_late_initialize() will be
* called immediately after up_initialize() is called and just before the
* initial application is started. This additional initialization phase
* may be used, for example, to initialize board-specific device drivers.
*
****************************************************************************/
#ifdef CONFIG_BOARD_LATE_INITIALIZE
void board_late_initialize(void)
{
rp23xx_bringup();
}
#endif

View file

@ -0,0 +1,132 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/rp23xx_bringup.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/debug.h>
#include <stddef.h>
#include <errno.h>
#include <nuttx/fs/fs.h>
#include <arch/board/board.h>
#include "rp23xx_pico.h"
#ifdef CONFIG_ARCH_BOARD_COMMON
#include "rp23xx_common_bringup.h"
#endif /* CONFIG_ARCH_BOARD_COMMON */
#ifdef CONFIG_USERLED
# include <nuttx/leds/userled.h>
#endif
#ifdef CONFIG_INPUT_BUTTONS
# include <nuttx/input/buttons.h>
#endif
#ifdef CONFIG_RP23XX_INFINEON_CYW43439
# include "rp23xx_cyw43439.h"
#endif
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef CONFIG_RP23XX_INFINEON_CYW43439
gspi_dev_t *g_cyw43439 = NULL;
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: rp23xx_bringup
****************************************************************************/
int rp23xx_bringup(void)
{
int ret;
UNUSED(ret);
#ifdef CONFIG_ARCH_BOARD_COMMON
ret = rp23xx_common_bringup();
if (ret < 0)
{
return ret;
}
#endif /* CONFIG_ARCH_BOARD_COMMON */
/* --- Place any board specific bringup code here --- */
#ifdef CONFIG_RP23XX_INFINEON_CYW43439
/* Bring up the CYW43439 wireless chip. This registers the wlan0 network
* device; the chip's firmware is not downloaded until wlan0 is brought up.
*
* Do this before the LED driver, which drives a GPIO on this chip.
*/
g_cyw43439 = rp23xx_cyw_setup(GPIO_CYW43439_ON,
GPIO_CYW43439_CS,
GPIO_CYW43439_DATA,
GPIO_CYW43439_CLOCK,
GPIO_CYW43439_DATA);
if (g_cyw43439 == NULL)
{
syslog(LOG_ERR,
"ERROR: failed to initialize the cyw43439 (WiFi chip): %d\n",
errno);
}
#endif
#if defined(CONFIG_USERLED_LOWER) && defined(CONFIG_RP23XX_INFINEON_CYW43439)
/* Register the LED driver. The LED sits on the wireless chip, so there is
* nothing to register without it.
*/
ret = userled_lower_initialize("/dev/userleds");
if (ret < 0)
{
syslog(LOG_ERR, \
"ERROR: userled_lower_initialize() failed: %d\n", ret);
}
#endif
#ifdef CONFIG_INPUT_BUTTONS
/* Register the BUTTON driver */
ret = btn_lower_initialize("/dev/buttons");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
}
#endif
return OK;
}

View file

@ -0,0 +1,187 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/rp23xx_buttons.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "rp23xx_gpio.h"
#include "rp23xx_pico.h"
#if defined(CONFIG_ARCH_BUTTONS)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if defined(CONFIG_INPUT_BUTTONS) && !defined(CONFIG_ARCH_IRQBUTTONS)
# error "The NuttX Buttons Driver depends on IRQ support to work!\n"
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/* Pin configuration for the board's BOOT button, which doubles as a user
* button once NuttX is running.
*/
static const uint32_t g_buttons[NUM_BUTTONS] =
{
GPIO_BTN_USER1
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_button_initialize
*
* Description:
* board_button_initialize() must be called to initialize button resources.
* After that, board_buttons() may be called to collect the current state
* of all buttons or board_button_irq() may be called to register button
* interrupt handlers.
*
****************************************************************************/
uint32_t board_button_initialize(void)
{
int i;
/* Configure the GPIO pins as inputs. And we will use interrupts */
for (i = 0; i < NUM_BUTTONS; i++)
{
/* Initialize input pin */
rp23xx_gpio_init(g_buttons[i]);
/* The button shorts the pin to ground, so pull it up.
*
* Do not be tempted to leave the pin floating or pulled down here:
* erratum RP2350-E9 means a floating Bank 0 input leaks enough current
* to sit at about 2.2 V, and the internal pull-down is far too weak to
* overcome it. The pull-up is unaffected by the erratum.
*
* pull-up = true : pull-down = false
*/
rp23xx_gpio_set_pulls(g_buttons[i], true, false);
}
return NUM_BUTTONS;
}
/****************************************************************************
* Name: board_buttons
****************************************************************************/
uint32_t board_buttons(void)
{
uint32_t ret = 0;
int i;
/* Check that state of each key */
for (i = 0; i < NUM_BUTTONS; i++)
{
/* A LOW value means that the key is pressed. */
bool released = rp23xx_gpio_get(g_buttons[i]);
/* Accumulate the set of depressed (not released) keys */
if (!released)
{
ret |= (1 << i);
}
}
return ret;
}
/****************************************************************************
* Button support.
*
* Description:
* board_button_initialize() must be called to initialize button resources.
* After that, board_buttons() may be called to collect the current state
* of all buttons or board_button_irq() may be called to register button
* interrupt handlers.
*
* After board_button_initialize() has been called, board_buttons() may be
* called to collect the state of all buttons. board_buttons() returns
* an 32-bit bit set with each bit associated with a button. See the
* BUTTON_*_BIT definitions in board.h for the meaning of each bit.
*
* board_button_irq() may be called to register an interrupt handler that
* will be called when a button is depressed or released. The ID value is
* a button enumeration value that uniquely identifies a button resource.
* See the BUTTON_* definitions in board.h for the meaning of enumeration
* value.
*
****************************************************************************/
#ifdef CONFIG_ARCH_IRQBUTTONS
int board_button_irq(int id, xcpt_t irqhandler, void *arg)
{
int ret = -EINVAL;
/* The following should be atomic */
if (id >= MIN_IRQBUTTON && id <= MAX_IRQBUTTON)
{
/* Make sure the interrupt is disabled */
rp23xx_gpio_disable_irq(g_buttons[id]);
/* Attach the interrupt handler */
ret = rp23xx_gpio_irq_attach(g_buttons[id],
RP23XX_GPIO_INTR_EDGE_LOW,
irqhandler,
arg);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: irq_attach() failed: %d\n", ret);
return ret;
}
/* Enable interruption for this pin */
rp23xx_gpio_enable_irq(g_buttons[id]);
}
return ret;
}
#endif
#endif /* CONFIG_ARCH_BUTTONS */

View file

@ -0,0 +1,396 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/rp23xx_gpio.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <syslog.h>
#include <nuttx/irq.h>
#include <arch/irq.h>
#include <assert.h>
#include <nuttx/debug.h>
#include <nuttx/ioexpander/gpio.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "chip.h"
#include "rp23xx_gpio.h"
#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
/* Output pins.
*
* There is no onboard LED on an RP2350 pin on this board -- it hangs off the
* CYW43439 -- so this is just a free header pin. Note that GPIO 23, 24, 25
* and 29 are wired to the wireless chip and must not be used here.
*/
#define GPIO_OUT1 2
/* Input pins.
*/
#define GPIO_IN1 6
/* Interrupt pins.
*/
#define GPIO_IRQPIN1 14
/****************************************************************************
* Private Types
****************************************************************************/
struct rp23xxgpio_dev_s
{
struct gpio_dev_s gpio;
uint8_t id;
};
struct rp23xxgpint_dev_s
{
struct rp23xxgpio_dev_s rp23xxgpio;
pin_interrupt_t callback;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#if BOARD_NGPIOOUT > 0
static int gpout_read(struct gpio_dev_s *dev, bool *value);
static int gpout_write(struct gpio_dev_s *dev, bool value);
#endif
#if BOARD_NGPIOIN > 0
static int gpin_read(struct gpio_dev_s *dev, bool *value);
#endif
#if BOARD_NGPIOINT > 0
static int gpint_read(struct gpio_dev_s *dev, bool *value);
static int gpint_attach(struct gpio_dev_s *dev,
pin_interrupt_t callback);
static int gpint_enable(struct gpio_dev_s *dev, bool enable);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
#if BOARD_NGPIOOUT > 0
static const struct gpio_operations_s gpout_ops =
{
.go_read = gpout_read,
.go_write = gpout_write,
.go_attach = NULL,
.go_enable = NULL,
};
/* This array maps the GPIO pins used as OUTPUT */
static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] =
{
GPIO_OUT1
};
static struct rp23xxgpio_dev_s g_gpout[BOARD_NGPIOOUT];
#endif
#if BOARD_NGPIOIN > 0
static const struct gpio_operations_s gpin_ops =
{
.go_read = gpin_read,
.go_write = NULL,
.go_attach = NULL,
.go_enable = NULL,
};
/* This array maps the GPIO pins used as INTERRUPT INPUTS */
static const uint32_t g_gpioinputs[BOARD_NGPIOIN] =
{
GPIO_IN1
};
static struct rp23xxgpio_dev_s g_gpin[BOARD_NGPIOIN];
#endif
#if BOARD_NGPIOINT > 0
static const struct gpio_operations_s gpint_ops =
{
.go_read = gpint_read,
.go_write = NULL,
.go_attach = gpint_attach,
.go_enable = gpint_enable,
};
/* This array maps the GPIO pins used as INTERRUPT INPUTS */
static const uint32_t g_gpiointinputs[BOARD_NGPIOINT] =
{
GPIO_IRQPIN1,
};
static struct rp23xxgpint_dev_s g_gpint[BOARD_NGPIOINT];
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: gpout_read
****************************************************************************/
#if BOARD_NGPIOOUT > 0
static int gpout_read(struct gpio_dev_s *dev, bool *value)
{
struct rp23xxgpio_dev_s *rp23xxgpio =
(struct rp23xxgpio_dev_s *)dev;
DEBUGASSERT(rp23xxgpio != NULL && value != NULL);
DEBUGASSERT(rp23xxgpio->id < BOARD_NGPIOOUT);
gpioinfo("Reading...\n");
*value = rp23xx_gpio_get(g_gpiooutputs[rp23xxgpio->id]);
return OK;
}
/****************************************************************************
* Name: gpout_write
****************************************************************************/
static int gpout_write(struct gpio_dev_s *dev, bool value)
{
struct rp23xxgpio_dev_s *rp23xxgpio =
(struct rp23xxgpio_dev_s *)dev;
DEBUGASSERT(rp23xxgpio != NULL);
DEBUGASSERT(rp23xxgpio->id < BOARD_NGPIOOUT);
gpioinfo("Writing %d\n", (int)value);
rp23xx_gpio_put(g_gpiooutputs[rp23xxgpio->id], value);
return OK;
}
#endif
/****************************************************************************
* Name: gpin_read
****************************************************************************/
#if BOARD_NGPIOIN > 0
static int gpin_read(struct gpio_dev_s *dev, bool *value)
{
struct rp23xxgpio_dev_s *rp23xxgpio =
(struct rp23xxgpio_dev_s *)dev;
DEBUGASSERT(rp23xxgpio != NULL && value != NULL);
DEBUGASSERT(rp23xxgpio->id < BOARD_NGPIOIN);
gpioinfo("Reading... pin %d\n", (int)g_gpioinputs[rp23xxgpio->id]);
*value = rp23xx_gpio_get(g_gpioinputs[rp23xxgpio->id]);
return OK;
}
#endif
/****************************************************************************
* Name: rp23xxgpio_interrupt
****************************************************************************/
#if BOARD_NGPIOINT > 0
static int rp23xxgpio_interrupt(int irq, void *context, void *arg)
{
struct rp23xxgpint_dev_s *rp23xxgpint =
(struct rp23xxgpint_dev_s *)arg;
DEBUGASSERT(rp23xxgpint != NULL && rp23xxgpint->callback != NULL);
gpioinfo("Interrupt! callback=%p\n", rp23xxgpint->callback);
rp23xxgpint->callback(&rp23xxgpint->rp23xxgpio.gpio,
rp23xxgpint->rp23xxgpio.id);
return OK;
}
/****************************************************************************
* Name: gpint_read
****************************************************************************/
static int gpint_read(struct gpio_dev_s *dev, bool *value)
{
struct rp23xxgpint_dev_s *rp23xxgpint =
(struct rp23xxgpint_dev_s *)dev;
DEBUGASSERT(rp23xxgpint != NULL && value != NULL);
DEBUGASSERT(rp23xxgpint->rp23xxgpio.id < BOARD_NGPIOINT);
gpioinfo("Reading int pin...\n");
*value = rp23xx_gpio_get(g_gpiointinputs[rp23xxgpint->rp23xxgpio.id]);
return OK;
}
/****************************************************************************
* Name: gpint_attach
****************************************************************************/
static int gpint_attach(struct gpio_dev_s *dev,
pin_interrupt_t callback)
{
struct rp23xxgpint_dev_s *rp23xxgpint =
(struct rp23xxgpint_dev_s *)dev;
int irq = g_gpiointinputs[rp23xxgpint->rp23xxgpio.id];
int ret;
gpioinfo("Attaching the callback\n");
/* Make sure the interrupt is disabled */
rp23xx_gpio_disable_irq(irq);
ret = rp23xx_gpio_irq_attach(irq,
RP23XX_GPIO_INTR_EDGE_LOW,
rp23xxgpio_interrupt,
&g_gpint[rp23xxgpint->rp23xxgpio.id]);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: gpint_attach() failed: %d\n", ret);
return ret;
}
gpioinfo("Attach %p\n", callback);
rp23xxgpint->callback = callback;
return OK;
}
/****************************************************************************
* Name: gpint_enable
****************************************************************************/
static int gpint_enable(struct gpio_dev_s *dev, bool enable)
{
struct rp23xxgpint_dev_s *rp23xxgpint =
(struct rp23xxgpint_dev_s *)dev;
int irq = g_gpiointinputs[rp23xxgpint->rp23xxgpio.id];
if (enable)
{
if (rp23xxgpint->callback != NULL)
{
gpioinfo("Enabling the interrupt\n");
/* Configure the interrupt for rising edge */
rp23xx_gpio_enable_irq(irq);
}
}
else
{
gpioinfo("Disable the interrupt\n");
rp23xx_gpio_disable_irq(irq);
}
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: rp23xx_dev_gpio_init
****************************************************************************/
int rp23xx_dev_gpio_init(void)
{
int i;
int pincount = 0;
#if BOARD_NGPIOOUT > 0
for (i = 0; i < BOARD_NGPIOOUT; i++)
{
/* Setup and register the GPIO pin */
g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
g_gpout[i].gpio.gp_ops = &gpout_ops;
g_gpout[i].id = i;
gpio_pin_register(&g_gpout[i].gpio, g_gpiooutputs[i]);
/* Configure the pins that will be used as output */
rp23xx_gpio_init(g_gpiooutputs[i]);
rp23xx_gpio_setdir(g_gpiooutputs[i], true);
rp23xx_gpio_put(g_gpiooutputs[i], false);
pincount++;
}
#endif
pincount = 0;
#if BOARD_NGPIOIN > 0
for (i = 0; i < BOARD_NGPIOIN; i++)
{
/* Setup and register the GPIO pin */
g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN;
g_gpin[i].gpio.gp_ops = &gpin_ops;
g_gpin[i].id = i;
gpio_pin_register(&g_gpin[i].gpio, g_gpioinputs[i]);
/* Configure the pins that will be used as INPUT */
rp23xx_gpio_init(g_gpioinputs[i]);
pincount++;
}
#endif
pincount = 0;
#if BOARD_NGPIOINT > 0
for (i = 0; i < BOARD_NGPIOINT; i++)
{
/* Setup and register the GPIO pin */
g_gpint[i].rp23xxgpio.gpio.gp_pintype = GPIO_INTERRUPT_PIN;
g_gpint[i].rp23xxgpio.gpio.gp_ops = &gpint_ops;
g_gpint[i].rp23xxgpio.id = i;
gpio_pin_register(&g_gpint[i].rp23xxgpio.gpio, g_gpiointinputs[i]);
/* Configure the pins that will be used as interrupt input */
rp23xx_gpio_init(g_gpiointinputs[i]);
/* pull-up = false : pull-down = true */
rp23xx_gpio_set_pulls(g_gpiointinputs[i], false, true);
pincount++;
}
#endif
return OK;
}
#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */

View file

@ -0,0 +1,69 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/rp23xx_pico.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_SRC_RP23XX_PICO_H
#define __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_SRC_RP23XX_PICO_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/* CYW43439 wireless chip
*
* The gSPI bus is half duplex -- a single data line carries both directions
* and doubles as the chip's interrupt request line.
*/
#define GPIO_CYW43439_ON 23 /* Drive high to power the chip up */
#define GPIO_CYW43439_DATA 24 /* Bidirectional data, also the IRQ */
#define GPIO_CYW43439_CS 25 /* Drive low to select the chip */
#define GPIO_CYW43439_CLOCK 29 /* gSPI clock */
/* LEDs
*
* The board's only LED hangs off GPIO 0 of the CYW43439, see
* include/rp23xx_extra_gpio.h. There is no LED on an RP2350 pin.
*/
/* Buttons */
/* Buttons GPIO pins definition */
/* The board's BOOT button doubles as a user button once NuttX is running.
* It is active low. RESET is not readable as a GPIO.
*/
#define GPIO_BTN_USER1 45
/* Buttons IRQ definitions */
#define MIN_IRQBUTTON BUTTON_USER1
#define MAX_IRQBUTTON BUTTON_USER1
#define NUM_IRQBUTTONS (MAX_IRQBUTTON - MIN_IRQBUTTON + 1)
int rp23xx_bringup(void);
#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_ARCH_BOARD_COMMON)
int rp23xx_dev_gpio_init(void);
#endif
#endif /* __BOARDS_ARM_RP23XX_PIMORONI_PICO_PLUS_2_W_SRC_RP23XX_PICO_H */

View file

@ -0,0 +1,94 @@
/****************************************************************************
* boards/arm/rp23xx/pimoroni-pico-plus-2-w/src/rp23xx_userleds.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* The single LED on this board is wired to GPIO 0 of the CYW43439 wireless
* chip rather than to a pin of the RP2350, so setting it means sending an
* iovar request over the gSPI bus. Two consequences:
*
* - The LED only responds once the wireless chip is running, which happens
* when wlan0 is brought up. Before that every write fails with -EIO.
* - Writing the LED blocks, so it must not be done from interrupt context.
* That is why this board implements the user LED interface only and not
* the CONFIG_ARCH_LEDS auto-LED interface.
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <debug.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include <arch/board/rp23xx_extra_gpio.h>
#if defined(CONFIG_RP23XX_INFINEON_CYW43439) && !defined(CONFIG_ARCH_LEDS)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_userled_initialize
****************************************************************************/
uint32_t board_userled_initialize(void)
{
/* Nothing to configure -- the LED lives on the wireless chip, which the
* board bringup has already set up.
*/
return BOARD_NLEDS;
}
/****************************************************************************
* Name: board_userled
****************************************************************************/
void board_userled(int led, bool ledon)
{
if (led == BOARD_LED1)
{
int ret = rp23xx_extra_gpio_put(RP23XX_EXTRA_GPIO_LED, ledon);
if (ret < 0)
{
lederr("ERROR: cannot reach the LED on the CYW43439: %d\n", ret);
}
}
}
/****************************************************************************
* Name: board_userled_all
****************************************************************************/
void board_userled_all(uint32_t ledset)
{
board_userled(BOARD_LED1, (ledset & BOARD_LED1_BIT) != 0);
}
#endif /* CONFIG_RP23XX_INFINEON_CYW43439 && !CONFIG_ARCH_LEDS */