Tento displej se připojuje k počítači sériově přes SPI, ovšem nenabízí jen jedno SPI rozhraní, ale rovnou tři!
První SPI je pro obrazová data, je na pinech na levé hraně, v dolní části. Druhé SPI rozhraní je pro dotykovou vrstvu a je taktéž na pinech vlevo, ale na horních pěti (označených TOUCH). A poslední SPI rozhraní je pro čtečku SD karet a je vyvedeno na obrázku vpravo (který jsem trošku moc ořízl, takže ty vývody nejsou vidět).
SPI sběrnice umožňuje připojit několik slave zařízení naráz, takže jsem logicky propojil SDI (MOSI) s T_DIN, SDO (MISO) s T_DO a SCK s T_CLK. A pak jsem to zkoušel rozjet na třech různých mikrokontrolérech: Arduinu, STM32F103 a ESP8266.
Ještě než napíšu jak jsem dopadl, musím zdůraznit, že displej je prodejcem inzerován jako "5V/3.3V", což může kvalitně zmást. Pravda je, že napájení (VCC) může být 3,3 nebo 5 V, protože zespodu displeje je lineární regulátor napětí nastavený na 3,0 V. Dokonce bych řekl, že je lepší, když je displej napájený 5 V, protože se mi choval stabilněji, ale možná se mi to jen zdálo (v nepájivém kontaktním poli často zlobí jednotlivé drátky a výsledky pokusů nejsou zrovna směroplatné). Pokud ho napájíme jen 3,3 V, ze kterých si ten regulátor uzobne 0,3 V pro sebe, tak pak displej může dostat i méně než 3 V a nepracuje se mu možná tak dobře. Na to jsou tam ostatně ty dvě pájecí plošky hned pod regulátorem, které můžeme páječkou jednoduše propojit, čímž regulátor vyřadíme z cesty a displej pak má plných 3,3 V.
Zároveň ten prodejcův příslib "5V/3.3V" neznamená, že kterákoliv ze tří SPI sběrnic je 5V tolerantní! Proto pokud připojujeme displej k 5V mikrokontroléru, jakým je například Arduino, musíme zařadit do SPI cesty "level shifter", měnič napěťových úrovní, jinak bychom mohli něco v displeji usmažit. Jako převodník poslouží například obvod CD4050E nebo některý z hotových prodávaných modulů osazených MOSFET tranzistory.
Mimochodem, podsvícení displeje (pin označený jako "LED") funguje stejně dobře na 3,3 V i na 5 V a nevidím tam ani rozdíl v úrovni podsvícení.
Ještě pár slov k použitým knihovnám. Přestože je komunikace s XPT2046 poměrně jednoduchá, neztrácel jsem čas psaním vlastní knihovny, a místo toho jsem si našel již hotová řešení (a pak ztrácel čas s nimi). První knihovnu pro své Teensy napsal Paul Stoffregen a je dostupná pod názvem XPT2046_Touchscreen na https://github.com/PaulStoffregen/XPT2046_Touchscreen. Druhá je od Spirose Papadimitrioua https://github.com/spapadim/XPT2046 a na rozdíl od první vyžaduje zapojení i pinu T_IRQ. Třetí je od Bodmera https://github.com/Bodmer/TFT_Touch/ a nepoužívá hardwarovou SPI sběrnici mikrokontroléru, takže může být připojena na kterékoliv piny a obslouží si je ručně. To jsem zprvu považoval za nevýhodu a knihovnu tak vyřadil z dalších testů, ovšem dnes už to vidím trošku jinak...
Jako grafickou knihovnu pro ILI9341 jsem použil velmi známou Adafruit_GFX se svým Adafruit_ILI9341 ovladačem. Adafruit podporuje už nejen Arduino, ale i ESP8266, takže se mi zdálo super, že použiju jednu knihovnu pro všechny tři mikrokontroléry.
Nyní už tedy jak jsem dopadl: první testy probíhaly na ESP8266. Tam XPT2046_Touchscreen nefungoval při testech vůbec. Ladicí hlášky ukazovaly, že vrací nesmyslně vysoké hodnoty tlaku (od 4 do 8 tisíc) a hodnoty polohy pochodovaly v cyklu v celém ADC rozsahu. Zkusil jsem tedy knihovnu XPT2046 a ta nefungovala taktéž, přestože podle pěkného článku na http://nailbuster.com/?page_id=341 fungovat měla. Asi se ty knihovny nějak nepohodly o právo komunikace na sběrnici, nebo jedna nastavila rychlost, které druhá nestačila nebo něco podobného. Nakonec pomohlo vyměnit grafickou knihovnu od Adafruitu za upravenou verzi zvanou "Adafruit_ILI9341esp" (která je ke stažení na výše uvedeném článku) a pak se vše perfektně rozběhlo. Bohužel jsem nebyl sto na první pohled poznat, co je v té "ILI9341esp" verzi změněno tak, že XPT2046 už s ní nekoliduje (neboť tam bylo příliš mnoho rozdílů), ale neměl jsem dost času, tak jsem to přestal řešit a smířil se s tím, že stačí použít "esp" verzi grafické knihovny a dotyková vrstva funguje (resp. ta daná knihovna pak správně komunikuje).
Další testy proběhly na ARMu STM32F103 - resp. na Maple Mini. Použil jsem "plugin" z www.stm32duino.com, který se "zasune" do Arduino IDE 1.6.x. Díky tomu mi přijela i opět jaksi upravená knihovna Arduino_ILI9341_STM, kterou jsem zkusil a fungovala výborně (asi 20x rychleji než na Arduinu nebo ESP8266). K ní jsem zkusil přidat obě výše zmíněné XPT2046 knihovny, ale dle očekávání žádná nefungovala. Pro sdílení SPI mezi dvěma různými zařízeními jsou totiž potřeba SPI transakce, které ale moje (starší?) verze STM32 "pluginu" pro Arduino IDE nepodporovala. Takže konec, žádné dotyky. Ovšem teď zpětně si říkám, že jsem měl použít tu knihovnu od Bodmera a jednoduše připojit TOUCH piny k některým z 30 volných pinů STM32F103...
Poslední na řadu přišlo Arduino Pro Mini: knihovna XPT2046_Touchscreen fungovala ihned, ale vracela hodnoty otočené o 90 stupňů, nebo prostě prohozené osy X a Y. Chvíli mě to bavilo, ale pak jsem raději přešel na knihovnu XPT2046, která se mi osvědčila na ESP8266. Tady ovšem nefungovala a ještě navíc rozbila kreslení obrazu. Asi se ty dva čipy porvaly o SPI sběrnici jako na ESP8266.
O správném připojení a ovládání více zařízení na jedné SPI sběrnici napsal pěkný článek výše už zmíněný Paul - http://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps. Zkusil jsem upravit knihovnu XPT2046 podle jeho rad: nejdřív jsem do ní přidal podporu transakcí, a když to nestačilo, tak jsem ještě korektně předinicializoval obě CS linky, jak Paul doporučuje.
Přesto příklad kreslicí aplikace XPTPaint (v "examples" u XPT2046) pořád nefungoval, než jsem s úžasem zjistil, že v jedné ose vrací knihovna hodnoty od 0 do 20 a pak naráz skáče až na 56738 a až ke druhé straně obrazovky drží tento nesmyslný ofset (který nevím, kde se bere). Z nedostatku času jsem to vyřešil následujícím hackem (přidáním jednoho řádku do aplikace XPTPaint):
touch.getPosition(x, y);
if (x > 56730) x -= 56710; // WTF!?
Od té chvíle fungovalo na Arduinu s Adafruit_ILI9341 a XPT2046 vše v pořádku a mohl jsem nehtem malovat jak na malířském plátně.
Měl bych teď, po správné implementaci transakcí do XPT2046, ji znovu zkusit na ESP8266 s jinými ILI9341 knihovnami, ale nevím, kdy se k tomu dostanu. Taktéž bych měl zjistit, kde se na Arduinu bere ten nesmyslný ofset (možná přeteče nějaká proměnná?). A také bych měl zkusit pohledat na stm32duino.com, jestli už nemají SPI s transakcemi. Hmmm, napíšu, jestli se k něčemu z toho někdy dostanu.