diff --git a/pio/spi/pio_spi.h b/pio/spi/pio_spi.h index dfa929d8b..f2ce42d8a 100644 --- a/pio/spi/pio_spi.h +++ b/pio/spi/pio_spi.h @@ -13,6 +13,7 @@ typedef struct pio_spi_inst { PIO pio; uint sm; uint cs_pin; + uint offset; } pio_spi_inst_t; void pio_spi_write8_blocking(const pio_spi_inst_t *spi, const uint8_t *src, size_t len); diff --git a/pio/spi/spi.pio b/pio/spi/spi.pio index 4033a74ab..be3e9eee7 100644 --- a/pio/spi/spi.pio +++ b/pio/spi/spi.pio @@ -55,8 +55,8 @@ static inline void pio_spi_init(PIO pio, uint sm, uint prog_offs, uint n_bits, sm_config_set_clkdiv(&c, clkdiv); // MOSI, SCK output are low, MISO is input - pio_sm_set_pins_with_mask(pio, sm, 0, (1u << pin_sck) | (1u << pin_mosi)); - pio_sm_set_pindirs_with_mask(pio, sm, (1u << pin_sck) | (1u << pin_mosi), (1u << pin_sck) | (1u << pin_mosi) | (1u << pin_miso)); + pio_sm_set_pins_with_mask64(pio, sm, 0, (1ull << pin_sck) | (1ull << pin_mosi)); + pio_sm_set_pindirs_with_mask64(pio, sm, (1ull << pin_sck) | (1ull << pin_mosi), (1ull << pin_sck) | (1ull << pin_mosi) | (1ull << pin_miso)); pio_gpio_init(pio, pin_mosi); pio_gpio_init(pio, pin_miso); pio_gpio_init(pio, pin_sck); @@ -65,7 +65,7 @@ static inline void pio_spi_init(PIO pio, uint sm, uint prog_offs, uint n_bits, // and this is a cheesy way to get CPOL=1 gpio_set_outover(pin_sck, cpol ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL); // SPI is synchronous, so bypass input synchroniser to reduce input delay. - hw_set_bits(&pio->input_sync_bypass, 1u << pin_miso); + hw_set_bits(&pio->input_sync_bypass, (pin_miso >= 32) ? (1u << (pin_miso - 16)) : (1u << pin_miso)); pio_sm_init(pio, sm, prog_offs, &c); pio_sm_set_enabled(pio, sm, true); @@ -150,14 +150,14 @@ static inline void pio_spi_cs_init(PIO pio, uint sm, uint prog_offs, uint n_bits sm_config_set_in_shift(&c, false, true, n_bits); sm_config_set_clkdiv(&c, clkdiv); - pio_sm_set_pins_with_mask(pio, sm, (2u << pin_sck), (3u << pin_sck) | (1u << pin_mosi)); - pio_sm_set_pindirs_with_mask(pio, sm, (3u << pin_sck) | (1u << pin_mosi), (3u << pin_sck) | (1u << pin_mosi) | (1u << pin_miso)); + pio_sm_set_pins_with_mask64(pio, sm, (2ull << pin_sck), (3ull << pin_sck) | (1ull << pin_mosi)); + pio_sm_set_pindirs_with_mask64(pio, sm, (3ull << pin_sck) | (1ull << pin_mosi), (3ull << pin_sck) | (1ull << pin_mosi) | (1ull << pin_miso)); pio_gpio_init(pio, pin_mosi); pio_gpio_init(pio, pin_miso); pio_gpio_init(pio, pin_sck); pio_gpio_init(pio, pin_sck + 1); gpio_set_outover(pin_sck, cpol ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL); - hw_set_bits(&pio->input_sync_bypass, 1u << pin_miso); + hw_set_bits(&pio->input_sync_bypass, (pin_miso >= 32) ? (1u << (pin_miso - 16)) : (1u << pin_miso)); uint entry_point = prog_offs + (cpha ? spi_cpha1_cs_offset_entry_point : spi_cpha0_cs_offset_entry_point); pio_sm_init(pio, sm, entry_point, &c); diff --git a/pio/spi/spi_loopback.c b/pio/spi/spi_loopback.c index ac5897f9c..014fa9243 100644 --- a/pio/spi/spi_loopback.c +++ b/pio/spi/spi_loopback.c @@ -49,19 +49,20 @@ void test(const pio_spi_inst_t *spi) { int main() { stdio_init_all(); - pio_spi_inst_t spi = { - .pio = pio0, - .sm = 0 - }; + pio_spi_inst_t spi[2]; float clkdiv = 31.25f; // 1 MHz @ 125 clk_sys - uint cpha0_prog_offs = pio_add_program(spi.pio, &spi_cpha0_program); - uint cpha1_prog_offs = pio_add_program(spi.pio, &spi_cpha1_program); + + // pio_claim_free_sm_and_add_program_for_gpio_range finds a free pio and state machine for a program and sets the gpio base correctly + const uint pin_base = MIN(PIN_SCK, MIN(PIN_MOSI, PIN_MISO)); + const uint pin_count = MAX(PIN_SCK, MAX(PIN_MOSI, PIN_MISO)) - pin_base + 1; + hard_assert(pio_claim_free_sm_and_add_program_for_gpio_range(&spi_cpha0_program, &spi[0].pio, &spi[0].sm, &spi[0].offset, pin_base, pin_count, true)); + hard_assert(pio_claim_free_sm_and_add_program_for_gpio_range(&spi_cpha1_program, &spi[1].pio, &spi[1].sm, &spi[1].offset, pin_base, pin_count, true)); for (int cpha = 0; cpha <= 1; ++cpha) { for (int cpol = 0; cpol <= 1; ++cpol) { printf("CPHA = %d, CPOL = %d\n", cpha, cpol); - pio_spi_init(spi.pio, spi.sm, - cpha ? cpha1_prog_offs : cpha0_prog_offs, + pio_spi_init(spi[cpha].pio, spi[cpha].sm, + spi[cpha].offset, 8, // 8 bits per SPI frame clkdiv, cpha, @@ -70,7 +71,7 @@ int main() { PIN_MOSI, PIN_MISO ); - test(&spi); + test(&spi[cpha]); sleep_ms(10); } }