Post Go back to editing

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

  • Depending on the maximum endpoint size there could be multiple transactions in a transfer. It appears like your device is a full speed device with maximum ep0 size of 16 bytes. confirm. Also are you getting any errors? The driver should not return the buffer until the entire transfer is complete. Is it returning the buffer partially? Also are you enabling data cache? If so does the behavior change if data cache is disabled?

    -Srinivas.

  • 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;

  • Thank your for the clarification. It appears like with full/low speed devices the handler is returning prematurely. We should stay in the data phase until the entire data is accumlated and then process it.Thank you for reporting the problem, we will log a bug for this problem and schedule the fix in the subsequent releases.

    -Srinivas.