I tried to use IRQs for synchronizing other PIO state machines (SM) with a free running clock generator.
The idea is this:
Here, my first approach for a clock generator "clk":Idea:
generate a fastest clock as possible, generate an IRQ (4 for raising edge, 5 for falling edge) and synchronize other SMs by using code like this:But it does not work this way (see y assumptions below):So, it tells me:
So, IRQs work only up to 1/4 of the SYS CLK speed.
And: even I want to be "in sync" with the clock edges: my SM has an "uncertainty" of 1/2 (or even 1/4) of SYS CLK speed, before it will act on the IRQ signal generated.
If I run the generated clock via "clk" faster as 18.75 MHz - it does not work anymore as expected (the waveform looks wrong in terms of duty cycles and when signals are changed).
And the behavior becomes "random" (obvious, sometimes delayed or not).
So, assume, when using IRQ, the max. speed generating IRQs is 1/4 or even 1/8 of the SYS CLK speed.
The idea is this:
- have one SM just generating an endlessly running clock (as "clk" source)
- let other SMs synchronize with raising and falling edges of the generated clock, e.g. to send out or to sample in with edges
- try to use the max. frequency possible, e.g. 1/2 of SYS CLOCK (because two instructions needed to handle IRQs anyway)
Here, my first approach for a clock generator "clk":
Code:
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW)def clk(): wrap_target() irq(4)[0].side(1)#1 irq(clear, 4)[0] #2 irq(5)[0].side(0) #3 irq(clear, 5)[0] #4 wrap()
generate a fastest clock as possible, generate an IRQ (4 for raising edge, 5 for falling edge) and synchronize other SMs by using code like this:
Code:
set(x, 14)#5: 15 bits to send label("loop") irq(block, 4)#6: wait for rising edge - be in sync with clock generator "clk" out(pins, 1)#7: shift one bit out jmp(x_dec, "loop")
- I get an "offset": even I want to change with falling edge, the change happens not in sync with the clock edge (see below, obvious,
the IRQ signal itself is delayed inside system, but by how much? (assume, at least 1 SYS CLK cycle) - if I run the "clk" this way: I get two triggers (it looks like, or one additional SYS CLK needed), and it generates twice as many bits (every bit out has two clock cycles now)
Code:
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW)def clk(): wrap_target() irq(4)[0].side(1)#1 irq(clear, 4)[0] #2 nop()[1].side(0)#3: needed just to create a 50% duty cycle, without it looks wrong irq(5)[0] #4 irq(clear, 5)[0] #5 nop()[1] .side(1)#6: just for the duty cycle as approx. 50% wrap()
- I need already 2 clocks just for "irq(4)" and "irq(clear, 4)" (OK, obvious)
- but without this "nop() [1]" the clock is not symmetrical (50% duty cycle) anymore
- so, I have to divide the "clk" generated by 4 already, at least, to make it a symmetrical duty cycle
- every change on this code does not give me a nice 50% duty cycle
- or the synchronization with other SMs is messed up, e.g. getting an IRQ edge just two or four clocks later
- even I try to generate on every half SYS CLK cycle an IRQ
- this IRQ signal seems to go internally through a "clock synchronizer" (between PIO and other blocks)
- even I want to consume the IRQ signal generated in another SM "immediately" - it will be internally synchronized with the SM clock, the
IRQ logic etc. (all synced to the SYS CLK again) - there seems to be a synchronizer for the IRQ signal - it is not populated asynchronously ("immediately") to the consuming SM - so that it can delay the IRQ by at least one addition SYS CLK cycle more
So, IRQs work only up to 1/4 of the SYS CLK speed.
And: even I want to be "in sync" with the clock edges: my SM has an "uncertainty" of 1/2 (or even 1/4) of SYS CLK speed, before it will act on the IRQ signal generated.
If I run the generated clock via "clk" faster as 18.75 MHz - it does not work anymore as expected (the waveform looks wrong in terms of duty cycles and when signals are changed).
And the behavior becomes "random" (obvious, sometimes delayed or not).
So, assume, when using IRQ, the max. speed generating IRQs is 1/4 or even 1/8 of the SYS CLK speed.
Statistics: Posted by tjaekel — Thu Aug 29, 2024 2:16 am