//***************************************************************************** // // Initialize the application interface. // //***************************************************************************** void UIInit(uint32_t ui32SysClock) { // // Initialize the display driver. // Kentec320x240x16_SSD2119Init(ui32SysClock); // // Initialize the graphics context. // GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119); // // Draw the application frame. // FrameDraw(&g_sContext, "usb-host-keyboard"); // // Set the font for the application. // GrContextFontSet(&g_sContext, g_psFontFixed6x8); // // Calculate the number of characters that will fit on a line. // Make sure to leave a small border for the text box. // g_ui32CharsPerLine = (GrContextDpyWidthGet(&g_sContext) - 16) / GrFontMaxWidthGet(g_psFontFixed6x8); // // 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_ui32LinesPerScreen = (GrContextDpyHeightGet(&g_sContext) - (2*(DISPLAY_BANNER_HEIGHT + 1)) - BUTTON_HEIGHT) / GrFontHeightGet(g_psFontFixed6x8); // // Set up the text scrolling variables. // g_ui32CurrentLine = 0; g_ui32EntryLine = 0; // // Draw the initial prompt on the screen. // DrawPrompt(); // // Initial update of the screen. // UIUpdateStatus(); }
//***************************************************************************** // // Draws the prompt for each new line. // //***************************************************************************** static void DrawPrompt(void) { int32_t i32Idx; g_ppcLines[g_ui32CurrentLine][0] = '>'; for(i32Idx = 1; i32Idx < MAX_COLUMNS - 1; i32Idx++) { g_ppcLines[g_ui32CurrentLine][i32Idx] = ' '; } g_ppcLines[g_ui32CurrentLine][i32Idx] = 0; GrStringDraw(&g_sContext, g_ppcLines[g_ui32CurrentLine], MAX_COLUMNS, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32EntryLine * GrFontHeightGet(g_psFontFixed6x8)), true); g_ui32Column = 2; }
//***************************************************************************** // // 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; } } } }
//***************************************************************************** // // This function prints the character out the UART and into the text area of // the screen. // // \param ucChar is the character to print out. // // This function handles all of the detail of printing a character to both the // UART and to the text area of the screen on the evaluation board. The text // area of the screen will be cleared any time the text goes beyond the end // of the text area. // // \return None. // //***************************************************************************** void PrintChar(const char ucChar) { tRectangle sRect; // // If both the line and column have gone to zero then clear the screen. // if((g_ulLine == 0) && (g_ulColumn == 0)) { // // Form the rectangle that makes up the text box. // sRect.sXMin = 0; sRect.sYMin = (2 * DISPLAY_BANNER_HEIGHT) + DISPLAY_TEXT_BORDER; sRect.sXMax = GrContextDpyWidthGet(&g_sContext) - DISPLAY_TEXT_BORDER; sRect.sYMax = GrContextDpyHeightGet(&g_sContext) - DISPLAY_BANNER_HEIGHT - DISPLAY_TEXT_BORDER; // // Change the foreground color to black and draw black rectangle to // clear the screen. // GrContextForegroundSet(&g_sContext, DISPLAY_TEXT_BG); GrRectFill(&g_sContext, &sRect); // // Reset the foreground color to the text color. // GrContextForegroundSet(&g_sContext, DISPLAY_TEXT_FG); } // // Send the character to the UART. // UARTprintf("%c", ucChar); // // Allow new lines to cause the column to go back to zero. // if(ucChar != '\n') { // // Did we get a backspace character? // if(ucChar != ASCII_BACKSPACE) { // // This is not a backspace so print the character to the screen. // GrStringDraw(&g_sContext, &ucChar, 1, GrFontMaxWidthGet(g_pFontFixed6x8) * g_ulColumn, (2 * DISPLAY_BANNER_HEIGHT) + DISPLAY_TEXT_BORDER + (g_ulLine * GrFontHeightGet(g_pFontFixed6x8)), 0); } else { // // We got a backspace. If we are at the top left of the screen, // return since we don't need to do anything. // if(g_ulColumn || g_ulLine) { // // Adjust the cursor position to erase the last character. // if(g_ulColumn) { g_ulColumn--; } else { g_ulColumn = g_ulCharsPerLine; g_ulLine--; } // // Print a space at this position then return without fixing up // the cursor again. // GrStringDraw(&g_sContext, " ", 1, GrFontMaxWidthGet(g_pFontFixed6x8) * g_ulColumn, (2 * DISPLAY_BANNER_HEIGHT) + DISPLAY_TEXT_BORDER + (g_ulLine * GrFontHeightGet(g_pFontFixed6x8)), true); } return; } } else { // // This will allow the code below to properly handle the new line. // g_ulColumn = g_ulCharsPerLine; } // // Update the text row and column that the next character will use. // if(g_ulColumn < g_ulCharsPerLine) { // // No line wrap yet so move one column over. // g_ulColumn++; } else { // // Line wrapped so go back to the first column and update the line. // g_ulColumn = 0; g_ulLine++; // // The line has gone past the end so go back to the first line. // if(g_ulLine >= g_ulLinesPerScreen) { g_ulLine = 0; } } }
//***************************************************************************** // //! Paints the clock set widget on the display. //! //! \param psWidget is a pointer to the clock setting widget to be drawn. //! //! This function draws the date and time fields of the clock setting widget //! onto the display. One of the fields can be highlighted. This is //! called in response to a \b WIDGET_MSG_PAINT message. //! //! \return None. // //***************************************************************************** static void ClockSetPaint(tWidget *psWidget) { tClockSetWidget *psClockWidget; tContext sContext; tRectangle sRect, sRectSel; struct tm *psTime; char pcBuf[8]; int32_t i32X, i32Y, i32Width, i32Height; uint32_t ui32Idx, ui32FontHeight, ui32FontWidth, ui32SelWidth; // // Check the arguments. // ASSERT(psWidget); ASSERT(psWidget->psDisplay); // // Convert the generic widget pointer into a clock set widget pointer. // psClockWidget = (tClockSetWidget *)psWidget; ASSERT(psClockWidget->psTime); // // Get pointer to the time structure // psTime = psClockWidget->psTime; // // Initialize a drawing context. // GrContextInit(&sContext, psWidget->psDisplay); // // Initialize the clipping region based on the extents of this widget. // GrContextClipRegionSet(&sContext, &(psWidget->sPosition)); // // Set the font for the context, and get font height and width - they // are used a lot later. // GrContextFontSet(&sContext, psClockWidget->psFont); ui32FontHeight = GrFontHeightGet(psClockWidget->psFont); ui32FontWidth = GrFontMaxWidthGet(psClockWidget->psFont); // // Fill the widget with the background color. // GrContextForegroundSet(&sContext, psClockWidget->ui32BackgroundColor); GrRectFill(&sContext, &sContext.sClipRegion); // // Draw a border around the widget // GrContextForegroundSet(&sContext, psClockWidget->ui32ForegroundColor); GrContextBackgroundSet(&sContext, psClockWidget->ui32BackgroundColor); GrRectDraw(&sContext, &sContext.sClipRegion); // // Compute a rectangle for the screen title. Put it at the top of // the widget display, and sized to be the height of the font, plus // a few pixels of space. // sRect.i16XMin = sContext.sClipRegion.i16XMin; sRect.i16XMax = sContext.sClipRegion.i16XMax; sRect.i16YMin = sContext.sClipRegion.i16YMin; sRect.i16YMax = ui32FontHeight * 2; GrRectDraw(&sContext, &sRect); // // Print a title for the widget // GrContextFontSet(&sContext, psClockWidget->psFont); GrStringDrawCentered(&sContext, "CLOCK SET", -1, (1 + sRect.i16XMax - sRect.i16XMin) / 2, (1 + sRect.i16YMax - sRect.i16YMin) / 2, 1); // // Reset the rectangle to cover the non-title area of the display // sRect.i16YMin = sRect.i16YMax + 1; sRect.i16YMax = sContext.sClipRegion.i16YMax; // // Compute the width and height of the area remaining for showing the // clock fields. // i32Width = 1 + (sRect.i16XMax - sRect.i16XMin); i32Height = 1 + (sRect.i16YMax - sRect.i16YMin); // // Compute the X and Y starting point for the row that will show the // date. // i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 10)) / 2; i32Y = sRect.i16YMin + ((i32Height * 1) / 6) - (ui32FontHeight / 2); // // Draw the date field separators on the date row. // GrStringDraw(&sContext, "/", -1, i32X + (ui32FontWidth * 4), i32Y, 0); GrStringDraw(&sContext, "/", -1, i32X + (ui32FontWidth * 7), i32Y, 0); // // Compute the X and Y starting point for the row that will show the // time. // i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 5)) / 2; i32Y = sRect.i16YMin + ((i32Height * 3) / 6) - (ui32FontHeight / 2); // // Draw the time field separators on the time row. // GrStringDraw(&sContext, ":", -1, i32X + (ui32FontWidth * 2), i32Y, 0); // // Process each of the fields to be shown on the widget // for(ui32Idx = 0; ui32Idx < NUM_FIELDS; ui32Idx++) { // // Compute the X and Y for the text for each field, and print the // text into a buffer. // switch(ui32Idx) { // // Year // case FIELD_YEAR: { usnprintf(pcBuf, sizeof(pcBuf), "%4u", psTime->tm_year+1900); i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 10)) / 2; i32Y = sRect.i16YMin + ((i32Height * 1) / 6) - (ui32FontHeight / 2); ui32SelWidth = 4; break; } // // Month // case FIELD_MONTH: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_mon + 1); i32X += ui32FontWidth * 5; ui32SelWidth = 2; break; } // // Day // case FIELD_DAY: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_mday); i32X += ui32FontWidth * 3; ui32SelWidth = 2; break; } // // Hour // case FIELD_HOUR: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_hour); i32X = sRect.i16XMin + (i32Width - (ui32FontWidth * 5)) / 2; i32Y = sRect.i16YMin + ((i32Height * 3) / 6) - (ui32FontHeight / 2); ui32SelWidth = 2; break; } // // Minute // case FIELD_MINUTE: { usnprintf(pcBuf, sizeof(pcBuf), "%02u", psTime->tm_min); i32X += ui32FontWidth * 3; ui32SelWidth = 2; break; } // // OK // case FIELD_OK: { usnprintf(pcBuf, sizeof(pcBuf), "OK"); i32X = (i32Width - (ui32FontWidth * 9)) / 2; i32X += sRect.i16XMin; i32Y = ((i32Height * 5) / 6) - (ui32FontHeight / 2); i32Y += sRect.i16YMin; ui32SelWidth = 2; break; } // // CANCEL (default case is purely to keep the compiler from // issuing a warning that ui32SelWidth may be used ininitialized). // case FIELD_CANCEL: default: { usnprintf(pcBuf, sizeof(pcBuf), "CANCEL"); i32X += ui32FontWidth * 3; ui32SelWidth = 6; break; } } // // If the current field index is the highlighted field, then this // text field will be drawn with highlighting. // if(ui32Idx == psClockWidget->ui32Highlight) { // // Compute a rectangle for the highlight area. // sRectSel.i16XMin = i32X; sRectSel.i16XMax = (ui32SelWidth * ui32FontWidth) + i32X; sRectSel.i16YMin = i32Y - 2; sRectSel.i16YMax = ui32FontHeight + i32Y + 2; // // Set the foreground color to the text color, and then fill the // highlight rectangle. The text field will be highlighted by // inverting the normal colors. // Then draw the highlighting rectangle. // GrContextForegroundSet(&sContext, psClockWidget->ui32ForegroundColor); GrRectFill(&sContext, &sRectSel); // // Change the foreground color to the normal background color. // This will be used for drawing the text for the highlighted // field, which has the colors inverted (FG <--> BG) // GrContextForegroundSet(&sContext, psClockWidget->ui32BackgroundColor); } else { // // This text field is not highlighted so just set the normal // foreground color. // GrContextForegroundSet(&sContext, psClockWidget->ui32ForegroundColor); } // // Print the text from the buffer to the display at the computed // location. // GrStringDraw(&sContext, pcBuf, -1, i32X, i32Y, 0); } }
//***************************************************************************** // // 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 peripherals used by this example. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // // Configure the relevant pins such that UART0 owns them. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Open UART0 for debug output. // UARTStdioInit(0); // // 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 connector. // GPIOPinTypeGPIOOutput(USB_MUX_GPIO_BASE, USB_MUX_GPIO_PIN); GPIOPinWrite(USB_MUX_GPIO_BASE, USB_MUX_GPIO_PIN, USB_MUX_SEL_HOST); // // Configure the power pins for host controller. // GPIOPinTypeUSBDigital(GPIO_PORTH_BASE, GPIO_PIN_3 | GPIO_PIN_4); // // 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 = 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); // // Put the application name in the middle of the banner. // GrContextFontSet(&g_sContext, g_pFontFixed6x8); GrStringDrawCentered(&g_sContext, "usb_host_keyboard", -1, GrContextDpyWidthGet(&g_sContext) / 2, 7, 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) - (2*(DISPLAY_BANNER_HEIGHT + 1)))/ GrFontHeightGet(g_pFontFixed6x8); // // Register the host class drivers. // USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ulNumHostClassDrivers); // // Open and instance of the keyboard class driver. // UARTprintf("Host Keyboard Application\n"); // // 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); // // Initialize the host controller stack. // USBHCDInit(0, g_pHCDPool, HCD_MEMORY_SIZE); // // Call the main loop for the Host controller driver. // USBHCDMain(); // // Initial update of the screen. // UpdateStatus(); // // The main loop for the application. // while(1) { 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); // // Update the screen now that the keyboard has been // initialized. // UpdateStatus(); 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; } } // // Periodic call the main loop for the Host controller driver. // USBHCDMain(); } }
//***************************************************************************** // // This function prints the character out the UART and into the text area of // the screen. // // \param ucChar is the character to print out. // // This function handles all of the detail of printing a character to both the // UART and to the text area of the screen on the evaluation board. The text // area of the screen will be cleared any time the text goes beyond the end // of the text area. // // \return None. // //***************************************************************************** void PrintChar(const char ucChar) { tRectangle sRect; // // If both the line and column have gone to zero then clear the screen. // if((g_ulLine == 0) && (g_ulColumn == 0)) { // // Form the rectangle that makes up the text box. // sRect.sXMin = 0; sRect.sYMin = DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER; sRect.sXMax = GrContextDpyWidthGet(&g_sContext) - DISPLAY_TEXT_BORDER; sRect.sYMax = GrContextDpyHeightGet(&g_sContext) - DISPLAY_BANNER_HEIGHT - DISPLAY_TEXT_BORDER; // // Change the foreground color to black and draw black rectangle to // clear the screen. // GrContextForegroundSet(&g_sContext, DISPLAY_TEXT_BG); GrRectFill(&g_sContext, &sRect); // // Reset the foreground color to the text color. // GrContextForegroundSet(&g_sContext, DISPLAY_TEXT_FG); } // // Send the character to the UART. // UARTprintf("%c", ucChar); // // Allow new lines to cause the column to go back to zero. // if(ucChar != '\n') { // // Print the character to the screen. // GrStringDraw(&g_sContext, &ucChar, 1, GrFontMaxWidthGet(g_pFontFixed6x8) * g_ulColumn, DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ulLine * GrFontHeightGet(g_pFontFixed6x8)), 0); } else { // // This will allow the code below to properly handle the new line. // g_ulColumn = g_ulCharsPerLine; } // // Update the text row and column that the next character will use. // if(g_ulColumn < g_ulCharsPerLine) { // // No line wrap yet so move one column over. // g_ulColumn++; } else { // // Line wrapped so go back to the first column and update the line. // g_ulColumn = 0; g_ulLine++; // // The line has gone past the end so go back to the first line. // if(g_ulLine >= g_ulLinesPerScreen) { g_ulLine = 0; } } }
//***************************************************************************** // // This is the main loop that runs the application. // //***************************************************************************** int main(void) { tRectangle sRect; unsigned int i; unsigned char *src, *dest; // //configures arm interrupt controller to generate raster interrupt // SetupIntc(); // //Configures raster to display image // SetUpLCD(); /* configuring the base ceiling */ RasterDMAFBConfig(SOC_LCDC_0_REGS, (unsigned int)(g_pucBuffer+PALETTE_OFFSET), (unsigned int)(g_pucBuffer+PALETTE_OFFSET) + sizeof(g_pucBuffer) - 2 - PALETTE_OFFSET, 0); RasterDMAFBConfig(SOC_LCDC_0_REGS, (unsigned int)(g_pucBuffer+PALETTE_OFFSET), (unsigned int)(g_pucBuffer+PALETTE_OFFSET) + sizeof(g_pucBuffer) - 2 - PALETTE_OFFSET, 1); // Copy palette info into buffer src = (unsigned char *) palette_32b; dest = (unsigned char *) (g_pucBuffer+PALETTE_OFFSET); for( i = 4; i < (PALETTE_SIZE+4); i++) { *dest++ = *src++; } GrOffScreen16BPPInit(&g_sSHARP480x272x16Display, g_pucBuffer, LCD_WIDTH, LCD_HEIGHT); GrContextInit(&g_sContext, &g_sSHARP480x272x16Display); /* enable End of frame interrupt */ RasterEndOfFrameIntEnable(SOC_LCDC_0_REGS); /* enable raster */ RasterEnable(SOC_LCDC_0_REGS); ConfigRasterDisplayEnable(); // // 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 = DISPLAY_BANNER_HEIGHT; // // Set the banner background. // 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); // // Put the application name in the middle of the banner. // GrContextFontSet(&g_sContext, &g_sFontCm20); GrStringDrawCentered(&g_sContext, "usb host keyboard", -1, GrContextDpyWidthGet(&g_sContext) / 2, 10, 0); // //Setup the interrupt controller // #ifdef _TMS320C6X SetupDSPINTCInt(); ConfigureDSPINTCIntUSB(); #else SetupAINTCInt(); ConfigureAINTCIntUSB(); #endif DelayTimerSetup(); // // 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_sFontCm20); // // 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) - (2*(DISPLAY_BANNER_HEIGHT + 1)))/ GrFontHeightGet(&g_sFontCm20); // // 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); // // Initialize the host controller stack. // USBHCDInit(0, g_pHCDPool, HCD_MEMORY_SIZE); // // Call the main loop for the Host controller driver. // USBHCDMain(); // // Initial update of the screen. // UpdateStatus(); // // The main loop for the application. // while(1) { 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(); 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; } } // // Periodic call the main loop for the Host controller driver. // USBHCDMain(); } }
//***************************************************************************** // // The main application loop. // //***************************************************************************** int main(void) { int32_t i32Status, i32Idx; uint32_t ui32SysClock, ui32PLLRate; #ifdef USE_ULPI uint32_t ui32Setting; #endif ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // // Set the part pin out appropriately for this device. // PinoutSet(); #ifdef USE_ULPI // // Switch the USB ULPI Pins over. // USBULPIPinoutSet(); // // Enable USB ULPI with high speed support. // ui32Setting = USBLIB_FEATURE_ULPI_HS; USBOTGFeatureSet(0, USBLIB_FEATURE_USBULPI, &ui32Setting); // // Setting the PLL frequency to zero tells the USB library to use the // external USB clock. // ui32PLLRate = 0; #else // // Save the PLL rate used by this application. // ui32PLLRate = 480000000; #endif // // Initialize the hub port status. // for(i32Idx = 0; i32Idx < NUM_HUB_STATUS; i32Idx++) { g_psHubStatus[i32Idx].bConnected = false; } // // Enable Clocking to the USB controller. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); // // Enable Interrupts // ROM_IntMasterEnable(); // // Initialize the USB stack mode and pass in a mode callback. // USBStackModeSet(0, eUSBModeHost, 0); // // Register the host class drivers. // USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ui32NumHostClassDrivers); // // Open the Keyboard interface. // KeyboardOpen(); MSCOpen(ui32SysClock); // // Open a hub instance and provide it with the memory required to hold // configuration descriptors for each attached device. // USBHHubOpen(HubCallback); // // 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); // // Tell the USB library the CPU clock and the PLL frequency. // USBOTGFeatureSet(0, USBLIB_FEATURE_CPUCLK, &ui32SysClock); USBOTGFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate); // // Initialize the USB controller for Host mode. // USBHCDInit(0, g_pui8HCDPool, sizeof(g_pui8HCDPool)); // // Initialize the display driver. // Kentec320x240x16_SSD2119Init(ui32SysClock); // // Initialize the graphics context. // GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119); // // Draw the application frame. // FrameDraw(&g_sContext, "usb-host-hub"); // // Calculate the number of characters that will fit on a line. // Make sure to leave a small border for the text box. // g_ui32CharsPerLine = (GrContextDpyWidthGet(&g_sContext) - 16) / GrFontMaxWidthGet(g_psFontFixed6x8); // // 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_ui32LinesPerScreen = (GrContextDpyHeightGet(&g_sContext) - (2*(DISPLAY_BANNER_HEIGHT + 1)))/ GrFontHeightGet(g_psFontFixed6x8); // // Initial update of the screen. // UpdateStatus(0); UpdateStatus(1); UpdateStatus(2); UpdateStatus(3); g_ui32CmdIdx = 0; g_ui32CurrentLine = 0; // // Initialize the file system. // FileInit(); // // The main loop for the application. // while(1) { // // Print a prompt to the console. Show the CWD. // WriteString("> "); // // Is there a command waiting to be processed? // while((g_ui32Flags & FLAG_CMD_READY) == 0) { // // Call the YSB library to let non-interrupt code run. // USBHCDMain(); // // Call the keyboard and mass storage main routines. // KeyboardMain(); MSCMain(); } // // Pass the line from the user to the command processor. // It will be parsed and valid commands executed. // i32Status = CmdLineProcess(g_pcCmdBuf); // // Handle the case of bad command. // if(i32Status == CMDLINE_BAD_CMD) { WriteString("Bad command!\n"); } // // Handle the case of too many arguments. // else if(i32Status == CMDLINE_TOO_MANY_ARGS) { WriteString("Too many arguments for command processor!\n"); } // // Otherwise the command was executed. Print the error // code if one was returned. // else if(i32Status != 0) { WriteString("Command returned error code\n"); WriteString((char *)StringFromFresult((FRESULT)i32Status)); WriteString("\n"); } // // Reset the command flag and the command index. // g_ui32Flags &= ~FLAG_CMD_READY; g_ui32CmdIdx = 0; } }
//***************************************************************************** // // This function prints the character out the screen and into the command // buffer. // // ucChar is the character to print out. // // This function handles all of the detail of printing a character to the // screen and into the command line buffer. // // No return value. // //***************************************************************************** void PrintChar(const char cChar) { int32_t i32Char; char *pcCurLine; GrContextForegroundSet(&g_sContext, ClrWhite); pcCurLine = g_pcLines + (MAX_COLUMNS * g_ui32CurrentLine); // // Allow new lines to cause the column to go back to zero. // if(cChar != '\n') { // // Handle when receiving a backspace character. // if(cChar != ASCII_BACKSPACE) { // // This is not a backspace so print the character to the screen. // GrStringDraw(&g_sContext, &cChar, 1, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1); pcCurLine[g_ui32Column] = cChar; } else { // // We got a backspace. If we are at the top left of the screen, // return since we don't need to do anything. // if(g_ui32Column || g_ui32Line) { // // Adjust the cursor position to erase the last character. // if(g_ui32Column > 2) { g_ui32Column--; g_ui32CmdIdx--; } // // Print a space at this position then return without fixing up // the cursor again. // GrStringDraw(&g_sContext, " ", 1, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), true); pcCurLine[g_ui32Column] = ' '; } return; } } else { for(i32Char = g_ui32Column; i32Char < MAX_COLUMNS - 1; i32Char++) { pcCurLine[i32Char] = ' '; } // // Null terminate the string when enter is pressed. // pcCurLine[MAX_COLUMNS - 1] = 0; g_ui32CurrentLine++; if(g_ui32CurrentLine >= MAX_LINES) { g_ui32CurrentLine = 0; } // // This will allow the code below to properly handle the new line. // g_ui32Column = g_ui32CharsPerLine; g_ui32Flags |= FLAG_CMD_READY; g_pcCmdBuf[g_ui32CmdIdx++] = ' '; } // // Update the text row and column that the next character will use. // if(g_ui32Column < g_ui32CharsPerLine) { // // No line wrap yet so move one column over. // g_ui32Column++; } else { // // Line wrapped so go back to the first column and update the line. // g_ui32Column = 0; g_ui32Line++; // // The line has gone past the end so go back to the first line. // if(g_ui32Line >= g_ui32LinesPerScreen) { g_ui32Line = g_ui32LinesPerScreen - 1; } } // // Save the new character in the buffer. // g_pcCmdBuf[g_ui32CmdIdx++] = cChar; }
//***************************************************************************** // // Print a string to the screen and save it to the screen buffer. // //***************************************************************************** void WriteString(const char *pcString) { uint32_t ui32Size, ui32StrSize; char *pcCurLine; int32_t i32Idx; ui32StrSize = ustrlen(pcString); // // Check if the string requires scrolling the text in order to print. // if((g_ui32Line >= MAX_LINES) && (g_ui32Column == 0)) { // // Start redrawing at line 0. // g_ui32Line = 0; // // Print lines from the current position down first. // for(i32Idx = g_ui32CurrentLine + 1; i32Idx < MAX_LINES; i32Idx++) { GrStringDraw(&g_sContext, g_pcLines + (MAX_COLUMNS * i32Idx), ustrlen(g_pcLines + (MAX_COLUMNS * i32Idx)), DISPLAY_TEXT_BORDER_H, DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1); g_ui32Line++; } // // If not already at the top then print the lines starting at the // top of the buffer. // if(g_ui32CurrentLine != 0) { for(i32Idx = 0; i32Idx < g_ui32CurrentLine; i32Idx++) { GrStringDraw(&g_sContext, g_pcLines + (MAX_COLUMNS * i32Idx), ustrlen(g_pcLines + (MAX_COLUMNS * i32Idx)), DISPLAY_TEXT_BORDER_H, DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1); g_ui32Line++; } } } // // Save the current line pointer to use in references below. // pcCurLine = g_pcLines + (MAX_COLUMNS * g_ui32CurrentLine); if(g_ui32Column + ui32StrSize >= MAX_COLUMNS - 1) { ui32Size = MAX_COLUMNS - g_ui32Column - 1; } else { ui32Size = ui32StrSize; } // // Handle the case where the string has a new line at the end. // if(pcString[ui32StrSize-1] == '\n') { // // Make sure that this is not a single new line. // if(ui32Size > 0 ) { // // Copy the string into the screen buffer. // ustrncpy(pcCurLine + g_ui32Column, pcString, ui32Size - 1); } // // If this is the start of a new line then clear out the rest of the // line by writing spaces to the end of the line. // if(g_ui32Column == 0) { // // Clear out the string with spaces to overwrite any existing // characters with spaces. // for(i32Idx = ui32Size - 1; i32Idx < MAX_COLUMNS; i32Idx++) { pcCurLine[i32Idx] = ' '; } } // // Null terminate the string. // pcCurLine[g_ui32Column + MAX_COLUMNS - 1] = 0; // // Draw the new string. // GrStringDraw(&g_sContext, pcCurLine + g_ui32Column, ui32Size - 1, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1); // // Increment the line values and reset the column to 0. // g_ui32Line++; g_ui32CurrentLine++; if(g_ui32CurrentLine >= MAX_LINES) { g_ui32CurrentLine = 0; } g_ui32Column = 0; } else { // // Copy the string into the screen buffer. // ustrncpy(pcCurLine + g_ui32Column, pcString, ui32Size); // // See if this was the first string draw on this line. // if(g_ui32Column == 0) { // // Pad the rest of the string with spaces to overwrite any existing // characters with spaces. // for(i32Idx = ui32Size; i32Idx < MAX_COLUMNS - 1; i32Idx++) { pcCurLine[i32Idx] = ' '; } // // Draw the new string. // GrStringDraw(&g_sContext, pcCurLine + g_ui32Column, MAX_COLUMNS - 1, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1); } else { // // Draw the new string. // GrStringDraw(&g_sContext, pcCurLine + g_ui32Column, g_ui32Column + ui32Size, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1); } // // Update the current column. // g_ui32Column += ui32Size; } }
//***************************************************************************** // // This function prints the character out the screen and into the command // buffer. // // ucChar is the character to print out. // // This function handles all of the detail of printing a character to the // screen and into the command line buffer. // // No return value. // //***************************************************************************** void UIPrintChar(const char cChar) { bool bNewLine; int32_t i32Idx; GrContextForegroundSet(&g_sContext, ClrWhite); bNewLine = true; // // Allow new lines to cause the column to go back to zero. // if(cChar != '\n') { // // Handle when receiving a backspace character. // if(cChar != ASCII_BACKSPACE) { // // This is not a backspace so print the character to the screen. // GrStringDraw(&g_sContext, &cChar, 1, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32EntryLine * GrFontHeightGet(g_psFontFixed6x8)), 1); g_ppcLines[g_ui32CurrentLine][g_ui32Column] = cChar; if(g_ui32Column < g_ui32CharsPerLine) { // // No line wrap yet so move one column over. // g_ui32Column++; bNewLine = false; } } else { // // We got a backspace. If we are at the top left of the screen, // return since we don't need to do anything. // if(g_ui32Column || g_ui32EntryLine) { // // Adjust the cursor position to erase the last character. // if(g_ui32Column > 2) { g_ui32Column--; } // // Print a space at this position then return without fixing up // the cursor again. // GrStringDraw(&g_sContext, " ", 1, DISPLAY_TEXT_BORDER_H + (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column), DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32EntryLine * GrFontHeightGet(g_psFontFixed6x8)), true); g_ppcLines[g_ui32CurrentLine][g_ui32Column] = ' '; } bNewLine = false; } } // // . // if(bNewLine) { g_ui32Column = 0; if(g_ui32EntryLine < (MAX_LINES - 1)) { g_ui32EntryLine++; } else { ScrollText(); } g_ui32CurrentLine++; // // The line has gone past the end so go back to the first line. // if(g_ui32CurrentLine >= MAX_LINES) { g_ui32CurrentLine = 0; } // // Add a prompt to the new line. // if(cChar == '\n') { DrawPrompt(); } else { // // Clear out the current line. // for(i32Idx = 0; i32Idx < MAX_COLUMNS - 1; i32Idx++) { g_ppcLines[g_ui32CurrentLine][i32Idx] = ' '; } g_ppcLines[g_ui32CurrentLine][i32Idx] = 0; GrStringDraw(&g_sContext, g_ppcLines[g_ui32CurrentLine], strlen(g_ppcLines[g_ui32CurrentLine]), DISPLAY_TEXT_BORDER_H, DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER + (g_ui32EntryLine * GrFontHeightGet(g_psFontFixed6x8)), 1); } } }
//***************************************************************************** // //! Draws the strip chart into a drawing context, off-screen buffer. //! //! \param psChartWidget points at the StripsChartWidget being processed. //! \param psContext points to the context where all drawing should be done. //! //! This function renders a strip chart into a drawing context. //! It assumes that the drawing context is an off-screen buffer, and that //! the entire buffer belongs to this widget. //! //! \return None. // //***************************************************************************** void StripChartDraw(tStripChartWidget *psChartWidget, tContext *psContext) { tStripChartAxis *psAxisY; int32_t i32Y; int32_t i32Ygrid; int32_t i32X; int32_t i32GridRange; int32_t i32DispRange; int32_t i32GridMin; int32_t i32DispMax; tStripChartSeries *psSeries; // // Check the parameters // ASSERT(psChartWidget); ASSERT(psContext); ASSERT(psChartWidget->psAxisY); // // Get handy pointer to Y axis // psAxisY = psChartWidget->psAxisY; // // Find the range of Y axis in Y axis units // i32GridRange = psAxisY->i32Max - psAxisY->i32Min; // // Find the range of the Y axis in display units (pixels) // i32DispRange = (psContext->sClipRegion.i16YMax - psContext->sClipRegion.i16YMin); // // Find the minimum Y units value to be shown, and the maximum of the // clipping region. // i32GridMin = psAxisY->i32Min; i32DispMax = psContext->sClipRegion.i16YMax; // // Set the fg color for the rectangle fill to match what we want as the // chart background. // GrContextForegroundSet(psContext, psChartWidget->ui32BackgroundColor); GrRectFill(psContext, &psContext->sClipRegion); // // Draw vertical grid lines // GrContextForegroundSet(psContext, psChartWidget->ui32GridColor); for(i32X = psChartWidget->i32GridX; i32X < psContext->sClipRegion.i16XMax; i32X += psChartWidget->psAxisX->i32GridInterval) { GrLineDrawV(psContext, psContext->sClipRegion.i16XMax - i32X, psContext->sClipRegion.i16YMin, psContext->sClipRegion.i16YMax); } // // Draw horizontal grid lines // for(i32Ygrid = psAxisY->i32Min; i32Ygrid < psAxisY->i32Max; i32Ygrid += psAxisY->i32GridInterval) { i32Y = ((i32Ygrid - i32GridMin) * i32DispRange) / i32GridRange; i32Y = i32DispMax - i32Y; GrLineDrawH(psContext, psContext->sClipRegion.i16XMin, psContext->sClipRegion.i16XMax, i32Y); } // // Compute location of Y=0 line, and draw it // i32Y = ((-i32GridMin) * i32DispRange) / i32GridRange; i32Y = i32DispMax - i32Y; GrLineDrawH(psContext, psContext->sClipRegion.i16XMin, psContext->sClipRegion.i16XMax, i32Y); // // Iterate through each series to draw it // psSeries = psChartWidget->psSeries; while(psSeries) { int idx = 0; // // Find the starting X position on the display for this series. // If the series has less data points than can fit on the display // then starting X can be somewhere in the middle of the screen. // i32X = 1 + psContext->sClipRegion.i16XMax - psSeries->ui16NumItems; // // If the starting X is off the left side of the screen, then the // staring index (idx) for reading data needs to be adjusted to the // first value in the series that will be visible on the screen // if(i32X < psContext->sClipRegion.i16XMin) { idx = psContext->sClipRegion.i16XMin - i32X; i32X = psContext->sClipRegion.i16XMin; } // // Set the drawing color for this series // GrContextForegroundSet(psContext, psSeries->ui32Color); // // Scan through all possible X values, find the Y value, and draw the // pixel. // for(; i32X <= psContext->sClipRegion.i16XMax; i32X++) { // // Find the Y value at each position in the data series. Take into // account the data size and the stride // if(psSeries->ui8DataTypeSize == 1) { i32Y = ((int8_t *)psSeries->pvData)[idx * psSeries->ui8Stride]; } else if(psSeries->ui8DataTypeSize == 2) { i32Y = ((int16_t *)psSeries->pvData)[idx * psSeries->ui8Stride]; } else if(psSeries->ui8DataTypeSize == 4) { i32Y = ((int32_t *)psSeries->pvData)[idx * psSeries->ui8Stride]; } else { // // If there is an invalid data size, then just force Y value // to be off the display // i32Y = i32DispMax + 1; break; } // // Advance to the next position in the data series. // idx++; // // Now scale the Y value according to the axis scaling // i32Y = ((i32Y - i32GridMin) * i32DispRange) / i32GridRange; i32Y = i32DispMax - i32Y; // // Draw the pixel on the display // GrPixelDraw(psContext, i32X, i32Y); } // // Advance to the next series until there are no more. // psSeries = psSeries->psNextSeries; } // // Draw a frame around the entire chart. // GrContextForegroundSet(psContext, psChartWidget->ui32Y0Color); GrRectDraw(psContext, &psContext->sClipRegion); // // Draw titles // GrContextForegroundSet(psContext, psChartWidget->ui32TextColor); GrContextFontSet(psContext, psChartWidget->psFont); // // Draw the chart title, if there is one // if(psChartWidget->pcTitle) { GrStringDrawCentered(psContext, psChartWidget->pcTitle, -1, psContext->sClipRegion.i16XMax / 2, GrFontHeightGet(psChartWidget->psFont), 0); } // // Draw the Y axis max label, if there is one // if(psChartWidget->psAxisY->pcMaxLabel) { GrStringDraw(psContext, psChartWidget->psAxisY->pcMaxLabel, -1, psContext->sClipRegion.i16XMin + GrFontMaxWidthGet(psChartWidget->psFont) / 2, GrFontHeightGet(psChartWidget->psFont) / 2, 0); } // // Draw the Y axis min label, if there is one // if(psChartWidget->psAxisY->pcMinLabel) { GrStringDraw(psContext, psChartWidget->psAxisY->pcMinLabel, -1, psContext->sClipRegion.i16XMin + GrFontMaxWidthGet(psChartWidget->psFont) / 2, psContext->sClipRegion.i16YMax - (GrFontHeightGet(psChartWidget->psFont) + (GrFontHeightGet(psChartWidget->psFont) / 2)), 0); } // // Draw a label for the name of the Y axis, if there is one // if(psChartWidget->psAxisY->pcName) { GrStringDraw(psContext, psChartWidget->psAxisY->pcName, -1, psContext->sClipRegion.i16XMin + 1, (psContext->sClipRegion.i16YMax / 2) - (GrFontHeightGet(psChartWidget->psFont) / 2), 1); } }