| 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);
}
|