\ Enumerace

Enumerace
Enumerace je proces počátečního vyjednávání, kdy hostitel a host komunikují za účelem vzájemného poznávání a nastavování. Během enumerace posílá zařízení informace o svých hardwarových a softwarových prostředcích hostiteli, zatímco hostitel poskytuje zařízení adresu a mění vnitřní stavy zařízení.
Pokud budeme chápat komunikaci mezi hostitelem a zařízením jako obousměrnou rouru, po které proudí užitečná data, nutně dojdeme k potřebě odlišit data, která jsou předmětem enumerace a ostatní data, která jsou závislá na funkci zařízení, kvůli které bylo sestrojeno. USB specifikace řeší potřebu více komunikačních kanálů zavedením tzv. endpointů. Endpoint je funkční celek, který má k dispozici obousměrnou rouru, po níž komunikuje s hostitelem. Endpoint může být jak konzument, tak producent datového toku. Jedno zařízení může mít až 7 endpointů (rour). Nultý endpoint je určen pro vyřizování enumerace a má vlastnosti pevně dané specifikací. Vlastnosti ostatních endpointů jsou předány hostiteli během enumerace ve speciálních datových strukturách.
Pokud by se komunikace po rouře skládala pouze z užitečných dat (například výsledků měření), neměl by hostitel k dispozici žádný nástroj, kterým by měnil vnitřní stavy zařízení a nemohl by ovlivňovat jeho chování. Aby mohl hostitel posílat kromě dat také příkazy, zavádí USB specifikace zvláštní druh paketů (setup packet), které říkají, že data předaná v následné transakci nejsou určena pro funkčnost zařízení, ale pro řízení stavů zařízení.
Endpoint 0 musí reagovat na setup pakety a odesílat informace, které jsou po zařízení požadovány. Abychom mohli navrhnout program, který bude požadavky vyřizovat, musíme si uvědomit, z jakých atomických operací se komunikace po USB skládá.

Transakce

Jak již bylo uvedeno v rozboru USB, přenosovou jednotkou na sběrnici je paket. Paket může obsahovat sdělení různé povahy:
  1. lichá část dat, sudá část dat (DATA0, DATA1)
  2. handshaková odpověď (ACK, NAK)
  3. oznámení, že následující data jsou příkazem (SETUP packet)
  4. výzva k odebrání dat (OUT packet)
  5. výzva k odeslání dat (IN packet)
Problém, který obecně nastává u datových přenosů, je konečná délka paketu. MTU (maximum transfer unit) udává počet bytů, které smějí být přeneseny v rámci jednoho paketu. MTU reflektuje hardwarová omezení, například nepřesnost synchronicity příjemce a odesílatele, velikosti vstupně/výstupních bufferů, účinnost CRC a podobně. Endpoint 0 má maximální délku dat stanovenu na 8 bytů. Jev, který nastává v důsledku omezení velikosti paketů, se nazývá fragmentace (dělení na části). Proces přenosu dat se zesložiťuje a přenos paketů musí být opatřen rozšířením nazvaným transakce.
Transakce je předpis, který stanoví posloupnost různých druhů paketů za účelem přenesení zprávy libovolné délky. Transakce budeme dělit na tři druhy:
  1. vstupní transakce - přenáší data ze zařízení k hostiteli
  2. výstupní transakce - přenáší data od hostitele do zařízení
  3. řídící transakce - posílá řídící data od hostitele do zařízení

Výstupní transakce

Hostitel nejprve uvědomí zařízení, do kterého chce zapisovat, vysláním OUT packetu. Data, která chce hostitel odeslat, si rozdělí na bloky pevné délky (poslední blok může být kratší). Hostitel bez čekání odešle první blok dat v paketu typu DATA0. Zařízení odpovídá handshakovým paketem (ACK nebo NAK). V případě, že zařízení pošle ACK, hostitel vysílá OUT packet následovaný bez prodlení paketem DATA1 s dalším blokem dat a znovu čeká na handshakovou odpověď zařízení. Střídavě se tak přenášejí OUT+DATA0 a OUT+DATA1, dokud nejsou přeneseny všechny části zprávy. Pokud zařízení odpoví na nějaký paket negativně (NAK), zopakuje hostitel své předchozí vysílání (v paketu stejného typu). Když hostitel odešle vše, co potřeboval, nastává posloupnost paketů ukončující celou transakci. Hostitel vyšle IN packet a očekává, že zařízení pošle paket DATA0 s nulovou délkou obsahu (prázdný paket). Hostitel takový paket potvrdí vysláním ACK paketu. Tím se ukončuje transakce a zpráva, která byla předmětem transakce, je považována za platnou. Pokud není dodržena posloupnost paketů jednou ze stran, transakce se ruší a dosud přenesená data se musí zahodit.

Vstupní transakce

Hostitel vyšle do endpointu, ze kterého chce číst zprávu, IN paket. Zařízení odpovídá první částí zprávy v paketu DATA0. Hostitel handshakuje (ACK nebo NAK). Hostitel opakuje IN packet a předpokládá, že zařízení mu nyní odpoví v paketu DATA1 (střídavě). Hostitel přijatá data opět potvrzuje a podle potřeby opakuje vysílání paketu tolikrát, dokud neobdrží buď prázdný paket nebo paket s menším počtem bytů, než je maximum. Tím se hostitel dozví, že zařízení již poslalo celou zprávu a nastane okamžik pro potvrzení platnosti celé transakce. Hostitel vysílá OUT packet a bez čekání pošle i DATA0 packet bez obsahu (prázdný DATA0 packet). Zařízení musí odpovědět ACK packetem.
U obou transakcí se vyskytuje potvrzení transakce, které je realizováno posláním prázdného datového paketu v opačném směru, než ve kterém probíhal přenos zprávy.

Řídící transakce

Řídící transakce začíná okamžikem, kdy hostitel pošle SETUP packet do endpointu. Poté pošle DATA0 packet o délce 8 bytů (rozumí se 8 bytů obsahu). Hostitel očekává ACK od zařízení. Obsah paketu DATA0 má přesně specifikovanou strukturu a zařízení se z ní dozví, zda bude následovat vstupní či výstupní transakce. Zařízení si buď připraví data k odeslání nebo uvolní vstupní buffer pro přijímání a pak provede standardní transakci podle toho, jak bylo uvedeno výše. Řídící transakce je tedy stejná jako vstupní či výstupní transakce s tím rozdílem, že užitečná data, která by byla normálně přenášena, jsou nahrazena daty, o které hostitel požádal v posloupnosti SETUP+DATA0 paketech.
Transakce je nejkomplexnějším útvarem při USB komunikaci. Transakce přenáší zprávy, které jsou připraveny ve vstupně/výstupních bufferech zařízení i hostitele a jejich obsah může být libovolný. Pouze při příchodu SETUP+DATA0 paketu do zařízení jsou tyto buffery nahrazeny odpovědí s přesně specifikovaným významem a strukturou. SETUP paket lze tedy chápat jako přepnutí vnitřního stavu zařízení.

Stavy zařízení

Program, který bude rozebírat přišlé pakety, rozhodovat se o jejich sdělení a odesílat zpět odpověď, bude pracovat podle schématu přijmi-vyhodnoť-odpověz. Rutiny tohoto analyzátoru (parseru) se zavolají jednou po příchodu paketu, provedou se a uvolní procesorový čas. Rutiny nebudou obsahovat žádné čekání. Vzhledem k omezeným možnostem procesorů AVR nebude nikde uložena celá zpráva, která je předmětem transakce. Každý blok (max. 8 bytů) bude do bufferu vložen těsně před odesláním a přijatá data budou ihned po přijetí zpracována. Parser bude tedy pracovat obdobně jako stavový automat, jehož vstupem je příchozí paket a výstupem odchozí paket a změna vnitřního stavu.
Požadavky, které musí zařízení plnit:
  1. užitečná data (rqData)
  2. device descriptor (rqDevDesc)
  3. configuration descriptor (rqConfDesc)
  4. set address (rqSetAddr)
Fáze transakce (x-action), kterými zařízení prochází:
  1. klid, výchozí stav (xaNone)
  2. požadavek na zápis (OUT paket) (xaOut)
  3. požadavek na čtení (IN paket) (xaIn)
  4. požadavek na nastavení (SETUP paket) (xaSetup)
  5. ukončení zápisové transakce (IN paket přicházející při zápisové transakci) (xaWriteEnd)
  6. ukončení čtecí transakce (OUT paket přicházející při čtecí transakci) (xaReadEnd)
  7. odmítnutí ukončení čtecí transakce (OUT paket přicházející při čtecí transakci, aniž by byla potvrzena poslední data) (xaReadEndFail)
  8. čekání na potvrzení datového paketu při čtecí transakci (xaInAckWait)
Stavy musejí být rozšířeny o počítadlo odeslaných bytů a o další pomocné proměnné (spánek, stav bez adresy, úsporný režim).
StavPříchozí paketNový stavOdchozí paket
cokolivSETUPxaSetup-
xaNone (klid)OUTxaOut-
INxaInWaitAckDATA1
ACK, NAKxaNone-
DATAnxaNoneNAK
xaInOUTxaReadEnd-
INxaInWaitAckDATA0 nebo DATA1
ACK, NAKxaNone (transakce zrušena)-
DATAnxaInNAK
xaInWaitAckOUTxaReadEndFail-
INxaInWaitAckDATA0 nebo DATA1 (opakované odeslání)
ACKxaIn (+připravit další paket)-
NAKxaIn-
DATAnxaNone (transakce zrušena)NAK
xaReadEndFailOUTxaOut (transakce zrušena)-
INxaInWaitAck (transakce zrušena)DATA1
ACK, NAKxaNone (transakce zrušena)-
DATAnxaNone (transakce zrušena)NAK
xaOutOUTxaOut-
INxaWriteEndzero DATA
ACK, NAKxaNone (transakce zrušena)-
DATAnxaOut (paket přijat v pořádku)ACK
xaWriteEndOUTxaOut (transakce zrušena)-
INxaWriteEndzero DATA
ACKxaNone (data odeslána v pořádku)-
NAKxaNone (transakce zrušena)-
DATAnxaNone (transakce zrušena)NAK
xaReadEndOUTxaOut (transakce zrušena)-
INxaInWaitAck (transakce zrušena)DATA1
ACK,NAKxaNone (transakce zrušena)-
DATAnxaNone (transakce potvrzena)ACK
xaSetupOUTxaOut (setup zrušen)-
INxaInWaitAck (setup zrušen)DATA1
ACK, NAKxaNone (setup zrušen)-
DATAnxaOut nebo xaIn (dle obsahu dat)ACK

Požadavky

Zařízení musí na požádání zasílat dvě datové struktury (dvě zprávy). První je popisovač zařízení (Device Descriptor) a druhý je popisovač nastavení (Configuration Descriptor). Obě datové struktury mají více než 8 bytů a proto se rozpadají na více paketů. Dalším požadavkem, který je posílán hositelem je nastavení adresy, ale odpověď je zařízením signalizována tak, že úspěšně ukončí transakci (prázdný paket, zero DATA) a takovou odpověď zařídí stavový automat sám od sebe.

Device Descriptor

OffsetPopisHodnota
0bLength0x12
1bDescriptorType0x01
2,3bcdUSB0x0100
4bDeviceClass0x00
5bDeviceSubClass0x00
6bDeviceProtocol0x00
7bMaxPacketSize0x08
8,9idVendor0x065d
10,11idProduct0x1031
12,13bcdDevice0x0004
14iManufacturer0x00
15iProduct0x00
16iSerialNumber0x00
17bNumConfigurations0x01


Configuration Descriptor (spojení Configuration, Interface a Endpoint descriptoru)

OffsetPopisHodnota
Configuration Descriptor
0bLength0x09
1bDescriptorType0x02
2,3wTotalLenght0x0020
4bNumInterfaces0x01
5bConfigurationValue0x01
6iConfiguration0x00
7bmAttributes0x80
8bMaxPower0x32
Interface Descriptor
9bLength0x09
10bDescriptorType0x04
11bInterfaceNumber0x00
12bAlternateSetting0x00
13bNumEndpoints0x02
14bInterfaceClass0x00
15bInterfaceSubClass0x00
16bInterfaceProtocol0x00
17iInterface0x00
Endpoint 1 Descriptor
18bLength0x07
19bDescriptionType0x05
20bEndpointAddress0x01
21bmAttributes0x00
22,23wMaxPacketSize0x0001
24bInterval0x00
Endpoint 2 Descriptor
25bLength0x07
26bDescriptionType0x05
27bEndpointAddress0x82
28bmAttributes0x00
29,30wMaxPacketSize0x0001
31bInterval0x00


Deskriptory budou odeslány v následujících paketech:

Device Descriptor:
DATA1 packet - CRC 0xe713 - Device Descriptor
80 4b 12 01 00 01 00 00 00 08 13 e7 eop
DATA0 packet - CRC 0x83d9 - Device Descriptor
80 c3 5d 06 31 10 04 00 00 00 d9 83 eop
DATA1 packet - CRC 0x8f3f - Device Descriptor
80 4b 00 01 3f 8f eop



Configuration Descriptors:
DATA1 packet - CRC 0xa20a - Configuration Descriptor
80 4b 09 02 20 00 01 01 00 80 0a a2 eop
DATA0 packet - CRC 0x7d04 - Configuration Descriptor a Interface Descriptor
80 c3 32 09 04 00 00 02 00 00 04 7d eop
DATA1 packet - CRC 0x2f72 - Interface Descriptor a Endpoint 1 Descriptor
80 4b 00 00 07 05 01 00 01 00 72 2f eop
DATA0 packet - CRC 0xbfe0 - Endpoint 1 Descriptor a Endpoint 2 Descriptor
80 c3 00 07 05 82 00 01 00 00 e0 bf eop
DATA1 packet - CRC 0x0000 - konec
80 4b 00 00 eop