Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pio/spi/pio_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 6 additions & 6 deletions pio/spi/spi.pio
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
19 changes: 10 additions & 9 deletions pio/spi/spi_loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -70,7 +71,7 @@ int main() {
PIN_MOSI,
PIN_MISO
);
test(&spi);
test(&spi[cpha]);
sleep_ms(10);
}
}
Expand Down