Are your interrupt handlers definitely running on the right CPU? Where do you initialise them - inside screen_worker() or screen_initialise()? If you initialise the interrupt handler and enable the interrupt in screen_initialise() which is running on core0, then those interrupts will happen on core0 even though the rest of the screen handling has moved to core1.
This does sound very much like interrupt latency from the USB, and you should be able to get rid of almost all of that by moving to core1 - though to make it totally untouched by the other CPU you would need to arrange the two CPUs to be executing from separate RAM banks (otherwise timing could be perturbed by a few nanoseconds due to bus contention - much better than the few microseconds you might get from interrupts on the same CPU, but still maybe just visible as a fractional-pixel shimmer in the display).
However, if I have understood it correctly, I think your video timing generation like this is really much too fragile - you have the HSYNC accurately placed by the PIO, but then position the video relative to it by an IRQ handler starting a DMA. You really want the two PIO programs linked together such that the DMA started before the HSYNC, filled the PIO FIFO with pixels, and then the pixel PIO program starts a defined interval after the HSYNC.
One approach would be:
- make the pixel PIO program count the pixels in a line
- at the end of the line, use WAIT instruction(s) to wait for the HSYNC being generated by the other SM
- Either add some dummy blank pixels to the start of each line to cover the back porch time, or else have the PIO program insert a fixed
delay between the end of HSYNC and starting to move the pixels.
You might draw some inspiration from this project, even though it's doing rather different things to what you are:
https://github.com/arg08/pico-mode7
It's doing 50Hz TV video rather than VGA video, but that's just a difference in the timing constants. It was also originally written to overlay the video on top of syncs coming in from another piece of hardware, but for testing there's an HSYNC generator in a separate PIO SM so that it ends up doing rather similar to what you need - syncs generated in one SM, and pixels in another SM watching the timing of that to accurately position the video relative to the syncs.
It's also doing character-cell video for a text display rather than the graphics you are doing, so my PIO programs aren't directly relevant to your setup, but maybe a source of inspiration.
Probably if I was doing an output-only setup I would do the syncs and the video all in one SM, bit maybe there's some merit in separating them.
This does sound very much like interrupt latency from the USB, and you should be able to get rid of almost all of that by moving to core1 - though to make it totally untouched by the other CPU you would need to arrange the two CPUs to be executing from separate RAM banks (otherwise timing could be perturbed by a few nanoseconds due to bus contention - much better than the few microseconds you might get from interrupts on the same CPU, but still maybe just visible as a fractional-pixel shimmer in the display).
However, if I have understood it correctly, I think your video timing generation like this is really much too fragile - you have the HSYNC accurately placed by the PIO, but then position the video relative to it by an IRQ handler starting a DMA. You really want the two PIO programs linked together such that the DMA started before the HSYNC, filled the PIO FIFO with pixels, and then the pixel PIO program starts a defined interval after the HSYNC.
One approach would be:
- make the pixel PIO program count the pixels in a line
- at the end of the line, use WAIT instruction(s) to wait for the HSYNC being generated by the other SM
- Either add some dummy blank pixels to the start of each line to cover the back porch time, or else have the PIO program insert a fixed
delay between the end of HSYNC and starting to move the pixels.
You might draw some inspiration from this project, even though it's doing rather different things to what you are:
https://github.com/arg08/pico-mode7
It's doing 50Hz TV video rather than VGA video, but that's just a difference in the timing constants. It was also originally written to overlay the video on top of syncs coming in from another piece of hardware, but for testing there's an HSYNC generator in a separate PIO SM so that it ends up doing rather similar to what you need - syncs generated in one SM, and pixels in another SM watching the timing of that to accurately position the video relative to the syncs.
It's also doing character-cell video for a text display rather than the graphics you are doing, so my PIO programs aren't directly relevant to your setup, but maybe a source of inspiration.
Probably if I was doing an output-only setup I would do the syncs and the video all in one SM, bit maybe there's some merit in separating them.
Statistics: Posted by arg001 — Thu Oct 24, 2024 8:14 am