Repository navigation
Home
When looking at various designs for the generation of video signals, I found an example with VGA output using a STM32 at http://www.artekit.eu/vga-output-using-a-36-pin-stm32/
I used parts of the code and modified it to create a similar demonstration which produces a PAL compatible interlaced video signal which can be connected to a TV set. The experiment was a useful exercise to get familiar with the STM32 and its built-in peripherals.
Unlike most other samples on the web which make use the interrupt facility of the CPU, my goal was to make a design which generates the video signal independent of the ARM processor, i.e. without any interrupt processing. The merit hereof is that the video signal is available at all times, even when the processor is stopped or at a breakpoint while debugging.
Another property of such a design is that the timing of the video signal will not depend on the (variable) execution time or latency of the interrupt system. Using a continuously running I2S serial output and associated timer, a rock solid video signal can be generated. So, I chose the I2S peripheral to stream out the pixel data. By streaming without pausing during blanking, the constant timing of the pixel data is guaranteed. Given the STM32L100C DISCO board, the dot-clock must be at or around 8 MHz. A second limitation of the specific DISCO board is the available RAM space for the frame buffer. With 16 kB, I calculated a resolution of 320 * 240, which occupies 9600 bytes of the RAM. Theoretically it is possible to double the dot-clock and modify the resolution to 640 * 480 when using a fixed image in flash-ROM, or with other STM32 variants that have more RAM. I have not tried this however.
Given the basic timing data of a PAL video signal, the following specification results:
I.e. 12 half words blank (zero) video data
Generating the sync pulses was a big puzzle. First, as the I2S peripheral is the origin of all timing, and the instant of when the pixel output commences is determined by the clock divider of that interface, the synchronisation pulses must be added to the pixel stream, rather than the other way around. The sync pulses are generated by a timer (TIM3) with separated outputs for Hsync and Vsync. When studying the required pulse pattern, it is clear that generating the Hsync is easy. It has a fixed pulse width and frequency, and a standard PWM output is appropriate. Generating the Vsync pattern required a lot of tuning. I succeeded by using another channel of the same timer (TIM3), configuring it with a toggling output, and using a DMA channel to reload the compare value from a circular table.<br> The pixel data source of the I2S interface is also loaded from a table using DMA, twice per 64 µsec line interval. Finally, some way of locking the sync pulse timer to the pixel data was needed. This was done by making the WordSelect output of the I2S interface available on a port pin, and feeding it into a delay timer. When the delay expires, it triggers the sync pulse timer (TIM3) so that the sync pulses are aligned to the video data stream with pixel accuracy.
Initially I used the internal HSI clock as the main clock source. When the video signal appeared at the output, it was blurred and unstable. After changing the clock source to the external 8 MHz crystal based clock, the picture got stable. This proved that the internal HSI clock is fairly accurate, but has quite some jitter which makes it unsuitable for precision (pulse) timing applications.
The video amplifier serves two purposes. It mixes the video and sync signals, and buffers them for the low-impedance output. The sync pulse outputs are configured using open-drain outputs so that they can be wire-ored, and pull the amplifier input to ground during sync. The input resistance of television sets is 75 Ω which is in parallel to R6.
