Electronic – image distortion generating VGA signal on STM32 f4 using DMA

interruptssoftwarestm32vgavideo

I'm trying to build a video generator using the STM32f4 (168MHz, using discovery board) + R ladder DAC to the VGA signal.

The idea is not to be based on a framebuffer (this would limit the resolution and color depth cause the board has 128k RAM externally addressable which allows 320×200 double buffer @ 8bpp) but to compose one line buffer by the CPU while the other line buffer is being sent to the DAC by the DMA.

The H-sync interrupt (at 30-something KHz for vga signals) would :

  • trigger sync signal generation,
  • switch linebuffers between displayed and background buffer
  • start the DMA on the "displayed" linebuffer
  • then fill / do compositing of the "backbuffer" with data

This idea works quite well for now , except I see a LOT of horizontal jittering (up to 1/4 of the screen), resulting in vertical lines being stable in time but varying a lot horizontally (ie being not vertical at all and giving bad image distortion).

I suspect contention on the memory bus, but I gave DMA and interrupts the highest priority.
(there has to be memory transfers because the data line gets modified at each h-sync).

(same resolution static framebuffer -320×200 repeated horzintally / vertically ) works quite well and does not have this shearing, maybe by a single pixel sometimes)

I'll include a screenshot as soon as I can.

Is there a means to improve on this, or am I damned by the frequent memory transfers between the CPU and the RAM ? Should I switch every N lines ? (ie have bigger buffers, reducing the number of switches but not the amount transferred ?)

Shall I separate buffers more so that the same "memory bank" / line is not solicited (if such a thing exists) ? Use several interrupts ?
Should I put the CPU to sleep before timer interrupts ?
Any idea ?

Best Answer

OK, answering my own question because I finally got it : the FIFO feature of the DMA was not enabled, so any interruption or memory transfer was delaying access to the memory bus by the DMA.

Enabling it is much better now. This has been done with this :

// Enable FIFO (see p190 of ref manual)
DMA2_Stream1->FCR=DMA_SxFCR_DMDIS; // disable direct mode