Documentation improvements

This commit is contained in:
Wayne Venables
2025-08-26 20:47:11 -07:00
parent 4753b270f6
commit faef620629
517 changed files with 8124 additions and 4888 deletions

View File

@@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.17"/>
<meta name="generator" content="Doxygen 1.9.1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>PicoVGA: Usage Rules</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
@@ -29,7 +29,7 @@
<td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">PicoVGA
&#160;<span id="projectnumber">1.0-cmake</span>
&#160;<span id="projectnumber">1.2-cmake</span>
</div>
<div id="projectbrief">VGA/TV display on Raspberry Pico</div>
</td>
@@ -38,10 +38,10 @@
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.17 -->
<!-- Generated by Doxygen 1.9.1 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
@@ -90,24 +90,97 @@ $(document).ready(function(){initNavTree('usagerules.html',''); initResizable();
<div class="title">Usage Rules </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Image generation on the Raspberry Pico is a matter of processor utilization limits and other processor activities must be subordinated to it. When using the PicoVGA library, there are several principles to keep in mind:</p>
<p>The library always runs on the second core of the processor and the program on the first core. Rendering the image can completely overload the CPU core and is usually unusable for other use. The separation of core functions also has the advantage that the cores do not affect each other and there is no need for mutual locking. The first core simply uses write to the frame buffers and the second core displays the contents of the frame buffers without any communication between them. This makes the overall work easier and faster.</p>
<p>If the second core is not very busy (e.g. when displaying 8-bit graphics that are simply transferred using DMA transfer), it can also be used for the main program work. However, some limitations should be taken into account - the program in the second core should not use interrupts (it would interfere with the rendering function), the interpolation unit should be used with caution (the rendering function does not save its state) and it must not disable interrupts.</p>
<p>An important rule is that all data to be accessed by the PicoVGA library <b>must be stored in the RAM memory</b>. External flash memory is slow and cannot be used for rendering functions. For example, if a flash image is to be displayed, it must first be copied to a buffer in RAM, and then a pointer to the RAM copy of the image will be passed to the rendering function. If a pointer to the image in flash were passed to it, slow access to flash would cause video dropouts. In addition to images, this also applies to fonts and tile patterns, for example.</p>
<p>The limited rendering speed must be taken into account when scheduling screen layout. Some modes render very fast (e.g. 8-bit graphics are just transferred from the frame buffer using DMA) and some modes are very rendering intensive - e.g. rendering sprites in slow mode. When using demanding rendering, some video lines may not render fast enough in the required time and the video image will break (drop out of sync). In such cases, it is necessary to use another mode, or to reduce the rendered area (add other modes, faster ones - e.g. add tile controls on the sides of the screen), reduce the screen resolution or increase the CPU clock speed. Video lines are rendered separately and therefore it is always just content on one video line about, video lines do not affect each other. For example, you can test the speed of sprite rendering by placing all the sprites horizontally next to each other (the most challenging case) and check if the video synchronization fails.</p>
<p>Care must also be taken when using DMA transfer. DMA is used to transfer data to the PIO. Although the transfer uses a FIFO cache, using a different DMA channel may cause the render DMA channel to be delayed and thus cause the video to drop out. A DMA overload can occur, for example, when a large block of data in RAM is transferred quickly. However, the biggest load is the DMA transfer of data from flash memory. In this case, the DMA channel waits for data to be read from flash via QSPI and thus blocks the DMA render channel.</p>
<p>The CPU clock frequency must also be subordinated to the image generator. Before initializing the video node, the library calculates the required system clock frequency so that the timing matches the requirements and the processor speed is sufficient for the required image resolution. It is a good idea to initially print out the calculated clock frequency for checking on the console. It is possible to prohibit the library from changing the system clock, or to prescribe only a certain range, in which case some modes may be unreachable (or the video image may break up).</p>
<p>Image buffers must be aligned to 4 bytes (32-bit CPU word) and image segments must be horizontally aligned to 4 pixels - this refers to the horizontal position of the segment, its width, alignment (wrapx) and offset (offx). Alignment does not apply to the vertical direction. This restriction is necessary because the image information is transferred to the PIO controller using a 32-bit DMA transfer, and this must be aligned to a 32-bit word. One 32-bit word contains 4 pixels (1 pixel has 8 bits), so the horizontal data in the image must also be aligned to 4 pixels. So you cannot do fine horizontal scrolling of the image in 1 pixel increments (the restriction does not apply to vertical scrolling), but only in 4 pixel increments. The exception to this is slow sprites, which are software rendered to the video line and can therefore be scrolled in 1 pixel increments. Similarly, the restriction does not apply to software rendering to framebuffer (e.g. rendering an image to video memory can be done to any coordinate).</p>
<p>The display of the image by the PicoVGA library is performed by the PIO controller (PIO0). The other controller, PIO1, is unused and can be used for other purposes. </p>
<div class="textblock"><p><a class="anchor" id="md_pages_UsageRules"></a> Image generation on the Raspberry Pi Pico with PicoVGA is highly demanding on processor resources. The VGA signal must always be generated on time, which means other processor activities must be carefully designed around it. The following principles are critical for stable and reliable operation of the library:</p>
<h1><a class="anchor" id="autotoc_md31"></a>
Core Utilization</h1>
<ul>
<li>The PicoVGA library always runs on the <b>second core (core 1)</b>, while your application code runs on the <b>first core (core 0)</b>. This separation ensures that rendering does not interfere with your main program logic.</li>
<li>Rendering can fully saturate core 1, making it unsuitable for other tasks in most cases. Your main program should interact with PicoVGA by writing to frame buffers on core 0, while core 1 continuously handles video output without synchronization overhead.</li>
<li>In lightweight modes (e.g., 8-bit graphics rendered via DMA transfers), core 1 may have spare capacity. Code dispatched to core 1 through the library should not use interrupts, be careful with the interpolation unit (its state is not preserved by the renderer), and never disable interrupts.</li>
</ul>
<h1><a class="anchor" id="autotoc_md32"></a>
Memory Rules</h1>
<ul>
<li>All data accessed by PicoVGA (images, fonts, tile patterns, etc.) must be stored in <b>RAM</b>, not flash. Flash memory is too slow and will cause video dropouts.</li>
<li>If assets are stored in external flash, copy them into a RAM buffer before passing them to the rendering functions.</li>
</ul>
<h1><a class="anchor" id="autotoc_md33"></a>
Rendering Performance</h1>
<ul>
<li>Some modes (e.g., 8-bit DMA transfers) render very quickly, while others (e.g., sprite rendering in slow mode) are CPU-intensive.</li>
<li>Rendering is performed per line. If a mode is too demanding, individual scanlines may fail to render on time, breaking video synchronization.</li>
<li><b>If rendering is too slow:</b><ul>
<li>Switch to a faster video mode. <br />
</li>
<li>Reduce the resolution or rendered area. <br />
</li>
<li>Mix modes (e.g., add tile borders around the display area). <br />
</li>
<li>Increase the CPU clock speed. <br />
</li>
</ul>
</li>
</ul>
<p>A good stress test is to render many sprites side by side horizontally, which creates the most demanding case.</p>
<h1><a class="anchor" id="autotoc_md34"></a>
DMA Considerations</h1>
<ul>
<li>PicoVGA uses DMA to stream pixel data into the PIO. Even though the PIO has a TX <b>FIFO</b>, competing DMA traffic can delay the render DMA and cause <b>video dropouts</b>.</li>
<li><b>Conflicts to watch:</b><ul>
<li>Large, fast <b>RAM↔RAM</b> transfers on other DMA channels. <br />
</li>
<li><b>QSPI flash</b> reads (e.g., XIP or DMA from external flash). In these cases, the non-render DMA may stall waiting on flash, effectively <b>blocking</b> the render DMA channel.</li>
</ul>
</li>
<li>Minimize or schedule other DMA operations so they do not overlap with active rendering.</li>
</ul>
<h1><a class="anchor" id="autotoc_md35"></a>
CPU Clock Frequency</h1>
<ul>
<li>Before initializing video output, PicoVGA calculates and sets the required system clock frequency to ensure precise timing.</li>
<li>You should print the calculated frequency to the console at startup to verify configuration.</li>
<li>You may restrict the library from changing the system clock or limit its range. However, this can make some video modes unavailable or unstable.</li>
</ul>
<h1><a class="anchor" id="autotoc_md36"></a>
Memory Alignment</h1>
<ul>
<li>Image buffers must be aligned to <b>4 bytes</b> (32-bit words).</li>
<li>Image <b>segments must be horizontally aligned to 4 pixels</b>. This applies to the segments <b>X position</b>, <b>width</b>, <b>wrapping</b> (<b>wrapx</b>), and <b>horizontal offset</b> (<b>offx</b>). Vertical alignment has no such restriction.</li>
<li>Pixel data is transferred to the PIO using 32bit DMA words; each word packs <b>4× 8bit pixels</b>, so horizontal data must start on a 4pixel boundary.</li>
<li>Horizontal scrolling is limited to <b>4pixel steps</b>. Exceptions:<ul>
<li><b>Slow sprites</b> software-rendered per scanline; can scroll at <b>1pixel</b> precision.</li>
<li><b>Framebuffer software rendering</b> drawing directly into video memory allows <b>any pixel coordinate</b>.</li>
</ul>
</li>
</ul>
<h1><a class="anchor" id="autotoc_md37"></a>
PIO Usage</h1>
<ul>
<li>PicoVGA exclusively uses <b>PIO0</b> for video output.</li>
<li>The second controller, <b>PIO1</b>, remains free and can be used for other purposes in your program.</li>
</ul>
<h1><a class="anchor" id="autotoc_md38"></a>
Summary</h1>
<p>To use PicoVGA effectively:</p><ol type="1">
<li>Treat core 1 as dedicated to rendering. <br />
</li>
<li>Keep all rendering assets in RAM. <br />
</li>
<li>Match your rendering mode to the available performance. <br />
</li>
<li>Avoid DMA conflicts and verify clock settings. <br />
</li>
<li>Respect memory alignment rules (including <b>wrapx</b> and <b>offx</b>) for stable operation. <br />
</li>
</ol>
<p>Following these principles ensures smooth VGA output and stable integration of PicoVGA into your Raspberry Pi Pico projects. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.17 </li>
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
</ul>
</div>
</body>