Пример #1
0
//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{
    FRESULT FileResult;
    tRectangle sRect;

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

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

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

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

    //
    // Set the USB pins to be controlled by the USB controller.
    //
    GPIOPinTypeUSBDigital(GPIO_PORTH_BASE, GPIO_PIN_3 | GPIO_PIN_4);

    //
    // The LM3S3748 board uses a USB mux that must be switched to use the
    // host connecter and not the device connecter.
    //
    GPIOPinTypeGPIOOutput(USB_MUX_GPIO_BASE, USB_MUX_GPIO_PIN);
    GPIOPinWrite(USB_MUX_GPIO_BASE, USB_MUX_GPIO_PIN, USB_MUX_SEL_HOST);

    //
    // Turn on USB Phy clock.
    //
    SysCtlUSBPLLEnable();

    //
    // Set the system tick to fire 100 times per second.
    //
    SysTickPeriodSet(SysCtlClockGet()/100);
    SysTickIntEnable();
    SysTickEnable();

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

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

    //
    // Turn on the backlight.
    //
    Formike128x128x16BacklightOn();

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

    //
    // 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 = SPLASH_HEIGHT - 1;
    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_sFontFixed6x8);

    GrStringDrawCentered(&g_sContext, "usb_host_msc", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 7, 0);

    //
    // Set the color to white and select the 20 point font.
    //
    GrContextForegroundSet(&g_sContext, FILE_COLOR);

    GrStringDraw(&g_sContext, "No Device",
        100, 0, TOP_HEIGHT, 1);

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

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

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

    //
    // Initialize the host controller.
    //
    USBHCDInit(0, g_pHCDPool, HCD_MEMORY_SIZE);

    //
    // Initialize the pushbuttons.
    //
    ButtonsInit();

    //
    // Set the auto repeat rates for the up and down buttons.
    //
    ButtonsSetAutoRepeat(UP_BUTTON, 50, 15);
    ButtonsSetAutoRepeat(DOWN_BUTTON, 50, 15);

    //
    // Current directory is "/"
    //
    g_DirData.szPWD[0] = '/';
    g_DirData.szPWD[1] = 0;

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

    while(1)
    {
        USBHCDMain();

        switch(g_eState)
        {
            case STATE_DEVICE_ENUM:
            {
                //
                // Reset the root directory.
                //
                g_DirData.szPWD[0] = '/';
                g_DirData.szPWD[1] = 0;

                //
                // Open the root directory.
                //
                FileResult = f_opendir(&g_DirData.DirState, g_DirData.szPWD);

                //
                // Wait for the root directory to open successfully.  The MSC
                // device can enumerate before being read to be accessed, so
                // there may be some delay before it is ready.
                //
                if(FileResult == FR_OK)
                {
                    //
                    // Reset the directory state.
                    //
                    g_DirData.ulIndex = 0;
                    g_DirData.ulSelectIndex = 0;
                    g_DirData.ulValidValues = 0;
                    g_eState = STATE_DEVICE_READY;

                    //
                    // Ignore buttons pressed before being ready.
                    //
                    g_ulButtons = 0;

                    //
                    // Update the screen if the root dir opened successfully.
                    //
                    DirUpdate();
                    UpdateWindow();
                }
                else if(FileResult != FR_NOT_READY)
                {
                    // some kind of error
                }

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

                break;
            }

            //
            // This is the running state where buttons are checked and the
            // screen is updated.
            //
            case STATE_DEVICE_READY:
            {
                //
                // Down button pressed and released.
                //
                if(g_ulButtons & BUTTON_DOWN_CLICK)
                {
                    //
                    // Update the screen and directory state.
                    //
                    MoveDown();

                    //
                    // Clear the button pressed event.
                    //
                    g_ulButtons &= ~BUTTON_DOWN_CLICK;
                }

                //
                // Up button pressed and released.
                //
                if(g_ulButtons & BUTTON_UP_CLICK)
                {
                    //
                    // Update the screen and directory state.
                    //
                    MoveUp();

                    //
                    // Clear the button pressed event.
                    //
                    g_ulButtons &= ~BUTTON_UP_CLICK;
                }

                //
                // Select button pressed and released.
                //
                if(g_ulButtons & BUTTON_SELECT_CLICK)
                {
                    //
                    // If this was a directory go into it.
                    //
                    SelectDir();

                    //
                    // Clear the button pressed event.
                    //
                    g_ulButtons &= ~BUTTON_SELECT_CLICK;
                }
                break;
            }

            //
            // If there is no device then just wait for one.
            //
            case STATE_NO_DEVICE:
            {
                if(g_ulFlags == FLAGS_DEVICE_PRESENT)
                {
                    //
                    // Clear the screen and indicate that there is no longer
                    // a device present.
                    //
                    ClearTextBox();
                    GrStringDraw(&g_sContext, "No Device",
                         100, 0, TOP_HEIGHT, 1);

                    //
                    // Clear the Device Present flag.
                    //
                    g_ulFlags &= ~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_ulFlags & FLAGS_DEVICE_PRESENT) == 0)
                {
                    //
                    // Clear the screen and indicate that an unknown device is
                    // present.
                    //
                    ClearTextBox();
                    GrStringDraw(&g_sContext, "Unknown Device",
                         100, 0, TOP_HEIGHT, 1);
                }

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

                break;
            }

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

            default:
            {
                break;
            }
        }
    }
}
//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{
    tRectangle sRect;

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

    //
    // Enable the USB mux GPIO.
    //
    SysCtlPeripheralEnable(USB_MUX_GPIO_PERIPH);

    //
    // The LM3S3748 board uses a USB mux that must be switched to use the
    // host connector and not the device connecter.
    //
    GPIOPinTypeGPIOOutput(USB_MUX_GPIO_BASE, USB_MUX_GPIO_PIN);
    GPIOPinWrite(USB_MUX_GPIO_BASE, USB_MUX_GPIO_PIN, USB_MUX_SEL_DEVICE);

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

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

    //
    // Initialize the pushbuttons.
    //
    ButtonsInit();
    ButtonsSetAutoRepeat((LEFT_BUTTON | RIGHT_BUTTON | UP_BUTTON |
                          DOWN_BUTTON), 0, 2);

    //
    // Set the system tick to fire 100 times per second.
    //
    SysTickPeriodSet(SysCtlClockGet() / SYSTICKS_PER_SECOND);
    SysTickIntEnable();
    SysTickEnable();

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

    //
    // Turn on the backlight.
    //
    Formike128x128x16BacklightOn();

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

    //
    // 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, "boot_demo_usb", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 7, 0);

    //
    // Initialize each of the device instances that will form our composite
    // USB device.
    //
    g_sCompDevice.psDevices[0].pvInstance =
        USBDHIDMouseCompositeInit(0, (tUSBDHIDMouseDevice *)&g_sMouseDevice);
    g_sCompDevice.psDevices[1].pvInstance =
        USBDDFUCompositeInit(0, (tUSBDDFUDevice *)&g_sDFUDevice);

    //
    // Pass the USB library our device information, initialize the USB
    // controller and connect the device to the bus.
    //
    USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_BUFFER_SIZE,
                      g_pcDescriptorBuffer);

    //
    // Drop into the main loop.
    //
    while(!g_bUpdateSignalled)
    {
        //
        // Fill all but the top 15 rows of the screen with black to erase the
        // previous status.
        //
        sRect.sXMin = 0;
        sRect.sYMin = 15;
        sRect.sXMax = GrContextDpyWidthGet(&g_sContext) - 1;
        sRect.sYMax = GrContextDpyHeightGet(&g_sContext) - 1;
        GrContextForegroundSet(&g_sContext, ClrBlack);
        GrRectFill(&g_sContext, &sRect);

        //
        // Tell the user what we are doing.
        //
        GrContextForegroundSet(&g_sContext, ClrWhite);
        GrStringDrawCentered(&g_sContext, "Waiting for host...", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 24, true);
        //
        // Wait for USB configuration to complete.
        //
        while(!g_bConnected)
        {
        }

        //
        // Update the status.
        //
        GrStringDrawCentered(&g_sContext, " Host connected... ", -1,
                             GrContextDpyWidthGet(&g_sContext) / 2, 24, true);

        //
        // Now keep processing the mouse as long as the host is connected.
        //
        while(g_bConnected && !g_bUpdateSignalled)
        {
            //
            // If it is time to check the button state then do so.
            //
            if(g_ulCommands & BUTTON_TICK_EVENT)
            {
                g_ulCommands &= ~BUTTON_TICK_EVENT;
                ButtonHandler();
            }
        }

        //
        // If we drop out of the previous loop, the host has disconnected so
        // go back and wait for a new connection.
        //
    }

    //
    // If we drop out of the main loop, the host has signalled that it wants us
    // to switch into DFU mode in preparation for a firmware upgrade.  First,
    // let the user know what's going on.
    //
    GrStringDrawCentered(&g_sContext, "Entering DFU mode...", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 24, true);

    //
    // Call the USB DFU device class to tidy things up and transfer control to
    // the boot loader for us.  Note that this function never returns.
    //
    USBDDFUUpdateBegin();
}