Open Host Controller Interface — Änderungen 10075 → 10089

Zeile 2: Zeile 2:
 
*Die Liste der Register vervollständigen (Spezifikation: Seite 137ff)
 
*Die Liste der Register vervollständigen (Spezifikation: Seite 137ff)
 
*Isochronous Transfers (Spezifikation: Seite 39ff und 48ff)
 
*Isochronous Transfers (Spezifikation: Seite 39ff und 48ff)
−
*Initialisierung des HCs (Seite 52ff)
+
*Alignment der verschiedenen Datenstrukturen!
 +
*Vielleicht noch ein paar nette Flowcharts, wie man Transfers durchführt?
 
}}
 
}}
  
Zeile 184: Zeile 185:
 
==== Root-Hub-Register ====
 
==== Root-Hub-Register ====
 
*'''HcRhDescriptorA''' (0x48)
 
*'''HcRhDescriptorA''' (0x48)
 +
//TODO
 
*'''HcRhDescriptorB''' (0x4C)
 
*'''HcRhDescriptorB''' (0x4C)
 +
//TODO
 
*'''HcRhStatus''' (0x50)
 
*'''HcRhStatus''' (0x50)
 +
//TODO
 
*'''HcRhPortStatus'''[1] (0x54)
 
*'''HcRhPortStatus'''[1] (0x54)
 +
//TODO
  
 
=== Host Controller Communications Area (HCCA) ===
 
=== Host Controller Communications Area (HCCA) ===
Zeile 223: Zeile 228:
  
 
==== Organisation von nicht-periodischen Transfers ====
 
==== Organisation von nicht-periodischen Transfers ====
−
Die Organisation der Datentransfers erfolgt über zwei Datenstrukturen, die über einfach verkettete Listen miteinander verknüpft sind. Die Datenstrukturen sind zum einen der Endpoint Descriptor (ED) und zum anderen der Transfer Descriptor (TD). Die EDs beschreiben genau einen Endpunkt einer Funktion (d.h. eines USB-Geräts). Die TDs beschreiben einen Transfer, der einem Endpunkt zugeordnet wird. Die EDs sind in einfach verketteten Listen organisiert. Von diesen Listen gibt es zwei für die nicht-periodischen, d.h. Bulk und Control Transfers. Die Zeiger auf die Anfänge dieser Listen sind in den Registern HcBulkHeadED sowie HcControlHeadED gespeichert. Jeder ED enthält wiederum einen Zeiger auf den Kopf einer verketteten Liste von TDs, die für diesen Endpunkt ausgeführt werden sollen.
+
Die Organisation der Datentransfers erfolgt über zwei Datenstrukturen, die über einfach verkettete Listen miteinander verknüpft sind. Die Datenstrukturen sind zum einen der Endpoint Descriptor (ED) und zum anderen der Transfer Descriptor (TD). Die EDs beschreiben genau einen Endpunkt einer Funktion (d.h. eines USB-Geräts). Die TDs beschreiben einen Transfer, der einem Endpunkt zugeordnet wird. Die EDs sind in einfach verketteten Listen organisiert. Von diesen Listen gibt es zwei für die nicht-periodischen, d.h. Bulk und Control Transfers. Die Zeiger auf die Anfänge dieser Listen sind in den Registern HcBulkHeadED sowie HcControlHeadED gespeichert. Jeder ED enthält wiederum einen Zeiger auf den Kopf einer verketteten Liste von TDs, die für diesen Endpunkt ausgeführt werden sollen, zB:
 +
 
 +
<pre>
 +
HcBulkHeadED
 +
|
 +
V
 +
ED --> ED --> ED --> ED --> ED --> ED
 +
|      |            |      |
 +
V      V            V      V
 +
TD      TD          TD    TD
 +
        |                  |
 +
        V                  V
 +
        TD                  TD
 +
                            |
 +
                            V
 +
                            TD
 +
</pre>
 +
               
 +
Es ist dabei Aufgabe des USB-Treibers diese Listen im Arbeitsspeicher anzulegen, wobei beide Deskriptoren an 16 Byte Grenzen im Arbeitsspeicher ausgerichtet sein müssen. Außerdem muss der Treiber die Felder ''HcBulkHeadED'', ''HcControlHeadED'' sowie die Bits ''CLE/BLE'' im Feld ''HcControl'' sowie ''CLF/BLF'' in ''HcCommandStatus'' entsprechend zu setzen.
 +
Es ist dann Aufgabe des HCs die Listen abzuarbeiten und die Felder ''HcBulkCurrentED'' und HcControlCurrentED zu setzen. Außerdem entfernt er die TDs und fügt sie in die sogenannte Done-Liste ein, auf die ''HcDoneHead'' zeigt.
 +
 
 +
===== Aufbau EndpointDescriptor =====
 +
 
 +
{| {{prettytable}}
 +
|- align="center"
 +
! Bit || style="padding:1px 5px;"|31 || style="padding:1px 5px;"|30 || style="padding:1px 5px;"|29 || style="padding:1px 5px;"|28 || style="padding:1px 5px;"|27 || style="padding:1px 5px;"|26 || style="padding:1px 5px;"|25 || style="padding:1px 5px;"|24 || style="padding:1px 5px;"|23 || style="padding:1px 5px;"|22 || style="padding:1px 5px;"|21 || style="padding:1px 5px;"|20 || style="padding:1px 5px;"|19 || style="padding:1px 5px;"|18 || style="padding:1px 5px;"|17 || style="padding:1px 5px;"|16 || style="padding:1px 5px;"|15 || style="padding:1px 5px;"|14 || style="padding:1px 5px;"|13 || style="padding:1px 5px;"|12 || style="padding:1px 5px;"|11 || style="padding:1px 5px;"|10 || style="padding:1px 5px;"|9 || style="padding:1px 5px;"|8 || style="padding:1px 5px;"|7 || style="padding:1px 5px;"|6 || style="padding:1px 5px;"|5 || style="padding:1px 5px;"|4 || style="padding:1px 5px;"|3 || style="padding:1px 5px;"|2 || style="padding:1px 5px;"|1 || style="padding:1px 5px;"|0
 +
|- align="center"
 +
|DWORD 1 || colspan="6" | ''??'' || colspan="11" | MPS || F || K || S || colspan="2" | D || colspan="4" | EN  || colspan="7" | FA
 +
|- align="center"
 +
|DWORD 2 || colspan="28" | TD Queue Tail Pointer (TailP) || colspan="4" | ''??''
 +
|- align="center"
 +
|DWORD 3 || colspan="28" | TD Queue Head Pointer (HeadP) || colspan="2" | 0 || C || H
 +
|- align="center"
 +
|DWORD 4 || colspan="28" | Next Endpoint Descriptor (NextED) || colspan="4" | ''??''
 +
|}
  
−
//BILD
+
//TODO: Beschreibung der Felder
  
−
//Aufbau ED / TD
+
===== Aufbau TransferDescriptor =====
  
−
Es ist dabei Aufgabe des USB-Treibers diese Listen im Arbeitsspeicher anzulegen, wobei beide Deskriptoren an 16 Byte Grenzen im Arbeitsspeicher ausgerichtet sein müssen. Außerdem muss der Treiber die Felder ''HcBulkHeadED'', ''HcControlHeadED'' sowie die Bits ''CLE/BLE'' im Feld ''HcControl'' sowie ''CLF/BLF'' in ''HcCommandStatus'' entsprechend zu setzen.
+
{| {{prettytable}}
−
Es ist dann Aufgabe des HCs die Listen abzuarbeiten und die Felder ''HcBulkCurrentED'' und HcControlCurrentED zu setzen. Außerdem entfernt er die TDs und fügt sie in die sogenannte Done-Liste ein, auf die ''HcDoneHead'' zeigt.
+
|- align="center"
 +
! Bit || style="padding:1px 5px;"|31 || style="padding:1px 5px;"|30 || style="padding:1px 5px;"|29 || style="padding:1px 5px;"|28 || style="padding:1px 5px;"|27 || style="padding:1px 5px;"|26 || style="padding:1px 5px;"|25 || style="padding:1px 5px;"|24 || style="padding:1px 5px;"|23 || style="padding:1px 5px;"|22 || style="padding:1px 5px;"|21 || style="padding:1px 5px;"|20 || style="padding:1px 5px;"|19 || style="padding:1px 5px;"|18 || style="padding:1px 5px;"|17 || style="padding:1px 5px;"|16 || style="padding:1px 5px;"|15 || style="padding:1px 5px;"|14 || style="padding:1px 5px;"|13 || style="padding:1px 5px;"|12 || style="padding:1px 5px;"|11 || style="padding:1px 5px;"|10 || style="padding:1px 5px;"|9 || style="padding:1px 5px;"|8 || style="padding:1px 5px;"|7 || style="padding:1px 5px;"|6 || style="padding:1px 5px;"|5 || style="padding:1px 5px;"|4 || style="padding:1px 5px;"|3 || style="padding:1px 5px;"|2 || style="padding:1px 5px;"|1 || style="padding:1px 5px;"|0
 +
|- align="center"
 +
|DWORD 1 || colspan="4" | CC || colspan="2" | EC || colspan="2" | T || colspan="3" | DI || colspan="2" | DP || R || colspan="18" | ''??''
 +
|- align="center"
 +
|DWORD 2 || colspan="32" | Current Buffer Pointer (CBP)
 +
|- align="center"
 +
|DWORD 3 || colspan="28" | Next TD (NextTD) || colspan="4" | 0
 +
|- align="center"
 +
|DWORD 4 || colspan="32" | Buffer End (BE)
 +
|}
 +
 
 +
//TODO: Beschreibung der Felder
  
 
==== Organisation von Interrupt Transfers ====
 
==== Organisation von Interrupt Transfers ====
Zeile 247: Zeile 298:
  
 
=== Host Controller zurücksetzen ===
 
=== Host Controller zurücksetzen ===
−
 
+
Vor dem Zurücksetzen muss der Wert des Registers ''HcFmInterval'' gesichert werden. Dann wird das HCR Bit in ''HcCommandStatus'' gesetz, um den HC zurückzusetzen. Der HC darf nicht länger als 10µs für den Reset benötigen, diese Zeit sollte der Treiber warten.
  
 
=== Host Controller einrichten ===
 
=== Host Controller einrichten ===
−
 
+
# Die HCCA anlegen, ihre Adresse in HcHCCA eintragen
 +
# CLE/BLE/IE/PLE in ''HcControl' löschen, andernfalls müssen die entsprechenden Listen angelegt werden!
 +
# Speicher für die Done-Liste reservieren und deren physikalische Adresse in HcDoneHead eintragen
 +
# ''HcPeriodicStart'' auf 90% vom ursprünglichen Wert von ''HcFmInterval'' setzen
 +
# In ''HcInterruptEnable'' gewünschte Interrupts aktivieren
 +
# HCFS in ''HcControl'' auf 10b (USB_OPERATIONAL) setzen
 +
# Innerhalb von 1ms beginnt der HC nun SOF-Tokens zu senden, womit er auch mit Transfers beginnt.
  
 
== Weblinks ==
 
== Weblinks ==