/*
 *  ======== USBMSCHFatFsTiva_diskInitialize ========
 *  This function checks the USB Drive to see if it's ready to be accessed.
 *
 *  This function attempts to read the USBHMSCDriveReady() function up to 10
 *  times to get a good return code. For some reason the first attempt to read
 *  this function doesn't return a good response value. Generally, you should
 *  get a good response on the second attempt.
 *  A gateMutex lock is required to prevent concurrent access to the USB
 *  Library's state machine variables within MSCInstance.
 *
 *  @param  drv Drive Number
 *
 *  @return Returns the disk status to the FatFs module
 */
DSTATUS USBMSCHFatFsTiva_diskInitialize(BYTE drv)
{
    unsigned char               i;
    unsigned int                key;
    uint32_t                    driveReady;
    USBMSCHFatFsTiva_Object    *object = USBMSCHFatFs_config->object;

    /* Determine if the USB Drive is ready up to 10 times */
    for (i = 0; i < 10; i++ ) {

        key = GateMutex_enter(GateMutex_handle(&(object->gateUSBLibAccess)));
        driveReady = USBHMSCDriveReady(object->MSCInstance);
        GateMutex_leave(GateMutex_handle(&(object->gateUSBLibAccess)), key);

        if (driveReady == 0) {
            Log_print1(Diags_USER1, "USBMSCHFatFs: disk initialization: "
                                    "ready after %d tries", i);

            return (0x00); /* Disk OK */
        }
    }

    Log_print0(Diags_USER1, "USBMSCHFatFs: disk initialization: not ready");
    return (STA_NOINIT);
}
Esempio n. 2
0
//*****************************************************************************
//
// Calls the USB host stack tick function.
//
// This function is called periodically to allow the USB host stack to
// process any outstanding items.
//
// \return None.
//
//*****************************************************************************
void
ScopeUSBHostTick(void)
{
    tBoolean bRetcode;

    //
    // Call the stack to allow it to perform any processing needing done.
    //
    USBHCDMain();

    //
    // See if we need to do anything here.
    //
    if(g_eState == STATE_DEVICE_ENUM)
    {
        //
        // Take it easy on the Mass storage device if it is slow to
        // start up after connecting.
        //
        if(USBHMSCDriveReady(g_ulMSCInstance) != 0)
        {
            //
            // Wait about 500ms before attempting to check if the
            // device is ready again.
            //
            SysCtlDelay(SysCtlClockGet()/(3*2));
        }
        else
        {
            //
            // The device is available.  Try to open its root directory just
            // to make sure it is accessible.
            //
            bRetcode = FileIsDrivePresent(1);

            if(bRetcode)
            {
                //
                // The USB drive is accessible so dump a message and set the state
                // to indicate that the device is ready for use.
                //
                UARTprintf("Opened root directory - USB drive present.\n");
                RendererSetAlert("USB drive\ndetected.", 200);
                g_eState = STATE_DEVICE_READY;
            }
        }
    }
}
Esempio n. 3
0
void usbMscProcess() {
   USBHCDMain(USB_INSTANCE_FOR_USBDISK, g_ulMSCInstance);
   switch (g_usbMscState) {
   case USBMSC_NO_DEVICE:
      break;
   case USBMSC_DEVICE_ENUM:
      if (USBHMSCDriveReady(g_ulMSCInstance) == 0) {
         f_mount(FatFS_Drive_Index, &g_sFatFs);
         g_usbMscState = USBMSC_DEVICE_READY;
      }
      break;
   case USBMSC_DEVICE_READY:
      break;
   default:
      break;
   }
}
Esempio n. 4
0
//*****************************************************************************
//
// Read the application image from the file system and program it into flash.
//
// This function will attempt to open and read the firmware image file from
// the mass storage device.  If the file is found it will be programmed into
// flash.  The name of the file to be read is configured by the macro
// \b USB_UPDATE_FILENAME.  It will be programmed into flash starting at the
// address specified by APP_START_ADDRESS.
//
// \return Zero if successful or non-zero if the file cannot be read or
// programmed.
//
//*****************************************************************************
uint32_t
ReadAppAndProgram(void)
{
    uint_fast32_t ui32FlashEnd;
    uint_fast32_t ui32FileSize;
    uint_fast32_t ui32DataSize;
    uint_fast32_t ui32Remaining;
    uint_fast32_t ui32ProgAddr;
    uint_fast32_t ui32SavedRegs[2];
    volatile uint_fast32_t ui32Idx;
    uint_fast32_t ui32DriveTimeout;

    //
    // Initialize the drive timeout.
    //
    ui32DriveTimeout = USBMSC_DRIVE_RETRY;

    //
    // Check to see if the mass storage device is ready.  Some large drives
    // take a while to be ready, so retry until they are ready.
    //
    while(USBHMSCDriveReady(g_psMSCInstance))
    {
        //
        // Wait about 500ms before attempting to check if the
        // device is ready again.
        //
        SysCtlDelay(SysCtlClockGet()/(3*2));

        //
        // Decrement the retry count.
        //
        ui32DriveTimeout--;

        //
        // If the timeout is hit then return with a failure.
        //
        if(ui32DriveTimeout == 0)
        {
            return(1);
        }
    }

    //
    // Initialize the file system and return if error.
    //
    if(SimpleFsInit(g_ui8SectorBuf))
    {
        return(1);
    }

    //
    // Attempt to open the firmware file, retrieving the file/image size.
    // A file size of error means the file was not there, or there was an
    // error.
    //
    ui32FileSize = SimpleFsOpen(USB_UPDATE_FILENAME);
    if(ui32FileSize == 0)
    {
        return(1);
    }

    //
    // Get the size of flash.  This is the ending address of the flash.
    // If reserved space is configured, then the ending address is reduced
    // by the amount of the reserved block.
    //
    ui32FlashEnd = FLASH_SIZE;
#ifdef FLASH_RSVD_SPACE
    ui32FlashEnd -= FLASH_RSVD_SPACE;
#endif

    //
    // If flash code protection is not used, then change the ending address
    // to be the ending of the application image.  This will be the highest
    // flash page that will be erased and so only the necessary pages will
    // be erased.  If flash code protection is enabled, then all of the
    // application area pages will be erased.
    //
#ifndef FLASH_CODE_PROTECTION
    ui32FlashEnd = ui32FileSize + APP_START_ADDRESS;
#endif

    //
    // Check to make sure the file size is not too large to fit in the flash.
    // If it is too large, then return an error.
    //
    if((ui32FileSize + APP_START_ADDRESS) > ui32FlashEnd)
    {
        return(1);
    }

    //
    // Enter a loop to erase all the requested flash pages beginning at the
    // application start address (above the USB stick updater).
    //
    for(ui32Idx = APP_START_ADDRESS; ui32Idx < ui32FlashEnd; ui32Idx += 1024)
    {
        ROM_FlashErase(ui32Idx);
    }

    //
    // Enter a loop to read sectors from the application image file and
    // program into flash.  Start at the user app start address (above the USB
    // stick updater).
    //
    ui32ProgAddr = APP_START_ADDRESS;
    ui32Remaining = ui32FileSize;
    while(SimpleFsReadFileSector())
    {
        //
        // Compute how much data was read from this sector and adjust the
        // remaining amount.
        //
        ui32DataSize = ui32Remaining >= 512 ? 512 : ui32Remaining;
        ui32Remaining -= ui32DataSize;

        //
        // Special handling for the first block of the application.
        // This block contains as the first two location the application's
        // initial stack pointer and instruction pointer.  The USB updater
        // relied on the values in these locations to determine if a valid
        // application is present.  When there is a valid application the
        // updater runs the user application.  Otherwise the updater attempts
        // to load a new application.
        // In order to prevent a partially programmed imaged (due to some
        // error occurring while programming), the first two locations are
        // not programmed until all of the rest of the image has been
        // successfully loaded into the flash.  This way if there is some error,
        // the updater will detect that a user application is not present and
        // will not attempt to run it.
        //
        // For the first block, do not program the first two word locations
        // (8 bytes).  These two words will be programmed later, after
        // everything else.
        //
        if(ui32ProgAddr == APP_START_ADDRESS)
        {
            uint32_t *pui32Temp;

            pui32Temp = (uint32_t *)g_ui8SectorBuf;
            ui32SavedRegs[0] = pui32Temp[0];
            ui32SavedRegs[1] = pui32Temp[1];

            //
            // Call the function to program a block of flash.  Skip the first
            // two words (8 bytes) since these contain the initial SP and PC.
            //
            ROM_FlashProgram((uint32_t *)&g_ui8SectorBuf[8],
                             ui32ProgAddr + 8,
                             ((ui32DataSize - 8) + 3) & ~3);
        }

        //
        // All other blocks except the first block
        //
        else
        {
            //
            // Call the function to program a block of flash.  The length of the
            // block passed to the flash function must be divisible by 4.
            //
            ROM_FlashProgram((uint32_t *)g_ui8SectorBuf, ui32ProgAddr,
                             (ui32DataSize + 3) & ~3);
        }

        //
        // If there is more image to program, then update the programming
        // address.  Progress will continue to the next iteration of
        // the while loop.
        //
        if(ui32Remaining)
        {
            ui32ProgAddr += ui32DataSize;
        }

        //
        // Otherwise we are done programming so perform final steps.
        // Program the first two words of the image that were saved earlier,
        // and return a success indication.
        //
        else
        {
            ROM_FlashProgram((uint32_t *)ui32SavedRegs, APP_START_ADDRESS,
                              8);

            return(0);
        }
    }

    //
    // If we make it here, that means that an attempt to read a sector of
    // data from the device was not successful.  That means that the complete
    // user app has not been programmed into flash, so just return an error
    // indication.
    //
    return(1);
}
//*****************************************************************************
//
// The program main function.  It performs initialization, then runs a loop to
// process USB activities and operate the user interface.
//
//*****************************************************************************
int
main(void)
{
    uint32_t ui32DriveTimeout;

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

    //
    // 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 the uDMA controller and set up the control table base.
    // The uDMA controller is used by the USB library.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    ROM_uDMAEnable();
    ROM_uDMAControlBaseSet(g_psDMAControlTable);

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

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

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

    //
    // Initialize two offscreen displays and assign the palette.  These
    // buffers are used by the slide menu widget to allow animation effects.
    //
    GrOffScreen4BPPInit(&g_sOffscreenDisplayA, g_pui8OffscreenBufA, 96, 64);
    GrOffScreen4BPPPaletteSet(&g_sOffscreenDisplayA, g_pui32Palette, 0,
                              NUM_PALETTE_ENTRIES);
    GrOffScreen4BPPInit(&g_sOffscreenDisplayB, g_pui8OffscreenBufB, 96, 64);
    GrOffScreen4BPPPaletteSet(&g_sOffscreenDisplayB, g_pui32Palette, 0,
                              NUM_PALETTE_ENTRIES);

    //
    // Show an initial status screen
    //
    g_pcStatusLines[0] = "Waiting";
    g_pcStatusLines[1] = "for device";
    ShowStatusScreen(g_pcStatusLines, 2);

    //
    // Add the compile-time defined widgets to the widget tree.
    //
    WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sFileMenuWidget);

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

    //
    // Initialize the USB stack for host mode.
    //
    USBStackModeSet(0, eUSBModeHost, 0);

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

    //
    // Open an instance of the mass storage class driver.
    //
    g_psMSCInstance = USBHMSCDriveOpen(0, MSCCallback);

    //
    // Initialize the drive timeout.
    //
    ui32DriveTimeout = USBMSC_DRIVE_RETRY;

    //
    // 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 host operation.
    //
    USBHCDInit(0, g_pui8HCDPool, HCD_MEMORY_SIZE);

    //
    // Initialize the file system.
    //
    FileInit();

    //
    // Enter an infinite loop to run the user interface and process USB
    // events.
    //
    while(1)
    {
        uint32_t ui32LastTickCount = 0;

        //
        // Call the USB stack to keep it running.
        //
        USBHCDMain();

        //
        // Process any messages in the widget message queue.  This keeps the
        // display UI running.
        //
        WidgetMessageQueueProcess();

        //
        // Take action based on the application state.
        //
        switch(g_eState)
        {
            //
            // A device has enumerated.
            //
            case STATE_DEVICE_ENUM:
            {
                //
                // Check to see if the device is ready.  If not then stay
                // in this state and we will check it again on the next pass.
                //
                if(USBHMSCDriveReady(g_psMSCInstance) != 0)
                {
                    //
                    // Wait about 500ms before attempting to check if the
                    // device is ready again.
                    //
                    ROM_SysCtlDelay(ROM_SysCtlClockGet()/(3));

                    //
                    // Decrement the retry count.
                    //
                    ui32DriveTimeout--;

                    //
                    // If the timeout is hit then go to the
                    // STATE_TIMEOUT_DEVICE state.
                    //
                    if(ui32DriveTimeout == 0)
                    {
                        g_eState = STATE_TIMEOUT_DEVICE;
                    }

                    break;
                }

                //
                // Getting here means the device is ready.
                // Reset the CWD to the root directory.
                //
                g_pcCwdBuf[0] = '/';
                g_pcCwdBuf[1] = 0;

                //
                // Set the initial directory level to the root
                //
                g_ui32Level = 0;

                //
                // We need to reset the indexes of the root menu to 0, so that
                // it will start at the top of the file list, and reset the
                // slide menu widget to start with the root menu.
                //
                g_psFileMenus[g_ui32Level].ui32CenterIndex = 0;
                g_psFileMenus[g_ui32Level].ui32FocusIndex = 0;
                SlideMenuMenuSet(&g_sFileMenuWidget, &g_psFileMenus[g_ui32Level]);

                //
                // Initiate a directory change to the root.  This will
                // populate a menu structure representing the root directory.
                //
                if(ProcessDirChange("/", g_ui32Level))
                {
                    //
                    // If there were no errors reported, we are ready for
                    // MSC operation.
                    //
                    g_eState = STATE_DEVICE_READY;

                    //
                    // Set the Device Present flag.
                    //
                    g_ui32Flags = FLAGS_DEVICE_PRESENT;

                    //
                    // Request a repaint so the file menu will be shown
                    //
                    WidgetPaint(WIDGET_ROOT);
                }

                break;
            }

            //
            // If there is no device then just wait for one.
            //
            case STATE_NO_DEVICE:
            {
                if(g_ui32Flags == FLAGS_DEVICE_PRESENT)
                {
                    //
                    // Show waiting message on screen
                    //
                    g_pcStatusLines[0] = "Waiting";
                    g_pcStatusLines[1] = "for device";
                    ShowStatusScreen(g_pcStatusLines, 2);

                    //
                    // Clear the Device Present flag.
                    //
                    g_ui32Flags &= ~FLAGS_DEVICE_PRESENT;
                }
                break;
            }

            //
            // An unknown device was connected.
            //
            case STATE_UNKNOWN_DEVICE:
            {
                //
                // If this is a new device then change the status.
                //
                if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0)
                {
                    //
                    // Clear the screen and indicate that an unknown device
                    // is present.
                    //
                    g_pcStatusLines[0] = "Unknown";
                    g_pcStatusLines[1] = "device";
                    ShowStatusScreen(g_pcStatusLines, 2);
                }

                //
                // Set the Device Present flag.
                //
                g_ui32Flags = FLAGS_DEVICE_PRESENT;

                break;
            }

            //
            // The connected mass storage device is not reporting ready.
            //
            case STATE_TIMEOUT_DEVICE:
            {
                //
                // If this is the first time in this state then print a
                // message.
                //
                if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0)
                {
                    //
                    //
                    // Clear the screen and indicate that an unknown device
                    // is present.
                    //
                    g_pcStatusLines[0] = "Device";
                    g_pcStatusLines[1] = "Timeout";
                    ShowStatusScreen(g_pcStatusLines, 2);
                }

                //
                // Set the Device Present flag.
                //
                g_ui32Flags = FLAGS_DEVICE_PRESENT;

                break;
            }

            //
            // The device is ready and in use.
            //
            case STATE_DEVICE_READY:
            {
                //
                // Process occurrence of timer tick.  Check for user input
                // once each tick.
                //
                if(g_ui32SysTickCount != ui32LastTickCount)
                {
                    uint8_t ui8ButtonState;
                    uint8_t ui8ButtonChanged;

                    ui32LastTickCount = g_ui32SysTickCount;

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

                    //
                    // If select button or right button is pressed, then we
                    // are trying to descend into another directory
                    //
                    if(BUTTON_PRESSED(SELECT_BUTTON,
                                      ui8ButtonState, ui8ButtonChanged) ||
                       BUTTON_PRESSED(RIGHT_BUTTON,
                                      ui8ButtonState, ui8ButtonChanged))
                    {
                        uint32_t ui32NewLevel;
                        uint32_t ui32ItemIdx;
                        char *pcItemName;

                        //
                        // Get a pointer to the current menu for this CWD.
                        //
                        tSlideMenu *psMenu = &g_psFileMenus[g_ui32Level];

                        //
                        // Get the highlighted index in the current file list.
                        // This is the currently highlighted file or dir
                        // on the display.  Then get the name of the file at
                        // this index.
                        //
                        ui32ItemIdx = SlideMenuFocusItemGet(psMenu);
                        pcItemName = psMenu->psSlideMenuItems[ui32ItemIdx].pcText;

                        //
                        // Make sure we are not yet past the maximum tree
                        // depth.
                        //
                        if(g_ui32Level < MAX_SUBDIR_DEPTH)
                        {
                            //
                            // Potential new level is one greater than the
                            // current level.
                            //
                            ui32NewLevel = g_ui32Level + 1;

                            //
                            // Process the directory change to the new
                            // directory.  This function will populate a menu
                            // structure with the files and subdirs in the new
                            // directory.
                            //
                            if(ProcessDirChange(pcItemName, ui32NewLevel))
                            {
                                //
                                // If the change was successful, then update
                                // the level.
                                //
                                g_ui32Level = ui32NewLevel;

                                //
                                // Now that all the prep is done, send the
                                // KEY_RIGHT message to the widget and it will
                                // "slide" from the previous file list to the
                                // new file list of the CWD.
                                //
                                SendWidgetKeyMessage(WIDGET_MSG_KEY_RIGHT);

                            }
                        }
                    }

                    //
                    // If the UP button is pressed, just pass it to the widget
                    // which will handle scrolling the list of files.
                    //
                    if(BUTTON_PRESSED(UP_BUTTON, ui8ButtonState, ui8ButtonChanged))
                    {
                        SendWidgetKeyMessage(WIDGET_MSG_KEY_UP);
                    }

                    //
                    // If the DOWN button is pressed, just pass it to the widget
                    // which will handle scrolling the list of files.
                    //
                    if(BUTTON_PRESSED(DOWN_BUTTON, ui8ButtonState, ui8ButtonChanged))
                    {
                        SendWidgetKeyMessage(WIDGET_MSG_KEY_DOWN);
                    }

                    //
                    // If the LEFT button is pressed, then we are attempting
                    // to go up a level in the file system.
                    //
                    if(BUTTON_PRESSED(LEFT_BUTTON, ui8ButtonState, ui8ButtonChanged))
                    {
                        uint32_t ui32NewLevel;

                        //
                        // Make sure we are not already at the top of the
                        // directory tree (at root).
                        //
                        if(g_ui32Level)
                        {
                            //
                            // Potential new level is one less than the
                            // current level.
                            //
                            ui32NewLevel = g_ui32Level - 1;

                            //
                            // Process the directory change to the new
                            // directory.  This function will populate a menu
                            // structure with the files and subdirs in the new
                            // directory.
                            //
                            if(ProcessDirChange("..", ui32NewLevel))
                            {
                                //
                                // If the change was successful, then update
                                // the level.
                                //
                                g_ui32Level = ui32NewLevel;

                                //
                                // Now that all the prep is done, send the
                                // KEY_LEFT message to the widget and it will
                                // "slide" from the previous file list to the
                                // new file list of the CWD.
                                //
                                SendWidgetKeyMessage(WIDGET_MSG_KEY_LEFT);
                            }
                        }
                    }
                }
                break;
            }
            //
            // Something has caused a power fault.
            //
            case STATE_POWER_FAULT:
            {
                //
                // Clear the screen and show a power fault indication.
                //
                g_pcStatusLines[0] = "Power";
                g_pcStatusLines[1] = "fault";
                ShowStatusScreen(g_pcStatusLines, 2);
                break;
            }

            default:
            {
                break;
            }
        }
    }
}
Esempio n. 6
0
//*****************************************************************************
//
// This is called by the application main loop to perform regular processing.
// It keeps the USB host stack running and tracks the state of the attached
// device.
//
//*****************************************************************************
void
USBStickRun(void)
{
    //
    // Call the USB stack to keep it running.
    //
    USBHCDMain();

    //
    // Take action based on the application state.
    //
    switch(g_iState)
    {
        //
        // A device has enumerated.
        //
        case eSTATE_DEVICE_ENUM:
        {
            //
            // Check to see if the device is ready.  If not then stay
            // in this state and we will check it again on the next pass.
            //
            if(USBHMSCDriveReady(g_psMSCInstance) != 0)
            {
                //
                // Wait about 500ms before attempting to check if the
                // device is ready again.
                //
                MAP_SysCtlDelay(MAP_SysCtlClockGet()/3);
                break;
            }

            //
            // If there were no errors reported, we are ready for
            // MSC operation.
            //
            g_iState = eSTATE_DEVICE_READY;

            //
            // Set the Device Present flag.
            //
            g_ui32Flags = FLAGS_DEVICE_PRESENT;

            break;
        }

        //
        // If there is no device then just wait for one.
        //
        case eSTATE_NO_DEVICE:
        {
            if(g_ui32Flags == FLAGS_DEVICE_PRESENT)
            {
                //
                // Clear the Device Present flag.
                //
                g_ui32Flags &= ~(FLAGS_DEVICE_PRESENT | FLAGS_FILE_OPENED);
            }
            break;
        }

        //
        // An unknown device was connected.
        //
        case eSTATE_UNKNOWN_DEVICE:
        {
            //
            // If this is a new device then change the status.
            //
            if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0)
            {
                //
                // Unknown device is present
                //
            }

            //
            // Set the Device Present flag even though the unknown device
            // is not useful to us.
            //
            g_ui32Flags = FLAGS_DEVICE_PRESENT;
            break;
        }

        //
        // The device is ready and in use.
        //
        case eSTATE_DEVICE_READY:
        {
            break;
        }

        //
        // Something has caused a power fault.
        //
        case eSTATE_POWER_FAULT:
        {
            break;
        }

        //
        // Unexpected USB state.  Set back to default.
        //
        default:
        {
            g_iState = eSTATE_NO_DEVICE;
            g_ui32Flags &= ~(FLAGS_DEVICE_PRESENT | FLAGS_FILE_OPENED);
            break;
        }
    }
}
Esempio n. 7
0
//*****************************************************************************
//
// The program main function.  It performs initialization, then runs
// a command processing loop to read commands from the console.
//
//*****************************************************************************
int
main(void)
{
    uint32_t ui32DriveTimeout;
    uint32_t ui32SysClock;
    tContext sContext;

    //
    // Run from the PLL at 120 MHz.
    //
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_PLL |
                                       SYSCTL_CFG_VCO_480), 120000000);

    //
    // Configure the device pins.
    //
    PinoutSet();

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

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

    //
    // Draw the application frame.
    //
    FrameDraw(&sContext, "usb-host-msc");

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

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

    //
    // Initialize the touch screen driver.
    //
    TouchScreenInit(ui32SysClock);

    //
    // Set the touch screen event handler.
    //
    TouchScreenCallbackSet(WidgetPointerMessage);

    //
    // Add the compile-time defined widgets to the widget tree.
    //
    WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sBackground);

    //
    // Set some initial strings.
    //
    ListBoxTextAdd(&g_sDirList, "Waiting for device...");

    //
    // Issue the initial paint request to the widgets then immediately call
    // the widget manager to process the paint message.  This ensures that the
    // display is drawn as quickly as possible and saves the delay we would
    // otherwise experience if we processed the paint message after mounting
    // and reading the SD card.
    //
    WidgetPaint(WIDGET_ROOT);
    WidgetMessageQueueProcess();

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

    //
    // Initialize the USB stack for host mode.
    //
    USBStackModeSet(0, eUSBModeHost, 0);

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

    //
    // Open an instance of the mass storage class driver.
    //
    g_psMSCInstance = USBHMSCDriveOpen(0, MSCCallback);

    //
    // Initialize the drive timeout.
    //
    ui32DriveTimeout = USBMSC_DRIVE_RETRY;

    //
    // 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 host operation.
    //
    USBHCDInit(0, g_pHCDPool, HCD_MEMORY_SIZE);

    //
    // Initialize the file system.
    //
    FileInit();

    //
    // Enter an (almost) infinite loop for reading and processing commands from
    // the user.
    //
    while(1)
    {
        //
        // Call the USB stack to keep it running.
        //
        USBHCDMain();

        //
        // Process any messages in the widget message queue.  This keeps the
        // display UI running.
        //
        WidgetMessageQueueProcess();

        switch(g_eState)
        {
            case STATE_DEVICE_ENUM:
            {
                //
                // Take it easy on the Mass storage device if it is slow to
                // start up after connecting.
                //
                if(USBHMSCDriveReady(g_psMSCInstance) != 0)
                {
                    //
                    // Wait about 500ms before attempting to check if the
                    // device is ready again.
                    //
                    ROM_SysCtlDelay(ui32SysClock / (3 * 2));

                    //
                    // Decrement the retry count.
                    //
                    ui32DriveTimeout--;

                    //
                    // If the timeout is hit then go to the
                    // STATE_TIMEOUT_DEVICE state.
                    //
                    if(ui32DriveTimeout == 0)
                    {
                        g_eState = STATE_TIMEOUT_DEVICE;
                    }
                    break;
                }

                //
                // Getting here means the device is ready.
                // Reset the CWD to the root directory.
                //
                g_cCwdBuf[0] = '/';
                g_cCwdBuf[1] = 0;

                //
                // Set the initial directory level to the root
                //
                g_ui32Level = 0;

                //
                // Fill the list box with the files and directories found.
                //
                if(!PopulateFileListBox(true))
                {
                    //
                    // If there were no errors reported, we are ready for
                    // MSC operation.
                    //
                    g_eState = STATE_DEVICE_READY;
                }

                //
                // Set the Device Present flag.
                //
                g_ui32Flags = FLAGS_DEVICE_PRESENT;
                break;
            }

            //
            // If there is no device then just wait for one.
            //
            case STATE_NO_DEVICE:
            {
                if(g_ui32Flags == FLAGS_DEVICE_PRESENT)
                {
                    //
                    // Empty the list box on the display.
                    //
                    ListBoxClear(&g_sDirList);
                    ListBoxTextAdd(&g_sDirList, "Waiting for device...");
                    WidgetPaint((tWidget *)&g_sDirList);

                    //
                    // Clear the Device Present flag.
                    //
                    g_ui32Flags &= ~FLAGS_DEVICE_PRESENT;
                }
                break;
            }

            //
            // An unknown device was connected.
            //
            case STATE_UNKNOWN_DEVICE:
            {
                //
                // If this is a new device then change the status.
                //
                if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0)
                {
                    //
                    // Clear the screen and indicate that an unknown device
                    // is present.
                    //
                    ListBoxClear(&g_sDirList);
                    ListBoxTextAdd(&g_sDirList, "Unknown device.");
                    WidgetPaint((tWidget *)&g_sDirList);
                }
                //
                // Set the Device Present flag.
                //
                g_ui32Flags = FLAGS_DEVICE_PRESENT;
                break;
            }

            //
            // The connected mass storage device is not reporting ready.
            //
            case STATE_TIMEOUT_DEVICE:
            {
                //
                // If this is the first time in this state then print a
                // message.
                //
                if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0)
                {
                    //
                    // Clear the screen and indicate that an unknown device
                    // is present.
                    //
                    ListBoxClear(&g_sDirList);
                    ListBoxTextAdd(&g_sDirList, "Device Timeout.");
                    WidgetPaint((tWidget *)&g_sDirList);
                }

                //
                // Set the Device Present flag.
                //
                g_ui32Flags = FLAGS_DEVICE_PRESENT;
                break;
            }

            //
            // Something has caused a power fault.
            //
            case STATE_POWER_FAULT:
            {
                break;
            }
            default:
            {
                break;
            }
        }
    }
}