Beispiel #1
0
//*****************************************************************************
//
// Initializes the sound output.
//
// \param ui32Flags is unused as this point but is included for future
// functionality.
// \param pfnCallback is the event callback function for audio devices.
//
// This function prepares the sound driver to enumerate an audio device and
// prepares to play audio once a valid audio device is detected.  The
// \e pfnCallback function can be used to receive callbacks when there are
// changes related to the audio device.  The ui32Event parameter to the callback
// will be one of the SOUND_EVENT_* values.
//
// \return None
//
//*****************************************************************************
void
USBSoundInit(uint32_t ui32Flags, tEventCallback pfnCallback)
{
    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Set the USB power pins to be controlled by the USB controller.
    //
    GPIOPinTypeUSBDigital(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    //
    // Enable the uDMA controller and set up the control table base.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    uDMAEnable();
    uDMAControlBaseSet(g_sDMAControlTable);

    //
    // Initialize the USB stack mode to OTG.
    //
    USBStackModeSet(0, eUSBModeOTG, 0);

    //
    // Register the host class drivers.
    //
    USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ui32NumHostClassDrivers);

    //
    // Open an instance of the audio class driver.
    //
    g_psAudioInstance = USBHostAudioOpen(0, AudioCallback);

    //
    // Initialize the power configuration. This sets the power enable signal
    // to be active high and does not enable the power fault.
    //
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    //
    // Initialize the USB controller for OTG operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pHCDPool, HCD_MEMORY_SIZE);

    //
    // Save the event callback function.
    //
    g_sAudioState.pfnCallbackEvent = pfnCallback;
}
//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{
    tRectangle sRect;
    tUSBMode eLastMode;
    char *pcString;

    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();

    //
    // Set the system clock to run at 50MHz from the PLL.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Initially wait for device connection.
    //
    g_eUSBState = STATE_NO_DEVICE;
    eLastMode = USB_MODE_OTG;
    g_eCurrentUSBMode = USB_MODE_OTG;

    //
    // Enable Clocking to the USB controller.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    
    //
    // Configure the required pins for USB operation.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    ROM_GPIOPinConfigure(GPIO_PG4_USB0EPEN);
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTG_BASE, GPIO_PIN_4);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Configure SysTick for a 100Hz interrupt.
    //
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND);
    ROM_SysTickEnable();
    ROM_SysTickIntEnable();

    //
    // Enable Interrupts
    //
    ROM_IntMasterEnable();

    //
    // Enable clocking to the UART and associated GPIO
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure the relevant pins such that UART0 owns them.
    //
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Open UART0 for debug output.
    //
    UARTStdioInit(0);

    //
    // Initialize the USB stack mode and pass in a mode callback.
    //
    USBStackModeSet(0, USB_MODE_OTG, ModeCallback);

    //
    // Register the host class drivers.
    //
    USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ulNumHostClassDrivers);

    //
    // Open an instance of the keyboard driver.  The keyboard does not need
    // to be present at this time, this just save a place for it and allows
    // the applications to be notified when a keyboard is present.
    //
    g_ulKeyboardInstance = USBHKeyboardOpen(KeyboardCallback, g_pucBuffer,
                                            KEYBOARD_MEMORY_SIZE);

    //
    // Initialize the power configuration. This sets the power enable signal
    // to be active high and does not enable the power fault.
    //
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    //
    // Initialize the USB controller for OTG operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pHCDPool, HCD_MEMORY_SIZE);

    //
    // Initialize the display driver.
    //
    CFAL96x64x16Init();

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sCFAL96x64x16);

    //
    // Fill the top part of the screen with blue to create the banner.
    //
    sRect.sXMin = 0;
    sRect.sYMin = 0;
    sRect.sXMax = GrContextDpyWidthGet(&g_sContext) - 1;
    sRect.sYMax = (2 * DISPLAY_BANNER_HEIGHT) - 1;
    GrContextForegroundSet(&g_sContext, DISPLAY_BANNER_BG);
    GrRectFill(&g_sContext, &sRect);

    //
    // Change foreground for white text.
    //
    GrContextForegroundSet(&g_sContext, DISPLAY_TEXT_FG);

    //
    // Put the application name in the middle of the banner.
    //
    GrContextFontSet(&g_sContext, g_pFontFixed6x8);
    GrStringDrawCentered(&g_sContext, "usb-host-", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 4, 0);
    GrStringDrawCentered(&g_sContext, "keyboard", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 14, 0);


    //
    // Calculate the number of characters that will fit on a line.
    // Make sure to leave a small border for the text box.
    //
    g_ulCharsPerLine = (GrContextDpyWidthGet(&g_sContext) - 4) /
                        GrFontMaxWidthGet(g_pFontFixed6x8);

    //
    // Calculate the number of lines per usable text screen.  This requires
    // taking off space for the top and bottom banners and adding a small bit
    // for a border.
    //
    g_ulLinesPerScreen = (GrContextDpyHeightGet(&g_sContext) -
                          (3*(DISPLAY_BANNER_HEIGHT + 1)))/
                          GrFontHeightGet(g_pFontFixed6x8);

    //
    // Open and instance of the keyboard class driver.
    //
    UARTprintf("Host Keyboard Application\n");

    //
    // Initial update of the screen.
    //
    UpdateStatus();

    //
    // The main loop for the application.
    //
    while(1)
    {
        //
        // Tell the OTG library code how much time has passed in
        // milliseconds since the last call.
        //
        USBOTGMain(GetTickms());

        //
        // Has the USB mode changed since last time we checked?
        //
        if(g_eCurrentUSBMode != eLastMode)
        {
            //
            // Remember the new mode.
            //
            eLastMode = g_eCurrentUSBMode;

            switch(eLastMode)
            {
                case USB_MODE_HOST:
                    pcString = "HOST";
                    break;

                case USB_MODE_DEVICE:
                    pcString = "DEVICE";
                    break;

                case USB_MODE_NONE:
                    pcString = "NONE";
                    break;

                default:
                    pcString = "UNKNOWN";
                    break;
            }

            UARTprintf("USB mode changed to %s\n", pcString);
        }

        switch(g_eUSBState)
        {
            //
            // This state is entered when they keyboard is first detected.
            //
            case STATE_KEYBOARD_INIT:
            {
                //
                // Initialized the newly connected keyboard.
                //
                USBHKeyboardInit(g_ulKeyboardInstance);

                //
                // Proceed to the keyboard connected state.
                //
                g_eUSBState = STATE_KEYBOARD_CONNECTED;

                //
                // Update the screen now that the keyboard has been
                // initialized.
                //
                UpdateStatus();

                USBHKeyboardModifierSet(g_ulKeyboardInstance, g_ulModifiers);

                break;
            }
            case STATE_KEYBOARD_UPDATE:
            {
                //
                // If the application detected a change that required an
                // update to be sent to the keyboard to change the modifier
                // state then call it and return to the connected state.
                //
                g_eUSBState = STATE_KEYBOARD_CONNECTED;

                USBHKeyboardModifierSet(g_ulKeyboardInstance, g_ulModifiers);

                break;
            }
            case STATE_KEYBOARD_CONNECTED:
            {
                //
                // Nothing is currently done in the main loop when the keyboard
                // is connected.
                //
                break;
            }

            case STATE_UNKNOWN_DEVICE:
            {
                //
                // Nothing to do as the device is unknown.
                //
                break;
            }

            case STATE_NO_DEVICE:
            {
                //
                // Nothing is currently done in the main loop when the keyboard
                // is not connected.
                //
                break;
            }
            default:
            {
                break;
            }
        }
    }
}
Beispiel #3
0
//*****************************************************************************
//
// Initialize and operate the data logger.
//
//*****************************************************************************
int
main(void)
{
    tContext sDisplayContext, sBufferContext;
    uint32_t ui32HibIntStatus, ui32SysClock, ui32LastTickCount;
    bool bSkipSplash;
    uint8_t ui8ButtonState, ui8ButtonChanged;
    uint_fast8_t ui8X, ui8Y;


    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    MAP_FPULazyStackingEnable();

    //
    // Set the clocking to run at 50 MHz.
    //
    MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                       SYSCTL_OSC_MAIN);
    ui32SysClock = MAP_SysCtlClockGet();

    //
    // Initialize locals.
    //
    bSkipSplash = false;
    ui32LastTickCount = 0;

    //
    // Initialize the data acquisition module.  This initializes the ADC
    // hardware.
    //
    AcquireInit();

    //
    // Enable access to  the hibernate peripheral.  If the hibernate peripheral
    // was already running then this will have no effect.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

    //
    // Check to see if the hiberate module is already active and if so then
    // read the saved configuration state.  If both are okay, then proceed
    // to check and see if we are logging data using sleep mode.
    //
    if(HibernateIsActive() && !GetSavedState(&g_sConfigState))
    {
        //
        // Read the status of the hibernate module.
        //
        ui32HibIntStatus = HibernateIntStatus(1);

        //
        // If this is a pin wake, that means the user pressed the select
        // button and we should terminate the sleep logging.  In this case
        // we will fall out of this conditional section, and go through the
        // normal startup below, but skipping the splash screen so the user
        // gets immediate response.
        //
        if(ui32HibIntStatus & HIBERNATE_INT_PIN_WAKE)
        {
            //
            // Clear the interrupt flag so it is not seen again until another
            // wake.
            //
            HibernateIntClear(HIBERNATE_INT_PIN_WAKE);
            bSkipSplash = true;
        }

        //
        // Otherwise if we are waking from hibernate and it was not a pin
        // wake, then it must be from RTC match.  Check to see if we are
        // sleep logging and if so then go through an abbreviated startup
        // in order to collect the data and go back to sleep.
        //
        else if(g_sConfigState.ui32SleepLogging &&
                (ui32HibIntStatus & HIBERNATE_INT_RTC_MATCH_0))
        {
            //
            // Start logger and pass the configuration.  The logger should
            // configure itself to take one sample.
            //
            AcquireStart(&g_sConfigState);
            g_iLoggerState = eSTATE_LOGGING;

            //
            // Enter a forever loop to run the acquisition.  This will run
            // until a new sample has been taken and stored.
            //
            while(!AcquireRun())
            {
            }

            //
            // Getting here means that a data acquisition was performed and we
            // can now go back to sleep.  Save the configuration and then
            // activate the hibernate.
            //
            SetSavedState(&g_sConfigState);

            //
            // Set wake condition on pin-wake or RTC match.  Then put the
            // processor in hibernation.
            //
            HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC);
            HibernateRequest();

            //
            // Hibernating takes a finite amount of time to occur, so wait
            // here forever until hibernate activates and the processor
            // power is removed.
            //
            for(;;)
            {
            }
        }

        //
        // Otherwise, this was not a pin wake, and we were not sleep logging,
        // so just fall out of this conditional and go through the normal
        // startup below.
        //
    }
    else
    {
        //
        // In this case, either the hibernate module was not already active, or
        // the saved configuration was not valid.  Initialize the configuration
        // to the default state and then go through the normal startup below.
        //
        GetDefaultState(&g_sConfigState);
    }

    //
    // Enable the Hibernate module to run.
    //
    HibernateEnableExpClk(SysCtlClockGet());

    //
    // The hibernate peripheral trim register must be set per silicon
    // erratum 2.1
    //
    HibernateRTCTrimSet(0x7FFF);

    //
    // Start the RTC running.  If it was already running then this will have
    // no effect.
    //
    HibernateRTCEnable();

    //
    // In case we were sleep logging and are now finished (due to user
    // pressing select button), then disable sleep logging so it doesnt
    // try to start up again.
    //
    g_sConfigState.ui32SleepLogging = 0;
    SetSavedState(&g_sConfigState);

    //
    // Initialize the display driver.
    //
    CFAL96x64x16Init();

    //
    // Initialize the buttons driver.
    //
    ButtonsInit();

    //
    // Pass the restored state to the menu system.
    //
    MenuSetState(&g_sConfigState);

    //
    // Enable the USB peripheral
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

    //
    // Configure the required pins for USB operation.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    MAP_GPIOPinConfigure(GPIO_PG4_USB0EPEN);
    MAP_GPIOPinTypeUSBDigital(GPIO_PORTG_BASE, GPIO_PIN_4);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    MAP_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    MAP_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Erratum workaround for silicon revision A1.  VBUS must have pull-down.
    //
    if(CLASS_IS_BLIZZARD && REVISION_IS_A1)
    {
        HWREG(GPIO_PORTB_BASE + GPIO_O_PDR) |= GPIO_PIN_1;
    }

    //
    // Initialize the USB stack mode and pass in a mode callback.
    //
    USBStackModeSet(0, eUSBModeOTG, ModeCallback);

    //
    // Initialize the stack to be used with USB stick.
    //
    USBStickInit();

    //
    // Initialize the stack to be used as a serial device.
    //
    USBSerialInit();

    //
    // Initialize the USB controller for dual mode operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pui8HCDPool, HCD_MEMORY_SIZE);

    //
    // Initialize the menus module.  This module will control the user
    // interface menuing system.
    //
    MenuInit(WidgetActivated);

    //
    // Configure SysTick to periodically interrupt.
    //
    g_ui32TickCount = 0;
    MAP_SysTickPeriodSet(ui32SysClock / CLOCK_RATE);
    MAP_SysTickIntEnable();
    MAP_SysTickEnable();

    //
    // Initialize the display context and another context that is used
    // as an offscreen drawing buffer for display animation effect
    //
    GrContextInit(&sDisplayContext, &g_sCFAL96x64x16);
    GrContextInit(&sBufferContext, &g_sOffscreenDisplayA);

    //
    // Show the splash screen if we are not skipping it.  The only reason to
    // skip it is if the application was in sleep-logging mode and the user
    // just waked it up with the select button.
    //
    if(!bSkipSplash)
    {
        const uint8_t *pui8SplashLogo = g_pui8Image_TI_Black;

        //
        // Draw the TI logo on the display.  Use an animation effect where the
        // logo will "slide" onto the screen.  Allow select button to break
        // out of animation.
        //
        for(ui8X = 0; ui8X < 96; ui8X++)
        {
            if(ButtonsPoll(0, 0) & SELECT_BUTTON)
            {
                break;
            }
            GrImageDraw(&sDisplayContext, pui8SplashLogo, 95 - ui8X, 0);
        }

        //
        // Leave the logo on the screen for a long duration.  Monitor the
        // buttons so that if the user presses the select button, the logo
        // display is terminated and the application starts immediately.
        //
        while(g_ui32TickCount < 400)
        {
            if(ButtonsPoll(0, 0) & SELECT_BUTTON)
            {
                break;
            }
        }

        //
        // Extended splash sequence
        //
        if(ButtonsPoll(0, 0) & UP_BUTTON)
        {
            for(ui8X = 0; ui8X < 96; ui8X += 4)
            {
                GrImageDraw(&sDisplayContext,
                            g_ppui8Image_Splash[(ui8X / 4) & 3],
                            (int32_t)ui8X - 96L, 0);
                GrImageDraw(&sDisplayContext, pui8SplashLogo, ui8X, 0);
                MAP_SysCtlDelay(ui32SysClock / 12);
            }
            MAP_SysCtlDelay(ui32SysClock / 3);
            pui8SplashLogo = g_ppui8Image_Splash[4];
            GrImageDraw(&sDisplayContext, pui8SplashLogo, 0, 0);
            MAP_SysCtlDelay(ui32SysClock / 12);
        }

        //
        // Draw the initial menu into the offscreen buffer.
        //
        SlideMenuDraw(&g_sMenuWidget, &sBufferContext, 0);

        //
        // Now, draw both the TI logo splash screen (from above) and the initial
        // menu on the screen at the same time, moving the coordinates so that
        // the logo "slides" off the display and the menu "slides" onto the
        // display.
        //
        for(ui8Y = 0; ui8Y < 64; ui8Y++)
        {
            GrImageDraw(&sDisplayContext, pui8SplashLogo, 0, -ui8Y);
            GrImageDraw(&sDisplayContext, g_pui8OffscreenBufA, 0, 63 - ui8Y);
        }
    }

    //
    // Add the menu widget to the widget tree and send an initial paint
    // request.
    //
    WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sMenuWidget);
    WidgetPaint(WIDGET_ROOT);

    //
    // Set the focus handle to the menu widget.  Any button events will be
    // sent to this widget
    //
    g_ui32KeyFocusWidgetHandle = (uint32_t)&g_sMenuWidget;

    //
    // Forever loop to run the application
    //
    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;
        }

        //
        // If in the erasing state, then erase the data stored in flash.
        //
        if(g_iLoggerState == eSTATE_ERASING)
        {
            //
            // Save data from flash to USB
            //
            FlashStoreErase();

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

        //
        // If in the flash reporting state, then show the report of the amount
        // of used and free flash memory.
        //
        if(g_iLoggerState == eSTATE_FREEFLASH)
        {
            //
            // Report free flash space
            //
            FlashStoreReport();

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

        //
        // If we are exiting the clock setting widget, that means that control
        // needs to be given back to the menu system.
        //
        if(g_iLoggerState == eSTATE_CLOCKEXIT)
        {
            //
            // Give the button event focus back to the menu system
            //
            g_ui32KeyFocusWidgetHandle = (uint32_t)&g_sMenuWidget;

            //
            // Send a button event to the menu widget that means the left
            // key was pressed.  This signals the menu widget to deactivate
            // the current child widget (which was the clock setting wigdet).
            // This will cause the menu widget to slide the clock set widget
            // off the screen and resume control of the display.
            //
            SendWidgetKeyMessage(WIDGET_MSG_KEY_LEFT);
            g_iLoggerState = eSTATE_IDLE;
        }

        //
        // Process any new messages that are in the widget queue.  This keeps
        // the user interface running.
        //
        WidgetMessageQueueProcess();
    }
}
//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{
    tRectangle sRect;

    //
    // Set the clocking to run from the PLL at 50MHz.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Initialize the display driver.
    //
    CFAL96x64x16Init();

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sCFAL96x64x16);

    //
    // Fill the top part of the screen with blue to create the banner.
    //
    sRect.i16XMin = 0;
    sRect.i16YMin = 0;
    sRect.i16XMax = GrContextDpyWidthGet(&g_sContext) - 1;
    sRect.i16YMax = (DISPLAY_BANNER_HEIGHT) - 1;
    GrContextForegroundSet(&g_sContext, DISPLAY_BANNER_BG);
    GrRectFill(&g_sContext, &sRect);

    //
    // Change foreground for white text.
    //
    GrContextForegroundSet(&g_sContext, DISPLAY_TEXT_FG);

    //
    // Put the application name in the middle of the banner.
    //
    GrContextFontSet(&g_sContext, g_psFontFixed6x8);
    GrStringDrawCentered(&g_sContext, "usb-host-mouse", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 4, 0);

    //
    // Display default information about the mouse
    //
    GrStringDrawCentered(&g_sContext, "Position:", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 16, 0);
    GrStringDrawCentered(&g_sContext, "-,-", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 26, 1);
    GrStringDrawCentered(&g_sContext, "Buttons:", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 36, 0);
    GrStringDrawCentered(&g_sContext, "---", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 46, 1);

    //
    // Fill the bottom rows of the screen with blue to create the status area.
    //
    sRect.i16XMin = 0;
    sRect.i16YMin = GrContextDpyHeightGet(&g_sContext) -
                  DISPLAY_BANNER_HEIGHT - 1;
    sRect.i16XMax = GrContextDpyWidthGet(&g_sContext) - 1;
    sRect.i16YMax = sRect.i16YMin + DISPLAY_BANNER_HEIGHT;

    GrContextForegroundSet(&g_sContext, DISPLAY_BANNER_BG);
    GrRectFill(&g_sContext, &sRect);

    //
    // Put a white box around the banner.
    //
    GrContextForegroundSet(&g_sContext, ClrWhite);
    GrRectDraw(&g_sContext, &sRect);

    //
    // Print a no device message a placeholder for the message printed
    // during an event.
    //
    GrStringDrawCentered(&g_sContext, "No Device", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2,
                         sRect.i16YMin + 5, 0);

    //
    // Configure SysTick for a 100Hz interrupt.
    //
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND);
    ROM_SysTickEnable();
    ROM_SysTickIntEnable();

    //
    // Enable Clocking to the USB controller.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

    //
    // Configure the required pins for USB operation.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    ROM_GPIOPinConfigure(GPIO_PG4_USB0EPEN);
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTG_BASE, GPIO_PIN_4);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Initially wait for device connection.
    //
    g_eUSBState = STATE_NO_DEVICE;

    //
    // Initialize the USB stack mode and pass in a mode callback.
    //
    USBStackModeSet(0, eUSBModeOTG, ModeCallback);

    //
    // Register the host class drivers.
    //
    USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ui32NumHostClassDrivers);

    //
    // Initialized the cursor.
    //
    g_ui32Buttons = 0;
    g_i32CursorX = 0;
    g_i32CursorY = 0;

    //
    // Open an instance of the mouse driver.  The mouse does not need
    // to be present at this time, this just saves a place for it and allows
    // the applications to be notified when a mouse is present.
    //
    g_psMouseInstance =
        USBHMouseOpen(MouseCallback, g_pui8Buffer, MOUSE_MEMORY_SIZE);

    //
    // Initialize the power configuration. This sets the power enable signal
    // to be active high and does not enable the power fault.
    //
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    //
    // Initialize the USB controller for OTG operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pui8HCDPool, HCD_MEMORY_SIZE);

    //
    // The main loop for the application.
    //
    while(1)
    {
        //
        // Tell the OTG state machine how much time has passed in
        // milliseconds since the last call.
        //
        USBOTGMain(GetTickms());

        switch(g_eUSBState)
        {
            //
            // This state is entered when the mouse is first detected.
            //
            case STATE_MOUSE_INIT:
            {
                //
                // Initialize the newly connected mouse.
                //
                USBHMouseInit(g_psMouseInstance);

                //
                // Proceed to the mouse connected state.
                //
                g_eUSBState = STATE_MOUSE_CONNECTED;

                break;
            }

            case STATE_MOUSE_CONNECTED:
            {
                //
                // Nothing is currently done in the main loop when the mouse
                // is connected.
                //
                break;
            }

            case STATE_NO_DEVICE:
            {
                //
                // The mouse is not connected so nothing needs to be done here.
                //
                break;
            }

            default:
            {
                break;
            }
        }
    }
}
Beispiel #5
0
//*****************************************************************************
//
// Initializes the USB OTG task.
//
//*****************************************************************************
unsigned long
USBOTGTaskInit(void)
{
    //
    // Configure the required pins for USB operation.
    //
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    ROM_GPIOPinTypeUSBDigital(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 host stack.
    //
    HostMSCInit();

    //
    // Initialize the device stack.
    //
    DeviceMSCInit();

    //
    // Initialize the USB controller for dual mode operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pHCDPool, HCD_MEMORY_SIZE);
    //
    // Set the new state so that the screen updates on the first
    // pass.
    //
    g_ulNewState = 1;
    //
    // Create a queue for sending messages to the display task.
    //
    if(xQueueCreate((signed portCHAR *)g_pulDisplayQueueMem, DISPLAY_MEM_SIZE,
                    DISPLAY_QUEUE_SIZE, DISPLAY_ITEM_SIZE,
                    &g_pDisplayQueue) != pdPASS)
    {
        return(1);
    }

    //
    // Create the display task.
    //
    if(xTaskCreate(USBOTGTask, (signed portCHAR *)"USB-OTG",
                   (signed portCHAR *)ulUSBOTGTaskStack,
                   sizeof(ulUSBOTGTaskStack), NULL, PRIORITY_USB_CTRL_TASK,
                   NULL) != pdPASS)
    {
        return(1);
    }
    TaskCreated();

    //
    // Success.
    //
    return(0);
}
void Hardware_Init(void)
{
    // Initially wait for device connection.
    g_eState = STATE_NO_DEVICE;
    g_eUIState = STATE_NO_DEVICE;

    // Set the clocking to run from the PLL at 50MHz.
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |    SYSCTL_XTAL_16MHZ);

    // Initialize the UART.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_4 | GPIO_PIN_5);    
    
    UARTprintf("\n\nUSB Android ADK Firmware for EvalBot by [email protected]\n");

    /*  Configure EvalBot available Buttons (User Switch 1, 2 ...) */
    // Enable the GPIO pin to read the select button.
    ROM_SysCtlPeripheralEnable(USER_SW1_SYSCTL_PERIPH);
    ROM_GPIODirModeSet(USER_SW1_PORT_BASE, USER_SW1_PIN, GPIO_DIR_MODE_IN);
    ROM_GPIOPadConfigSet(USER_SW1_PORT_BASE, USER_SW1_PIN, GPIO_STRENGTH_2MA,
    GPIO_PIN_TYPE_STD_WPU);
    // Enable the GPIO pin to read the select button.
    ROM_SysCtlPeripheralEnable(USER_SW2_SYSCTL_PERIPH);
    ROM_GPIODirModeSet(USER_SW2_PORT_BASE, USER_SW2_PIN, GPIO_DIR_MODE_IN);
    ROM_GPIOPadConfigSet(USER_SW2_PORT_BASE, USER_SW2_PIN, GPIO_STRENGTH_2MA,
    GPIO_PIN_TYPE_STD_WPU);
    
    // Enable the GPIO pin to read the select button.
    // Enable the GPIO ports used for the bump sensors.
    ROM_SysCtlPeripheralEnable(BUMP_L_SW3_SYSCTL_PERIPH);    
    ROM_GPIODirModeSet(BUMP_L_SW3_PORT_BASE, BUMP_L_SW3_PIN, GPIO_DIR_MODE_IN);
    ROM_GPIOPadConfigSet(BUMP_L_SW3_PORT_BASE, BUMP_L_SW3_PIN, GPIO_STRENGTH_2MA,
                        GPIO_PIN_TYPE_STD_WPU);
    // Enable the GPIO pin to read the select button.
    ROM_SysCtlPeripheralEnable(BUMP_R_SW4_SYSCTL_PERIPH);    
    ROM_GPIODirModeSet(BUMP_R_SW4_PORT_BASE, BUMP_R_SW4_PIN, GPIO_DIR_MODE_IN);
    ROM_GPIOPadConfigSet(BUMP_R_SW4_PORT_BASE, BUMP_R_SW4_PIN, GPIO_STRENGTH_2MA,
                        GPIO_PIN_TYPE_STD_WPU);

    // Enable the GPIO pin for the LED1 (PF4) & LED2 (PF5) 
    // Set the direction as output, and enable the GPIO pin for digital function.
    ROM_SysCtlPeripheralEnable(LED1_SYSCTL_PERIPH);      
    GPIOPinTypeGPIOOutput(LED1_PORT_BASE, LED1_PIN);
    ROM_SysCtlPeripheralEnable(LED2_SYSCTL_PERIPH);  
    GPIOPinTypeGPIOOutput(LED2_PORT_BASE, LED2_PIN);

    // Configure SysTick for a 1KHz interrupt.
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND);
    ROM_SysTickEnable();
    ROM_SysTickIntEnable();

    // Enable Clocking to the USB controller.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

    // Set the USB pins to be controlled by the USB controller.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    
    GPIOPinConfigure(GPIO_PA6_USB0EPEN);
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTA_BASE, GPIO_PIN_6);

    // Enable the GPIO pin for the USB HOST / DEVICE Selection (PB0).  Set the direction as output, and
    // enable the GPIO pin for digital function.
    GPIO_PORTB_DIR_R |= GPIO_PIN_0;    GPIO_PORTB_DEN_R |= GPIO_PIN_0;
    // PB0 = GND =USB HOST Enabled.
    GPIO_PORTB_DATA_R &= ~(GPIO_PIN_0);      

    // Enable the uDMA controller and set up the control table base.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    ROM_uDMAEnable();
    ROM_uDMAControlBaseSet(g_sDMAControlTable);

    // Initialize the USB stack mode and pass in a mode callback.
    USBStackModeSet(0, USB_MODE_OTG, ModeCallback);

    // Register the host class drivers.
    USBHCDRegisterDrivers(0, g_ppHostClassDrivers, NUM_CLASS_DRIVERS);

    // Initialize the power configuration.  This sets the power enable signal
    // to be active high and does not enable the power fault.
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    // Initialize the USB controller for OTG operation with a 250ms polling
    // rate.
    // Warning if this delay is higher it cannot connect correctly to Android ADK.
    USBOTGModeInit(0, 250, g_pHCDPool, HCD_MEMORY_SIZE);

}
//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{
    //
    // Set the clocking to run from the PLL at 50MHz.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Enable the peripherals used by this example.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);

    //
    // Enable the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);
    UARTprintf("\033[2JHost Keyboard Application\n");

    //
    // Configure SysTick for a 100Hz interrupt.
    //
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND);
    ROM_SysTickEnable();
    ROM_SysTickIntEnable();

    //
    // Enable Clocking to the USB controller.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

    //
    // Configure the power pins for host controller.
    //
    GPIOPinConfigure(GPIO_PH3_USB0EPEN);
    GPIOPinConfigure(GPIO_PH4_USB0PFLT);
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTH_BASE, GPIO_PIN_3 | GPIO_PIN_4);

    //
    // Initially wait for device connection.
    //
    g_eUSBState = STATE_NO_DEVICE;

    //
    // Initialize the USB stack mode and pass in a mode callback.
    //
    USBStackModeSet(0, USB_MODE_OTG, ModeCallback);

    //
    // Register the host class drivers.
    //
    USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ulNumHostClassDrivers);

    //
    // Open an instance of the keyboard driver.  The keyboard does not need
    // to be present at this time, this just save a place for it and allows
    // the applications to be notified when a keyboard is present.
    //
    g_ulKeyboardInstance = USBHKeyboardOpen(KeyboardCallback, g_pucBuffer,
                                            KEYBOARD_MEMORY_SIZE);

    //
    // Initialize the power configuration. This sets the power enable signal
    // to be active high and does not enable the power fault.
    //
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    //
    // Initialize the USB controller for OTG operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pHCDPool, HCD_MEMORY_SIZE);

    //
    // The main loop for the application.
    //
    while(1)
    {
        //
        // Tell the OTG state machine how much time has passed in
        // milliseconds since the last call.
        //
        USBOTGMain(GetTickms());

        switch(g_eUSBState)
        {
            //
            // This state is entered when they keyboard is first detected.
            //
            case STATE_KEYBOARD_INIT:
            {
                //
                // Initialized the newly connected keyboard.
                //
                USBHKeyboardInit(g_ulKeyboardInstance);

                //
                // Proceed to the keyboard connected state.
                //
                g_eUSBState = STATE_KEYBOARD_CONNECTED;

                USBHKeyboardModifierSet(g_ulKeyboardInstance, g_ulModifiers);

                break;
            }

            case STATE_KEYBOARD_UPDATE:
            {
                //
                // If the application detected a change that required an
                // update to be sent to the keyboard to change the modifier
                // state then call it and return to the connected state.
                //
                g_eUSBState = STATE_KEYBOARD_CONNECTED;

                USBHKeyboardModifierSet(g_ulKeyboardInstance, g_ulModifiers);

                break;
            }

            case STATE_KEYBOARD_CONNECTED:
            {
                //
                // Nothing is currently done in the main loop when the keyboard
                // is connected.
                //
                break;
            }

            case STATE_UNKNOWN_DEVICE:
            {
                //
                // Nothing to do as the device is unknown.
                //
                break;
            }

            case STATE_NO_DEVICE:
            {
                //
                // Nothing is currently done in the main loop when the keyboard
                // is not connected.
                //
                break;
            }

            default:
            {
                break;
            }
        }
    }
}
//*****************************************************************************
//
// main routine.
//
//*****************************************************************************
int
main(void)
{
    tLPMFeature sLPMFeature;

    //
    // 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.
    //
    PinoutSet();

    //
    // Configure the UART.
    //
    UARTStdioConfig(0, 115200, g_ui32SysClock);

    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init(g_ui32SysClock);

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Draw the application frame.
    //
    FrameDraw(&g_sContext, "usb-otg-mouse");

    //
    // 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();

    //
    // Initialize the device stack.
    //
    DeviceInit();

    //
    // Initialize the USB controller for dual mode operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pui8HCDPool, HCD_MEMORY_SIZE);

    //
    // Set the new state so that the screen updates on the first
    // pass.
    //
    g_ui32NewState = 1;

    //
    // 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)
        {
            g_ui32NewState =0;

            //
            // Update the status area of the screen.
            //
            ClearMainWindow();

            //
            // Update the status bar with the new mode.
            //
            switch(g_iCurrentMode)
            {
                case eUSBModeHost:
                {
                    UpdateStatus("Host Mode", 0, true);
                    break;
                }
                case eUSBModeDevice:
                {
                    UpdateStatus("Device Mode", 0, true);
                    break;
                }
                case eUSBModeNone:
                {
                    UpdateStatus("Idle Mode\n", 0, true);
                    break;
                }
                default:
                {
                    break;
                }
            }
        }

        if(g_iCurrentMode == eUSBModeDevice)
        {
            DeviceMain();
        }
        else if(g_iCurrentMode == eUSBModeHost)
        {
            HostMain();
        }
    }
}
//*****************************************************************************
//
// Capture one sequence of DEVCTL register values during a session request.
//
//*****************************************************************************
int
main(void)
{
    tRectangle sRect;

    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Set the pinout appropriately for this board.
    //
    PinoutSet();

    //
    // Initialize the display driver.
    //
    Kitronix320x240x16_SSD2119Init();

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sKitronix320x240x16_SSD2119);

    //
    // Fill the top 15 rows of the screen with blue to create the banner.
    //
    sRect.sXMin = 0;
    sRect.sYMin = 0;
    sRect.sXMax = GrContextDpyWidthGet(&g_sContext) - 1;
    sRect.sYMax = 14;
    GrContextForegroundSet(&g_sContext, ClrDarkBlue);
    GrRectFill(&g_sContext, &sRect);

    //
    // Put a white box around the banner.
    //
    GrContextForegroundSet(&g_sContext, ClrWhite);
    GrRectDraw(&g_sContext, &sRect);

    //
    // Put the application name in the middle of the banner.
    //
    GrContextFontSet(&g_sContext, g_pFontFixed6x8);
    GrStringDrawCentered(&g_sContext, "OTG Example", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 7, 0);

#ifdef DEBUG
    //
    // Configure the relevant pins such that UART0 owns them.
    //
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Open the UART for I/O
    //
    UARTStdioInit(0);
#endif

    //
    // Determine the number of SysCtlDelay loops required to delay 1mS.
    //
    g_ulClockMS = ROM_SysCtlClockGet() / (3 * 1000);

    //
    // Configure the required pins for USB operation.
    //
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    ROM_GPIOPinTypeUSBDigital(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 host stack.
    //
    HostInit();

    //
    // Initialize the device stack.
    //
    DeviceInit();

    //
    // Initialize the USB controller for dual mode operation with a 2ms polling
    // rate.
    //
    USBOTGModeInit(0, 2000, g_pHCDPool, HCD_MEMORY_SIZE);

    //
    // Set the new state so that the screen updates on the first
    // pass.
    //
    g_ulNewState = 1;

    //
    // 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_ulNewState)
        {
            g_ulNewState =0;

            //
            // Update the status area of the screen.
            //
            ClearMainWindow();

            //
            // Update the status bar with the new mode.
            //
            switch(g_eCurrentUSBMode)
            {
                case USB_MODE_HOST:
                {
                    UpdateStatus("Host Mode", 0, true);
                    break;
                }
                case USB_MODE_DEVICE:
                {
                    UpdateStatus("Device Mode", 0, true);
                    break;
                }
                case USB_MODE_NONE:
                {
                    UpdateStatus("Idle Mode", 0, true);
                    break;
                }
                default:
                {
                    break;
                }
            }

        }

        if(g_eCurrentUSBMode == USB_MODE_DEVICE)
        {
            DeviceMain();
        }
        else if(g_eCurrentUSBMode == USB_MODE_HOST)
        {
            HostMain();
        }
    }
}