Hi All,
We have a custom board which has separate device receptacles and host port for USB0 using TM4C1290NCPDT. Our design has a MUX circuit in order to use the same USB (USB0) data pins on device receptacle and host port.
Software is configured for OTG mode, with mux mapped to the device mode, in the beginning, changing to host if the device is not detected.
Reference from SDK, board dk-tm4c129x and example usb_otg_mouse is modified as per our requirement. Attached the modified main file.
//***************************************************************************** // // usb_otg_mouse.c - USB OTG Mouse (combined host and device mouse). // // Copyright (c) 2013-2017 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // This is part of revision 2.1.4.178 of the DK-TM4C129X Firmware Package. // //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_usb.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "grlib/grlib.h" #include "usblib/usblib.h" #include "usblib/device/usbdevice.h" #include "usblib/host/usbhost.h" #include "utils/uartstdio.h" #include "drivers/frame.h" #include "drivers/kentec320x240x16_ssd2119.h" #include "drivers/pinout.h" #include "inc/hw_gpio.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "usb_otg_mouse.h" //***************************************************************************** // //! \addtogroup example_list //! <h1>USB OTG HID Mouse Example (usb_otg_mouse)</h1> //! //! This example application demonstrates the use of USB On-The-Go (OTG) to //! offer both USB host and device operation. When the DK board is connected //! to a USB host, it acts as a BIOS-compatible USB mouse. The select button //! on the board (on the bottom right corner) acts as mouse button 1 and //! the mouse pointer may be moved by dragging your finger or a stylus across //! the touchscreen in the desired direction. //! //! If a USB mouse is connected to the USB OTG port, the board operates as a //! USB host and draws dots on the display to track the mouse movement. The //! states of up to three mouse buttons are shown at the bottom right of the //! display. //! //***************************************************************************** //***************************************************************************** // // The current state of the USB in the system based on the detected mode. // //***************************************************************************** volatile tUSBMode g_iCurrentMode = eUSBModeNone; //***************************************************************************** // // The size of the host controller's memory pool in bytes. // //***************************************************************************** #define HCD_MEMORY_SIZE 254 //***************************************************************************** // // The memory pool to provide to the Host controller driver. // //***************************************************************************** uint8_t g_pui8HCDPool[HCD_MEMORY_SIZE]; //***************************************************************************** // // This global is used to indicate to the main that a mode change has // occurred. // //***************************************************************************** uint32_t g_ui32NewState; //***************************************************************************** // // The system clock frequency in Hz. // //***************************************************************************** uint32_t g_ui32SysClock; //***************************************************************************** // // The graphics context for the screen. // //***************************************************************************** tContext g_sContext; #define WAIT_DELAY_COUNT 100000 //***************************************************************************** // // A function which returns the number of milliseconds since it was last // called. This can be found in usb_dev_mouse.c. // //***************************************************************************** extern uint32_t GetTickms(void); //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif //***************************************************************************** // // Callback function for mode changes. // //***************************************************************************** void ModeCallback(uint32_t ui32Index, tUSBMode iMode) { // // Save the new mode. // g_iCurrentMode = iMode; switch (iMode) { case eUSBModeHost: { break; } case eUSBModeDevice: { break; } case eUSBModeNone: { break; } default: { break; } } g_ui32NewState = 1; } //***************************************************************************** // //! Configures the device pins for the standard usages on the DK-TM4C129X. //! //! This function enables the GPIO modules and configures the device pins for //! the default, standard usages on the DK-TM4C129X. Applications that require //! alternate configurations of the device pins can either not call this //! function and take full responsibility for configuring all the device pins, //! or can reconfigure the required device pins after calling this function. //! //! \return None. // //***************************************************************************** void PinInit(void) { // // Enable all the GPIO peripherals. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); // // PA0-1 are used for UART0. // ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // PB0-1/PD6-7/PL6-7 are used for USB. // // // Configure the required pins for USB operation. // // HWREG(GPIO_PORTA_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; // HWREG(GPIO_PORTA_BASE + GPIO_O_CR) = 0xff; ROM_GPIOPinConfigure(GPIO_PA6_USB0EPEN); ROM_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); //ID and VBUS ROM_GPIOPinTypeUSBDigital(GPIO_PORTA_BASE, GPIO_PIN_6); ROM_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7); // DP and DM // ROM_GPIOPinTypeGPIOInput(GPIO_PORTQ_BASE, GPIO_PIN_4); ROM_GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_7); //Enable GPIO for USB_SEL and ID_DRIVE ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_5); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_3); //Set values for USB_SEL = 0 and ID_DRIVE = 1 for device configuration GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, 0);//TODO - change it to 0 for while board testing; GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, 0); GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_3, GPIO_PIN_3); //VBUS contropl pin for custom board ROM_GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_5); GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_5, GPIO_PIN_5); } //***************************************************************************** // // Initialize the USB for OTG mode on the platform. // //***************************************************************************** void USBOTGInit(uint32_t ui32ClockRate, tUSBModeCallback pfnModeCallback) { uint32_t ui32PLLRate; // // Enable USB controller. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); // // Set the current processor speed to provide more accurate timing // information to the USB library. // SysCtlVCOGet(SYSCTL_XTAL_25MHZ, &ui32PLLRate); USBOTGFeatureSet(0, USBLIB_FEATURE_CPUCLK, &ui32ClockRate); USBOTGFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate); // // Initialize the USB OTG mode and pass in a mode callback. // USBStackModeSet(0, eUSBModeOTG, pfnModeCallback); } //***************************************************************************** // // main routine. // //***************************************************************************** int main(void) { tLPMFeature sLPMFeature; int count = 0; // // Run from the PLL at 120 MHz. // g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // // Configure the device pins. // PinInit(); // // Configure the UART. // UARTStdioConfig(0, 115200, g_ui32SysClock); UARTprintf("USB switchover\r\n"); // // Configure USB for OTG operation. // USBOTGInit(g_ui32SysClock, ModeCallback); sLPMFeature.ui32HIRD = 500; sLPMFeature.ui32Features = USBLIB_FEATURE_LPM_EN | USBLIB_FEATURE_LPM_RMT_WAKE; USBHCDFeatureSet(0, USBLIB_FEATURE_LPM, &sLPMFeature); // // Initialize the host stack. // HostInit(); UARTprintf("Host stack initialization done\r\n"); // // Initialize the device stack. // DeviceInit(); UARTprintf("Device stack initialization done\r\n"); // // Initialize the USB controller for dual mode operation with a 2ms polling // rate. // USBOTGModeInit(0, 2000, g_pui8HCDPool, HCD_MEMORY_SIZE); #if 0//Commenting as, device mode configuration is done during int //Set values for USB_SEL = 0 and ID_DRIVE = 1 for device configuration GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, 0);//TODO - change it to 0 for while board testing; GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, 0); GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_3, GPIO_PIN_3); #endif // // Loop forever. // while (1) { // // Tell the OTG library code how much time has passed in milliseconds // since the last call. // USBOTGMain(GetTickms()); // // Handle deferred state change. // if (g_ui32NewState) { UARTprintf("New state detected\r\n"); g_ui32NewState = 0; } if (g_iCurrentMode == eUSBModeDevice) { UARTprintf("connected to host\r\n"); DeviceMain(); } if (g_iCurrentMode == eUSBModeHost) { UARTprintf("device connected\r\n"); HostMain(); } if(count < WAIT_DELAY_COUNT) { count++; } else if(count == WAIT_DELAY_COUNT && g_iCurrentMode == eUSBModeNone) { count++; //Set values for USB_SEL = 1 and ID_DRIVE = 0for host configuration GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, GPIO_PIN_5); GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_3, 0); } } }
We need to test two cases, anyone among the below cases will be happening in real time.
1. Connect TM4C to host (PC) with USB type-A male connector on the product - this will continue to work in device mode
2. Connect the device with USB type-A male connector to TM4C's USB type-A female port - this will continue to work in host mode
It is not working as expected. Only one mode will work with varying WAIT_DELAY_COUNT value.
Below are the observations,
1. WAIT_DELAY_COUNT > 100000, works TM4C as device mode only but we are missing to capture the TM4C connection to host PC.
2. WAIT_DELAY_COUNT < 10000, works TM4C as host mode only but we are missing to capture the device connection.
Any feedbacks are appreciated.
Thanks in advance.
Regards,
Ambika