From 024864a55c93406edabeb9828315439b054a9037 Mon Sep 17 00:00:00 2001 From: Ricard Rosson Date: Wed, 1 Jul 2026 16:09:04 +0100 Subject: [PATCH 1/4] boards/arm/rp23xx: add Raspberry Pi Pico 2 W board (CYW43439 Wi-Fi) Add a board port for the Raspberry Pi Pico 2 W (RP2350 + Infineon CYW43439). The board reuses the existing raspberrypi-pico-2 port and adds support for the onboard CYW43439 Wi-Fi device, driven through a new RP2350 PIO-based gSPI transport (arch/arm/src/rp23xx/rp23xx_cyw43439.c) that plugs into NuttX's existing bcm43xxx (bcmf) FullMAC driver. A telnet defconfig is provided that associates to an AP (NETINIT WAPI), obtains a DHCP lease, and exposes an NSH shell over TCP/telnet. This board port and the RP2350 PIO-gSPI CYW43439 driver were developed with Claude Code (Anthropic's agentic coding tool) and validated on real Pico 2 W hardware: Wi-Fi association, DHCP, and a TCP/telnet session over the CYW43439. Signed-off-by: Ricard Rosson Co-Authored-By: Claude Opus 4.8 --- .../boards/raspberrypi-pico-2-w/index.rst | 132 +++ arch/arm/src/rp23xx/CMakeLists.txt | 4 + arch/arm/src/rp23xx/Make.defs | 4 + arch/arm/src/rp23xx/rp23xx_cyw43439.c | 879 ++++++++++++++++++ arch/arm/src/rp23xx/rp23xx_cyw43439.h | 117 +++ boards/Kconfig | 13 + .../raspberrypi-pico-2-w/CMakeLists.txt | 40 + .../arm/rp23xx/raspberrypi-pico-2-w/Kconfig | 42 + .../configs/telnet/defconfig | 88 ++ .../raspberrypi-pico-2-w/include/board.h | 169 ++++ .../include/rp23xx_i2cdev.h | 72 ++ .../include/rp23xx_i2sdev.h | 72 ++ .../include/rp23xx_spidev.h | 69 ++ .../include/rp23xx_spisd.h | 83 ++ .../raspberrypi-pico-2-w/scripts/Make.defs | 47 + .../scripts/memmap_copy_to_ram.ld | 331 +++++++ .../scripts/memmap_default.ld | 343 +++++++ .../scripts/memmap_no_flash.ld | 284 ++++++ .../raspberrypi-pico-2-w/src/.gitignore | 1 + .../raspberrypi-pico-2-w/src/CMakeLists.txt | 57 ++ .../rp23xx/raspberrypi-pico-2-w/src/Make.defs | 91 ++ .../raspberrypi-pico-2-w/src/rp23xx_appinit.c | 76 ++ .../src/rp23xx_autoleds.c | 165 ++++ .../src/rp23xx_boardinitialize.c | 116 +++ .../raspberrypi-pico-2-w/src/rp23xx_bringup.c | 151 +++ .../raspberrypi-pico-2-w/src/rp23xx_buttons.c | 177 ++++ .../src/rp23xx_firmware.c | 158 ++++ .../raspberrypi-pico-2-w/src/rp23xx_gpio.c | 392 ++++++++ .../raspberrypi-pico-2-w/src/rp23xx_pico.h | 53 ++ .../src/rp23xx_userleds.c | 214 +++++ 30 files changed, 4440 insertions(+) create mode 100644 Documentation/platforms/arm/rp23xx/boards/raspberrypi-pico-2-w/index.rst create mode 100644 arch/arm/src/rp23xx/rp23xx_cyw43439.c create mode 100644 arch/arm/src/rp23xx/rp23xx_cyw43439.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/CMakeLists.txt create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/Kconfig create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/configs/telnet/defconfig create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/include/board.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2cdev.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2sdev.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spidev.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spisd.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/Make.defs create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_copy_to_ram.ld create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_default.ld create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_no_flash.ld create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/.gitignore create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_appinit.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_autoleds.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_boardinitialize.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_bringup.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_buttons.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_firmware.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_gpio.c create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_pico.h create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_userleds.c diff --git a/Documentation/platforms/arm/rp23xx/boards/raspberrypi-pico-2-w/index.rst b/Documentation/platforms/arm/rp23xx/boards/raspberrypi-pico-2-w/index.rst new file mode 100644 index 0000000000000..694b2932b0450 --- /dev/null +++ b/Documentation/platforms/arm/rp23xx/boards/raspberrypi-pico-2-w/index.rst @@ -0,0 +1,132 @@ +============================== +Raspberry Pi Pico 2 W +============================== + +.. tags:: chip:rp2350, wifi + +The `Raspberry Pi Pico 2 W `_ +is a general purpose board supplied by Raspberry Pi. The W variant adds an +Infineon CYW43439 for built-in 2.4 GHz WiFi and Bluetooth. + +Features +======== + +* RP2350 microcontroller chip +* Dual-core ARM Cortex-M33 processor, flexible clock running up to 150 MHz +* 520 kB of SRAM, and 4 MB of on-board Flash memory +* Castellated module allows soldering direct to carrier boards +* USB 1.1 Host and Device support +* Low-power sleep and dormant modes +* Drag & drop programming using mass storage over USB +* 26 multi-function GPIO pins +* 2x SPI, 2x I2C, 2x UART, 3x 12-bit ADC, 16x controllable PWM channels +* Accurate clock and timer on-chip +* Temperature sensor +* Accelerated floating point libraries on-chip +* 12 x Programmable IO (PIO) state machines for custom peripheral support +* Built in WiFi radio (Infineon CYW43439) + +Serial Console +============== + +By default a serial console appears on pin 1 (TX GPIO0) and pin 2 +(RX GPIO1). This console runs at 115200-8N1. + +The board can be configured to use the USB connection as the serial console; +see the ``usbnsh`` configuration of the base ``raspberrypi-pico-2`` board. + +Buttons and LEDs +================ + +The user LED is controlled by the CYW43439 wireless chip (not directly by an +RP2350 GPIO), so networking must be brought up before it can be driven. + +A BOOTSEL button, which if held down when power is first applied to the board, +will cause the RP2350 to boot into programming mode and appear as a storage +device to a computer connected via USB. Saving a .UF2 file to this device +will replace the Flash ROM contents on the Pico 2 W. + +Wireless Communication +====================== + +The on board Infineon CYW43439 supports 2.4 GHz WiFi 4 (802.11n). It is +driven over a PIO-based gSPI link by the NuttX ``bcmf`` FullMAC driver, ported +from the RP2040 ``raspberrypi-pico-w`` support. + +WiFi firmware blob +------------------ + +The CYW43439 requires a firmware/CLM blob that is **not** bundled with NuttX. +It is fetched from the Raspberry Pi Pico SDK at build time; set +``PICO_SDK_PATH`` (see Installation) or point +``CONFIG_CYW43439_FIRMWARE_BIN_PATH`` at a local copy. When the blob is +absent the build substitutes a dummy so that CI still passes, but an image +built with the dummy will not associate to an access point. + +The board's NVRAM calibration data (``src/rp23xx_firmware.c``) is the same +Broadcom-supplied table used by the RP2040 ``raspberrypi-pico-w`` board. + +RP2350 Wireless Pins +==================== + +The CYW43439 is wired to the RP2350 in the same arrangement as the RP2040 +Pico W: + +* GPIO23 Output - WiFi controller power / on-off control. +* GPIO24 I/O - WiFi controller data line (gSPI). +* GPIO25 Output - WiFi controller chip select line. +* GPIO29 Output - WiFi controller clock line. + +Supported Capabilities +====================== + +NuttX supports the following Pico 2 W capabilities: + +* UART (console port) + + * GPIO 0 (UART0 TX) and GPIO 1 (UART0 RX) are used for the console. + +* WiFi station mode (CYW43439, 2.4 GHz 802.11n) via the ``bcmf`` driver +* I2C +* SPI (master only) +* DMAC +* PWM +* ADC +* Watchdog +* USB device +* PIO (RP2350 Programmable I/O) +* Flash ROM Boot / SRAM Boot +* Persistent flash filesystem in unused flash ROM + +Installation +============ + +The Pico 2 W shares the RP2350 tool-chain and SDK setup of the base +``raspberrypi-pico-2`` board; follow the Installation steps of the main +:doc:`RP2350 documentation <../../index>` to install the Pico SDK and +``picotool`` and to set ``PICO_SDK_PATH`` (which also provides the CYW43439 +firmware blob). + +Configurations +============== + +All configurations listed below can be configured using the following command +in the ``nuttx`` directory (consult the main :doc:`RP2350 documentation +<../../index>`): + +.. code:: console + + $ ./tools/configure.sh raspberrypi-pico-2-w: + +telnet +------ + +NuttShell configuration (console enabled on UART0, at 115200 bps) with WiFi +station mode brought up at boot and a telnet server enabled, so the shell is +reachable over the network once the board associates. + +Set your network credentials before building via ``make menuconfig`` under +Application Configuration -> Network Utilities -> Network initialization -> +WAPI Configuration (SSID and passphrase), and the country code under Device +Drivers -> Wireless Device Support -> IEEE 802.11 Device Support. The shipped +defconfig carries only placeholder credentials. diff --git a/arch/arm/src/rp23xx/CMakeLists.txt b/arch/arm/src/rp23xx/CMakeLists.txt index b67f08039aad2..40fb7f54fceec 100644 --- a/arch/arm/src/rp23xx/CMakeLists.txt +++ b/arch/arm/src/rp23xx/CMakeLists.txt @@ -89,4 +89,8 @@ if(CONFIG_CRYPTO_CRYPTODEV_HARDWARE) list(APPEND SRCS rp23xx_crypto.c) endif() +if(CONFIG_IEEE80211_INFINEON_CYW43439) + list(APPEND SRCS rp23xx_cyw43439.c) +endif() + target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/rp23xx/Make.defs b/arch/arm/src/rp23xx/Make.defs index 0042124804909..ff27b2209dab4 100644 --- a/arch/arm/src/rp23xx/Make.defs +++ b/arch/arm/src/rp23xx/Make.defs @@ -92,3 +92,7 @@ endif ifeq ($(CONFIG_CRYPTO_CRYPTODEV_HARDWARE),y) CHIP_CSRCS += rp23xx_crypto.c endif + +ifeq ($(CONFIG_IEEE80211_INFINEON_CYW43439),y) +CHIP_CSRCS += rp23xx_cyw43439.c +endif diff --git a/arch/arm/src/rp23xx/rp23xx_cyw43439.c b/arch/arm/src/rp23xx/rp23xx_cyw43439.c new file mode 100644 index 0000000000000..7631774d9e05a --- /dev/null +++ b/arch/arm/src/rp23xx/rp23xx_cyw43439.c @@ -0,0 +1,879 @@ +/**************************************************************************** + * arch/arm/src/rp23xx/rp23xx_cyw43439.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 + +#include +#include +#include + +#include +#include +#include +#include + +#include "rp23xx_cyw43439.h" +#include "rp23xx_pio.h" +#include "rp23xx_pio_instructions.h" + +#ifdef CONFIG_NDEBUG +# define PRINT_GSPI(block) +#else +void bcmf_hexdump(uint8_t *data, unsigned int len, unsigned long offset); +bool g_print_gspi = false; +# define PRINT_GSPI(block) if (g_print_gspi) { block } +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GSPI_CLOCK_FREQ 31250000 /* Hz (Max: 50MHz) */ + +#define PIO_WRAP_TARGET 0 +#define PIO_WRAP 5 + +#define TX_FIFO_SIZE 4 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct dma_info_s +{ + sem_t sem; + uint8_t status; +} dma_info_t; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the PIO program to write and then read from the data pin. + * + * The X register is the output bit count register. It should be set + * to one less than the total number of BITS to be transmitted. + * + * The Y register is the input bit count register. It too must be set + * to one less than the total number of bits to be read. + * + * The PIO's state machine is set up to auto-pull data from the input + * fifo whenever the output shift register is empty. This happens at + * the start and every 32 bits thereafter. + * + * The state machine also auto-pushes whenever we have a full 32 bits + * in the input shift register. To make sure we receive all the data, + * we need to make sure that the read bit count is a multiple of 32. + * (Y = 32*N - 1 for some integer N) + */ + +static const uint16_t cyw_program_instructions[] = +{ + 0x6001, /* 0: out pins, 1 side 0 # Write one bit */ + 0x1040, /* 1: jmp x--, 0 side 1 # Loop until write count is zero */ + 0xe080, /* 2: set pindirs, 0 side 0 # Make data pin an input */ + 0xb042, /* 3: nop side 1 # Keep clock in sync */ + 0x4001, /* 4: in pins, 1 side 0 # Read 1 bit */ + 0x1084, /* 5: jmp y--, 4 side 1 # Loop until read count is zero */ +}; + +static const rp23xx_pio_program_t pio_program = +{ + .instructions = cyw_program_instructions, + .length = 6, /* Six, count 'em, six. */ + .origin = -1, /* Put it wherever it fits */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dma_complete + * + * Description: + * Called on completion of the DMA transfer. + * + * Input Parameters: + * handle - handle to our DMA channel + * status - status of the transfer + * arg - Pointer to dma info structure. + * + ****************************************************************************/ + +static void dma_complete(DMA_HANDLE handle, uint8_t status, void *arg) +{ + dma_info_t *dma_info = arg; + + /* Remember the status and post the dma complete event. */ + + dma_info->status = status; + nxsem_post(&(dma_info->sem)); +} + +/**************************************************************************** + * Name: rp23xx_cyw_init + * + * Description: + * Connect to and initialize the cyw43439. + * + ****************************************************************************/ + +static int rp23xx_cyw_init(gspi_dev_t *gspi) +{ + rp23xx_gspi_t *rp_io = (rp23xx_gspi_t *)(gspi->io_dev); + + uint32_t divisor; + irqstate_t flags; + rp23xx_pio_sm_config config = + { + 0 + }; + + /* Make sure the cyw43439 chip is deselected, and off. + * so we know it is reset + */ + + rp23xx_gpio_put(rp_io->gpio_select, true); /* deselect */ + rp23xx_gpio_put(rp_io->gpio_on, false); /* power off */ + + /* Pull the data line low so that we initialise to gSPI mode */ + + rp23xx_gpio_init(rp_io->gpio_data); + rp23xx_gpio_setdir(rp_io->gpio_data, true); + rp23xx_gpio_put(rp_io->gpio_data, false); + + nxsched_usleep(50000); /* Leave off for at least 50ms. */ + + rp23xx_gpio_put(rp_io->gpio_on, true); /* power on */ + + nxsched_usleep(50000); /* Wait a bit to let the power come up. */ + + /* Don't let anyone else grab a PIO while we are doing so. */ + + flags = enter_critical_section(); + + /* Find a PIO instance and load program. */ + + for (rp_io->pio = 0; rp_io->pio < RP23XX_PIO_NUM; ++rp_io->pio) + { + /* Try to claim a state machine. */ + + rp_io->pio_sm = rp23xx_pio_claim_unused_sm(rp_io->pio, false); + + /* If we did not get one try the next pio block, if any. */ + + if (rp_io->pio_sm < 0) continue; + + /* See if we have space in this block to load our program. */ + + if (rp23xx_pio_can_add_program(rp_io->pio, &pio_program)) + { + /* Great! load the program and exit the pio choice loop. */ + + rp_io->pio_location = rp23xx_pio_add_program(rp_io->pio, + &pio_program); + + break; + } + + /* Oops -- no room at the inn! Release sm and try next pio. */ + + rp23xx_pio_sm_unclaim(rp_io->pio, rp_io->pio_sm); + } + + if (rp_io->pio >= RP23XX_PIO_NUM) + { + leave_critical_section(flags); + return -ENOMEM; + } + + leave_critical_section(flags); + + /* ==== Configure the PIO State Machine ==== */ + + /* Configure pins that are used by PIO. */ + + rp23xx_pio_gpio_init(rp_io->pio, rp_io->gpio_data); + rp23xx_pio_gpio_init(rp_io->pio, rp_io->gpio_clock); + + rp23xx_gpio_set_input_hysteresis_enabled(rp_io->gpio_data, true); + + rp23xx_gpio_set_slew_fast(rp_io->gpio_clock, true); + rp23xx_gpio_set_drive_strength(rp_io->gpio_clock, + RP23XX_PADS_BANK0_GPIO_DRIVE_12MA); + + /* Set the clock divisor as appropriate for our system clock + * speed, so the pio clock runs the requested bit clock rate. + */ + + divisor = ((uint64_t)BOARD_SYS_FREQ << 8) / (2 * GSPI_CLOCK_FREQ); + + rp23xx_sm_config_set_clkdiv_int_frac(&config, + divisor >> 8, + divisor & 0xff); + + /* Set the wrap points as required by the program. */ + + rp23xx_sm_config_set_wrap(&config, + rp_io->pio_location + PIO_WRAP_TARGET, + rp_io->pio_location + PIO_WRAP); + + /* set to shift left, 32 bits, with autopull/push */ + + rp23xx_sm_config_set_in_shift(&config, false, true, 32); + rp23xx_sm_config_set_out_shift(&config, false, true, 32); + + /* Configure a single mandatory side-set pin. */ + + rp23xx_sm_config_set_sideset(&config, 1, false, false); + + /* Configure our GPIO clock pin as side-set output. */ + + rp23xx_sm_config_set_sideset_pins(&config, rp_io->gpio_clock); + + /* Configure out GPIO data pin as an OUT pin, SET pin, and IN pin */ + + rp23xx_sm_config_set_out_pins(&config, rp_io->gpio_data, 1); + rp23xx_sm_config_set_set_pins(&config, rp_io->gpio_data, 1); + rp23xx_sm_config_set_in_pins (&config, rp_io->gpio_data); + + /* Load the configuration into the state machine. */ + + rp23xx_pio_sm_init(rp_io->pio, + rp_io->pio_sm, + rp_io->pio_location, + &config); + + /* Disable the input synchronizers on the data pin */ + + rp23xx_pio_set_input_sync_bypass(rp_io->pio, rp_io->gpio_data, true); + + wlinfo("finished\n"); + + return OK; +} + +/**************************************************************************** + * Name: rp23xx_cyw_set_isr + * + * Description: + * Setup the data line interrupt service routine. + * + ****************************************************************************/ + +static int rp23xx_cyw_set_isr(gspi_dev_t *gspi, + xcpt_t thread_isr, + void *thread_isr_arg) +{ + rp23xx_gspi_t *rp_io = (rp23xx_gspi_t *)(gspi->io_dev); + + /* Set up, but do not enable, interrupt service for the data pin */ + + rp23xx_gpio_irq_attach(rp_io->gpio_intr, + RP23XX_GPIO_INTR_LEVEL_HIGH, + thread_isr, + thread_isr_arg); + + wlinfo("attached\n"); + + return OK; +} + +/**************************************************************************** + * Name: rp23xx_cyw_interrupt_enable + * + * Description: + * Setup the data line isr. + * + ****************************************************************************/ + +static int rp23xx_cyw_interrupt_enable(gspi_dev_t *gspi, + bool enable) +{ + rp23xx_gspi_t *rp_io = (rp23xx_gspi_t *)(gspi->io_dev); + static int disable_count = 0; + + if (enable) + { + if (--disable_count <= 0) rp23xx_gpio_enable_irq(rp_io->gpio_intr); + } + else + { + rp23xx_gpio_disable_irq(rp_io->gpio_intr); + ++disable_count; + } + + return OK; +} + +/**************************************************************************** + * Name: rp23xx_cyw_deinit + * + * Description: + * Disconnect from cyw43439 and cleanup. + * + ****************************************************************************/ + +static int rp23xx_cyw_deinit(gspi_dev_t *gspi) +{ + rp23xx_gspi_t *rp_io = (rp23xx_gspi_t *)(gspi->io_dev); + + rp23xx_gpio_irq_attach(rp_io->gpio_data, + RP23XX_GPIO_INTR_EDGE_LOW, + NULL, + NULL); + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, false); + rp23xx_pio_remove_program(rp_io->pio, &pio_program, rp_io->pio_location); + rp23xx_pio_sm_unclaim(rp_io->pio, rp_io->pio_sm); + + /* Turn the power off to the cyw43439. */ + + rp23xx_gpio_put(rp_io->gpio_on, false); + + return OK; +} + +/**************************************************************************** + * Name: rp23xx_cyw_write + * + * Description: + * write data to the cyw43439 + * + ****************************************************************************/ + +static int rp23xx_cyw_write(struct gspi_dev_s *gspi, + bool increment, + enum gspi_cmd_func_e function, + uint32_t address, + uint16_t length, + const uint32_t *data) +{ + rp23xx_gspi_t *rp_io = (rp23xx_gspi_t *)(gspi->io_dev); + dma_info_t dma_info; + DMA_HANDLE xfer_dma = rp23xx_dmachannel(); + uint32_t command = (0x1 << 31) + | ((increment ? 1 : 0) << 30) + | ((function & 0x3) << 28) + | ((address & 0x1ffff) << 11) + | (length & 0x7ff); + + dma_config_t dma_config = + { + .size = RP23XX_DMA_SIZE_WORD, + .noincr = false, + .dreq = rp23xx_pio_get_dreq(rp_io->pio, + rp_io->pio_sm, + true), + }; + + PRINT_GSPI( + printf("------ cmd: 0x%08lx [W %d %d 0x%05lX %d]\n", command, + increment, + function, + address, + length); + bcmf_hexdump((void *)data, length, (uint32_t)data); + ) + + /* Claim the exclusive lock */ + + nxmutex_lock(&gspi->lock); + + /* Reset the PIO state machine just to be sure. */ + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, false); + + rp23xx_pio_sm_clear_fifos(rp_io->pio, rp_io->pio_sm); + + rp23xx_pio_sm_restart(rp_io->pio, rp_io->pio_sm); + + rp23xx_pio_sm_clkdiv_restart(rp_io->pio, rp_io->pio_sm); + + rp23xx_pio_sm_exec(rp_io->pio, + rp_io->pio_sm, + pio_encode_jmp(rp_io->pio_location)); + + /* Set the PIO X and Y registers. + * + * We load X (the TX bit length) with one less than the number of + * bits to transmit to the chip. This length includes the 32-bit + * command word and all the 32-bit data words. Since the length + * parameter is a byte count we round up just to be sure. + * + * We load Y (the RX bit length) with zero as we're not reading + * any data. + * + * This is slightly magical. The way we load the X is to first + * push the the number of bits to transmit onto the transmit fifo. + * Then we force the PIO state machine to execute the instruction + * "out x, 32" which transfers the word from the output shift + * register (OSR) to the X register. When this instruction executes + * the PIO will notice that the OSR is empty, so will automatically + * pull a value (the one we just added) from the input fifo. + * + * Loading the Y works the same way. + */ + + rp23xx_pio_sm_put(rp_io->pio, rp_io->pio_sm, 32 * ((length + 3) / 4) + 31); + rp23xx_pio_sm_exec(rp_io->pio, rp_io->pio_sm, pio_encode_out(pio_x, 32)); + + rp23xx_pio_sm_put(rp_io->pio, rp_io->pio_sm, 0); + rp23xx_pio_sm_exec(rp_io->pio, rp_io->pio_sm, pio_encode_out(pio_y, 32)); + + /* Disable interrupts so data won't trigger interrupt. */ + + rp23xx_cyw_interrupt_enable(gspi, false); + + /* Make sure the clock and data pins direction set to output. */ + + rp23xx_pio_sm_set_pindirs_with_mask(rp_io->pio, + rp_io->pio_sm, + (1 << rp_io->gpio_data) + | (1 << rp_io->gpio_clock), + (1 << rp_io->gpio_data) + | (1 << rp_io->gpio_clock)); + + /* Make sure there is nothing in the fifos before starting DMA. */ + + rp23xx_pio_sm_clear_fifos(rp_io->pio, rp_io->pio_sm); + + /* Load the command into the transmit fifo. */ + + if (function == gspi_f0_bus_rev16) + { + __asm ("rev16 %0, %0" : "+l" (command) : :); + } + + __asm ("rev %0, %0" : "+l" (command) : :); + + putreg32(command, RP23XX_PIO_TXF(rp_io->pio, rp_io->pio_sm)); + + /* Initialize and start the transmit DMA. It will + * keep adding data to the TX_FIFO until all data is sent. + */ + + nxsem_init(&dma_info.sem, 0, 0); + + rp23xx_dmastop(xfer_dma); + + rp23xx_txdmasetup(xfer_dma, + (uintptr_t) RP23XX_PIO_TXF(rp_io->pio, + rp_io->pio_sm), + (uintptr_t) data, + (length + 3) & 0xfffffffc, + dma_config); + + modifyreg32(rp23xx_dma_register(xfer_dma, + RP23XX_DMA_CTRL_TRIG_OFFSET), + RP23XX_DMA_CTRL_TRIG_BSWAP, + RP23XX_DMA_CTRL_TRIG_BSWAP); + + rp23xx_dmastart(xfer_dma, dma_complete, &dma_info); + + /* Assert gpio_select by pulling line low */ + + rp23xx_gpio_put(rp_io->gpio_select, false); + UP_DMB(); + + /* Enable the state machine. This starts the pio program running */ + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, true); + + /* Wait for transfer to complete */ + + nxsem_wait(&dma_info.sem); + + /* At this point all the data has been queued but my not have all been + * sent. We know that the PIO program will make the data line an input + * once all the data is sent so we'll check for this. + * + * NOTE (RP2350 port): the RP2040 read this via the OEFROMPERI status + * bit. That bit does not exist on RP2350; the GPIO_STATUS register + * exposes OETOPAD (the output enable presented to the pad, after any + * register override). With the default OEOVER (drive from peripheral) + * the two are equivalent for our purposes -- the bit is set while the + * PIO is still driving the data pin as an output. + */ + + while (getreg32(RP23XX_IO_BANK0_GPIO_STATUS(rp_io->gpio_data)) + & RP23XX_IO_BANK0_GPIO_STATUS_OETOPAD) + { + /* Just busy wait -- testing indicates a worst case of + * 20 loops (100 instructions). + */ + } + + /* Un-assert select by pulling line high. */ + + UP_DMB(); + rp23xx_gpio_put(rp_io->gpio_select, true); + + /* Free the DMA controller */ + + rp23xx_dmafree(xfer_dma); + nxsem_destroy(&dma_info.sem); + + /* Disable the PIO */ + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, false); + + /* At this point the data pin is input so it should have been + * pulled high by rp23xx's gpio pullup. + */ + + rp23xx_cyw_interrupt_enable(gspi, true); + + /* Release the exclusive lock */ + + nxmutex_unlock(&gspi->lock); + return dma_info.status; +} + +/**************************************************************************** + * Name: rp23xx_cyw_read + * + * Description: + * read data to the cyw43439 + * + ****************************************************************************/ + +static int rp23xx_cyw_read(struct gspi_dev_s *gspi, + bool increment, + enum gspi_cmd_func_e function, + uint32_t address, + uint16_t length, + uint32_t *buffer) +{ + rp23xx_gspi_t *rp_io = (rp23xx_gspi_t *)(gspi->io_dev); + dma_info_t dma_info; + DMA_HANDLE xfer_dma = rp23xx_dmachannel(); + DMA_HANDLE ctrl_dma = rp23xx_dmachannel(); + uint32_t temp_word; + uint32_t bit_length; + uint32_t command = ((increment ? 1 : 0) << 30) + | ((function & 0x3) << 28) + | ((address & 0x1ffff) << 11) + | (length & 0x7ff); + + uint32_t pacing = rp23xx_pio_get_dreq(rp_io->pio, + rp_io->pio_sm, + false); + + dma_control_block_t ctrl_blks[] = + { + /* For F1 transfers we read 1 word that we throw away */ + + { + rp23xx_dma_ctrl_blk_ctrl(ctrl_dma, + RP23XX_DMA_SIZE_WORD, + pacing, + 0), + (uintptr_t) RP23XX_PIO_RXF(rp_io->pio, rp_io->pio_sm), + (uintptr_t) &temp_word, + 1, + }, + + /* Read requested data into output buffer */ + + { + rp23xx_dma_ctrl_blk_ctrl(ctrl_dma, + RP23XX_DMA_SIZE_WORD, + pacing, + RP23XX_DMA_CTRL_TRIG_INCR_WRITE + | RP23XX_DMA_CTRL_TRIG_BSWAP), + (uintptr_t) RP23XX_PIO_RXF(rp_io->pio, rp_io->pio_sm), + (uintptr_t) buffer, + (length + 3) / 4, + }, + + RP23XX_DMA_CTRL_BLOCK_END + }; + + PRINT_GSPI( + printf("------ cmd: 0x%08lx [R %d %d 0x%05lX %d]\n", command, + increment, + function, + address, + length); + ) + + /* Claim the exclusive lock */ + + nxmutex_lock(&gspi->lock); + + /* Reset the PIO state machine just to be sure. */ + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, false); + + rp23xx_pio_sm_clear_fifos(rp_io->pio, rp_io->pio_sm); + + rp23xx_pio_sm_restart(rp_io->pio, rp_io->pio_sm); + + rp23xx_pio_sm_clkdiv_restart(rp_io->pio, rp_io->pio_sm); + + rp23xx_pio_sm_exec(rp_io->pio, + rp_io->pio_sm, + pio_encode_jmp(rp_io->pio_location)); + + /* Set the PIO X and Y registers. + * + * We load X (the TX bit length) with one less than the number of + * bits to transmit to the chip. Since we only send the 32-bit command + * word we set X to 31. + * + * We load Y with the number of bits to read. This is based on the + * byte count in "length" which we round up to a 32-bit boundary so the + * pio program will be sure to autopush the final data to the output fifo. + * + * This is slightly magical. The way we load the X is to first + * push the the number of bits to transmit onto the transmit fifo. + * Then we force the PIO state machine to execute the instruction + * "out x, 32" which transfers the word from the output shift + * register (OSR) to the X register. When this instruction executes + * the PIO will notice that the OSR is empty, so will automatically + * pull a value (the one we just added) from the input fifo. + * + * Loading the Y works the same way. + */ + + rp23xx_pio_sm_put(rp_io->pio, rp_io->pio_sm, 31); + rp23xx_pio_sm_exec(rp_io->pio, rp_io->pio_sm, pio_encode_out(pio_x, 32)); + + /* RX bit length is 32 bits for each 4 bytes requested. */ + + bit_length = 32 * ((length + 3) / 4); + + /* For F1 reads add 32 bits for delay */ + + if (function == gspi_f1_backplane) + { + bit_length += 32; + } + + rp23xx_pio_sm_put(rp_io->pio, rp_io->pio_sm, bit_length); + rp23xx_pio_sm_exec(rp_io->pio, rp_io->pio_sm, pio_encode_out(pio_y, 32)); + + /* Disable interrupts so data won't trigger interrupt. */ + + rp23xx_cyw_interrupt_enable(gspi, false); + + /* Make sure the clock and data pins direction set to output. */ + + rp23xx_pio_sm_set_pindirs_with_mask(rp_io->pio, + rp_io->pio_sm, + (1 << rp_io->gpio_data) + | (1 << rp_io->gpio_clock), + (1 << rp_io->gpio_data) + | (1 << rp_io->gpio_clock)); + + /* Make sure there is nothing in the fifos before starting DMA. */ + + rp23xx_pio_sm_clear_fifos(rp_io->pio, rp_io->pio_sm); + + /* Load the command into the transmit fifo. */ + + if (function == gspi_f0_bus_rev16) + { + __asm ("rev16 %0, %0" : "+l" (command) : :); + } + + __asm ("rev %0, %0" : "+l" (command) : :); + + putreg32(command, RP23XX_PIO_TXF(rp_io->pio, rp_io->pio_sm)); + + /* Initialize and start the control DMA. It will + * use the xfer_dma to transfer data from the chip. + */ + + nxsem_init(&dma_info.sem, 0, 0); + + rp23xx_dmastop(ctrl_dma); + rp23xx_dmastop(xfer_dma); + + /* Check the function bits if the command word to see if + * this is an F1 read. If it is we throw away the first + * four bytes read as this is a delay word. + */ + + rp23xx_ctrl_dmasetup(ctrl_dma, + xfer_dma, + &ctrl_blks[function == 1 ? 0 : 1], + dma_complete, + &dma_info); + + rp23xx_dmastart(ctrl_dma, NULL, NULL); + + /* Assert gpio_select by pulling line low */ + + rp23xx_gpio_put(rp_io->gpio_select, false); + UP_DMB(); + + /* Enable the state machine. This starts the pio program running */ + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, true); + + /* Wait for transfer to complete */ + + nxsem_wait(&dma_info.sem); + + PRINT_GSPI( + bcmf_hexdump((void *)buffer, length, (uint32_t)buffer); + ) + + /* Un-assert select by pulling line high. */ + + UP_DMB(); + rp23xx_gpio_put(rp_io->gpio_select, true); + + /* Free the DMA controllers */ + + rp23xx_dmafree(ctrl_dma); + rp23xx_dmafree(xfer_dma); + + nxsem_destroy(&dma_info.sem); + + /* Disable the PIO */ + + rp23xx_pio_sm_set_enabled(rp_io->pio, rp_io->pio_sm, false); + + /* At this point the data pin is input so it should have been + * pulled high by rp23xx's gpio pullup. + */ + + rp23xx_cyw_interrupt_enable(gspi, true); + + /* Release the exclusive lock */ + + nxmutex_unlock(&gspi->lock); + return dma_info.status; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_cyw_setup + * + * Description: + * Initialize the cyw43439 private data and PIO communication. + * + ****************************************************************************/ + +gspi_dev_t *rp23xx_cyw_setup(uint8_t gpio_on, + uint8_t gpio_select, + uint8_t gpio_data, + uint8_t gpio_clock, + uint8_t gpio_intr) +{ + gspi_dev_t *gspi; + rp23xx_gspi_t *rp_io; + int err; + + wlinfo("entered.\n"); + + gspi = kmm_zalloc(sizeof(gspi_dev_t)); + + if (gspi == NULL) + { + set_errno(ENOMEM); + return NULL; + } + + rp_io = kmm_zalloc(sizeof(rp23xx_gspi_t)); + + if (rp_io == NULL) + { + kmm_free(gspi); + set_errno(ENOMEM); + return NULL; + } + + gspi->init = rp23xx_cyw_init; + gspi->deinit = rp23xx_cyw_deinit; + gspi->set_isr = rp23xx_cyw_set_isr; + gspi->interrupt_enable = rp23xx_cyw_interrupt_enable; + gspi->write = rp23xx_cyw_write; + gspi->read = rp23xx_cyw_read; + gspi->io_dev = rp_io; + + rp_io->gpio_on = gpio_on; + rp_io->gpio_select = gpio_select; + rp_io->gpio_data = gpio_data; + rp_io->gpio_clock = gpio_clock; + rp_io->gpio_intr = gpio_intr; + + nxmutex_init(&gspi->lock); + + /* Initialize the cyw43439 power-on and chip select lines. */ + + rp23xx_gpio_init(gpio_on); + rp23xx_gpio_setdir(gpio_on, true); + rp23xx_gpio_put(gpio_on, false); /* set low to turn wifi chip off */ + + rp23xx_gpio_init(gpio_select); + rp23xx_gpio_setdir(gpio_select, true); + rp23xx_gpio_put(gpio_select, true); /* set high to deselect chip */ + + err = bcmf_gspi_initialize(gspi); + + if (err != OK) + { + kmm_free(gspi); + kmm_free(rp_io); + + set_errno(err); + return NULL; + } + + wlinfo("setup complete. gspi = 0x%p\n", gspi); + + return gspi; +} + +/**************************************************************************** + * Name: rp23xx_cyw_remove + * + * Description: + * Deinitialize the cyw43439 PIO communication. + * + ****************************************************************************/ + +void rp23xx_cyw_remove(gspi_dev_t *gspi) +{ + /* gspi_deregister((gspi_dev_t *)gspi); */ +} + +/**************************************************************************** + * Name: bcmf_board_etheraddr + ****************************************************************************/ + +bool bcmf_board_etheraddr(struct ether_addr *ethaddr) +{ + return false; +} diff --git a/arch/arm/src/rp23xx/rp23xx_cyw43439.h b/arch/arm/src/rp23xx/rp23xx_cyw43439.h new file mode 100644 index 0000000000000..76cda33e32937 --- /dev/null +++ b/arch/arm/src/rp23xx/rp23xx_cyw43439.h @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/src/rp23xx/rp23xx_cyw43439.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 __ARCH_ARM_SRC_RP23XX_RP23XX_CYW43439_H +#define __ARCH_ARM_SRC_RP23XX_RP23XX_CYW43439_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef struct rp23xx_gspi_s +{ + uint32_t pio; /* The pio instance we are using. */ + uint32_t pio_sm; /* The state machine we are using. */ + uint32_t pio_location; /* the program location in the pio. */ + uint8_t gpio_on; /* Set high to power chip on */ + uint8_t gpio_select; /* Pull low to select chip */ + uint8_t gpio_data; /* Data line -- idle high */ + uint8_t gpio_clock; /* Clock line -- idle low */ + uint8_t gpio_intr; /* May be shared with data */ +} rp23xx_gspi_t; + +typedef struct cyw_pio_program_s +{ + const uint16_t *instructions; + uint8_t length; + int8_t origin; /* required instruction memory origin or -1 */ +} cyw_pio_program_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_cyw_setup + * + * Description: + * Initialize the cyw43439 device. + * + * Returns: + * A pointer to the cyw43439 device + * + ****************************************************************************/ + +gspi_dev_t *rp23xx_cyw_setup(uint8_t gpio_on, + uint8_t gpio_select, + uint8_t gpio_data, + uint8_t gpio_clock, + uint8_t gpio_intr); + +/**************************************************************************** + * Name: rp23xx_cyw_remove + * + * Description: + * Deinitialize the cyw43439 device. + * + * Parameters: + * A pointer (as returned by rp23xx_cyw_setup) to the device to remove. + * + ****************************************************************************/ + +void rp23xx_cyw_remove(gspi_dev_t *dev); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_RP23XX_RP23XX_CYW43439_H */ diff --git a/boards/Kconfig b/boards/Kconfig index ad047a75f11ce..5af6902b95f68 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -2214,6 +2214,15 @@ config ARCH_BOARD_RASPBERRYPI_PICO_2 ---help--- This is a port to the Raspberry Pi Pico 2 board. +config ARCH_BOARD_RASPBERRYPI_PICO_2_W + bool "Raspberry Pi Pico 2 W board" + depends on ARCH_CHIP_RP23XX + select ARCH_HAVE_LEDS + ---help--- + This is a port to the Raspberry Pi Pico 2 W board. It adds support + for the onboard Infineon CYW43439 Wi-Fi device, driven over a + PIO-based gSPI bus (see arch/arm/src/rp23xx/rp23xx_cyw43439.c). + config ARCH_BOARD_RASPBERRYPI_PICO_2_RV bool "Raspberry Pi Pico 2 board RISC-V (not Pico, not W)" depends on ARCH_CHIP_RP23XX_RV @@ -3895,6 +3904,7 @@ config ARCH_BOARD default "adafruit-qt-py-rp2040" if ARCH_BOARD_ADAFRUIT_QT_PY_RP2040 default "waveshare-rp2040-lcd-1.28" if ARCH_BOARD_WAVESHARE_RP2040_LCD_1_28 default "raspberrypi-pico-2" if ARCH_BOARD_RASPBERRYPI_PICO_2 + default "raspberrypi-pico-2-w" if ARCH_BOARD_RASPBERRYPI_PICO_2_W 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 @@ -4422,6 +4432,9 @@ endif if ARCH_BOARD_RASPBERRYPI_PICO_2 source "boards/arm/rp23xx/raspberrypi-pico-2/Kconfig" endif +if ARCH_BOARD_RASPBERRYPI_PICO_2_W +source "boards/arm/rp23xx/raspberrypi-pico-2-w/Kconfig" +endif if ARCH_BOARD_XIAO_RP2350 source "boards/arm/rp23xx/xiao-rp2350/Kconfig" endif diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/CMakeLists.txt b/boards/arm/rp23xx/raspberrypi-pico-2-w/CMakeLists.txt new file mode 100644 index 0000000000000..2fcb33e653ed9 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/CMakeLists.txt @@ -0,0 +1,40 @@ +# ############################################################################## +# boards/arm/rp23xx/raspberrypi-pico-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") diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/Kconfig b/boards/arm/rp23xx/raspberrypi-pico-2-w/Kconfig new file mode 100644 index 0000000000000..5eeb2e8df5150 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/Kconfig @@ -0,0 +1,42 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_RASPBERRYPI_PICO_2_W + +menuconfig RP23XX_INFINEON_CYW43439 + bool "Has Infineon cyw43439 WiFi chip" + depends on IEEE80211_INFINEON_CYW43439 + default y + ---help--- + The Raspberry Pi Pico 2 W has an onboard Infineon CYW43439 WiFi chip + connected to the RP2350 via a PIO-based gSPI interface. + +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 CLB 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. + +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 diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/configs/telnet/defconfig b/boards/arm/rp23xx/raspberrypi-pico-2-w/configs/telnet/defconfig new file mode 100644 index 0000000000000..b58624dd28c20 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/configs/telnet/defconfig @@ -0,0 +1,88 @@ +# +# 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_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_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="raspberrypi-pico-2-w" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_W=y +CONFIG_ARCH_CHIP="rp23xx" +CONFIG_ARCH_CHIP_RP23XX=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +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_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=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_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_NETUTILS_TELNETD=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_LOOPBACK=y +CONFIG_NET_LOOPBACK_PKTSIZE=1024 +CONFIG_NET_TCP=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_UDP=y +CONFIG_NSH_ARCHINIT=y +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_BUFFER=y +CONFIG_SYSLOG_INTBUFFER=y +CONFIG_SYSLOG_INTBUFSIZE=2048 +CONFIG_SYSLOG_PROCESSID=y +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_TELNET_CLIENT=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGTSTP=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_WIRELESS_WAPI=y +CONFIG_WIRELESS_WAPI_CMDTOOL=y +CONFIG_WQUEUE_NOTIFIER=y diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/include/board.h b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/board.h new file mode 100644 index 0000000000000..37c8afc1d392c --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/board.h @@ -0,0 +1,169 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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_RASPBERRYPI_PICO_2_INCLUDE_BOARD_H +#define __BOARDS_ARM_RP23XX_RASPBERRYPI_PICO_2_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "rp23xx_i2cdev.h" +#include "rp23xx_spidev.h" +#include "rp23xx_i2sdev.h" +#include "rp23xx_spisd.h" + +#ifndef __ASSEMBLY__ +# include +#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_GPIO_LED_PIN 25 +#define BOARD_NGPIOOUT 1 +#define BOARD_NGPIOIN 1 +#define BOARD_NGPIOINT 1 + +/* LED definitions **********************************************************/ + +/* If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs + * in any way. The following definitions are used to access individual 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) + +/* This LED is not used by the board port unless CONFIG_ARCH_LEDS is + * defined. In that case, the usage by the board port is defined in + * include/board.h and src/rp23xx_autoleds.c. The LED is used to encode + * OS-related events as follows: + * + * -------------------- ----------------------------- ------ + * SYMBOL Meaning LED + * -------------------- ----------------------------- ------ + */ + +#define LED_STARTED 0 /* NuttX has been started OFF */ +#define LED_HEAPALLOCATE 0 /* Heap has been allocated OFF */ +#define LED_IRQSENABLED 0 /* Interrupts enabled OFF */ +#define LED_STACKCREATED 1 /* Idle stack created ON */ +#define LED_INIRQ 2 /* In an interrupt N/C */ +#define LED_SIGNAL 2 /* In a signal handler N/C */ +#define LED_ASSERTION 2 /* An assertion failed N/C */ +#define LED_PANIC 3 /* The system has crashed FLASH */ +#undef LED_IDLE /* Not used */ + +/* Thus if the LED is statically on, NuttX has successfully booted and is, + * apparently, running normally. If the LED is flashing at approximately + * 2Hz, then a fatal error has been detected and the system has halted. + */ + +/* BUTTON definitions *******************************************************/ + +#define NUM_BUTTONS 0 + +#define BUTTON_USER1 0 +#define BUTTON_USER2 1 +#define BUTTON_USER1_BIT (1 << BUTTON_USER1) +#define BUTTON_USER2_BIT (1 << BUTTON_USER2) + +/**************************************************************************** + * 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_RASPBERRYPI_PICO_2_INCLUDE_BOARD_H */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2cdev.h b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2cdev.h new file mode 100644 index 0000000000000..bf8a179935228 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2cdev.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_I2CDEV_H +#define __BOARDS_ARM_RP23XX_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_I2CDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * 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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_I2CDEV_H */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2sdev.h b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2sdev.h new file mode 100644 index 0000000000000..41d68d519c019 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_i2sdev.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_I2SDEV_H +#define __BOARDS_ARM_RP23XX_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_I2SDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * 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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_I2SDEV_H */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spidev.h b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spidev.h new file mode 100644 index 0000000000000..df4c73eae1731 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spidev.h @@ -0,0 +1,69 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_SPIDEV_H +#define __BOARDS_ARM_RP23XX_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_SPIDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * 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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_SPIDEV_H */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spisd.h b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spisd.h new file mode 100644 index 0000000000000..1f71de10ee91f --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spisd.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/include/rp23xx_spisd.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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_SPISD_H +#define __BOARDS_ARM_RP23XX_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_SPISD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * 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_RASPBERRYPI_PICO_2_INCLUDE_RP23XX_SPISD_H */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/Make.defs b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/Make.defs new file mode 100644 index 0000000000000..cf214e955c780 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/Make.defs @@ -0,0 +1,47 @@ +############################################################################ +# boards/arm/rp23xx/raspberrypi-pico-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) + +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +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 diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_copy_to_ram.ld b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_copy_to_ram.ld new file mode 100644 index 0000000000000..db52cb5543507 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_copy_to_ram.ld @@ -0,0 +1,331 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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 = 4096k + 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*) + + . = 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 */ +} diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_default.ld b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_default.ld new file mode 100644 index 0000000000000..07328ad23c211 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_default.ld @@ -0,0 +1,343 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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 = 4096k + 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*) + + . = 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 */ +} diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_no_flash.ld b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_no_flash.ld new file mode 100644 index 0000000000000..0900fb9e61b9f --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/scripts/memmap_no_flash.ld @@ -0,0 +1,284 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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*) + + . = 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 */ +} diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/.gitignore b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/.gitignore new file mode 100644 index 0000000000000..608fca90dbfc2 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/.gitignore @@ -0,0 +1 @@ +*.image diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt new file mode 100644 index 0000000000000..7f459ff9cef63 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt @@ -0,0 +1,57 @@ +# ############################################################################## +# boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt +# +# 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() + +if(CONFIG_ARCH_LEDS) + list(APPEND SRCS rp23xx_autoleds.c) +else() + list(APPEND SRCS rp23xx_userleds.c) +endif() + +if(CONFIG_ARCH_BUTTONS) + list(APPEND SRCS rp23xx_buttons.c) +endif() + +if(CONFIG_BOARDCTL) + list(APPEND SRCS rp23xx_appinit.c) +endif() + +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() + +if(CONFIG_ETC_ROMFS) + # TODO: etc/init.d/rc.sysinit etc/init.d/rcS +endif() diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs new file mode 100644 index 0000000000000..6af8d704a8839 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs @@ -0,0 +1,91 @@ +############################################################################ +# boards/arm/rp23xx/raspberrypi-pico-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_appinit.c +CSRCS += rp23xx_bringup.c + +ifeq ($(CONFIG_DEV_GPIO),y) +CSRCS += rp23xx_gpio.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += rp23xx_autoleds.c +else +CSRCS += rp23xx_userleds.c +endif + +ifeq ($(CONFIG_ARCH_BUTTONS),y) + CSRCS += rp23xx_buttons.c +endif + +CSRCS += rp23xx_firmware.c + +DEPPATH += --dep-path board +VPATH += :board +CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board + +############################################################################ +# The rules below copy the cyw43439 blob from the pico-sdk. The firmware +# source path is configured via CONFIG_CYW43439_FIRMWARE_BIN_PATH. +############################################################################ + +ifeq ($(CONFIG_IEEE80211_INFINEON_CYW43439),y) + +# When CONFIG_ARCH_BOARD_COMMON is selected, the libboard build runs from +# the common board directory and reaches these board-specific sources via +# the "board" symlink (arch/arm/src/board/board -> this src dir). The +# firmware blob is therefore generated alongside rp23xx_firmware.c so that +# the assembler's ".incbin" (which searches the source file's directory) +# can find it, and the object is made to depend on it so generation always +# runs before the compile. + +FIRMWARE = board$(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 run successfully +# when built with this dummy file. The sole purpose of adding +# this dummy is so the build (and GitHub's validation tests) will +# not fail when the real firmware blob is not present. + +$(FIRMWARE_SRC): + mkdir -p `dirname $(FIRMWARE_SRC)` + echo "dummy" >$(FIRMWARE_SRC) + +$(FIRMWARE): $(FIRMWARE_SRC) + $(call CATFILE, $(FIRMWARE), $(FIRMWARE_SRC)) + +rp23xx_firmware$(OBJEXT): $(FIRMWARE) + +distclean:: + $(call DELFILE, board$(DELIM)cyw43439.firmware.image) + +endif diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_appinit.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_appinit.c new file mode 100644 index 0000000000000..bea44c62dd2c8 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_appinit.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_appinit.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 + +#include +#include + +#include "rp23xx_pico.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value could be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifdef CONFIG_BOARD_LATE_INITIALIZE + /* Board initialization already performed by board_late_initialize() */ + + return OK; +#else + /* Perform board-specific initialization */ + + return rp23xx_bringup(); +#endif +} diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_autoleds.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_autoleds.c new file mode 100644 index 0000000000000..cbe1ae50e60e8 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_autoleds.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_autoleds.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. + * + ****************************************************************************/ + +/* There are four LED status indicators located on the EVK Board. The + * functions of these LEDs include: + * + * - Main Power Supply(D3) + * Green: DC 5V main supply is normal. + * Red: J2 input voltage is over 5.6V. + * Off: The board is not powered. + * - Reset RED LED(D15) + * - OpenSDA LED(D16) + * - USER LED(D18) + * + * Only a single LED, D18, is under software control. + * + * This LED is not used by the board port unless CONFIG_ARCH_LEDS is + * defined. In that case, the usage by the board port is defined in + * include/board.h and src/rp23xx_autoleds.c. The LED is used to encode + * OS-related events as follows: + * + * -------------------- ----------------------- ------ + * SYMBOL Meaning LED + * -------------------- ----------------------- ------ + * + * LED_STARTED 0 NuttX has been started OFF + * LED_HEAPALLOCATE 0 Heap has been allocated OFF + * LED_IRQSENABLED 0 Interrupts enabled OFF + * LED_STACKCREATED 1 Idle stack created ON + * LED_INIRQ 2 In an interrupt N/C + * LED_SIGNAL 2 In a signal handler N/C + * LED_ASSERTION 2 An assertion failed N/C + * LED_PANIC 3 The system has crashed FLASH + * LED_IDLE Not used + * + * Thus if the LED is statically on, NuttX has successfully booted and is, + * apparently, running normally. If the LED is flashing at approximately + * 2Hz, then a fatal error has been detected and the system has halted. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "rp23xx_gpio.h" + +#include "rp23xx_pico.h" + +#ifdef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_autoled_initialize + * + * Description: + * Initialize NuttX-controlled LED logic + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + /* Configure LED GPIO for output */ + + rp23xx_gpio_init(GPIO_LED1); + rp23xx_gpio_setdir(GPIO_LED1, true); +} + +/**************************************************************************** + * Name: board_autoled_on + * + * Description: + * Turn on the "logical" LED state + * + * Input Parameters: + * led - Identifies the "logical" LED state (see definitions in + * include/board.h) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_autoled_on(int led) +{ + bool ledon = true; + + switch (led) + { + case 0: /* LED Off */ + ledon = false; + break; + + case 2: /* LED No change */ + return; + + case 1: /* LED On */ + case 3: /* LED On */ + break; + } + + rp23xx_gpio_put(GPIO_LED1, ledon); /* High illuminates */ +} + +/**************************************************************************** + * Name: board_autoled_off + * + * Description: + * Turn off the "logical" LED state + * + * Input Parameters: + * led - Identifies the "logical" LED state (see definitions in + * include/board.h) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_autoled_off(int led) +{ + switch (led) + { + case 0: /* LED Off */ + case 1: /* LED Off */ + case 3: /* LED Off */ + break; + + case 2: /* LED No change */ + return; + } + + rp23xx_gpio_put(GPIO_LED1, false); /* High illuminates */ +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_boardinitialize.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_boardinitialize.c new file mode 100644 index 0000000000000..7ffdda18fde3b --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_boardinitialize.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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 + +#include + +#include +#include + +#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 --- */ + + /* Set board LED pin */ + + rp23xx_gpio_init(BOARD_GPIO_LED_PIN); + rp23xx_gpio_setdir(BOARD_GPIO_LED_PIN, true); + rp23xx_gpio_put(BOARD_GPIO_LED_PIN, true); +} + +/**************************************************************************** + * 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 drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + rp23xx_bringup(); +} +#endif diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_bringup.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_bringup.c new file mode 100644 index 0000000000000..d8455f40201c4 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_bringup.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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 + +#include +#include +#include + +#include + +#include + +#include + +#include "rp23xx_pico.h" + +#ifdef CONFIG_ARCH_BOARD_COMMON +#include "rp23xx_common_bringup.h" +#endif /* CONFIG_ARCH_BOARD_COMMON */ + +#ifdef CONFIG_USERLED +# include +#endif + +#ifdef CONFIG_RP23XX_INFINEON_CYW43439 +#include "rp23xx_cyw43439.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_RP23XX_INFINEON_CYW43439 + +/* CYW43439 wireless host-interface GPIO assignments. + * + * These match the Raspberry Pi Pico W (RP2040) wiring, which the Pico 2 W + * carries over unchanged so that existing CYW43 software keeps working. + * The data line is bidirectional (single-wire gSPI), so it is also used as + * the host-wake interrupt line. + * + * VERIFY: Pico 2 W datasheet -- confirm these GPIO numbers against the + * official Raspberry Pi Pico 2 W datasheet / schematic before relying on a + * hardware bring-up. + */ + +# define CYW43439_POWER_ON_GPIO 23 /* WL_ON - power/enable */ +# define CYW43439_CHIP_SELECT_GPIO 25 /* WL_CS - chip select (active 0) */ +# define CYW43439_DATA_GPIO 24 /* WL_D - bidirectional gSPI data */ +# define CYW43439_CLOCK_GPIO 29 /* WL_CLK - gSPI clock */ + +#endif + +/**************************************************************************** + * Global Data + ****************************************************************************/ + +#ifdef CONFIG_RP23XX_INFINEON_CYW43439 +gspi_dev_t *g_cyw43439 = NULL; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_bringup + ****************************************************************************/ + +int rp23xx_bringup(void) +{ + int ret = OK; + +#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_USERLED + /* Register the LED driver */ + + 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 + +#ifdef CONFIG_RP23XX_INFINEON_CYW43439 + /* Initialize the cyw43439 (onboard WiFi chip) over PIO-based gSPI. */ + + g_cyw43439 = rp23xx_cyw_setup(CYW43439_POWER_ON_GPIO, + CYW43439_CHIP_SELECT_GPIO, + CYW43439_DATA_GPIO, + CYW43439_CLOCK_GPIO, + CYW43439_DATA_GPIO); + + if (g_cyw43439 == NULL) + { + ret = errno; + + syslog(LOG_ERR, + "Failed to initialize cyw43439 (WiFi chip): %d\n", + ret); + + return ret; + } +#endif + + return ret; +} diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_buttons.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_buttons.c new file mode 100644 index 0000000000000..b984c6458e5fc --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_buttons.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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 + +#include +#include + +#include +#include +#include + +#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 external raspberrypi-pico-2 buttons. */ + +static const uint32_t g_buttons[NUM_BUTTONS] = +{ + GPIO_BTN_USER1, GPIO_BTN_USER2 +}; + +/**************************************************************************** + * 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]); + + /* pull-up = false : pull-down = false */ + + rp23xx_gpio_set_pulls(g_buttons[i], false, 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 */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_firmware.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_firmware.c new file mode 100644 index 0000000000000..58e071503702d --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_firmware.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/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 +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#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+" + STRINGIFY(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 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_gpio.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_gpio.c new file mode 100644 index 0000000000000..cc6b3810ca39e --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_gpio.c @@ -0,0 +1,392 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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 + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "arm_internal.h" +#include "chip.h" +#include "rp23xx_gpio.h" + +#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) + +/* Output pins. GPIO25 is onboard LED any other outputs could be used. + */ + +#define GPIO_OUT1 25 + +/* 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 */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_pico.h b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_pico.h new file mode 100644 index 0000000000000..65bf3393709c8 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_pico.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-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_RASPBERRYPI_PICO_2_SRC_RP23XX_PICO_H +#define __BOARDS_ARM_RP23XX_RASPBERRYPI_PICO_2_SRC_RP23XX_PICO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* LEDs */ + +#define GPIO_LED1 25 /* The board's LED is connected to this pin */ + +/* Buttons */ + +/* Buttons GPIO pins definition */ + +#define GPIO_BTN_USER1 16 +#define GPIO_BTN_USER2 17 + +/* Buttons IRQ definitions */ + +#define MIN_IRQBUTTON BUTTON_USER1 +#define MAX_IRQBUTTON BUTTON_USER2 +#define NUM_IRQBUTTONS (BUTTON_USER1 - BUTTON_USER2 + 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_RASPBERRYPI_PICO_2_SRC_RP23XX_PICO_H */ diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_userleds.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_userleds.c new file mode 100644 index 0000000000000..7e95de4917fcb --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_userleds.c @@ -0,0 +1,214 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_userleds.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 + +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "rp23xx_gpio.h" + +#include "rp23xx_pico.h" + +#ifndef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps an LED number to GPIO pin configuration */ + +static uint32_t g_ledcfg[BOARD_NLEDS] = +{ + GPIO_LED1, +}; + +/**************************************************************************** + * Private Function Protototypes + ****************************************************************************/ + +/* LED Power Management */ + +#ifdef CONFIG_PM +static void led_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +static int led_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_PM +static struct pm_callback_s g_ledscb = +{ + .notify = led_pm_notify, + .prepare = led_pm_prepare, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: led_pm_notify + * + * Description: + * Notify the driver of new power state. This callback is called after + * all drivers have had the opportunity to prepare for the new power state. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void led_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + switch (pmstate) + { + case PM_NORMAL: + { + /* Restore normal LEDs operation */ + + board_userled(BOARD_LED, true); + } + break; + + case PM_IDLE: + { + /* Entering IDLE mode - Turn leds off */ + + board_userled(BOARD_LED, false); + } + break; + + case PM_STANDBY: + { + /* Entering STANDBY mode - Logic for PM_STANDBY goes here */ + } + break; + + case PM_SLEEP: + { + /* Entering SLEEP mode - Logic for PM_SLEEP goes here */ + } + break; + + default: + { + /* Should not get here */ + } + break; + } +} +#endif + +/**************************************************************************** + * Name: led_pm_prepare + * + * Description: + * Request the driver to prepare for a new power state. This is a warning + * that the system is about to enter into a new power state. The driver + * should begin whatever operations that may be required to enter power + * state. The driver may abort the state change mode by returning a + * non-zero value from the callback function. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int led_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + /* No preparation to change power modes is required by the LEDs driver. + * We always accept the state change by returning OK. + */ + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_userled_initialize + ****************************************************************************/ + +uint32_t board_userled_initialize(void) +{ + /* Configure LED GPIO for output */ + + rp23xx_gpio_init(GPIO_LED1); + rp23xx_gpio_setdir(GPIO_LED1, true); + + return BOARD_NLEDS; +} + +/**************************************************************************** + * Name: board_userled + ****************************************************************************/ + +void board_userled(int led, bool ledon) +{ + if ((unsigned)led < BOARD_NLEDS) + { + rp23xx_gpio_put(g_ledcfg[led], ledon); + } +} + +/**************************************************************************** + * Name: board_userled_all + ****************************************************************************/ + +void board_userled_all(uint32_t ledset) +{ + rp23xx_gpio_put(GPIO_LED1, (ledset & BOARD_LED1_BIT)); +} + +/**************************************************************************** + * Name: rp23xx_led_pminitialize + ****************************************************************************/ + +#ifdef CONFIG_PM +void rp23xx_led_pminitialize(void) +{ + /* Register to receive power management callbacks */ + + int ret = pm_register(&g_ledscb); + if (ret != OK) + { + board_autoled_on(LED_ASSERTION); + } +} +#endif /* CONFIG_PM */ + +#endif /* !CONFIG_ARCH_LEDS */ From 9bc86d8aa99f8650953cf3cf1ad406cb851f2dd4 Mon Sep 17 00:00:00 2001 From: Ricard Rosson Date: Sat, 11 Jul 2026 05:38:19 +0100 Subject: [PATCH 2/4] rp23xx_usbdev: fix bulk RX overrun, double-arm and AVAIL ordering Port the three RP2040 USB device fixes (PR #19378) to the RP2350 controller, without which CDC-NCM RX returns zero-length reads and the data-PID toggle desynchronises under load: - Clamp the bulk-OUT read length to the endpoint maxpacket size before arming the hardware buffer. The buffer-control LEN field is 10 bits; a larger request overflows it and the host sees zero-byte reads. - Track whether a request already armed the hardware buffer (new rp23xx_req_s.armed) so a request resubmitted from its own completion callback is not armed a second time. A double arm toggles the data PID and the host drops the packet. - Set the AVAILABLE bit in a separate write after the LEN/PID word, per RP2040 datasheet section 4.1.2.5.1, instead of in the same store. Co-Authored-By: Claude Opus 4.8 Signed-off-by: Ricard Rosson --- arch/arm/src/rp23xx/rp23xx_usbdev.c | 72 ++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/rp23xx/rp23xx_usbdev.c b/arch/arm/src/rp23xx/rp23xx_usbdev.c index 582f9cd430730..f4652abc18d1c 100644 --- a/arch/arm/src/rp23xx/rp23xx_usbdev.c +++ b/arch/arm/src/rp23xx/rp23xx_usbdev.c @@ -218,6 +218,7 @@ struct rp23xx_req_s { struct usbdev_req_s req; /* Standard USB request */ struct rp23xx_req_s *flink; /* Supports a singly linked list */ + bool armed; /* Hardware buffer armed for this request */ }; /* This is the internal representation of an endpoint */ @@ -472,6 +473,7 @@ static void rp23xx_update_buffer_control(struct rp23xx_ep_s *privep, uint32_t or_mask) { uint32_t value = 0; + int i; if (and_mask) { @@ -481,6 +483,24 @@ static void rp23xx_update_buffer_control(struct rp23xx_ep_s *privep, if (or_mask) { value |= or_mask; + + if (or_mask & RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL) + { + /* RP2040 datasheet 4.1.2.5.1: the AVAILABLE bit must be set + * after the rest of the buffer control register has been + * written and had time to settle across the clock domain + * crossing, or the controller may act on a stale length/PID. + * 12 CPU cycles covers system clocks up to 12x clk_usb. + */ + + putreg32(value & ~RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL, + privep->buf_ctrl); + + for (i = 0; i < 12; i++) + { + __asm__ volatile("nop"); + } + } } putreg32(value, privep->buf_ctrl); @@ -534,6 +554,20 @@ static int rp23xx_epread(struct rp23xx_ep_s *privep, uint16_t nbytes) uint32_t val; irqstate_t flags; + /* The hardware receives a single USB packet into the buffer, and the + * buffer-control LEN field is only 10 bits wide. Arm the buffer for at + * most one maximum-size packet; rp23xx_rxcomplete accumulates the request + * across multiple packets and re-arms until it is satisfied or a short + * packet arrives. Passing the full (possibly multi-kByte) request length + * would overflow LEN and corrupt the neighbouring control bits, making the + * transfer complete immediately with zero bytes. + */ + + if (nbytes > privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + val = nbytes | RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL | (privep->next_pid ? @@ -631,6 +665,7 @@ static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result) static void rp23xx_txcomplete(struct rp23xx_ep_s *privep) { struct rp23xx_req_s *privreq; + bool completed = false; privreq = rp23xx_rqpeek(privep); if (!privreq) @@ -647,10 +682,31 @@ static void rp23xx_txcomplete(struct rp23xx_ep_s *privep) usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); privep->txnullpkt = 0; rp23xx_reqcomplete(privep, OK); + completed = true; + } + } + + if (completed) + { + /* Start the next queued request -- unless it was already armed. The + * completion callback above may have submitted a new request on the + * now idle endpoint; epsubmit then armed the hardware buffer itself, + * and arming it a second time here would toggle the data PID twice + * and make the host silently discard the packet as a retransmission. + */ + + privreq = rp23xx_rqpeek(privep); + if (privreq && !privreq->armed) + { + rp23xx_wrrequest(privep); } } + else if (privreq) + { + /* Continue with the next packet of the in-progress request */ - rp23xx_wrrequest(privep); + rp23xx_wrrequest(privep); + } } /**************************************************************************** @@ -683,6 +739,7 @@ static int rp23xx_wrrequest(struct rp23xx_ep_s *privep) { if (privep->epphy == 0) { + privreq->armed = true; rp23xx_epwrite(privep, NULL, 0); } else @@ -708,6 +765,7 @@ static int rp23xx_wrrequest(struct rp23xx_ep_s *privep) * bytes to send. */ + privreq->armed = true; privep->txnullpkt = 0; if (bytesleft > privep->ep.maxpacket) { @@ -763,6 +821,16 @@ static void rp23xx_rxcomplete(struct rp23xx_ep_s *privep) { usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); rp23xx_reqcomplete(privep, OK); + + /* Re-arm only if the completion callback didn't already do it by + * resubmitting a request (see rp23xx_txcomplete). + */ + + privreq = rp23xx_rqpeek(privep); + if (privreq && privreq->armed) + { + return; + } } rp23xx_rdrequest(privep); @@ -793,6 +861,7 @@ static int rp23xx_rdrequest(struct rp23xx_ep_s *privep) usbtrace(TRACE_READ(privep->epphy), privreq->req.len); + privreq->armed = true; return rp23xx_epread(privep, privreq->req.len); } @@ -1622,6 +1691,7 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep, req->result = -EINPROGRESS; req->xfrd = 0; + privreq->armed = false; flags = enter_critical_section(); From f72dbf9a6b6073bd89d1f73008dd4e3d21715fea Mon Sep 17 00:00:00 2001 From: Ricard Rosson Date: Sat, 11 Jul 2026 05:38:28 +0100 Subject: [PATCH 3/4] rp23xx/raspberrypi-pico-2-w: CDC-ACM + CDC-NCM composite USB device Add a composite USB device that presents a CDC-ACM serial console and a CDC-NCM network interface (eth0) at once, for the Pico 2 W access device: the host gets a console and a USB NIC over a single connection. The two classes must use disjoint endpoint numbers or they collide, so board_composite_connect() assigns CDC-ACM 1/2/3 and CDC-NCM 4/5/6. Build the new rp23xx_composite.c under CONFIG_USBDEV_COMPOSITE (CMake and Make.defs). The common bringup optionally autostarts the "portalup" helper (CONFIG_EXAMPLES_PORTALUP) which connects the composite, brings up the interfaces and starts the mDNS responder. Co-Authored-By: Claude Opus 4.8 Signed-off-by: Ricard Rosson --- .../rp23xx/common/src/rp23xx_common_bringup.c | 26 ++++ .../raspberrypi-pico-2-w/src/CMakeLists.txt | 4 + .../rp23xx/raspberrypi-pico-2-w/src/Make.defs | 4 + .../src/rp23xx_composite.c | 123 ++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c diff --git a/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c b/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c index 10b941ce3c650..75cb29a92387b 100644 --- a/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c +++ b/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c @@ -28,6 +28,11 @@ #include #include #include +#ifdef CONFIG_EXAMPLES_PORTALUP +# include +# include +# include +#endif #include @@ -74,6 +79,11 @@ int rp23xx_common_bringup(void) { int ret = 0; +#ifdef CONFIG_EXAMPLES_PORTALUP + FAR char *portalup_argv[2]; + pid_t portalup_pid; +#endif + #ifdef CONFIG_RP23XX_I2C_DRIVER #ifdef CONFIG_RP23XX_I2C0 ret = board_i2cdev_initialize(0); @@ -520,5 +530,21 @@ int rp23xx_common_bringup(void) } #endif + +#ifdef CONFIG_EXAMPLES_PORTALUP + /* Autostart the access-device boot helper: bring up wlan0 and start the + * mDNS responder so the board is reachable by name at boot. + */ + + portalup_argv[0] = "portalup"; + portalup_argv[1] = NULL; + + if (posix_spawn(&portalup_pid, "portalup", NULL, NULL, + portalup_argv, NULL) != 0) + { + syslog(LOG_ERR, "ERROR: failed to spawn portalup: %d\n", errno); + } +#endif + return ret; } diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt index 7f459ff9cef63..7c2dd142f342a 100644 --- a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt @@ -38,6 +38,10 @@ if(CONFIG_BOARDCTL) list(APPEND SRCS rp23xx_appinit.c) endif() +if(CONFIG_USBDEV_COMPOSITE) + list(APPEND SRCS rp23xx_composite.c) +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_BOOT_RUNFROMFLASH) diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs index 6af8d704a8839..c31c11f40548b 100644 --- a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs @@ -89,3 +89,7 @@ distclean:: $(call DELFILE, board$(DELIM)cyw43439.firmware.image) endif + +ifeq ($(CONFIG_USBDEV_COMPOSITE),y) +CSRCS += rp23xx_composite.c +endif diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c new file mode 100644 index 0000000000000..8dd9a8e4b6177 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.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 +#include +#include +#include + +#include +#include + +#ifdef CONFIG_CDCACM_COMPOSITE +# include +#endif +#ifdef CONFIG_CDCNCM_COMPOSITE +# include +#endif + +#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_composite_initialize + ****************************************************************************/ + +int board_composite_initialize(int port) +{ + return OK; +} + +/**************************************************************************** + * Name: board_composite_connect + * + * Description: + * Connect the CDC/ACM serial console + CDC/NCM network composite device. + * The two classes use disjoint endpoint numbers (ACM: 1/2/3, NCM: 4/5/6) + * so they can coexist in one configuration. + * + ****************************************************************************/ + +void *board_composite_connect(int port, int configid) +{ + if (configid == 0) + { + struct composite_devdesc_s dev[2]; + int ifnobase = 0; + int strbase = COMPOSITE_NSTRIDS; + int n = 0; + +#ifdef CONFIG_CDCACM_COMPOSITE + /* CDC/ACM serial console */ + + cdcacm_get_composite_devdesc(&dev[n]); + + dev[n].classobject = cdcacm_classobject; + dev[n].uninitialize = cdcacm_uninitialize; + + dev[n].devinfo.ifnobase = ifnobase; + dev[n].minor = 0; + dev[n].devinfo.strbase = strbase; + + dev[n].devinfo.epno[CDCACM_EP_INTIN_IDX] = 1; + dev[n].devinfo.epno[CDCACM_EP_BULKIN_IDX] = 2; + dev[n].devinfo.epno[CDCACM_EP_BULKOUT_IDX] = 3; + + ifnobase += dev[n].devinfo.ninterfaces; + strbase += dev[n].devinfo.nstrings; + n++; +#endif + +#ifdef CONFIG_CDCNCM_COMPOSITE + /* CDC/NCM network device */ + + cdcncm_get_composite_devdesc(&dev[n]); + + dev[n].devinfo.ifnobase = ifnobase; + dev[n].minor = 0; + dev[n].devinfo.strbase = strbase; + + dev[n].devinfo.epno[CDCNCM_EP_INTIN_IDX] = 4; + dev[n].devinfo.epno[CDCNCM_EP_BULKIN_IDX] = 5; + dev[n].devinfo.epno[CDCNCM_EP_BULKOUT_IDX] = 6; + + ifnobase += dev[n].devinfo.ninterfaces; + strbase += dev[n].devinfo.nstrings; + n++; +#endif + + return composite_initialize(composite_getdevdescs(), dev, n); + } + else + { + return NULL; + } +} + +#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */ From 380a2e7c50cc49c4759309715b631f6ca0b2bfe9 Mon Sep 17 00:00:00 2001 From: Ricard Rosson Date: Sat, 11 Jul 2026 06:21:58 +0100 Subject: [PATCH 4/4] rp23xx/raspberrypi-pico-2-w: add access-device config Add an "access" board configuration for the Pico 2 W access device: a WiFi station plus a composite USB device (CDC-ACM console + CDC-NCM NIC) with a DHCP server, and an mDNS responder pinned to the USB NIC (eth0) via CONFIG_NETUTILS_MDNS_BIND_IFNAME so a host plugged into USB resolves the board by name without advertising onto the WiFi network. The portalup boot helper brings the interfaces up and starts the responder. Requires an apps tree providing EXAMPLES_PORTALUP and the mDNS single-interface bind option, e.g.: ./tools/configure.sh -a ../apps-integration raspberrypi-pico-2-w:access Co-Authored-By: Claude Opus 4.8 Signed-off-by: Ricard Rosson --- .../configs/access/defconfig | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/configs/access/defconfig diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/configs/access/defconfig b/boards/arm/rp23xx/raspberrypi-pico-2-w/configs/access/defconfig new file mode 100644 index 0000000000000..578d0a47ba820 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/configs/access/defconfig @@ -0,0 +1,113 @@ +# +# 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_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_STANDARD_SERIAL is not set +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="raspberrypi-pico-2-w" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_W=y +CONFIG_ARCH_CHIP="rp23xx" +CONFIG_ARCH_CHIP_RP23XX=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=10450 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_COMPOSITE=y +CONFIG_CDCACM_CONSOLE=y +CONFIG_CDCNCM_COMPOSITE=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DISABLE_POSIX_TIMERS=y +CONFIG_DRIVERS_IEEE80211=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_MDNSD=y +CONFIG_EXAMPLES_MDNS_SERVICE="_http._tcp.local" +CONFIG_EXAMPLES_MDNS_SERVICE_PORT="80" +CONFIG_EXAMPLES_PORTALUP=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=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_IOB_NBUFFERS=196 +CONFIG_IOB_NCHAINS=24 +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIB_MDNS=y +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="x6PWXaErWMJy" +CONFIG_NETINIT_WAPI_SSID="SKYMGIII" +CONFIG_NETUTILS_DHCPD=y +CONFIG_NETUTILS_DHCPD_DNSIP=0x0 +CONFIG_NETUTILS_DHCPD_NETMASK=0xFFFFFF00 +CONFIG_NETUTILS_DHCPD_ROUTERIP=0x0 +CONFIG_NETUTILS_DHCPD_STARTIP=0xC0A80702 +CONFIG_NETUTILS_MDNS=y +CONFIG_NETUTILS_MDNS_BIND_IFNAME="eth0" +CONFIG_NETUTILS_MDNS_DAEMON=y +CONFIG_NETUTILS_MDNS_STACKSIZE=8192 +CONFIG_NETUTILS_TELNETD=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_CDCNCM=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_IGMP=y +CONFIG_NET_LOOPBACK=y +CONFIG_NET_LOOPBACK_PKTSIZE=1024 +CONFIG_NET_TCP=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_UDP=y +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_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=9 +CONFIG_START_MONTH=2 +CONFIG_START_YEAR=2021 +CONFIG_SYSLOG_BUFFER=y +CONFIG_SYSLOG_INTBUFFER=y +CONFIG_SYSLOG_INTBUFSIZE=2048 +CONFIG_SYSLOG_PROCESSID=y +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_TELNET_CLIENT=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGINT_CHAR=0x03 +CONFIG_TTY_SIGTSTP=y +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_COMPOSITE=y +CONFIG_WIRELESS_WAPI=y +CONFIG_WIRELESS_WAPI_CMDTOOL=y +CONFIG_WQUEUE_NOTIFIER=y