paul@148 | 1 | = VGA Output Example (Timed DMA Transfers) = |
paul@148 | 2 | |
paul@149 | 3 | This example demonstrates the generation of an analogue [[VGA Signal Output| |
paul@149 | 4 | VGA]] signal from a PIC32 microcontroller using general output pins. Unlike |
paul@149 | 5 | the [[../vga|vga]] and [[../vga-pmp|vga-pmp]] examples, it employs a regular |
paul@149 | 6 | interrupt condition to schedule single-byte (single-pixel) DMA transfers |
paul@149 | 7 | instead of a single whole-line transfer. |
paul@148 | 8 | |
paul@148 | 9 | The principal advantage of this method over the whole-line transfer method is |
paul@148 | 10 | its production of pixels with consistent widths. The principal disadvantage is |
paul@148 | 11 | the significant loss of horizontal resolution due to the latencies involved in |
paul@148 | 12 | propagating interrupt conditions to the DMA controller and thereby initiating |
paul@148 | 13 | each transfer. |
paul@148 | 14 | |
paul@148 | 15 | Employing a peripheral clock that has half the frequency of the system clock |
paul@148 | 16 | should ensure the stability of the picture, since the lower frequency may make |
paul@148 | 17 | transfers easier to schedule. The peripheral clock should provide a more |
paul@148 | 18 | forgiving deadline for each transfer, permitting late transfers to complete on |
paul@148 | 19 | time. |
paul@148 | 20 | |
paul@148 | 21 | Meanwhile, matching the system and peripheral clock frequencies appears to |
paul@148 | 22 | leave the scheduling of transfers open to uncertainty, with transfers being |
paul@148 | 23 | more readily delayed by other activity in the system, and with instability of |
paul@148 | 24 | the picture being the result. |
paul@148 | 25 | |
paul@148 | 26 | Unlike the [[../vga|vga]] example, but in common with the |
paul@148 | 27 | [[../vga-dual|vga-dual]] example, this example employs two DMA channels for |
paul@148 | 28 | pixel data which are interleaved to investigate a potential remedy for the |
paul@148 | 29 | wide pixel effect. This seems to preserve consistent pixel widths only with a |
paul@148 | 30 | transfer cell size of 1: other cell sizes suffer from the wide pixel problem. |
paul@148 | 31 | Despite not offering the greater throughput of larger cell sizes, merely |
paul@148 | 32 | employing dual channels increases throughput for a cell size of 1, making the |
paul@148 | 33 | technique worth using. |
paul@148 | 34 | |
paul@148 | 35 | In contrast to the [[../vga|vga]] and [[../vga-pmp|vga-pmp]] examples, a |
paul@148 | 36 | special DMA channel is employed to initiate the pixel transfer process without |
paul@148 | 37 | actually transferring any pixel data itself. The channel arrangement is as |
paul@148 | 38 | follows: |
paul@148 | 39 | |
paul@148 | 40 | || Transfer Initiator || DMA Channel || Transfer Activity || |
paul@148 | 41 | || Timer2 || DMA1 || zerodata -> PORTB || |
paul@148 | 42 | || Timer3 || DMA0 || linedata -> PORTB || |
paul@148 | 43 | || Timer3 || DMA2 || linedata -> PORTB || |
paul@148 | 44 | || Timer3 || DMA3 || zerodata -> PORTB || |
paul@148 | 45 | |
paul@148 | 46 | The real purpose of this channel (DMA1) is to capture the Timer2 interrupt |
paul@148 | 47 | condition and to enable the following channels (DMA0, DMA2) through channel |
paul@148 | 48 | chaining. Having been enabled, DMA0 and DMA2 are then able to conduct |
paul@148 | 49 | transfers at a tempo dictated by Timer3. Finally, DMA3 acts as the "reset" or |
paul@148 | 50 | "zero" channel to ensure that the pixel level is set to black at the end of |
paul@148 | 51 | each display line. |
paul@148 | 52 | |
paul@148 | 53 | In principle, other initiating conditions can be used instead of Timer3, which |
paul@148 | 54 | is configured to produce such conditions as frequently as possible: |
paul@148 | 55 | |
paul@148 | 56 | * A persistent interrupt condition can be employed instead. For example, |
paul@148 | 57 | configuring UART2 and setting the UART2 transfer interrupt, employing this |
paul@148 | 58 | interrupt condition for DMA0 and DMA2, produces the same effect. |
paul@148 | 59 | |
paul@148 | 60 | * An external interrupt such as INT2 can be configured, and the peripheral |
paul@148 | 61 | clock can be routed through the CLKO pin and back into the microcontroller |
paul@148 | 62 | via an appropriate pin. With INT2 being employed as the interrupt |
paul@148 | 63 | condition for DMA0 and DMA2, the same effect is produced. |
paul@148 | 64 | |
paul@148 | 65 | == Hardware Details == |
paul@148 | 66 | |
paul@148 | 67 | The pin usage of this solution is documented below. |
paul@148 | 68 | |
paul@148 | 69 | === PIC32MX270F256B-50I/SP Pin Assignments === |
paul@148 | 70 | |
paul@148 | 71 | {{{ |
paul@148 | 72 | MCLR# 1 \/ 28 |
paul@148 | 73 | HSYNC/OC1/RA0 2 27 |
paul@148 | 74 | VSYNC/OC2/RA1 3 26 RB15/U1TX |
paul@148 | 75 | D0/RB0 4 25 RB14 |
paul@148 | 76 | D1/RB1 5 24 RB13/U1RX |
paul@148 | 77 | D2/RB2 6 23 |
paul@148 | 78 | D3/RB3 7 22 RB11/PGEC2 |
paul@154 | 79 | 8 21 RB10/PGED2 |
paul@148 | 80 | RA2 9 20 |
paul@148 | 81 | RA3 10 19 |
paul@148 | 82 | D4/RB4 11 18 RB9 |
paul@148 | 83 | 12 17 RB8 |
paul@148 | 84 | 13 16 RB7/D7 |
paul@148 | 85 | D5/RB5 14 15 |
paul@148 | 86 | }}} |
paul@148 | 87 | |
paul@148 | 88 | Note that RB6 is not available on pin 15 on this device (it is needed for VBUS |
paul@148 | 89 | unlike the MX170 variant). |
paul@148 | 90 | |
paul@148 | 91 | === UART Connections === |
paul@148 | 92 | |
paul@148 | 93 | UART1 is exposed by the RB13 and RB15 pins. |
paul@148 | 94 | |
paul@148 | 95 | === Data Signal Routing === |
paul@148 | 96 | |
paul@148 | 97 | For one bit of intensity, two bits per colour channel: |
paul@148 | 98 | |
paul@148 | 99 | {{{ |
paul@148 | 100 | D7 -> 2200R -> I |
paul@148 | 101 | |
paul@148 | 102 | I -> diode -> R |
paul@148 | 103 | I -> diode -> G |
paul@148 | 104 | I -> diode -> B |
paul@148 | 105 | |
paul@148 | 106 | D6 (not connected) |
paul@148 | 107 | |
paul@148 | 108 | D5 -> 470R -> R |
paul@148 | 109 | D4 -> 1000R -> R |
paul@148 | 110 | D3 -> 470R -> G |
paul@148 | 111 | D2 -> 1000R -> G |
paul@148 | 112 | D1 -> 470R -> B |
paul@148 | 113 | D0 -> 1000R -> B |
paul@148 | 114 | |
paul@148 | 115 | HSYNC -> HS |
paul@148 | 116 | VSYNC -> VS |
paul@148 | 117 | }}} |