Difference between revisions of "Unit DWCOTG"
Line 48: | Line 48: | ||
! '''Note''' | ! '''Note''' | ||
| None documented | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | |||
+ | '''DWCOTG functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostStart(Host:PUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of USBHostStart for the DesignWare Hi-Speed USB 2.0 On-The-Go Controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | See usb.pas for the documentation of this interface of the Host Controller Driver | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostStop(Host:PUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of USBHostStop for the DesignWare Hi-Speed USB 2.0 On-The-Go Controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | See usb.pas for the documentation of this interface of the Host Controller Driver | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostReset(Host:PUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Performs a software reset of the DWC OTG Controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostResetEx(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Performs a software reset of the DWC OTG Controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostSubmit(Host:PUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of USBHostSubmit for the DesignWare Hi-Speed USB 2.0 On-The-Go Controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | See usb.pas for the documentation of this interface of the Host Controller Driver | ||
+ | <br />This Host Controller Driver implements this interface asynchronously, as intended. Furthermore, it uses a simplistic scheduling algorithm where it places requests into a single queue and executes them in the order they were submitted. Transfers that need to be retried, including periodic transfers that receive a NAK reply and split transactions that receive a NYET reply when doing the Complete Split transaction, are scheduled to be retried at an appropriate time by separate code that shortcuts the main queue when the timer expires | ||
+ | <br />Caller must hold the device lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostCancel(Host:PUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of USBHostCancel for the DesignWare Hi-Speed USB 2.0 On-The-Go Controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | See usb.pas for the documentation of thisinterface of the Host Controller Driver | ||
+ | <br />Caller must hold the device lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostResubmit(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Called when a USB transfer needs to be retried at a later time due to no data being available from the endpoint</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | USB transfer to resubmit | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | For periodic transfers (e.g. polling an interrupt endpoint), the exact time at which the transfer must be retried is specified by the bInterval member of the endpoint descriptor. For low and full-speed devices, bInterval specifies the number of millisconds to wait before the next poll, while for high-speed devices it specifies the exponent (plus one) of a power-of-two number of | ||
+ | milliseconds to wait before the next poll. | ||
+ | <br />To actually implement delaying a transfer, we associate each transfer with a thread created on-demand. Each such thread simply enters a loop where it calls sleep() for the appropriate number of milliseconds, then retries the transfer. A semaphore is needed to make the thread do nothing until the request has actually been resubmitted. | ||
+ | <br />This code gets used to scheduling polling of IN interrupt endpoints, including those on hubs and HID devices. Thus, polling of these devices for status changes (in the case of hubs) or new input (in the case of HID devices) is done in software. This wakes up the CPU a lot and wastes time and energy. But with USB 2.0, there is no way around this, other than by suspending the USB device which we don't support. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPowerOn(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Power on the DWCOTG Host controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host to power on | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPowerOff(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Powers off the DWCOTG Host controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host to power off | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostCheck(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Check the DWC OTG USB Host Controller to confirm it is valid</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostInit(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Initialize the DWC OTG USB Host Controller with core USB settings and perform a host reset</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostSetup(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Configure the DWC OTG USB Host Controller with....</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostSetupDMA(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set up the DWC OTG USB Host Controller for DMA (direct memory access). This makes it possible for the Host Controller to directly access in-memory buffers when performing USB transfers</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostSetupInterrupts(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Performs initial setup of the Synopsys Designware USB 2.0 On-The-Go Controller (DWC) interrupts</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | The DWC contains several levels of interrupt registers, detailed in the following list. Note that for each level, each bit of the "interrupt" register contains the state of a pending interrupt (1 means interrupt pending; write 1 to clear), while the "interrupt mask" register has the same format but is used to turn the corresponding interrupt on or off (1 means on; write 1 to turn on; write 0 to turn off). | ||
+ | <br />- The AHB configuration register contains a mask bit used to enable/disable all interrupts whatsoever from the DWC hardware. | ||
+ | <br />- The "Core" interrupt and interrupt mask registers control top-level interrupts. For example, a single bit in these registers corresponds to all channel interrupts. | ||
+ | <br />- The "Host All Channels" interrupt and interrupt mask registers control all interrupts on each channel. | ||
+ | <br />- The "Channel" interrupt and interrupt mask registers, of which one copy exists for each channel, control individual interrupt types on that channel. | ||
+ | <br />We can assume that an interrupt only occurs if it is enabled in all the places listed above. Furthermore, it only seems to work to clear interrupts at the lowest level; for example, a channel interrupt must be cleared in its individual channel interrupt register rather than in one of the higher level interrupt registers. | ||
+ | <br />The above just covers the DWC-specific interrupt registers. In addition to those, the system will have other ways to control interrupts. For example, on the BCM2835 (Raspberry Pi), the interrupt line going to the DWC is just one of many dozen and can be enabled/disabled using the interrupt controller. In the code below we enable this interrupt line and register a handler function so that we can actually get interrupts from the DWC. | ||
+ | <br />And all that's in addition to the CPSR of the ARM processor itself, or the equivalent on other CPUs. So all in all, you literally have to enable interrupts in 6 different places to get an interrupt when a USB transfer has completed | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostStartFrameInterrupt(Host:PDWCUSBHost; Enable:Boolean):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCAllocateChannel(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the next available host channel on the supplied DWC host</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host to get available channel from | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | Channel number of the next available channel | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCReleaseChannel(Host:PDWCUSBHost; Channel:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Mark the specified host channel on the supplied DWC host as available</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host to mark available channel on | ||
+ | |- | ||
+ | ! '''Channel''' | ||
+ | | The channel number to mark as available | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCChannelStartTransfer(Host:PDWCUSBHost; Channel:LongWord; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Start or restart a USB request on a channel of the supplied DWC host</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host to start the request on | ||
+ | |- | ||
+ | ! '''Channel''' | ||
+ | | The channel number to start the request on | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | USB request to start | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the host lock | ||
+ | <br />Can be called by the interrupt handler | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCChannelStartTransaction(Host:PDWCUSBHost; Channel:LongWord; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Start a USB transaction on a channel of the supplied DWC host</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host to start the transaction on | ||
+ | |- | ||
+ | ! '''Channel''' | ||
+ | | The host channel number to start the transaction on | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | USB request set up for the next transaction | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the host lock | ||
+ | <br />Can be called by the interrupt handler | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPortReset(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Resets the DWC host port (The USB port that is attached to the root hub)</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPortPowerOn(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Powers on the DWC host port (The USB port that is attached to the root hub)</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPortGetStatus(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Read the Host Port Control and Status register with the intention of modifying it. Due to the inconsistent design of the bits in this register, this requires zeroing the write-clear bits so they aren't unintentionally cleared by writing back 1's to them</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPortSetFeature(Host:PDWCUSBHost; Feature:Word):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Handle a SetPortFeature request on the port attached to the root hub</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCHostPortClearFeature(Host:PDWCUSBHost; Feature:Word):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Handle a ClearPortFeature request on the port attached to the root hub</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure DWCHostPortStatusChanged(Host:PDWCUSBHost);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Complete any outstanding IN interrupt status change request</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host for the change request | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | <br />Can be called by the interrupt handler | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCRootHubRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Perform a request to the root hub</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host for the request | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | The USB request to perform | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCRootHubControlRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Perform a control request to or from the root hub</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host for the request | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | The USB request to perform | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCRootHubClassRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Perform a hub specific control request to the root hub</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host for the request | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | Hub specific request to the root hub | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCRootHubStandardRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Perform a standard (non hub specific) control request to the root hub</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWCOTG host for the request | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | Standard request to the root hub | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Caller must hold the Host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCSchedulerStart(Host:PDWCUSBHost):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Initialize a bitmask and semaphore that keep track of the Free/Used status of the host channels and a queue in which to place submitted USB transfer requests, then start the USB request scheduler thread</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCSchedulerExecute(Host:PDWCUSBHost):PtrInt;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' USB request scheduler thread</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | USB host to service submitted requests for | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | This thread receives requests that have been submitted and schedules them on the next available channel | ||
+ | <br />This is a very simplistic scheduler that does not take into account bandwidth requirements or which endpoint a transfer is for | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCCompletionExecute(Host:PDWCUSBHost):PtrInt;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' USB request completion thread</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | USB host to service completed requests for | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | This thread receives completed requests which have either succeeded or failed and calls the completion handler which will call the registered callback for the request | ||
+ | <br />This thread also receives requests that need to be resubmitted and resubmits them for later processing by another thread | ||
+ | <br />Message contents are as follows: | ||
+ | <br />Msg = Request to be completed | ||
+ | <br />wParam = Channel that the request executed on (or INVALID_HANDLE_VALUE if no channel was allocated) | ||
+ | <br />lParam = Status of the channel interrupt | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCResubmitExecute(Request:PUSBRequest):PtrInt;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' USB request resubmit thread</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | USB request to resubmit | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | An instance of this thread is created for each request that needs to be resubmitted, this thread then either waits for a predetermined number of milliseconds before scheduling the request on the next available channel or waits for a signal from the interrupt handler to indicate a start of frame before scheduling the request on the allocated channel | ||
+ | <br />Once the request has been resubmitted the thread waits for the semaphore to be signaled again. If the request is a periodic polling of an endpoint then it will be resubmitted continuously at the predetermined interval, otherwise the semaphore will be destroyed by the completion handler and the thread will terminate | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure DWCInterruptHandler(Host:PDWCUSBHost);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Interrupt handler for the DWCOTG controller</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host where the interrupt occurred | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCChannelInterrupt(Host:PDWCUSBHost; Channel:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Handle a channel interrupt on the specified channel</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host where the interrupt occurred | ||
+ | |- | ||
+ | ! '''Channel''' | ||
+ | | DWC host channel where the channel interrupt occurred | ||
+ | |- | ||
+ | ! '''Return''' | ||
+ | | USB_STATUS_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Only called by DWCInterruptHandler | ||
+ | <br />Caller must hold the host lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function DWCChannelCompleted(Host:PDWCUSBHost; Request:PUSBRequest; Channel,Interrupts:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Handle a channel interrupt where no error occurred</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! '''Request''' | ||
+ | | The USB request currently scheduled on this channel | ||
+ | |- | ||
+ | ! '''Host''' | ||
+ | | The DWC host where the interrupt occurred | ||
+ | |- | ||
+ | ! '''Channel''' | ||
+ | | DWC host channel where the channel interrupt occurred | ||
+ | |- | ||
+ | ! '''Interrupts''' | ||
+ | | The currently pending interrupts on this channel | ||
+ | |- | ||
+ | ! '''Note''' | ||
+ | | Only called by DWCChannelInterrupt | ||
+ | <br />Caller must hold the host lock | ||
|- | |- | ||
|} | |} |
Revision as of 05:15, 19 October 2016
Return to Unit Reference
Description
This is a USB Host Controller Driver (HCD) that interfaces with the Synopsys DesignWare Hi-Speed USB 2.0 On-The-Go Controller, henceforth abbreviated as "DWC". This is the USB Host Controller used on the BCM2835 SoC used on the Raspberry Pi.
Please note that there is no publicly available official documentation for this particular piece of hardware, and it uses its own custom host controller interface rather than a standard one such as EHCI. Therefore, this driver was written on a best-effort basis using several sources to glean the necessary hardware details, including the extremely complicated and difficult to understand vendor provided Linux driver.
This file implements the Host Controller Driver Interface defined in TUSBHost. Most importantly, it implements a function to power on and start the host controller (HostStart) and a function to send and receive messages over the USB (HostSubmit).
The DWC is controlled by reading and writing to/from memory-mapped registers. The most important registers are the host channel registers. On this particular hardware, a "host channel", or simply "channel", is a set of registers to which software can read and write to cause transactions to take place on the USB. A fixed number of host channels exist, on the Raspberry Pi there are 8. From the software's perspective, transactions using different host channels can be executed at the same time.
Some of the host channel registers, as well as other registers, deal with interrupts. This driver makes heavy use of these and performs all USB transfers in an interrupt-driven manner. However, due to design flaws in this hardware and in USB 2.0 itself, "interrupt" and "isochronous" transfers still need to make use of software polling when checking for new data, even though each individual transfer is itself interrupt-driven. This means that, for example, if your USB mouse specifies a polling rate of 100 times per second, then it will, unfortunately, be polled 100 times per second in software. For more detail about how interrupts can be controlled on this particular hardware, see the comment above DWCSetupInterrupts. Another important concept is the idea of "packets", "transactions", and "transfers". A USB transfer, such as a single control message or bulk request, may need to be split into multiple packets if it exceeds the endpoint's maximum packet size. Unfortunately, this has to be dealt with explicitly in this code, as this hardware doesn't do it for us. But at least, from the viewpoint of this software, a "transaction" is essentially the same as a "packet".
The "On-The-Go" in the name of this hardware means that it supports the USB On-The-Go protocol, which allows it to act either as a host or a device. However, we only are concerned with it acting as a host, which simplifies our driver.
To simplify the USB core software, a useful design technique (as recommended by the USB 2.0 standard and used in other implementations such as Linux's) is to have the HCD present the root hub as a standard USB hub, even if the root hub is integrated with the host controller and does not appear as a standard hub at the hardware level. This is the case with the DWC, and we implement this design. Therefore, some code in this file deals with faking requests sent to the root hub.
Constants
To be documented
Type definitions
To be documented
Public variables
To be documented
Function declarations
Initialization functions
procedure DWCInit;
Note | None documented |
---|
DWCOTG functions
function DWCHostStart(Host:PUSBHost):LongWord;
Note | See usb.pas for the documentation of this interface of the Host Controller Driver |
---|
function DWCHostStop(Host:PUSBHost):LongWord;
Note | See usb.pas for the documentation of this interface of the Host Controller Driver |
---|
function DWCHostReset(Host:PUSBHost):LongWord;
Note | None documented |
---|
function DWCHostResetEx(Host:PDWCUSBHost):LongWord;
Note | Caller must hold the Host lock |
---|
function DWCHostSubmit(Host:PUSBHost; Request:PUSBRequest):LongWord;
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
---|---|
Note | See usb.pas for the documentation of this interface of the Host Controller Driver
|
function DWCHostCancel(Host:PUSBHost; Request:PUSBRequest):LongWord;
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
---|---|
Note | See usb.pas for the documentation of thisinterface of the Host Controller Driver
|
function DWCHostResubmit(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;
Request | USB transfer to resubmit |
---|---|
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
Note | For periodic transfers (e.g. polling an interrupt endpoint), the exact time at which the transfer must be retried is specified by the bInterval member of the endpoint descriptor. For low and full-speed devices, bInterval specifies the number of millisconds to wait before the next poll, while for high-speed devices it specifies the exponent (plus one) of a power-of-two number of
milliseconds to wait before the next poll.
|
function DWCHostPowerOn(Host:PDWCUSBHost):LongWord;
Host | The DWCOTG host to power on |
---|---|
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
function DWCHostPowerOff(Host:PDWCUSBHost):LongWord;
Host | The DWCOTG host to power off |
---|---|
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
function DWCHostCheck(Host:PDWCUSBHost):LongWord;
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
---|
function DWCHostInit(Host:PDWCUSBHost):LongWord;
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
---|
function DWCHostSetup(Host:PDWCUSBHost):LongWord;
Note | None documented |
---|
function DWCHostSetupDMA(Host:PDWCUSBHost):LongWord;
Note | None documented |
---|
function DWCHostSetupInterrupts(Host:PDWCUSBHost):LongWord;
Note | The DWC contains several levels of interrupt registers, detailed in the following list. Note that for each level, each bit of the "interrupt" register contains the state of a pending interrupt (1 means interrupt pending; write 1 to clear), while the "interrupt mask" register has the same format but is used to turn the corresponding interrupt on or off (1 means on; write 1 to turn on; write 0 to turn off).
|
---|
function DWCHostStartFrameInterrupt(Host:PDWCUSBHost; Enable:Boolean):LongWord;
Note | None documented |
---|
function DWCAllocateChannel(Host:PDWCUSBHost):LongWord;
Host | The DWC host to get available channel from |
---|---|
Return | Channel number of the next available channel |
function DWCReleaseChannel(Host:PDWCUSBHost; Channel:LongWord):LongWord;
Host | The DWC host to mark available channel on |
---|---|
Channel | The channel number to mark as available |
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
function DWCChannelStartTransfer(Host:PDWCUSBHost; Channel:LongWord; Request:PUSBRequest):LongWord;
Host | The DWC host to start the request on |
---|---|
Channel | The channel number to start the request on |
Request | USB request to start |
Note | Caller must hold the host lock
|
function DWCChannelStartTransaction(Host:PDWCUSBHost; Channel:LongWord; Request:PUSBRequest):LongWord;
Host | The DWC host to start the transaction on |
---|---|
Channel | The host channel number to start the transaction on |
Request | USB request set up for the next transaction |
Note | Caller must hold the host lock
|
function DWCHostPortReset(Host:PDWCUSBHost):LongWord;
Note | Caller must hold the Host lock |
---|
function DWCHostPortPowerOn(Host:PDWCUSBHost):LongWord;
Note | Caller must hold the Host lock |
---|
function DWCHostPortGetStatus(Host:PDWCUSBHost):LongWord;
Note | Caller must hold the Host lock |
---|
function DWCHostPortSetFeature(Host:PDWCUSBHost; Feature:Word):LongWord;
Note | Caller must hold the Host lock |
---|
function DWCHostPortClearFeature(Host:PDWCUSBHost; Feature:Word):LongWord;
Note | Caller must hold the Host lock |
---|
procedure DWCHostPortStatusChanged(Host:PDWCUSBHost);
Host | The DWCOTG host for the change request |
---|---|
Note | Caller must hold the Host lock
|
function DWCRootHubRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;
Host | The DWCOTG host for the request |
---|---|
Request | The USB request to perform |
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
Note | Caller must hold the Host lock |
function DWCRootHubControlRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;
Host | The DWCOTG host for the request |
---|---|
Request | The USB request to perform |
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
Note | Caller must hold the Host lock |
function DWCRootHubClassRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;
Host | The DWCOTG host for the request |
---|---|
Request | Hub specific request to the root hub |
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
Note | Caller must hold the Host lock |
function DWCRootHubStandardRequest(Host:PDWCUSBHost; Request:PUSBRequest):LongWord;
Host | The DWCOTG host for the request |
---|---|
Request | Standard request to the root hub |
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
Note | Caller must hold the Host lock |
function DWCSchedulerStart(Host:PDWCUSBHost):LongWord;
Note | None documented |
---|
function DWCSchedulerExecute(Host:PDWCUSBHost):PtrInt;
Host | USB host to service submitted requests for |
---|---|
Note | This thread receives requests that have been submitted and schedules them on the next available channel
|
function DWCCompletionExecute(Host:PDWCUSBHost):PtrInt;
Host | USB host to service completed requests for |
---|---|
Note | This thread receives completed requests which have either succeeded or failed and calls the completion handler which will call the registered callback for the request
|
function DWCResubmitExecute(Request:PUSBRequest):PtrInt;
Request | USB request to resubmit |
---|---|
Note | An instance of this thread is created for each request that needs to be resubmitted, this thread then either waits for a predetermined number of milliseconds before scheduling the request on the next available channel or waits for a signal from the interrupt handler to indicate a start of frame before scheduling the request on the allocated channel
|
procedure DWCInterruptHandler(Host:PDWCUSBHost);
Host | The DWC host where the interrupt occurred |
---|
function DWCChannelInterrupt(Host:PDWCUSBHost; Channel:LongWord):LongWord;
Host | The DWC host where the interrupt occurred |
---|---|
Channel | DWC host channel where the channel interrupt occurred |
Return | USB_STATUS_SUCCESS if completed or another error code on failure |
Note | Only called by DWCInterruptHandler
|
function DWCChannelCompleted(Host:PDWCUSBHost; Request:PUSBRequest; Channel,Interrupts:LongWord):LongWord;
Request | The USB request currently scheduled on this channel |
---|---|
Host | The DWC host where the interrupt occurred |
Channel | DWC host channel where the channel interrupt occurred |
Interrupts | The currently pending interrupts on this channel |
Note | Only called by DWCChannelInterrupt
|
Return to Unit Reference