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.

TMS320F28377S: TMS320F28377S: TMS320F28379D: USB examples from C2000Ware events problems

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

Hello,

I'm on a F28377s board and my problem was about USB (code use the exemple USB CDC)

My problem is about this post but which was closed..:

https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/632973

It was on the USB ControlHandler notification:

When I connect the USB cable between computer and my board, I receive the notification ControlHandler with Event = 0 = CONNECTED.

In the same handler, there are a case for "DISCONNECT"

Then the reported problem was this "DISCONNECT" event was not received when the cable is plug out.

The solution provide to me is to implement a routine on the USB Power pin get on a GPIO.

When this pin goes high, call USBDevConnect, then when this pin goes low (cable unplug), call USBDevDisconnect.

This is what I do, but the ControlHandler is not called on cable unplug after USBDevDisconnect was called...

Then also, the Event "Connect" not called when cable is plugged again.

:-(

My aim is to inform application the cable is plugged or not to switch an internal mode needed on higher layer.

  • Hi,

    It is strange, ,the call to USBDevDisconnect place the bit SOFTCONN of USB_POWER register to 0, this generate the IT in USB_IS bit DISCON to 1 (0xFE)

    But on USBIntStatus:

    USBIntStatus(uint32_t ui32Base, uint32_t *pui32IntStatusEP)
    
    {
    
       uint32_t ui32Status = 0;
    
       *pui32IntStatusEP = 0;
    
       uint32_t usbis = 0;
    
       uint32_t rxis = 0;
    
       uint32_t txis = 0;
    
       //
    
       // Check the arguments.
    
       //
    
       ASSERT(ui32Base == USB0_BASE);
    
       //
    
       // Do-While to make sure that all status registers are cleared before continuing.
    
       // This eliminates the race condition which can cause the USB interrupt to stay high
    
       // and never get triggered again.
    
       //
    
       do
    
       {
    
           // Get the general interrupt status.
    
           usbis = (uint32_t)HWREGB(ui32Base + USB_O_IS);
    
           // Get the transmit interrupt status.
    
           txis = (uint32_t)HWREGH(ui32Base + USB_O_TXIS);
    
           // Get the receive interrupt status.
    
           rxis = (uint32_t)HWREGH(ui32Base + USB_O_RXIS);
    
           // Get the general interrupt status, these bits go into the upper 8 bits
    
           // of the returned value.
    
           ui32Status |= usbis;
    
           // Get the transmit interrupt status.
    
           *pui32IntStatusEP |= txis;
    
           // Get the receive interrupt status, these bits go into the second byte of
    
           // the returned value.
    
           *pui32IntStatusEP |= ((uint32_t)rxis << USB_INTEP_RX_SHIFT);
    
       } while(usbis != 0x0000 || txis != 0x0000 || rxis != 0x0000);
    

     ...

    The read of the status lead to get ui32Status=0!

    Then after that the handler which is called with the status to 0 can't react to the "Disconnect" event..

    ???

  • Hi A GIR,

    We are trying to look into this.
    Will get back to you shortly.

    Thanks and Regards
    Harshmeet Singh
  • Hi,

    As a device the USB controller will not generate an interrupt due to a disconnect.

    You can monitor VBUS to set and clear the SOFTCONN bit accordingly.

    What is the exact issue and sequence of events you are seeing?

    Regards,
    sal
  • I test the solution proposed to me on the link placed above (Too bad this post was closed :-( )

    if(GpioDataRegs.GPBDAT.bit.GPIO46 == 1)

    {

    USBDevConnect(USB0_BASE);

    }

    else

    {

    USBDevDisconnect(USB0_BASE);

    }

    But this no generate the Handler with "Disconnect" information.

    I remember my aim: Know when the USB cable was unplug quite simply!

  • Hi,

    This will not create a disconnect event. By monitoring VBUS you can determine if it is disconnected.

    For more information, please see the TRM chapter on USB and the USB Library User Guide in C2000Ware.

    sal
  • Hi,

    So it is was the aim of my post linked above where the solution provided to me was this :-(

    Then: How be called by pfnControlCallback with the ui32Event = 1 ?

    //
    //! The device has been disconnected from the USB host (used by device classes
    //! only).
    //!
    //! Note: Due to a hardware erratum in revision A of LM3S3748, this
    //! event is not posted to self-powered USB devices when they are disconnected
    //! from the USB host.
    //
    #define USB_EVENT_DISCONNECTED (USB_EVENT_BASE + 1)
    

  • The user guide has this below:

    4.3.3.7 USB_EVENT_DISCONNECTED
    Definition:
    #define USB_EVENT_DISCONNECTED
    Description:
    The device has been disconnected from the USB host (used by device classes only).
    Note:
    In device mode, the USB_EVENT_DISCONNECTED will not be reported if the MCU’s
    PB1/USB0VBUS pin is connected to a fixed +5 Volts rather than directly to the VBUS pin
    on the USB connector.

    There is no interrupt generated when the device is disconnected from the host. I believe you will have to monitor the VBUS pin yourself. You can then set the disconnected event status and call the callback function from your application.

    sal
  • Ok,

    I implement this:

      uint8_t NewPowerStatus;  
      
      NewPowerStatus = DV_Gpio_GetMacro(DV_GPIO_USB_POWER_INFO_ID);
    
      if (IsRisingEdge(NewPowerStatus, DV_Usb_PowerOldStatus))
      {
        USBDevConnect(USBA_BASE);
      }
      else if (IsFallingEdge(NewPowerStatus, DV_Usb_PowerOldStatus))
    
      {
        USBDevDisconnect(USBA_BASE);
        DV_Usb_iControlHandler(NULL, USB_EVENT_DISCONNECTED, 0, NULL);
      }
      
      DV_Usb_PowerOldStatus = NewPowerStatus;
    

    But when cable is plug again, the Event connected is not called again.

    If i call it on Rising edge detection, on the first plug, the call back will be called twice. (By the USB stack, and by my patch above)..

  • It looks like you are getting close to what you need.

    In your application, do not set SOFTCONN until you see the VBUS pin go high. Or you can set at first, and then clear it once your application determines VBUS is low.

    You can create an external interrupt (XINT) based on VBUS, and have it triggered on rising or falling edge. Then inside the ISR check the status of VBUS. If VBUS is high, then set SOFTCONN. If VBUS is low, then clear SOFTCONN.

    Hope this helps.

    sal
  • Hi,


    Detect the rising and Falling edge of the VBUS on a GPIO is exactly what I do in the code written above. I can't use external interrupt XINT because on my application, there are all used!.


    So I use a background task which pull the GPIO every 1 ms. Then I do exactly you said:


    If VBUS is High then set SOFTCONN bit. If VBUS is low then clear SOFTCONN. I don't know exactly what is the impact of this. It seem this set the USB pin D+/D- in tri-state or not. But in anyway, this not lead to a calling of the pfnControlCallback (by the USB stack) with the event CONNECT / DISCONNECT.


    This is why I added a manual call to it on the VBUS falling edge to indicate to my application the cable was plug out.


    But If I add this call on rising edge detection with event "CONNECT", on the first cable plug in, this callback will be called twice: One by the USB stack due to the enumeration, one other by myself on VBUS rising edge detection....

    I'm looking for a way to call the pfnControlCallback only one time on each cable plug in / plug out with the event CONNECT/DISCONNECT.

  • You can use a C variable to determine if the function has been called before, of if it is the first time that VBUS is high. In that case, do not call the function from your application. Let the USB library alone call it. I believe this should solve the problem.

    Regards,
    sal
  • Ok
    After test this behavior work properly.
    Just a remark according ControlCard.
    The hardware link the USB VBUS to a GPIO via a 100K resistor. The internal diode limit Input voltage to 3.3V.
    But with this, when no cable is pluged in the connector, the GPIO input has no fixed state. Then the GPIO input detect hasardous state.

    Don't forget to set an internal pull down or external.
  • Glad you got it working! Thanks for the helpful information.

    sal