0

Working on an RP2040, the PIO application below is designed to output 32bits from the output shift register. One of the pins is designed to output the actual data data. While the side set pin operates as a clock. The operation of the program is nearly correct, however, the output appears to be reading in one byte from the OSR and repeating that byte to be shifted out 4 times for the 32 bit loop.

.program arinc429
.side_set 1 opt
loop:
    set x, 31              ; A variable used to keep track of how many bits we have gone through
    pull 32         side 0 ; Ensure we have 32 bits to shift out
bitloop:                   ; This is where we will loop back to until all bits are written out
    out pins, 1     side 1 ; Set the pin high based on `y` to write out
    jmp x-- bitloop side 0 ; Keep looping while bits has not performed 32 times
complete:
    set pins, 0
    jmp loop               ; Loop back to the beginning where we will wait for more data to write

This is the code that is used to configure the PIO program:

sm = rp2pio.StateMachine(
    program,
    frequency=200000,
    first_out_pin=board.D12,
    out_pin_count=1,
    first_set_pin=board.D12,
    first_sideset_pin=board.D13,
    sideset_pin_count=1,
    sideset_enable=True,
    out_shift_right=False,  # Start pulling out most sigificant bits first
    auto_pull=False,
    pull_threshold=32,  # Make sure we can pull 32 bits
)

For example: I am trying to write out 0AFF00AA. A 32 bit word. The output I am getting on the oscilloscope is 0A0A0A0A FFFFFFFF 00000000 AAAAAAAA (with the space indicating a pause).

So it appears that while I am looping, the out pins, 1 instruction will receive one byte from the shift register and rotate shift that one byte out while in the bitloop? In any case, I would like to ensure that I have 32 bits to shift out before beginning the bitloop, then proceed to shift out those 32 bits.

2
  • Any update on this topic ? Could use a PIO implementation to drive an RS485 transceiver :-)
    – nerohmot
    Feb 12 at 14:35
  • @nerohmot Yes. I forgot I made a question for this. The solution ended up being very easy. Instead of shoving in a large int, I used an array.array. This was specified in the documentation, but I missed it for quite some time. Feb 14 at 18:45

1 Answer 1

0

The issue ended up not being the code of the PIO or how the PIO was initialized, but rather the data that was being sent to the PIO through the OSR (Output Shift Register). Putting 4 bytes in the OSR via bytes, bytesarray, or int results in only 1 byte being read in regardless of other bytes being provided. This is apparently by design as well. So, with the documentation, to provide in multiple bytes into the OSR you need to use array.array with each entry being read in as an int.

Specifically the last sentence in the documentation for that function:

To perform 16 or 32 bits writes into the FIFO use an array.array with a type code of the desired size.

In my case, I was targeting 32 bytes. So using an array.array was required.

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Feb 19 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.