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 plug in unrecognisable

Hello again,

I've been trying to handle this issue for the past month unsuccessfully, so at the end I decided to ask if you guys could help.

The brief description of the problem is that after a USB stick is reattached to the hub the controller does not register it at all. On the older version of the project I am working on, the USB could be somtimes recognised, but in the majority of cases the controller was not able to find a device descriptor and the function USBHMSCDriveReady( g_psMSCInstance ) used to always return -1 because psMSCInstance->psDevice was always 0. psMSCInstance is the structure containing the instance of a USB host driver and the psDevice is the structure containing the device information. Without any changes made to the USB part in the new project, the program does not output properly from the USBOTGMain function, as it always gives eUSBModeNone as output. I cannot put breakpoints in the mode.c file and cannot change anything in it so I am not quite sure what exactly is the root of the issue.

This is how the USB is initialised in the code:

void TIVA_Init_USB0( void )
{
    // Enable the USB peripheral
    MAP_SysCtlPeripheralEnable( SYSCTL_PERIPH_USB0 );

    // Initialize the USB stack mode and pass in a mode callback.
    USBStackModeSet( 0, eUSBModeOTG, ModeCallback );

    // Initialize the stack to be used with USB stick.
    USBStickInit();

    // TODO Initialize the stack to be used as a serial device.

    USBOTGModeInit( 0, 40, g_pui8HCDPool, HCD_MEMORY_SIZE );        // STM (Originally 40ms Polling rate)


    usbInit = true;            // STM

    // TODO Test
    IntPrioritySet( INT_USB0, 0x0 );

}

void USBStickInit( void )
{
    //
    // Enable the uDMA controller and set up the control table base.
    // The uDMA controller is used by the USB library.
    //
    MAP_SysCtlPeripheralEnable( SYSCTL_PERIPH_UDMA );
    MAP_uDMAEnable();
    MAP_uDMAControlBaseSet( g_psDMAControlTable );

    //
    // Initially wait for device connection.
    //
    g_iState = eSTATE_NO_DEVICE;

    //
    // Register the host class drivers.
    //
    USBHCDRegisterDrivers( 0, g_ppHostClassDrivers, g_ui32NumHostClassDrivers );

    //
    // Open an instance of the mass storage class driver.
    //
    g_psMSCInstance = USBHMSCDriveOpen( 0, MSCCallback );

    USBHCDPowerConfigInit( 0, USBHCD_VBUS_AUTO_LOW | USBHCD_VBUS_FILTER );

    //
    // Run initial pass through USB host stack.
    //
    USBHCDMain();

    //
    // Initialize the file system.
    //
    FileInit();
}

This is the function, called periodically from an event based interrupt, to operate the USB data logging:

void usb_go( void )
{

    USBOTGMain( GetTickms() );


    if( g_iCurrentUSBMode == eUSBModeHost )
    {
        USBStickRun();
    }

}

void USBStickRun( void )
{
    //
    // Call the USB stack to keep it running.
    //
    USBHCDMain();

    //
    // Take action based on the application state.
    //
    switch( g_iState )
    {
        //
        // A device has enumerated.
        //
        case eSTATE_DEVICE_ENUM:
        {
            //
            // Check to see if the device is ready.  If not then stay
            // in this state and we will check it again on the next pass.
            //
            if( USBHMSCDriveReady( g_psMSCInstance ) != 0 )
            {
                //
                // Wait about 500ms before attempting to check if the
                // device is ready again.
                //
                MAP_SysCtlDelay( MAP_SysCtlClockGet() / 15 );
                break;
            }

            //
            // If there were no errors reported, we are ready for
            // MSC operation.
            //
            g_iState = eSTATE_DEVICE_READY;

            break;
        }

        //
        // If there is no device then just wait for one.
        //
        case eSTATE_NO_DEVICE:
        {

            break;
        }

        //
        // An unknown device was connected.
        //
        case eSTATE_UNKNOWN_DEVICE:
        {

            break;
        }

        //
        // The device is ready and in use.
        //
        case eSTATE_DEVICE_READY:
        {

            break;
        }

        //
        // Something has caused a power fault.
        //
        case eSTATE_POWER_FAULT:
        {
            break;
        }

        //
        // Unexpected USB state.  Set back to default.
        //
        default:
        {
            g_iState = eSTATE_NO_DEVICE;
            break;
        }
    }
}

And that's the Modecall, essentially does not do anything:

void ModeCallback( uint32_t ui32Index, tUSBMode iMode )
{
    //
    // Save the new mode.
    //
    g_iCurrentUSBMode = iMode;

    // Mode-specific handling code could go here.
    switch( iMode )
    {
        case eUSBModeHost:
        {

            if( usbInit == false )                                            // STM
            {
            MAP_SysCtlPeripheralDisable( SYSCTL_PERIPH_USB0 );
            MAP_SysCtlPeripheralEnable( SYSCTL_PERIPH_USB0 );
            MAP_SysCtlPeripheralReset( SYSCTL_PERIPH_USB0 );
            TIVA_Init_USB0();
            USBStickInit();

            usbInit = true;
            }

            break;                // STM Reset peripheral and initialize USB stick
        }
        case eUSBModeDevice:
        {

            break;
        }
        case eUSBModeOTG:
        {
            break;
        }
        case eUSBModeNone:
        {
            break;
        }
        case eUSBModeForceHost:
        {
            break;
        }
        case eUSBModeForceDevice:
        {
            break;
        }
        default:
        {

            break;
        }
    }
}

Should I change the modecallback or the OTG mode call from the initialisation or should look for the problem somewhere else?

Thank you!

  • Hello Stamen

    Is OTG mode required? If not then use the forced Host or Device mode.

    Regards
    Amit
  • Hello Amit,
    Thanks for the fast responses.

    It is required, as I would like to be able to log data directly to a PC in the next step of the development.
    Maybe if I could set a breakpoint in mode.c and make changes to it I could find the specific issue.
    I also use the dual-disk-drive to log data to both the sd card an the USB, but as far as I could tell it works properly, so doesn't have anything to do with this problem.
    I also tried to re-initialise after a disconnect event has occurred but it doesn't work either.

    Regards,
    Stamen
  • Hello Stamen.

    Is the interrupt handler mapped for the OTG Interrupt call or to the device interrupt call. There is an OTG example in the TM4C1294 data base. Can you first use the same to baseline your hardware?

    Regards
    Amit
  • Hello Amit,
    I wasn't able to check the forum earlier than that.
    The USB0 interrupt is mapped to the OTG interrupt handler. Unofrtunately I haven't been able to find the OTG example project in the examples I have.
    Best,
    Stamen
  • Hello Stamen,

    Please have a look at the example project. If this otg example folder is not there, then download the full version installer for TivaWare

    D:\ti\TivaWare_C_Series-2.1.1.71\examples\boards\dk-tm4c129x\usb_otg_mouse

    Regards
    Amit
  • Hey again Amit,
    I'm sorry I didn't reply earlier, but some other problems with the BMS occurred and we had to solve them first.
    At the end the controller started to recognise the USB when I re-plug it, but unfortunately the misfunction still persists.
    As we use it in car applications the battery management system that uses the TI controller communicates between different modules and measurement devices using CAN communication. The USB data logging event used to be set every 50ms, which is also the the period of the data flow of the CAN. It also used to log data in 4 byte chunks directly from the CAN. However, some of the data was missing because, I guess, the CAN and the USB event are not synchronised. When we used a buffer to store the USB data temporarily and set the event on each second, the USB started behaving properly when we plug it in and out.
    Now the question is how to make it work withour using the buffer.
    Thanks and regards,
    Stamen
  • Hello Stamen,

    A buffer would be required and the USB and CAN would need to be synchronized with a software flag (semaphore). If the USB has not stored the data then CAN must not put a new message and ask for retransmission of the last message. Alternatively a ring buffer can be used so that CAN can keep on writing a new message while USB if not synchronized can empty it.

    Regards
    Amit
  • Thanks Amit, I'll try that.