mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
Changes for pico2_w (#1816)
* Add board file for pico2_w This is a copy of pico2 with the definitions from pico_w added. Set PICO_BOARD=pico2_w * Simplify CYW43 PIO config cyw43_spi_init contains code to find a free PIO and state machine. This can all be replaced with pio_claim_free_sm_and_add_program_for_gpio_range * Make CYW43 gpio pins configurable at build time The CYW43 gpio pins are currently hardcoded. Give the defines better names and make them overrideable at build time. Note: CYW43_PIN_WL_REG_ON and CYW43_PIN_WL_HOST_WAKE are already used by the driver via cyw43_hal_* functions * Fix pio initialisation Need to make sure the pio can work with all the gpios * Add missing doxygen for cyw43_set_pio_clock_divisor * Support dynamic configuration of cyw43 gpio pins Add CYW43_PIN_WL_DYNAMIC that means cyw43 gpio pins can be changed at runtime. Then CYW43_PIN_WL_* calls cyw43_get_pin_wl to get the gpio out of the array. cyw43_set_pins_wl can be used to change the cyw43 gpio pins although care is needed when calling this? * Some fixes for cyw32 gpio > 32 * Allow CYW43 to be configured with cmake * Add default config of CYW43_WL_GPIO_COUNT to cyw43_configport.h * Fix some review comments Add some PICO_CMAKE_CONFIG Stop using gpio_*_mask64 functions
This commit is contained in:
parent
6500c59d70
commit
af2f42613e
6 changed files with 351 additions and 85 deletions
116
src/boards/include/boards/pico2_w.h
Normal file
116
src/boards/include/boards/pico2_w.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------
|
||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// -----------------------------------------------------
|
||||
|
||||
// This header may be included by other board headers as "boards/pico2_w.h"
|
||||
|
||||
// pico_cmake_set PICO_PLATFORM=rp2350
|
||||
// pico_cmake_set PICO_CYW43_SUPPORTED = 1
|
||||
|
||||
#ifndef _BOARDS_PICO2_W_H
|
||||
#define _BOARDS_PICO2_W_H
|
||||
|
||||
// For board detection
|
||||
#define RASPBERRYPI_PICO2_W
|
||||
|
||||
// --- RP2350 VARIANT ---
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// --- UART ---
|
||||
#ifndef PICO_DEFAULT_UART
|
||||
#define PICO_DEFAULT_UART 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_UART_TX_PIN
|
||||
#define PICO_DEFAULT_UART_TX_PIN 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_UART_RX_PIN
|
||||
#define PICO_DEFAULT_UART_RX_PIN 1
|
||||
#endif
|
||||
|
||||
// --- LED ---
|
||||
// no PICO_DEFAULT_LED_PIN - LED is on Wireless chip
|
||||
// no PICO_DEFAULT_WS2812_PIN
|
||||
|
||||
// --- I2C ---
|
||||
#ifndef PICO_DEFAULT_I2C
|
||||
#define PICO_DEFAULT_I2C 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||
#define PICO_DEFAULT_I2C_SDA_PIN 4
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_I2C_SCL_PIN
|
||||
#define PICO_DEFAULT_I2C_SCL_PIN 5
|
||||
#endif
|
||||
|
||||
// --- SPI ---
|
||||
#ifndef PICO_DEFAULT_SPI
|
||||
#define PICO_DEFAULT_SPI 0
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_SCK_PIN
|
||||
#define PICO_DEFAULT_SPI_SCK_PIN 18
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_TX_PIN
|
||||
#define PICO_DEFAULT_SPI_TX_PIN 19
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_RX_PIN
|
||||
#define PICO_DEFAULT_SPI_RX_PIN 16
|
||||
#endif
|
||||
#ifndef PICO_DEFAULT_SPI_CSN_PIN
|
||||
#define PICO_DEFAULT_SPI_CSN_PIN 17
|
||||
#endif
|
||||
|
||||
// --- FLASH ---
|
||||
|
||||
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
|
||||
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 2
|
||||
#endif
|
||||
|
||||
// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024)
|
||||
#ifndef PICO_FLASH_SIZE_BYTES
|
||||
#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024)
|
||||
#endif
|
||||
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
|
||||
// note the SMSP mode pin is on WL_GPIO1
|
||||
|
||||
#ifndef CYW43_WL_GPIO_COUNT
|
||||
#define CYW43_WL_GPIO_COUNT 3
|
||||
#endif
|
||||
|
||||
#ifndef CYW43_WL_GPIO_LED_PIN
|
||||
#define CYW43_WL_GPIO_LED_PIN 0
|
||||
#endif
|
||||
|
||||
// If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS.
|
||||
// This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered.
|
||||
// PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined.
|
||||
#ifndef CYW43_WL_GPIO_VBUS_PIN
|
||||
#define CYW43_WL_GPIO_VBUS_PIN 2
|
||||
#endif
|
||||
|
||||
// If CYW43_USES_VSYS_PIN is defined then CYW43 uses the VSYS GPIO (defined by PICO_VSYS_PIN) for other purposes.
|
||||
// If this is the case, to use the VSYS GPIO it's necessary to ensure CYW43 is not using it.
|
||||
// This can be achieved by wrapping the use of the VSYS GPIO in cyw43_thread_enter / cyw43_thread_exit.
|
||||
#ifndef CYW43_USES_VSYS_PIN
|
||||
#define CYW43_USES_VSYS_PIN 1
|
||||
#endif
|
||||
|
||||
// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC.
|
||||
// There is an example in adc/read_vsys in pico-examples.
|
||||
#ifndef PICO_VSYS_PIN
|
||||
#define PICO_VSYS_PIN 29
|
||||
#endif
|
||||
|
||||
#ifndef PICO_RP2350_A2_SUPPORTED
|
||||
#define PICO_RP2350_A2_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -86,14 +86,6 @@
|
|||
#define PICO_RP2040_B1_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#ifndef CYW43_PIN_WL_HOST_WAKE
|
||||
#define CYW43_PIN_WL_HOST_WAKE 24
|
||||
#endif
|
||||
|
||||
#ifndef CYW43_PIN_WL_REG_ON
|
||||
#define CYW43_PIN_WL_REG_ON 23
|
||||
#endif
|
||||
|
||||
#ifndef CYW43_WL_GPIO_COUNT
|
||||
#define CYW43_WL_GPIO_COUNT 3
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -56,6 +56,43 @@ if (EXISTS ${PICO_CYW43_DRIVER_PATH}/${CYW43_DRIVER_TEST_FILE})
|
|||
hardware_exception
|
||||
)
|
||||
|
||||
if (CYW43_DEFAULT_PIN_WL_REG_ON)
|
||||
# PICO_CMAKE_CONFIG: CYW43_DEFAULT_PIN_WL_REG_ON, gpio pin to power up the cyw43 chip, type=int, default=23, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_DEFAULT_PIN_WL_REG_ON=${CYW43_DEFAULT_PIN_WL_REG_ON})
|
||||
endif()
|
||||
if (CYW43_DEFAULT_PIN_WL_DATA_OUT)
|
||||
# PICO_CMAKE_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_OUT, gpio pin for spi data out to the cyw43 chip, type=int, default=24, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_DEFAULT_PIN_WL_DATA_OUT=${CYW43_DEFAULT_PIN_WL_DATA_OUT})
|
||||
endif()
|
||||
if (CYW43_DEFAULT_PIN_WL_DATA_IN)
|
||||
# PICO_CMAKE_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_IN, gpio pin for spi data in from the cyw43 chip, type=int, default=24, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_DEFAULT_PIN_WL_DATA_IN=${CYW43_DEFAULT_PIN_WL_DATA_IN})
|
||||
endif()
|
||||
if (CYW43_DEFAULT_PIN_WL_HOST_WAKE)
|
||||
# PICO_CMAKE_CONFIG: CYW43_DEFAULT_PIN_WL_HOST_WAKE, gpio (irq) pin for the irq line from the cyw43 chip, type=int, default=24, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_DEFAULT_PIN_WL_HOST_WAKE=${CYW43_DEFAULT_PIN_WL_HOST_WAKE})
|
||||
endif()
|
||||
if (CYW43_DEFAULT_PIN_WL_CLOCK)
|
||||
# PICO_CMAKE_CONFIG: CYW43_DEFAULT_PIN_WL_HOST_WAKE, gpio pin for the spi clock line to the cyw43 chip, type=int, default=29, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_DEFAULT_PIN_WL_CLOCK=${CYW43_DEFAULT_PIN_WL_CLOCK})
|
||||
endif()
|
||||
if (CYW43_DEFAULT_PIN_WL_CS)
|
||||
# PICO_CMAKE_CONFIG: CYW43_DEFAULT_PIN_WL_CS, gpio pin for the spi chip select to the cyw43 chip, type=int, default=25, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_DEFAULT_PIN_WL_CS=${CYW43_DEFAULT_PIN_WL_CS})
|
||||
endif()
|
||||
if (CYW43_PIO_CLOCK_DIV_INT)
|
||||
# PICO_CMAKE_CONFIG: CYW43_PIO_CLOCK_DIV_INT, integer component of pio clock divider used for cyw43 comms, type=int, default=2, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_PIO_CLOCK_DIV_INT=${CYW43_PIO_CLOCK_DIV_INT})
|
||||
endif()
|
||||
if (CYW43_PIO_CLOCK_DIV_FRAC)
|
||||
# PICO_CMAKE_CONFIG: CYW43_PIO_CLOCK_DIV_FRAC, fractional component of pio clock divider used for cyw43 comms, type=int, default=0, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_PIO_CLOCK_DIV_FRAC=${CYW43_PIO_CLOCK_DIV_FRAC})
|
||||
endif()
|
||||
if (CYW43_PIO_CLOCK_DIV_DYNAMIC)
|
||||
# PICO_CMAKE_CONFIG: CYW43_PIO_CLOCK_DIV_DYNAMIC, flag used to enable dynamic pio clock divider API, type=bool, default=false, group=pico_cyw43_driver
|
||||
target_compile_definitions(cyw43_driver_picow INTERFACE CYW43_PIO_CLOCK_DIV_DYNAMIC=${CYW43_PIO_CLOCK_DIV_DYNAMIC})
|
||||
endif()
|
||||
|
||||
# Note: This is used by MP, so check for issues when making changes
|
||||
# e.g. Don't add new depenedences
|
||||
pico_add_library(pico_btstack_hci_transport_cyw43 NOFLAG)
|
||||
|
|
|
|||
|
|
@ -21,15 +21,15 @@
|
|||
#include "pico/cyw43_driver.h"
|
||||
|
||||
#if CYW43_SPI_PIO
|
||||
#define WL_REG_ON 23
|
||||
#define DATA_OUT_PIN 24u
|
||||
#define DATA_IN_PIN 24u
|
||||
#define IRQ_PIN 24u
|
||||
// #define MONITOR_PIN 3u
|
||||
#define CLOCK_PIN 29u
|
||||
#define CS_PIN 25u
|
||||
|
||||
#define IRQ_SAMPLE_DELAY_NS 100
|
||||
|
||||
#if !CYW43_PIN_WL_DYNAMIC && PICO_PIO_USE_GPIO_BASE
|
||||
// The pins should all work in the same gpio base
|
||||
static_assert((CYW43_PIN_WL_DATA_OUT < 32 && CYW43_PIN_WL_DATA_IN < 32 && CYW43_PIN_WL_CLOCK < 32) ||
|
||||
(CYW43_PIN_WL_DATA_OUT >= 16 && CYW43_PIN_WL_DATA_IN >= 16 && CYW43_PIN_WL_CLOCK >= 16), "");
|
||||
#endif
|
||||
|
||||
#ifdef CYW43_SPI_PROGRAM_NAME
|
||||
#define SPI_PROGRAM_NAME CYW43_SPI_PROGRAM_NAME
|
||||
#else
|
||||
|
|
@ -85,16 +85,10 @@ __force_inline static uint32_t __swap16x2(uint32_t a) {
|
|||
}
|
||||
#define SWAP32(a) __swap16x2(a)
|
||||
|
||||
#ifndef CYW43_SPI_PIO_PREFERRED_PIO
|
||||
#define CYW43_SPI_PIO_PREFERRED_PIO 1
|
||||
#endif
|
||||
static_assert(CYW43_SPI_PIO_PREFERRED_PIO >=0 && CYW43_SPI_PIO_PREFERRED_PIO < NUM_PIOS, "");
|
||||
|
||||
typedef struct {
|
||||
pio_hw_t *pio;
|
||||
uint8_t pio_func_sel;
|
||||
int8_t pio_offset;
|
||||
int8_t pio_sm;
|
||||
PIO pio;
|
||||
uint pio_offset;
|
||||
uint pio_sm;
|
||||
int8_t dma_out;
|
||||
int8_t dma_in;
|
||||
} bus_data_t;
|
||||
|
|
@ -105,65 +99,46 @@ int cyw43_spi_init(cyw43_int_t *self) {
|
|||
// Only does something if CYW43_LOGIC_DEBUG=1
|
||||
logic_debug_init();
|
||||
|
||||
static_assert(NUM_PIOS == 2 || NUM_PIOS == 3, "");
|
||||
|
||||
#if NUM_PIOS == 2
|
||||
pio_hw_t *pios[NUM_PIOS] = {pio0, pio1};
|
||||
#else
|
||||
pio_hw_t *pios[NUM_PIOS] = {pio0, pio1, pio2};
|
||||
#endif
|
||||
uint pio_index = CYW43_SPI_PIO_PREFERRED_PIO;
|
||||
// Check we can add the program
|
||||
for(uint i=1; i < NUM_PIOS;i++) {
|
||||
if (pio_can_add_program(pios[pio_index], &SPI_PROGRAM_FUNC)) break;
|
||||
if (i == NUM_PIOS - 1) {
|
||||
return CYW43_FAIL_FAST_CHECK(-CYW43_EIO);
|
||||
}
|
||||
pio_index = (pio_index + 1 ) % NUM_PIOS;
|
||||
}
|
||||
assert(!self->bus_data);
|
||||
self->bus_data = &bus_data_instance;
|
||||
bus_data_t *bus_data = (bus_data_t *)self->bus_data;
|
||||
bus_data->pio = pios[pio_index];
|
||||
bus_data->pio = NULL;
|
||||
bus_data->dma_in = -1;
|
||||
bus_data->dma_out = -1;
|
||||
|
||||
static_assert(GPIO_FUNC_PIO1 == GPIO_FUNC_PIO0 + 1, "");
|
||||
bus_data->pio_func_sel = GPIO_FUNC_PIO0 + pio_index;
|
||||
bus_data->pio_sm = (int8_t)pio_claim_unused_sm(bus_data->pio, false);
|
||||
if (bus_data->pio_sm < 0) {
|
||||
const uint min_gpio = MIN(CYW43_PIN_WL_CLOCK, MIN(CYW43_PIN_WL_DATA_IN, CYW43_PIN_WL_DATA_OUT));
|
||||
const uint max_gpio = MAX(CYW43_PIN_WL_CLOCK, MAX(CYW43_PIN_WL_DATA_IN, CYW43_PIN_WL_DATA_OUT));
|
||||
if (!pio_claim_free_sm_and_add_program_for_gpio_range(&SPI_PROGRAM_FUNC, &bus_data->pio, &bus_data->pio_sm, &bus_data->pio_offset, min_gpio, max_gpio - min_gpio + 1, true)) {
|
||||
cyw43_spi_deinit(self);
|
||||
return CYW43_FAIL_FAST_CHECK(-CYW43_EIO);
|
||||
}
|
||||
|
||||
bus_data->pio_offset = pio_add_program(bus_data->pio, &SPI_PROGRAM_FUNC);
|
||||
pio_sm_config config = SPI_PROGRAM_GET_DEFAULT_CONFIG_FUNC(bus_data->pio_offset);
|
||||
|
||||
sm_config_set_clkdiv_int_frac(&config, cyw43_pio_clock_div_int, cyw43_pio_clock_div_frac);
|
||||
hw_write_masked(&pads_bank0_hw->io[CLOCK_PIN],
|
||||
hw_write_masked(&pads_bank0_hw->io[CYW43_PIN_WL_CLOCK],
|
||||
(uint)PADS_DRIVE_STRENGTH << PADS_BANK0_GPIO0_DRIVE_LSB,
|
||||
PADS_BANK0_GPIO0_DRIVE_BITS
|
||||
);
|
||||
hw_write_masked(&pads_bank0_hw->io[CLOCK_PIN],
|
||||
hw_write_masked(&pads_bank0_hw->io[CYW43_PIN_WL_CLOCK],
|
||||
(uint)1 << PADS_BANK0_GPIO0_SLEWFAST_LSB,
|
||||
PADS_BANK0_GPIO0_SLEWFAST_BITS
|
||||
);
|
||||
|
||||
sm_config_set_out_pins(&config, DATA_OUT_PIN, 1);
|
||||
sm_config_set_in_pins(&config, DATA_IN_PIN);
|
||||
sm_config_set_set_pins(&config, DATA_OUT_PIN, 1);
|
||||
sm_config_set_out_pins(&config, CYW43_PIN_WL_DATA_OUT, 1);
|
||||
sm_config_set_in_pins(&config, CYW43_PIN_WL_DATA_IN);
|
||||
sm_config_set_set_pins(&config, CYW43_PIN_WL_DATA_OUT, 1);
|
||||
sm_config_set_sideset(&config, 1, false, false);
|
||||
sm_config_set_sideset_pins(&config, CLOCK_PIN);
|
||||
sm_config_set_sideset_pins(&config, CYW43_PIN_WL_CLOCK);
|
||||
sm_config_set_in_shift(&config, false, true, 32);
|
||||
sm_config_set_out_shift(&config, false, true, 32);
|
||||
hw_set_bits(&bus_data->pio->input_sync_bypass, 1u << DATA_IN_PIN);
|
||||
hw_set_bits(&bus_data->pio->input_sync_bypass, 1u << (CYW43_PIN_WL_DATA_IN - pio_get_gpio_base(bus_data->pio)));
|
||||
pio_sm_set_config(bus_data->pio, bus_data->pio_sm, &config);
|
||||
pio_sm_set_consecutive_pindirs(bus_data->pio, bus_data->pio_sm, CLOCK_PIN, 1, true);
|
||||
gpio_set_function(DATA_OUT_PIN, bus_data->pio_func_sel);
|
||||
pio_sm_set_consecutive_pindirs(bus_data->pio, bus_data->pio_sm, CYW43_PIN_WL_CLOCK, 1, true);
|
||||
gpio_set_function(CYW43_PIN_WL_DATA_OUT, pio_get_funcsel(bus_data->pio));
|
||||
|
||||
// Set data pin to pull down and schmitt
|
||||
gpio_set_pulls(DATA_IN_PIN, false, true);
|
||||
gpio_set_input_hysteresis_enabled(DATA_IN_PIN, true);
|
||||
gpio_set_pulls(CYW43_PIN_WL_DATA_IN, false, true);
|
||||
gpio_set_input_hysteresis_enabled(CYW43_PIN_WL_DATA_IN, true);
|
||||
|
||||
pio_sm_exec(bus_data->pio, bus_data->pio_sm, pio_encode_set(pio_pins, 1));
|
||||
|
||||
|
|
@ -179,10 +154,9 @@ int cyw43_spi_init(cyw43_int_t *self) {
|
|||
void cyw43_spi_deinit(cyw43_int_t *self) {
|
||||
if (self->bus_data) {
|
||||
bus_data_t *bus_data = (bus_data_t *)self->bus_data;
|
||||
if (bus_data->pio_sm >= 0) {
|
||||
if (bus_data->pio_offset != -1)
|
||||
pio_remove_program(bus_data->pio, &SPI_PROGRAM_FUNC, bus_data->pio_offset);
|
||||
pio_sm_unclaim(bus_data->pio, bus_data->pio_sm);
|
||||
if (bus_data->pio) {
|
||||
pio_remove_program_and_unclaim_sm(&SPI_PROGRAM_FUNC, bus_data->pio, bus_data->pio_sm, bus_data->pio_offset);
|
||||
bus_data->pio = NULL;
|
||||
}
|
||||
if (bus_data->dma_out >= 0) {
|
||||
dma_channel_cleanup(bus_data->dma_out);
|
||||
|
|
@ -199,7 +173,7 @@ void cyw43_spi_deinit(cyw43_int_t *self) {
|
|||
}
|
||||
|
||||
static void cs_set(bool value) {
|
||||
gpio_put(CS_PIN, value);
|
||||
gpio_put(CYW43_PIN_WL_CS, value);
|
||||
}
|
||||
|
||||
static __noinline void ns_delay(uint32_t ns) {
|
||||
|
|
@ -210,9 +184,9 @@ static __noinline void ns_delay(uint32_t ns) {
|
|||
|
||||
static void start_spi_comms(cyw43_int_t *self) {
|
||||
bus_data_t *bus_data = (bus_data_t *)self->bus_data;
|
||||
gpio_set_function(DATA_OUT_PIN, bus_data->pio_func_sel);
|
||||
gpio_set_function(CLOCK_PIN, bus_data->pio_func_sel);
|
||||
gpio_pull_down(CLOCK_PIN);
|
||||
gpio_set_function(CYW43_PIN_WL_DATA_OUT, pio_get_funcsel(bus_data->pio));
|
||||
gpio_set_function(CYW43_PIN_WL_CLOCK, pio_get_funcsel(bus_data->pio));
|
||||
gpio_pull_down(CYW43_PIN_WL_CLOCK);
|
||||
// Pull CS low
|
||||
cs_set(false);
|
||||
}
|
||||
|
|
@ -268,7 +242,9 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
|
|||
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
|
||||
pio_sm_set_wrap(bus_data->pio, bus_data->pio_sm, bus_data->pio_offset, bus_data->pio_offset + SPI_OFFSET_END - 1);
|
||||
pio_sm_clear_fifos(bus_data->pio, bus_data->pio_sm);
|
||||
pio_sm_set_pindirs_with_mask(bus_data->pio, bus_data->pio_sm, 1u << DATA_OUT_PIN, 1u << DATA_OUT_PIN);
|
||||
pio_sm_set_pindirs_with_mask(bus_data->pio, bus_data->pio_sm,
|
||||
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)),
|
||||
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)));
|
||||
pio_sm_restart(bus_data->pio, bus_data->pio_sm);
|
||||
pio_sm_clkdiv_restart(bus_data->pio, bus_data->pio_sm);
|
||||
pio_sm_put(bus_data->pio, bus_data->pio_sm, tx_length * 8 - 1);
|
||||
|
|
@ -310,7 +286,9 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
|
|||
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
|
||||
pio_sm_set_wrap(bus_data->pio, bus_data->pio_sm, bus_data->pio_offset, bus_data->pio_offset + SPI_OFFSET_LP1_END - 1);
|
||||
pio_sm_clear_fifos(bus_data->pio, bus_data->pio_sm);
|
||||
pio_sm_set_pindirs_with_mask(bus_data->pio, bus_data->pio_sm, 1u << DATA_OUT_PIN, 1u << DATA_OUT_PIN);
|
||||
pio_sm_set_pindirs_with_mask(bus_data->pio, bus_data->pio_sm,
|
||||
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)),
|
||||
1u << (CYW43_PIN_WL_DATA_OUT - pio_get_gpio_base(bus_data->pio)));
|
||||
pio_sm_restart(bus_data->pio, bus_data->pio_sm);
|
||||
pio_sm_clkdiv_restart(bus_data->pio, bus_data->pio_sm);
|
||||
pio_sm_put(bus_data->pio, bus_data->pio_sm, tx_length * 8 - 1);
|
||||
|
|
@ -334,7 +312,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
|
|||
}
|
||||
__compiler_memory_barrier();
|
||||
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
|
||||
pio_sm_set_consecutive_pindirs(bus_data->pio, bus_data->pio_sm, DATA_IN_PIN, 1, false);
|
||||
pio_sm_set_consecutive_pindirs(bus_data->pio, bus_data->pio_sm, CYW43_PIN_WL_DATA_IN, 1, false);
|
||||
} else if (rx != NULL) { /* currently do one at a time */
|
||||
DUMP_SPI_TRANSACTIONS(
|
||||
printf("[%lu] bus TX %u bytes:", counter++, rx_length);
|
||||
|
|
@ -356,32 +334,32 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
|
|||
|
||||
// Initialise our gpios
|
||||
void cyw43_spi_gpio_setup(void) {
|
||||
// Setup WL_REG_ON (23)
|
||||
gpio_init(WL_REG_ON);
|
||||
gpio_set_dir(WL_REG_ON, GPIO_OUT);
|
||||
gpio_pull_up(WL_REG_ON);
|
||||
// Setup CYW43_PIN_WL_REG_ON (23)
|
||||
gpio_init(CYW43_PIN_WL_REG_ON);
|
||||
gpio_set_dir(CYW43_PIN_WL_REG_ON, GPIO_OUT);
|
||||
gpio_pull_up(CYW43_PIN_WL_REG_ON);
|
||||
|
||||
// Setup DO, DI and IRQ (24)
|
||||
gpio_init(DATA_OUT_PIN);
|
||||
gpio_set_dir(DATA_OUT_PIN, GPIO_OUT);
|
||||
gpio_put(DATA_OUT_PIN, false);
|
||||
gpio_init(CYW43_PIN_WL_DATA_OUT);
|
||||
gpio_set_dir(CYW43_PIN_WL_DATA_OUT, GPIO_OUT);
|
||||
gpio_put(CYW43_PIN_WL_DATA_OUT, false);
|
||||
|
||||
// Setup CS (25)
|
||||
gpio_init(CS_PIN);
|
||||
gpio_set_dir(CS_PIN, GPIO_OUT);
|
||||
gpio_put(CS_PIN, true);
|
||||
gpio_init(CYW43_PIN_WL_CS);
|
||||
gpio_set_dir(CYW43_PIN_WL_CS, GPIO_OUT);
|
||||
gpio_put(CYW43_PIN_WL_CS, true);
|
||||
}
|
||||
|
||||
// Reset wifi chip
|
||||
void cyw43_spi_reset(void) {
|
||||
gpio_put(WL_REG_ON, false); // off
|
||||
gpio_put(CYW43_PIN_WL_REG_ON, false); // off
|
||||
sleep_ms(20);
|
||||
gpio_put(WL_REG_ON, true); // on
|
||||
gpio_put(CYW43_PIN_WL_REG_ON, true); // on
|
||||
sleep_ms(250);
|
||||
|
||||
// Setup IRQ (24) - also used for DO, DI
|
||||
gpio_init(IRQ_PIN);
|
||||
gpio_set_dir(IRQ_PIN, GPIO_IN);
|
||||
gpio_init(CYW43_PIN_WL_HOST_WAKE);
|
||||
gpio_set_dir(CYW43_PIN_WL_HOST_WAKE, GPIO_IN);
|
||||
}
|
||||
|
||||
static inline uint32_t make_cmd(bool write, bool inc, uint32_t fn, uint32_t addr, uint32_t sz) {
|
||||
|
|
@ -568,3 +546,54 @@ int cyw43_write_bytes(cyw43_int_t *self, uint32_t fn, uint32_t addr, size_t len,
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CYW43_PIN_WL_DYNAMIC
|
||||
|
||||
// storage for cyw43 pins
|
||||
static uint cyw43_pin_array[CYW43_PIN_INDEX_WL_COUNT] = {
|
||||
CYW43_DEFAULT_PIN_WL_REG_ON,
|
||||
CYW43_DEFAULT_PIN_WL_DATA_OUT,
|
||||
CYW43_DEFAULT_PIN_WL_DATA_IN,
|
||||
CYW43_DEFAULT_PIN_WL_HOST_WAKE,
|
||||
CYW43_DEFAULT_PIN_WL_CLOCK,
|
||||
CYW43_DEFAULT_PIN_WL_CS
|
||||
};
|
||||
|
||||
// Check the cyw43 gpio pin array is valid
|
||||
static bool cyw43_pins_valid(uint pins[CYW43_PIN_INDEX_WL_COUNT]) {
|
||||
// check the gpios are valid
|
||||
for(int i = 0; i < CYW43_PIN_INDEX_WL_COUNT; i++) {
|
||||
if (pins[i] >= NUM_BANK0_GPIOS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#if PICO_PIO_USE_GPIO_BASE
|
||||
// These pins should use the same gpio base
|
||||
return (pins[CYW43_PIN_INDEX_WL_DATA_OUT] < 32 && pins[CYW43_PIN_INDEX_WL_DATA_IN] < 32 && pins[CYW43_PIN_INDEX_WL_CLOCK] < 32) ||
|
||||
(pins[CYW43_PIN_INDEX_WL_DATA_OUT] >= 16 && pins[CYW43_PIN_INDEX_WL_DATA_IN] >= 16 && pins[CYW43_PIN_INDEX_WL_CLOCK] >= 16);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set the gpio pin array
|
||||
int cyw43_set_pins_wl(uint pins[CYW43_PIN_INDEX_WL_COUNT]) {
|
||||
assert(!bus_data_instance.pio);
|
||||
if (bus_data_instance.pio) {
|
||||
return PICO_ERROR_RESOURCE_IN_USE;
|
||||
}
|
||||
assert(cyw43_pins_valid(pins));
|
||||
if (!cyw43_pins_valid(pins)) {
|
||||
return PICO_ERROR_INVALID_ARG;
|
||||
}
|
||||
memcpy(cyw43_pin_array, pins, sizeof(cyw43_pin_array));
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
// Get a gpio pin
|
||||
uint cyw43_get_pin_wl(cyw43_pin_index_t pin_id) {
|
||||
assert(pin_id < CYW43_PIN_INDEX_WL_COUNT);
|
||||
assert(cyw43_pin_array[pin_id] < NUM_BANK0_GPIOS);
|
||||
return cyw43_pin_array[pin_id];
|
||||
}
|
||||
#endif // CYW43_PIN_WL_DYNAMIC
|
||||
|
|
@ -80,6 +80,10 @@ extern "C" {
|
|||
#define CYW43_EINVAL (-PICO_ERROR_INVALID_ARG) // Invalid argument
|
||||
#define CYW43_ETIMEDOUT (-PICO_ERROR_TIMEOUT) // Connection timed out
|
||||
|
||||
#ifndef CYW43_WL_GPIO_COUNT
|
||||
#define CYW43_WL_GPIO_COUNT 3
|
||||
#endif
|
||||
|
||||
#define CYW43_NUM_GPIOS CYW43_WL_GPIO_COUNT
|
||||
|
||||
#define cyw43_hal_pin_obj_t uint
|
||||
|
|
@ -95,16 +99,75 @@ static inline uint32_t cyw43_hal_ticks_ms(void) {
|
|||
return to_ms_since_boot(get_absolute_time());
|
||||
}
|
||||
|
||||
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_REG_ON, gpio pin to power up the cyw43 chip, type=int, default=23, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_DEFAULT_PIN_WL_REG_ON
|
||||
#define CYW43_DEFAULT_PIN_WL_REG_ON 23
|
||||
#endif
|
||||
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_OUT, gpio pin for spi data out to the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT
|
||||
#define CYW43_DEFAULT_PIN_WL_DATA_OUT 24u
|
||||
#endif
|
||||
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_IN, gpio pin for spi data in from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN
|
||||
#define CYW43_DEFAULT_PIN_WL_DATA_IN 24u
|
||||
#endif
|
||||
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_HOST_WAKE, gpio (irq) pin for the irq line from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE
|
||||
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 24u
|
||||
#endif
|
||||
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CLOCK, gpio pin for the spi clock line to the cyw43 chip, type=int, default=29, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_DEFAULT_PIN_WL_CLOCK
|
||||
#define CYW43_DEFAULT_PIN_WL_CLOCK 29u
|
||||
#endif
|
||||
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CS, gpio pin for the spi chip select to the cyw43 chip, type=int, default=25, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_DEFAULT_PIN_WL_CS
|
||||
#define CYW43_DEFAULT_PIN_WL_CS 25u
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: CYW43_PIN_WL_DYNAMIC, flag to indicate if cyw43 SPI pins can be changed at runtime, type=bool, default=false, advanced=true, group=pico_cyw43_driver
|
||||
#ifndef CYW43_PIN_WL_DYNAMIC
|
||||
#define CYW43_PIN_WL_DYNAMIC 0
|
||||
#endif
|
||||
|
||||
#if CYW43_PIN_WL_DYNAMIC
|
||||
// these are just an index into an array
|
||||
typedef enum cyw43_pin_index_t {
|
||||
CYW43_PIN_INDEX_WL_REG_ON,
|
||||
CYW43_PIN_INDEX_WL_DATA_OUT,
|
||||
CYW43_PIN_INDEX_WL_DATA_IN,
|
||||
CYW43_PIN_INDEX_WL_HOST_WAKE,
|
||||
CYW43_PIN_INDEX_WL_CLOCK,
|
||||
CYW43_PIN_INDEX_WL_CS,
|
||||
CYW43_PIN_INDEX_WL_COUNT // last
|
||||
} cyw43_pin_index_t;
|
||||
#define CYW43_PIN_WL_REG_ON cyw43_get_pin_wl(CYW43_PIN_INDEX_WL_REG_ON)
|
||||
#define CYW43_PIN_WL_DATA_OUT cyw43_get_pin_wl(CYW43_PIN_INDEX_WL_DATA_OUT)
|
||||
#define CYW43_PIN_WL_DATA_IN cyw43_get_pin_wl(CYW43_PIN_INDEX_WL_DATA_IN)
|
||||
#define CYW43_PIN_WL_HOST_WAKE cyw43_get_pin_wl(CYW43_PIN_INDEX_WL_HOST_WAKE)
|
||||
#define CYW43_PIN_WL_CLOCK cyw43_get_pin_wl(CYW43_PIN_INDEX_WL_CLOCK)
|
||||
#define CYW43_PIN_WL_CS cyw43_get_pin_wl(CYW43_PIN_INDEX_WL_CS)
|
||||
// Lookup the gpio value in an array
|
||||
uint cyw43_get_pin_wl(cyw43_pin_index_t pin_id);
|
||||
#else
|
||||
// Just return the gpio number configured at build time
|
||||
#define CYW43_PIN_WL_REG_ON CYW43_DEFAULT_PIN_WL_REG_ON
|
||||
#define CYW43_PIN_WL_DATA_OUT CYW43_DEFAULT_PIN_WL_DATA_OUT
|
||||
#define CYW43_PIN_WL_DATA_IN CYW43_DEFAULT_PIN_WL_DATA_IN
|
||||
#define CYW43_PIN_WL_HOST_WAKE CYW43_DEFAULT_PIN_WL_HOST_WAKE
|
||||
#define CYW43_PIN_WL_CLOCK CYW43_DEFAULT_PIN_WL_CLOCK
|
||||
#define CYW43_PIN_WL_CS CYW43_DEFAULT_PIN_WL_CS
|
||||
#endif // !CYW43_PIN_WL_DYNAMIC
|
||||
|
||||
static inline int cyw43_hal_pin_read(cyw43_hal_pin_obj_t pin) {
|
||||
return gpio_get(pin);
|
||||
}
|
||||
|
||||
static inline void cyw43_hal_pin_low(cyw43_hal_pin_obj_t pin) {
|
||||
gpio_clr_mask(1 << pin);
|
||||
gpio_put(pin, false);
|
||||
}
|
||||
|
||||
static inline void cyw43_hal_pin_high(cyw43_hal_pin_obj_t pin) {
|
||||
gpio_set_mask(1 << pin);
|
||||
gpio_put(pin, true);
|
||||
}
|
||||
|
||||
#define CYW43_HAL_PIN_MODE_INPUT (GPIO_IN)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include "pico.h"
|
||||
|
||||
#if CYW43_PIN_WL_DYNAMIC
|
||||
#include "cyw43_configport.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -60,9 +64,34 @@ void cyw43_driver_deinit(struct async_context *context);
|
|||
#endif
|
||||
|
||||
#if CYW43_PIO_CLOCK_DIV_DYNAMIC
|
||||
/*! \brief Set the clock divisor for the cyw43 pio clock
|
||||
* \ingroup pico_cyw43_driver
|
||||
*
|
||||
* SPI is used to communicate with the CYW43 device and this is implemented using a PIO running with a divisor of 2.
|
||||
* If the system clock is changed it may be necessary to adjust for this to allow communications to succeed.
|
||||
* This function is only available if \ref CYW43_PIO_CLOCK_DIV_DYNAMIC is true
|
||||
*
|
||||
* \param clock_div_int Integer part of the divisor
|
||||
* \param clock_div_frac Fractional part in 1/256ths
|
||||
*/
|
||||
void cyw43_set_pio_clock_divisor(uint16_t clock_div_int, uint8_t clock_div_frac);
|
||||
#endif
|
||||
|
||||
#if CYW43_PIN_WL_DYNAMIC
|
||||
/*! \brief Set the gpio pins for the communication with the cyw43 device
|
||||
* \ingroup pico_cyw43_driver
|
||||
*
|
||||
* Set or change the pins used to communicate with the cyw43 device
|
||||
* This function is only available if \ref CYW43_PIN_WL_DYNAMIC is true
|
||||
*
|
||||
* \note The cyw43 driver should not be de-initialised before this function is called or else the behaviour is undefined.
|
||||
*
|
||||
* \param pins An array containing the gpio pins to use
|
||||
* \return PICO_OK if the pin configuration could be changed and is valid
|
||||
*/
|
||||
int cyw43_set_pins_wl(uint pins[CYW43_PIN_INDEX_WL_COUNT]);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue