//***************************************************************************** // // Initialize the offscreen buffers and the menu structure. This should be // called before using the application menus. // The parameter is a function pointer to a callback function whenever the // menu widget activates or deactivates a child widget. // //***************************************************************************** void MenuInit(void (*pfnActive)(tWidget *, tSlideMenuItem *, bool)) { uint32_t ui32Idx; // // Initialize two offscreen displays and assign the palette. These // buffers are used by the slide menu widget and other parts of the // application to allow for 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); // // Initialize each of the text fields with a "blank" indication. // for(ui32Idx = 0; ui32Idx < NUM_LOG_ITEMS; ui32Idx++) { usnprintf(g_pcTextFields[ui32Idx], TEXT_FIELD_LENGTH, "----"); } // // Set the slide menu widget callback function. // SlideMenuActiveCallbackSet(&g_sMenuWidget, pfnActive); }
//***************************************************************************** // // 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; } } } }
//***************************************************************************** // // Compute and display a sine wave. // //***************************************************************************** int main(void) { uint_fast16_t ui16ItemCount = 0; uint32_t ui32LastTickCount = 0; // // 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 clocking to run directly at 50 MHz. // ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); // // Configure SysTick to generate a periodic time tick interrupt. // ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND); ROM_SysTickEnable(); ROM_SysTickIntEnable(); // // Initialize the display driver. // CFAL96x64x16Init(); // // Initialize an offscreen display and assign the palette. This offscreen // buffer is needed by the strip chart widget. // GrOffScreen4BPPInit(&g_sOffscreenDisplay, g_pui8OffscreenBuf, 96, 64); GrOffScreen4BPPPaletteSet(&g_sOffscreenDisplay, g_pui32Palette, 0, NUM_PALETTE_ENTRIES); // // Set the data series buffer pointer to point at the storage where the // series data points will be stored. // g_sSeries.pvData = g_i8SeriesData; // // Add the series to the strip chart // StripChartSeriesAdd(&g_sStripChart, &g_sSeries); // // Add the strip chart to the widget tree. // WidgetAdd(WIDGET_ROOT, &g_sStripChart.sBase); // // Enter a loop to continuously calculate a sine wave. // while(1) { float fElapsedTime; float fRadians; float fSine; // // Wait for the next timer tick. // while(ui32LastTickCount == g_ui32TickCount) { } ui32LastTickCount = g_ui32TickCount; // // Preparing to add a new data point to the strip chart ... // If the number count of items in the strip chart has reached the // maximum value, then the data points need to "slide down" in the // buffer so new data can be added at the end. // if(ui16ItemCount == SERIES_LENGTH) { memmove(&g_i8SeriesData[0], &g_i8SeriesData[1], SERIES_LENGTH - 1); } // // Otherwise, the series data buffer is less than full so just // increment the count of data points. // else { // // Increment the number of items that have been added to the strip // chart series data buffer. // ui16ItemCount++; // // Since the count of data items has changed, it must be updated in // the data series. // g_sSeries.ui16NumItems = ui16ItemCount; } // // Compute the elapsed time in decimal seconds, in floating point // format. // fElapsedTime = (float)g_ui32TickCount * FSECONDS_PER_TICK; // // Convert the time to radians. // fRadians = fElapsedTime * 2.0 * M_PI; // // Adjust the period of the wave. This will give us a wave period // of 4 seconds, or 0.25 Hz. This number was chosen arbitrarily to // provide a nice looking wave on the display. // fRadians /= 4.0; // // Compute the sine. Multiply by 0.5 to reduce the amplitude. // fSine = sinf(fRadians) * 0.5; // // Finally, save the sine value into the last location in the series // data point buffer. Convert the sine amplitude to display pixels. // (Amplitude 1 = 32 pixels) // g_i8SeriesData[ui16ItemCount - 1] = (int8_t)(fSine * 32.0); // // Now that a new data point has been added to the series, advance // the strip chart. // StripChartAdvance(&g_sStripChart, 1); // // Request a repaint and run the widget processing queue. // WidgetPaint(WIDGET_ROOT); WidgetMessageQueueProcess(); } }