A Google elhatározta, hogy támogatni fogja az elektronikus
kiegészítők (accessory-k) kapcsolását az Android készülékekhez. Ehhez egy Android Open
Accessory Development Kit (ADK) kiadásával járult hozzá, amely USB-s
kiegészítők kapcsolódását támogatja 2.3.4 verzió fölött. No de mi is ez az
egész, és mire is jó?
Ahhoz, hogy egy külső hardver eszközt vezérelni tudjunk
Android alatt, szükség van valami szabványos kapcsolódási módra, amivel a
hardvert az Androiddal össze tudjuk kötni. Természetesen több lehetőség van
(Bluetooth, USB, WiFi, bizonyos készülékeknél soros interfész) de egyik módszer
sem egyszerre univerzális, egyszerű, olcsó és felhasználóbarát. Ezen kívül szükség van egy könnyen kezelhető
API-ra, ami lehetővé teszi az egyszerű és gyors fejlesztést.
Az ADK tehát szabványos USB kapcsolódási lehetőséget és API
támogatást nyújt Android kiegészítő (accessory) üzemmódban kapcsolódó kütyük
vezérlésére. Az ADK kiadásával egyidejűleg
természetesen kiadtak egy referencia platformot is, ami egy népszerű Arduino modulra épül. Az ADK használhatósága
persze nem korlátozódik erre a modulra, már több alternatív platformot is
bejelentettek. A referencia platform tulajdonképpen két részből áll: egy
Arduino Mega 2560 formátumú mikrokontroller kártyából (bal oldal) és egy „demo
shield” elnevezésű kiegészítő lapból (jobb oldal) amelyen a demóban használt szenzorok,
LED-ek, relék, nyomógombok és egy analóg joystick található.
A Google által kiadott DemoKit alkalmazás tulajdonképpen
ennek a hardvernek a vezérlését mutatja be.
Sajnos a referencia platformnak húzós ára van (~$400), de ennek ellenére
elkapkodták. Az alternatívák (Microchip, stb.) még nem elérhetők. De miért
olyan különlegesek ezek az eszközök? Nem lehetne egyet készíteni házilag?
Dehogynem. Az ADK honlapján megtalálhatók az információk hogy hogyan, ebből
kiindulva elkészült az Edudroid Accessory board.
Elsősorban tekintsük át a megoldás lényegét. Amint már
említettem, USB alapú megoldásról van szó. A megoldás során gondolom szempont
volt a platformtól való függetlenség, azaz hogy bármilyen telefonon használható
legyen. Bár a legelegánsabb megoldás az lett volna, ha az Android eszköz játssza
az USB host szerepét, az telefon hardvertől való függetlenségi követelmény
nagyjából kizárta a host módot mivel semmi garancia nincs arra, hogy ezt minden
készülék hardvere támogatja. Az USB host mód vagy az USB OTG (On-The-Go,
szükség esetén átválthat host módba mint pl. a digitális fényképezők
nyomtatáskor) hardveres támogatást igényel a telefon USB vezérlőben. Marad
tehát a device mód az Android oldalon, amiből egyenesen következik a
legfontosabb követelmény az mikrokontroller oldalon: a host mód támogatása. Ez
a követelmény igencsak behatárolja az alkalmas mikrokontrollerek számát, vagy
pedig egy host módú kiegészítő használatát igényli, mint ahogy a referencia
platform esetében is történt. Ugyanis a referencia platformon az AVR
mikrokontroller mellett ott figyel a MAX3421 USB host vezérlő.
Nekem történetesen ott figyelt a fiókban egy régebben
elkészített Cypress EZ-HOST CY7C67300
alapú fejlesztő kártya, és rögtön arra gondoltam, hogy ez felhasználható akár
kiegészítő host vezérlőként egy mikrokontroller mellett, vagy alapvető
feladatok ellátására önmagában is alkalmas. Az EZ-HOST fontosabb tulajdonságai:
-
4 USB port, host vagy device mód
-
48 MHz RISC mikrokontroller
-
16Kbyte belső RAM, külsőleg bővíthető 64Kbyte-ig
-
akár 32 GPIO láb
-
2 soros port
-
SPI port
-
HPI interfész (gyors párhuzamos interfész
koprocesszor üzemmódhoz)
-
I2C port
-
IDE vezérlő (igen, vinyót lehet rá kötni!)
A fejlesztői kártyán helyet kapott egy külső RAM, ami
komplexebb programok futtatását teszi lehetővé, így viszont kevesebb GPIO port
maradt. Kivezetésre kerültek az SPI, az I2C, a PWM interfészek, a soros port,
egy host és egy debug/fejlesztői USB port valamint 12 általános célú GPIO láb.
Az EZ-Host egy nyílt forrású GNU C fejlesztői környezetben
programozható, ami letölthető a Cypress honlapjáról. Ugyanitt példaprogramokat
is találunk, amik alapján gyorsan megvalósítható a host működés. A feladat
tehát az volt, hogy megírjam a host vezérlő programját úgy, hogy Android
kiegészítőként ismerje fel a telefon.
Az USB host szabványos működési elve a következő. Először is detektáljuk, hogy fizikailag
csatlakoztatva van-e egy eszköz, majd „enumeráljuk”, azaz kiolvassuk az
alapvető paramétereit (gyártó/termék azonosító, kommunikációs paraméterek).
Ezután megkeressük, hogy milyen szabványos interfészeket támogat (pl. USB
háttértár vagy HID (Human Interface Device) beviteli eszköz), majd eldöntjük
milyen drivert használjunk hozzá. Azután
megkeressük a felhasználni kívánt szolgáltatás kommunikációs végpontjait, és
aktiváljuk a kívánt konfigurációt mindezt szabványos vezérlő parancsokkal. A
Google viszont egy kicsit módosított az inicializáláson: az enumerálás után egy
nem szabványos lekérdezést indítunk a vezérlő végponton, amire válaszként megkapjuk,
hogy az eszköz támogatja-e az accessory módot és ha igen, milyen verziót. Ha
támogatott az accessory mód, elküldjük az eszköz azonosítóit (gyártó, modell,
verzió, szériaszám stb.) majd kiadjuk a parancsot az accessory mód
bekapcsolására. A parancs kiadása után újra „enumerálni” kell a készüléket, ami
most már a Google gyártói azonosítóját jelenti (0x18D1) és a termékazonosító
0x2D00 (vagy 0x2D01 ha ADB-t is támogat) lesz. Hogy miért kellett egy ilyen furcsa módszerrel
megoldani egy új szolgáltatás szabványos meghirdetése helyett, azt csak a
Google tudja (találgatni
lehet). Viszont leprogramozni USB host oldalról így elég kényelmes: nem
kell a szolgáltatásokat enumerálni, keresgélni, egyszerűen megnézem, hogy a
gyártó/termék azonosítója 0x18D1/0x2D00? Ha nem, megpróbálom átkapcsolni, és
újra enumerálom… Ha minden OK, még meg kell keresni a felajánlott BULK
végpontokat (a Nexus S esetében ez az 5 (be)-ös és 7-es (ki)) és a
konfigurációt 1-re állítani, aztán mehet a móka.
Tehát ott tartunk, hogy él az USB kapcsolat a telefon és az
eszköz között. Mit tudunk csinálni? Üzeneteket tudunk küldeni az eszköznek és
az eszköz üzeneteket tud küldeni a telefonnak. A DemoKit alkalmazás egy
egyszerű 3 bájtos üzenetet használ, amelynek az értelmezése egyszerű:
1.
byte:
Kontroller Osztály. Ez lehet Szervo vezérlő, LED vezérlő, relé vezérlő
stb.
2.
byte: Az
osztályon belül a címzett gomb, LED száma, vagy két bájtos (szenzor) átvitel
esetén az MSB. Joystick esetén az X koordináta.
3.
byte:
Kiolvasott/elküldött érték byte, vagy LSB a szenzoroknál és Y a
joysticknál.
Az első bájt esetében
a következő értékek értelmezettek:
1.
Gombok <=
2.
LED-ek és szervók =>
3.
Relék =>
4.
Hőmérséklet szenzor <=
5.
Fény szenzor <=
6.
Joystick <=
Természetesen ez a kommunikáció nincs kőbe vésve, egyszerűen
a DemoKit App és a referencia platform között ez a kommunikáció. Az egyszerűség
kedvéért én is ezt használtam, és készült egy igen egyszerű „Demo Shield” az
EZ-Host kártyához is, amelyen van 4 LED és 4 gomb. A firmware-t meg úgy írtam
meg, hogy kompatibilis legyen a DemoKit app-al, így lehet vele tesztelni.
A kapcsolat szépen létrejön, és a LED-ek vezérlése meg a
gombok állapotváltásai szépen működnek. Az egyetlen gondot a telefon
áramfelvétele jelenti: az USB kapcsolaton a telefon elkezd tölteni, és ez
rendesen fűti a táp stabilizátorát. De egy jó kis hűtőborda megoldja a
problémát.