RP2350: PIO IRQ between different PIO - something odd
As far as I can see the documentation is clear but appears backwards
PIO0:
irq 1 next 2 compiles to 0xC01A
PIO1:
wait 1 irq prev 2 compiles to 20CA
should work - but it doesn't.
What does work is:
PIO0:
irq 1 prev 2 compiles to 0xc00A
PIO1:
wait 1 irq next 2 compiles to 20DA
This is on a RP2350 where according to the documentation prev on pio0 should refer to PIO2 as should next on PIO1.
What am I missing?
At the moment I can' get an IRQ set on PIO 1 to trigger a wait on PIO0 at all given any combination of prevs and nexts
PIO0:
irq 1 next 2 compiles to 0xC01A
PIO1:
wait 1 irq prev 2 compiles to 20CA
should work - but it doesn't.
What does work is:
PIO0:
irq 1 prev 2 compiles to 0xc00A
PIO1:
wait 1 irq next 2 compiles to 20DA
This is on a RP2350 where according to the documentation prev on pio0 should refer to PIO2 as should next on PIO1.
What am I missing?
At the moment I can' get an IRQ set on PIO 1 to trigger a wait on PIO0 at all given any combination of prevs and nexts
Re: RP2350: PIO IRQ between different PIO - something odd
I think the issue is that, if in PIO 0 you "Trigger IRQ 2 in Next PIO", then, in PIO 1, the Wait needs to be on "its own IRQ 2", not the previous PIO's.
The second version works because "PIO 0 PREV 2" and "PIO 1 NEXT 2" both refer to "IRQ 2 in PIO 2".
This works for me. It uses interrupts to trigger tasks on alternative PIO -
The second version works because "PIO 0 PREV 2" and "PIO 1 NEXT 2" both refer to "IRQ 2 in PIO 2".
This works for me. It uses interrupts to trigger tasks on alternative PIO -
Code: Select all
.----->| |<-------------------------.
| | : |
| print "Master" .----> Wait for IRQ 1 |
| | | | |
| Wait 10 seconds | print "Slave" |
| | | | |
| Trigger IRQ 1 on NEXT PIO -----' Wait 5 seconds |
| : | |
| Wait for IRQ 0 <--------------------- Trigger IRQ 0 on PREV PIO |
| | | |
`------' `--------------------------'
Code: Select all
Trigger 0xC019 Wait 0x20C1
Wait 0x20C0 Trigger 0xC008
Code: Select all
from rp2 import asm_pio, StateMachine
import time
@asm_pio()
def Master():
def Irq(CLR, WAIT, MODE, INDEX):
return 0xC000 | ((CLR & 1) << 6) | ((WAIT & 1) << 5) | \
((MODE & 3) << 3) | (INDEX & 7)
def Wait(POL, SRC, MODE, INDEX):
return 0x2000 | ((POL & 1) << 7) | ((SRC & 3) << 5) | \
((MODE & 3) << 3) | (INDEX & 7)
# Get the time delay
pull(block)
mov(x, osr)
label("loop")
# Indicate activation
push()
# Do the delay
mov(y, x)
label("delay")
jmp(y_dec, "delay")
# Trigger the Slave - Set IRQ 1 in next PIO
n = Irq(CLR=0, WAIT=0, MODE=0b11, INDEX=1)
print("Trigger Slave = 0x{:04X}".format(n,))
word(n)
# Wait for the Slave complete - Wait until IRQ 0 set, clear IRQ 0
n = Wait(POL=1, SRC=0b10, MODE=0, INDEX=0)
print("Wait for Slave = 0x{:04X}".format(n))
word(n)
# And repeat forever
jmp("loop")
@asm_pio()
def Slave():
def Irq(CLR, WAIT, MODE, INDEX):
return 0xC000 | ((CLR & 1) << 6) | ((WAIT & 1) << 5) | \
((MODE & 3) << 3) | (INDEX & 7)
def Wait(POL, SRC, MODE, INDEX):
return 0x2000 | ((POL & 1) << 7) | ((SRC & 3) << 5) | \
((MODE & 3) << 3) | (INDEX & 7)
# Get the time delay
pull(block)
mov(x, osr)
label("loop")
# Wait to be triggered by Master - Wait until IRQ 1 becomes 1, clear IRQ 1
n = Wait(POL=1, SRC=0b10, MODE=0, INDEX=1)
print("Wait for Master = 0x{:04X}".format(n))
word(n)
# Indicate activation
push()
# Do the delay
mov(y, x)
label("delay")
jmp(y_dec, "delay")
# Trigger the Master - Set IRQ 0 in previous PIO
n = Irq(CLR=0, WAIT=0, MODE=0b01, INDEX=0)
print("Trigger Master = 0x{:04X}".format(n))
word(n)
# And repeat forever
jmp("loop")
# Allocate State Machines
SM_MASTER = 0 # PIO 0
SM_SLAVE = 4 # PIO 1
# Validity checks
print("")
if SM_MASTER < 0 or SM_MASTER > 11:
print("No such PIO{} for Master on SM{}".format(SM_MASTER >> 2, SM_MASTER))
elif SM_SLAVE < 0 or SM_SLAVE > 11:
print("No such PIO{} for Slave on SM{}".format(SM_SLAVE >> 2, SM_SLAVE))
elif SM_MASTER >> 2 == SM_SLAVE >> 2:
print("Master SM{} and Slave SM{} are on the same PIO engine".format(
SM_MASTER, SM_SLAVE))
else:
PIO_HZ = 1_000_000
ONE_SECOND = 1_000_000
master = StateMachine(SM_MASTER, Master, freq=PIO_HZ)
master.active(1)
slave = StateMachine(SM_SLAVE, Slave, freq=PIO_HZ)
slave.active(1)
master.put(10 * ONE_SECOND)
slave.put( 5 * ONE_SECOND)
# Report when State Machines activate
NOW = time.time
was = NOW()
while True:
while master.rx_fifo() > 0:
now = NOW()
master.get()
print("{} +{:<3} Master".format(now, now - was))
was = now
while slave.rx_fifo() > 0:
now = NOW()
slave.get()
print("{} +{:<3} Slave".format(now, now - was))
if now == was:
print("Needs a hard reset")
was = now
Code: Select all
pi@Pi4B:~/pico/micropython/ports/picopython/modules-examples $ mptool run RP235X_CrossPioIrqTriggers.py
Running './RP235X_CrossPioIrqTriggers.py' on the device
Trigger Slave = 0xC019
Wait for Slave = 0x20C0
Trigger Slave = 0xC019
Wait for Slave = 0x20C0
Wait for Master = 0x20C1
Trigger Master = 0xC008
Wait for Master = 0x20C1
Trigger Master = 0xC008
1609460230 +0 Master
1609460240 +10 Slave
1609460245 +5 Master
1609460255 +10 Slave
1609460260 +5 Master
1609460270 +10 Slave
^C
Re: RP2350: PIO IRQ between different PIO - something odd
I knew I was missing something - duh.
Thanks
Thanks
Re: RP2350: PIO IRQ between different PIO - something odd
Yep, each PIO block has its own set of IRQ flags.
To communicate between blocks, both should use the same set, not necessarily owned any of them but the same set, not crossed like pipelines.
PIO0 NEXT <=> PIO1
PIO1 NEXT <=> PIO2
PIO2 NEXT <=> PIO0 (wrapping to PIO0 if this is the highest-numbered PIO)
PIO0 PREV <=> PIO2 (wrapping to the highest-numbered PIO if this is PIO0)
PIO1 PREV <=> PIO0
PIO2 PREV <=> PIO1
And then combinations like this:
PIO0 NEXT <=> PIO1 <=> PIO2 PREV
PIO1 NEXT <=> PIO2 <=> PIO0 PREV
PIO2 NEXT <=> PIO0 <=> PIO1 PREV
I hope I didn't mess anything. :)
To communicate between blocks, both should use the same set, not necessarily owned any of them but the same set, not crossed like pipelines.
PIO0 NEXT <=> PIO1
PIO1 NEXT <=> PIO2
PIO2 NEXT <=> PIO0 (wrapping to PIO0 if this is the highest-numbered PIO)
PIO0 PREV <=> PIO2 (wrapping to the highest-numbered PIO if this is PIO0)
PIO1 PREV <=> PIO0
PIO2 PREV <=> PIO1
And then combinations like this:
PIO0 NEXT <=> PIO1 <=> PIO2 PREV
PIO1 NEXT <=> PIO2 <=> PIO0 PREV
PIO2 NEXT <=> PIO0 <=> PIO1 PREV
I hope I didn't mess anything. :)
Jump to
- Community
- General discussion
- Announcements
- Other languages
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- 日本語
- Polski
- Português
- Русский
- Türkçe
- User groups and events
- Raspberry Pi Official Magazine
- Using the Raspberry Pi
- Beginners
- Troubleshooting
- Advanced users
- Assistive technology and accessibility
- Education
- Picademy
- Teaching and learning resources
- Staffroom, classroom and projects
- Astro Pi
- Mathematica
- High Altitude Balloon
- Weather station
- Programming
- C/C++
- Java
- Python
- Scratch
- Other programming languages
- Windows 10 for IoT
- Wolfram Language
- Bare metal, Assembly language
- Graphics programming
- OpenGLES
- OpenVG
- OpenMAX
- General programming discussion
- Projects
- Networking and servers
- Automation, sensing and robotics
- Graphics, sound and multimedia
- Other projects
- Media centres
- Gaming
- AIY Projects
- Hardware and peripherals
- Camera board
- Compute Module
- Official Display
- HATs and other add-ons
- Device Tree
- Interfacing (DSI, CSI, I2C, etc.)
- Keyboard computers (400, 500, 500+)
- Raspberry Pi Pico
- General
- SDK
- MicroPython
- Other RP2040 boards
- Zephyr
- Rust
- AI Accelerator
- AI Camera - IMX500
- Hailo
- Software
- Raspberry Pi OS
- Raspberry Pi Connect
- Raspberry Pi Desktop for PC and Mac
- Beta testing
- Other
- Android
- Debian
- FreeBSD
- Gentoo
- Linux Kernel
- NetBSD
- openSUSE
- Plan 9
- Puppy
- Arch
- Pidora / Fedora
- RISCOS
- Ubuntu
- Ye Olde Pi Shoppe
- For sale
- Wanted
- Off topic
- Off topic discussion