I have a problem with a simple use of the IRQ and WAIT instructions for synchronising two PIO state machines. Here’s the bones of the problem:
* One state machine (call it sm_A) waits for an interrupt flag to be raised and then turns on a LED:* The other state machine (call it sm_B) waits for a second or two and then raises the interrupt flag:Both state machines are started together. In principle, sm_A should stall at the wait instruction until (a second or two later) sm_B raises the interrupt flag. Then, sm_A should continue execution and turn on the LED. But, in practice, I find that the LED remains off, indicating that sm_A hasn’t advanced beyond the wait instruction. It hasn't responded to the raised flag.
I would welcome advice: I imagine I must be overlooking something fairly basic . . .
The actual PIO program file is:(The purpose of the RGB LED is simply to confirm that sm_B is functioning as expected.)
The accompanying C program is:
* One state machine (call it sm_A) waits for an interrupt flag to be raised and then turns on a LED:
Code:
.define FLAG 2; An arbitrary choice of IRQ.program pp_Await 1 irq FLAG; Wait until the flag is raisedset pins 1; Turn on the LEDloop: jmp loop; StopCode:
.program pp2 . . .; Pause for a second irq set FLAG; Raise the flag loop: jmp loop; StopI would welcome advice: I imagine I must be overlooking something fairly basic . . .
The actual PIO program file is:
Code:
.define FLAG 2 ; An arbitrary choice of IRQ.program pp_A set pins 0 ; Turn off the LED wait 1 irq FLAG ; Wait until IRQ flag is raised set pins 1 ; Turn on the LEDloop: jmp loop ; Halt ; ====================================================== .program pp_B .define RED 0b110 ; A RGB LED is attached to the Pico.define GREEN 0b101.define BLUE 0b011.define ALL_OFF 0b111 set pins RED ; Turn on the red LED set x 8 ; Set X to 0x10000000 mov x :: xl: jmp x-- l ; Count X down to zero (takes a second or two) irq set FLAG ; Raise the IRQ flag set pins GREEN ; Turn on the green LEDloop: jmp loop ; HaltThe accompanying C program is:
Code:
#include <stdio.h>#include <math.h>#include "pico/stdlib.h"#include "hardware/pio.h"#include "pp.pio.h"int main() { stdio_init_all(); // Configure and run two SMs, sm_A and sm_B // sm_A will run program pp_A which will: // - turn off the on-board LED // - wait for an IRQ flag to be raised // - turn on the on-board LED // - halt // // sm_B will run program pp_B which will: // - turn on the Red LED // - delay for a couple of seconds // - raise that IRQ flag // - turn on the Green LED // - halt const PIO pio = pio0; const uint pin_A = PICO_DEFAULT_LED_PIN; const uint PIN_BASE = 11; // RGB LED attached to GPIO 11, 12, 13 // Initialise sm_A to run program pp_A const uint sm_A = 0; uint offset_A = pio_add_program(pio, &pp_A_program); pio_sm_config c_A = pp_A_program_get_default_config(offset_A); // Configure outputs to on-board LED pio_gpio_init(pio, pin_A); pio_sm_set_consecutive_pindirs(pio, sm_A, pin_A, 1, true); sm_config_set_set_pins(&c_A, pin_A, 1); pio_sm_init(pio, sm_A, offset_A, &c_A); pio_sm_set_enabled(pio, sm_A, true); // -------------------------------------------------- // Initialise sm_B to run program pp_B const uint sm_B = 0; uint offset_B = pio_add_program(pio, &pp_B_program); pio_sm_config c_B = pp_B_program_get_default_config(offset_B); // Configure outputs to RGB LEDs sm_config_set_out_pins(&c_B, PIN_BASE, 3); sm_config_set_set_pins(&c_B, PIN_BASE, 3); for (uint i = 0; i < 3; i++) { pio_gpio_init(pio, PIN_BASE + i); } pio_sm_set_consecutive_pindirs(pio, sm_B, PIN_BASE, 3, true); pio_sm_init(pio, sm_B, offset_B, &c_B); pio_sm_set_enabled(pio, sm_B, true);}Statistics: Posted by KeithHan — Thu Sep 25, 2025 4:15 pm — Replies 0 — Views 40