2015. augusztus 23., vasárnap

Néhány tapasztalat az FTDI EVE FT800 grafikus chippel (1. rész)

Az elmúlt, idestova két év alatt néhányszor volt szerencsém "küzdeni" a címbeli áramkörrel. Az így szerzett érdekesebb tapasztalataimat vagy ötleteimet osztom meg, több bejegyzésben.

Aki nem ismerné az FT80x családot, annak előtte mindenképpen érdemes az FTDI EVE anyagok között olvasgatni. Aki inkább a videókat kedveli, van itt néhány a sok közül, lehet válogatni. Nekem a Gameduino 2 a kedvencem.

Az FT800 Programmer Guide kicsit döcögősen alakult azzá, amivé mára vált. Amikor elkezdtem a gyári fejlesztői áramkörrel és egy 4.3"-es reszisztív TFT-vel barátkozni az említett Guide alapján, hát... elég nehezen fogtam fel az egésznek a logikáját. Ma már azért sokat tisztult a kép a fejemben, meg a leíráson is javítottak, továbbá jóval több a bevezető jellegű, értelmes leírás és példaprogram is.

Időközben megjelent néhány ingyenes gyári szoftver is, ami jócskán megkönnyíti a képernyőképek grafikus tervezését. Az egyik ilyen szoftver a Screen Editor, a másik a Screen Designer. Tervezem a részletes bemutatásukat egy következő bejegyzésben. Persze, aki ennél többet akar, annak pl. a MikroElektronika kínálja a Visual TFT fejlesztői rendszert - persze nem ingyen.

2014 elején még némi nehézséget jelentett egy Atmel megaAVR-ekhez használható, működő FT800-as library beszerzése. Az FTDI gyári minta alkalmazása illetve annak megfejtése számomra sok órás keresztrejtvény fejtéssel volt egyenlő a több platformos hardver absztrakciós réteget tartalmazó forrásprogram miatt. A hócipőm is tele volt már vele, nem is tagadom!

További nehézséget jelentett, hogy én a HP InfoTech CodeVisionAVR fejlesztői rendszerét használom, ami némileg különbözik a GNU licenc alatti AVR GCC-től. De aki keres, az talál! Így jött a képbe Guillaume Smolders GitHub-os FT800 Library-ja (köszönet érte). Na ez átlendített a holtponton, ennek nyomán hamarosan megszületett a saját adaptációm, amit azóta is csiszolgatok, bővítgetek.

Emlékeztetőül, röviden: szoftveres szempontból az FT80x chip kezelése egyszerű macro-szerű vagy kicsit összetettebb tényleges függvényekkel történik. A függvények rendelkezhetnek bemenő paraméterekkel és/vagy függvényértékkel. Többek között vannak a hardvert (pl. órajel, szinkronjelek, stb.), a hangot, a megjelenési környezetet (pl. háttér vagy előtér színe), és az egyes ú.n. primitíveket és widgeteket (én utóbbiakat az egyszerűség kedvéért komponenseknek hívom) beállító függvények (pl. egy gomb, vagy egy folyamatjelző).

Csak nagyon egyszerű esetben, leginkább az FT80x programozás tanulásakor érdemes fix értékekkel ellátott ú.n. Display List-eket létrehozni, mert az így "bevasalt" értékeket nem lehet programfutás közben megváltoztatni. Ilyen tipikusan egy nyomógomb megnyomásakor látható 3D hatás (a gomb érintéskor "benyomódik", majd elengedéskor "felugrik"). Helyette minden módosítandó értéket változókba érdemes elhelyezni, amelyek értékét egy önálló megjelenítő függvény írja majd be a chip megfelelő regisztereibe. A jó átláthatóság érdekében viszont érdemes egy komponens összes paraméterét egy egységbe összefogni. Igaziból erre (is) lennének jók az egyes komponens osztályok az ő tulajdonságaikkal...

A  CvAVR nem objektum orientált C++, hanem csak sima ANSI C fejlesztést enged meg. Ezért osztályok helyett előszeretettel használok struktúrákat, amikkel többek között jól össze lehet fogni az FT80x EVE grafikus primitíveinek, komponenseinek a tulajdonságait, állapotát, stb. Aki az ingyenes Atmel Studiót használja és ismeri a C++-t, meg is valósíthatja (az Arduino részére az FTDI ad C++ támogatást, de tudtommal az Atmel Studio részére nem).

Egy kicsit is összetettebb képernyőt azonban már kezelni, kiszolgálni kell.

A feladatok "ütemezéséhez" nem használok FreeRTOS-t, hanem állapotgépet. Az egyes állapotokat egy végtelen ciklusban elhelyezett függvény elemzi és azután intézkedik az éppen aktuális állapot szerint.

Ha már itt tartunk, a megjelenítéshez nálam tipikusan négy függvény tartozik, amelyek közül:

  1. az első függvény az adott képernyőkép megjelenítéséért felelős. A képernyőn általában vannak statikus (mindig egyformán látható, például főcím vagy ablakcím) és dinamikus (helyzettől függően látható és/vagy tulajdonságú, például gomb, szövegmező, stb.) komponensek. A megjelenítő függvény minden komponenst tartalmaz, ami csak az adott képernyőn előfordulhat. Az, hogy éppen mi látszik, az adott komponens struktúrájában egy visible nevű struktúra tag értéke határozza meg egy if feltételeként (FALSE vagy TRUE). A megjelenítő függvény neve mindig disp_xxx_yyy(), ahol a disp a megjelenítésre utal, a többi az egyéb feladatra. Például: disp_menu_main(), vagy disp_menu_treatments(), de ilyen lehet a disp_msg_error() függvény is;
  2. egy init_task_yyy() függvény (pl. init_task_treatment), amely többek között a feladat (taszk) változóinak, a hardvernek, stb. az inicializálását végzi el . Itt hívódik meg az yyy taszkhoz tartozó nyitó képernyő is, amelynek a neve a fenti disp_xxx_yyy (pl. disp_menu_treatment);
  3. egy run_task_yyy() függvény (pl. run_task_treatment), ami többek között az "eseményeket" (képernyő érintés, időzítés és számlálás eredménye, hardver állapot, stb.) kezeli, szükség szerint beállítja a megjelenítéshez tartozó komponensek állapotát, majd meghívja a hozzá tartozó disp_xxx_yyy() függvényt;
  4. végül egy done_task_yyy() függvény (pl. done_task_treatment), ami többek között befejezi az adott feladatot, szükség szerint módosítja a kijelzés paramétereit és végül megjeleníti a kilépő képernyőképet a disp_xxx_yyy() függvénnyel;

Egy interaktív érintőképernyős programban döntő szerep jut a képernyő érintések megfelelő kezelésének. A rezisztív érintőképernyő (FT800 chippel) mindössze egyetlen pont érintését képes helyesen kiértékelni, míg a kapacitív érintőképernyő (FT801 chippel) akár öt pontos érintést is.

A következő részben a rezisztív érintőképernyő kezelésről szeretnék írni, mert bizony itt futottam bele egy olyan fura jelenségbe, amit csak nehezen tudtam elhárítani, ez pedig a prel-szerű hatás...


2015. január 22., csütörtök

CodeVisionAVR

Ebben a bejegyzésben szeretném röviden ismertetni az Atmel 8-bites AVR-einek (tiny, mega és xmega) egyik szoftverfejlesztő eszközét, a CodeVisionAVR-t.

A szoftver 32 és 64-bites Windows-ok alatt fut (XP-től felfelé), a bejegyzés írásakor éppen a 3.18-as verzió a legfrissebb. Jómagam már több, mint 10 éve használom a különféle verziókat és el kell mondanom, hogy Pavel Haiduc lelkiismeretesen javítja az esetleges hibákat, fejleszti a rendszert.

De mit is tud ez a szoftver?

Ez egy C forrásprogramokat lefordítani és összeállítani képes, ANSI C-vel kompatibilis compilert tartalmazó IDE, amely képes arra is, hogy C függvényekben akár assembly utasításokat is használjunk. Ez utóbbi nagyon hasznos, ha speciális, például nagy sebességű szubrutinokat kell elkészítenünk.

A forrásprogram több fájlból is állhat, amelyeket projektbe szervezve lehet együtt kezelni. A fordító-szerkesztő elég gyors, működése, optimalizálása és egyéb tulajdonságai akár az IDE megfelelő menüin keresztül, akár a forrásprogramba a megfelelő helyeken beírt ú.n. pragmákkal beállítható, szabályozható.

A forrásprogram előállításához szerintem mindenképpen érdemes használni a beépített automatikus programgenerátort, amely vizuálisan segít a kiválasztott mikrokontroller minden hardver elemét beállítani, kezdve az órajeltől az I/O portokon át az utolsó timerig. Ez a kiváló eszköz különösen az xmega családnál jön kapóra, ahol tényleg el lehet tévedni a rengeteg regiszterben, bitben és bitcsoportban! Jómagam mindig használom, ez volt az egyik oka annak, hogy végül ezt a szoftverfejlesztő eszközt vásároltam meg.

A "varázslóval" előállított konfiguráció elmenthető, bármikor visszatölthető, módosítható, stb. Ebből azután generálhatunk egy C forrás fájlt, amit már "csak" a feladathoz szükséges részekkel kell bővíteni és kész is vagyunk!

A lefordított és a mikrovezérlőbe letölthető Intel HEX fájl mellett az Atmel Studióval debugolható COFF fájl is készül. Mivel a 3.x verziótól felfelé a CodeVisionAVR képes az Atmel Studio keretrendszerbe beépülni, a hibakeresés még könnyebbé vált, mint a korábbi verziókban (amilyen még nekem is van). Az Atmel Studio  hibakereső funkciójának rövid ismertetése önmagában is megtölthetne egy egész bejegyzés, ezért erre most nem térek ki.

Fontos még kiemelni a CodeVisionAVR szerintem igen kényelmes függvénykönyvtárait, amelyekkel tényleg könnyedén lehet I2C, SPI, de akár alfanumerikus vagy grafikus kijelzőket is kezelni. Jómagam az USB könyvtárak kivételével már mindegyiket kipróbáltam és meg vagyok velük elégedve.

Ami nem igazán tetszik az, hogy a programgenerátor által elkészített forrás megjelenési formája, azaz a tördelések, behúzások, néha nagyon hosszú programsorok nekem zavaróak, eltérnek attól, amit én szeretek használni. Zavar még az is, hogy az egyes hardver egységekhez tartozó programrészeket nem teszi különálló függvényekbe, esetleg fájlokba, hanem az összes kódsort egyben "ledarálja". Sajnos, ez így "bele van drótozva" a szoftverbe, tehát nincsenek módosítható kódsablonok - a felhasználó eszi vagy nem eszi, nem kap mást!

Végül a minőség/ár aránya szerintem a legjobb a 8-bites AVR fejlesztői rendszerek piacán. Aki már végigverekedte magát például egy ATxmega128A1U inicializáló kódján, az tudja csak igazán becsülni a kódvarázsló munkáját - legyen akár kicsit csúnyácska is a végeredmény!