Page 1 of 1

sm.exec() and Pin.value()

Posted: Wed Mar 23, 2022 2:36 pm
by podex
Hi,

I would like to stop the PIO and set the output pin in the main loop. But it looks to me that it's not possible to set the pin output state from the main loop when it's defined to be the output of the PIO. Is this feature not available?

As an example I extended the LED blink example:

Code: Select all

import utime
import rp2
from machine import Pin

p0 = Pin(25,Pin.OUT)

# Blink state machine program. Blinks LED at 10 Hz (with freq=2000)
# 2000 Hz / (20 cycles per instruction * 10 instructions) = 10 Hz
# Single pin (base pin) starts at output and logic low
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink():
    wrap_target()
    set(pins, 1) [19]
    nop()        [19]
    nop()        [19]
    nop()        [19]
    nop()        [19]
    set(pins, 0) [19]
    nop()        [19]
    nop()        [19]
    nop()        [19]
    nop()        [19]
    
    label("wait")    # y set to '0' results in an wait loop
    jmp(not_y,"wait")    
    wrap()

# Init state machine with "blink" program
# (state machine 0, running at 2kHz, base pin is GP25 (LED))
sm = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(25))

# Continually start and stop state machine
while True:
    print("Starting state machine...")
    sm.exec("set(y, 1)")
    sm.active(1)
    utime.sleep(1)

    print("Stopping state machine...")
    sm.exec("set(y, 0)")   // first stop it via register y (LED then is OFF)
    utime.sleep(0.1)
    sm.active(0)

    utime.sleep(1)
    print("LED on...")
    p0.value(1)

    utime.sleep(1)
    print("LED off...")
    p0.value(0)
    utime.sleep(1)
Setting the pins via

Code: Select all

    sm.exec("mov(osr,1)")
    sm.exec("out(pins,32) ")
is also not switching the LED on in the mail loop.

Re: sm.exec() and Pin.value()

Posted: Thu Mar 24, 2022 9:14 am
by podex
No ideas up to now?

In the meantime I tried to find a work-around. So I modified https://github.com/raspberrypi/pico-mic ... io_exec.py in order to change 2 pins with an exec instruciton.

Code: Select all

import time
from machine import Pin
import rp2

# Define an empty program that uses a single set pin.
@rp2.asm_pio(set_init=(rp2.PIO.OUT_LOW,rp2.PIO.OUT_LOW))
def prog():
    pass


# Construct the StateMachine, binding Pin(0) and Pin(1) to the set pin.
sm = rp2.StateMachine(0, prog, set_base=Pin(0))

# Turn on the set pin via an exec instruction.
sm.exec("set(pins, 3)")

# loop forever
while True:
    pass
This is ok for Pin(0) but is not changing Pin(1). Is there a bug that only one pin can be changed with the exec command?

Thanks for any ideas leading me to a working solution!

KR,
Christof

Re: sm.exec() and Pin.value()

Posted: Thu Mar 24, 2022 4:37 pm
by GerryKeely
Hi
In def prog replace pass with any valid instruction eg nop() and it works (don't no why)
regards
Gerry