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.

TM4C1294KCPDT: USB CDC does not work in my design

Part Number: TM4C1294KCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Hello!

We are developing a lab device based on TM4C1294KCPDT, and it works fine, except of USB. I want to connect device to PC with USB CDC driver, emulating serial port. The schematic is very simple - as this is just device, I connected USB_DP, USB_DM, USB_VBUS directly to mini-USB connector, protecting the signals with reverse diodes, and pulled up USB_ID to 3.3v. Pin 1 is VBUS, Pin 2 is USB_DM, Pin 3 is USB_DP and Pin 5 is GND.

Here is the initialization code:

//*****************************************************************************
//
// The languages supported by this device.
//
//*****************************************************************************
const uint8_t g_pui8LangDescriptor[] =
{
	4,
	USB_DTYPE_STRING,
	USBShort(USB_LANG_EN_US)
};
//*****************************************************************************
//
// The manufacturer string.
//
//*****************************************************************************
const uint8_t g_pui8ManufacturerString[] =
{
	(12 + 1) * 2,
	USB_DTYPE_STRING,
	'P', 0, 'o', 0, 'r', 0, 't', 0, 'l', 0, 'a', 0, 'b', 0, ' ', 0, 'l', 0,
	't', 0, 'd', 0, '.', 0,
};
//*****************************************************************************
//
// The product string.
//
//*****************************************************************************
const uint8_t g_pui8ProductString[] =
{
	2 + (12 * 2),
	USB_DTYPE_STRING,
	'A', 0, 'u', 0, 't', 0, 'o', 0, 't', 0, 'r', 0, 'a', 0, 't', 0,
	'e', 0, ' ', 0, '0', 0, '2', 0,
};
//*****************************************************************************
//
// The serial number string.
//
//*****************************************************************************
/*const*/ uint8_t g_pui8SerialNumberString[] =
{
	2 + (8 * 2),
	USB_DTYPE_STRING,
	'1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0
};
//*****************************************************************************
//
// The control interface description string.
//
//*****************************************************************************
const uint8_t g_pui8ControlInterfaceString[] =
{
	2 + (21 * 2),
	USB_DTYPE_STRING,
	'A', 0, 'C', 0, 'M', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0,
	'r', 0, 'o', 0, 'l', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0,
	'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0
};
//*****************************************************************************
//
// The configuration description string.
//
//*****************************************************************************
const uint8_t g_pui8ConfigString[] =
{
	2 + (26 * 2),
	USB_DTYPE_STRING,
	'S', 0, 'e', 0, 'l', 0, 'f', 0, ' ', 0, 'P', 0, 'o', 0, 'w', 0,
	'e', 0, 'r', 0, 'e', 0, 'd', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0,
	'f', 0, 'i', 0, 'g', 0, 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0,
	'o', 0, 'n', 0
};
//*****************************************************************************
//
// The descriptor string table.
//
//*****************************************************************************
const uint8_t * const g_ppui8StringDescriptors[] =
{
	g_pui8LangDescriptor,
	g_pui8ManufacturerString,
	g_pui8ProductString,
	g_pui8SerialNumberString,
	g_pui8ControlInterfaceString,
	g_pui8ConfigString
};
#define NUM_STRING_DESCRIPTORS (sizeof(g_ppui8StringDescriptors) / \
sizeof(uint8_t *))

tUSBDCDCDevice g_sCDCDevice =
{
	//
	// The Vendor ID you have been assigned by USB-IF.
	//
	0x8F0F,		// Temporary
	//
	// The product ID you have assigned for this device.
	//
	0x100,
	//
	// The power consumption of your device in milliamps.
	//
	20,
	//
	// The value to be passed to the host in the USB configuration descriptor’s
	// bmAttributes field.
	//
	USB_CONF_ATTR_SELF_PWR,
	//
	// A pointer to your control callback event handler.
	//
	AT_USBControlEventCallback,
	//
	// A value that you want passed to the control callback alongside every
	// event.
	//
	//(void *)&g_sYourInstanceData,
	0,
	//
	// A pointer to your receive callback event handler.
	//
	AT_USBReceiveEventCallback,
	//
	// A value that you want passed to the receive callback alongside every
	// event.
	//
	//(void *)&g_sYourInstanceData,
	0,
	//
	// A pointer to your transmit callback event handler.
	//
	AT_USBTransmitEventCallback,
	//
	// A value that you want passed to the transmit callback alongside every
	// event.
	//
	//(void *)&g_sYourInstanceData,
	0,
	//
	// A pointer to your string table.
	//
	g_ppui8StringDescriptors,
	//
	// The number of entries in your string table.
	//
	NUM_STRING_DESCRIPTORS
};

extern unsigned int Clk;

void initUSBCDC()
{
	uint32_t ui32PLLRate;
	SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
	SysCtlVCOGet(SYSCTL_XTAL_16MHZ, &ui32PLLRate);
	USBStackModeSet(0, eUSBModeDevice, 0);
	USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &Clk);
	USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate);
	pvDevice = USBDCDCInit(0, &g_sCDCDevice);
}

Then I connect the device to the PC, nothing happend. What is the problem?

Thank you!

  • Hello Oleg,

    It sounds like a custom board so can you provide the schematic for it?

    Was OS are you using? What version of TivaWare?

    Are you seeing an unknown device anywhere in Device manager when the board is plugged such as under USB controllers?
  • Windows 7

    TivaWare_C_Series-2.1.4.178

    No device, even unknown, appears in device manager.

    When I measure voltage on USB plug pins, I see 5V on VBUS and 0V on DP/DM

  • Hello Oleg,

    Sorry for the delay in following up.

    Further questions as it's not apparent currently what might be going on.

    1) What is your SysClk settings? Can you post your SysClk Initialization code? While at it, can you post the code for initializing the GPIOs as well?

    2) Did you initialize the USB Buffers for TX and RX?

    3) Have you tried using the default TI VID/PID to see if Windows will recognize that? I think it would show up in device manager as unknown if Windows doesn't, but worth checking out.

    4) Do you have any way to sniff the USB lines to see if data is being transmitted? Using a voltmeter isn't going to cut it, you need to use an o-scope or ideally a logic state analyzer.

  • Hello Ralph,

    Thank you for answer!

    1) Here is the code. As I do not have general GPIO initialization code, I collected the code from drivers in chronological order:

    Clk = SysCtlClockFreqSet(SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000L);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0);
        
        GPIOPinTypeGPIOOutput(GPIO_PORTJ_BASE, /*GPIO_PIN_0 | */GPIO_PIN_1);
        GPIOPinTypeGPIOOutput(GPIO_PORTL_BASE, GPIO_PIN_0);
        GPIOPinTypeGPIOOutput(GPIO_PORTP_BASE, GPIO_PIN_3);
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_2);
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_3);
        GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_2);
    
        GPIOPinConfigure(GPIO_PK0_EPI0S0);
        GPIOPinConfigure(GPIO_PK1_EPI0S1);
        GPIOPinConfigure(GPIO_PK2_EPI0S2);
        GPIOPinConfigure(GPIO_PK3_EPI0S3);
        GPIOPinConfigure(GPIO_PC7_EPI0S4);
        GPIOPinConfigure(GPIO_PC6_EPI0S5);
        GPIOPinConfigure(GPIO_PC5_EPI0S6);
        GPIOPinConfigure(GPIO_PC4_EPI0S7);
        GPIOPinConfigure(GPIO_PA6_EPI0S8);
        GPIOPinConfigure(GPIO_PA7_EPI0S9);
        GPIOPinConfigure(GPIO_PG1_EPI0S10);
        GPIOPinConfigure(GPIO_PG0_EPI0S11);
        GPIOPinConfigure(GPIO_PM3_EPI0S12);
        GPIOPinConfigure(GPIO_PM2_EPI0S13);
        GPIOPinConfigure(GPIO_PM1_EPI0S14);
        GPIOPinConfigure(GPIO_PM0_EPI0S15);
        //GPIOPinConfigure(GPIO_PL0_EPI0S16);
        GPIOPinConfigure(GPIO_PB3_EPI0S28);
        GPIOPinConfigure(GPIO_PN2_EPI0S29);
        GPIOPinConfigure(GPIO_PP3_EPI0S30);
        
        GPIOPinTypeEPI(GPIO_PORTA_BASE, EPI_PORTA_PINS);
        GPIOPinTypeEPI(GPIO_PORTB_BASE, EPI_PORTB_PINS);
        GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS);
        GPIOPinTypeEPI(GPIO_PORTG_BASE, EPI_PORTG_PINS);
        GPIOPinTypeEPI(GPIO_PORTK_BASE, EPI_PORTK_PINS);
        //GPIOPinTypeEPI(GPIO_PORTL_BASE, EPI_PORTL_PINS);
        GPIOPinTypeEPI(GPIO_PORTM_BASE, EPI_PORTM_PINS);
        GPIOPinTypeEPI(GPIO_PORTN_BASE, EPI_PORTN_PINS);
        GPIOPinTypeEPI(GPIO_PORTP_BASE, EPI_PORTP_PINS);
    
    #define BEEPER_PORT		GPIO_PORTD_BASE, GPIO_PIN_7
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
        HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xff;
    	GPIOPinTypeGPIOOutput(BEEPER_PORT);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    	GPIODirModeSet(GPIO_PORTL_BASE, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_DIR_MODE_OUT);
    	GPIODirModeSet(GPIO_PORTE_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_DIR_MODE_IN);
    	GPIOPinTypeGPIOOutput(GPIO_PORTL_BASE, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
    	GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
    	GPIOPinWrite(GPIO_PORTL_BASE, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
    	GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    	GPIOPinConfigure(GPIO_PL1_PHA0);
    	GPIOPinConfigure(GPIO_PL2_PHB0);
    	GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_1 | GPIO_PIN_2);
    	GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_5);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
    	QEIEnable(QEI0_BASE);
    	QEIConfigure(QEI0_BASE, QEI_CONFIG_CAPTURE_A | QEI_CONFIG_QUADRATURE | 
    		QEI_CONFIG_SWAP | QEI_CONFIG_FILTEN | 0x000F0000, 1000000);
    	QEIPositionSet(QEI0_BASE, QEIPos = 500000);
    	QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_16, 2000);
    	QEIVelocityEnable(QEI0_BASE);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    	GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_5);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
        GPIOPinConfigure(GPIO_PA2_SSI0CLK);
        GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0XDAT0);
        GPIOPinConfigure(GPIO_PA5_SSI0XDAT1);
    	GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
                       GPIO_PIN_2);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
    	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
    

    2) I am using my custom buffers for TX and RX

    3) and 4) I will try it when will reach my work place, maybe tomorrow or in monday.

  • Hello Oleg,

    I don't see any initializations for the USB pins shown in your schematic in what you posted. Can you please verify on your code that you have the USB GPIO's you are using configured correctly?

    Also another check that would be useful is to verify what the result of the SysCtlClockFreqSet function (saved in Clk variable) is to ensure the system clock is running at 120MHz. It sounds like the rest of your firmware is working correctly from your first post, right? If so that at least should rule out startup issues with the 16MHz crystal.
  • Hello!

    I added GPIO initialization to code:

    	SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
        HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
        HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xff;
    	GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    	GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    	SysCtlVCOGet(SYSCTL_XTAL_16MHZ, &ui32PLLRate);
    	USBStackModeSet(0, eUSBModeDevice, 0);
    	USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &Clk);
    	USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate);
    	pvDevice = USBDCDCInit(0, &g_sCDCDevice);
    

    Now device started to connect to Windows, but it appears as "Unknown device" even with default VID/PID pair:

    	//
    	// The Vendor ID you have been assigned by USB-IF.
    	//
    		0x1cbe, //0x8F0F,		// Temporary
    	//
    	// The product ID you have assigned for this device.
    	//
    		0x0002, //0x100,
    

    Device manager says "This device was stopped as it reported failure" (I translated russian message, so this could be inaccurate translation)

  • Hello Oleg,

    Glad to hear we are making some positive progress! Have you tried installing the TivaWare drivers for the new device now that is being recognized by Windows?

    Right now it sounds like something being passed from your board to the PC is not meshing with Windows. So my suspicions are either the driver, or the descriptors the application sends over. See if there are any other possible variations from the LaunchPad examples to what you are doing on the descriptor side as well. Also if you could use the same USB procedure on a LaunchPad board and see if that device is recognized or not this could help too.

    Also if you are using any interrupts, you should verify the startup_ccs.c file is properly configured.
  • Hello, Ralph!

    Now it looks like Windows does not receive any correct VID/PID from device. Let me try Linux machine to get log messages. I'll post the result in next message.

  • Aug 17 11:54:44 linux-5n5i.suse kernel: usb 3-1.2: device descriptor read/64, error -32
    Aug 17 11:54:44 linux-5n5i.suse kernel: usb 3-1.2: device descriptor read/64, error -32
    Aug 17 11:54:44 linux-5n5i.suse kernel: usb 3-1.2: new full-speed USB device number 6 using ehci-pci
    Aug 17 11:54:44 linux-5n5i.suse kernel: usb 3-1.2: device descriptor read/64, error -32
    Aug 17 11:54:44 linux-5n5i.suse kernel: usb 3-1.2: device descriptor read/64, error -32
    Aug 17 11:54:44 linux-5n5i.suse kernel: usb 3-1.2: new full-speed USB device number 7 using ehci-pci
    Aug 17 11:54:45 linux-5n5i.suse kernel: usb 3-1.2: device not accepting address 7, error -32
    Aug 17 11:54:45 linux-5n5i.suse kernel: usb 3-1.2: new full-speed USB device number 8 using ehci-pci
    Aug 17 11:54:45 linux-5n5i.suse kernel: usb 3-1.2: device not accepting address 8, error -32
    Aug 17 11:54:45 linux-5n5i.suse kernel: usb 3-1-port2: unable to enumerate USB device
    Aug 17 11:55:43 linux-5n5i.suse kernel: usb 3-1.1.4: new low-speed USB device number 9 using ehci-pci
    Aug 17 11:55:43 linux-5n5i.suse kernel: usb 3-1.1.4: device descriptor read/64, error -32
    Aug 17 11:55:44 linux-5n5i.suse kernel: usb 3-1.1.4: device descriptor read/64, error -32
    Aug 17 11:55:44 linux-5n5i.suse kernel: usb 3-1.1.4: new low-speed USB device number 10 using ehci-pci
    Aug 17 11:55:44 linux-5n5i.suse kernel: usb 3-1.1.4: device descriptor read/64, error -32
    Aug 17 11:55:44 linux-5n5i.suse kernel: usb 3-1.1.4: device descriptor read/64, error -32
    Aug 17 11:55:44 linux-5n5i.suse kernel: usb 3-1.1.4: new low-speed USB device number 11 using ehci-pci
    Aug 17 11:55:45 linux-5n5i.suse kernel: usb 3-1.1.4: device not accepting address 11, error -32
    Aug 17 11:55:45 linux-5n5i.suse kernel: usb 3-1.1.4: new low-speed USB device number 12 using ehci-pci
    Aug 17 11:55:45 linux-5n5i.suse kernel: usb 3-1.1.4: device not accepting address 12, error -32
    Aug 17 11:55:45 linux-5n5i.suse kernel: usb 3-1.1-port4: unable to enumerate USB device
    

  • Hello Oleg,

    I don't work with Linux so that isn't meaningful for me unfortunately, sorry. Furthermore, I don't believe our USB Driver is setup for Linux anyways.

    Have you verified your USB application works correctly and enumerates as expected on a TI eval board like a LaunchPad? Right now this seems to be application related provided you are using the latest TM4C Windows drivers. I'd like to understand if this application has been tested before.
  • Hello Ralph,

    Of course, Linux supports virtually any USB CDC device. This log tells us that USB device reports an error on the very early request, so it cannot even provide VID/PID to host.

    Unfortunately, we do not have any eval boards.

    Anyway, the problem is deeper: to setup drivers OS should know device's VID/PID, and it cannot aquire it.

  • Hello Oleg,

    Sounds like the application isn't setup correctly then. I have an example of a CDC device which I will share so you can reference it and compare your setup and your USB descriptor settings etc. to it.

    You will want to make sure your usb_structs files mirror the CDC example to start with. You can modify them after you get the initial example working, but for now use the TI VID/PID and all other info to get started with.

    This example works on the EK-TM4C1294XL LaunchPad and has been tested for both Windows 7 and Windows 10. You will need to install the latest USB driver after the port shows up in device manager (it will not enumerate properly until you do this).

    Example project: usb_dev_cdcserial.zip