Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

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.

EK-TM4C1294XL USB 2.0 High Speed External PHY Setup

Other Parts Discussed in Thread: EK-TM4C1294XL

Hi All,

I am attempting to setup my EK-TM4C1294XL with an external USB PHY and I seem to be running into some errors. The code executes up to the last line, where it gets stuck trying to read the ULPI register (Within the function called ULPIConfigSet).

The goal of this program is to allow me to use bulk transfers to transfer data from the MCU to my PC through a virtual com port. Can anyone point me in the right direction? I have a hunch that the issue might be with my hardware connector, but I am quite sure that is not the case. Can anyone who has utilized an external PHY with Tiva C verify that my initialization is correct?

Thanks!

void USB_Initialize(uint32_t ui32PLLRate, uint32_t sysClkFrequency)
{
	uint32_t ulpiSettings;
	uint32_t pllSpeed;
	HWREG(GPIO_PORTB_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
	HWREG(GPIO_PORTB_BASE + GPIO_O_CR) = 0xff;
	HWREG(GPIO_PORTL_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
	HWREG(GPIO_PORTL_BASE + GPIO_O_CR) = 0xff;
	HWREG(GPIO_PORTP_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
	HWREG(GPIO_PORTP_BASE + GPIO_O_CR) = 0xff;
	// Enable the USB GPIO peripherals.
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
	// PP5 -> PP2, PB3, PB2, PL5 -> PL0 are used for ULPI

	ROM_GPIOPinConfigure(GPIO_PP5_USB0D6);
	ROM_GPIOPinConfigure(GPIO_PP4_USB0D7);
	ROM_GPIOPinConfigure(GPIO_PP3_USB0DIR);
	ROM_GPIOPinConfigure(GPIO_PP2_USB0NXT);
	ROM_GPIOPinConfigure(GPIO_PB3_USB0CLK);
	ROM_GPIOPinConfigure(GPIO_PB2_USB0STP);
	ROM_GPIOPinConfigure(GPIO_PL5_USB0D5);
	ROM_GPIOPinConfigure(GPIO_PL4_USB0D4);
	ROM_GPIOPinConfigure(GPIO_PL3_USB0D3);
	ROM_GPIOPinConfigure(GPIO_PL2_USB0D2);
	ROM_GPIOPinConfigure(GPIO_PL1_USB0D1);
	ROM_GPIOPinConfigure(GPIO_PL0_USB0D0);

	// Configure the buffer type for the pin
	ROM_GPIOPinTypeUSBDigital(GPIO_PORTB_BASE, GPIO_PIN_3 | GPIO_PIN_2);
	ROM_GPIOPinTypeUSBDigital(GPIO_PORTP_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
	ROM_GPIOPinTypeUSBDigital(GPIO_PORTL_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2| GPIO_PIN_1| GPIO_PIN_0);
	ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_USB0);

	USBClockEnable(USB0_BASE,1,USB_CLOCK_EXTERNAL);

	// Enable ULPI
	USBULPIEnable(USB0_BASE);

	// Configure the ULPI
	USBULPIConfig(USB0_BASE, USB_ULPI_EXTVBUS | USB_ULPI_EXTVBUS_IND);

	// Enable High Speed
	USBHighSpeed(USB0_BASE, true);

	// Initialize the transmit and receive buffers.
	USBBufferInit(&g_sTxBuffer);
	USBBufferInit(&g_sRxBuffer);
	USBBufferFlush(&g_sTxBuffer);
	USBBufferFlush(&g_sRxBuffer);

	// Set the USB stack mode to Device-mode with VBUS monitoring.
	USBStackModeSet(0, eUSBModeDevice, 0);

	// Tell the USB library the CPU clock and the PLL frequency.  This is a
	// new requirement for TM4C129 devices.
	ulpiSettings = USBLIB_FEATURE_ULPI_HS;
	pllSpeed = 0;
	USBDCDFeatureSet(0,USBLIB_FEATURE_USBULPI, &ulpiSettings);
	USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &sysClkFrequency);
	USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &pllSpeed);
	// Pass our device information to the USB library and place the device
	// on the bus.
	USBDCDCInit(0, (tUSBDCDCDevice *)&g_sCDCDevice);


	//ULPIConfigSet(USB0_BASE, ULPI_CFG_HS);
}

  • Extra details:

    I am interfacing with a EVB-USB3320 by Microchip

    I solved the write ULPI register issue and now the problem is that the configuration descriptor request failed when trying to recognize the device. I did not get this error before when using the Internal USB PHY with full speed transfer
  • Hello Bryan

    Do you have a LeCroy to see what is being transacted on the USB Bus?

    Regards
    Amit
  • Amit,

    I have USBPcap, a free USB packet capture utility. I am finding that my hardware is behaving unpredictably. Sitting down and resetting/power cycling the EK-TM4C1294XL leads to my external PHY being recognized maybe once every 50 times or so.

    Usually, the device gets plugged in and then the device manager will say that an unknown USB device was connected and that the device descriptor request was failed.

    In the case that the device descriptor request succeeds, the USB device is recognized as a Tivaware USB serial port. But the problem is that windows then shows error code 10 (which means that it is unable to start the device)

    This makes me think that the issue lies with my connections to my external PHY. I have ordered a new connector last week and it is due to arrive sometime today. Are there any obvious errors within my setup code? I tried to follow chapter 21 of the TM4C129NCPDT user manual as closely as possible.

  • Hello Bryan

    I do not find anything in the code that could suggest an issue. I do know some users who have used the ULPI (USB3300 from Mircochip though). One thing to note is how you are interfacing the two devices. Is it jumpered via wires or is it a hard socket connection.

    Regards
    Amit
  • Amit,

    I am interfacing through wires between the microchip EVB-USB3320 and the Launchpad. I am currently reworking this connection and hopefully it will allow me to have more predictable behavior.
  • Hello Bryan

    Wires at 60MHz for 8+3 bits is not a good idea. I would rather expect a solid connector in between

    Regards
    Amit
  • Amit,

    When Windows reports that the device descriptor request has failed and it is not recognized does it mean that there is a hardware error or that there is a problem with the setup of the device?

    Regards,
    Bryan
  • Hello Bryan,

    It is rather tough without having a protocol analyzer like LeCroy. Since the packets sent by the devices are well defined, any malformed packet would be detected easily for finding the source of the issue. I am more certain of a HW issue than a SW issue.

    Regards
    Amit
  • Hi Amit,

    I have attached a copy of a packet capture I did. I unplugged and plugged the device in. Please excuse all of the unnecessary inclusions from my USB mouse and keyboard! It is a .pcap file that can be read with Wireshark.

    Thanks,

    Bryan

    usbpacketcapture1027.zip

  • Hello Bryan,

    Thanks for the log. When the PC is requesting for the String Descriptor (No 264-265 transaction in the log file) from the uC, the uC is sending 0x36 0x03 0x49 0x00. The first parameter is the length which must be 0x04 and not 0x36. That is why the PC is having a tough time. Can you please check if the g_pui8LangDescriptor is set correctly.

    Regards
    Amit
  • Good morning Amit,

    I simply copied the language descriptor from example code. Below is my initialization of g_pui8LangDescriptor

    //***************************************************************************** // // The languages supported by this device. // //***************************************************************************** const uint8_t g_pui8LangDescriptor[] = { 4, USB_DTYPE_STRING, USBShort(USB_LANG_EN_US) };

  • To be clear,

    The descriptor requests you are looking at are in response to plugging in the Launchpad's debug USB port.

    When I plug in the USB port corresponding to the external PHY, there is no response. Earlier in the debugging stage I found that the uC would get stuck trying to read from ULPI registeres, but now that is not an issue. The current issue is that there are problems corresponding to communicating with the PC.

    It seems like the host is able to recognize that I plugged the device in, but the device is unable to respond to the host.
  • Hello Bryan

    Then how do I know which message is for the ULPI PHY port?

    Regards
    Amit
  • Amit,

    I just did some experimentation. I uninstalled the USB driver for a version of the code that works with the internal PHY and USB FS, and when I tried plugging and unplugging my device in I was not able to see the packets on my packet sniffer.

    It must be the case that without a hardware USB sniffer I will not be able to see the USB packets until I have a proper driver installed.

    I am going through the example code for the DK-TM4C129X and I noticed that to set up the ULPI interface all that was necessary to do was the following:

    - Enable ports B, L and P

    - Configure the pins on B, L and P as the ULPI interface and set pin drive strength to 12mA

    - Set the USBLib feature of ULPI to be USBLIB_FEATURE_ULPI_HS

    - Set the clock rate as the CPU clock and the USB PLL frequency to 0 (external source)

    - Call USBDCDInit to put the device on the bus

    Below is the current version of my initialization code. It is basically a direct copy of the usb_dev_serial.c code that pertains to ULPI initialization:

            uint32_t pllSpeed;
    	uint32_t ulpiSettings;
    
    	// Enable the USB GPIO peripherals.
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    
    	//
    	// ULPI Port B pins.
    	//
    	ROM_GPIOPinConfigure(GPIO_PB2_USB0STP);
    	ROM_GPIOPinConfigure(GPIO_PB3_USB0CLK);
    	ROM_GPIOPinTypeUSBDigital(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
    	GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3,
    	                 GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD);
    
    	//
    	// ULPI Port P pins.
    	//
    	ROM_GPIOPinConfigure(GPIO_PP2_USB0NXT);
    	ROM_GPIOPinConfigure(GPIO_PP3_USB0DIR);
    	ROM_GPIOPinConfigure(GPIO_PP4_USB0D7);
    	ROM_GPIOPinConfigure(GPIO_PP5_USB0D6);
    	ROM_GPIOPinTypeUSBDigital(GPIO_PORTP_BASE, GPIO_PIN_2 | GPIO_PIN_3 |
    	                                           GPIO_PIN_4 | GPIO_PIN_5);
    	GPIOPadConfigSet(GPIO_PORTP_BASE,
    	                 GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5,
    	                 GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD)
    	//
    	// ULPI Port L pins.
    	//
    	ROM_GPIOPinConfigure(GPIO_PL5_USB0D5);
    	ROM_GPIOPinConfigure(GPIO_PL4_USB0D4);
    	ROM_GPIOPinConfigure(GPIO_PL3_USB0D3);
    	ROM_GPIOPinConfigure(GPIO_PL2_USB0D2);
    	ROM_GPIOPinConfigure(GPIO_PL1_USB0D1);
    	ROM_GPIOPinConfigure(GPIO_PL0_USB0D0);
    	ROM_GPIOPinTypeUSBDigital(GPIO_PORTL_BASE, GPIO_PIN_0 | GPIO_PIN_1 |
    	                                           GPIO_PIN_2 | GPIO_PIN_3 |
    	                                           GPIO_PIN_4 | GPIO_PIN_5);
    	GPIOPadConfigSet(GPIO_PORTL_BASE,
    	                 GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
    	                 GPIO_PIN_4 | GPIO_PIN_5,
    	                 GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD);
    
    	ulpiSettings = USBLIB_FEATURE_ULPI_HS;
    
    	USBOTGFeatureSet(0,USBLIB_FEATURE_USBULPI, &ulpiSettings);
    
    	// Initialize the transmit and receive buffers.
    	USBBufferInit(&g_sTxBuffer);
    	USBBufferInit(&g_sRxBuffer);
    	USBBufferFlush(&g_sTxBuffer);
    	USBBufferFlush(&g_sRxBuffer);
    
    	// Set the USB stack mode to Device-mode with VBUS monitoring.
    	USBStackModeSet(0, eUSBModeDevice, 0);
    
    	// Tell the USB library the CPU clock and the PLL frequency.  This is a
    	// new requirement for TM4C129 devices.
    	pllSpeed = 0;
    
    	USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &sysClkFrequency);
    	USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &pllSpeed);
    
    	// Pass our device information to the USB library and place the device
    	// on the bus.
    	USBDCDCInit(0, (tUSBDCDCDevice *)&g_sCDCDevice);

    Is there anything else I need to be doing besides the initialization in order for me to be able to do things like issue commands like USBBufferWrite to send data over virtual com port?

    I am aware that TI has internally tested microchip USB3320 USB transceiver with the EK-TM4C1294XL so I am not sure exactly what I am doing wrong. Are there device specific (to the USB3320) things I need to be accounting for? I am specifically interfacing with EVB-USB3320.

    The datasheet for USB3320 implies that the uC will have to send commands to the USB3320 followed by pieces of data. It is unclear whether this is something that is covered by the Tivaware USB Library or it is something that I will have to implement myself. Could you please clarify this for me?

    Thanks,

    Bryan

  • Amit,

    I worked on my connector some more and I found that the speeds I am getting are very close if not the same as USB FS rather than USB HS

    I have attached a packet log of plugging in the external PHY for your review. It seems like somehow it is not being set properly.

    descriptor.zip

  • Hello Bryan

    That could be because the USB device is showing the USB protocol as 1.1 and not 2.0 (one of the pre-equisite for High Speed Mode)

    Regards
    Amit
  • Hi Amit,

    With my initialization code as shown above, shouldn't I be in HS mode?

    What register can I check to see whether or not I am truly in HS mode?  I have attached screenshots of some registers that I thought corresponded to USB 2.0 HS operation.

    Thanks,

    Bryan

  • Hello Bryan

    It is the device descriptor which exchanges this information.

    www.usbmadesimple.co.uk/ums_4.htm

    Regards
    Amit
  • Hey Amit,

    I attempted to fix this by changing the device descriptor in usbcdc.c in the USBLIB so that it has the value 0x200 for bcdUSB, but for some reason this gets overwritten. Is there a setting I can use to change bcdUSB using the USBLIB?
  • My dear friend Amit,

    I found that I had to change the value of the descriptor within the usbdcdc library. It is too bad there is no way to do this without modifying the library! It works now though, thank you!
  • Hello Bryan,

    Which brings us to TivaWare 2.1.2 in which the issue of HS mode is fixed for ULPI.

    Regards
    Amit
  • Amit,

    The only problem I have now is that it seems like using High Speed mode has not really increased my transfer speed by much. I am only able to hit about 512Kbyte/s using the CDC device class drivers. Is this wrong do you think? Or is this the limitation of HS
  • Hello Bryan,

    What is on the other end of the USB: A serial port?

    Regards
    Amit
  • Amit,

    I am representing the USB as a virtual com port and reading the data through Termite. My goal is to send 8192 bytes of data within 1ms.

    Cheers,
    Bryan
  • Hello Bryan

    I am not familiar with Termite (would need some link to study up). Generally CDC class drivers were not meant to be high speed, but a native bulk device could work at high speed with high data throughput.

    Also I will have to check on CDC class devices as the speed requirement is not very clear in the USB Specification.

    Regards
    Amit
  • Amit,

    I will attempt to use bulk transfers and report back to you. Termite is simply a telnet client similar to PuTTY but with slightly different features. The reason why we wanted to use CDC transfer is because it would be possible to send the data over virtual COM port, which would make interfacing easy for the customer. By my understanding this would not be possible if using bulk transfers, is that correct?

    Kind regards,

    Bryan

  • Hello Bryan

    CDC uses Bulk Transfers. However each Device Class puts certain limitation or structure. That is what I am checking.

    Regards
    Amit
  • Amit,

    I switched my code around so that I am writing to the FIFO using MAP_USBEndpointDataPut instead of the costly USBBufferWrite calls I was using. I also tried using the function USBBufferWritten, but it was slightly slower than writing using MAP_USBEndpointDataPut.

    I was able to increase my transmission speed by a factor of about 4, but I am still 5 times too slow. Is there anything you see in my data transfer code that I can do to speed this up?

    for (ii= 0; ii < 128; ii++) {
    		 while (psInst->iCDCTxState != eCDCStateIdle) {}
    
    		 i32Retcode = MAP_USBEndpointDataPut(psInst->ui32USBBase,
    		 psInst->ui8BulkINEndpoint, dummyData, 64);
    
    		 if (i32Retcode != -1) {
    		 // Remember how many bytes we sent.
    		 psInst->ui16LastTxSize += 64;
    
    		 psInst->iCDCTxState = eCDCStateWaitData;
    		 i32Retcode = MAP_USBEndpointDataSend(psInst->ui32USBBase,
    		 psInst->ui8BulkINEndpoint,
    		 USB_TRANS_IN);
    
    		 }
    }

    Thanks,

    Bryan

  • Amit,

    Do you know if it is possible to increase USB data throughput by using more than one endpoint for data transfer?
  • Hello Bryan

    All end points share the same physical medium. So the limitation would still be there on maximum data transfer

    Regards
    Amit
  • Dear Amit,

    We can finally put this thread to a close. It turns out that I was able to transmit at the speeds I need by reconfiguring the FIFO to be 512 Bytes large and changing the bulk transfer endpoint max transfer size to 512 bytes. It turns out it is very important to look over the USB 2.0 Specification very carefully!

    Cheers,
    Bryan
  • Hello Bryan,

    And the same is already planned for the next TivaWare release.

    Regards
    Amit