This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

usb bulk not reporting USB_EVENT_RX_AVAILABLE events

Other Parts Discussed in Thread: SYSBIOS, TM4C1294KCPDT

TIVAWARE is not posting a USB_EVENT_RX_AVAILABLE event even when connected.

We have an existing Stellarisware + SYSBIOS - based product that I am porting to the TM4C1294KCPT chip.  The Stellarisware version easily connects and exchanges data with a PC running a proprietary application.  I am unable to get the TIVAWARE product to communicate. 

Background:  I am running TI-RTOS version 2.12.01.33 and the TIVAWARE version 2.1.0.12573c that came with the TI-RTOS distribution.  The USB port is OTG which is not supported by the TI-RTOS driver.  So, I have generated a wrapper function to handle the interrupt call differences between TIVAWARE and TI-RTOS:

void USB0OTGModeIntHandler_wrapper(UArg arg)
{
    USB0OTGModeIntHandler();
}

On the device side of the OTG I am using the TIVAWARE Bulk Device Class Driver with the USB Buffer API:

tBulkInstance g_sBulkInstance;

tUSBDBulkDevice g_sBulkDevice =    // TIVAWARE change:  cannot be a const.
                                // Note that some TIVAWARE docs say this can be a const,
                                // but Section 3.7 of the Stellarisware -> TIVAWARE
                                // migration document state that USBLib makes changes
                                // to some of the data fields....
{
    //USB_VID_STELLARIS,
    //USB_PID_BULK,
    USB_VID_NEWPORT,
    USB_PID_OPENLOOP_IPICO,
    500,
    USB_CONF_ATTR_SELF_PWR,
    USBBufferEventCallback,
    (void *)&g_sRxBuffer,
    USBBufferEventCallback,
    (void *)&g_sTxBuffer,
    g_ppui8StringDescriptors,
    NUM_STRING_DESCRIPTORS
};

//*****************************************************************************
//
// Receive buffer (from the USB perspective).
//
//*****************************************************************************
uint8_t g_pui8USBRxBuffer[BULK_BUFFER_SIZE];
uint8_t g_pui8RxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];
tUSBBuffer g_sRxBuffer =
{
    false,                           // This is a receive buffer.
    RxHandler,                       // pfnCallback
    (void *)&g_sBulkDevice,          // Callback data is our device pointer.
    USBDBulkPacketRead,              // pfnTransfer
    USBDBulkRxPacketAvailable,       // pfnAvailable
    (void *)&g_sBulkDevice,          // pvHandle
    g_pui8USBRxBuffer,               // pcBuffer
    BULK_BUFFER_SIZE,                // ulBufferSize
    g_pui8RxBufferWorkspace          // pvWorkspace
};

//*****************************************************************************
//
// Transmit buffer (from the USB perspective).
//
//*****************************************************************************
uint8_t g_pui8USBTxBuffer[BULK_BUFFER_SIZE];
uint8_t g_pui8TxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];
tUSBBuffer g_sTxBuffer =
{
    true,                            // This is a transmit buffer.
    TxHandler,                       // pfnCallback
    (void *)&g_sBulkDevice,          // Callback data is our device pointer.
    USBDBulkPacketWrite,             // pfnTransfer
    USBDBulkTxPacketAvailable,       // pfnAvailable
    (void *)&g_sBulkDevice,          // pvHandle
    g_pui8USBTxBuffer,                // pcBuffer
    BULK_BUFFER_SIZE,                // ulBufferSize
    g_pui8TxBufferWorkspace           // pvWorkspace
};

The windows device manager sees the TIVAWARE-version device just fine, but the proprietary application on the host PC is unable to connect.  That application sees the initial attach and sends an inquiry message to the TIVAWARE device, but the TIVAWARE never reports a USB_EVENT_RX_AVAILABLE event to my rxRxHandler function.  Hence, no response is returned to the proprietary application and it ultimately times out.

More specifically, when the USB cable is attached to the PC, 3 or 4 USB_EVENT_SUSPEND events are reported to RxHandler (which my code ignores) followed by a USB_EVENT_CONNECTED event which I do handle.  When the application then sends its inquiry, nothing happens on the TIVA device because no USB_EVENT_RX_AVAILABLE is posted .  If the USB cable is subsequently removed, several USB_EVENT_SUSPEND are posted (which I again ignore) and then nothing.  I definitely do not get a USB_EVENT_DISCONNECTED.

So there are two issues that may be related -- the failure to post USB_EVENT_RX_AVAILABLE events when data is sent and the failure to post USB_EVENT_DISCONNECTED when the USB cable is disconnected.

  • Hello Tom,

    There have been a few problems reported in USB for TivaWare 2.1.0-12573 that were subsequently fixed in 2.1.1.71

    TI-RTOS 2.14.00.10 has the latest TivaWare with the fixes. Now since lot of the information is proprietary and Windows device manager since the TM4C device, I suspect a basic code may not be useful.

    What can be checked is putting a breakpoint on the interrupt handler to see if it is being called when the PC application sends a Data request packet to the TM4C uC.

    Regards
    Amit
  • Hi Amit,


    What else can you suggest?

    I updated to TI-RTOS 2.14.00.10 with TIVAWARE 2.1.1.71.  I needed to make a couple of changes related to the change to the private workspace area change but everything else compiled fine.  Unfortunately, the behavior is the same as before in that my RxHandler does not receive USB_EVENT_RX_AVAILABLE nor USB_EVENT_DISCONNECTED events.

    I tried putting a breakpoint on the interrupt handler, but it keeps firing off on SOF interrupts which seem to be handled by the void USBDeviceIntHandlerInternal(uint32_t ui32Index, uint32_t ui32Status) function in the TIVAWARE usbdenum.c file.  Is there some other place to put an breakpoint?

    Regards,

    Tom

  • Hello Tom,

    Yes, in the file usbdenum.c you can put a breakpoint at

    if((g_ppsDevInfo[0]->psCallbacks->pfnEndpointHandler) &&
    ((ui32Status != 0) || (ui32DMAIntStatus != 0)))
    {
    >> g_ppsDevInfo[0]->psCallbacks->pfnEndpointHandler(pvInstance, ui32Status); // Put BP here to see if the call back function is getting executed or not...
    }

    Regards,
    Amit
  • Hi Amit,

    I put a breakpoint at the point you indicated; the breakpoint never tripped. Just to make sure I subsequently added a breakpoint to the IF statement; that trips frequently (more than 1 per second of execution time).

    What do you suggest we do next?

    Regards,
    Tom

    P.S. I don't know if this matters, but here is how I am setting up the interrupt handling:

        //------------------------------------------------------------------------------------------------------
        //    Set up the HAL to deal with USBOTG interrupts
        //------------------------------------------------------------------------------------------------------

        Error_init(&eb);

        Hwi_Params_init(&USBOTG_Hwi_Params);
        USBOTG_Hwi_Params.priority = USB0_Priority;
        USBOTG_Hwi_Params.enableInt = true;

        USBOTG_Hwi_Handle = Hwi_create(INT_USB0, USB0OTGModeIntHandler_wrapper, &USBOTG_Hwi_Params, &eb);
        if (NULL == USBOTG_Hwi_Handle)
        {
            System_abort("USBOTG Hwi create failed");
        }

  • Hello Tom,

    So it seems that the call back function is not being registered in the TI RTOS. The first thing to check would be to see what are the variables value when the if statement break point is tripped, to make sure that indeed g_ppsDevInfo[0]->psCallbacks->pfnEndpointHandler is the false condition.

    Regards
    Amit
  • Hi Amit,

    The if statement break point is tripped, but it is never true because ui32Status and ui32DMAIntStatus are always 0.

    So, I put breakpoints on lines 3157 and 3171 of usbdenum.c. The one at 3157 trips a few times when the USB connector is inserted. Once the connection is established, I start my PC application which senses the attach and attempts to send a '*IDN?<cr>' to the Tiva-based board. Neither interrupt trips when the application attempts to send its first string. Eventually the PC application times out, but the Windows Device Manager still shows the device to be connected.

    //
    // Handle end point 0 interrupts.
    //
    if(ui32Status & USB_INTEP_0)
    {
    USBDeviceEnumHandler(&g_psDCDInst[0]); // This is line 3157 of usbdenum.c (TF)
    ui32Status &= ~USB_INTEP_0;
    }

    //
    // Check to see if any DMA transfers are pending
    //
    ui32DMAIntStatus = USBLibDMAIntStatus(g_psDCDInst[0].psDMAInstance);

    if(ui32DMAIntStatus)
    {
    //
    // Handle any DMA interrupt processing.
    //
    USBLibDMAIntHandler(g_psDCDInst[0].psDMAInstance, ui32DMAIntStatus); // This is line 3171.
    }

    What shall I try next?

    Regards,
    Tom
  • Hello Tom

    Can you please send a register dump of the USB address space?

    Since the ui32DMAIntStatus is 0, it would mean that the DMA is not being used/configured in the application
    The ui32Status being 0 would mean the interrupt enable bits for the EP's are getting cleared for some reason and not computing

    Also is the control message being sent on EP0 or some other End Point from the PC Host?

    Regards
    Amit
  • Hi Amit,

    1.  I will not be able to answer your endpoint question until I can speak with the engineer responsible for the application.  I expect that will be around noon our time (PDT).

    2.  Please confirm that the dump region you want is 0x40050000 thru 0x40050FFF.  (The device is a TM4C1294KCPDT.)

    3.  What format do you want the dump, TI DATA or something else?  The memory save dialog box has three other choices -- COFF, TI RAW DATA, and Binary.

    4.  When do you want the dumps?  I assume that you will want one before the cable is inserted, one after the windows device manager has recognized the device, and one after the PC application has failed in its attempt to send data to the TIVA device. Please advise if you prefer something else/more.

    5. The files are quite large.  It might be better to email them to you rather than post them here.  Please send an email to the address associated with my myti account indicating how I should deliver these files to you.

    Regards,

    Tom

  • Hello Tom

    #2-#3: Yes, the USB register address space. It can be a simple snapshot or file dump in txt format.
    #4: Yes, that is correct.
    #5: The file can be easily attached to a forum post. We have attached MB worth of files on the forum.

    Regards
    Amit
  • Hi Amit,

    As for the endpoints, we believe endpoint 2 is being used to send the *IDN? command from the PC to the TIVA device. We believe endpoint 1 is being used for the return data pipe.

    How do I attach a file to the forum? The only options I see on this web site are "Like", "Cancel", "Verify Answer", "Suggest Answer", "Reply", and "More". The more only allows me to flag the post as spam/abuse.

    Alternatively I can cut and paste the files into this text box, but they are really long.....

    Tom
  • Hello Tom,

    When you reply to the post, then on the bottom right you will see "Use rich formatting". That will give the option to attach a file.

    When you mentioned endpoint 2 to send the command, does it mean RX endpoint 2 or RX endpoint 1. Note that RX endpoint 0 is the control end point.

    Regards
    Amit
  • Hi Amit,

    BTW -- I noticed at line 73 of Tivaware usbdbulk.c that the two endpoint are the same. I thought these needed to be different per the USB specification. In the Stellarisware usbdbulk.c DATA_OUT_ENDPOINT is set to USB_EP_2....

    Here is the Tivaware version:
    //*****************************************************************************
    //
    // Endpoints to use for each of the required endpoints in the driver.'
    //
    //*****************************************************************************
    #define DATA_IN_ENDPOINT USB_EP_1
    #define DATA_OUT_ENDPOINT USB_EP_1

    Regards,
    Tom
  • Hello Tom

    And that is what my last post did mention. The USB_EP_1 has both TX and RX to it. So you may be sending it on USB_EP_2 and that is why it is not being received by the controller as the USB controller is looking at USB_EP_1

    Regards
    Amit
  • Hi Amit,

    Why was this changed? It is a REALLY big deal if my TIVAWARE version of the product is not form/fit/function IDENTICAL to the existing Stellarisware one. Besides, everything I have seen on USB bulk transfers says that the two pipes should have different end points...

    Is this a bug that TI will fix in future versions of TIVAWARE, or will things remain this way going forward? Will editing the usbdbulk.c file to use EP2 have secondary impacts?

    Later today I will try modifying the TIVAWARE usbdbulk.c file (and rebuild usblib) to see if that resolves my immediate issue. But I also need to know what we will need to support this in the future...

    Regards,
    Tom
  • Hello Tom,

    I checked version 9453 of the StellarisWare release and it has the same lines. Could it have been modified for your application?

    //*****************************************************************************
    //
    // Endpoints to use for each of the required endpoints in the driver.
    //
    //*****************************************************************************
    #define DATA_IN_ENDPOINT USB_EP_1
    #define DATA_OUT_ENDPOINT USB_EP_1

    Regards
    Amit
  • Hi Amit,

    The previous product was based on Stellarisware version 8132.0.0.

    You raise an interesting point -- it is possible my predecessor modified the Stellarisware..... Is there some way I can get a copy of the official v8132.0.0? I wonder if anything else got changed.....

    Regards,
    Tom
  • Hello Tom

    No. Only the last working copy of the StellarisWare are available at the following link.

    http://www.ti.com/tool/sw-lm3s

    Regards
    Amit
  • Hi Amit,

    This is is now resolved and the interface is working. For those that run into this problem and find this posting, here is the resolution:

    The standard TIVAWARE and (STELLARISWARE) implementations do not match that described in the Don Anderson book "Universal Serial Bus System Architecture" (Mindshare, Inc publisher) that many of us use (Figure 6-1 on page 120 of the second edition). That figure shows three pipes, a bidirectional control pipe on endpoint 0, a unidirectional data-in pipe on a different endpoint, and a unidirectional data-out pipe on another endpoint. The TIVAWARE device bulk software (in usbdbulk.c) puts both the data-in and data-out on Endpoint 1.

    My company's standard convention is data-in on endpoint 1 and data-out on endpoint 2. I was able to make things work by editing the usbdbulk.c file in the TIVAWARE to change the #define DATA_OUT_ENDPOINT from USB_EP_1 to USB_EP_2. I also added a readme.h to my source code and identified this TIVAWARE modification so subsequent engineers maintaining my code will not run into this again (hopefully).

    Anyway, changing this one #define resolved the issue and the USB interface now works correctly for me.

    Tom
  • Hello Tom,

    Thanks for the information. Note that the version of StellarisWare was a very old version and since we do not have the source modification status it could have been a change done locally.

    Regards
    Amit