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.

TM4C1294NCPDT: USB CDC does not work

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL,

Hello,

I have an issue with USB module in device mode with CDC.

I ran the exactly the same code on a launchpad and it works, but on an separate microcontroller, it does not work.

I can remove any hardware issue because I am able to get in boot loader mode (Tiva firmware upgrade)

Please find attached the code for initializing the USB module.

 ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                        SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
                                        SYSCTL_CFG_VCO_480), 120000000);
 
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7 );
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

USBBufferInit(&g_sTxBuffer);
USBBufferInit(&g_sRxBuffer);
SysCtlVCOGet(SYSCTL_XTAL_25MHZ, &ui32PLLRate);
USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &ui32SysClock);
USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate); // ui32PLLRate = 240000000 ?
USBDCDCInit(0, &g_psCDCDevice);


I loaded "usb_dev_cserial" example for TM4C1294XL but the device does not show up.

Is there something wrong with the frequency ?

  • Hello Briceag,

    If you are using Windows 10, the cserial example has issues with enumeration. I am attaching a CDC device version which should enumerate fine. Please try and that and also compare the initialization code from my example to yours.

    7026.usb_dev_cdcserial.zip

  • Hello Ralph,

    Thank's for involving.

    Unfortunately I cannot compile your example on OSX, but I compared the initialization steps and they are identical.
    I am not able to see the content of "SetPinout" function.

    What does the boot loader different than the method I posted ?
    Is it a matter of pin configuration ? I mean, the USB_ID is floating and USB_VBUS is connected but the device is configured as self powered.
  • Hello Briceag,

    The boot loader is coming straight out of the ROM boot loader, and it wouldn't be set as a CDC device.

    Based on your connections, I think you need the following API:

        //
        // Initialize the USB stack for device mode.
        //
        USBStackModeSet(0, eUSBModeDevice, 0);

    Please try and include that as part of the initialization and see if that helps. Call it before USBDCDCInit.

  • Calling that function has no effect.
    Is there something else to force the usb in device mode ?

    Besides USB_DP and USB_DM do I need to configure other pins ?
  • Hello Briceag,

    I apologize!! I made a mistake on the API I posted, it's supposed to be eUSBModeForceDevice and not eUSBModeDevice!

    Just to be sure, I edited my CDC example to remove the Pinout set and just added in:

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    And before USBDCDCInit:

    USBStackModeSet(0, eUSBModeForceDevice, 0);

    And with those changes, it enumerated successfully with PinoutSet being commented out.

  • Hi Briceag,

    Perhaps the (&ui32PLLRate) should be set to match _VCO_480 and not 240mHz as you //?

    e.g., 480000000/8=60Mhz or a PLL Divide of 8

    Remove USBDCDCInit(0, &g_psCDCDevice); Ralf suggested proper call for device mode.

    Another way to force VBUS pin in register may help resolve a possible ID pin issue.

         /* USB_GPCS_DEVMOD_DEV:
         * Force USB0VBUS and USB0ID high */
        HWREG(USB0_BASE + USB_O_GPCS) |= USB_GPCS_DEVMOD_DEV;  //USB_GPCS_DEVMOD_DEVVBUS

    Your close to success it seems!

  • Hi Ralph,

    Indeed, something changed.
    On Windows the message in device manager is "Device Descriptor Request Failed"
    On Linux the message is "device not accepting address 16, error -71", "unable to enumerate USB device"

  • Hello BP101,

    Perhaps the (&ui32PLLRate) should be set to match _VCO_480 and not 240mHz as you //?
    -That looked strange for me, too. That's why I put that comment, I've seen the value in debugger. How can I set it properly ?

    Remove USBDCDCInit(0, &g_psCDCDevice); Ralf suggested proper call for device mode.
    -What do you mean ?

    Forcing VBUS and ID on high, has no effect.

    Taking into account the enumeration problem, most probably the issue comes from an inadequate frequency.
    Please give me more details about setting the proper _VCO_480.
  • Hello Briceag,

    Definitely getting far closer now. Are you using custom descriptors, or using the descriptors from usb_structs.c?
  • Hello Briceag & BP101,

    The PLL rate and USBDCDCInit commands are correct. From the working LaunchPad example the following calls are made:

    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480), 120000000);

    and

        //
        // Pass the device information to the USB library and place the device
        // on the bus.
        //
        USBDCDCInit(0, &g_sCDCDevice);

  • Hi Ralph,

    Yes, I'm using a custom struct (the same struct used on launchpad where it worked).
    Why do I get ui32PLLRate equals to 240000000 ? It is supposed to be 480000000?
  • Hello Briceag,

    Although we are using a VCO of 480MHz while setting up the PLL, in reality we are setting it to 240MHz. This is because the PSYSDIV is always set to '1' by the driver, which means the VCO is always divided by 2.
  • Alright, then I'm gonna try with the descriptor struct provided by you and see what happens.

    Keep you informed.
  • Hello Ralph,

    I tried with the struct you provided which ends with the same enumeration error. In fact, the difference between mine and yours is about strings description.
  • Hello Briceag,

    So to summarize:

    1) The example I provided works on the EK-TM4C1294XL LaunchPad on both your Linux and Windows machines
    2) The custom hardware you are using is based on the TM4C1294NCPDT but does not have a connection for USB_ID
    3) The custom software based on the cdc_device example w/ TI descriptors is currently being seen by both Linux and Windows machines, but neither are capable of successfully enumerating it

    Am I correct on all these points?

    If so, would it be possible for you to try uploading my modified cdc_serial example to your custom board? I can provide it if that is possible and you can try and use that to see if there may be some other step we have missed on your custom software.
  • Hello Ralph,

    Yes, those points are correct and well understood.
    I am going to load your example on my custom board and let you know as quick as possible.
  • Hello Briceag,

    Because of the connections with the USB ID pin, you will need to use the version that I just tested which forces device mode and only initializes the DP/DM USB pins. I am attaching it for you:

    usb_dev_cdcserial_custom.zip

  • Hello Ralph,

    I found something that can help you to figure out why I encounter this behavior.

    Once the device is plugged, an interrupt is generated and the event is "suspend". Please find attached the picture.

    I was unable to run your software (the environment needs some external resources like utils..).

  • Hello Briceag,

    That doesn't really tell me much unfortunately. What would be more valuable would be to see USB analyzer data of the communication, especially to see if anything with the descriptor is not setup right.

    Can you post the descriptor you are using so I can compare it?
  • Hello Ralph,

    I replaced all my structures with yours. Unfortunately, the same behavior.

    As far as I know, the device gets suspended if few consecutive Start Of Frames are not detected. Why would happen this ? 

  • Hello Briceag,

    I haven't really seen that happen before so without getting US Analyzer data I wouldn't be able to figure out anything on that front. The initialization should work and that along with the descriptors have been working on my end, so my suspicion is that either something didn't get passed in correctly somehow on your code or that something is occurring on a hardware level. The Analyzer should be able to indicate both of these.

    One other idea could be that the USB drivers for TM4C is not being applied by Win 10 to the USB connection from your custom board. I don't think that should be the case if the same PID and VID are used, but to crosscheck this see if you can manually point Windows to use the TivaWare USB drivers. Make sure they are the latest ones as well: software-dl.ti.com/.../SW-TM4C-2.1.4.178.PATCH-1.0.zip
  • I don't know why they were seeing PSYSDIV=1 when it was always being set 2 several MUC's tested or viewed in  CCS debug 480Mhz PLL. Notice blue edit my post above value 16 = (&ui32PLLRate=480Mhz) though several other values may work depending on your PLL rate being set.

    Some of the USB bulk device mode calls Ralf posted appear different than ones I have entered. Assume you are not trying to connect a keyboard or mouse to the target MCU? It seems you are trying to connect target MCU to a host (Linux/Win) not a CDC/HID device.

    USBStackModeSet(0, eUSBModeDevice, 0);
    
    USBDBulkInit(0, &g_sBulkDevice);

    All else add lines below to report a message after POR showing VCO/PLL rates.

     static uint32_t ui32VCOSpeed;
    
    SysCtlVCOGet(SYSCTL_XTAL_25MHZ, &ui32VCOSpeed);
    UARTprintf("> VCO-Speed-->>:%i\r\n", ui32VCOSpeed);

  • Hello Ralph,

    It seems that something is wrong with the bus, bit stuffing error occurs. All I have is a trace captured with a logic analyzer. Please find it attached.USB_enumeration_issue.csv.zip

  • Hello BP101,

    The VCO is 375000000. I've logged that using SysCtlVCOGet.
  • Hello BP101,

    Wha about value 16 ? Where to be set ?
  • Hello Ralph,

    I found the issue. Indeed, forcing the USB stack in device mode worked perfectly.

    Initially I configured the system clock as :

    (a) MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480), 120000000);

    Then, I modified the configuration to :

    (b) MAP_SysCtlClockFreqSet((SYSCTL_OSC_INT |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480), 120000000);

    Then you proposed to force the usb stack in device mode, but during this period I had a wrong clock configuration.
    So, taking configuration (a) along with forcing USB stack in device mode gave me good results.

    Thank you very much for your help, I will always count on you !
  • That's what I was trying to point out that CDC is not correct call for bulk device initialization, thus time to post correct calls.

    VCO showing 375Mhz is very odd speed. The value 16 is the PLL divisor (480/16=30mHz) USB clock rate. Value can be (8) for higher speed USB up to 60Mhz. Depending on the PLL rate and version of Tivaware driverlib you are loading that may vary. You may be under or even over clocking SYSCLK and peripheral clocks depending on PSYSDIV being 1 or 2 in debug register view.