Summary |
#include <RTL.h>
#include <rl_usb.h>
#include "usb_for_lib.h"
U8 Config (
U8 ctrl,
U8 port,
U8 spd,
U8 adr,
USB_CONFIGURATION_DESCRIPTOR *ptr_cfg_desc
);
|
Description |
The Config function is used for configuration of resources
for the new device instance of class. It will be called automatically
by the USB Host Core when new device of this class is attached. The
argument ctrl specifies controller index. The argument
port specifies the new device's port index. The argument
spd specifies the new device's enumerated speed. The argument
adr specifies the new device's enumerated address. The
argument ptr_cfg_desc specifies pointer to the new device's
configuration descriptor that is analyzed.
Configuration function has to fill Device Class Instance
(USBH_DCI) structure with
new device parameters and it also has to store any class specific
details needed for class specific handling (in example below these
parameters are stored in structure USBH_MSC, for example handle to IN
Endpoint, handle to OUT Endpoint ...), it also has to set Config bit
in Device Class Instance (USBH_DCI) structure to 1 after
initialization is successful.
You can modify this function to suit different class driver. This
function will need to be changed for class that does not have driver
provided.
|
Example |
/* MSC Class Driver Control Block */
USBH_DCD usbh_dcd_cls = {
USB_DEVICE_CLASS_STORAGE,
Config,
UnConfig,
Init,
UnInit,
GetLastError
};
static U8 Config (U8 ctrl, U8 port, U8 spd, U8 adr, USB_CONFIGURATION_DESCRIPTOR *ptrCfgDesc) {
USBH_HCI *ptrHCI;
USBH_HCD *ptrHCD;
USBH_DCI *ptrDCI;
USBH_MSC *ptrMSC;
USB_INTERFACE_DESCRIPTOR *ptrIntfcDesc;
USB_ENDPOINT_DESCRIPTOR *ptrEPDesc;
U8 num;
U8 dev_idx;
/* Find first free device class instance block */
for (dev_idx = 0; dev_idx <= usbh_msc_num; dev_idx++) {
if (dev_idx == usbh_msc_num)
return (255); /* Free block not found */
if (!(usbh_dci_msc[ctrl*usbh_msc_num+dev_idx].ptrMSC))
break; /* Free block found */
}
ptrHCI = &usbh_hci[ctrl];
ptrHCD = usbh_hcd_ptr[ctrl];
ptrDCI = &usbh_dci_msc[ctrl*usbh_msc_num+dev_idx];
ptrMSC = &usbh_msc[ctrl*usbh_msc_num+dev_idx];
if (!ptrHCI) {
USBH_MSC_SetLastError (ctrl, dev_idx, ERROR_USBH_HCI);
return (__FALSE);
}
if (!ptrHCD) {
USBH_MSC_SetLastError (ctrl, dev_idx, ERROR_USBH_HCD);
return (255);
}
if (!ptrDCI) {
USBH_MSC_SetLastError (ctrl, dev_idx, ERROR_USBH_DCI);
return (255);
}
if (!ptrMSC) {
USBH_MSC_SetLastError (ctrl, dev_idx, ERROR_USBH_MSC);
return (255);
}
memset (ptrDCI, 0, sizeof (USBH_DCI));
memset (ptrMSC, 0, sizeof (USBH_MSC));
ptrDCI->ptrMSC = ptrMSC;
ptrIntfcDesc = (USB_INTERFACE_DESCRIPTOR *)((U32)ptrCfgDesc + ptrCfgDesc->bLength);
num = ptrIntfcDesc->bNumEndpoints; /* Number of endpoints */
switch (ptrIntfcDesc->bInterfaceClass) {
case USB_DEVICE_CLASS_STORAGE:
switch (ptrIntfcDesc->bInterfaceSubClass) {
case MSC_SUBCLASS_SCSI: /* SCSI transparent command set */
if (ptrIntfcDesc->bInterfaceProtocol == MSC_PROTOCOL_BULK_ONLY) {
ptrDCI->Protocol = MSC_PROTOCOL_BULK_ONLY;
ptrDCI->Port = port;
ptrDCI->Address = adr;
ptrDCI->Speed = spd;
/* Bulk only */
ptrEPDesc = (USB_ENDPOINT_DESCRIPTOR *)((U32)ptrIntfcDesc + ptrIntfcDesc->bLength);
while (num--) {
if ((ptrEPDesc->bmAttributes & 3) == 2) { /* Bulk Endpoint */
if (ptrEPDesc->bEndpointAddress & 0x80) { /* IN Endpoint */
ptrMSC->BulkInEP.Handle = ptrHCD->ep_add (adr, spd, ptrEPDesc);
if (!(ptrMSC->BulkInEP.Handle)) {
USBH_MSC_SetLastError (ctrl, dev_idx, ERROR_USBH_EP_ADD);
return (255);
}
ptrMSC->BulkInEP.Descriptor = *ptrEPDesc;
} else { /* OUT Endpoint */
ptrMSC->BulkOutEP.Handle = ptrHCD->ep_add (adr, spd, ptrEPDesc);
if (!(ptrMSC->BulkOutEP.Handle)) {
USBH_MSC_SetLastError (ctrl, dev_idx, ERROR_USBH_EP_ADD);
return (255);
}
ptrMSC->BulkOutEP.Descriptor = *ptrEPDesc;
}
}
ptrEPDesc++;
}
}
break;
}
break;
}
ptrDCI->Config = 1;
return (dev_idx);
}
|