Struggling with PIO

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
RPhoton
Posts: 2
Joined: Wed May 05, 2021 7:51 pm

Struggling with PIO

Post by RPhoton » Wed May 05, 2021 8:25 pm

Hello,
The micropython PIO documentation is, as has been stated before, not complete yet.
I'm just a python newbie, so trying to discern the arguments of each function from the c source code while fighting with my first assembly is less than ideal for me. The coordination between CPU code and PIO code without blocking is hard to grasp right now.

I've started writing something that's maybe too hard to begin with and failing miserably, so I said: let's try the basics first... can you even output the same signal that you're reading?

The answers is... sort of. But why is it inverted?

Here's the code:

Code: Select all

from machine import Pin
import rp2

sm_freq = 1_000_000 
sm_nr = 0
@rp2.asm_pio(
    set_init=rp2.PIO.IN_HIGH,
    sideset_init = rp2.PIO.OUT_HIGH,
)
def mimic():
    wrap_target()
    wait(1, pin, 0).side(1)
    wait(0, pin, 0).side(0)
    wrap()

pininput = Pin(5,Pin.IN,Pin.PULL_UP)
pinside = Pin(15,Pin.OUT)

smtest = rp2.StateMachine(
    sm_nr, 
    prog = mimic, 
    freq = sm_freq,
    in_base = pininput,
    set_base = pininput,
    jmp_pin = pininput,
    sideset_base = pinside
    )

smtest.active(1)

And this is my output:
https://imgur.com/a/34gkGYB

I've played with different polarities of set_init and sideset_init and it doesn't change the result. Where is my mistake?

rafl
Posts: 10
Joined: Tue Mar 23, 2021 7:15 am

Re: Struggling with PIO

Post by rafl » Wed May 05, 2021 10:32 pm

Your issue here is how you're using sideset. The sideset outputs will be set when the wait instruction begins executing, not after the wait finishes and the next instruction is about to start executing. I hope the following example program illustrates what's causing the inversion in your original code.

Code: Select all

    wrap_target()
    wait(1, pin, 0)
    nop() .side(1)
    wait(0, pin, 0)
    nop() .side(0)
    wrap()

RPhoton
Posts: 2
Joined: Wed May 05, 2021 7:51 pm

Re: Struggling with PIO

Post by RPhoton » Fri May 07, 2021 2:44 pm

The sideset outputs will be set when the wait instruction begins executing, not after the wait finishes and the next instruction is about to start executing.
Thanks so much rafl. I thought wait stalled until its condition was met and then, starting on the match, it "fired" one cycle of execution. I thought the sideset would ride on that match. I was wrong, it makes more sense this way. Baby steps in assembly. :lol:

Post Reply