sm.exec() and Pin.value()

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
podex
Posts: 10
Joined: Tue Nov 16, 2021 9:03 am

sm.exec() and Pin.value()

Post by podex » Wed Mar 23, 2022 2:36 pm

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.

podex
Posts: 10
Joined: Tue Nov 16, 2021 9:03 am

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

Post by podex » Thu Mar 24, 2022 9:14 am

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

GerryKeely
Posts: 5
Joined: Wed Feb 17, 2021 10:12 pm

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

Post by GerryKeely » Thu Mar 24, 2022 4:37 pm

Hi
In def prog replace pass with any valid instruction eg nop() and it works (don't no why)
regards
Gerry

Post Reply