This example demonstrates the generation of an analogue VGA signal from a PIC32 microcontroller using general output pins. Instead of using DMA, which was the focus of the VGAPIC32 project and is a central feature of the approaches demonstrated by other examples (vga, vga-dual, vga-pmp, vga-timer), here the CPU is given the task of transferring pixel data to the output pins.
Instead of a timer interrupt condition initiating DMA transfers, the interrupt is handled and a routine invoked to issue the necessary load and store instructions in a loop. Otherwise, the use of the timer to generate sync pulses is as in the other examples and the general display state machine is largely the same.
The resulting picture is more pleasing than that produced by most of the DMA examples in that the display pixels have consistent widths. Moreover, the pixels are also narrower than those produced by the vga-timer example. It is possible to generate a display with something approaching 200 pixels horizontally, with 160 pixels being demonstrated.
However, the CPU now spends a lot of time occupied in an interrupt request handler generating pixels. This seems less elegant than using DMA, but in practice, the CPU may be effectively stalled where DMA transfers dominate access to the RAM. Even if, in such situations, the CPU may be able to access flash memory to load instructions, programs typically end up accessing RAM at some point, and this would effectively limit the concurrency within the system. Certainly, this approach seems to result in slower programs than the plain DMA-based approach.
One potential advantage of this approach is in the flexibility that might be achieved by manipulating the pixel data. With DMA, data is transferred as it is found and is generally not transformed (although there are some features in the PIC32 DMA controller for certain kinds of data), whereas we might envisage supporting display modes employing fewer bits for the output signal, reducing the number of colours but also the size of the framebuffer.
The pin usage of this solution is documented below.
MCLR# 1 \/ 28 HSYNC/OC1/RA0 2 27 VSYNC/OC2/RA1 3 26 RB15/U1TX D0/RB0 4 25 RB14 D1/RB1 5 24 RB13/U1RX D2/RB2 6 23 D3/RB3 7 22 RB11/PGEC2 8 21 RB10/PGEC3 RA2 9 20 RA3 10 19 D4/RB4 11 18 RB9 12 17 RB8 13 16 RB7/D7 D5/RB5 14 15
Note that RB6 is not available on pin 15 on this device (it is needed for VBUS unlike the MX170 variant).
UART1 is exposed by the RB13 and RB15 pins.
For one bit of intensity, two bits per colour channel:
D7 -> 2200R -> I I -> diode -> R I -> diode -> G I -> diode -> B D6 (not connected) D5 -> 470R -> R D4 -> 1000R -> R D3 -> 470R -> G D2 -> 1000R -> G D1 -> 470R -> B D0 -> 1000R -> B HSYNC -> HS VSYNC -> VS