# RP2040 - get PIO data into Python by IRQ and Push
# by Anthony Vogelaar, Perth Scotland
# rev 0.10  2025-08-22  Initial release

from	machine		import	Pin
import	time
import	rp2

# ======================= PIO functions ======================

# Push counter Y to python @ 1 Hz (div 2000 = 32 * 62 + 16
@rp2.asm_pio()
def freq1HzLed():
    set(y, 0)							# no clear at soft reset
    label('loop')
    irq(rel(0))							# Set IRQ relative SM 0
    jmp(y_dec, 'next')					# decrement Y
    label('next')
    mov(isr,y)							# push out Y through RX_FIFO
    push(noblock)
    set(x, 31)                  [10]
    label('l1')
    nop()						[30]
    jmp(x_dec, 'l1')			[30]
    jmp('loop')

# ======================= State machine ========================

# helper class for PIO StateMachines
class PioMach:
    
    # PIO state machine setup
    def  __init__(self, program, freq=2_000, id=0, **kwargs):
        self.sm = rp2.StateMachine(id, program, freq, **kwargs)
        self.sm.irq(self.onPioIrq)
        self.sm.active(True)

    
    # handle IRQ from state machine
    def onPioIrq(self, sender):
        print(sender, time.ticks_ms())


    # handle state machine pushed  data
    def get(self):
        if self.sm.rx_fifo():
            return self.sm.get()
                                                                                                                                                                                                                                                                                                                                                                                
# ========================== main ==============================

def main():
    sm = PioMach(freq1HzLed, set_base=Pin(25))
    while True:
        if res := sm.get(): print(res)
        time.sleep_ms(10)


main()

# =========================== end ==============================