Bug in adi_usb_otg.c ( host mode, device enumeration )

I've been looking at the Host OTG USB Drivers, as our application will need to communicate with a 3G/4G modem all nearly all devices currently are USB based.

I'm very new to USB Device drivers and we just using the USB Mass Storage driver ( our software alreay integrates the FSS ), and I've been looking at the device enumeration aspects using the Debugger.

I noticed that when I plugged in a USB RS232 Converter ( this particular one is and FTTI chip ) the enumerated Device Descriptor was corrupted.

After alot of debugging I've tracked the issue down to the EnumDeviceStateMachine function in adi_usb_otg.c file.

in the

   case DEP_GET_DEV_DESCRIPTOR_1: is the line

          memcpy(pUsbOtgHostData->pRemoteDeviceObj->pDeviceDesc,pBuffer->Data,DEVICE_DESCRIPTOR_LEN);

but for this particular device the descriptor is delivered in a 16 byte transaction then a 2 byte transaction, thus the buffer being coppied into the pDeviceDesc only has the last 2 bytes resulting in a corrupted device descriptor.

I've modifed the line to read

          memcpy(pUsbOtgHostData->pRemoteDeviceObj->pDeviceDesc,pDevD, DEVICE_DESCRIPTOR_LEN);

and that from my testing now results in a complete device descriptor being give back to the upper level.

If this is not the place to report bugs please let me know.

If there is any more information that migh help me write a usd host mode driver please let me know as there appear to be very little documentation on host mode.

Development Setup

VisualDSP++ V5.0 Update 10

VDK based project

BF548 EzKit

Parents
  • The Device being attached is a USB 1.1 Usb-RS232 converter.

    Since i can now enumerate it correctly I can tell you thats its

    Maximum EP0 size is 8 bytes.

    I have not written any drivers for this yet, all testing was done with the FileSystemServices and the USB Mass Storage Driver.

    Obviously it does not recognise the RS232 converter but the USBHDRC driver still enumerates it.

    The fault is in this Enumeration.

    All code used is from the Library, although its is in My application you should see the same issue with the ShellBrowser example.

    Heres the relavent part of static s32_t EnumDeviceStateMachine(void *AppHandle,unsigned int wEvent,void *pArg)

    /*

    * We issued Get Device descrioptor request already. By the time we come here buffer should have

    * the obtained device descriptor.

    */

    case DEP_GET_DEV_DESCRIPTOR_1:

    {

    USB_ASSERT(pBuffer == NULL);

    pDevD = (PDEVICE_DESCRIPTOR)pDevO->pSetupData;  //cast to correct type and use later ( same colour )

    USB_ASSERT(pDevD->bDescriptorType != TYPE_DEVICE_DESCRIPTOR);

    USB_ASSERT(pUsbOtgHostData->pRemoteDeviceObj == NULL);

    /* Save any valid string descriptor indexes for later retrieval */

    if(pDevD->bIManufacturer > 0) { UPDATE_STRING_INDEX((s32_t)pDevD->bIManufacturer); };

    if(pDevD->bIProduct > 0)      { UPDATE_STRING_INDEX((s32_t)pDevD->bIProduct); };

    if(pDevD->bISerialNumber > 0) { UPDATE_STRING_INDEX((s32_t)pDevD->bISerialNumber); };

    // memcpy(pUsbOtgHostData->pRemoteDeviceObj->pDeviceDesc,pBuffer->Data,DEVICE_DESCRIPTOR_LEN);  // Copy DeviceDesc from buffer which may not contain the complete description

    memcpy(pUsbOtgHostData->pRemoteDeviceObj->pDeviceDesc,pDevD, DEVICE_DESCRIPTOR_LEN);   // Corrected copy Device desc from pSetupData where its been assembled

    #ifdef USB_OTG_PRINT_DESCRIPTOR

    adi_usb_PrintDeviceDescriptor(pUsbOtgHostData->pRemoteDeviceObj);

    #endif /* USB_OTG_PRINT_DESCRIPTOR */

    /* Request has been sent now move from Data phase to Status phase */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pBuffer);

    /* move from data phase to IDLE */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pBuffer);

    memset(pUsbOtgHostData->pSetupPkt,0,sizeof(SETUP_PACKET));

    pUsbOtgHostData->pSetupPkt->bmRequestType =  USB_DIR_DEVICE_TO_HOST | USB_TYPE_STANDARD | USB_RECIPIENT_DEVICE;

    pUsbOtgHostData->pSetupPkt->bRequest =  USB_STD_RQST_GET_DESCRIPTOR;

    pUsbOtgHostData->pSetupPkt->wValue   =  ((TYPE_CONFIGURATION_DESCRIPTOR << 8) & 0xffff);

    pUsbOtgHostData->pSetupPkt->wIndex   =  0x0000;

    pUsbOtgHostData->pSetupPkt->wLength  =  CONFIGURATION_DESCRIPTOR_LEN;

    pEpInfo->EpState                     = EP_STATE_IDLE;

    /* Puts the EpZero endpoint state machine in EP_STATE_SETUP_RQST_PHASE */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pUsbOtgHostData->pSetupPkt);

    ret = SendEpZeroDataEx(pDevO,(char*)pUsbOtgHostData->pSetupPkt,SETUP_PACKET_LEN);

    pUsbOtgHostData->eDepState = DEP_GET_CONFIG_DESCRIPTOR_0;

    pDevO->pSetupData      = pDevO->pSetupDataArea;

    pEpInfo->TransferSize  = CONFIGURATION_DESCRIPTOR_LEN;

    /* Move from SETUP RQST phase to data phase. Send IN token in case you are expecting data */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pUsbOtgHostData->pSetupPkt);

    USB_LOG_EVENT(HSD(GET_CONFIGURATION),pUsbOtgHostData->pSetupPkt->wValue,"SetupPkt: HTD-STD-RD-GET_CONFIGURATION_DESCRIPTOR");

    }

    break;

Reply
  • The Device being attached is a USB 1.1 Usb-RS232 converter.

    Since i can now enumerate it correctly I can tell you thats its

    Maximum EP0 size is 8 bytes.

    I have not written any drivers for this yet, all testing was done with the FileSystemServices and the USB Mass Storage Driver.

    Obviously it does not recognise the RS232 converter but the USBHDRC driver still enumerates it.

    The fault is in this Enumeration.

    All code used is from the Library, although its is in My application you should see the same issue with the ShellBrowser example.

    Heres the relavent part of static s32_t EnumDeviceStateMachine(void *AppHandle,unsigned int wEvent,void *pArg)

    /*

    * We issued Get Device descrioptor request already. By the time we come here buffer should have

    * the obtained device descriptor.

    */

    case DEP_GET_DEV_DESCRIPTOR_1:

    {

    USB_ASSERT(pBuffer == NULL);

    pDevD = (PDEVICE_DESCRIPTOR)pDevO->pSetupData;  //cast to correct type and use later ( same colour )

    USB_ASSERT(pDevD->bDescriptorType != TYPE_DEVICE_DESCRIPTOR);

    USB_ASSERT(pUsbOtgHostData->pRemoteDeviceObj == NULL);

    /* Save any valid string descriptor indexes for later retrieval */

    if(pDevD->bIManufacturer > 0) { UPDATE_STRING_INDEX((s32_t)pDevD->bIManufacturer); };

    if(pDevD->bIProduct > 0)      { UPDATE_STRING_INDEX((s32_t)pDevD->bIProduct); };

    if(pDevD->bISerialNumber > 0) { UPDATE_STRING_INDEX((s32_t)pDevD->bISerialNumber); };

    // memcpy(pUsbOtgHostData->pRemoteDeviceObj->pDeviceDesc,pBuffer->Data,DEVICE_DESCRIPTOR_LEN);  // Copy DeviceDesc from buffer which may not contain the complete description

    memcpy(pUsbOtgHostData->pRemoteDeviceObj->pDeviceDesc,pDevD, DEVICE_DESCRIPTOR_LEN);   // Corrected copy Device desc from pSetupData where its been assembled

    #ifdef USB_OTG_PRINT_DESCRIPTOR

    adi_usb_PrintDeviceDescriptor(pUsbOtgHostData->pRemoteDeviceObj);

    #endif /* USB_OTG_PRINT_DESCRIPTOR */

    /* Request has been sent now move from Data phase to Status phase */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pBuffer);

    /* move from data phase to IDLE */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pBuffer);

    memset(pUsbOtgHostData->pSetupPkt,0,sizeof(SETUP_PACKET));

    pUsbOtgHostData->pSetupPkt->bmRequestType =  USB_DIR_DEVICE_TO_HOST | USB_TYPE_STANDARD | USB_RECIPIENT_DEVICE;

    pUsbOtgHostData->pSetupPkt->bRequest =  USB_STD_RQST_GET_DESCRIPTOR;

    pUsbOtgHostData->pSetupPkt->wValue   =  ((TYPE_CONFIGURATION_DESCRIPTOR << 8) & 0xffff);

    pUsbOtgHostData->pSetupPkt->wIndex   =  0x0000;

    pUsbOtgHostData->pSetupPkt->wLength  =  CONFIGURATION_DESCRIPTOR_LEN;

    pEpInfo->EpState                     = EP_STATE_IDLE;

    /* Puts the EpZero endpoint state machine in EP_STATE_SETUP_RQST_PHASE */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pUsbOtgHostData->pSetupPkt);

    ret = SendEpZeroDataEx(pDevO,(char*)pUsbOtgHostData->pSetupPkt,SETUP_PACKET_LEN);

    pUsbOtgHostData->eDepState = DEP_GET_CONFIG_DESCRIPTOR_0;

    pDevO->pSetupData      = pDevO->pSetupDataArea;

    pEpInfo->TransferSize  = CONFIGURATION_DESCRIPTOR_LEN;

    /* Move from SETUP RQST phase to data phase. Send IN token in case you are expecting data */

    pEpInfo->EpStateMachineHandler(pDevO,0,(void*)pUsbOtgHostData->pSetupPkt);

    USB_LOG_EVENT(HSD(GET_CONFIGURATION),pUsbOtgHostData->pSetupPkt->wValue,"SetupPkt: HTD-STD-RD-GET_CONFIGURATION_DESCRIPTOR");

    }

    break;

Children
No Data