Skip to content

Commit

Permalink
Support dynamic configuration of cyw43 gpio pins
Browse files Browse the repository at this point in the history
Add CYW43_PIN_WL_DYNAMIC that means cyw43 gpio pins can be changed at
runtime.

Then CYW43_PIN_WL_REG_ON 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.
  • Loading branch information
peterharperuk committed Aug 15, 2024
1 parent 4aed040 commit a005e3c
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@

#define IRQ_SAMPLE_DELAY_NS 100

#if !CYW43_PIN_WL_DYNAMIC
// 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
Expand Down Expand Up @@ -540,3 +542,50 @@ 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;
}
}
// 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);
}

// 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
27 changes: 27 additions & 0 deletions src/rp2_common/pico_cyw43_driver/include/cyw43_configport.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,39 @@ static inline uint32_t cyw43_hal_ticks_ms(void) {
#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);
Expand Down
19 changes: 19 additions & 0 deletions src/rp2_common/pico_cyw43_driver/include/pico/cyw43_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

#include "pico.h"

#if CYW43_PIN_WL_DYNAMIC
#include "cyw43_configport.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -73,6 +77,21 @@ void cyw43_driver_deinit(struct async_context *context);
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
Expand Down

0 comments on commit a005e3c

Please sign in to comment.