PIO docs in the rp2040 datasheet re stalling in combination with side-set need improvement
From what I found, in a PIO program like this
wait 0, pin 0
wait 1, pin 0 side 0
the side-set seems to be executed in every PIO cycle while the instruction is stalled, effectively making the side-set mostly sticky (depending on the clkdiv of the SM). The affected pin(s) can't be permanently changed neither from an instruction to SMx_INST on the same SM nor by any other SM, because that will be overwritten on the next cycle.
Therefore I consider the following statements in the RP2040 datasheet misleading and incomplete:
3.2.4 Stalling
-
"In this case, the program counter does not advance, and the state machine will continue executing this instruction on the next cycle"
:arrow_right: I'd understand "continue" as "doing stuff it hasn't already done" while in reality it seems to be "[...] will keep executing this instruction (including a possible side-set) until the stall clears."
- "Note":
"Side-set [...] always takes place on the first cycle of the attached instruction."
:arrow_right: In fact not only on the first, but continuously on every cycle, until the stall is cleared.
3.5.1 Side-set
- "Note": "If an instruction stalls, the side-set still takes effect immediately."
:arrow_right: Again, not only immediately, but continuously on every cycle, until the stall is cleared.
Ouch! Nice catch ... that would have bitten me also.
If I understand correctly then, to allow the side-set pin to be set high by another SM during the (stalled) wait, the program would need to be rewritten as:
wait 0, pin 0
nop side 0
wait 1, pin 0
with, of course, the cascading effects of that now taking an extra cycle....
with, of course, the cascading effects of that now taking an extra cycle....
Yes, though I'd argue the extra cycle doesn't hurt much in this case, which basically translates to "wait for an edge on one pin and set another pin in response", as it would only matter if the monitored pin immediately changes again in the next (PIO) cycle (and in a scenario where the input is expected to change that often, you'd probably use a different construct, anyway). But it also uses one additional word of instruction memory, which I'd consider more precious.
with, of course, the cascading effects of that now taking an extra cycle.... Yes, though I'd argue the extra cycle doesn't hurt much in this case ...
That's good. Some programs, however, have very specific cycle time requirements. The complexity escalates more when synchronizing two or state machines.
also uses one additional word of instruction memory, which I'd consider more precious.
So true! I recently became aware that the X, Y, and OSR register contents are not ensured to be zero when I start execution of a state machine ... and even SM_RESTART doesn't clear them to zero. I'm now thinking of starting my programs with a single-instruction infinite loop, and then using the SMx_INSTR register to manually perform initialization from the CPU (at least when the init isn't cycle-sensitive ... good enough to init X, Y, OSR, etc.).
Always something new to learn! 🙂
I'm now thinking of starting my programs with a single-instruction infinite loop, and then using the SMx_INSTR register to manually perform initialization from the CPU (at least when the init isn't cycle-sensitive ... good enough to init X, Y, OSR, etc.).
If I'm not mistaken, instructions written to SMx_INSTR are executed regardless if the SM is running or not. So you could initialize it with a series of instructions written to SMx_INSTR and then start it. No need for a dummy loop, IMO.
Hi,
I jst wanted to say I encountered the same problem today: I executed a NOP with a SIDE_SET using a forced execution via SMx_INSTR while the state machine was stalled on an OUT + SIDE_SET, the "stalled" OUT overrode the other side set (which then lasted for only 1 cycle and was not easy to spot without an oscilloscope).
I did not find the datasheet source in https://github.com/raspberrypi/documentation/tree/develop/documentation/asciidoc/microcontrollers/rp2040 . Is there a place were I could submit a PR ?
Is there a place were I could submit a PR ?
Unfortunately the source of our datasheets is not public.