-
Notifications
You must be signed in to change notification settings - Fork 30
Micropython
Christian Köhlke edited this page Jan 27, 2026
·
1 revision
The following code load the PIO-progamm "pio_code" into a PIO. The programm itself pulse a pin. The FIFO is used to communicate how often (steps) the pin should be pulsed and the delay between each step. The FIFO has 4*32bits. The controller checks in a loop whether there is a free slot in the FIFO and send alternating data (few slow pulse; many fast pulses) to the PIO programm.
import time
from machine import Pin
import rp2
# Global variable to store step count (incremented by IRQ handler)
step_count = 0
class PioData:
def __init__(self, steps=0, delay=0):
"""
PIO data structure to hold steps and delay
Args:
steps (int): Number of toggle cycles
delay (int): Delay between toggles in ms
"""
self.steps = steps
self.delay = delay
def put(self, sm: rp2.StateMachine, pio_freq=2000):
delay = int((self.delay / 1000) * pio_freq)
print(f"Putting steps: {self.steps}, delay: {delay} (PIO cycles)")
data = ((self.steps & 0xFFFF) << 16) | (delay & 0xFFFF)
sm.put(data)
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def pio_code():
wrap_target()
pull(block)
out(y, 16)
out(isr, 16)
label("step_loop")
set(pins, 1)
set(pins, 0)
irq(0)
mov(x, isr)
label("low_delay")
jmp(x_dec, "low_delay")
jmp(y_dec, "step_loop")
wrap()
# IRQ Handler: Called when PIO triggers IRQ after each step
def pio_irq_handler(sm):
global step_count
step_count += 1
# Initialize PIO
PIN = 17
sm = rp2.StateMachine(0, pio_code, freq=2000, set_base=Pin(PIN))
sm.irq(handler=pio_irq_handler)
sm.active(1)
pio_data1 = PioData()
pio_data1.steps = 3
pio_data1.delay = 1000
pio_data1.put(sm)
pio_data2 = PioData()
pio_data2.steps = 10
pio_data2.delay = 100
pio_data2.put(sm)
pio_data = [pio_data1, pio_data2]
print("Press Ctrl+C to stop")
current_data_index = 0
try:
while True:
time.sleep(1)
free_slots = 4 - sm.tx_fifo()
print(f"TX FIFO free slots: {free_slots}")
if free_slots > 0:
pio_data[current_data_index].put(sm)
current_data_index = (current_data_index + 1) % len(pio_data)
except KeyboardInterrupt:
sm.irq(handler=None)
sm.active(0)
print("\nStopped")