Skip to content

Commit

Permalink
Make CYW43 gpio pins configurable at build time
Browse files Browse the repository at this point in the history
The CYW43 gpio pins are currently hardcoded. Give the defines better
names and make them overrideable at build time.
  • Loading branch information
peterharperuk committed Aug 14, 2024
1 parent 6eb230a commit 9d41c54
Showing 1 changed file with 65 additions and 41 deletions.
106 changes: 65 additions & 41 deletions src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,41 @@
#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

// PICO_CONFIG: CYW43_WL_REG_ON_PIN, gpio pin to power up the cyw43 chip, type=int, default=23, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_WL_REG_ON_PIN
#define CYW43_WL_REG_ON_PIN 23
#endif

// PICO_CONFIG: CYW43_DATA_OUT_PIN, gpio pin for spi data out to the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DATA_OUT_PIN
#define CYW43_DATA_OUT_PIN 24u
#endif

// PICO_CONFIG: CYW43_DATA_IN_PIN, gpio pin for spi data in from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DATA_IN_PIN
#define CYW43_DATA_IN_PIN 24u
#endif

// PICO_CONFIG: CYW43_IRQ_PIN, gpio pin for the irq line from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_IRQ_PIN
#define CYW43_IRQ_PIN 24u
#endif

// PICO_CONFIG: CYW43_IRQ_PIN, gpio pin for the spi clock line to the cyw43 chip, type=int, default=29, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_CLOCK_PIN
#define CYW43_CLOCK_PIN 29u
#endif

// PICO_CONFIG: CYW43_IRQ_PIN, gpio pin for the spi chip select to the cyw43 chip, type=int, default=25, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_CS_PIN
#define CYW43_CS_PIN 25u
#endif

#define IRQ_SAMPLE_DELAY_NS 100

// The pins should all work in the same gpio base
static_assert((DATA_OUT_PIN < 32 && DATA_IN_PIN < 32 && CLOCK_PIN < 32) || (DATA_OUT_PIN > 16 && DATA_IN_PIN > 16 && CLOCK_PIN > 16), "");
static_assert((CYW43_DATA_OUT_PIN < 32 && CYW43_DATA_IN_PIN < 32 && CYW43_CLOCK_PIN < 32) || (CYW43_DATA_OUT_PIN > 16 && CYW43_DATA_IN_PIN > 16 && CYW43_CLOCK_PIN > 16), "");

#ifdef CYW43_SPI_PROGRAM_NAME
#define SPI_PROGRAM_NAME CYW43_SPI_PROGRAM_NAME
Expand Down Expand Up @@ -109,37 +133,37 @@ int cyw43_spi_init(cyw43_int_t *self) {
bus_data->dma_in = -1;
bus_data->dma_out = -1;

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, DATA_OUT_PIN, 1, true)) {
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, CYW43_DATA_OUT_PIN, 1, true)) {
cyw43_spi_deinit(self);
return CYW43_FAIL_FAST_CHECK(-CYW43_EIO);
}
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_CLOCK_PIN],
(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_CLOCK_PIN],
(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_DATA_OUT_PIN, 1);
sm_config_set_in_pins(&config, CYW43_DATA_IN_PIN);
sm_config_set_set_pins(&config, CYW43_DATA_OUT_PIN, 1);
sm_config_set_sideset(&config, 1, false, false);
sm_config_set_sideset_pins(&config, CLOCK_PIN);
sm_config_set_sideset_pins(&config, CYW43_CLOCK_PIN);
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_DATA_IN_PIN);
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, pio_get_funcsel(bus_data->pio));
pio_sm_set_consecutive_pindirs(bus_data->pio, bus_data->pio_sm, CYW43_CLOCK_PIN, 1, true);
gpio_set_function(CYW43_DATA_OUT_PIN, 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_DATA_IN_PIN, false, true);
gpio_set_input_hysteresis_enabled(CYW43_DATA_IN_PIN, true);

pio_sm_exec(bus_data->pio, bus_data->pio_sm, pio_encode_set(pio_pins, 1));

Expand Down Expand Up @@ -173,7 +197,7 @@ void cyw43_spi_deinit(cyw43_int_t *self) {
}

static void cs_set(bool value) {
gpio_put(CS_PIN, value);
gpio_put(CYW43_CS_PIN, value);
}

static __noinline void ns_delay(uint32_t ns) {
Expand All @@ -184,9 +208,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, pio_get_funcsel(bus_data->pio));
gpio_set_function(CLOCK_PIN, pio_get_funcsel(bus_data->pio));
gpio_pull_down(CLOCK_PIN);
gpio_set_function(CYW43_DATA_OUT_PIN, pio_get_funcsel(bus_data->pio));
gpio_set_function(CYW43_CLOCK_PIN, pio_get_funcsel(bus_data->pio));
gpio_pull_down(CYW43_CLOCK_PIN);
// Pull CS low
cs_set(false);
}
Expand Down Expand Up @@ -242,7 +266,7 @@ 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_DATA_OUT_PIN, 1u << CYW43_DATA_OUT_PIN);
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);
Expand Down Expand Up @@ -284,7 +308,7 @@ 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_DATA_OUT_PIN, 1u << CYW43_DATA_OUT_PIN);
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);
Expand All @@ -308,7 +332,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_DATA_IN_PIN, 1, false);
} else if (rx != NULL) { /* currently do one at a time */
DUMP_SPI_TRANSACTIONS(
printf("[%lu] bus TX %u bytes:", counter++, rx_length);
Expand All @@ -330,32 +354,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_WL_REG_ON_PIN (23)
gpio_init(CYW43_WL_REG_ON_PIN);
gpio_set_dir(CYW43_WL_REG_ON_PIN, GPIO_OUT);
gpio_pull_up(CYW43_WL_REG_ON_PIN);

// 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_DATA_OUT_PIN);
gpio_set_dir(CYW43_DATA_OUT_PIN, GPIO_OUT);
gpio_put(CYW43_DATA_OUT_PIN, false);

// Setup CS (25)
gpio_init(CS_PIN);
gpio_set_dir(CS_PIN, GPIO_OUT);
gpio_put(CS_PIN, true);
gpio_init(CYW43_CS_PIN);
gpio_set_dir(CYW43_CS_PIN, GPIO_OUT);
gpio_put(CYW43_CS_PIN, true);
}

// Reset wifi chip
void cyw43_spi_reset(void) {
gpio_put(WL_REG_ON, false); // off
gpio_put(CYW43_WL_REG_ON_PIN, false); // off
sleep_ms(20);
gpio_put(WL_REG_ON, true); // on
gpio_put(CYW43_WL_REG_ON_PIN, 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_IRQ_PIN);
gpio_set_dir(CYW43_IRQ_PIN, GPIO_IN);
}

static inline uint32_t make_cmd(bool write, bool inc, uint32_t fn, uint32_t addr, uint32_t sz) {
Expand Down

0 comments on commit 9d41c54

Please sign in to comment.