diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2014-06-29 12:34:32 +0300 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2014-06-29 12:34:32 +0300 |
| commit | c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 (patch) | |
| tree | added370d1e356901f8579f076e3263fb0464db7 /boards/ek-lm4f232/drivers/stripchartwidget.c | |
| parent | 990090a4cc9070837d31e66b58d40f0c3d038741 (diff) | |
Add more board models
Diffstat (limited to 'boards/ek-lm4f232/drivers/stripchartwidget.c')
| -rw-r--r-- | boards/ek-lm4f232/drivers/stripchartwidget.c | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/boards/ek-lm4f232/drivers/stripchartwidget.c b/boards/ek-lm4f232/drivers/stripchartwidget.c new file mode 100644 index 0000000..60d9d37 --- /dev/null +++ b/boards/ek-lm4f232/drivers/stripchartwidget.c @@ -0,0 +1,672 @@ +//*****************************************************************************
+//
+// stripchartwidget.c - A simple strip chart widget.
+//
+// Copyright (c) 2011-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the EK-LM4F232 Firmware Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "driverlib/debug.h"
+#include "grlib/grlib.h"
+#include "grlib/widget.h"
+#include "stripchartwidget.h"
+
+//*****************************************************************************
+//
+//! \addtogroup stripchartwidget_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// This is a custom widget for drawing a simple strip chart. The strip
+// chart can be configured with an X/Y grid, and data series can be added
+// to and displayed on the strip chart. The strip chart can be "advanced"
+// so that the grid lines will move on the display. Before advancing
+// the chart, the application must update the series data in the buffers.
+// The strip chart will only display whatever is in the series buffers, the
+// application must scroll the data in the series data buffers. By adjusting
+// the data in the series data buffers, advancing the strip chart, and
+// repainting, the strip chart can be made to scroll the data across the
+// display.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! 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);
+ }
+}
+
+//*****************************************************************************
+//
+//! Paints the strip chart on the display.
+//!
+//! \param psWidget is a pointer to the strip chart widget to be drawn.
+//!
+//! This function draws the contents of a strip chart on the display. This is
+//! called in response to a \b WIDGET_MSG_PAINT message.
+//!
+//! \return None.
+//
+//*****************************************************************************
+static void
+StripChartPaint(tWidget *psWidget)
+{
+ tStripChartWidget *psChartWidget;
+ tContext sContext;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(psWidget);
+ ASSERT(psWidget->psDisplay);
+
+ //
+ // Convert the generic widget pointer into a strip chart widget pointer.
+ //
+ psChartWidget = (tStripChartWidget *)psWidget;
+
+ //
+ // Initialize a context for the primary off-screen drawing buffer.
+ // Clip region is set to entire display by default, which is what we want.
+ //
+ ASSERT(psChartWidget->psOffscreenDisplay);
+ GrContextInit(&sContext, psChartWidget->psOffscreenDisplay);
+
+ //
+ // Render the strip chart into the off-screen buffer
+ //
+ StripChartDraw(psChartWidget, &sContext);
+
+ //
+ // Initialize a drawing context for the display where the widget is to be
+ // drawn. This is the physical display, not an off-screen buffer.
+ //
+ GrContextInit(&sContext, psWidget->psDisplay);
+
+ //
+ // Initialize the clipping region on the physical display, based on the
+ // extents of this widget.
+ //
+ GrContextClipRegionSet(&sContext, &(psWidget->sPosition));
+
+ //
+ // Now copy the rendered strip chart into the physical display
+ //
+ GrImageDraw(&sContext, psChartWidget->psOffscreenDisplay->pvDisplayData,
+ psWidget->sPosition.i16XMin, psWidget->sPosition.i16YMin);
+}
+
+//*****************************************************************************
+//
+//! Advances the strip chart X grid by a certain number of pixels.
+//!
+//! \param psChartWidget is a pointer to the strip chart widget to be advanced.
+//! \param i32Count is the number of positions to advance the grid.
+//!
+//! This function advances the X grid of the strip chart by the specified
+//! number of positions. By using this function to advance the grid in
+//! combination with updating the data in the series data buffers, the strip
+//! chart can be made to appear to scroll across the display.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+StripChartAdvance(tStripChartWidget *psChartWidget, int32_t i32Count)
+{
+ //
+ // Adjust the starting point of the X-grid
+ //
+ psChartWidget->i32GridX += i32Count;
+ psChartWidget->i32GridX %= psChartWidget->psAxisX->i32GridInterval;
+}
+
+//*****************************************************************************
+//
+//! Adds a data series to the strip chart.
+//!
+//! \param psWidget is a pointer to the strip chart widget to be modified.
+//! \param psNewSeries is a strip chart data series to be added to the strip
+//! chart.
+//!
+//! This function will add a data series to the strip chart. This function
+//! just links the series into the strip chart. It is up to the application
+//! to make sure that the data series is initialized correctly.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+StripChartSeriesAdd(tStripChartWidget *psWidget,
+ tStripChartSeries *psNewSeries)
+{
+ //
+ // If there is already at least one series in this chart, then link
+ // in to the existing chain.
+ //
+ if(psWidget->psSeries)
+ {
+ tStripChartSeries *psSeries = psWidget->psSeries;
+ while(psSeries->psNextSeries)
+ {
+ psSeries = psSeries->psNextSeries;
+ }
+ psSeries->psNextSeries = psNewSeries;
+ }
+
+ //
+ // Otherwise, there is not already a series in this chart, so set this
+ // new series as the first series for the chart.
+ //
+ else
+ {
+ psWidget->psSeries = psNewSeries;
+ }
+ psNewSeries->psNextSeries = 0;
+}
+
+//*****************************************************************************
+//
+//! Removes a data series from the strip chart.
+//!
+//! \param psWidget is a pointer to the strip chart widget to be modified.
+//! \param psOldSeries is a strip chart data series that is to be removed
+//! from the strip chart.
+//!
+//! This function will remove an existing data series from a strip chart. It
+//! will search the list of data series for the specified series, and if
+//! found it will be unlinked from the chain of data series for this strip
+//! chart.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+StripChartSeriesRemove(tStripChartWidget *psWidget,
+ tStripChartSeries *psOldSeries)
+{
+ //
+ // If the series to be removed is the first one, then find the next
+ // series in the chain and set it to be first.
+ //
+ if(psWidget->psSeries == psOldSeries)
+ {
+ psWidget->psSeries = psOldSeries->psNextSeries;
+ }
+
+ //
+ // Otherwise, scan through the chain to find the old series
+ //
+ else
+ {
+ tStripChartSeries *psSeries = psWidget->psSeries;
+ while(psSeries->psNextSeries)
+ {
+ //
+ // If the old series is found, unlink it from the chain
+ //
+ if(psSeries->psNextSeries == psOldSeries)
+ {
+ psSeries->psNextSeries = psOldSeries->psNextSeries;
+ break;
+ }
+ else
+ {
+ psSeries = psSeries->psNextSeries;
+ }
+ }
+ }
+
+ //
+ // Finally, set the "next" pointer of the old series to null so that
+ // there will not be any confusing chain fragments if this series is
+ // reused.
+ //
+ psOldSeries->psNextSeries = 0;
+}
+
+//*****************************************************************************
+//
+//! Handles messages for a strip chart widget.
+//!
+//! \param psWidget is a pointer to the strip chart widget.
+//! \param ui32Msg is the message.
+//! \param ui32Param1 is the first parameter to the message.
+//! \param ui32Param2 is the second parameter to the message.
+//!
+//! This function receives messages intended for this strip chart widget and
+//! processes them accordingly. The processing of the message varies based on
+//! the message in question.
+//!
+//! Unrecognized messages are handled by calling WidgetDefaultMsgProc().
+//!
+//! \return Returns a value appropriate to the supplied message.
+//
+//*****************************************************************************
+int32_t
+StripChartMsgProc(tWidget *psWidget, uint32_t ui32Msg, uint32_t ui32Param1,
+ uint32_t ui32Param2)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psWidget);
+
+ //
+ // Determine which message is being sent.
+ //
+ switch(ui32Msg)
+ {
+ //
+ // The widget paint request has been sent.
+ //
+ case WIDGET_MSG_PAINT:
+ {
+ //
+ // Handle the widget paint request.
+ //
+ StripChartPaint(psWidget);
+
+ //
+ // Return one to indicate that the message was successfully
+ // processed.
+ //
+ return(1);
+ }
+
+ //
+ // Deliberately ignore all button press messages. They may be handled
+ // by another widget.
+ //
+ case WIDGET_MSG_KEY_SELECT:
+ case WIDGET_MSG_KEY_UP:
+ case WIDGET_MSG_KEY_DOWN:
+ case WIDGET_MSG_KEY_LEFT:
+ case WIDGET_MSG_KEY_RIGHT:
+ {
+ return(0);
+ }
+
+ //
+ // An unknown request has been sent.
+ //
+ default:
+ {
+ //
+ // Let the default message handler process this message.
+ //
+ return(WidgetDefaultMsgProc(psWidget, ui32Msg, ui32Param1,
+ ui32Param2));
+ }
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes a strip chart widget.
+//!
+//! \param psWidget is a pointer to the strip chart widget to initialize.
+//! \param psDisplay is a pointer to the display on which to draw the chart.
+//! \param i32X is the X coordinate of the upper left corner of the canvas.
+//! \param i32Y is the Y coordinate of the upper left corner of the canvas.
+//! \param i32Width is the width of the canvas.
+//! \param i32Height is the height of the canvas.
+//! \param pcTitle is the label text for the strip chart
+//! \param psFont is the font to use for drawing text on the chart.
+//! \param ui32BackgroundColor is the colr of the background for the chart.
+//! \param ui32TextColor is the color used for drawing text.
+//! \param ui32Y0Color is the color used for drawing the Y=0 line and the frame
+//! around the chart.
+//! \param ui32GridColor is the color of the X/Y grid
+//! \param psAxisX is a pointer to the X-axis object
+//! \param psAxisY is a pointer to the Y-axis object
+//! \param psOffscreenDisplay is a pointer to an offscreen display that will
+//! be used for rendering the strip chart prior to drawing it on the
+//! physical display.
+//!
+//! This function initializes the caller provided strip chart widget.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+StripChartInit(tStripChartWidget *psWidget, const tDisplay *psDisplay,
+ int32_t i32X, int32_t i32Y, int32_t i32Width, int32_t i32Height,
+ char * pcTitle, tFont *psFont,
+ uint32_t ui32BackgroundColor,
+ uint32_t ui32TextColor,
+ uint32_t ui32Y0Color,
+ uint32_t ui32GridColor,
+ tStripChartAxis *psAxisX, tStripChartAxis *psAxisY,
+ tDisplay *psOffscreenDisplay)
+{
+ uint32_t ui32Idx;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(psWidget);
+ ASSERT(psDisplay);
+ ASSERT(psAxisX);
+ ASSERT(psAxisY);
+ ASSERT(psOffscreenDisplay);
+
+ //
+ // Clear out the widget structure.
+ //
+ for(ui32Idx = 0; ui32Idx < sizeof(tStripChartWidget); ui32Idx += 4)
+ {
+ ((uint32_t *)psWidget)[ui32Idx / 4] = 0;
+ }
+
+ //
+ // Set the size of the widget structure.
+ //
+ psWidget->sBase.i32Size = sizeof(tStripChartWidget);
+
+ //
+ // Mark this widget as fully disconnected.
+ //
+ psWidget->sBase.psParent = 0;
+ psWidget->sBase.psNext = 0;
+ psWidget->sBase.psChild = 0;
+
+ //
+ // Save the display pointer.
+ //
+ psWidget->sBase.psDisplay = psDisplay;
+
+ //
+ // Set the extents of the display area.
+ //
+ psWidget->sBase.sPosition.i16XMin = i32X;
+ psWidget->sBase.sPosition.i16YMin = i32Y;
+ psWidget->sBase.sPosition.i16XMax = i32X + i32Width - 1;
+ psWidget->sBase.sPosition.i16YMax = i32Y + i32Height - 1;
+
+ //
+ // Initialize the widget fields
+ //
+ psWidget->pcTitle = pcTitle;
+ psWidget->psFont = psFont;
+ psWidget->ui32BackgroundColor = ui32BackgroundColor;
+ psWidget->ui32TextColor = ui32TextColor;
+ psWidget->ui32Y0Color = ui32Y0Color;
+ psWidget->ui32GridColor = ui32GridColor;
+ psWidget->psAxisX = psAxisX;
+ psWidget->psAxisY = psAxisY;
+ psWidget->psOffscreenDisplay = psOffscreenDisplay;
+
+ //
+ // Use the strip chart message handler to process messages to this widget.
+ //
+ psWidget->sBase.pfnMsgProc = StripChartMsgProc;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
|
