Pins incorrectly mapped in PIO+SPI w/CS sample?

Open
#282 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
c
Domain
embedded-iot

Research direction

Start with pio/spi/spi.pio and compare its CS and SCK assumptions with the pinout described in the issue. Review the sample's pin masks and sideset setup, including whether the SDK configuration matches the .side_set 2 declaration. Done means the sample's mapping and initialization are confirmed or corrected, with transmit behavior matching the documented pinout.

Written by the indexing model from the issue text.

Description

i'm wondering if maybe the pins were differently mapped a little before launch when the samples were written, and maybe something got changed around? the sample code at the bottom seems to confidently assume that the CS pin should follow the SCK pin, where in the pinout we seem to have them the other way around.

in my own code i've modified the sample to reverse these pins and i'm successfully writing out the values i mean to, so i'm inclined to think i'm not wrong.

i'm happy to supply a patch for the sample along the lines of what i wrote, but i just wanted to confirm i'm not totally confused, and ask if there is some particular preferred way to resolve this, especially wrt the particular way the pins/pindirs and their masks are composed together, a lot of 1u/2u/3u mixing there for reasons that aren't always clear to me.

also, in my own code, i added the line sm_config_set_sideset(&c, 2, false, false); because i'm not sure if the 2 pin sideset is somehow automatically applied due to the .side_set 2 annotation, but from what i can tell in the documentation it's not.

in my case i was just doing transmit, no receive, so i ripped some things out but here's my working code:

; CPHA=0: data is captured on the leading edge of each SCK pulse (including
; the first pulse), and transitions on the trailing edge

.program dac_spi
.side_set 2

.wrap_target
bitloop:
    out pins, 1        side 0x0 [1]
    jmp x-- bitloop    side 0x2 [1]

    out pins, 1        side 0x0
    mov x, y           side 0x0     ; Reload bit counter from Y
    jmp !osre bitloop  side 0x2 [1] ; Fall-through if TXF empties

    nop                side 0x0 [1] ; CSn back porch
public entry_point:                 ; Must set X,Y to n-2 before starting!
    pull ifempty       side 0x1 [1] ; Block with CSn high (minimum 2 cycles)
.wrap                               ; Note ifempty to avoid time-of-check race

% c-sdk {
#include "hardware/gpio.h"
static inline void dac_spi_init(PIO pio, uint sm, uint prog_offs, uint n_bits, float clkdiv, bool cpha, bool cpol,
        uint pin_cs, uint pin_sck, uint pin_mosi) {
    assert(cpha == 0);
    assert((pin_sck - pin_cs) == 1);

    pio_sm_config c = dac_spi_program_get_default_config(prog_offs);
    sm_config_set_out_pins(&c, pin_mosi, 1);
    sm_config_set_out_shift(&c, false, true, n_bits);
    sm_config_set_sideset(&c, 2, false, false);
    sm_config_set_sideset_pins(&c, pin_cs);
    sm_config_set_clkdiv(&c, clkdiv);

    pio_sm_set_pins_with_mask(pio, sm, (1u << pin_cs), (3u << pin_cs) | (1u << pin_mosi));
    pio_sm_set_pindirs_with_mask(pio, sm, (3u << pin_cs) | (1u << pin_mosi), (3u << pin_cs) | (1u << pin_mosi));
    pio_gpio_init(pio, pin_mosi);
    pio_gpio_init(pio, pin_sck);
    pio_gpio_init(pio, pin_cs);
    gpio_set_outover(pin_sck, cpol ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL);

    uint entry_point = prog_offs + dac_spi_offset_entry_point;
    pio_sm_init(pio, sm, entry_point, &c);
    pio_sm_exec(pio, sm, pio_encode_set(pio_x, n_bits - 2));
    pio_sm_exec(pio, sm, pio_encode_set(pio_y, n_bits - 2));
    pio_sm_set_enabled(pio, sm, true);
}
%}
Dominant language
C
Stars
3.9k
Forks
1k
Avg merge
1d 16h
Merged PRs (30d)
1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from raspberrypi/pico-examples

All issues in raspberrypi/pico-examples

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.