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.

USB OTG using TI-RTOS Examples

Other Parts Discussed in Thread: SYSBIOS

I am wondering if the USB Serial Device and FatSD USB Copy TI-RTOS examples for the LM4F23x can be combined into a single USB-OTG application which can detect either a PC or flash drive connection and execute the appropriate host or device tasks.  If so, what modifications would I have to make to accomplish this?

Thank you in advance for your help.

  • Hi Anthony,

    Yes - what you want to accomplish is possible.  The best place to start is the otg_detect example for the DK-LM3S9D96 board.

    Regards,

    Sue

  • Hi Sue, is it possible to port this code into the TI-RTOS environment?  I started by bringing usblib.h and usbmodes.c, it compiled but does not work.  I am only utilizing the code to detect the usb mode.  I assume there is a conflict with the low level pin settings being done by the two said files and sys/bios. 

  • I guess a more direct question would be are there any USB OTG drivers/examples for TI-RTOS?  If not, where would one start to make this happen?  I have ported the USB OTG code from qs-logger, got it to compile, but am unable to successfully get this to work in the TI-RTOS envrionment due to a HWI w/o a corresponding ISR.  Thanks in advance for any insight you may provide!

  • Hi Ben,

    I'm sorry for the delay in responding.  Have you reviewed this app note?

    Regards,

    Sue

  • Hi Sue, no worries.  No, I have not seen this app note before.  I briefly looked it over and it appears to be exactly what I was looking for.  Thanks!

  • Hi Sue, although this was helpful I am still struggling with this.  Also, I work with Anthony (just so you didn't think I hijacked his thread).  I have posted my code below.  Basically, mapping to the USBOTGModeIntHandler locks the RTOS.  Any thoughts would be greatly appreciated!

    //*****************************************************************************
    //
    // The clock rate for the SysTick interrupt and a counter of system clock
    // ticks. The SysTick interrupt is used for basic timing in the application.
    //
    //*****************************************************************************
    static volatile unsigned long g_ulTickCount;

    //*****************************************************************************
    //
    // The current state of USB OTG in the system based on the detected mode.
    //
    //*****************************************************************************
    volatile tUSBMode g_eCurrentUSBMode = USB_MODE_NONE;

    //*****************************************************************************
    //
    // The size of the host controller's memory pool in bytes.
    //
    //*****************************************************************************
    #define HCD_MEMORY_SIZE 128

    //*****************************************************************************
    //
    // The memory pool to provide to the Host controller driver.
    //
    //*****************************************************************************
    unsigned char g_pHCDPool[HCD_MEMORY_SIZE];

    int junk = 0;
    void testFxn1() {
         junk--;
    }

    void testFxn2() {
         junk++;
    }

    Void task0Handler(Void) {

         while (TRUE) {
              //
              // Tell the OTG library code how much time has passed in milliseconds
              // since the last call.
              //
              USBOTGMain(1);

              //
              // Call functions as needed to keep the host or device mode running.
              //
              if (g_eCurrentUSBMode == USB_MODE_DEVICE) {
                   testFxn1();
              } else if (g_eCurrentUSBMode == USB_MODE_HOST) {
                   testFxn2();
              }
              Task_sleep(1);
         }
    }

    //*****************************************************************************
    //
    // Callback function for USB OTG mode changes.
    //
    //*****************************************************************************
    static void ModeCallback(unsigned long ulIndex, tUSBMode eMode) {
         //
         // Save the new mode.
         //
         g_eCurrentUSBMode = eMode;

         //
         // Mode-specific handling code could go here.
         //
         switch (eMode) {
              case USB_MODE_HOST: {
              break;
              }
              case USB_MODE_DEVICE: {
              break;
              }
              case USB_MODE_NONE: {
              break;
              }
             default: {
             break;
             }
        }
    }

    //*****************************************************************************
    //
    // Initialize and operate the data logger.
    //
    //*****************************************************************************
    int main(void) {
         Board_initGeneral();
         //
         // Enable the USB peripheral
         //
         SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
         SysCtlUSBPLLEnable();
         //
         // Configure the required pins for USB operation.
         //
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
         GPIOPinConfigure(GPIO_PG4_USB0EPEN);
         GPIOPinTypeUSBDigital(GPIO_PORTG_BASE, GPIO_PIN_4);
         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
         GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
         GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
         //
         // Initialize the USB stack mode and pass in a mode callback.
         //
         USBStackModeSet(0, USB_MODE_OTG, ModeCallback);
         //
         // Initialize the USB controller for dual mode operation with a 2ms polling
         // rate.
         //
         USBOTGModeInit(0, 2000, g_pHCDPool, HCD_MEMORY_SIZE);

         Hwi_Handle hwi0;
         Hwi_Params hwiParams;
         Error_Block eb;
         Error_init(&eb);
         Hwi_Params_init(&hwiParams);
         hwi0 = Hwi_create(60, (ti_sysbios_hal_Hwi_FuncPtr) USB0OTGModeIntHandler,
         &hwiParams, &eb);
         if (hwi0 == NULL) {
         System_abort("Hwi create failed");
         }

         BIOS_start();
    }

  • Hi Ben,

    I spoke to someone who has worked a lot with TI-RTOS (SYSBIOS) and he has this advice:

    It would simplify things, I think, if you statically registers your ISRs in the sysbios.cfg file.  I've never successfully created a dynamic sysbios object myself (not for lack of trying).  Your hwi_params are probably not right.  Using the GUI will get you off on a better foot.

    For that matter, maybe you should start with something a bit more basic… like hooking a GPIO ISR connected to a switch.   And then once you are confident that's working you can attempt to hook the USB ISR.

    I hope that helps!

    Regards,

    Sue

  • Hello Sue, I actually started by using the GUI/static method.  Some things to note:  SysTick Interrupt works fine; it's function is in main (code posted above).  The last line of this .cfg (commented out) works with testFxn1 in main (code posted above).  However, once registering the usb interrupt to USB0OTGModeIntHandler (located in usbmodes.c) the code becomes unresponsive: upon running I don't even get to start from main.  It is getting stuck in Hwi_excFillContext in hwi.c.

    I'm not sure if this helps clarify.  If not I'm sure I could gather more info.

    /* ================ General configuration ================ */
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var FatFS = xdc.useModule('ti.sysbios.fatfs.FatFS');

    /* ================ System configuration ================ */
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    System.SupportProxy = SysMin;

    /* ================ Logging configuration ================ */
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');

    /* ================ Driver configuration ================ */
    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');

    var GPIO = xdc.useModule('ti.drivers.GPIO');
    var SDSPI = xdc.useModule('ti.drivers.SDSPI');
    var UART = xdc.useModule('ti.drivers.UART');
    var USBMSCHFatFs = xdc.useModule('ti.drivers.USBMSCHFatFs');
    var Watchdog = xdc.useModule('ti.drivers.Watchdog');
    var task0Params = new Task.Params();
    task0Params.instance.name = "task0";
    task0Params.vitalTaskFlag = false;
    Program.global.task0 = Task.create("&task0Handler", task0Params);
    BIOS.libType = BIOS.LibType_Custom;
    var hwi0Params = new Hwi.Params();
    hwi0Params.instance.name = "hwi0";
    Program.global.hwi0 = Hwi.create(15, "&SysTickIntHandler", hwi0Params);
    var hwi1Params = new Hwi.Params();
    hwi1Params.instance.name = "hwi1";

    //This does not work
    Program.global.hwi1 = Hwi.create(60, "&USB0OTGModeIntHandler", hwi1Params);

    //This works
    //Program.global.hwi1 = Hwi.create(60, "&testFxn1", hwi1Params);

     

  • Ben,

    Ben Malchow said:
    The last line of this .cfg (commented out) works with testFxn1 in main (code posted above).

    Can you define "works"?  You mean to say that IRQ60 causes a call to testFxn1?  And you infer this because you observe 'junk' decrementing?  Did you set a breakpoint on testFxn1 and look at the call stack?  You also call it from task0Handler() in your while() loop.  Are you in testFxn1() because of the interrupt or because of your task?

    Ben Malchow said:
    However, once registering the usb interrupt to USB0OTGModeIntHandler (located in usbmodes.c) the code becomes unresponsive

    I haven't worked with USB much.  There are probably interactions between USBOTGMain() and USB0OTGModeIntHandler() which are probably telling to USB folks but I'm going to treat this as a generic interrupt/sys-bios interaction problem and ignore the inner workings of USB for now.

    Please #if 0 out the HWI_create() in main() and go back to the static creation in sysbios.cfg.  Then:

    1. rebuild
    2. reset the target
    3. reload the code
    4. set breakpoint on main().
    5. set a breakpoint on task0IntHandler().
    6. set a breakpoint on  USB0OTGModeIntHandler()
    7. run

    Do you hit a breakpoint?  In which order do you hit them?  What board are you running on?  

    --Miles

  • Hi Miles.  I did all of the above and none of the breakpoints hit.  I am running on a LM4F232H5QD.  Thanks!

  • Hi Miles,  I should have been more specific on my last response.  It works because IRQ60 calls it.  I never get the usb call back function to set the mode of the usb, therefore testFxn1 is never called from the while loop within my task.  Thanks!

  • You're not making it to main?  So it's dying in one of the runtime init functions? 

    Can you clean your CCS project, zip it up, and post it to this thread?  You should be able to right click the project, select "export", general, archive file.

    Thanks!

    --Miles

  • Hi Miles, I really appreciate you taking the time to do this.  Attached is the cleaned project export.  Thanks!

  • Ben,

    Those files never came through on the forum.  Could you email them to support_lmi@ti.com ?

    Which board/part are you running on these days?  I assume you're still using sys/bios and CCS v5.4 or later?

    --Miles