CommonPIC32

docs/wiki/VGA_Signal_Output

154:c8a37eb47211
2021-12-14 Paul Boddie Fixed pin labels: RB10/PGEC3 should be RB10/PGED2.
     1 = VGA Signal Output =     2      3 A number of [[VGA Output Examples|examples]] demonstrate VGA signal generation     4 from a PIC32 microcontroller. These examples employ a particular [[VGA Signal     5 Wiring|wiring scheme]] in order to deliver signals to a suitable display or     6 monitor.     7      8 Within the microcontroller, there are two principal mechanisms demonstrated in     9 this project for generating a VGA signal:    10     11  * Using the CPU to "copy" pixel data to an output port    12  * Using DMA transfers to "copy" pixel data to an output port    13     14 Within the latter, there are a number of variations in the mechanism employed:    15     16  * Use of general-purpose output pins versus parallel mode outputs    17  * Use of large transfer cells containing each entire pixel line versus small    18    transfer cells containing fragments of each line    19  * Use of a single transfer-initiating event versus separate line-initiating    20    and transfer-initiating events    21     22 == Using the CPU for Transfers ==    23     24 {{{#!graphviz    25 //format=svg    26 //transform=notugly    27 digraph cpu {    28   node [shape=box,fontsize="13.0",fontname="sans-serif"];    29   rankdir=TD;    30     31   subgraph {    32     rank=same;    33     34     timer [label="Display line\ntimer",style=filled,fillcolor=gold];    35     t_0 [label="0",shape=ellipse];    36     t_hsync [label="hsync",shape=ellipse];    37     t_limit [label="limit",shape=ellipse];    38   }    39     40   oc1 [label="Output compare",style=filled,fillcolor=gold];    41     42   subgraph {    43     rank=same;    44     45     lineirq [label="Display line\ninterrupt handler"];    46     pixelirq [label="Pixel output\ninterrupt handler"];    47   }    48     49   subgraph {    50     rank=same;    51     52     pixels [label="Pixel output\nBlack/reset output",style=filled,fillcolor=green,shape=parallelogram];    53     hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];    54     vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];    55   }    56     57   /* The timer starts at 0 and wraps around at limit. */    58     59   timer -> t_0 [arrowhead=none];    60   t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];    61     62   /* The timer initiates the interrupt request for pixel production. */    63     64   t_0 -> pixelirq;    65     66   /* The interrupt handler generates the pixel output. */    67     68   pixelirq -> pixels;    69     70   /* The timer feeds the output compare unit, driving hsync. */    71     72   t_hsync -> oc1;    73   oc1 -> hsync;    74     75   /* The output compare unit initiates the interrupt request for each line,    76      driving vsync. */    77     78   oc1 -> lineirq;    79   lineirq -> vsync;    80 }    81 }}}    82     83 == Using DMA for Transfers ==    84     85 {{{#!graphviz    86 //format=svg    87 //transform=notugly    88 digraph dma {    89   node [shape=box,fontsize="13.0",fontname="sans-serif"];    90   rankdir=TD;    91     92   subgraph {    93     rank=same;    94     95     timer [label="Display line\ntimer",style=filled,fillcolor=gold];    96     t_0 [label="0",shape=ellipse];    97     t_hsync [label="hsync",shape=ellipse];    98     t_limit [label="limit",shape=ellipse];    99   }   100    101   oc1 [label="Output compare",style=filled,fillcolor=gold];   102    103   subgraph {   104     rank=same;   105    106     dma_line [label="Pixel output\nDMA channel",style=filled,fillcolor=lightblue];   107     dma_reset [label="Pixel reset\nDMA channel",style=filled,fillcolor=lightblue];   108     lineirq [label="Display line\ninterrupt handler"];   109   }   110    111   subgraph {   112     rank=same;   113    114     pixels [label="Pixel output",style=filled,fillcolor=green,shape=parallelogram];   115     black [label="Black/reset output",style=filled,fillcolor=black,fontcolor=white,shape=parallelogram];   116     hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];   117     vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];   118   }   119    120   /* The timer starts at 0 and wraps around at limit. */   121    122   timer -> t_0 [arrowhead=none];   123   t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];   124    125   /* The timer initiates the DMA transfer for pixel production. */   126    127   t_0 -> dma_line;   128    129   /* The line channel generates the pixel output. */    130    131   dma_line -> pixels;   132    133   /* The completion of the line channel initiates the reset channel. */   134    135   dma_line -> dma_reset;   136    137   /* The reset channel generates black/reset output. */   138    139   dma_reset -> black;   140    141   /* The black/reset value follows the visible pixels. */   142    143   pixels -> black [style=dashed];   144    145   /* The timer feeds the output compare unit, driving hsync. */   146    147   t_hsync -> oc1;   148   oc1 -> hsync;   149    150   /* The output compare unit initiates the interrupt request for each line,   151      driving vsync. */   152    153   oc1 -> lineirq;   154   lineirq -> vsync;   155 }   156 }}}   157    158 == Using DMA and Timed Transfers ==   159    160 {{{#!graphviz   161 //format=svg   162 //transform=notugly   163 digraph dma {   164   node [shape=box,fontsize="13.0",fontname="sans-serif"];   165   rankdir=TD;   166    167   subgraph {   168     rank=same;   169    170     timer [label="Display line\ntimer",style=filled,fillcolor=gold];   171     t_0 [label="0",shape=ellipse];   172     t_hsync [label="hsync",shape=ellipse];   173     t_limit [label="limit",shape=ellipse];   174   }   175    176   oc1 [label="Output compare",style=filled,fillcolor=gold];   177    178   subgraph {   179     rank=same;   180    181     trtimer [label="Transfer timer",style=filled,fillcolor=gold];   182     tr_0 [label="0",shape=ellipse];   183     tr_limit [label="limit",shape=ellipse];   184   }   185    186   subgraph {   187     rank=same;   188    189     dma_init [label="Initiator\nDMA channel",style=filled,fillcolor=lightblue];   190     dma_line [label="Pixel output\nDMA channel",style=filled,fillcolor=lightblue];   191     dma_reset [label="Pixel reset\nDMA channel",style=filled,fillcolor=lightblue];   192     lineirq [label="Display line\ninterrupt handler"];   193   }   194    195   subgraph {   196     rank=same;   197    198     pixels [label="Pixel output",style=filled,fillcolor=green,shape=parallelogram];   199     black [label="Black/reset output",style=filled,fillcolor=black,fontcolor=white,shape=parallelogram];   200     hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];   201     vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];   202   }   203    204   /* The line timer starts at 0 and wraps around at limit. */   205    206   timer -> t_0 [arrowhead=none];   207   t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];   208    209   /* The transfer timer starts at 0 and wraps around at limit. */   210    211   trtimer -> tr_0 [arrowhead=none];   212   tr_0 -> tr_limit -> tr_0 [style=dashed];   213    214   /* The line timer initiates the DMA transfers for the display line. */   215    216   t_0 -> dma_init;   217    218   /* The completion of the initiating channel enables the line channel. */   219    220   dma_init -> dma_line;   221    222   /* Each cell transfer in the line channel is initiated by the transfer   223      timer. */   224    225   tr_0 -> dma_line;   226    227   /* The line channel generates the pixel output. */    228    229   dma_line -> pixels;   230    231   /* The completion of the line channel initiates the reset channel. */   232    233   dma_line -> dma_reset;   234    235   /* The reset channel generates black/reset output. */   236    237   dma_reset -> black;   238    239   /* The black/reset value follows the visible pixels. */   240    241   pixels -> black [style=dashed];   242    243   /* The timer feeds the output compare unit, driving hsync. */   244    245   t_hsync -> oc1;   246   oc1 -> hsync;   247    248   /* The output compare unit initiates the interrupt request for each line,   249      driving vsync. */   250    251   oc1 -> lineirq;   252   lineirq -> vsync;   253 }   254 }}}   255    256 == Using DMA and Timed Dual-Channel Transfers ==   257    258 {{{#!graphviz   259 //format=svg   260 //transform=notugly   261 digraph dma {   262   node [shape=box,fontsize="13.0",fontname="sans-serif"];   263   rankdir=TD;   264    265   subgraph {   266     rank=same;   267    268     timer [label="Display line\ntimer",style=filled,fillcolor=gold];   269     t_0 [label="0",shape=ellipse];   270     t_hsync [label="hsync",shape=ellipse];   271     t_limit [label="limit",shape=ellipse];   272   }   273    274   oc1 [label="Output compare",style=filled,fillcolor=gold];   275    276   subgraph {   277     rank=same;   278    279     trtimer [label="Transfer timer",style=filled,fillcolor=gold];   280     tr_0 [label="0",shape=ellipse];   281     tr_limit [label="limit",shape=ellipse];   282   }   283    284   subgraph {   285     rank=same;   286    287     dma_init [label="Initiator\nDMA channel",style=filled,fillcolor=lightblue];   288     dma_line [label="{Pixel output\nDMA channel #1 | Pixel output\nDMA channel #2}",style=filled,fillcolor=lightblue,shape=record];   289     dma_reset [label="Pixel reset\nDMA channel",style=filled,fillcolor=lightblue];   290     lineirq [label="Display line\ninterrupt handler"];   291   }   292    293   subgraph {   294     rank=same;   295    296     pixels [label="Pixel output",style=filled,fillcolor=green,shape=parallelogram];   297     black [label="Black/reset output",style=filled,fillcolor=black,fontcolor=white,shape=parallelogram];   298     hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];   299     vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];   300   }   301    302   /* The line timer starts at 0 and wraps around at limit. */   303    304   timer -> t_0 [arrowhead=none];   305   t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];   306    307   /* The transfer timer starts at 0 and wraps around at limit. */   308    309   trtimer -> tr_0 [arrowhead=none];   310   tr_0 -> tr_limit -> tr_0 [style=dashed];   311    312   /* The line timer initiates the DMA transfers for the display line. */   313    314   t_0 -> dma_init;   315    316   /* The completion of the initiating channel enables the line channels. */   317    318   dma_init -> dma_line;   319    320   /* Each cell transfer in the line channels is initiated by the transfer   321      timer. */   322    323   tr_0 -> dma_line;   324    325   /* The line channels generate the pixel output. */    326    327   dma_line -> pixels;   328    329   /* The completion of the line channels initiates the reset channel. */   330    331   dma_line -> dma_reset;   332    333   /* The reset channel generates black/reset output. */   334    335   dma_reset -> black;   336    337   /* The black/reset value follows the visible pixels. */   338    339   pixels -> black [style=dashed];   340    341   /* The timer feeds the output compare unit, driving hsync. */   342    343   t_hsync -> oc1;   344   oc1 -> hsync;   345    346   /* The output compare unit initiates the interrupt request for each line,   347      driving vsync. */   348    349   oc1 -> lineirq;   350   lineirq -> vsync;   351 }   352 }}}