Page 1 of 1

Struggling with PIO

Posted: Wed May 05, 2021 8:25 pm
by RPhoton
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?

Re: Struggling with PIO

Posted: Wed May 05, 2021 10:32 pm
by rafl
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()

Re: Struggling with PIO

Posted: Fri May 07, 2021 2:44 pm
by RPhoton
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: