Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 3586

MicroPython • Testing PIO on Pico 2

$
0
0
I finally got my hands on Pico 2 and decided to check out some of the new PIO features. I have written a program to test using RX FIFO as storage registers (FJOIN_RX_GET mode) and using IRQ to branch the program running on another state machine and across PIO blocks. Those features don't seem to be supported by the current MicroPython build, so I had to directly write to some registers and encode the related PIO instructions by hand, but everything seems to work as expected.

The program uses two state machines, the first is set to use RX FIFO to store the on and off times for the LED and rises/clears the IRQ appropriately, and the second uses the IRQ status to turn the LED on and off. Overall it's just an overcomplicated LED blinking program with programmable on/off times, but it demonstrates the features mentioned earlier.

Code:

from machine import Pin, mem32from rp2 import asm_pio, StateMachine, PIOPIO0_BASE = 0x50200000PIO1_BASE = 0x50300000RXF0_PUTGET0 = 0x128RXF0_PUTGET1 = 0x12cSM0_SHIFTCTRL = 0x0d0SM1_EXECCTRL = 0x0e4RXF0 = [RXF0_PUTGET0, RXF0_PUTGET1]def putget_write(index: int, value: int):    """Writes value to RXF0_PUTGET[index] register."""    mem32[PIO0_BASE + RXF0[index]] = value@asm_pio(sideset_init=PIO.OUT_HIGH)def rx_get_sm():    word(0b100_00000_1001_1_000)  # Load RXF0_PUTGET0 to OSR.    mov(x, osr)    irq(1)    label('on')    jmp(x_dec, 'on')    word(0b100_00000_1001_1_001)  # Load RXF0_PUTGET1 to OSR.    mov(x, osr)    irq(clear, 1)    label('off')    jmp(x_dec, 'off')@asm_pio(set_init=PIO.OUT_LOW)def irq_sm():    label('check')    mov(y, status)    jmp(not_y, 'off')    set(pins, 1)    jmp('check')    label('off')    set(pins, 0)sm0 = StateMachine(0, rx_get_sm)sm1 = StateMachine(5, irq_sm, set_base=Pin(25))  # Use state machine 1 on PIO1 to test communication between PIO blocks.mem32[PIO0_BASE + SM0_SHIFTCTRL] |= 1 << 14  # Enable FJOIN_RX_PUT.mem32[PIO1_BASE + SM1_EXECCTRL] |= 0x02 << 5 | 0x09  # Set STATUS_SEL to IRQ and IRQ index to 1 in lower-numbered PIO.putget_write(0, 10_000_000)putget_write(1, 300_000_000)sm0.active(1)sm1.active(1)
There's a helper function putget_write(index: int, value: int) for loading the PUTGET registers. Index=0 changes the on time, index=1 changes the off time, and value is the number of cycles the LED will be on/off.

I hope someone will find it useful or at least interesting. If you have any suggestions or ideas for other tests I could run, I'd be happy to hear them.

Statistics: Posted by horuable — Sun Aug 25, 2024 6:27 pm — Replies 0 — Views 28



Viewing all articles
Browse latest Browse all 3586

Trending Articles