Sziasztok!
Próbálkozom STM32 Host módjával USB billentyűzetet kezelni.
Belefutottam néhány dologba, de egész szépen működik már.
Az egy dolog, hogy vannak ezek a kombinált billentyűzetek, aminek több végpontja is van, és hol az egér, hol a billentyűzet szerepel korábban a leíróban.
Ezzel nincs problémám.
Most viszont sikerült szereznem egy okosabb Genius rádiós billentyűzetet, és elakadtam vele.
Ezen három végpont van, az első egy egér, a második egy billentyűzet és a harmadik is billentyűzet.
A probléma ezzel, hogy a második eszközzel (első billentyűzettel) nem működik a billentyűzet-kezelésem, a harmadikkal viszont igen.
Nyilván ez utóbbi lesz a normál "Keyboard Boot Protocol", az előbbi pedig valamiféle bővített változat.
Nem látom viszont, hogy az eszközleíróban ezek meg lennének különböztetve, ill. mindegyiket keyboard boot code-ként azonosítja nekem.
Hogyan tudnám megállapítani, hogy több billentyűzet interfész esetén melyik az, amelyik valóban a többé-kevésbé szabványos boot protokollt implementálja?
Nem hiszem ugyanis, hogy két billentyűzet végpont esetén mindig a második a "fallback" - vagy erre kellene építenem?
Tudtok ebben segíteni?
--------------------------------------------------------------------------------------------------------------------------------------------------------
Végül azt a megoldást választottam, hogy inicializáláskor megpróbálja beállítani a num/caps/scroll lock LED-eket.
Visszaolvasni ugyan nem sikerült (tartok tőle, hogy a hostnak kell emlékezni rá), de nem is volt rá szükség, mert a speciális billentyűzet interfészen ez a setreport hibára futott.
Ha záros határidőn belül nem sikerül beállítania a LED-eket, akkor továbblép a következő interfészre.
Ha sikerült a LED-eket beállítani, akkor ~100ms-ot követően kikapcsolja őket.
Az interfészekkel növekvő sorrendben próbálkozik, de most mindegyik billentyűzetet a megfelelő interfészen megtalálja, és jó eséllyel minden további billentyűzetnek is mennie kell vele, aminek van egy alternatív billentyűzet profilja ugyan, de támogatja ezt a "Keyboard Boot Protocol" megoldást is (amennyiben azok is hibára futnak a "nem megfelelő" interfészen).
Ebben a formában jobban tetszik a megoldás mint a fix második billentyűzetet megkeresni, bár kicsit át kellett írnom hozzá a billentyűzet felismerésemet.
- 317 megtekintés
Hozzászólások
Egyszerre nem tudsz két billentyűzetet vagy többet kezelni?
Esetleg egy NumLock/CapsLock teszt, szóval bekapcsolod rajta a NumLock-ot majd olvasod hogy változott-e, akkor valódi billentyűzet.
- A hozzászóláshoz be kell jelentkezni
Sajnos egyszerűen nem - így is hozzá kellett nyúlnom, hogy ne feltétlen az első eszközt kezelje, de, úgy tűnt, elég sokat kellene módosítani rajt, ha egyidejűleg akarnék több eszközt kezelni...
Egyébként num/caps/scroll lock LED kezelése valamiért nem is működött ezzel a billentyűzettel, csak a többivel, amit próbáltam (lehet, nem teljesen jól küldöm neki az adatot, vagy itt is van némi különbség).
A normál és módosító billentyűk működnek rajt, a caps lock is, csak a LED kapcsolgatás nem ment...
Egyik kínai, giroszkópos cucc meg másutt küldte a módosító billentyűket pl... van néhány hülyeség ezen a téren...
Szerk.:
A LED-kapcsolgatási problémát visszavonom - nincs rajta LED, vagy legalábbis Linuxon sem kapcsolgatja semmi.
Elemes mivolta miatt ez érthető, viszont így az adat visszaolvasása segíthet - bár abban elbizonytalanodtam, hogy ez egyáltalán lehetséges-e...
- A hozzászóláshoz be kell jelentkezni
Dugd fel a billentyűzetet egy linux -os gépre és a sudo lsusb -v -d <vid:pid> kimenetét tedd fel ide légyszi!
- A hozzászóláshoz be kell jelentkezni
Ez volt az első lépésem, de nem sokra jutottam vele - bár nem kizárt, hogy elkerülte valami a figyelmem.
Ez a szóban forgó Genius billentyűzeté, ez pedig a kínai giroszkópos billentyűzet/egér kombóé.
Akár a nyers konfigurációs leíró adatait is ki tudom exportálni, nem kizárt, hogy abból kihámozható valami...
- A hozzászóláshoz be kell jelentkezni
Hát ettől tényleg nem lettem okosabb. Arra gondoltam, talán elnéztél valamit, de én is arra jutottam amire te.
A 2. ötletem az volt, hogy a report deszkriptror hossza alapján talán lehet azonosítani, hiszen a boot protokol reportja fix. De a geniusnál 65 byte -os a report, az air mouse -nál 113. Aztán a speckót olvasva rájöttem, hogy ez amúgy sem a boot módot írja le, eleve halott ötlet volt.
Találtam a speckóban ilyet: " The Boot Keyboard shall, upon reset, return to the non- boot protocol which is described in its Report descriptor. That is, the Report descriptor for a Boot Keyboard does not necessarily match the boot protocol. The Report descriptor for a Boot Keyboard is the non-boot protocol descriptor. " Esetleg hiányzik egy set_protocol() request? Lehet, hogy ettől az első interfész is "megjavulna"?
- A hozzászóláshoz be kell jelentkezni
Igen, nekem is ez volt a másik ötletem, ezért linkeltem az air mouse adatait is - itt bukott el a gondolat.
Egy SetProtocol függvényt meghív néhányszor az inicializáció során, ennek ellenére nem akar működni.
...viszont éjjel benéztem a dolgot, sajnos nem fut hibára a SetReport, tehát ezzel mégsem tudom megállapítani, hogy sikerült-e elküldeni a LED-kapcsoló üzenetet.
Helyesebben elküldeni sikerül, csak vélhetően nem jut érvényre, de nem tudom, hogyan lehetne visszaolvasni, ha egyáltalán...
Úgy tűnik, nem olyan egyszerű, hogy szimplán GetReport-tal hasonló módon visszaolvassa az ember, ahogy azt Móricka elképzeli. :)
- A hozzászóláshoz be kell jelentkezni
Elvileg set_idle() nélkül akkor is kell reportot küldenie, ha nem volt állapot változás. Talán kérd be a report -ot, és ha nem stimmel a méret, próbáld a következő interfészt. Persze ha a report mérete egyezik a boot-mode -ossal, csak a tartalom inkompatibilis, az szívás. De ilyet csinálni elég extrém volna a gyártól.
- A hozzászóláshoz be kell jelentkezni
Érdekes amúgy.
Egy helyen hív egy SetIdle függvényt, "0" paraméterrel, még inicializáció során - többször is próbálkozik, végül hiba nélkül tér vissza.
Próbáltam kikommentelni, ill. értéket adni neki (pl. 10), valamint panel gombnyomásra is elküldeni (vagyis nem a billentyűzetről), de látszólag nincs hatása.
Van egy függvény, ami a HID FIFO-ját olvassa, ennek kiírattam az értékét, de csak gombnyomáskor és elengedéskor van adatom belőle.
Ami érdekes, hogy az a billentyűzet, amin LED-ek is vannak, a LED-ek megváltoztatásakor generál egy üzenetet (külső gombnyomással tudom triggerelni).
A rádiós billentyűzeteim, amiken nincs LED, azoknál is átmegy a LED-ek bekapcsolása, de nem generál ilyenkor üzenetet - ez a Genius csodabillentyűzet sem.
Milyen reportra és méretre gondolsz?
Nem kifejezetten ezt a billentyűzetet szeretném jól kezelni, hanem a lehető legtöbbet - vagyis jó lenne olyan adatot vagy megoldást találni, amiből kiderül, hogy az eszköz számomra ideálisan kommunikál-e.
Ezért tűnt jónak a visszaolvasás használata, de valahogy nem sikerült eddig összehozni.
- A hozzászóláshoz be kell jelentkezni
Arra a HID report -ra gondolok, amiben a billentyűzet elküldi a billentyű állapotot.
- A hozzászóláshoz be kell jelentkezni
Nem tudom... van neki egy timere, aminek segítségével folyamatosan polloz, alapértelmezetten 10 ms időközönként...
Ekkor kér valamiféle riportot USB_D2H | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_CLASS flag-ekkel, 8 byte hosszan és átad egy buffert.
A bufferben nem láttam adatot (gombnyomás mondjuk nem volt közben).
Ezt követően küld egy URB kérést INTERRUPT "típusú" IN végpontra, adat típusra, 8 byte-hoz.
Ezt követően, ha az állapotgép az URB "Done" állapotba kerül, lekérdezi a fogadott karakterek számát (ezeket egy interrupt rutin intézi), és, ha van mit, beteszi egy FIFO bufferbe.
Ezt a buffert kezeli a másik rész, és ebből mazsolázza ki a lenyomott billentyűket.
Ha jól értem, gyakorlatilag felhúzza az STM32 USB interfészét, hogy generáljon egy interruptot adat érkezésekor.
Ezután adat akkor érkezik, amikor megnyomok egy billentyűt, a másik billentyűzet "furcsa" interfészén pedig nem kapok adatot emiatt.
- A hozzászóláshoz be kell jelentkezni
Hmm. Érdekes, mert a genius 64 byte -os csomagméretet használ az interrupt endpoint -okon. Vajon honnan szedi a driver a 8 byte -os hosszt?
- A hozzászóláshoz be kell jelentkezni
Az endpoint inicializálásakor meg is van ez az érték (64 byte a Geniusnál és talán 32 byte a másikon).
Amikor rájön, hogy billentyűzetről van szó, meghív egy billentyűzet initet, aminek van egy "keybd_report_data" nevű változója, ami egy kételemű, 32-bites elemekből álló tömb.
Ha a "hossz" (HID_Handle->length) nagyobb ennek a tömbnek a méreténél, akkor beállítja erre az értékre - gyakorlatilag a billentyűzetkezelés inicializálása után lesz a fent írtak következményeként 8 az értéke.
- A hozzászóláshoz be kell jelentkezni
Ha bedugod ezt a csodabillentyuzetet sima linux ala majd valamivel (pl ezzel: https://wiki.wireshark.org/CaptureSetup/USB) monitorozod a forgalmat akkor nem deritheto ki hogy mi a kulonbseg? Es akkor annak megfeleloen tudsz finomhagnolni az STM32-es host driveren...
Egyebkent ha nem titok milyen STM libet hasznalsz ehhez? Vagy bare metal + CMSIS peripheral access layer headers csak?
- A hozzászóláshoz be kell jelentkezni
Elvileg a "probléma" ott kezdődik, hogy ez a "Keyboard Boot Protocol" kicsit korlátozott, pl. maximum 6 egyidejű billentyűlenyomást kezel.
Ezen egyes billentyűzetgyártók szerettek volna túllépni, és készítettek okosabb megoldást.
Azt nem tudom, ezek az okosabb megoldások mennyire különböznek egymástól vagy hányféle létezik, de az alap "Keyboard Boot Protocol" szükséges ahhoz, hogy a BIOS-ban is tudjon működni, a bővített prtotokoll(oka)t az sem támogatja.
Nem tudom, az UEFI tartalmaz-e erre vonatkozó bővítést, ott mennyire működnek azok a billentyűzetek, amiknél ezt esetleg nem implementálták, de UEFI esetén is elég széles skálán mozognak a támogatott funkciók.
Feltételezem, Linux esetén a bővített protokollt fogja használni, ez nekem alapvetően nem célom - valójában így is többet foglalkoztam már vele a szükségesnél.
Ez az STM32 HAL library-jével van kezelve, de kellett módosítani néhány dolgon.
Jelenleg hajlok arra, hogy megkeresem az "utolsó" elérhető billentyűzetet és azt inicializáltatom vele - ez működni fog az általam eddig ismert összes billentyűzeten (általában csak két interfész van), és ezen az okosabb cuccon is.
...csak attól tartok, ez sehol sincs leírva, hogy a második billentyűzet eszköz mindig működni fog, így valószínűsíthetően lehet találni olyat is, ami fordítva csinálja (ahogy a billentyűzet + egér vs. egér + billentyűzet sorrend is előfordult).
Azt talán remélhetem, hogy a többi Genius is így működik...
Szerk.: 6KRO-nak is nevezik ezt, ill. amit nem értek, hogy miért mondja magáról a bővített billentyűzet is azt típusra, hogy boot interface protocol és 0x01, vagyis billentyűzet... szerintem az nem ez a kategória kellene legyen.
- A hozzászóláshoz be kell jelentkezni
kicsit korlátozott, pl. maximum 6 egyidejű billentyűlenyomást kezel.
Miért akarna valaki, akár 6 db billentyűt lenyomni egyszerre?
- A hozzászóláshoz be kell jelentkezni
Nem tudhatom... talán gamerek harapnak rá az ilyesmire vagy nekik szánják, de lehet, nem kifejezetten emiatt a funkció miatt.
Én nem akarok ennyit kezelni, de látom ezeket a lenyomott billentyűket is.
- A hozzászóláshoz be kell jelentkezni