<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Truly Integrated</title>
	<atom:link href="http://truly-integrated.net/feed/?language=pl" rel="self" type="application/rss+xml" />
	<link>http://truly-integrated.net</link>
	<description>electronics microcontrollers fpga vhdl</description>
	<lastBuildDate>Fri, 19 Feb 2010 21:22:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Płytki z GAMA sp. z o.o.</title>
		<link>http://truly-integrated.net/2010/02/plytki-z-gama-sp-z-o-o/</link>
		<comments>http://truly-integrated.net/2010/02/plytki-z-gama-sp-z-o-o/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 21:22:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=346</guid>
		<description><![CDATA[Podczas przeszukiwania Internetu natknąłem się na wiele bardzo negatywnych opinii nt. płytkarni GAMA sp. z o.o. znanej również jako drukowane.pl. Dwa tygodnie temu, skuszony niską ceną, zleciłem wykonanie płytek do mojej pracy magisterskiej.  Płytka zawierała elementy których realizacja wymagała często przekroczenia maksymalnych, oferowanych przez tę firmę, parametrów technicznych, jednak projekt został przyjęty bez zarzutu przez osobę [...]]]></description>
			<content:encoded><![CDATA[<p>Podczas przeszukiwania Internetu natknąłem się na wiele bardzo negatywnych opinii nt. płytkarni GAMA sp. z o.o. znanej również jako <a href="http://drukowane.pl">drukowane.pl</a>. Dwa tygodnie temu, skuszony niską ceną, zleciłem wykonanie płytek do mojej pracy magisterskiej.  Płytka zawierała elementy których realizacja wymagała często przekroczenia maksymalnych, oferowanych przez tę firmę, parametrów technicznych, jednak projekt został przyjęty bez zarzutu przez osobę weryfikującą zlecenia. Dziś odebrałem płytki, które przyszły do mnie za pośrednictwem Poczty Polskiej (która, co podpowiada praktyka, jest <em>spółką z nieograniczoną nieodpowiedzialnością</em>). Oto rezultaty:</p>
<p style="text-align: left;"><a href="http://truly-integrated.net/wp-content/uploads/2010/02/płytka3.jpg"><img class="aligncenter size-medium wp-image-349" title="płytka3" src="http://truly-integrated.net/wp-content/uploads/2010/02/płytka3-570x427.jpg" alt="" width="570" height="427" /></a><a href="http://truly-integrated.net/wp-content/uploads/2010/02/płytka2.jpg"><img class="aligncenter size-medium wp-image-348" title="płytka2" src="http://truly-integrated.net/wp-content/uploads/2010/02/płytka2-570x427.jpg" alt="" width="570" height="427" /></a></p>
<p>Płytka została wykonana poprawnie. Jedyne co można zarzucić to delikatne przesunięcie soldermaski (&lt;&lt; 1 mm). Warstwa opisu jest wykonana poprawnie, jak na produkcję prototypową. Litery opisu są niestety niezbyt wyraźne, co jest spowodowane najprawdopodobniej tym, że wybrałem zbyt <em>cienką</em> czcionkę podczas projektowania.  Należy jednak podkreślić, że za cenę 100 PLN (wraz z przesyłką) otrzymałem 4 płytki o wymiarach 70&#215;105mm, co jest ofertą nie do pobicia, przynajmniej na polskim rynku.  Firma GAMA nie jest, z całą pewnością najlepszą firmą, której możemy zlecić wykonanie obwodów drukowanych, lecz stosunek ceny do jakości, jaki oferuje, jest wg mnie bardzo dobry. Polecam ją każdemu, kto niema zbytnich wymagań co do procesu technologicznego i nie dysponuje zbyt wielkimi środkami finansowymi.</p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2010/02/plytki-z-gama-sp-z-o-o/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>USBasp Programator AVR</title>
		<link>http://truly-integrated.net/2009/12/usbasp/</link>
		<comments>http://truly-integrated.net/2009/12/usbasp/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 18:09:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Projekty]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=228</guid>
		<description><![CDATA[Tydzień temu sfinalizowałem pracę nad moim nowym projektem. Jest nim programator uC z rodziny AVR oparty na USBasp.  Programator ten współpracuje z wszystkimi normalnymi systemami operacyjnymi. Jego głównymi zaletami są:

nie wymaga LPT, gdyż korzysta z USB. Co raz trudniej o laptopa z wyprowadzonym portem LPT, tak więc jest to wyjście w stronę użytkowników z komputerami [...]]]></description>
			<content:encoded><![CDATA[<p>Tydzień temu sfinalizowałem pracę nad moim nowym projektem. Jest nim programator uC z rodziny AVR oparty na <a title="usbasp" href="http://www.fischl.de/usbasp/">USBasp</a>.  Programator ten współpracuje z wszystkimi <em>normalnymi</em> systemami operacyjnymi. Jego głównymi zaletami są:</p>
<ul>
<li>nie wymaga LPT, gdyż korzysta z USB. Co raz trudniej o laptopa z wyprowadzonym portem LPT, tak więc jest to wyjście w stronę użytkowników z komputerami przenośnymi.</li>
<li>umożliwia ZNACZNIE szybsze wgrywanie firmware niż programatory LPT.</li>
<li>jest mały (:</li>
</ul>
<p>Programator bezproblemowo współpracuje z popularnym oprogramowaniem<em> avrdude</em>. Na płytce umieszczono trzy zworki. Pierwsza z nich (piny 1-2) służy do wyboru prędkości programowania, zwarcie oznacza programowanie układów taktowanych zegarem &lt; 1.5 MHz. Zwora druga (piny 3-4) służy do umożliwienia zaprogramowania samego programatora, co jest przydatne, gdyż prace nad firmware ciągle trwają. Zwora (5-6) służy do zasilania układu docelowego z programatora. Należy pamiętać, że napięcie zasilające pobierane jest wprost z portu USB, a zatem obciążenie nie może być większe niż 0,5 A. Poniżej przedstawiam zdjęcia programatora.</p>
<p><a href="http://truly-integrated.net/wp-content/uploads/2009/12/usbasp3.jpg"><img class="alignleft size-thumbnail wp-image-233" title="usbasp3" src="http://truly-integrated.net/wp-content/uploads/2009/12/usbasp3-150x150.jpg" alt="" width="150" height="150" /></a><a href="http://truly-integrated.net/wp-content/uploads/2009/12/usbasp4.jpg"><img class="alignleft size-thumbnail wp-image-234" title="usbasp4" src="http://truly-integrated.net/wp-content/uploads/2009/12/usbasp4-150x150.jpg" alt="" width="150" height="150" /></a><a href="http://truly-integrated.net/wp-content/uploads/2009/12/usbasp5.jpg"><img class="alignleft size-thumbnail wp-image-235" title="usbasp5" src="http://truly-integrated.net/wp-content/uploads/2009/12/usbasp5-150x150.jpg" alt="" width="150" height="150" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/12/usbasp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generator sygnałów VGA w VHDL</title>
		<link>http://truly-integrated.net/2009/08/generator-sygnalow-vga-w-vhdl/</link>
		<comments>http://truly-integrated.net/2009/08/generator-sygnalow-vga-w-vhdl/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 11:01:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=189</guid>
		<description><![CDATA[W dzisiejszym wpisie zaprezentuję jak wykonać generator sygnałów VGA dla trybu 640&#215;480@60Hz. Jest to element umożliwiający wyświetlanie czegokolwiek na matrycy/kineskopie monitora, także, o ile zajmujemy się projektowaniem GPU, warto poświęcić mu trochę uwagi (:
Każdy monitor ze złączem w standardzie VGA wymaga podawania pięciu sygnałów:

R,G,B &#8211; składowe kolorów (&#8220;treść&#8221; obrazu)
v_sync &#8211; synchronizacja pionowa
h_sync &#8211; synchronizacja pozioma

Poszczególne [...]]]></description>
			<content:encoded><![CDATA[<p>W dzisiejszym wpisie zaprezentuję jak wykonać generator sygnałów VGA dla trybu 640&#215;480@60Hz. Jest to element umożliwiający wyświetlanie czegokolwiek na matrycy/kineskopie monitora, także, o ile zajmujemy się projektowaniem GPU, warto poświęcić mu trochę uwagi (:</p>
<p>Każdy monitor ze złączem w standardzie VGA wymaga podawania pięciu sygnałów:</p>
<ul>
<li><em>R,G,B</em> &#8211; składowe kolorów (&#8220;treść&#8221; obrazu)</li>
<li><em>v_sync</em> &#8211; synchronizacja pionowa</li>
<li><em>h_sync</em> &#8211; synchronizacja pozioma</li>
</ul>
<p>Poszczególne sygnały muszą spełniać pewne normy czasowe, które zostały opisane (również dla innych rozdzielczości) na <a href="http://www.epanorama.net/documents/pc/vga_timing.html">tej stronie</a>. Obraz jest wyświetlany z częstotliwością 25MHz (jest to wartość przybliżona, rzeczywista jest nieco większa, ale nie ma to znaczenia) na pojedynczy piksel, przy czym należy zauważyć, iż całkowity obraz ma wymiary 800&#215;525px, z czego obszar aktywny zajmuje oczywiście 640&#215;480px. Czas spędzony w pozostałym obszarze jest używany do cofania plamki do pozycji początkowej oraz przechodzenia do nowej linii. Jest to &#8220;pamiątka&#8221; po erze monitorów CRT które wyświetlały obraz z użyciem działa elektronowego, o czym więcej <a href="http://en.wikipedia.org/wiki/Cathode_ray_tube">tutaj</a>.</p>
<p>Wyróżniamy cztery podstawowe etapy synchronizacji poziomej:</p>
<ol>
<li>640 px &#8211; obszar aktywny (Horizontal Display, HD)</li>
<li>16 px &#8211; obszar wygaszania plamki i &#8220;przygotowania do powrotu&#8221; (Horizontal Front Porch, HF)</li>
<li>96 px &#8211; obszar powrotu plamki (Horizontal Return, HR)</li>
<li>48 px &#8211; obszar zapalania plamki i &#8220;przygotowania do rysowania&#8221; (Horizontal Back Porch, HB)</li>
</ol>
<p>Sumarycznie etapy te trwają 800px. Sygnał synchronizacji poziomej powiniem mieć wartość &#8216;0&#8242; podczas trwania etapu nr 3 oraz wartość &#8216;1&#8242; we wszystkich pozostałych.</p>
<p>Analogicznie, dla sychrnonizacji pionowej, mamy:</p>
<ol>
<li>480 li &#8211; obszar aktywny (Vertical Display, VD)</li>
<li>10 li &#8211; (Vertical Front Porch, VF)</li>
<li>33 li &#8211; (Vertical Back Porch, VB)</li>
<li>2 li &#8211; powrót plamki (Vertical Return, VR)</li>
</ol>
<p>Sumarycznie 525 linii. Sygnał synchronizacji pionowej powinien mieć wartość &#8216;0&#8242; podczas etapu nr 3, w pozostałych wypadkach powinien mieć wartość &#8216;1&#8242;. Posileni takim ładunkiem teorii możnemy przystąpić do wcielania naszego generatora w życie.</p>
<p>Pierwszym krokiem jest dobór sygnałów wejściowych i wyjściowych naszego generatora. Ja rozpisałem je następująco:</p>
<div class="codesnip-container" >
<div class="vhdl codesnip" style="font-family:monospace;"><span class="kw1">entity</span> vga_640_gen <span class="kw1">is</span><br />
<span class="kw1">port</span> <span class="br0">&#40;</span> &nbsp;<span class="co1">&#8211; common signals</span><br />
clk, rst <span class="sy0">:</span> <span class="kw1">in</span> <span class="kw2">std_logic</span><span class="sy0">;</span><br />
<span class="co1">&#8211; vga signals</span><br />
pix_x, pix_y <span class="sy0">:</span> <span class="kw1">out</span> <span class="kw2">std_logic_vector</span><span class="br0">&#40;</span>9 <span class="kw1">downto</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
hs, vs, blank, pix_clk <span class="sy0">:</span> <span class="kw1">out</span> <span class="kw2">std_logic</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">end</span> vga_640_gen<span class="sy0">;</span></div>
</div>
<p>Sygnały clk, i rst to nic innego jak wejście zegara, który na płycie Nexys 2 ma częstotliwość 50MHz, tak więc po podzieleniu na 2 idealnie nadaje się na zegar pikseli 25MHz oraz sygnał resetu całego generatora. 10-bitowe sygnały pix_x oraz pix_y zawierają informację odnośnie aktualnie wyświetlanego piksela. Linie hs i vs to linie synchronizacji odpowiednio: poziomej i pionowej. Sygnał blank informuje nas o tym czy generator znajduje się w obszarze aktywnym czy też nie, zaś pix_clk to wyjście zegara pikseli 25Mhz.</p>
<p>Przystępujemy do implementacji architektury generatora:</p>
<div class="codesnip-container" >
<div class="vhdl codesnip" style="font-family:monospace;"><span class="kw1">architecture</span> Behavioral <span class="kw1">of</span> vga_640_gen <span class="kw1">is</span></p>
<p><span class="co1">&#8211; signals for pixel clock generation</span><br />
<span class="kw1">signal</span> pix_clk_reg, pix_clk_next <span class="sy0">:</span> <span class="kw2">std_logic</span><span class="sy0">;</span></p>
<p><span class="kw1">signal</span> blank_reg, blank_next <span class="sy0">:</span> <span class="kw2">std_logic</span><span class="sy0">;</span></p>
<p><span class="co1">&#8211; internal signals</span><br />
<span class="kw1">signal</span> h_tick, v_tick <span class="sy0">:</span> <span class="kw2">std_logic</span><span class="sy0">;</span><br />
<span class="kw1">signal</span> h_sync_reg, h_sync_next <span class="sy0">:</span> <span class="kw2">std_logic</span><span class="sy0">;</span><br />
<span class="kw1">signal</span> v_sync_reg, v_sync_next <span class="sy0">:</span> <span class="kw2">std_logic</span><span class="sy0">;</span></p>
<p><span class="co1">&#8211; counters for horizontal and vertical sync</span><br />
<span class="kw1">signal</span> v_count_reg, v_count_next <span class="sy0">:</span> <span class="kw2">std_logic_vector</span><span class="br0">&#40;</span>9 <span class="kw1">downto</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">signal</span> h_count_reg, h_count_next <span class="sy0">:</span> <span class="kw2">std_logic_vector</span><span class="br0">&#40;</span>9 <span class="kw1">downto</span> 0<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="co1">&#8211; horizontal and vertical syncs generating constants</span><br />
<span class="kw1">constant</span> HD <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">640</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> HF <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">16</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> HB <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">48</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> HR <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">96</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> VD <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">480</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> VF <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">10</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> VB <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">33</span><span class="sy0">;</span><br />
<span class="kw1">constant</span> VR <span class="sy0">:</span> <span class="kw2">integer</span> <span class="sy0">:=</span> <span class="nu0">2</span><span class="sy0">;</span></p>
<p><span class="kw1">begin</span></p>
<p><span class="co1">&#8211; update process</span><br />
update <span class="sy0">:</span> <span class="kw1">process</span> <span class="br0">&#40;</span>clk, rst<span class="br0">&#41;</span><br />
<span class="kw1">begin</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>rst <span class="sy0">=</span> &#8216;1&#8242;<span class="br0">&#41;</span> <span class="kw1">then</span><br />
h_count_reg &amp;lt<span class="sy0">;=</span> <span class="br0">&#40;</span><span class="kw1">others</span> <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> &#8216;0&#8242;<span class="br0">&#41;</span><span class="sy0">;</span><br />
v_count_reg &amp;lt<span class="sy0">;=</span> <span class="br0">&#40;</span><span class="kw1">others</span> <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> &#8216;0&#8242;<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>pix_clk_reg &amp;lt<span class="sy0">;=</span> &#8216;0&#8242;<span class="sy0">;</span><br />
h_sync_reg &amp;lt<span class="sy0">;=</span> &#8216;0&#8242;<span class="sy0">;</span><br />
v_sync_reg &amp;lt<span class="sy0">;=</span> &#8216;0&#8242;<span class="sy0">;</span></p>
<p>blank_reg &amp;lt<span class="sy0">;=</span> &#8216;0&#8242;<span class="sy0">;</span><br />
<span class="kw1">elsif</span> <span class="kw1">rising_edge</span><span class="br0">&#40;</span>clk<span class="br0">&#41;</span> <span class="kw1">then</span><br />
pix_clk_reg &amp;lt<span class="sy0">;=</span> pix_clk_next<span class="sy0">;</span></p>
<p>h_count_reg &amp;lt<span class="sy0">;=</span> h_count_next<span class="sy0">;</span><br />
v_count_reg &amp;lt<span class="sy0">;=</span> v_count_next<span class="sy0">;</span></p>
<p>h_sync_reg &amp;lt<span class="sy0">;=</span> h_sync_next<span class="sy0">;</span><br />
v_sync_reg &amp;lt<span class="sy0">;=</span> v_sync_next<span class="sy0">;</span></p>
<p>blank_reg &amp;lt<span class="sy0">;=</span> blank_next<span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">if</span><span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">process</span> update<span class="sy0">;</span></p>
<p><span class="co1">&#8211; clock generation</span><br />
pix_clk_next &amp;lt<span class="sy0">;=</span> <span class="kw1">not</span> pix_clk_reg<span class="sy0">;</span></p>
<p><span class="co1">&#8211; blank generation</span><br />
blank_next &amp;lt<span class="sy0">;=</span> &#8216;0&#8242; <span class="kw1">when</span> <span class="br0">&#40;</span>h_count_reg &amp;lt<span class="sy0">;</span> HD<span class="br0">&#41;</span> <span class="kw1">and</span> <span class="br0">&#40;</span>v_count_reg &amp;lt<span class="sy0">;</span> VD<span class="br0">&#41;</span> <span class="kw1">else</span> &#8216;1&#8242;<span class="sy0">;</span></p>
<p><span class="co1">&#8211; horizontal and vertical tick signal generation</span><br />
h_tick &amp;lt<span class="sy0">;=</span> &#8216;1&#8242; <span class="kw1">when</span> h_count_reg <span class="sy0">=</span> <span class="br0">&#40;</span>HD+HF+HB+HR-1<span class="br0">&#41;</span> <span class="kw1">else</span> &#8216;0&#8242;<span class="sy0">;</span><br />
v_tick &amp;lt<span class="sy0">;=</span> &#8216;1&#8242; <span class="kw1">when</span> v_count_reg <span class="sy0">=</span> <span class="br0">&#40;</span>VD+VF+VB+VR-1<span class="br0">&#41;</span> <span class="kw1">else</span> &#8216;0&#8242;<span class="sy0">;</span></p>
<p><span class="co1">&#8211; sync signals generation</span><br />
h_sync_next &amp;lt<span class="sy0">;=</span> &#8216;1&#8242; <span class="kw1">when</span> <span class="br0">&#40;</span>h_count_reg &amp;gt<span class="sy0">;=</span> <span class="br0">&#40;</span>HD+HF<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">and</span><br />
<span class="br0">&#40;</span>h_count_reg &amp;lt<span class="sy0">;=</span> <span class="br0">&#40;</span>HD+HF+HR-1<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">else</span> &#8216;0&#8242;<span class="sy0">;</span><br />
v_sync_next &amp;lt<span class="sy0">;=</span> &#8216;1&#8242; <span class="kw1">when</span> <span class="br0">&#40;</span>v_count_reg &amp;gt<span class="sy0">;=</span> <span class="br0">&#40;</span>VD+VF<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">and</span><br />
<span class="br0">&#40;</span>v_count_reg &amp;lt<span class="sy0">;=</span> <span class="br0">&#40;</span>VD+VF+VR-1<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">else</span> &#8216;0&#8242;<span class="sy0">;</span></p>
<p><span class="co1">&#8211; horizontal counter process</span><br />
h_counter <span class="sy0">:</span> <span class="kw1">process</span> <span class="br0">&#40;</span>pix_clk_reg, h_tick, h_count_reg<span class="br0">&#41;</span><br />
<span class="kw1">begin</span><br />
<span class="kw1">if</span> pix_clk_reg <span class="sy0">=</span> &#8216;1&#8242; <span class="kw1">then</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>h_tick <span class="sy0">=</span> &#8216;1&#8242;<span class="br0">&#41;</span> <span class="kw1">then</span><br />
h_count_next &amp;lt<span class="sy0">;=</span> <span class="br0">&#40;</span><span class="kw1">others</span> <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> &#8216;0&#8242;<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">else</span><br />
h_count_next &amp;lt<span class="sy0">;=</span> h_count_reg + <span class="nu0">1</span><span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">if</span><span class="sy0">;</span><br />
<span class="kw1">else</span><br />
h_count_next &amp;lt<span class="sy0">;=</span> h_count_reg<span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">if</span><span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">process</span> h_counter<span class="sy0">;</span></p>
<p><span class="co1">&#8211; vertical counter process</span><br />
v_counter <span class="sy0">:</span> <span class="kw1">process</span> <span class="br0">&#40;</span>pix_clk_reg, h_tick, v_tick, v_count_reg<span class="br0">&#41;</span><br />
<span class="kw1">begin</span><br />
<span class="kw1">if</span> pix_clk_reg <span class="sy0">=</span> &#8216;1&#8242; <span class="kw1">and</span> h_tick <span class="sy0">=</span> &#8216;1&#8242; <span class="kw1">then</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>v_tick <span class="sy0">=</span> &#8216;1&#8242;<span class="br0">&#41;</span> <span class="kw1">then</span><br />
v_count_next &amp;lt<span class="sy0">;=</span> <span class="br0">&#40;</span><span class="kw1">others</span> <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> &#8216;0&#8242;<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">else</span><br />
v_count_next &amp;lt<span class="sy0">;=</span> v_count_reg + <span class="nu0">1</span><span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">if</span><span class="sy0">;</span><br />
<span class="kw1">else</span><br />
v_count_next &amp;lt<span class="sy0">;=</span> v_count_reg<span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">if</span><span class="sy0">;</span><br />
<span class="kw1">end</span> <span class="kw1">process</span> v_counter<span class="sy0">;</span></p>
<p><span class="co1">&#8211; pixel clock signal</span><br />
pix_clk &amp;lt<span class="sy0">;=</span> pix_clk_reg<span class="sy0">;</span></p>
<p><span class="co1">&#8211; blank signal</span><br />
blank &amp;lt<span class="sy0">;=</span> blank_reg<span class="sy0">;</span></p>
<p><span class="co1">&#8211; generate horizontal sync signal</span><br />
hs &amp;lt<span class="sy0">;=</span> h_sync_reg<span class="sy0">;</span><br />
<span class="co1">&#8211; generate vertical sync signal</span><br />
vs &amp;lt<span class="sy0">;=</span> v_sync_reg<span class="sy0">;</span></p>
<p><span class="co1">&#8211; output pixel counter signals</span><br />
pix_x &amp;lt<span class="sy0">;=</span> h_count_reg<span class="sy0">;</span><br />
pix_y &amp;lt<span class="sy0">;=</span> v_count_reg<span class="sy0">;</span></p>
<p><span class="kw1">end</span> Behavioral<span class="sy0">;</span></div>
</div>
<p>Proces <em>update</em> odpowiada za przypisywanie nowych wartości do wszystkich rejestrów, jakie zostały użyte w implementacji. Dzięki temu mamy pełną synchronizację wewnątrz bloku generatora VGA i możliwość pracy całego FPGA z wysoką częstotliwością taktowania. Zegar jest uzyskany poprzez negowanie &#8220;samego siebie&#8221; (linia 56) z częstotliwością zegara, co w rezultacie owocuje przebiegiem o częstotliwości 25Mhz. Proces <em>h_count</em> odpowiada za aktualizację wartości licznika synchronizacji poziomej, dla wartości mniejszych niż 800 następuje zwiększenie wartości licznika o 1, dla wartości 800 następuje wyzerowanie licznika. Podobnie funkcjonuje proces <em>v_count</em> tyle że on jest synchronizowany przejściem do nowej linii. Sygnał blank ma wartość &#8216;0&#8242; gdy aktualnie wyświetlany piksel należy do obszaru aktywnego (linia 59). Sygnały <em>hs</em> i <em>vs</em> są generowane zgodnie z &#8220;przepisem&#8221; podanym wcześniej (linie 66 i 68).</p>
<p><strong>Test generatora</strong></p>
<p>Aby przetestować generator należałoby spróbować wyświetlić jakikolwiek obraz na monitorze. Najprostszym sposobem jest wygenerowanie tzw. <em>xor pattern</em>, tzn takiego obrazu, gdzie kolor każdego piksela ma wartość obliczoną jako <em>xor</em> jego współrzędnej x oraz y. Przykładowy plik testowy wygląda więc następująco:</p>
<div class="codesnip-container" >
<div class="vhdl codesnip" style="font-family:monospace;"><span class="kw1">library</span> <span class="kw2">IEEE</span><span class="sy0">;</span><br />
<span class="kw1">use</span> <span class="kw2">IEEE</span>.<span class="kw2">STD_LOGIC_1164</span>.<span class="kw1">ALL</span><span class="sy0">;</span><br />
<span class="kw1">use</span> <span class="kw2">IEEE</span>.<span class="kw2">STD_LOGIC_ARITH</span>.<span class="kw1">ALL</span><span class="sy0">;</span><br />
<span class="kw1">use</span> <span class="kw2">IEEE</span>.STD_LOGIC_UNSIGNED.<span class="kw1">ALL</span><span class="sy0">;</span><br />
<span class="kw1">entity</span> test <span class="kw1">is</span><br />
<span class="kw1">port</span><span class="br0">&#40;</span> clk <span class="sy0">:</span> <span class="kw1">in</span> <span class="kw2">std_logic</span><span class="sy0">;</span></p>
<p>vga_hs, vga_vs <span class="sy0">:</span> <span class="kw1">out</span> <span class="kw2">std_logic</span><span class="sy0">;</span><br />
vga_rgb <span class="sy0">:</span> <span class="kw1">out</span> <span class="kw2">std_logic_vector</span><span class="br0">&#40;</span>7 <span class="kw1">downto</span> 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">end</span> test<span class="sy0">;</span></p>
<p><span class="kw1">architecture</span> Behavioral <span class="kw1">of</span> test <span class="kw1">is</span><br />
<span class="kw1">signal</span> pix_x, pix_y <span class="sy0">:</span> <span class="kw2">std_logic_vector</span><span class="br0">&#40;</span>9 <span class="kw1">downto</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">signal</span> blank <span class="sy0">:</span> <span class="kw2">std_logic</span><span class="sy0">;</span><br />
<span class="kw1">begin</span></p>
<p>vga_gen <span class="sy0">:</span> <span class="kw1">entity</span> vga_640_gen<br />
<span class="kw1">port</span> <span class="kw1">map</span><span class="br0">&#40;</span>clk <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> clk, rst <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> ‘0′,<br />
pix_x <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> pix_x, pix_y <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> pix_y,<br />
hs <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> vga_hs, vs <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> vga_vs, blank <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> blank, pix_clk <span class="sy0">=</span>&amp;gt<span class="sy0">;</span> <span class="kw1">open</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>vga_rgb &amp;lt<span class="sy0">;=</span> pix_x<span class="br0">&#40;</span>7 <span class="kw1">downto</span> 0<span class="br0">&#41;</span> <span class="kw1">xor</span> pix_y<span class="br0">&#40;</span>7 <span class="kw1">downto</span> 0<span class="br0">&#41;</span> <span class="kw1">when</span> blank <span class="sy0">=</span> ‘0′ <span class="kw1">else</span> x<span class="st0">&quot;00&quot;</span><span class="sy0">;</span></p>
<p><span class="kw1">end</span> Behavioral<span class="sy0">;</span></div>
</div>
<p>Warto zauważyć, że sygnały wyjściowe <em>vga_rgb</em> powinny mieć wartość zera logicznego w momencie, gdy plamka znajduje się poza aktywnym obszarem wyświetlania (w tym celu z generatora wyprowadzono sygnał <em>blank</em>). Jeśli tego nie zrobimy, to niektóre monitory zaczynają wariować, obraz jest przesunięty i słychać syczenie i gwizdy (:. Kod wgrany do FPGA, znajdującego się na płytce Nexys 2, daje takie oto efekty:</p>
<p><a href="http://truly-integrated.net/wp-content/uploads/2009/08/monitor.jpg"><img class="aligncenter size-medium wp-image-205" title="monitor" src="http://truly-integrated.net/wp-content/uploads/2009/08/monitor-468x570.jpg" alt="monitor" width="468" height="570" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/08/generator-sygnalow-vga-w-vhdl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FPGA Nexys 2 Board</title>
		<link>http://truly-integrated.net/2009/08/fpga-nexys-2-board/</link>
		<comments>http://truly-integrated.net/2009/08/fpga-nexys-2-board/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 10:46:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/archives/154</guid>
		<description><![CDATA[Nie dawniej niż miesiąc temu w moje ręce wpadła płyta ewaluacyjna Nexys 2 z układem FPGA typu Spartan XC3S500E. Płytę tę otrzymałem w celu realizacji części praktycznej mojej pracy magisterskiej, której tematem jest zaprojektowanie rdzenia procesora graficznego z akceleracją 2D. Płytka zawiera:

FPGA: XC3s500E,
RAM: 128Mb (8M x 16b) Micron Pseudo-Static RAM,
FLASH: 128 Mb Intel StrataFlash,
złącze RS232,
złącze [...]]]></description>
			<content:encoded><![CDATA[<p>Nie dawniej niż miesiąc temu w moje ręce wpadła płyta ewaluacyjna <a title="Nexys 2" href="http://www.digilentinc.com/Products/Detail.cfm?Prod=NEXYS2">Nexys 2</a> z układem FPGA typu <a title="Spartan 3E" href="www.xilinx.com/support/documentation/data_sheets/ds312.pdf">Spartan XC3S500E</a>. Płytę tę otrzymałem w celu realizacji części praktycznej mojej pracy magisterskiej, której tematem jest zaprojektowanie rdzenia procesora graficznego z akceleracją 2D. Płytka zawiera:</p>
<ul>
<li>FPGA: XC3s500E,</li>
<li>RAM: 128Mb (8M x 16b) Micron Pseudo-Static RAM,</li>
<li>FLASH: 128 Mb Intel StrataFlash,</li>
<li>złącze RS232,</li>
<li>złącze VGA z przetwornikiem DAC 8bit,</li>
<li>4 przyciski, 8 przełączników,</li>
<li>8 diód led, 4 wyświetlacze 7-segmentowe,</li>
<li>złącze rozszerzeń.</li>
</ul>
<p>Wszystko byłoby wspaniale, gdyby nie fakt że w roli pamięci zastosowano Pseudo Static RAM, a nie po prostu konwencjonalny Static RAM z jakimś sensownym czasem dostępu na poziomie 15 ns. Użyta kość odpowiada na rządania odczytu/zapisu dopiero po ok 70-80 ns, co jest wysoce niezadowalające w momencie, gdy chcemy wykorzystać ową pamięć jako bufor na dane graficzne&#8230; Pewnikiem będę musiał wykonać swoją płytkę zawierającą FPGA z pamięcią nieulotną (oznaczenia tych układów Xilinxa, które posiadają wbudowaną pamięć nieulotną kończą się na &#8220;AN&#8221;) oraz szybki statyczny RAM (kości 1Mbit są dostępne np. w <a href="tme.pl">tme.pl</a>).</p>
<p style="text-align: justify;">Niebawem zamieszczę informację o postępach moich prac nad GPU. Póki co ograniczę się do stwierdzenia, iż posiadam zaprojektowany RAMDAC, układ rysowania wypełnionych prostokątów, arbitera wewnętrznej magistrali, bank rejestrów konfiguracyjnych GPU oraz kilka innych przydatnych bajerów. Całość testuję  z użyciem złącza VGA dostępnego na płycie. Poniżej zamieszczam zdjęcie całości.</p>
<p style="text-align: justify;"><a href="http://truly-integrated.net/wp-content/uploads/2009/08/nexys2.jpg"></a></p>
<p style="text-align: justify;"><a href="http://truly-integrated.net/wp-content/uploads/2009/08/nexys2.jpg"><img class="aligncenter size-medium wp-image-175" title="nexys2" src="http://truly-integrated.net/wp-content/uploads/2009/08/nexys2-570x538.jpg" alt="nexys2" width="570" height="538" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/08/fpga-nexys-2-board/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPS Tracker</title>
		<link>http://truly-integrated.net/2009/07/gps-tracker/</link>
		<comments>http://truly-integrated.net/2009/07/gps-tracker/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 08:47:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[Projekty]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=119</guid>
		<description><![CDATA[Niedawno zakończyłem prace nad urządzeniem, które nazwałem GPS Tracker. Urządzenie to służy do raportowania pozycji samochodów ciężarowych lub osobowych, z wykorzystaniem pozycji z GPS, przesyłanej przez sieć GSM. Wykonanie zostało zlecone przez indywidualnego klienta.
Urządzenie wykorzystuje moduł SIM300D do wysyłania danych przez GPRS. Sam moduł jest rozwiązaniem dedykowanym zarówno do transmisji danych z wykorzystaniem wspomnianego GPRS [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Niedawno zakończyłem prace nad urządzeniem, które nazwałem GPS Tracker. Urządzenie to służy do raportowania pozycji samochodów ciężarowych lub osobowych, z wykorzystaniem pozycji z GPS, przesyłanej przez sieć GSM. Wykonanie zostało zlecone przez indywidualnego klienta.</p>
<p style="text-align: justify;">Urządzenie wykorzystuje moduł <a href="www.fleximatrix.fr/docs/sim300D_HD_V2.01.pdf">SIM300D</a> do wysyłania danych przez GPRS. Sam moduł jest rozwiązaniem dedykowanym zarówno do transmisji danych z wykorzystaniem wspomnianego GPRS jak również do transmisji głosu. Komunikacja z modułem odbywa się przy wykorzystaniu RS232 w pełnej 9-sygnałowej wersji. Umożliwia to sprawowanie kontroli nad szybkością transmisji. Do modułu podłączono złącze karty SIM z wyrzutnikiem. Antena jest przyłączona za pomocą gniazda SMA. Moduł został zakupiony w <a href="http://www.tme.pl">TME</a>.</p>
<p style="text-align: justify;">W roli uC zastosowałem AT91SAM7S64, gdyż takowy zalegał u mnie w warsztacie. Firmware został napisany z wykorzystaniem przerwań i timerów (i innych fajnych rzeczy..), tak aby uniknąć stosowania wielu procedur blokujących. Taka metoda pisana firmware w ostateczności przyczynia się do zmniejszenia awaryjności całego urządzenia, co jest szczególnie istotne w przypadku urządzenia do którego dostęp będzie później utrudniony.</p>
<p style="text-align: justify;">Wykorzystany moduł GPS to FGPMMOSL1 zakupiony z <a href="http://www.maritex.com.pl/pl/shop/products/ggid/10521">Maritexu</a>. Wybór został podyktowany tylko i wyłącznie ceną (: jednak zapewniam, iż moduł spisuje się bardzo dobrze, wraz z aktywną anteną można obierać sygnał z satelity w kamienicy (5m od okna), w której mieszkam. Moduł jest gotowy do pracy po ok. 30 sekundach od włączenia zasilania. Prędkość transmisji wynosi 9800 baud, jest więc dwukrotnie większa od standardowej prędkości protokołu <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA</a>. Z racji tego, że zastosowany AT91SAM7 dysponuje tylko dwoma USARTami, z czego jeden (USART1) jest podłączony do modułu GSM to linia TXD została wykorzystana do wysyłania komunikatów debugujących podczas gdy RXD jest podłączona do GPS. Takie współdzielenie linii jednego USART powoduje to, że debug pracuje z taką samą prędkością co GPS, zatem większa prędkość GPS oznacza w ostateczności przyspieszenie transmisji debugu.</p>
<p style="text-align: justify;">Urządzenie zostało również wyposażone w złącze USB, które umożliwia konfigurację parametrów pracy całości. Firmware zapewnia obsługę urządzenia klasy CDC będącego, tym przypadku, zwykłym portem szeregowym. Warto zaznaczyć, że nie posiłkowałem się biblioteką <a href="http://www.atmel.com">Atmela</a> dla USB, lecz klasę CDC napisałem całkowicie samodzielnie. (Nie jest to jedyna rzecz jaką implementowałem samodzielnie, nawet <em>printf</em> do debugu jest mój, co prawda nieco zubożony, ale taki właśnie miał być (: ).</p>
<p style="text-align: justify;">Krótka specyfikacja:</p>
<ul>
<li>Wymiary płytki: 64&#215;50 [mm]</li>
<li>Wysokość najwyższego elementu: 12 [mm]</li>
<li>Średni pobór prądu: ~40 [mA]</li>
<li>Napięcie zasilania: od 5 do 35 [V]</li>
<li>Złącza: USB, Zasilanie, 2x SMA (GPS, GSM), JTAG (przystosowany do pracy z moim programatorkiem).</li>
<li>3 Diody sygnalizacyjne (NET &#8211; GPRS, PWR  &#8211; Zasilanie, STAT &#8211; Status pracy)</li>
</ul>
<h4 style="text-align: justify;">Podstawowe problemy techniki</h4>
<p>Najważniejszym elementem każdego urządzenia elektronicznego jest zasilacz, gdyż jak wiadomo 90% urządzeń działa lepiej gdy są poprawnie zasilone (:. Należy mieć na uwadze fakt, że podczas nadawania komunikatu przez moduł GSM pobór prądu może w szczycie osiągnąć 2A, dlatego konstrukcja zasilacza musi być dokładnie przemyślana. Ponadto należy uwzględnić to, że napięcie w instalacji ciężarówki wynosi 24V, zaś w samochodach osobowych występuje 12V. Wybór padł na układ LM2594 będący przetwornicą step-down. Wykorzystano wersję nieregulowaną, o napięciu wyjściowym wynoszącym 5V. Wykorzystanie wersji 3,3V nie wchodziło w grę, gdyż moduł SIM300D do poprawnej pracy wymaga przynajmniej 3,6V. Napięcie z przetwornicy jest obniżane do poziomu ok 3,8-3,9V za pomocą układu LM1117-3,3V, którego wyprowadzenie GND jest dołączone do masy urządzenia za pośrednictwem diody krzemowej. Aby umożliwić chwilowe pobranie dużych prądów urządzenie zostało wyposażone w baterię kondensatorów tantalowych 330uF. Na płytce przewidziano miejsce dla trzech takich kondensatorów, jednak empirycznie stwierdziłem, że dwa w zupełności wystarczą i moduł nie uskarża się na <em>&#8216;under voltage operation&#8217;</em>. Warto zwrócić uwagę na to czy scalak przetwornicy pracuje ze stałą czy zmienną częstotliwością kluczowania dławika. W przypadku zmiennej częstotliwości może (w momencie dużych obciążeń) dochodzić do efektów dzwiękowych w dławiku (:. Wybrany układ pracuje z częstotliwością stałą, wynoszącą 150kHz, tak więc zdecydowanie ponad pasmem akustycznym.</p>
<p>Bardzo ważnym aspektem jest zapewnienie odpowiedniej grubości ścieżek doprowadzających napięcie do modułu GSM. W przypadku za wąskich ścieżek i dużych poborów prądu następują niepożądane spadki napięć.</p>
<h4>Jakie są potencjalne trudności podczas realizacji takiego projektu?</h4>
<p>Pierwszą trudnością jest poprawna implementacja procedur obsługujących błędy pracy modułu GSM. Jeżeli urządzenie wisi w momencie gdy padł zasięg, to znaczy dokładnie tyle, że programista nie zadbał o jakość firmware. Braki zasięgu się zdarzają, szczególnie w sieci Orange.</p>
<p>Następnym problemem są &#8216;ginące&#8217; pakiety w sieci GPRS. Należy zadbać o mechanizm potwierdzeń dostarczenia pakietów z danymi. Można wykorzystać protokół TCP zamiast UDP, ale nastręcza to dodatkowych problemów w momencie utraty zasięgu (trzeba na nowo ustanawiać połączenie socketów, a na serwerze socket cały czas zostaje otwarty) Na dobrą sprawę wystarczy UDP z prostym komunikatem potwierdzającym ze strony serwera.</p>
<p>Należy buforować dane, czasem utrata zasięgu może potrwać kilka minut, nie można dopuścić by dane nam wyparowały! w momencie <em>powrotu</em> zasięgu należy wysłać zgromadzoną paczkę danych. Serwer musi obsługiwać komunikaty zawierające informacje o kilku lokalizacjach. Komplikuje to protokół, ale tylko nieznacznie.</p>
<p>W przypadku utraty sygnału GPS, należy to sygnalizować do serwera jakimś prostym komunikatem (po co tracić pieniądze na nadmiarową ilość przesyłanych danych). Co nam daje taka informacja? Serwer <em>wie</em>, że urządzenie żyje, a problemy są przejściowe. Ponadto może wyświetlić komunikat o problemach z GPS.</p>
<p>Należy zaimplementować obsługę PIN. Kierowcy mają ciągoty do korzystania z kart SIM, znajdujących się w urządzeniu do wykonywania prywatnych rozmów (:.</p>
<p>Zaprojektowane urządzenie współpracuje aktualnie z aplikacją wykorzystującą Google Maps. Jest to najprostsza i dość niedoskonała metoda wizualizacji zgromadzonych informacji (niedokładność map). Warto zatem zastanowić się nad zakupem innych mapek.</p>
<h4>Pytania? Wątpliwości?</h4>
<p>To tyle ode mnie, jeśli ktokolwiek z Czytelników jest zainteresowany projektem to proszę o kontakt mailowy. Możliwe jest wykonanie większej liczby urządzeń, na specjalne zamówienie. Na zakończenie zamieszczam zdjęcie strony wierzchniej (GSM i GPS są przylutowane od spodu):</p>
<p><a href="http://truly-integrated.net/wp-content/uploads/2009/07/1.jpg"><img class="size-thumbnail wp-image-150 alignleft" title="gpsgsm_1" src="http://truly-integrated.net/wp-content/uploads/2009/07/1-150x150.jpg" alt="gpsgsm_1" width="150" height="150" /></a><a href="http://truly-integrated.net/wp-content/uploads/2009/07/2.jpg"><img class="alignleft size-thumbnail wp-image-151" title="gpsgsm_2" src="http://truly-integrated.net/wp-content/uploads/2009/07/2-150x150.jpg" alt="gpsgsm_2" width="150" height="150" /></a></p>
<p style="text-align: justify;">
<p style="text-align: justify;">
<p style="text-align: justify;">
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/07/gps-tracker/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GCC i funkcje o zmiennej liczbie argumentów</title>
		<link>http://truly-integrated.net/2009/07/gcc-i-funkcje-o-zmiennej-liczbie-argumentow/</link>
		<comments>http://truly-integrated.net/2009/07/gcc-i-funkcje-o-zmiennej-liczbie-argumentow/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 22:52:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[SW]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=91</guid>
		<description><![CDATA[Niniejszy wpis jest poświęcony zagadnieniu wykorzystania funkcji o zmiennej liczbie argumentów w swoich projektach. Najpopularniejszym przykładem funkcji posiadającą taką właściwość jest funkcja printf, której prototyp wygląda mniej-więcej tak:
int printf(char *fmt, ...);
Notacja &#8216;&#8230;&#8217; w polu argumentów funkcji informuje kompilator o tym, iż funkcja może przybierać dowolną liczbę argumentów. Powstaje podstawowe pytanie:  w jaki sposób takie argumenty [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Niniejszy wpis jest poświęcony zagadnieniu wykorzystania funkcji o zmiennej liczbie argumentów w swoich projektach. Najpopularniejszym przykładem funkcji posiadającą taką właściwość jest funkcja <em>printf, </em>której prototyp wygląda mniej-więcej tak:</p>
<pre>int printf(char *fmt, ...);</pre>
<p style="text-align: justify;">Notacja <em>&#8216;&#8230;&#8217;</em> w polu argumentów funkcji informuje kompilator o tym, iż funkcja może przybierać dowolną liczbę argumentów. Powstaje podstawowe pytanie:  w jaki sposób takie argumenty są przekazywane do funkcji skoro ich liczba nie jest wprost określona? Jak się do nich odwoływać?</p>
<p style="text-align: justify;">Twórcy kompilatora GCC rozwiązali sprawę przekazując takie parametry w formie obszaru pamięci zorganizowanego w specyficzny sposób. Na potrzeby rozważań ustalmy, iż funkcja, którą będziemy badać  będzie posiadała następujący prototyp:</p>
<pre>void foo(char *arg, ...);</pre>
<p>Jeżeli kolejne argumenty funkcji oznaczymy przez <em>arg0 &#8230; arg n</em> to zostaną one umieszczone w pamięci w sposób przedstawiony na poniższym rysunku:<img class="aligncenter size-full wp-image-107" title="gcc_va_args" src="http://truly-integrated.net/wp-content/uploads/2009/07/gcc_va_args.png" alt="gcc_va_args" width="318" height="272" /></p>
<p style="text-align: center;">
<p style="text-align: justify;">Wyjaśnienia wymaga zapis <em>a_sizeof(x). </em>Jest to makro zwracające rozmiar zmiennej (w bajtach) będącej jego argumentem w postaci &#8216;wyrównanej&#8217; do architektury dla której kompilujemy oprogramowanie. Przykładowo, jeśli architektura jest 32 bitowa to wartość dla zmiennej 1-bajtowej wynosi 4, a dla zmiennej 5-bajtowej wynosi 8. Powyższy rysunek mówi nam, iż każdy kolejny argument jest umieszczony po poprzednim w odległości równej <em>a_sizeof(x)</em>, gdzie <em>x</em> to argument poprzedni.</p>
<p style="text-align: justify;">Skoro wiemy już jak zmienne są rozmieszczone w pamięci to możemy zdefiniować sobie makra do poruszania się po nich i odczytywania ich wartości. Zestaw makr przygotowanych przeze mnie ma następującą postać:</p>
<div class="codesnip-container" >
<div class="c codesnip" style="font-family:monospace;"><span class="co2">#define __a_size(n)           ((sizeof(n) + sizeof(char *) &#8211; 1) &amp;amp; ~(sizeof(char *) &#8211; 1))</span></p>
<p><span class="co2">#define va_start(ptr, v)        (ptr = (va_list)(&amp;amp;v) + __a_size(v))</span><br />
<span class="co2">#define va_arg(ptr, t)          ( *(t *)((ptr += __a_size(v)) &#8211; __a_size(t)))</span><br />
<span class="co2">#define va_end(ptr)             (ptr = (va_list) 0)</span></p>
<p><span class="kw4">typedef</span> <span class="kw4">char</span> <span class="sy0">*</span> va_list</div>
</div>
<p style="text-align: justify;">Makro <em>__a_size(n)</em> jest odpowiednikiem notacji <em>a_sizeof(n)</em> z rysunku. Makro <em>va_start(ptr, v)</em> ustawia wskaźnik <em>ptr</em>, tak aby wskazywał na pierwszą zmienną ze zbioru. Aby poprawnie ustawić wskaźnik niezbędny jest adres ostatniej &#8216;normalnej&#8217; zmiennej (na rysunku jest zmienna <em>arg</em>). Makro <em>va_arg(ptr, t)</em> powoduje zwrócenie zmiennej wskazywanej przez ptr oraz ustawienie <em>ptr</em> tak by wskazywał na następną zmienną. Parametr <em>t</em> makra określa typ zmiennej jaką chcemy zwrócić. Jest on niezbędny, gdyż od niego zależy &#8216;odległość&#8217; do następnej zmiennej w pamięci. Makro <em>va_end(ptr)</em> służy do wyczyszczenia wartości wskaźnika ptr.</p>
<p style="text-align: justify;">Wyposażeni w taki zestaw makr możemy zacząć naszą przygodę z funkcjami o zmiennej liczbie argumentów. Dla przykładu napiszemy funkcję wypisującą wartość wszystkich zmiennych typu int podanych jako argumenty. Listing funkcji jest następujący:</p>
<div class="codesnip-container" >
<div class="c codesnip" style="font-family:monospace;"><span class="kw4">void</span> foo<span class="br0">&#40;</span><span class="kw4">int</span> num_ints<span class="sy0">,</span> &#8230;<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="kw4">int</span> i<span class="sy0">,</span> x<span class="sy0">;</span><br />
va_list va<span class="sy0">;</span></p>
<p>va_start<span class="br0">&#40;</span>va<span class="sy0">,</span> num_ints<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw1">for</span><span class="br0">&#40;</span>i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&amp;</span>lt<span class="sy0">;</span> num_ints<span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
x <span class="sy0">=</span> va_arg<span class="br0">&#40;</span>va<span class="sy0">,</span> <span class="kw4">int</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;arg: %d, val: %d<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> i<span class="sy0">,</span> x<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p style="text-align: justify;">Przykładowe wywołanie:</p>
<pre style="text-align: justify;">foo(3, 1, 2, 3);</pre>
<p style="text-align: justify;">I jego rezultat:</p>
<pre style="text-align: justify;">arg: 0, val: 1
arg: 1, val: 2
arg: 2, val: 3</pre>
<p style="text-align: justify;">
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/07/gcc-i-funkcje-o-zmiennej-liczbie-argumentow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>USB JTAG i OpenOCD 0.1.0 + Eclipse</title>
		<link>http://truly-integrated.net/2009/07/usb-jtag-i-openocd-010-eclipse/</link>
		<comments>http://truly-integrated.net/2009/07/usb-jtag-i-openocd-010-eclipse/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 16:24:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[HW]]></category>
		<category><![CDATA[SW]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=32</guid>
		<description><![CDATA[Jakiś czas temu światło dzienne ujrzała nowa wersja popularnego oprogramowania OpenOCD, służącego do programowania i debugowania uC. W związku z tym, jakże wspaniałym, wydarzeniem uznałem za zasadne przedstawienie Czytelnikowi treści skryptów, służących do programowania pamięci flash mikrokontrolerów AT91SAM7S64. Wybór mikrokontrolera jest podyktowany tym, iż znalazł on zastosowanie w dużej części wykonanych przeze mnie urządzeń. W [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu światło dzienne ujrzała nowa wersja popularnego oprogramowania <a title="OpenOCD" href="http://openocd.berlios.de/web/">OpenOCD</a>, służącego do programowania i debugowania uC. W związku z tym, jakże wspaniałym, wydarzeniem uznałem za zasadne przedstawienie Czytelnikowi treści skryptów, służących do programowania pamięci flash mikrokontrolerów AT91SAM7S64. Wybór mikrokontrolera jest podyktowany tym, iż znalazł on zastosowanie w dużej części wykonanych przeze mnie urządzeń. W roli JTAG&#8217;a wykorzystałem, własnoręcznie wykonany,<a href="http://truly-integrated.net/archives/3"> klon Turtelizera 2</a>.</p>
<p>W pakiecie OpenOCD dołączono wiele skryptów opisujących sposób pracy interfejsów JTAG, jak również dla poszczególnych układów docelowych (targetów). Nic nie stoi na przeszkodzie aby je wykorzystać i znacząco ułatwić sobie życie. Przykładowy skrypt flashujący uC plikiem<em> main.hex </em> wygląda następująco:</p>
<pre>source [find openocd-0.1.0/src/target/interface/turtelizer2.cfg] # (1)
source [find openocd-0.1.0/src/target/target/sam7s64.cfg]        # (2)

init                                  # (3)
reset halt                            # (4)
flash write_image main.hex 0          # (5)
reset run                             # (6)
shutdown                              # (7)</pre>
<p>Pierwsza linia zawiera ściężkę prowadzącą do opisu użytego interfejsu JTAG, zaś linia (2) wskazuje na plik z opisem układu docelowego. Jeśli Czytelnik w swej pracy wykorzystuje inne uklady docelowe należy przejrzeć katalog <em>target</em> w folderze instalacyjnym OpenOCD w poszukiwaniu odpowiedniego pliku. Z każdym dniem społeczność pracująca nad OpenOCD uzupełnia zbiór plików konfiguracyjnych o nowe targety. Pozostałe linie mają składnię podobną do znanej z poprzednich wersji OpenOCD. Powodują one inicjalizację komunikacji z targetem oraz jego zresetowanie i wstrzymanie (3, 4). Flashowanie odbywa się dzięki komendzie zawartej w linii (5), której pierwszym parametrem jest operacja jaką wykonujemy na pamięci flash, po niej następuje nazwa pliku oraz offset od początku przestrzeni adresowej uC pod jaki zostaną zapisane dane. Linie (6, 7) kolejno resetują mikrokontroler i &#8220;wprawiają go w ruch&#8221; oraz kończą pracę OpenOCD. Jak wynika z załączonego przykładu skrypty, dzięki gotowym zbiorom plików konfiguracyjnych, uległy znacznemu uproszczeniu.</p>
<p>Skrypt służący do debugowania jest równie prosty co powyższy, używany do flashowania. Jego treść przedstawia się w sposób zgodny z przdestawionym na listingu:</p>
<pre>source [find ./openocd-0.1.0/src/target/interface/turtelizer2.cfg] # (1)

# Change the default telnet port...
telnet_port 4444                     # (2)

# GDB connects here
gdb_port 3333                        # (3)

# GDB can also flash my flash!
gdb_memory_map enable                # (4)
gdb_flash_program enable             # (5)
gdb_breakpoint_override hard         # (6)

source [find ./openocd-0.1.0/src/target/target/sam7s64.cfg]        # (7)

init                                 # (8)</pre>
<p>Przeznaczenie linii  (1, 7)  jest znane z poprzedniego skryptu. Linia (2) służy do konfiguracji portu na którym będzie nasłuchiwać OpenOCD. Linia (3) ustawia port pracy samego debuggera GDB. Linie (4, 5) umożliwiają programowanie pamięci flash uC z wykorzystaniem GDB. Linia (6) ustawia rodzaj stosowanych breakpoinów na breakpointy hardwareowe. Opcja ta jest niezbędna w momencie gdy firmware został zlinkowany tak by pracować w pamięci flash a nie w pamięci ram. Należy mieć świadomość, iż liczba jednocześnie stosowanych breakpointów hardwareowych jest bardzo ograniczona, a w przypadku AT91SAM7S64 wynosi dokładnie dwa. Linia (8) służy do uruchomienia procesu debugującego.</p>
<p style="text-align: justify;">Tak przygotowany skrypt wyśmienicie współpracuje ze środowiskiem Eclipse. Konfigurację Eclipsa z doinstalowanym pluginem <a title="Zylin CDT plugin" href="http://opensource.zylin.com/embeddedcdt.html">Zylin Embedded CDT</a> rozpoczynamy od dodania nowej <em>Debug Configuration</em> typu <em>Zylin Embedded Debug (Native)</em>. Należy wybrać nazwę projektu dla którego konfigurujemy debug oraz plik wykonywalny w formacie <em>elf</em>, który zawiera m. in. symbole niezbędne dla debugu. Plik taki powstaje każdorazowo w wyniku zlinkowania skompilowanych źródeł projektu.</p>
<p style="text-align: center;"><a href="http://truly-integrated.net/wp-content/uploads/2009/07/debug_conf.png"><img class="aligncenter size-medium wp-image-63" title="debug_conf" src="http://truly-integrated.net/wp-content/uploads/2009/07/debug_conf-570x427.png" alt="debug_conf" width="570" height="427" /></a></p>
<p style="text-align: justify;">Następnie przechodzimy do zakładki <em>Debbuger</em>, gdzie ustawiamy jako aplikację debugującą <em>arm-elf-gcc</em> lub innym, w zależności z jakich kompilatorów korzystamy. W zakładce <em>Commands</em> ustawiamy komendy wysyłane podczas inicjalizacji oraz samego uruchomienia trybu debug. Komendy, jakie należy umieścić w sekcji <em>Initialize commands</em> są następujące:</p>
<pre style="text-align: justify;">target remote localhost:3333
monitor reset halt</pre>
<p>Sekcję<em> &#8216;Run commands&#8217;</em> pozostawiamy pustą. Tak przygotowany Eclipse jest gotowy do odpluskwiania (ech&#8230;), zaraz po uruchomieniu opisanego wcześniej skryptu uruchamiającego <em>debug mode</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/07/usb-jtag-i-openocd-010-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Turtelizer 2 JTAG Cloned.</title>
		<link>http://truly-integrated.net/2009/04/turtelizer-2-jtag-cloned/</link>
		<comments>http://truly-integrated.net/2009/04/turtelizer-2-jtag-cloned/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 12:50:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[HW]]></category>

		<guid isPermaLink="false">http://rzech.int.pl/~vontas/?p=3</guid>
		<description><![CDATA[Truly Integrated Turtelizer 2 Clone to kolejna implementacja popularnego Turtelizera 2, którego wersja pierwotna została opisana na ethrenut.de. Programator został zaprojektowany tak aby współpracować z oprogramowaniem OpenOCD. 10-pinowe złącze JTAG jest pinowo kompatybilne z pierwowzorem. Cały projekt jest oparty na popularnym scalaku FT 2232 firmy FTDI. Scalak ten ma wsparcie zarówno ze strony systemu operacyjnego [...]]]></description>
			<content:encoded><![CDATA[<p>Truly Integrated Turtelizer 2 Clone to kolejna implementacja popularnego Turtelizera 2, którego wersja pierwotna została opisana na<a title="ethernut.de" href="http://ethernut.de"> ethrenut.de</a>. Programator został zaprojektowany tak aby współpracować z oprogramowaniem <a href="http://openocd.berlios.de/web/">OpenOCD</a>. 10-pinowe złącze JTAG jest pinowo kompatybilne z pierwowzorem. Cały projekt jest oparty na popularnym scalaku FT 2232 firmy <a href="http://www.ftdichip.com/">FTDI</a>. Scalak ten ma wsparcie zarówno ze strony systemu operacyjnego Windows jak również Linux. Prócz samego interfejsu <a href="http://pl.wikipedia.org/wiki/JTAG">JTAG</a> programator został wyposażony  w port RS232 o prędkości do 115200 bps. Konwersję poziomów napięć dla RSa zapewnia ST3232, który jest podobnież jednym z lepszych konwerterów poziomów napięć spośród scalaków dostępnych na rynku. Aby zabezpieczyć komputer przed możliwością wystąpienia efektów typu światło-dzwięk-zapach, powstających w wyniku tzw. przepięć wyjścia układu zostały połączone poprzez bufory, które dodatkowo umożliwiają współpracę z targetami zasilanymi napięciami innymi niż to, którym zasilany jest sam JTAG.</p>
<p>Aby móc użyć portu szeregowego w systemie Linux należy załadować moduł jądra o nazwie <em>ftdi_sio</em>. Z racji tego iż programator korzysta z nietypowego <em>vendor_id</em> oraz <em>product_id</em> (nietypowe = różne od domyślnego dla kości FT2232) ładowanie modułu należy przeprowadzić w następujący sposób:</p>
<pre># modprobe ftdi_sio vendor=0x403 product=0xbdc8</pre>
<p>Sterowniki dla systemu Windows znajdują się w pakiecie OpenOCD.  Wieść niesie, że podobno działają, ja niestety potwierdzić tego nie mogę gdyż nie posiadam takowego systemu operacyjnego (bida, panie..).</p>
<p>Na zakończenie zamieszczam zdjęcie programatora mej produkcji:</p>
<p><img class="aligncenter size-medium wp-image-76" title="Programator JTAG" src="http://truly-integrated.net/wp-content/uploads/2009/04/prog1-570x358.jpg" alt="Programator JTAG" width="570" height="358" /></p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/04/turtelizer-2-jtag-cloned/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
