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.

TM4C123GH6PM: Using TM4C123 USB for memory stick application

Part Number: TM4C123GH6PM

Hello,

I am currently working on an application that needs to interface with a memory stick and write csv file into it. I am using the qs-logger example under the TIVAware dk-tm4c123 folder. I kinda get some parts of it. But what is really confusing me is the use of the USBOTGMain function. I pasted a portion of the sample code below. I highlighted the function call in bold red. Below is what the user's guide says about the function. Here are a few things I do not understand:

1) The description says it has to be called periodically. Why?  From the example it looks like it is called every time the while loop repeats but the time of iteration is not always going to be equal right? Why not call this function inside a timer handler? Maybe I am really getting confused here. And why call this function periodically? 

2)I have some understanding of freeRTOS, where each task is like a "small main" and I'm trying to relate that concept here based on the description below. Could someone please clarify this? The description mentions "cooperative system" My understanding of cooperative scheduling is that the task runs until it explicitly yields and this is when context switching occurs. I'm trying to tie this understanding to the description. Does this mean that while this USB main is running, no other task could run? And while this function is running, what happens when an interrupt (say pushbutton press) occurs? 

3)Also, If I use freeRTOS in my program, how will this function call come into play now that I have RTOS present?

My thoughts and ideas are all over the place so apologies in advance. I'm just so confused about what this function is for. 

Thank you very much. 

AJ

USBOTGMain
This function is the main routine for the OTG Controller Driver.


Prototype:
void
USBOTGMain(uint32_t ui32MsTicks)


Parameters:
ui32MsTicks is the number of milliseconds that have passed since the last time this function
was called.


Description:
This function is the main routine for the USB controller when using the library in OTG mode.
This routine must be called periodically by the main application outside of a callback context.
The ui32MsTicks value is used for basic timing needed by the USB library when operating in
OTG mode. This allows for a simple cooperative system to access the the OTG controller driver
interface without the need for an RTOS. All time critical operations are handled in interrupt
context but all longer operations are run from the this function to allow them to block and wait
for completion without holding off other interrupts.


Returns:
None.

  while(1)
    {

        //
        // Each time the timer tick occurs, process any button events.
        //
        if(g_ui32TickCount != ui32LastTickCount)
        {
            //
            // Remember last tick count
            //
            ui32LastTickCount = g_ui32TickCount;

            //
            // Read the debounced state of the buttons.
            //
            ui8ButtonState = ButtonsPoll(&ui8ButtonChanged, 0);

            //
            // Pass any button presses through to the widget message
            // processing mechanism.  The widget that has the button event
            // focus (probably the menu widget) will catch these button events.
            //
            if(BUTTON_PRESSED(SELECT_BUTTON, ui8ButtonState, ui8ButtonChanged))
            {
                SendWidgetKeyMessage(WIDGET_MSG_KEY_SELECT);
            }
            if(BUTTON_PRESSED(UP_BUTTON, ui8ButtonState, ui8ButtonChanged))
            {
                SendWidgetKeyMessage(WIDGET_MSG_KEY_UP);
            }
            if(BUTTON_PRESSED(DOWN_BUTTON, ui8ButtonState, ui8ButtonChanged))
            {
                SendWidgetKeyMessage(WIDGET_MSG_KEY_DOWN);
            }
            if(BUTTON_PRESSED(LEFT_BUTTON, ui8ButtonState, ui8ButtonChanged))
            {
                SendWidgetKeyMessage(WIDGET_MSG_KEY_LEFT);
            }
            if(BUTTON_PRESSED(RIGHT_BUTTON, ui8ButtonState, ui8ButtonChanged))
            {
                SendWidgetKeyMessage(WIDGET_MSG_KEY_RIGHT);
            }
        }

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

        //
        // Call functions as needed to keep the host or device mode running.
        //
        if(g_iCurrentUSBMode == eUSBModeDevice)
        {
            USBSerialRun();
        }
        else if(g_iCurrentUSBMode == eUSBModeHost)
        {
            USBStickRun();
        }

        //
        // If in the logging state, then call the logger run function.  This
        // keeps the data acquisition running.
        //
        if((g_iLoggerState == eSTATE_LOGGING) ||
           (g_iLoggerState == eSTATE_VIEWING))
        {
            if(AcquireRun() && g_sConfigState.ui32SleepLogging)
            {
                //
                // If sleep logging is enabled, then at this point we have
                // stored the first data item, now save the state and start
                // hibernation.  Wait for the power to be cut.
                //
                SetSavedState(&g_sConfigState);
                HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC);
                HibernateRequest();
                for(;;)
                {
                }
            }

            //
            // If viewing instead of logging then request a repaint to keep
            // the viewing window updated.
            //
            if(g_iLoggerState == eSTATE_VIEWING)
            {
                WidgetPaint(WIDGET_ROOT);
            }
        }

        //
        // If in the saving state, then save data from flash storage to
        // USB stick.
        //
        if(g_iLoggerState == eSTATE_SAVING)
        {
            //
            // Save data from flash to USB
            //
            FlashStoreSave();

            //
            // Return to idle state
            //
            g_iLoggerState = eSTATE_IDLE;
        }

  • Hello AJ,

    AJ_ee said:
    1) The description says it has to be called periodically. Why?

    This function handles tasks not suited for timers but that do need to be called before the USB stack times out. The variable passed is used to determine if a timeout may have occurred between calls.

    AJ_ee said:
    Why not call this function inside a timer handler?

    Periodically in this case doesn't mean it needs to be called at a specific interval, and more importantly, the function itself isn't good to be called from an ISR because it would cause the ISR to be active for a lengthy period of time.

    This is stated less directly worded in the description as well: "All time critical operations are handled in interrupt context but all longer operations are run from the this function to allow them to block and wait for completion without holding off other interrupts."

    I don't think the cooperative scheduling comment made in the code was meant to relate to RTOS, so I don't think your analogy would apply as well as you think it may.

    As far as the RTOS question goes, it just needs to be handled as a periodic task. It would need to be assigned a priority that would be lower than time critical tasks, but not at the bottom of the rung either. Exactly where that fits in is application specific, but in general you want to avoid it timing out often.