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/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(); 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/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/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/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 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..7c2dd142f342a --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt @@ -0,0 +1,61 @@ +# ############################################################################## +# 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() + +if(CONFIG_USBDEV_COMPOSITE) + list(APPEND SRCS rp23xx_composite.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..c31c11f40548b --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs @@ -0,0 +1,95 @@ +############################################################################ +# 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 + +ifeq ($(CONFIG_USBDEV_COMPOSITE),y) +CSRCS += rp23xx_composite.c +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_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 */ 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 */