<< Zpět

 

 

 

ATpad

Herní konzole s ATmega8

Sestavit výkonný a levný počítač pomocí moderních součástek není dnes už žádný problém. Ale použít k tomu zcela nevhodný a nevýkonný procesor - to je teprve ten pravý challenge! :-D ... A proč zrovna ATmega8?

  1. Je celkem levný,
  2. snadno se používá,
  3. mám jich nadpočetnou zásobu :-/
  4. a je to dostatečně špatný nápad to dělat!

Pozn.: Obrázky zde uvedené zvětšíte kliknutím

Ukázkové video ATpad na YouTube: https://www.youtube.com/watch?v=jmdYueKbfG8

Obsah

Vlastnosti ATpadu

ATpad generuje obrazový signál softwarově. Výstup lze připojit k televizoru s RGB vstupem (televizní normy PAL nebo NTSC) nebo počítačový monitor VGA. Přes redukci lze sloučit RGB a SYNC signály do černobílého kompozitního signálu (pouhým spojením vodičů) a připojit přes CINCH konektor na kompozitní vstup televizoru (vhodné v případě, že televizor nepodporuje RGB vstup).

Ke spouštění programů slouží běžná SD karta. Karta musí být naformátována formátem FAT16. Zbylý prostor SD karty může být používán běžným způsobem s FAT32.

Procesor obsahuje boot loader o velikosti 2 KB, který po resetu vyhledá na kartě soubor zavaděče BOOT.* (přípona souboru závisí na typu procesoru) a ten nahraje do paměti ROM Flash. Standardně je zavaděčem program pro výběr programů z karty - ten zajistí načtení vybraného programu do ROM paměti a jeho spuštění. Není-li při resetu zasunuta SD karta, spustí se z paměti naposledy nahraný program.

Součástí programů je pole vzorů dlaždic v ROM paměti. V RAM je pole indexů dlaždic (pro rozlišení 20 x 14 dlaždic zabere pole v RAM pouze 280 bajtů). Zobrazovací rutina čte indexy dlaždic z RAM a zobrazuje příslušné dlaždice z ROM. Každá dlaždice zabere v ROM 32 bajtů (8 x 8 pixelů, 16 barev, tj. 2 pixely na 1 bajt). Počet dlaždic je omezený pouze velikostí paměti. To umožňuje rychlou manipulaci s obrazem s malými nároky na paměť. Vhodně připravenými dlaždicemi lze zajistit i animace, jako např. jednoduché video.

Velikost programu v ROM je omezena na 6 KB (zbylé 2 KB zabírá boot loader). Lze spouštět i větší program technikou overlay - program může načítat potřebné další části z SD karty až za běhu (do ROM, RAM nebo EEPROM) - vhodné např. k načítání definice scén. Použitím vyššího typu procesoru (ATmega328p) lze načítat větší programy bez nutnosti overlay ... ovšem tím už přicházíte o tu správnou zábavu "vměstnat program do 6 KB" :-) .

ATpad umožňuje i generování zvukových tónů s obdélníkovým nebo pilovým průběhem. Tóny vznikají modulací horizontální synchronizace. U televizního obrazu je kmitočet synchronizace 16 kHz a je proto nutné počítat s poměrně špatnou kvalitou generovaného tónu (vysoký obsah rušivých harmonických). Při použití VGA monitoru je kmitočet 32 kHz a zvuk je podstatně lepší. Kvalita zvuku by byla lepší v případě, když by se místo modulace nosné použilo spínání výstupu podle periody tónu - ovšem za cenu snížení přesnosti frekvence tónu.

Typ procesoru a frekvence

Minimálním podporovaným procesorem je ATmega8 (8 KB ROM, 1 KB RAM, 512 B EEPROM). Poslední 2 KB ROM se používají pro zavaděč (bootloader), zbylých 6 KB je k dispozici pro aplikaci, včetně vzorů obrazových dlaždic. Procesor lze použít jak v TQFP pouzdru, tak v PDIP pouzdru. PDIP verze má výhodu v možnosti snadné výměny procesoru - při závadě nebo při experimentování s různými procesory.

Kromě ATmega8 lze použít i vyšší typy, pinově kompatibilní. Programy musí být přeloženy pro konkrétní použitý procesor a frekvenci krystalu. V ukázkových programech jsou připraveny překlady pro ATmega8, ATmega88 a ATmega328p. ATmega88 je nejnižší podporovaný typ z modernější řady xx8. ATmega328p je levný typ s větší pamětí (32 KB ROM, 2 KB RAM). To umožňuje použití většího rozlišení obrazovky a větších aplikací.

Frekvence krystalu není striktně určená. Je však nutné překládat aplikace i bootloader pro konkrétní použitou frekvenci. Během překladu se automaticky spočítá časování pro softwarové generování obrazového signálu. Frekvence krystalu určuje především dosažitelné rozlišení generovaného obrazu. Při použití jmenovité frekvence (16 MHz pro ATmega8 nebo 20 MHz pro ATmegaxx8) není u většiny programů podporováno typické rozlišení obrazu pro VGA monitor (to je dosaženo až přetaktováním vyšší frekvencí). Je použit nouzový režim dělené obrazovky, kdy se levá a pravá půlka obrazu zobrazí nad sebou. Pro televizní módy je jmenovitá frekvence dostatečná, obraz se zobrazí správně.

Dělená obrazovka na VGA monitoru při použití nízké frekvence:

Ukázkové aplikace jsou navrženy pro frekvenci 24 MHz. Na tuto frekvenci lze přetaktovat většinu procesorů (jak ATmega8, tak ATmegaxx8). Pouze u některých starších ATmega8 jsem narazil na omezení na 16 MHz. Některé procesory lze přetaktovat až na 27 MHz, ale na tuto frekvenci je nutné procesory již vybírat. Přínosem může být vyšší horizontální rozlišení, ovšem omezením už může být velikost RAM a tak je tato frekvence podporovaná jen jako zajímavost.

Aby bylo možné mít na jedné SD kartě verze pro různé procesory a různé frekvence, liší se soubory příponou a ATpad vybírá jen verze se správnou příponou. Jméno přípony je uloženo v bootloaderu a určuje se během překladu. V ukázkových programech jsou použity následující přípony:

Spouštění aplikací z SD karty

Aplikace se spouštějí z SD karty. V posledních 2 KB paměti ROM je uložen bootloader (zavaděč), který z root adresáře SD karty načte a spustí program BOOT.*, kde přípona souboru je určena typem procesoru a frekvencí krystalu (viz předešlá sekce). Programy se zavádějí do prvních 6 KB ROM paměti, resp. u ATmega328p do prvních 30 KB ROM paměti. Program se v paměti uchová i po vypnutí ATpadu. Není-li po zapnutí vložena SD karta s platným souborem BOOT.*, spustí se poslední nahraná aplikace (nacházející se v paměti ROM).

Počet zápisů do paměti ROM je omezen na asi 10 tisíc. Při běžném použití je to dostatečný počet, ale může to být omezení v případě zasunuté SD karty, provádí-li se častý reset.

Ke spouštění aplikací z SD karty slouží zaváděcí program BOOT.* (v ukázkových programech složka !BootLoader). Program zobrazí seznam aplikací na SD kartě. Zobrazí jen soubory se správnou příponou (=správný procesor a frekvence). Soubory lze umisťovat i do složek.

BootLoader umožňuje nastavení konfigurace displeje. Kombinací tlačítka B (vpravo nahoře) se současným stiskem šipky se změní použitý typ dispeje. Spouštěné programy si převezmou zvolenou konfiguraci z EEPROM paměti a při startu se přepnou na správný typ displeje. Konfigurace se uplatní pouze u programů s režimem displeje UNI.

SD kartu je nutné před použitím naformátovat ve čtečce karet na formát FAT16 (jediný formát podporovaný ATpadem). Na SD kartě se může nacházet více oddílů disku (max. 4), ATpad použije první nalezený oddíl s formátem FAT16. Postup při vytvoření SD karty pod Windows:

  1. Klikněte na "Tento počítač" pravým tlačítkem myši a zvolte "Spravovat". Vyberte řádek "Úložiště" - "Správa disků".
  2. Vložte SD kartu do čtečky a v seznamu disků v dolní části vyhledejte příslušný disk. POZOR ať nevyberete nesprávný disk, můžete si tak snadno zničit obsah jiného svého disku! Musí se jednat o "Vyměnitelné médium" a musí souhlasit uvedená kapacita.
  3. Obsahuje-li disk nějaké oddíly, vyberte je a zrušte (pravé tlačítko myši a volba "Odstranit svazek"). POZOR zda na disku nemáte nějaká svá data, odstraněním oddílu se data smažou!
  4. Klikněte do prázdného místa "Nepřiřazeno" a zvolte "Nový jednoduchý svazek".
  5. Po otevření Průvodce zvolte velikost v MB pro oddíl ATpad. Stačí několik desítek MB, např. 100 MB (ukázkové programy zaberou dohromady 2 MB).
  6. V dalším kroku zvolte písmeno disku (můžete později změnit).
  7. V dalším kroku vyberte systém souborů FAT. Zaškrtněte "Rychlé formátování". Vyberte velikost alokační jednotky podle tabulky níže tak, aby odpovídala formátu FAT16. Při příliš malé hodnotě systém může vyžadovat přepnutí na FAT32, při příliš velké hodnotě systém zvolí FAT12. Např. pro 100 MB zvolte 4096 B.
  8. Po zformátování oddílu nakopírujte na disk programy ATpad.
  9. Dále můžete pokračovat vytvořením dalšího diskového oddílu ve zbylém místu SD karty. Další oddíly mohou být vytvářeny i před oddílem ATpad, ale v tom případě nesmí použít formát FAT16 (mohou použít FAT32).

Velikost alokační jednotky Velikost FAT16 disku od- Velikost FAT16 disku do-
512 B 2 MB 32 MB
1024 B 4 MB 64 MB
2048 B 8 MB 128 MB
4096 B 16 MB 256 MB
8192 B 32 MB 512 MB
16 KB 64 MB 1 GB
32 KB 128 MB 2 GB

Schéma zapojení

ATpad je ve 2 provedeních, podle typu pouzdra procesoru - TQFP (SMD montáž) nebo PDIP (objímka).

Schéma zapojení TQFP varianty (kliknutím zvětšíte):

Schéma zapojení PDIP varianty (kliknutím zvětšíte):

Procesor je vybavený resetovacím tlačítkem S1, kterým se lze dostat z programu do bootloaderu. Konektor S5 ISP je programovací, slouží k naprogramování procesoru. Použijte některý standardní programátor pro AVR procesory s 6-pinovým ISP konektorem. Současně jsou programovací signály ISP přivedeny na SD kartu, přes odporové děličky sloužící k přizpůsobení úrovní 5V a 3.3V. Nemusí to být nutné, ale raději nepřipojujte programátor, máte-li zasunutou SD kartu. Mohlo by dojít k poškození jejího obsahu. Konektor X1S mini-USB je napájecí konektor. Nepoužívá datové vodiče, pouze zajišťuje napájení +5V ze standardního nabíjecího zdroje (nebo z USB portu počítače). Stabilizátor IC2 připravuje napětí +3.3V pro SD kartu. Rezistor R17 zajistí úroveň HIGH na CS vstupu SD karty během startu procesoru, kdy jsou výstupy v HIGH impedanci, aby náhodným stavem signálů nedošlo k modifikaci obsahu SD karty. Konektor SD karty nevyužívá signály vložení karty ani ochranu proti zápisu (v software ATpadu není ani zápis na kartu implementován). K CS signálu SD karty je připojena indikační LED dioda, monitorující aktivitu čtení z SD karty, a také jako signalizační LED programu.

Odpory R7 až R12, R19, R30 a R31 jsou odporové děliče, ke změně výstupní úrovně procesoru na video signály RGB. Odpory R19, R30 a R31 nejsou nutné. Byly přidány ve snaze zlepšit impedanční přizpůsobení výstupů k 75-ohmovému vstupu televizoru, aby se zlepšily zákmity na hranách obrazu. Zákmity se moc nezlepšily (problém bude asi někde jinde) a budete-li chtít tyto 3 odpory vypustit, v tom případě změňte odpory R7 až R12 na hodnoty 680 a 1K5. Odpory R21 a R29 vytváří napěťové úrovně potřebné pro signály SWITCH a BLANK pro SCART konektor. Pro výstup na TV nebo VGA lze použít jak X4 RGB konektor, tak X2 VGA konektor. Oba konektory obsahují všechny potřebné signály. Audio výstup je přiveden nestandardně na pin 14 VGA konektoru (běžně používaný pro VSYNC). Díky vstupní impedanci 75 ohmů je zvukový signál utlumen a nebude nesprávně považován za VSYNC signál. Při zasunutí konektoru do X3 AUDIO výstupu je signál od VGA konektoru odpojen, aby nebyl VGA monitorem utlumen. Synchronizační signál je na oba konektory veden jako synchronizační směs (HSYNC i VSYNC pohromadě), který podporují i VGA monitory. Je možné neosazovat konektor X4 RGB a používat pouze X2 VGA konektor - snáz se letuje (větší vzdálenost mezi piny) a s mini-DIN konektorem se špatně manipuluje (příliš jemný konektor na příliš silný kabel)..

Nepodporuje-li televizor RGB vstup, lze použít černobílý kompozitní obrazový signál - stačí pouze dohromady spojit výstupy R, G, B a SYNC. U některých televizorů již může dojít k přebuzení vstupu příliš vysokou úrovní signálu (špatně se synchronizuje horní část obrazu a je přejasněná) - v tom případě může být nutné přidat ještě omezující odpor.

Konektor X6 JOY je konektor portů. Obsahuje 2 digitální vstupně/výstupní piny (B1 a B2) a 2 analogové vstupní piny (X1 a Y1). Ke konektoru lze připojit standardní analogový joystick s 15-pinovým CANON konektorem. K tomu slouží odpory R6 a R13, které spolu s proměnlivým odporem joysticku (0 až 100 kOhm) vytvoří vstupní napětí v rozsahu +2.5 až +5.0V (hodnota naměřená na ADC převodníku bude v rozsahu 512 až 1023). Pro přístup k portům není v ukázkových programech připraven příklad. Předpokládá se začlenění obsluhy čtení ADC vstupů do obsluhy vertikální synchronizace video výstupu. Při čtení ADC vstupů je potřeba pamatovat na to, že z technických důvodů jsou během generování videosignálu vysílány na piny PC4 a PC5 náhodná data, což se projevuje náhodným připojováním a odpojováním pull-up rezistorů 36 kOhm. To by zkreslilo hodnotu naměřenou z analogového joysticku. Proto je vhodné doplnit obsluhu čtení ADC vstupu do obsluhy vertikální synchronizace, během které lze pull-up rezistory vypnout. Jinak, v krajním případě, by bylo možné vypnout interní pull-up rezistory procesoru globálně (přepínač PUD) a vstupy z tlačítek ošetřit externími pull-up rezistory.

Signály B1 a B2 (BTN1 a BTN2) lze použít jako digitální vstupy nebo digitální výstupy. Piny lze použít též k sériové komunikaci I2C (2-wire serial bus TWI, signály SDA a SCL). Takto lze vzájemně propojit více zařízení s procesory, formou sběrnice. Signály používají výstupy s otevřeným kolektorem. K I2C není připraven ukázkový příklad.

Chcete-li konstrukci minimalizovat, vypusťte konektor X4 RGB, odpory R19, R30, R31, konektor portů X6 JOY s odpory R2-R6, R13 a kondenzátor C8 (filtr zvuku).

Plošný spoj a osazení

Plošné spoje jsou navrženy jako oboustranné, bez prokovených děr, s nutností několika propojek mezi horní a spodní vrstvou. Spodní vrstvu je možné nahradit drátovými propojkami (spoje jsou vedeny především v horní vrstvě). Spoje jsou vytvořené ve free verzi Eagle, proto jsou limitovány rozměrem 10x15 cm. Současně je to i rozměr vhodný pro použitou krabičku. Shora jsou osazena tlačítka, SD konektor, USB konektor a procesor v TQFP verzi. Použijete-li tlačítka s aretačními výstupky, doporučuji výstupky upilovat, aby tlačítka dolehla těsně na plošný spoj - vnitřní výška krabičky doléhá těsně na tlačítka, při ponechání výstupků by tlačítka překážela.

Při osazování doporučuji osadit nejdříve USB konektor a zkontrolovat přítomnost napětí +5V. Dále přiletovat stabilizátor a zkontrolovat napětí +3.3V na jeho výstupu. U stabilizátoru pozor na to, že každý výrobce používá jiné zapojení pinů stabilizátoru. Neřiďte se zde uvedenou orientací pinů (nemusí souhlasit s vaším stabilizátorem). Dokonce prodejci (jako GME) přikládají datasheety od jiných výrobců, které jsou sice kompatibilní po elektrické stránce, ale nesouhlasí piny. Proto je důležité ověření správné funkce stabilizátoru hned na začátku, později se chyba už špatně hledá.

Výroba plošného spoje: Použijte oboustrannou desku plošného spoje o rozměru 10x15 cm. Pro ni jsou připraveny zaměřovací kříže v rozích předlohy spoje. Předlohu vytisknete na inkoustové nebo laserové tiskárně. Je potřeba použít průhlednou fólii pro inkoustovou nebo laserovou tiskárnu. Na jiné fólii barva nemusí držet. Každou stranu předlohy vytiskněte 2x, zrcadlově obráceně. Oba výtisky přiložte k sobě, přesně je sesaďte (podle krytí nejjemnějších částí spoje) a slepte izolepou. Přiložte předlohu tiskem dolů na plošný spoj (proto zrcadlově obrácený tisk), zaměřovací kříže v rozích usaďte přesně na rohy spoje 10x15 cm. Spoj osviťte UV zářivkou nebo UV LEDkami. Přesnou dobu osvitu si předem vyzkoušejte na proužku plošného spoje. Pro osvitku s 15 UV LEDkami je při vzdálenosti 30 cm doba osvitu asi 8 minut. Po osvitu jedné strany desku otočte a osviťte ji s použitím druhé předlohy (pozor na správnou orientaci stran k sobě). Spoj vyvolejte v 1% roztoku hydroxidu sodného (Tesco, drogerie) a vyleptejte v 7% roztoku kyseliny solné (PeMi, OBI) s 1% peroxidu vodíku (Barvy Laky).

Horní strana (varianta TQFP a PDIP):

Dolní strana (varianta TQFP a PDIP):

Potisk dolní strany (varianta TQFP a PDIP):

Montáž - pohled z dolní strany (varianta TQFP a PDIP):

Letování pinů na dolní straně (varianta TQFP a PDIP):

Konstrukce a krabička

Spoj je připraven k umístění do krabičky KM78.Ve stěnách a víku krabičky je nutné vyřezat následující otvory (klikněte pro zvětšení; pozor u bočních pohledů si povšimněte šipky směru nahoru). Otvor pro USB konektor bude nutné vyřezat poměrně velký, konektor je hluboko zapuštěný a je nutno zasunout zástrčku i s její izolací.

Ke dnu je deska uchycena pomocí distančních sloupků o délce 5 mm a se závitem M3. Závit sloupku je nutné trochu upilovat, aby nebyl delší než sloupek krabičky. Závit M3 drží ve sloupcích krabičky dobře, ale lze snadno strhnout neopatrným šroubováním sloupku.

Deska se do sloupků přišroubuje šroubky M3.

Konektory na dolní straně desky přiléhají těsně na dno krabičky. Horní víko krabičky doléhá těsně na osazení hmatníků tlačítek. Pozorujete-li, že tlačítka nereagují na stisk (necvakají), jsou zamáčknutá víkem krabičky. V tom připadě je nutné buď podložit víko krabičky, nebo zvětšit otvory pro tlačítka (aby se vešla i s jejich osazením), nebo ze spodní strany víka rozšířit otvory vyfrézováním drážky (to je použito na fotografiích).

Potisk krabičky jsem vyřešil vytištěním papírové popisky a přelepením průhlednou izolepou. Doporučuji na štítku uvést použitý procesor, frekvenci a příponu souborů. K tomu lze využít připravené potisky.

Oživení, programování procesoru

Použijete-li již naprogramovaný procesor, měla by po zapnutí (připojení USB nabíječky s mini-USB konektorem) začít blikat indikační LED, indikující že se bootloader snaží zavést bootovací program. Budete-li procesor programovat sami, doporučuji nejdříve vyzkoušet testovací program, který nedělá nic jiného, než že bliká indikační LED diodou v rytmu 1 Hz. Tím ověříte, zda je procesor funkční a zda je jeho oscilátor správně funkční. V balíku jsou testovací programy přeložené pro různé varianty ATpadu - podle dříve uvedeného seznamu označení přípon souborů. Pro testovací program použijte následující nastavení pojistek (rychlý krystal, reset vektor ukazuje do aplikace na adresu 0):

ATmega8: low 0xEF (default 0xE1), high 0xC9 (default 0xD9)
ATmega88: low 0xE7 (default 0x62), high 0xDF (default 0xDF), ext 0xF9 (default 0xF9)
ATmega328p: low 0xE7 (default 0x62), high 0xDB (default 0xD9), ext 0xFF (default 0xFF)

Po základním ověření funkčnosti naprogramujte do procesoru BootLoader, který naleznete v root adresáři demonstračního disku.- jsou to soubory s příponou .HEX, ve jménu souboru je jméno varianty podle dříve uvedeného seznamu. Pojistky naprogramujte takto:

ATmega8: low 0xEF (default 0xE1), high 0xC8 (default 0xD9)
ATmega88: low 0xE7 (default 0x62), high 0xDF (default 0xDF), ext 0xF8 (default 0xF9)
ATmega328p: low 0xE7 (default 0x62), high 0xDA (default 0xD9), ext 0xFF (default 0xFF)

V pojistkách je důležité nastavení - použít rychlý krystal, použít boot loader o velikosti 2 KB (= 1 K slov), resetovací vektor umístit do boot loaderu.

Po zápisu BootLoaderu zapněte pojistku procesoru BLB11. Ta slouží k ochraně boot loaderu proti chybě aplikace (aby aplikace nemohla boot loader poškodit neoprávněným zápisem). Bez této pojistky sice ATpad pojede také, ale mohlo by se stát, že někdy po chybě přestane boot loader fungovat.

Po naprogramování by měla začít blikat indikační LED, indikující zavádění boot loaderu z SD karty. Po připojení displeje by měl být vidět obraz zavaděče programů. Není-li obraz vidět, zkuste zapnout správný typ displeje pomocí tlačítek B+šipka (při prvním startu implicitně zvolen VGA displej).

Nejjednodušší způsob připojení je pro VGA displej, který jen zasunete do VGA monitoru. K připojení televizoru můžete použít buď X4 RGB konektor (8-pin mini-DIN) nebo X2 VGA konektor. U obou konektorů jsou k dispozici prakticky všechny potřebné signály (včetně zvuku). U X4 RGB konektoru jsou k dispozici řídicí signály SWITCH a BLANK pro SCART konektor, které zajistí automatické přepínání vstupu televizoru po zapnutí ATpadu a volbu správného poměru obrazu. U X2 VGA konektoru lze pro signál BLANK použít odpor 100R připojený k signálu SWITCH. Nepodporuje-li televizor RGB vstup, lze vytvořit kompozitní černobílý signál pouhým spojením výstupů R, G, B a SYNC (příp. ještě přes omezující odpor, dochází-li k přebuzení).

Ukázkové programy

Root složka disku:

BOOT - zavaděč programů (ve zdrojových kódech složka !BootLoader). Program obsahuje jednak rozhraní pro výběr programu ke spuštění a jednak na svém konci 2 KB bootovací zavaděč. Na disku je k dispozici jako soubor BOOT.*, který se automaticky zavádí do paměti po resetu, a také jako soubor v HEX formátu, který lze zapsat do procesoru programátorem. Spuštěním programu bez použití programátoru se do paměti načte pouze program pro spouštění aplikací, část s bootovacím zavaděčem se ignoruje. Klávesy: nahoru/dolů = posun kurzoru po souborech, vlevo/vpravo = přepínání stránek, A = start programu nebo změna adresáře, B+nahoru = přepnutí na VGA monitor, B+vlevo = TV s PAL, B+vpravo = TV s NTSC. U procesorů s nízkou frekvencí *L se nezobrazí číslo souboru.

Složka DEMO (demonstrace):

LINES - generování náhodných čárových obrazců. Program využívá atributovou grafiku podobnou ZX Spectru - ke každé skupině 8x8 pixelů přináleží barevný atribut udávající barvu pozadí a barvu popředí. Dosažené rozlišení závisí jednak na typu procesoru (velikost RAM) a jednak na rychlosti krystalu. Pro krystaly 24 a 27 MHz je u procesorů ATmega8 a ATmega88 rozlišení 88x56 pixelů, procesor ATmega328p má rozlišení 112x104 pixelů. Pro pomalejší krystaly je rozlišení o trochu menší. Klávesy: B = opuštění programu.
MELODY - přehraje melodii "Silent Night". Jak už jsem se zmínil výše, ke generování tónů u TV se používá modulace horizontální synchronizace 16 kHz a tak je kvalita generovaného zvuku nevalná. U monitoru VGA je zvuk lepší. Klávesy: B = opuštění programu.
PHOTO - zobrazení obrázků a fotografií. Program využívá atributovou grafiku (viz program LINES). Pro ATmega8 a ATmega88 je rozlišení obrazu 96x56 pixelů, pro ATmega328p 120x104 pixelů. Verze s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. K dispozici je program ATpad_graph, který zkonvertuje obrázky (TGA bez komprese) do interního formátu s atributy, který pak program načítá z disku do videopaměti jako overlay. Klávesy: B = opuštění programu.

PI - demonstrace výpočtu velkého čísla. Program počítá číslo PI na 200 číslic pomocí Machinovy formule. Po výpočtu zkontroluje výsledek porovnáním s tabulkovým číslem PI. Program též demonstruje zrychlení běhu programu zmenšením zobrazeného obrazu (během výpočtu PI se obraz zmenší jen na 1 řádek a tím se běh programu zrychlí 10x). Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: A = opakování výpočtu, B = opuštění programu.

Složka GAME (hry):

FIFTEEN - hra Patnáct. Na hrací ploše je 15 očíslovaných kamenů, náhodně rozmístěných. Úkolem je kameny seřadit v pořadí 1 až 15. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: šipky = pohyb, B = opuštění programu.
MAZE - hra Bludiště. Demonstruje algoritmus náhodného vytvoření bludiště. Úkolem je projít bludiště až k výchozím dveřím. Jsou vidět jen políčka blízko hráče. U verze s nízkou rychlostí krystalu se vygeneruje menší bludiště. Klávesy: šipky = pohyb, A = zobrazení dveří, B = opuštění programu.
PONG - hra Televizní Tenis. Protihráčem je počítač. Program používá atributovou grafiku. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: šipky = pohyb, A = podání míčku, B = opuštění programu.
SOKOBAN1 - klasická populární hra Sokoban. V této variantě je 84 scén sady "Box World". Scény se načítají jako overlay z disku. Každá scéna obsahuje i makro demonstrující řešení scény. K programu je připraven program pro RLE kompresi makra řešení scény. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: šipky = pohyb, A = ukázka řešení scény, B = opuštění programu.
SOKOBAN2 - klasická populární hra Sokoban. V této variantě je 40 scén sady "Mini Cosmos" a 16 zbylých scén sady "Box World" (tj. celkem 56 scén). Scény se načítají jako overlay z disku. Každá scéna obsahuje i makro demonstrující řešení scény. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: šipky = pohyb, A = ukázka řešení scény, B = opuštění programu.
SOKOBAN3 - klasická populární hra Sokoban. V této variantě je 88 scén sady "XSokoban". Scény se načítají jako overlay z disku. Každá scéna obsahuje i makro demonstrující řešení scény. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: šipky = pohyb, A = ukázka řešení scény, B = opuštění programu.
TETRIS - klasická hra TETRIS. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: vlevo/vpravo = pohyb do stran, nahoru = otočení, dolů = položení, A = pauza, B = konec hry.
TRAIN - vlak na principu HADA. Úkolem je posbírat všechny předměty a projet cílovou branou. Scény se načítají jako overlay z disku. K dispozici je 50 scén. Zadáním hesla lze vybrat scénu. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: šipky = pohyb, A = zadání hesla, B = přerušení scény. B+nahoru = ukázka řešení scény. Program lze přerušit pouze resetem ATpad.

Složka TEST (testování a diagnostika ATpad):

BUTTONS - test tlačítek ATpad. Tlačítka 1 a 2 jsou digitální vstupy z konektoru portů (u ATpad prototypu verze 1 to jsou tlačítka X a Y). Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Program lze přerušit pouze resetem ATpad.
COLORS - horizontální testovací pruhy barev s indexem 1 až 15 (černá barva s indexem 0 chybí). Klávesy: B = opuštění programu.
COLORS2 - vertikální testovací pruhy barev s indexem 1 až 15 (černá barva s indexem 0 chybí). Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku a zobrazí i černou barvu 0. Klávesy: B = opuštění programu.
COLORS3 - kombinovaný testovací obrazec. Horní a dolní pruh (černá a bílá barva pozadí) se již mohou nacházet mimo zobrazitelnou část displeje. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: B = opuštění programu.
COLORS4 - kombinovaný testovací obrazec s číslovanou tabulkou. Výsledný barevný atribut = řádek*16 + sloupec. Verze ATpad s nízkou rychlostí krystalu zobrazí tabulku 2x tak vysokou. Klávesy: B = opuštění programu.

FONT6 - zobrazení znakové sady fontu 6x8 pixelů. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: A = přepnutí dolní a horní půlky znaků, B = opuštění programu.

FONT8 - zobrazení znakové sady fontu 8x8 pixelů. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: A = přepnutí dolní a horní půlky znaků, B = opuštění programu.

FONTIBM - zobrazení znakové sady fontu IBM 8x8 pixelů. Verze ATpad s nízkou rychlostí krystalu používají u VGA monitoru dělenou obrazovku. Klávesy: A = přepnutí dolní a horní půlky znaků, B = opuštění programu.
LED - testovací blikání indikační LED, s intervalem 1 sekunda. Všechny ostatní funkce jsou potlačeny, neprobíhá výstup na displej. Program lze přerušit pouze resetem ATpad.

Složka TUTORIAL:

HELLO - nejjednodušší ukázkový program. Vypíše text na obrazovce. Program lze přerušit pouze resetem ATpad.

Překlad a tvorba aplikací

Programy pro ATpad (včetně bootovacího zavaděče) jsou napsány v C spolu s assemblerem AVR a překládají se na PC pomocí překladače WinAVR 20100110 (avr-gcc 4.3.3). Instalátor lze stáhnout např. ze SourceForge https://sourceforge.net/projects/winavr/. Instalátor by měl přidat do systémové proměnné PATH cestu do složky C:\WinAVR\bin, odkud se bude volat překladač.

Rozbalte archiv se zdrojovými kódy ATpad do nové složky. Uvnitř naleznete složky s jednotlivými aplikacemi. Složka !BootLoader obsahuje kód bootovacího zavaděče (2 KB trvale se nacházející na konci paměti ROM) spolu s programem pro spouštění aplikací. Po překladu se vygeneruje soubor HEX, který zapíšete do ROM procesoru programátorem. Po zápisu nastavte pojistky a zámky procesoru tak, jak bylo uvedeno v sekci Oživení. Další přeložené programy již nebudete do procesoru zapisovat programátorem, ale uložíte je na SD kartu a spustíte v ATpadu spouštěcím programem. SD karta musí být naformátována na FAT16, návod byl uveden v sekci SD karta.

Aplikace se překládají povelovým souborem c.bat (=compile). Nepotřebné produkty překladu lze smazat pomocí d.bat (=delete). Vygenerované soubory se současně nakopírují i do složky !OK. Po překladu všech aplikací bude složka obsahovat obraz SD disku. Všechny programy naráz lze přeložit dávkovým souborem c_all.bat. Překlad všech aplikací trvá asi půl hodiny.

Složka "_timings" obsahuje program ATpad_timings, který slouží k výpočtu časování. Volá se během překladu. Programu se předají potřebné parametry přes příkazový řádek. Ze souboru timings.ini si načítá konfiguraci knihoven (počet taktů jednotlivých větví programu). Pokud možno, nezasahujte do knihoven ve složce "video", změny by vyžadovaly opravu parametrů časování.

Složka "_sprites" obsahuje společné grafické podklady - definice fontů a programy pro import fontů, obrázků a sprajtů do ATpad.

Složka "_lib" obsahuje knihovny použité aplikacemi ATpad, většinou psané v assembleru - matematické operace, obsluha displeje, generátor náhody, obsluha souborů a zvuku. Podrobný popis funkcí naleznete v sekci Knihovny.

Budete-li si chtít vytvořit svou vlastní aplikaci:

Dobrým příkladem je aplikace HELLO. Nedělá nic jiného, než že zobrazí text uprostřed obrazovky. Je tam dobře vidět minimum potřebné pro překlad aplikací. Soubor "asm_sprites.S" obsahuje grafické podklady (fonty, sprajty). Je překládaný assemblerem, aby bylo možné řídit zarovnání polí. Soubor "include.h" obsahuje odkazy na všechny použité soubory *.h (definice) a je vnořen do každého souboru *.c. Soubor main.c je hlavní program, main.h je jeho hlavičkový soubor (zpřístupnění definic pro další části programu). Soubor makefile obsahuje odkazy na překládané části programu - do něj přidáte jména všech přidávaných souborů *.c a *.S.

Prvním příkazem funkce main() by vždy měl být Init(). Inicializuje ATpad, software i hardware. Druhým příkazem je ReadConfigLoader() - načte konfiguraci displeje a přepne displej na PAL, NTSC nebo VGA. Displej se přepíná programově pouze při použití UNI módu (univerzální mód). V UNI módu je rozměr videomódu omezen nejnáročnějším prvkem - což obvykle znamená VGA displej. Zvolíte-li typ displeje explicitně (místo UNI zvolíte PAL, NTSC nebo VGA), můžete u televizních módů použít podstatně vyšší horizontální rozlišení. Ovšem za cenu, že program nelze přepnout na jiný typ displeje (resp. pro každý displej musíte vygenerovat zvláštní soubor).

Používá-li se v aplikaci generátor náhodných čísel, měl by následovat příkaz Randomize(). Ten zajistí načtení výchozí hodnoty generátoru náhody z EEPROM a tím různou náhodnost při opakovaném spouštění. Následuje hlavní smyčka programu - obvykle nekonečná smyčka while(1) {}. Je vhodné, aby smyčka obsahovala příkaz WaitFrame(). Příkaz čeká na vertikální synchronizační puls a to zajistí nezávislost běhu programu na rychlosti procesoru.

Knihovny

Knihovní soubory se nachází ve složce "_lib". Do aplikace jsou přidané pomocí odkazu z makefile "include ..\_lib\makefile", v asm_sprites.S odkaz "#include ..\_lib\asm.inc" a v include.h odkaz "#include ..\_lib\base.h". Knihovna obsahuje složky: add součet čísel, bits bitové operace, disp zobrazení na textovém displeji, div dělení čísel, func matematické funkce, mul násobení čísel, rand generátor náhody, shift bitové posuvy, video generátor video signálu. V základní složce knihoven naleznete podporu klávesnice, inicializace, čekání, textový displej, eeprom, obsluha souborů, grafický displej a obsluha zvuku. Pro matematické operace můžete sice využít i standardní operace WinAVR, ale bývají často mnohem pomalejší a větší - obzvláště co se týká 64-bitových operací. V souboru common.h naleznete mnohé užitečné definice, společné pro C i assembler- bitové konstanty, barvy, kódy kláves. V souboru base.h jsou definice použité jen v C - definice znaků, datové typy, hlavičky funkcí. Během překladu se ve složce aplikace vytvoří soubor timings.h, ze kterého můžete použít definice pro displej - především konstanty WIDTH a HEIGHT, představující šířku a výšku displeje (resp. videopaměti) ve znacích (sprajtech). V grafickém módu tyto konstanty opět znamenají rozměr ve znacích, tj. políčko 8x8 pixelů.

Během překladu jsou překládány všechny knihovní soubory. Překladač zajistí, že jsou do výsledného kódu zahrnuty jen použité prvky. Použití znamená nejen uvedení funkce v kódu, ale také zavolání kódu z funkce, která nebude vypouštěna, např. z main(). Překlad funkcí tedy nezvětšuje velikost výsledného kódu, pouze zpomaluje překlad. Chcete-li překlad urychlit, můžete zakomentovat nepoužité funkce volané ze souboru makefile (ve složce _lib) - uvedením znaku # na začátku řádku.

Z důvodu mechanismu vypouštění funkcí je každá funkce v assembleru uvedená v samostatném souboru *.S. Zjistí-li totiž překladač, že některá z funkcí má být v kódu použita, zahrne do výsledného kódu celý soubor *.S, ne jen volanou funkci (ve skutečnosti ani neví, které části souboru k funkci patří a které ne). Proto musí být funkce odděleny.

Globální definice:

WIDTH ... šířka displeje ve znacích (sprajtech)
HEIGHT ... výška displeje ve znacích (sprajtech)
Board[] ... video paměť o velikost WIDTH*HEIGHT. Pro textové módy s barevným atributem je rozměr 2* větší. Pro grafický mód obsahuje barevné atributy.
BoardColor[] ... barvy řádků pro textové režimy MONO s celobarevným řádkem (bity 0..3=popředí, 4..7=pozadí)
Graph[] ... bitová grafika v grafickém módu (1 bit = 1 pixel, rozliší zda se zobrazí barva pozadí nebo popředí z pole Board[].
Sprites ... začátek grafických podkladů v ROM (fonty, sprajty)
s32 abs(s32 n) ... absolutní hodnota celého čísla
void Init() ... inicializace ATpadu
B0..B31 ... konstanta představující bit 0..31
BIT(pos) ... makro definující bit 0..31
COLOR(bg,fg) ... sloučení barevných složek pozadí a popředí do barevného atributu

knihovna add

Součet celých čísel bez znaménka, výstupem je u64 (QWORD)

u64 AddQB(u64 num1, u8 num2);
u64 AddQW(u64 num1, u16 num2);
u64 AddQD(u64 num1, u32 num2)
u64 AddQQ(u64 num1, u64 num2)

knihovna bits

Zjištění pořadí nejvyššího bitu (=bitová pozice + 1), binární logaritmus. Číslo 0 vrací 0.

u8 OrderByte(u8 val);
u8 OrderWord(u16 val);
u8 OrderDWord(u32 val);
u8 OrderQWord(u64 val);

Zjištění masky čísla, tj. binární číslo z "1" větší nebo rovno zadanému číslu. Např. 0x123 vrací 0x1FF.

u8 MaskByte(u8 val);
u16 MaskWord(u16 val);
u32 MaskDWord(u32 val);
u64 MaskQWord(u64 val);

knihovna div

Dělení čísel bez znaménka, s různou kombinací rozměru vstupů a výstupů. Parametr "rem" je ukazatel na zbytek po dělení (= modulo), může být NULL.

extern u8 DivBB(u8 num, u8 d, u8* rem);
extern u8 DivB10(u8 num);
extern u8 ModB10(u8 num, u8* quot);
extern u8 DivWBB(u16 num, u8 d, u8* rem);
extern u16 DivWB(u16 num, u8 d, u8* rem);
extern u16 DivWW(u16 num, u16 d, u16* rem);
extern u16 DivW10(u16 num);
extern u8 ModW10(u16 num, u16* quot);
extern u16 DivDWW(u32 num, u16 d, u16* rem);
extern u32 DivDB(u32 num, u8 d, u8* rem);
extern u32 DivDW(u32 num, u16 d, u16* rem);
extern u32 DivDD(u32 num, u32 d, u32* rem);
extern u32 DivD10(u32 num);
extern u8 ModD10(u32 num, u32* quot);
extern u32 DivQDB(u64 num, u8 d, u8* rem);
extern u32 DivQDW(u64 num, u16 d, u16* rem);
extern u32 DivQDD(u64 num, u32 d, u32* rem);
extern u64 DivQB(u64 num, u8 d, u8* rem);
extern u64 DivQW(u64 num, u16 d, u16* rem);
extern u64 DivQD(u64 num, u32 d, u32* rem);
extern u64 DivQQ(u64 num, u64 d, u64* rem);

knihovna mul

Násobení čísel bez znaménka, s různou kombinací rozměru vstupů a výstupu.

extern u8 MulBB(u8 num1, u8 num2);
extern u8 MulB10(u8 num);
extern u16 MulWBB(u8 num1, u8 num2);
extern u16 MulWB(u16 num1, u8 num2);
extern u16 MulWW(u16 num1, u16 num2);
extern u16 MulW10(u16 num);
extern u32 MulDWB(u16 num1, u8 num2);
extern u32 MulDWW(u16 num1, u16 num2);
extern u32 MulDB(u32 num1, u8 num2);
extern u32 MulDW(u32 num1, u16 num2);
extern u32 MulDD(u32 num1, u32 num2);
extern u32 MulD10(u32 num);
extern u64 MulQDB(u32 num1, u8 num2);
extern u64 MulQDW(u32 num1, u16 num2);
extern u64 MulQDD(u32 num1, u32 num2);
extern u64 MulQB(u64 num1, u8 num2);
extern u64 MulQW(u64 num1, u16 num2);
extern u64 MulQD(u64 num1, u32 num2);
extern u64 MulQQ(u64 num1, u64 num2);
extern u64 MulQ10(u64 num);

knihovna shift

Bitový posun celých čísel bez znaménka (Shl vlevo, Shr vpravo).

extern u8 ShlB(u8 num, s8 shift);
extern u16 ShlW(u16 num, s8 shift);
extern u32 ShlD(u32 num, s8 shift);
extern u64 ShlQ(u64 num, s8 shift);
extern u8 ShrB(u8 num, s8 shift);
extern u16 ShrW(u16 num, s8 shift);
extern u32 ShrD(u32 num, s8 shift);
extern u64 ShrQ(u64 num, s8 shift);

knihovna video

Obsluha video výstupu (renderování video signálu).

volatile s16 VLine; ... příští renderovaná videolinka
volatile u16 Frame; ... aktuální snímek (používá se k časování)
u8 DispMode; ... aktuálně vybraný displej VGA, PAL, NTSC
u8 SplitMode; ... aktuální mód displeje (0 normální, 1 dělená obrazovka, 2 dvojnásobná výška řádků, 3 poloviční výška řádků)
u8 Hor; ... horizontální rozlišení ve sprajtech
s16 VVisible; ... počet viditelných videolinek (používá se k zatemnění části obrazu)
s16 VSyncBeg; ... začátek vertikálního synchronizačního pulzu
s16 VSyncEnd; ... konec vertikálního synchronizačního pulzu
s16 VLines; ... celkový počet videolinek

u16 GetVLine(); ... zjištění aktuální video linky
void SetVLine(s16 num); ... nastavení aktuální videolinky
Bool CheckVSync(); ... test zda probíhá vertikální zatemnění
void SetVVisible(s16 num); ... nastavení počtu viditelných videolinek
void SetVSyncBeg(s16 num); ... nastavení začátku vertikálního synchronizačního pulzu
void SetVSyncEnd(s16 num); ... nastavení konce vertikálního synchronizačního pulzu
void SetVLines(s16 num); ... nastavení celkového počtu vertikálních videolinek
void WaitVSync(); ... čekání na vertikální synchronizační pulz
u16 GetFrame(); ... zjištění aktuálního snímku (inkrementuje se každý snímek, používá se jako časovač)
void WaitFrame(); ... čekání na další snímek (používá se jako časovač po 20 ms nebo 16.7 ms)
void WaitFrameNum(u16 num); ... čekání na zadaný počet snímků

knihovna key

Obsluha klávesnice. Indexy tlačítek naleznete v common.h (KEY_1 = B0, ...)

u8 KeyCnt[KEY_NUM]; ... čítače pro detekci stisku tlačítek.
u8 KeyMap; ... mapa stisknutých tlačítek
void KeyLoop(); ... obsluha tlačítek, měla by být volána opakovaně pokud možno každý video snímek
u8 GetKeyMap(); ... zjištění mapy stisknutých tlačítek (bitové pozice KEY_1 atd), nejdříve je potřeba volat KeyIn()
u16 KeyIn(); ... vstup tlačítek (stisk nebo uvolnění), ve vyšším bajtu vrací příznak uvolnění tlačítka KEY_REL; 0=nebyla změna
void KeyFlush(); ... vyprázdnění zásobníku kláves
void KeyAllOff(); ... čekání na uvolnění všech tlačítek

knihovna wait

Obsluha čekání. Čekání probíhá formou čekací smyčky s odpočítáváním taktů procesoru. Je přesné pouze v případě, že neprobíhá žádné přerušení. Probíhá-li obsluha zobrazení na displej, mohou se čekací smyčky zpomalit až 10x. Chcete-li čekání nezávislé na zatížení procesoru, použijte WaitFrame().

void wait1us(); ... prodleva 1 us
void waitus(u16 us); ... prodleva 2 až 65535 us
void waitms(u16 ms); ... prodleva 1 až 65535 ms

knihovna disp

Výstup na textový displej.

u8 Color ... aktuálně vybraná barva (implicitní barva pro textový výstup; bity 0..3=popředí, 4..7=pozadí)
void SetCol(u8 bg, u8 fg); ... nastavení aktuální barvy
void SetFgCol(u8 fg); ... nastavení barvy popředí
void SetBgCol(u8 bg); ... nastavení barvy pozadí

u8* BoardAddr(u8 x, u8 y); ... výpočet adresy ve videopaměti

s16 GetHCycles(); ... počet taktů na horizontální linku
s16 GetHSyncLen(); ... délka horizontálního synchronizačního pulzu
s16 GetVLines(); ... celkový počet vertikálních linek
s16 GetVVisible(); ... počet viditelných vertikálních linek
s16 GetVFreq(); ... vertikální frekvence v Hz * 256
s16 GetVBP(); ... vertikální back porch (mezi vsync a obrazem)
s16 GetVFP(); ... vertikální front porch (mezi obrazem a vsync)
u8 GetVSyncLen(); ... délka vertikálního synchronizačního pulzu
u8 GetRowLines(); ... počet linek na jeden řádek sprajtů
u8 GetSplit(); ... split mód (0 normální, 1 dělený displej, 2 dvojnásobná výška, 3 poloviční výška)
u8 GetHor(); ... počet sprajtů horizontálně

s16 GetViewDefStart() ... implicitní počáteční viditelná linka
s16 GetViewStart(); ... počáteční viditelná linka
s16 GetViewDefHeight() ... implicitní viditelná výška
s16 GetViewHeight(); ... viditelná výška
void SetView(s16 start, s16 height); ... nastavení počátku a výšky viditelných linek
void SetViewRel(s16 start, s16 height); ... nastavení počátku a výšky viditelného obrazu relativně (v 1/1000)
void DispOff() ... vypnutí displeje (pro zrychlení výpočtů)
void DispOn() ... zapnutí displeje
void OpenView(s16 minheight); ... otevření displeje - rozsvícení po dobu 1/3 sekundy
void CloseView(s16 minheight); ... uzavření displeje - zhasnutí po dobu 1/3 sekundy

u8 ConvAsc(u8 ch); ... konverze ASCII znaku na index sprajtu

Následující funkce jsou ve variantách: x = zobrazení s implicitní barvou Color, xCol = se zadanou barvou, xNoCol = bez změny barvy

Zobrazení znaku

void DispChar(u8 x, u8 y, u8 ch);
void DispCharCol(u8 x, u8 y, u8 ch, u8 col);
void DispCharNoCol(u8 x, u8 y, u8 ch);

Opakované zobrazení znaku

void DispCharRep(u8 x, u8 y, u8 ch, u8 num);
void DispCharRepCol(u8 x, u8 y, u8 ch, u8 num, u8 col);
void DispCharRepNoCol(u8 x, u8 y, u8 ch, u8 num);

Zobrazení mezery

void DispSpc(u8 x, u8 y);
void DispSpcCol(u8 x, u8 y, u8 col);
void DispSpcNoCol(u8 x, u8 y);

Opakované zobrazení mezery

void DispSpcRep(u8 x, u8 y, u8 num);
void DispSpcRepCol(u8 x, u8 y, u8 num, u8 col);
void DispSpcRepNoCol(u8 x, u8 y, u8 num);

Zobrazení textu z ROM (text má atribut PROGMEM)

void DispTextROM(u8 x, u8 y, const char* txt, u8 len);
void DispTextROMCol(u8 x, u8 y, const char* txt, u8 len, u8 col);
void DispTextROMNoCol(u8 x, u8 y, const char* txt, u8 len);

Zobrazení textu z RAM

void DispTextRAM(u8 x, u8 y, const char* txt, u8 len);
void DispTextRAMCol(u8 x, u8 y, const char* txt, u8 len, u8 col);
void DispTextRAMNoCol(u8 x, u8 y, const char* txt, u8 len);

Dekódování čísla od konce bufferu OutBuf s koncovou 0, vrací ukazatel na začátek textu.

u8* DecNum(u32 num);
u8* DecNumW(u16 num);
u8* DecNumB(u8 num);

Délka čísla v OutBuf (vstupem je ukazatel na začátek textu z DecNum)

u8 LenNum(u8* text);

Zobrazení čísla zarovnaného doprava (x je pozice posledního znaku)

void DispNumR(u8 x, u8 y, u32 num);
void DispNumRCol(u8 x, u8 y, u32 num, u8 col);
void DispNumRNoCol(u8 x, u8 y, u32 num);

Zobrazení čísla zarovnaného doleva (x je pozice prvního znaku)

void DispNum(u8 x, u8 y, u32 num);
void DispNumCol(u8 x, u8 y, u32 num, u8 col);
void DispNumNoCol(u8 x, u8 y, u32 num);

Zobrazení HEX čísla (počet číslic: 1, 2, 4, 8)

void DispHexN(u8 x, u8 y, u8 n);
void DispHexNCol(u8 x, u8 y, u8 n, u8 col);
void DispHexNNoCol(u8 x, u8 y, u8 n);

void DispHexB(u8 x, u8 y, u8 n);
void DispHexBCol(u8 x, u8 y, u8 n, u8 col);
void DispHexBNoCol(u8 x, u8 y, u8 n);

void DispHexW(u8 x, u8 y, u16 n);
void DispHexWCol(u8 x, u8 y, u16 n, u8 col);
void DispHexWNoCol(u8 x, u8 y, u16 n);

void DispHexD(u8 x, u8 y, u32 n);
void DispHexDCol(u8 x, u8 y, u32 n, u8 col);
void DispHexDNoCol(u8 x, u8 y, u32 n);

Zobrazení dat z RAM v HEX formátu

void DispHexData(u8 x, u8 y, const u8* data, u8 num);
void DispHexDataCol(u8 x, u8 y, const u8* data, u8 num, u8 col);
void DispHexDataNoCol(u8 x, u8 y, const u8* data, u8 num);

Zobrazení HEX dat z DOS sektoru 512 B, off=offset v sektoru (zajistí načtení z SD karty)

void DispHexSect(u8 x, u8 y, u32 sect, u16 off, u8 num);
void DispHexSectCol(u8 x, u8 y, u32 sect, u16 off, u8 num, u8 col);
void DispHexSectNoCol(u8 x, u8 y, u32 sect, u16 off, u8 num);

Vymazání obrazovky

void DispClear();
void DispClearCol(u8 col);
void DispClearNoCol();

void SetDispCol(u8 col); ... Nastavení barvy celé obrazovky a nastavení implicitní barvy (znaky nemaže)
void SetRowCol(u8 y, u8 col); ... Nastavení barvy jednoho řádku
void SetDispMode(u8 dispmode); ... Reinicializace módu displeje

knihovna eeprom

Obsluha EEPROM paměti (ukládání konfigurace programů). Každý program používá své 16-bitové číslo MAGIC k označení konfigurace. Čísla 0, 1 a 0xFFFF jsou rezervována pro systém. Konfiguračních dat může být 6 bajtů. sConfig (v eeprom.h) je konfigurační struktura.

u16 ConfigFind(u16 magic); ... vyhledání konfiguračního záznamu (vrací offset v EEPROM, -1=nenalezeno)
Bool ConfigRead(void* config); ... načtení konfiguračních dat (False=nenalezeno)
Bool ConfigVerify(const void* config, u16 off); ... verifikace konfiguračních dat (False=nesouhlasí)
Bool ConfigWrite(const void* config); ... zápis konfiguračních dat
sConfig_Loader ConfigLoader; ... konfigurační záznam boot loaderu
void ReadConfigLoader(); ... načtení konfigurace boot loaderu a nastavení módu displeje

knihovna file

Obsluha souborů. Souborové funkce v ATpad používají menší velikost sektorů SECT_SIZE než standardní 512 B, kvůli omezené velikosti RAM (pro ATmega8 je to 64 bajtů). SD karty vyžadují přístup po 512 bajtech - ATpad načítá jen potřebnou část fyzického sektoru, zbytek zahazuje. Proto je čtení z SD disku pomalejší než by mohlo být. Sektory se načítají do bufferu DiskBuf.

void FileOpen(sFile* file, u16 sclust); ... otevření souboru nebo adresáře se zadáním počátečního clusteru (=alokační blok)
Bool FileSeek(sFile* file, u32 off); ... posun ukazatele v souboru nebo adresáři
s16 FileReadSect(sFile* file, u32 off); ... načtení sektoru do DiskBuf (soubor/adresář musí být otevřený s FileOpen)
Bool FileRead(sFile* file, u32 off, void* buf, s16 len); ... načtení otevřeného souboru do bufferu v RAM

knihovna func

Matematické funkce - základní goniometrické funkce.

Celočíselný sin/cos. Vstupem je relativní úhel v rozsahu 0 až 255. Hodnota úhlu 0 až 256 odpovídá úhlu 0 až 90 stupňů. Výstupem je relativní číslo 0..255, představující hodnotu 0 až 1.

u8 SinB(u8 angle);
u8 CosB(u8 angle);

sin/cos v plném rozsahu. Vstupem je číslo 0..255 představující úhel 0..360 stupňů. Výstupem je hodnota -127 až +127, odpovídající hodnotě -1..+1.

s8 SinBFull(u8 angle);
s8 CosBFull(u8 angle);

knihovna graph

Obsluha grafického displeje - bitová mapa s barevnými atributy, 1 atribut je přiřazen políčku 8x8 pixelů. Definici barevného módu "colormode" naleznete v graph.h - zobrazení bez změny barvy, se zadáním barvy, nastavení pixelu, nulování pixelu, změna pixelu. Kreslicí funkce nekontrolují přetečení hranic displeje.

void DrawPixel(u8 x, u8 y, u8 colormode, u8 col); ... vykreslení pixelu
void DrawLine(u8 x1, u8 y1, u8 x2, u8 y2, u8 colormode, u8 col); ... vykreslení linky
void DrawBox(u8 x, u8 y, u8 w, u8 h, u8 colormode, u8 col); ... vykreslení obdélníku

knihovna sound

Obsluha zvukového výstupu. Je-li to možné, používejte k výstupu jednoduchých tónů pouze funkci Beep. Funkce pro přehrátí melodie Play je náročná na spotřebu paměti ROM.

void Beep(u16 f, u8 len); ... přehrátí tónu, f=časová konstanta (tón závisí na horizontální frekvenci displeje), len=délka ve snímcích
Bool Playing(); ... test zda probíhá přehrávání melodie (zadané příkazem Play)
void WaitPlaying(); ... čekání na ukončení přehrávání melodie
void PlayLoop(); ... obsluha přehrávání melodie (mělo by být voláno periodicky z hlavní smyčky)

Přehrátí melodie z ROM (zadané jako text s atributem PROGMEM). Syntaxe textu:
On ... nastavení bázové oktávy n=0..7
Ln ... nastavení implicitní délky n=0..7
+ ... zvýšení oktávy pro následující 1 notu
- ... snížení oktávy pro následující 1 notu
C, C#, D, D#, E, F, F#, G, G#, B (nebo H) ... přehrátí noty, může následovat číslice 0..7 udávající délku, tečka prodlouží o polovinu
R ... přehrátí pauzy, může následovat číslice 0..7 udávající délku, tečka prodlouží o polovinu
n ... číslice 0..7 následující za notou nebo pauzou udává délku noty
. ... tečka následující za notou nebo pauzou (a příp. číslicí délky) prodlouží délku o polovinu

void Play(const char* melody); ... přehrátí melodie zadané jako text v ROM (atribut PROGMEM)

knihovna rand

Generátor náhody.

u32 RandSeed; ... náplň generátoru náhody
void SetRandSeed(u32 seed); ... inicializace generátoru náhody
u32 RandShift(); ... posun generátoru náhody o 1 krok (navrací novou hodnotu RandSeed)

Výpočet náhodného čísla bez znaménka

u8 RandByte();
u16 RandWord();
u32 RandDWord();
u64 RandQWord();

Výpočet náhodného čísla se znaménkem

s8 RandChar()
s16 RandShort()
s32 RandInt()
s64 RandLong()

Výpočet náhodného čísla bez znaménka, v rozsahu 0 až max (včetně zadané hraniční hodnoty)

u8 RandByteMax(u8 max);
u16 RandWordMax(u16 max);
u32 RandDWordMax(u32 max);
u64 RandQWordMax(u64 max);

Výpočet náhodného čísla se znaménkem, v rozsahu 0 až max (včetně zadané hraniční hodnoty, max může být negativní)

s8 RandCharMax(s8 max);
s16 RandShortMax(s16 max);
s32 RandIntMax(s32 max);
s64 RandLongMax(s64 max);

Výpočet náhodného čísla v zadaném rozsahu min až max (včetně zadaných hraničních hodnot). Je-li min > max, generuje se číslo vně intervalu.

u8 RandByteMinMax(u8 min, u8 max);
u16 RandWordMinMax(u16 min, u16 max);
u32 RandDWordMinMax(u32 min, u32 max);
u64 RandQWordMinMax(u64 min, u64 max);
s8 RandCharMinMax(s8 min, s8 max);
s16 RandShortMinMax(s16 min, s16 max);
s32 RandIntMinMax(s32 min, s32 max);
s64 RandLongMinMax(s64 min, s64 max);

void Randomize(); ... inicializace generátoru náhody číslem z EEPROM. Mělo by být voláno pouze 1x při startu aplikace. Funkce zajistí, že při příštím spuštění bude mít aplikace jiný výchozí stav generátoru náhody.

knihovna boot

Funkce rezidentního bootovacího zavaděče. Zavaděč začíná na adrese BootStart, což odpovídá adrese resetovacího vektoru. U ATmega8 je to adresa 0x1800 (offset 6 KB). Pozor, boot loader nepoužívá fyzické sektory 512 bajtů (jak vyžadují SD karty), ale používá menší sektory SECT_SIZE (z důvodu omezené RAM, typicky 64 bajtů). Položky odvolávající se na sektory jsou přepočítány na logické sektory.

Data boot loaderu v RAM

u8 DiskBuf[SECT_SIZE]; ... diskový buffer (sem se načítá logický sektor z SD disku)
u32 DiskBufSect; ... aktuální logický sektor načtený v DiskBuf (-1 = není)
u16 RootNum; ... počet položek v ROOT adresáři
u16 ClustSizeSect; ... velikost clusteru v počtu logických sektorů
u32 FatBase; ... logický sektor začátku FAT
u32 RootBase; ... logický sektor začátku ROOT adresáře
u32 DataBase; ... logický sektor začátku dat
u16 FileClust; ... počáteční cluster aktuálně spouštěného programu
u16 DirClust; ... počáteční cluster adresáře se spouštěným programem
u16 FileInx; ... index spouštěného programu v adresáři
u8 ClustSizeSectBits; ... počet bitů vyjadřující velikost clusteru v počtu sektorů (0=1 sektor)
u8 SDType; ... typ SD karty

Data na začátku boot loaderu (jsou v ROM, tedy atribut PROGMEM)

const u8 BootVer PROGMEM; ... verze boot loaderu (bity 7..4 major číslice, bity 3..0 minor číslice)
const u8 BootVar PROGMEM; ... varianta procesoru (bit 7..4 velikost ROM v KB, 3=8KB...7=128KB, bit 3..0 alternativa MCU)
const u8 BootFile[8] PROGMEM; ... jméno startovaného boot loaderu ("BOOT")
const u8 BootExt[4] PROGMEM; ... přípona jména načítaných programů

Funkce boot loaderu

void BootReset(); ... reset boot loaderu
void SDInit(); ... inicializace SD karty
Bool SDConnect(); ... připojení SD karty
void SDDisconnect(); ... odpojení SD karty
Bool SDReadSect(u32 sector, u8* buffer); ... načtení sektoru z SD karty
u8 SDSendCmd(u8 cmd, u32 arg); ... odeslání povelu na SD kartu
void SDSel(); ... zapnutí výběru SD karty
void SDUnsel(); ... vypnutí výběru SD karty
u8 SDByte(u8 data); ... příjem a vyslání bajtu na SD kartu (vyšlete 0xFF chcete-li jen číst)
void DiskInit(); ... inicializace obsluhy disků (předtím volat SDInit())
extern Bool DiskMount(); ... mountování disku
extern void DiskUnmount(); ... odmountování disku
void DiskExecFile(u16 clust, u32 size); ... spuštění programu zadaného počátečním clusterem a velikostí
Bool DiskReadFile(u16 clust, u32 off, u16 num, u16 addr, u8 mem); .... načtení souboru do ROM, RAM, EEPROM
void DiskWriteMem(u16 addr, u8 off, u8 len, u8 mem); ... zápis dat z DiskBuf do ROM, RAM, EEPROM
Bool DiskMoveBuf(u32 sect); ... přesun okna v DiskBuf na zadaný sektor
Bool DiskClustValid(u16 clust); ... kontrola platnosti clusteru
u32 DiskClustSect(u16 clust); ... přepočet clusteru na logický sektor
u16 DiskReadFat(u16 clust); ... čtení položky FAT pro zadaný cluster
u8 DiskGetByte(u32 sect, u16 off); ... načtení bajtu z DOS sektoru (sect je fyzické číslo sektoru 512 B, off je offset v sektoru)
u8 DiskCheckFS(u32 sect); ... kontrola FAT souborového systému (sect je fyzické číslo sektoru 512 B)
void SpmWait(); ... čekání na ukončení SPM zápisu
void SpmCmd(u8 cmd); ... provedení instrukce SPM
void SpmWrite(void* dst, void* src); ... zápis SPM stránky do ROM
void EEWait(); ... čekání na ukončení zápisu do EEPROM
u8 EERead(u16 addr); ... čtení bajtu z EEPROM
void EEWrite(u16 addr, u8 data); ... zápis bajtu do EEPROM
void EEWriteData(u16 dst, const void* src, u16 num); ... zápis dat do EEPROM
void MemCpy(void* dst, const void* src, u16 len); ... kopie dat v RAM

Videomódy

V knihovně "video" je k dispozici 12 předdefinovaných videomódů. Je sice možné vytvořit si své vlastní videomódy, ovšem vyžadovalo by to úpravu programu ATpad_timings, který se používá k výpočtu časování renderovacích funkcí.

Horizontální rozlišení videomódu závisí na frekvenci použitého krystalu. Program pro výpočet časování kontroluje během překladu překročení hranic, v tom případě ohlásí chybu a překlad se přeruší. Kontrolují se hranice mezi horizontálními synchronizačními pulsy, ne zobrazitelnost. Skutečná zobrazitelná část je o něco menší než vzdálenost mezi pulzy a je potřeba zkontrolovat zkouškou. Obzvláště malé přenosné televizory ořezávají obraz značně.

(0) MODE_ASCMONO6 - mono ASCII text 6x8 pixelů. Tabulka znaků používá jen první polovinu, tj. nižších 128 znaků. Ze znaků se zobrazí jen 6 pixelů na lince. K jednotlivým znakům nelze přiřazovat barvu. Ovšem lze nastavovat barvu pro celý řádek najednou. Tento režim je velmi úsporný jak k paměti ROM (tabulka znaků spotřebuje 1 KB), tak i k paměti RAM. Oproti následujícímu módu (s 8 pixely) umožňuje zobrazit více znaků na řádek.

(1) MODE_ASCMONO8 - platí stejné jako u předešlého módu, jen znaky jsou širší (8 pixelů místo 6 pixelů) a tak se na řádek displeje vejde o něco méně znaků.

(2) MODE_MONO6 - liší se od režimu ASCMONO6 tím, že k dispozici je všech 256 znaků. To je náročnější na paměť ROM (tabulka znaků spotřebuje 2 KB).

(3) MODE_MONO8 - liší se od režimu ASCMONO8 tím, že k dispozici je všech 256 znaků. To je náročnější na paměť ROM (tabulka znaků spotřebuje 2 KB).

(4) MODE_ASCTEXT6 - barevný ASCII text 6x8 pixelů. Tabulka znaků používá jen první polovinu, tj. nižších 128 znaků, tabulka znaků tak zabere jen 1 KB ROM. Ze znaků se zobrazí jen 6 pixelů, to umožní zobrazit více znaků než font 8x8. Ke každému znaku lze přiřadit barevný atribut (ve videopaměti se střídají znaky s barevnými atributy) - za cenu 2x vyšší spotřeby paměti RAM oproti MONO videomódu.

(5) MODE_ASCTEXT8 - od předešlého módu se liší použitím znaků 8x8 pixelů (na řádek se vejde o něco méně znaků)

(6) MODE_TEXT6 - od režimu ASCTEXT6 se liší plnou tabulkou 256 znaků (náročnější na ROM, tabulka znaků zabere 2 KB)

(7) MODE_TEXT8 - od režimu ASCTEXT8 se liší plnou tabulkou 256 znaků (náročnější na ROM, tabulka znaků zabere 2 KB)

(8) MODE_TILE6 - barevné dlaždice (sprajty) 6x8 pixelů. Ve video-RAM jsou indexy do pole dlaždic. Tímto způsobem lze nadefinovat plně barevné dlaždice. Vhodnou přípravou sprajtů lze zajistit i animace. Ovšem dlaždice jsou velmi náročné na paměť ROM (1 dlaždice zabere 28 bajtů).

(9) MODE_TILE7 - barevné dlaždice 7x8 pixelů. Paměťové nároky jsou stejné jako u následujícího režimu 8x8 pixelů (1 dlaždice zabere 32 bajtů), výhodou je o něco větší počet sprajtů na řádek.

(10) MODE_TILE8 - barevné dlaždice 8x8 pixelů. 1 dlaždice zabere v ROM 32 bajtů.

(11) MODE_GRAPH - grafický mód s barevnými atributy (ve stylu grafiky ZX Spectrum). Velmi náročné na RAM. V poli Graph je bitová mapa. Každý 1 bit představuje 1 pixel na obrazovce a přepíná, zda se zobrazí barva pozadí nebo popředí. Pole Board obsahuje barevné atributy s barvou popředí a pozadí. Každý atribut přináleží políčku 8x8 pixelů.

Nedostatky a chyby

Downloady

Ukázkové aplikace (přeložené pro ATmega8, 88 a 328p, frekvence 16/20/24/27 MHz)

Zdrojové kódy boot loaderu a aplikací

Potisky krabičky

Schéma zapojení v Eagle Free

Grafické podklady (schéma a plošný spoj)

Kompletní download podkladů ATpad (včetně www stránky)

Použité součástky

Výběr součástek byl uzpůsoben na prodejnu GM Electronics, kterou mám blízko

Součet ceny za vše je 432 Kč (včetně fotocuprextitu, krabičky a zástrčky mini-din).

Prototyp verze 1

Výše uvedená verze ATpad je již 3. prototypovou verzí. První prototyp (ATpad verze 1) měl ale také zajímavé vlastnosti, které by mohly posloužit k inspiraci pro další vývoj. Čím se lišil:

Miroslav Němeček

<< Zpět