188 lines
9.2 KiB
HTML
188 lines
9.2 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<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.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"/>
|
||
<script type="text/javascript" src="jquery.js"></script>
|
||
<script type="text/javascript" src="dynsections.js"></script>
|
||
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
||
<script type="text/javascript" src="resize.js"></script>
|
||
<script type="text/javascript" src="navtreedata.js"></script>
|
||
<script type="text/javascript" src="navtree.js"></script>
|
||
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||
<script type="text/javascript" src="search/searchdata.js"></script>
|
||
<script type="text/javascript" src="search/search.js"></script>
|
||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
|
||
<link href="custom.css" rel="stylesheet" type="text/css"/>
|
||
</head>
|
||
<body>
|
||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||
<div id="titlearea">
|
||
<table cellspacing="0" cellpadding="0">
|
||
<tbody>
|
||
<tr style="height: 56px;">
|
||
<td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
|
||
<td id="projectalign" style="padding-left: 0.5em;">
|
||
<div id="projectname">PicoVGA
|
||
 <span id="projectnumber">1.2-cmake</span>
|
||
</div>
|
||
<div id="projectbrief">VGA/TV display on Raspberry Pico</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<!-- end header part -->
|
||
<!-- Generated by Doxygen 1.9.1 -->
|
||
<script type="text/javascript">
|
||
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
|
||
/* @license-end */
|
||
</script>
|
||
<script type="text/javascript" src="menudata.js"></script>
|
||
<script type="text/javascript" src="menu.js"></script>
|
||
<script type="text/javascript">
|
||
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||
$(function() {
|
||
initMenu('',true,false,'search.php','Search');
|
||
$(document).ready(function() { init_search(); });
|
||
});
|
||
/* @license-end */</script>
|
||
<div id="main-nav"></div>
|
||
</div><!-- top -->
|
||
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
||
<div id="nav-tree">
|
||
<div id="nav-tree-contents">
|
||
<div id="nav-sync" class="sync"></div>
|
||
</div>
|
||
</div>
|
||
<div id="splitbar" style="-moz-user-select:none;"
|
||
class="ui-resizable-handle">
|
||
</div>
|
||
</div>
|
||
<script type="text/javascript">
|
||
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||
$(document).ready(function(){initNavTree('usagerules.html',''); initResizable(); });
|
||
/* @license-end */
|
||
</script>
|
||
<div id="doc-content">
|
||
<!-- window showing the filter options -->
|
||
<div id="MSearchSelectWindow"
|
||
onmouseover="return searchBox.OnSearchSelectShow()"
|
||
onmouseout="return searchBox.OnSearchSelectHide()"
|
||
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||
</div>
|
||
|
||
<!-- iframe showing the search results (closed by default) -->
|
||
<div id="MSearchResultsWindow">
|
||
<iframe src="javascript:void(0)" frameborder="0"
|
||
name="MSearchResults" id="MSearchResults">
|
||
</iframe>
|
||
</div>
|
||
|
||
<div class="PageDoc"><div class="header">
|
||
<div class="headertitle">
|
||
<div class="title">Usage Rules </div> </div>
|
||
</div><!--header-->
|
||
<div class="contents">
|
||
<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_md33"></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_md34"></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_md35"></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_md36"></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_md37"></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_md38"></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 segment’s <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 32‑bit DMA words; each word packs <b>4× 8‑bit pixels</b>, so horizontal data must start on a 4‑pixel boundary.</li>
|
||
<li>Horizontal scrolling is limited to <b>4‑pixel steps</b>. Exceptions:<ul>
|
||
<li><b>Slow sprites</b> – software-rendered per scanline; can scroll at <b>1‑pixel</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_md39"></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_md40"></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="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>
|
||
</html>
|