From c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Sun, 29 Jun 2014 12:34:32 +0300 Subject: Add more board models --- boards/ek-lm4f232/qs-logger/Makefile | 108 ++ boards/ek-lm4f232/qs-logger/acquire.c | 965 +++++++++++++++ boards/ek-lm4f232/qs-logger/acquire.h | 57 + boards/ek-lm4f232/qs-logger/ccs/.ccsimportspec | 27 + boards/ek-lm4f232/qs-logger/ccs/.ccsproject | 10 + boards/ek-lm4f232/qs-logger/ccs/.cproject | 195 +++ boards/ek-lm4f232/qs-logger/ccs/.project | 135 +++ .../ccs/.settings/org.eclipse.cdt.codan.core.prefs | 3 + .../ek-lm4f232/qs-logger/ccs/Debug/qs-logger.bin | Bin 0 -> 59472 bytes .../ek-lm4f232/qs-logger/ccs/Debug/qs-logger.out | Bin 0 -> 1147339 bytes boards/ek-lm4f232/qs-logger/ccs/macros.ini_initial | 1 + .../ek-lm4f232/qs-logger/ccs/target_config.ccxml | 13 + boards/ek-lm4f232/qs-logger/clocksetwidget.c | 1031 ++++++++++++++++ boards/ek-lm4f232/qs-logger/clocksetwidget.h | 273 +++++ .../ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.bin | Bin 0 -> 55076 bytes .../ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.out | Bin 0 -> 955736 bytes boards/ek-lm4f232/qs-logger/flashstore.c | 625 ++++++++++ boards/ek-lm4f232/qs-logger/flashstore.h | 60 + boards/ek-lm4f232/qs-logger/gcc/qs-logger.axf | Bin 0 -> 139804 bytes boards/ek-lm4f232/qs-logger/gcc/qs-logger.bin | Bin 0 -> 61648 bytes boards/ek-lm4f232/qs-logger/images.c | 865 ++++++++++++++ boards/ek-lm4f232/qs-logger/images.h | 37 + boards/ek-lm4f232/qs-logger/menus.c | 704 +++++++++++ boards/ek-lm4f232/qs-logger/menus.h | 83 ++ boards/ek-lm4f232/qs-logger/qs-logger.c | 1260 ++++++++++++++++++++ boards/ek-lm4f232/qs-logger/qs-logger.ewd | 614 ++++++++++ boards/ek-lm4f232/qs-logger/qs-logger.ewp | 845 +++++++++++++ boards/ek-lm4f232/qs-logger/qs-logger.h | 180 +++ boards/ek-lm4f232/qs-logger/qs-logger.icf | 78 ++ boards/ek-lm4f232/qs-logger/qs-logger.ld | 57 + boards/ek-lm4f232/qs-logger/qs-logger.sct | 47 + boards/ek-lm4f232/qs-logger/qs-logger.uvopt | 555 +++++++++ boards/ek-lm4f232/qs-logger/qs-logger.uvproj | 519 ++++++++ boards/ek-lm4f232/qs-logger/qs-logger_ccs.cmd | 70 ++ boards/ek-lm4f232/qs-logger/readme.txt | 93 ++ boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.axf | Bin 0 -> 677900 bytes boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.bin | Bin 0 -> 60312 bytes boards/ek-lm4f232/qs-logger/startup_ccs.c | 305 +++++ boards/ek-lm4f232/qs-logger/startup_ewarm.c | 336 ++++++ boards/ek-lm4f232/qs-logger/startup_gcc.c | 352 ++++++ boards/ek-lm4f232/qs-logger/startup_rvmdk.S | 361 ++++++ boards/ek-lm4f232/qs-logger/stripchartmanager.c | 445 +++++++ boards/ek-lm4f232/qs-logger/stripchartmanager.h | 63 + boards/ek-lm4f232/qs-logger/usb_serial_structs.c | 217 ++++ boards/ek-lm4f232/qs-logger/usb_serial_structs.h | 49 + boards/ek-lm4f232/qs-logger/usbserial.c | 459 +++++++ boards/ek-lm4f232/qs-logger/usbserial.h | 56 + boards/ek-lm4f232/qs-logger/usbstick.c | 814 +++++++++++++ boards/ek-lm4f232/qs-logger/usbstick.h | 58 + 49 files changed, 13025 insertions(+) create mode 100644 boards/ek-lm4f232/qs-logger/Makefile create mode 100644 boards/ek-lm4f232/qs-logger/acquire.c create mode 100644 boards/ek-lm4f232/qs-logger/acquire.h create mode 100644 boards/ek-lm4f232/qs-logger/ccs/.ccsimportspec create mode 100644 boards/ek-lm4f232/qs-logger/ccs/.ccsproject create mode 100644 boards/ek-lm4f232/qs-logger/ccs/.cproject create mode 100644 boards/ek-lm4f232/qs-logger/ccs/.project create mode 100644 boards/ek-lm4f232/qs-logger/ccs/.settings/org.eclipse.cdt.codan.core.prefs create mode 100644 boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.bin create mode 100644 boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.out create mode 100644 boards/ek-lm4f232/qs-logger/ccs/macros.ini_initial create mode 100644 boards/ek-lm4f232/qs-logger/ccs/target_config.ccxml create mode 100644 boards/ek-lm4f232/qs-logger/clocksetwidget.c create mode 100644 boards/ek-lm4f232/qs-logger/clocksetwidget.h create mode 100644 boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.bin create mode 100644 boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.out create mode 100644 boards/ek-lm4f232/qs-logger/flashstore.c create mode 100644 boards/ek-lm4f232/qs-logger/flashstore.h create mode 100644 boards/ek-lm4f232/qs-logger/gcc/qs-logger.axf create mode 100644 boards/ek-lm4f232/qs-logger/gcc/qs-logger.bin create mode 100644 boards/ek-lm4f232/qs-logger/images.c create mode 100644 boards/ek-lm4f232/qs-logger/images.h create mode 100644 boards/ek-lm4f232/qs-logger/menus.c create mode 100644 boards/ek-lm4f232/qs-logger/menus.h create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.c create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.ewd create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.ewp create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.h create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.icf create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.ld create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.sct create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.uvopt create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger.uvproj create mode 100644 boards/ek-lm4f232/qs-logger/qs-logger_ccs.cmd create mode 100644 boards/ek-lm4f232/qs-logger/readme.txt create mode 100644 boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.axf create mode 100644 boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.bin create mode 100644 boards/ek-lm4f232/qs-logger/startup_ccs.c create mode 100644 boards/ek-lm4f232/qs-logger/startup_ewarm.c create mode 100644 boards/ek-lm4f232/qs-logger/startup_gcc.c create mode 100644 boards/ek-lm4f232/qs-logger/startup_rvmdk.S create mode 100644 boards/ek-lm4f232/qs-logger/stripchartmanager.c create mode 100644 boards/ek-lm4f232/qs-logger/stripchartmanager.h create mode 100644 boards/ek-lm4f232/qs-logger/usb_serial_structs.c create mode 100644 boards/ek-lm4f232/qs-logger/usb_serial_structs.h create mode 100644 boards/ek-lm4f232/qs-logger/usbserial.c create mode 100644 boards/ek-lm4f232/qs-logger/usbserial.h create mode 100644 boards/ek-lm4f232/qs-logger/usbstick.c create mode 100644 boards/ek-lm4f232/qs-logger/usbstick.h (limited to 'boards/ek-lm4f232/qs-logger') diff --git a/boards/ek-lm4f232/qs-logger/Makefile b/boards/ek-lm4f232/qs-logger/Makefile new file mode 100644 index 0000000..5d3f5d9 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/Makefile @@ -0,0 +1,108 @@ +#****************************************************************************** +# +# Makefile - Rules for building the Data logger quickstart example. +# +# 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. +# +#****************************************************************************** + +# +# Defines the part type that this project uses. +# +PART=TM4C123GH6PGE + +# +# The base directory for TivaWare. +# +ROOT=../../../.. + +# +# Include the common make definitions. +# +include ${ROOT}/makedefs + +# +# Where to find source files that do not live in this directory. +# +VPATH=../drivers +VPATH+=../../../../third_party/fatfs/port +VPATH+=../../../../third_party/fatfs/src +VPATH+=../../../../utils + +# +# Where to find header files that do not live in the source directory. +# +IPATH=.. +IPATH+=../../../.. +IPATH+=../../../../third_party + +# +# The default rule, which causes the Data logger quickstart example to be built. +# +all: ${COMPILER} +all: ${COMPILER}/qs-logger.axf + +# +# The rule to clean out all the build products. +# +clean: + @rm -rf ${COMPILER} ${wildcard *~} + +# +# The rule to create the target directory. +# +${COMPILER}: + @mkdir -p ${COMPILER} + +# +# Rules for building the Data logger quickstart example. +# +${COMPILER}/qs-logger.axf: ${COMPILER}/acquire.o +${COMPILER}/qs-logger.axf: ${COMPILER}/buttons.o +${COMPILER}/qs-logger.axf: ${COMPILER}/cfal96x64x16.o +${COMPILER}/qs-logger.axf: ${COMPILER}/clocksetwidget.o +${COMPILER}/qs-logger.axf: ${COMPILER}/fat_usbmsc.o +${COMPILER}/qs-logger.axf: ${COMPILER}/ff.o +${COMPILER}/qs-logger.axf: ${COMPILER}/flashstore.o +${COMPILER}/qs-logger.axf: ${COMPILER}/images.o +${COMPILER}/qs-logger.axf: ${COMPILER}/menus.o +${COMPILER}/qs-logger.axf: ${COMPILER}/qs-logger.o +${COMPILER}/qs-logger.axf: ${COMPILER}/slidemenuwidget.o +${COMPILER}/qs-logger.axf: ${COMPILER}/startup_${COMPILER}.o +${COMPILER}/qs-logger.axf: ${COMPILER}/stripchartmanager.o +${COMPILER}/qs-logger.axf: ${COMPILER}/stripchartwidget.o +${COMPILER}/qs-logger.axf: ${COMPILER}/uartstdio.o +${COMPILER}/qs-logger.axf: ${COMPILER}/usb_serial_structs.o +${COMPILER}/qs-logger.axf: ${COMPILER}/usbserial.o +${COMPILER}/qs-logger.axf: ${COMPILER}/usbstick.o +${COMPILER}/qs-logger.axf: ${COMPILER}/ustdlib.o +${COMPILER}/qs-logger.axf: ${ROOT}/usblib/${COMPILER}/libusb.a +${COMPILER}/qs-logger.axf: ${ROOT}/grlib/${COMPILER}/libgr.a +${COMPILER}/qs-logger.axf: ${ROOT}/driverlib/${COMPILER}/libdriver.a +${COMPILER}/qs-logger.axf: qs-logger.ld +SCATTERgcc_qs-logger=qs-logger.ld +ENTRY_qs-logger=ResetISR +CFLAGSgcc=-DTARGET_IS_TM4C123_RA1 + +# +# Include the automatically generated dependency files. +# +ifneq (${MAKECMDGOALS},clean) +-include ${wildcard ${COMPILER}/*.d} __dummy__ +endif diff --git a/boards/ek-lm4f232/qs-logger/acquire.c b/boards/ek-lm4f232/qs-logger/acquire.c new file mode 100644 index 0000000..52b530f --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/acquire.c @@ -0,0 +1,965 @@ +//***************************************************************************** +// +// acquire.c - Data acquisition module for data logger application. +// +// 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 +#include +#include +#include +#include "driverlib/debug.h" +#include "driverlib/adc.h" +#include "driverlib/gpio.h" +#include "driverlib/hibernate.h" +#include "driverlib/interrupt.h" +#include "driverlib/rom_map.h" +#include "driverlib/sysctl.h" +#include "grlib/grlib.h" +#include "grlib/widget.h" +#include "grlib/canvas.h" +#include "inc/hw_types.h" +#include "inc/hw_memmap.h" +#include "inc/hw_ints.h" +#include "inc/hw_gpio.h" +#include "utils/ustdlib.h" +#include "drivers/slidemenuwidget.h" +#include "drivers/stripchartwidget.h" +#include "stripchartmanager.h" +#include "clocksetwidget.h" +#include "qs-logger.h" +#include "usbstick.h" +#include "usbserial.h" +#include "flashstore.h" +#include "menus.h" +#include "acquire.h" + +//***************************************************************************** +// +// This is the data acquisition module. It performs acquisition of data from +// selected channels, starting and stopping data logging, storing acquired +// data, and running the strip chart display. +// +//***************************************************************************** + +//***************************************************************************** +// +// The following defines which ADC channel control should be used for each +// kind of data item. Basically it maps how the ADC channels are connected +// on the board. This is a hardware configuration. +// +//***************************************************************************** +#define CHAN_USER0 ADC_CTL_CH0 +#define CHAN_USER1 ADC_CTL_CH1 +#define CHAN_USER2 ADC_CTL_CH2 +#define CHAN_USER3 ADC_CTL_CH3 +#define CHAN_ACCELX ADC_CTL_CH8 +#define CHAN_ACCELY ADC_CTL_CH9 +#define CHAN_ACCELZ ADC_CTL_CH21 +#define CHAN_EXTTEMP ADC_CTL_CH20 +#define CHAN_CURRENT ADC_CTL_CH23 +#define CHAN_INTTEMP ADC_CTL_TS + +//***************************************************************************** +// +// The following maps the order that items are acquired and stored by the +// ADC sequencers. Note that 16 samples are specified, using 2 of the +// 8 sample sequencers. The current is sampled multiple times deliberately +// because that value tends to bounce around. It is sampled multiple +// times and will be averaged. +// +//***************************************************************************** +uint32_t g_pui32ADCSeq[] = +{ + CHAN_USER0, CHAN_USER1, CHAN_USER2, CHAN_USER3, CHAN_ACCELX, CHAN_ACCELY, + CHAN_ACCELZ, CHAN_EXTTEMP, CHAN_INTTEMP, CHAN_CURRENT, CHAN_CURRENT, + CHAN_CURRENT, CHAN_CURRENT, CHAN_CURRENT, CHAN_CURRENT, CHAN_CURRENT, +}; +#define NUM_ADC_CHANNELS (sizeof(g_pui32ADCSeq) / \ + sizeof(g_pui32ADCSeq[0])) +#define NUM_CURRENT_SAMPLES 7 + +//***************************************************************************** +// +// A buffer to hold one set of ADC data that is acquired per sample time. +// +//***************************************************************************** +static uint32_t g_pui32ADCData[NUM_ADC_CHANNELS]; + +//***************************************************************************** +// +// The following variables hold the current time stamp, the next match time +// for sampling, and the period of time between samples. All are stored in +// a 32.15 second.subsecond format. +// +//***************************************************************************** +static volatile uint32_t g_pui32TimeStamp[2]; +static volatile uint32_t g_pui32NextMatch[2]; +static uint32_t g_pui32MatchPeriod[2]; + +//***************************************************************************** +// +// The number of data items that are selected for acquisition. +// +//***************************************************************************** +static uint32_t g_ui32NumItems; + +//***************************************************************************** +// +// A counter for the ADC interrupt handler. It is used to track when new +// ADC data is acquired. +// +//***************************************************************************** +static volatile uint32_t g_ui32ADCCount; +static uint32_t g_ui32LastADCCount = 0; + +//***************************************************************************** +// +// A counter for the RTC interrupt handler. +// +//***************************************************************************** +static volatile uint32_t g_pui32RTCInts; + +//***************************************************************************** +// +// A flag to indicate that a keep alive packet is needed (when logging to host +// PC). +// +//***************************************************************************** +static volatile bool g_bNeedKeepAlive = false; + +//***************************************************************************** +// +// Storage for a single record of acquired data. This needs to be large +// enough to hold the time stamp and item mask (defined in the structure +// above) and as many possible data items that can be collected. Force the +// buffer to be a multiple of 32-bits. +// +//***************************************************************************** +#define RECORD_SIZE (sizeof(tLogRecord) + (NUM_LOG_ITEMS * 2)) +static union +{ + uint32_t g_pui32RecordBuf[(RECORD_SIZE + 3) / sizeof(uint32_t)]; + tLogRecord sRecord; +} +g_sRecordBuf; + +//***************************************************************************** +// +// Holds a pointer to the current configuration state, that is determined by +// the user's menu selections. +// +//***************************************************************************** +static tConfigState *g_psConfigState; + +//***************************************************************************** +// +// This function is called when in VIEW mode. The acquired data is written +// as text strings which will appear on the eval board display. +// +//***************************************************************************** +static void +UpdateViewerData(const tLogRecord *psRecord) +{ + static char pcViewerBuf[24]; + uint32_t ui32Idx, pui32RTC; + struct tm sTime; + + // + // Loop through the analog channels and update the text display strings. + // + for(ui32Idx = LOG_ITEM_USER0; ui32Idx <= LOG_ITEM_USER3; ui32Idx++) + { + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), " CH%u: %u.%03u V ", + ui32Idx - LOG_ITEM_USER0, psRecord->pi16Items[ui32Idx] / 1000, + psRecord->pi16Items[ui32Idx] % 1000); + MenuUpdateText(ui32Idx, pcViewerBuf); + } + + // + // Loop through the accel channels and update the text display strings. + // + for(ui32Idx = LOG_ITEM_ACCELX; ui32Idx <= LOG_ITEM_ACCELZ; ui32Idx++) + { + int16_t i16Accel = psRecord->pi16Items[ui32Idx]; + i16Accel *= (i16Accel < 0) ? -1 : 1; + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), " %c: %c%d.%02u g ", + (ui32Idx - LOG_ITEM_ACCELX) + 'X', + psRecord->pi16Items[ui32Idx] < 0 ? '-' : '+', + i16Accel / 100, i16Accel % 100); + MenuUpdateText(ui32Idx, pcViewerBuf); + } + + // + // Update the display string for internal temperature. + // + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), " INT: %d.%01u C ", + psRecord->pi16Items[LOG_ITEM_INTTEMP] / 10, + psRecord->pi16Items[LOG_ITEM_INTTEMP] % 10); + MenuUpdateText(LOG_ITEM_INTTEMP, pcViewerBuf); + + // + // Update the display string for external temperature. + // + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), " EXT: %d.%01u C ", + psRecord->pi16Items[LOG_ITEM_EXTTEMP] / 10, + psRecord->pi16Items[LOG_ITEM_EXTTEMP] % 10); + MenuUpdateText(LOG_ITEM_EXTTEMP, pcViewerBuf); + + // + // Update the display string for processor current. + // + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), " %u.%01u mA ", + psRecord->pi16Items[LOG_ITEM_CURRENT] / 10, + psRecord->pi16Items[LOG_ITEM_CURRENT] % 10); + MenuUpdateText(LOG_ITEM_CURRENT, pcViewerBuf); + + // + // Update the display strings for time and data. + // + pui32RTC = HibernateRTCGet(); + ulocaltime(pui32RTC, &sTime); + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), "%4u/%02u/%02u", + sTime.tm_year+1900, sTime.tm_mon + 1, sTime.tm_mday); + MenuUpdateText(TEXT_ITEM_DATE, pcViewerBuf); + usnprintf(pcViewerBuf, sizeof(pcViewerBuf), "%02u:%02u:%02u", + sTime.tm_hour, sTime.tm_min, sTime.tm_sec); + MenuUpdateText(TEXT_ITEM_TIME, pcViewerBuf); +} + +//***************************************************************************** +// +// This function is called from the AcquireRun() function and should be in +// context of the main thread. It pulls data items from the ADC data buffer, +// converts units as needed, and stores the results in a log record that is +// pointed at by the function parameter. +// +//***************************************************************************** +static void +ProcessDataItems(tLogRecord *psRecord) +{ + int32_t i32Accel, i32TempC; + uint32_t ui32SelectedMask, ui32Millivolts, ui32Current; + uint_fast8_t ui8Idx, ui8ItemIdx; + + + // + // Initialize locals. + // + ui8ItemIdx = 0; + ui32SelectedMask = g_psConfigState->ui16SelectedMask; + ui32Current = 0; + + // + // Save the time stamp that was saved when the ADC data was acquired. + // Also save into the record the bit mask of the selected data items. + // + psRecord->ui32Seconds = g_pui32TimeStamp[0]; + psRecord->ui16Subseconds = (uint16_t)g_pui32TimeStamp[1]; + psRecord->ui16ItemMask = (uint16_t)ui32SelectedMask; + + // + // Process the user analog input channels. These will be converted and + // stored as millivolts. + // + for(ui8Idx = LOG_ITEM_USER0; ui8Idx <= LOG_ITEM_USER3; ui8Idx++) + { + // + // Check to see if this item should be logged + // + if((1 << ui8Idx) & ui32SelectedMask) + { + ui32Millivolts = (g_pui32ADCData[ui8Idx] * 4100) / 819; + psRecord->pi16Items[ui8ItemIdx++] = (int16_t)ui32Millivolts; + } + } + + // + // Process the accelerometers. These will be processed and stored in + // units of 1/100 g. + // + for(ui8Idx = LOG_ITEM_ACCELX; ui8Idx <= LOG_ITEM_ACCELZ; ui8Idx++) + { + // + // Check to see if this item should be logged + // + if((1 << ui8Idx) & ui32SelectedMask) + { + i32Accel = (((int32_t)g_pui32ADCData[ui8Idx] - 2047L) * 1000L) / + 4095L; + psRecord->pi16Items[ui8ItemIdx++] = (int16_t)i32Accel; + } + } + + // + // Process the external temperature. The temperature is stored in units + // of 1/10 C. + // + if((1 << LOG_ITEM_EXTTEMP) & ui32SelectedMask) + { + i32TempC = (1866300 - ((200000 * g_pui32ADCData[LOG_ITEM_EXTTEMP]) / + 273)) / 1169; + psRecord->pi16Items[ui8ItemIdx++] = (int16_t)i32TempC; + } + + // + // Process the internal temperature. The temperature is stored in units + // of 1/10 C. + // + if((1 << LOG_ITEM_INTTEMP) & ui32SelectedMask) + { + i32TempC = 1475 - ((2250 * g_pui32ADCData[LOG_ITEM_INTTEMP]) / 4095); + psRecord->pi16Items[ui8ItemIdx++] = (int16_t)i32TempC; + } + + // + // Process the current. The current is stored in units of 100 uA, + // (or 1/10000 A). Multiple current samples were taken in order + // to average and smooth the data. + // + if((1 << LOG_ITEM_CURRENT) & ui32SelectedMask) + { + // + // Average all the current samples that are available in the ADC + // buffer. + // + for(ui8Idx = LOG_ITEM_CURRENT; + ui8Idx < (LOG_ITEM_CURRENT + NUM_CURRENT_SAMPLES); ui8Idx++) + { + ui32Current += g_pui32ADCData[ui8Idx]; + } + ui32Current /= NUM_CURRENT_SAMPLES; + + // + // Convert the averaged current into units + // + ui32Current = (ui32Current * 200) / 273; + psRecord->pi16Items[ui8ItemIdx++] = (int16_t)ui32Current; + } +} + +//***************************************************************************** +// +// This is the handler for the ADC interrupt. Even though more than one +// sequencer is used, they are configured so that this one runs last. +// Therefore when this ADC sequencer interrupt occurs, we know all of the ADC +// data has been acquired. +// +//***************************************************************************** +void +ADC0SS0Handler(void) +{ + // + // Clear the interrupts for all ADC sequencers that are used. + // + MAP_ADCIntClear(ADC0_BASE, 0); + MAP_ADCIntClear(ADC1_BASE, 0); + + // + // Retrieve the data from all ADC sequencers + // + MAP_ADCSequenceDataGet(ADC0_BASE, 0, &g_pui32ADCData[0]); + MAP_ADCSequenceDataGet(ADC1_BASE, 0, &g_pui32ADCData[8]); + + // + // Set the time stamp, assume it is what was set for the last match + // value. This will be close to the actual time that the samples were + // acquired, within a few microseconds. + // + g_pui32TimeStamp[0] = g_pui32NextMatch[0]; + g_pui32TimeStamp[1] = g_pui32NextMatch[1]; + + // + // Increment the ADC interrupt count + // + g_ui32ADCCount++; +} + +//***************************************************************************** +// +// This is the handler for the RTC interrupt from the hibernate peripheral. +// It occurs on RTC match. This handler will initiate an ADC acquisition, +// which will run all of the ADC sequencers. Then it computes the next +// match value and sets it in the RTC. +// +//***************************************************************************** +void +RTCHandler(void) +{ + uint32_t ui32Status, ui32Seconds; + + // + // Increment RTC interrupt counter + // + g_pui32RTCInts++; + + // + // Clear the RTC interrupts (this can be slow for hib module) + // + ui32Status = HibernateIntStatus(1); + HibernateIntClear(ui32Status); + + // + // Read and save the current value of the seconds counter. + // + ui32Seconds = HibernateRTCGet(); + + // + // If we are sleep logging, then there will be no remembered value for + // the next match value, which is also used as the time stamp when + // data is collected. In this case we will just use the current + // RTC seconds. This is safe because if sleep-logging is used, it + // is only with periods of whole seconds, 1 second or longer. + // + if(g_psConfigState->ui32SleepLogging) + { + g_pui32NextMatch[0] = ui32Seconds; + g_pui32NextMatch[1] = 0; + } + + // + // If we are logging data to PC and using a period greater than one + // second, then use special handling. For PC logging, if no data is + // collected, then we must send a keep-alive packet once per second. + // + if((g_psConfigState->ui8Storage == CONFIG_STORAGE_HOSTPC) && + (g_pui32MatchPeriod[0] > 1)) + { + // + // If the current seconds count is less than the match value, that + // means we got the interrupt due to one-second keep alive for the + // host PC. + // + if(ui32Seconds < g_pui32NextMatch[0]) + { + // + // Set the next match for one second ahead (next keep-alive) + // + HibernateRTCMatchSet(0, ui32Seconds + 1); + + // + // Set flag to indicate that a keep alive packet is needed + // + g_bNeedKeepAlive = true; + + // + // Nothing else to do except wait for next keep alive or match + // + return; + } + + // + // Else, this is a real match so proceed to below to do a normal + // acquisition. + // + } + + // + // Kick off the next ADC acquisition. When these are done they will + // cause an ADC interrupt. + // + MAP_ADCProcessorTrigger(ADC1_BASE, 0); + MAP_ADCProcessorTrigger(ADC0_BASE, 0); + + // + // Set the next RTC match. Add the match period to the previous match + // value. We are making an assumption here that there is enough time from + // when the match interrupt occurred, to this point in the code, that we + // are still setting the match time in the future. If the period is too + // long, then we could miss a match and never get another RTC interrupt. + // + g_pui32NextMatch[0] += g_pui32MatchPeriod[0]; + g_pui32NextMatch[1] += g_pui32MatchPeriod[1]; + if(g_pui32NextMatch[1] > 32767) + { + // + // Handle subseconds rollover + // + g_pui32NextMatch[1] &= 32767; + g_pui32NextMatch[0]++; + } + + // + // If logging to host PC at greater than 1 second period, then set the + // next RTC wakeup for 1 second from now. This will cause a keep alive + // packet to be sent to the PC + // + if((g_psConfigState->ui8Storage == CONFIG_STORAGE_HOSTPC) && + (g_pui32MatchPeriod[0] > 1)) + { + HibernateRTCMatchSet(0, ui32Seconds + 1); + } + else + { + // + // Otherwise this is a normal match and the next match should also be a + // normal match, so set the next wakeup to the calculated match time. + // + HibernateRTCMatchSet(0, g_pui32NextMatch[0]); + HibernateRTCSSMatchSet(0, g_pui32NextMatch[1]); + } + + // + // Toggle the LED on the board so the user can see that the acquisition + // is running. + // + MAP_GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, + ~MAP_GPIOPinRead(GPIO_PORTG_BASE, GPIO_PIN_2)); + + // + // Now exit the int handler. The ADC will trigger an interrupt when + // it is finished, and the RTC is set up for the next match. + // +} + +//***************************************************************************** +// +// This function is called from the application main loop to keep the +// acquisition running. It checks to see if there is any new ADC data, and +// if so it processes the new ADC data. +// +// The function returns non-zero if data was acquired, 0 if no data was +// acquired. +// +//***************************************************************************** +int32_t +AcquireRun(void) +{ + tLogRecord *psRecord = &g_sRecordBuf.sRecord; + + // + // Make sure we are properly configured to run + // + if(!g_psConfigState) + { + return(0); + } + + // + // Check to see if new ADC data is available + // + if(g_ui32ADCCount != g_ui32LastADCCount) + { + g_ui32LastADCCount = g_ui32ADCCount; + + // + // Process the ADC data and store it in the record buffer. + // + ProcessDataItems(psRecord); + + // + // Add the newly processed data to the strip chart. Do not add to + // strip start if sleep-logging. + // + if((g_psConfigState->ui8Storage != CONFIG_STORAGE_VIEWER) && + !g_psConfigState->ui32SleepLogging) + { + StripChartMgrAddItems(psRecord->pi16Items); + } + + // + // If USB stick is used, write the record to the USB stick + // + if(g_psConfigState->ui8Storage == CONFIG_STORAGE_USB) + { + USBStickWriteRecord(psRecord); + } + + // + // If host PC is used, write data to USB serial port + // + if(g_psConfigState->ui8Storage == CONFIG_STORAGE_HOSTPC) + { + USBSerialWriteRecord(psRecord); + } + + // + // If flash storage is used, write data to the flash + // + if(g_psConfigState->ui8Storage == CONFIG_STORAGE_FLASH) + { + FlashStoreWriteRecord(psRecord); + + // + // If we are sleep logging, then save the storage address for + // use in the next cycle. + // + if(g_psConfigState->ui32SleepLogging) + { + g_psConfigState->ui32FlashStore = FlashStoreGetAddr(); + } + } + else if(g_psConfigState->ui8Storage == CONFIG_STORAGE_VIEWER) + { + // + // If in viewer mode, then update the viewer text strings. + // + UpdateViewerData(psRecord); + } + + // + // Return indication to caller that data was processed. + // + return(1); + } + else if((g_psConfigState->ui8Storage == CONFIG_STORAGE_HOSTPC) && + (g_bNeedKeepAlive == true)) + { + // + // Else there is no new data to process, but check to see if we are + // logging to PC and a keep alive packet is needed. + // + // Clear keep-alive needed flag + // + g_bNeedKeepAlive = false; + + // + // Make a keep alive packet by creating a record with timestamp of 0. + // + psRecord->ui32Seconds = 0; + psRecord->ui16Subseconds = 0; + psRecord->ui16ItemMask = 0; + + // + // Transmit the dummy record to host PC. + // + USBSerialWriteRecord(psRecord); + } + + // + // Return indication that data was not processed. + // + return(0); +} + +//***************************************************************************** +// +// This function is called to start an acquisition running. It determines +// which channels are to be logged, enables the ADC sequencers, and computes +// the first RTC match value. This will start the acquisition running. +// +//***************************************************************************** +void +AcquireStart(tConfigState *psConfig) +{ + uint32_t ui32Idx, pui32RTC[2], ui32SelectedMask; + + // + // Check the parameters + // + ASSERT(psConfig); + if(!psConfig) + { + return; + } + + // + // Update the config state pointer, save the selected item mask + // + g_psConfigState = psConfig; + ui32SelectedMask = psConfig->ui16SelectedMask; + + // + // Get the logging period from the logger configuration. Split the + // period into seconds and subseconds pieces and save for later use in + // generating RTC match values. + // + g_pui32MatchPeriod[0] = psConfig->ui32Period >> 8; + g_pui32MatchPeriod[1] = (psConfig->ui32Period & 0xFF) << 8; + + // + // Determine how many channels are to be logged + // + ui32Idx = ui32SelectedMask; + g_ui32NumItems = 0; + while(ui32Idx) + { + if(ui32Idx & 1) + { + g_ui32NumItems++; + } + ui32Idx >>= 1; + } + + // + // Initialize the strip chart manager for a new run. Don't bother with + // the strip chart if we are using viewer mode, or sleep-logging. + // + if((psConfig->ui8Storage != CONFIG_STORAGE_VIEWER) && + !psConfig->ui32SleepLogging) + { + StripChartMgrInit(); + StripChartMgrConfigure(ui32SelectedMask); + } + + // + // Configure USB for memory stick if USB storage is chosen + // + if(psConfig->ui8Storage == CONFIG_STORAGE_USB) + { + USBStickOpenLogFile(0); + } + else if(psConfig->ui8Storage == CONFIG_STORAGE_FLASH) + { + + // + // Flash storage is to be used, prepare the flash storage module. + // If already sleep-logging, then pass in the saved flash address + // so it does not need to be searched. + // + if(psConfig->ui32SleepLogging) + { + FlashStoreOpenLogFile(psConfig->ui32FlashStore); + } + else + { + // + // Otherwise not sleep logging, so just initialize the flash store, + // this will cause it to search for the starting storage address. + // + FlashStoreOpenLogFile(0); + } + } + + // + // Enable the ADC sequencers + // + MAP_ADCSequenceEnable(ADC0_BASE, 0); + MAP_ADCSequenceEnable(ADC1_BASE, 0); + + // + // Flush the ADC sequencers to be sure there is no lingering data. + // + MAP_ADCSequenceDataGet(ADC0_BASE, 0, g_pui32ADCData); + MAP_ADCSequenceDataGet(ADC1_BASE, 0, g_pui32ADCData); + + // + // Enable ADC interrupts + // + MAP_ADCIntClear(ADC0_BASE, 0); + MAP_ADCIntClear(ADC1_BASE, 0); + MAP_ADCIntEnable(ADC0_BASE, 0); + MAP_IntEnable(INT_ADC0SS0); + + // + // If we are not already sleep-logging, then initialize the RTC match. + // If we are sleep logging then this does not need to be set up. + // + if(!psConfig->ui32SleepLogging) + { + // + // Get the current RTC value + // + do + { + pui32RTC[0] = HibernateRTCGet(); + pui32RTC[1] = HibernateRTCSSGet(); + } + while(pui32RTC[0] != HibernateRTCGet()); + + // + // Set an initial next match value. Start with the subseconds always + // 0 so the first match value will always be an even multiple of the + // subsecond match. Add 2 seconds to the current RTC just to be clear + // of an imminent rollover. This means that the first match will occur + // between 1 and 2 seconds from now. + // + g_pui32NextMatch[0] = pui32RTC[0] + 2; + g_pui32NextMatch[1] = 0; + + // + // Now set the match value + // + HibernateRTCMatchSet(0, g_pui32NextMatch[0]); + HibernateRTCSSMatchSet(0, g_pui32NextMatch[1]); + } + + // + // If we are configured to sleep, but not sleeping yet, then enter sleep + // logging mode if allowed. + // + if(psConfig->bSleep && !psConfig->ui32SleepLogging) + { + // + // Allow sleep logging if storing to flash at a period of 1 second + // or greater. + // + if((psConfig->ui8Storage == CONFIG_STORAGE_FLASH) && + (psConfig->ui32Period >= 0x100)) + { + psConfig->ui32SleepLogging = 1; + } + } + + // + // Enable the RTC interrupts from the hibernate module + // + HibernateIntClear(HibernateIntStatus(0)); + HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0 | HIBERNATE_INT_PIN_WAKE); + MAP_IntEnable(INT_HIBERNATE); + + // + // Logging data should now start running + // +} + +//***************************************************************************** +// +// This function is called to stop an acquisition running. It disables the +// ADC sequencers and the RTC match interrupt. +// +//***************************************************************************** +void +AcquireStop(void) +{ + // + // Disable RTC interrupts + // + MAP_IntDisable(INT_HIBERNATE); + + // + // Disable ADC interrupts + // + MAP_IntDisable(INT_ADC0SS0); + MAP_IntDisable(INT_ADC1SS0); + + // + // Disable ADC sequencers + // + MAP_ADCSequenceDisable(ADC0_BASE, 0); + MAP_ADCSequenceDisable(ADC1_BASE, 0); + + // + // If USB stick is being used, then close the file so it will flush + // the buffers to the USB stick. + // + if(g_psConfigState->ui8Storage == CONFIG_STORAGE_USB) + { + USBStickCloseFile(); + } + + // + // Disable the configuration pointer, which acts as a flag to indicate + // if we are properly configured for data acquisition. + // + g_psConfigState = 0; +} + +//***************************************************************************** +// +// This function initializes the ADC hardware in preparation for data +// acquisition. +// +//***************************************************************************** +void +AcquireInit(void) +{ + uint32_t ui32Chan, ui32Base, ui32Seq, ui32ChCtl; + + + // + // Enable the ADC peripherals and the associated GPIO port + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1); + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); + + // + // Enabled LED GPIO + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); + MAP_GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE, GPIO_PIN_2); + + // + // Configure the pins to be used as analog inputs. + // + MAP_GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | + GPIO_PIN_7 | GPIO_PIN_3); + MAP_GPIOPinTypeADC(GPIO_PORTP_BASE, GPIO_PIN_0); + + // + // Select the external reference for greatest accuracy. + // + MAP_ADCReferenceSet(ADC0_BASE, ADC_REF_EXT_3V); + MAP_ADCReferenceSet(ADC1_BASE, ADC_REF_EXT_3V); + + // + // Apply workaround for erratum 6.1, in order to use the + // external reference. + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + HWREG(GPIO_PORTB_BASE + GPIO_O_AMSEL) |= GPIO_PIN_6; + + // + // Initialize both ADC peripherals using sequencer 0 and processor trigger. + // + MAP_ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0); + MAP_ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_PROCESSOR, 0); + + // + // Enter loop to configure all of the ADC sequencer steps needed to + // acquire the data for the data logger. Multiple ADC and sequencers + // will be used in order to acquire all the channels. + // + for(ui32Chan = 0; ui32Chan < NUM_ADC_CHANNELS; ui32Chan++) + { + // + // If this is the first ADC then set the base for ADC0 + // + if(ui32Chan < 8) + { + ui32Base = ADC0_BASE; + ui32Seq = 0; + } + else if(ui32Chan < 16) + { + // + // Second ADC, set the base for ADC1 + // + ui32Base = ADC1_BASE; + ui32Seq = 0; + } + + // + // Get the channel control for each channel. Test to see if it is the + // last channel for the sequencer, and if so then also set the + // interrupt and "end" flags. + // + ui32ChCtl = g_pui32ADCSeq[ui32Chan]; + if((ui32Chan == 7) || (ui32Chan == 15) || + (ui32Chan == (NUM_ADC_CHANNELS - 1))) + { + ui32ChCtl |= ADC_CTL_IE | ADC_CTL_END; + } + + // + // Configure the sequence step + // + MAP_ADCSequenceStepConfigure(ui32Base, ui32Seq, ui32Chan % 8, + ui32ChCtl); + } + + // + // Erase the configuration in case there was a prior configuration. + // + g_psConfigState = 0; +} diff --git a/boards/ek-lm4f232/qs-logger/acquire.h b/boards/ek-lm4f232/qs-logger/acquire.h new file mode 100644 index 0000000..7a96936 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/acquire.h @@ -0,0 +1,57 @@ +//***************************************************************************** +// +// acquire.h - Prototypes and definitions for data acquisition module. +// +// 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. +// +//***************************************************************************** +#ifndef __ACQUIRE_H__ +#define __ACQUIRE_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Module function prototypes. +// +//***************************************************************************** +extern void AcquireInit(void); +extern void AcquireStart(tConfigState *psConfig); +extern void AcquireStop(void); +extern int32_t AcquireRun(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif diff --git a/boards/ek-lm4f232/qs-logger/ccs/.ccsimportspec b/boards/ek-lm4f232/qs-logger/ccs/.ccsimportspec new file mode 100644 index 0000000..4afea22 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/.ccsimportspec @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/boards/ek-lm4f232/qs-logger/ccs/.ccsproject b/boards/ek-lm4f232/qs-logger/ccs/.ccsproject new file mode 100644 index 0000000..e423367 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/.ccsproject @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/boards/ek-lm4f232/qs-logger/ccs/.cproject b/boards/ek-lm4f232/qs-logger/ccs/.cproject new file mode 100644 index 0000000..c94b602 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/.cproject @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/boards/ek-lm4f232/qs-logger/ccs/.project b/boards/ek-lm4f232/qs-logger/ccs/.project new file mode 100644 index 0000000..9fe61a4 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/.project @@ -0,0 +1,135 @@ + + + qs-logger + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + acquire.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/acquire.c + + + clocksetwidget.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/clocksetwidget.c + + + flashstore.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/flashstore.c + + + images.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/images.c + + + menus.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/menus.c + + + qs-logger.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/qs-logger.c + + + qs-logger_ccs.cmd + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/qs-logger_ccs.cmd + + + startup_ccs.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/startup_ccs.c + + + stripchartmanager.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/stripchartmanager.c + + + usb_serial_structs.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/usb_serial_structs.c + + + usbserial.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/usbserial.c + + + usbstick.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/qs-logger/usbstick.c + + + drivers/buttons.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/drivers/buttons.c + + + drivers/cfal96x64x16.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/drivers/cfal96x64x16.c + + + drivers/slidemenuwidget.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/drivers/slidemenuwidget.c + + + drivers/stripchartwidget.c + 1 + SW_ROOT/examples/boards/ek-lm4f232/drivers/stripchartwidget.c + + + utils/uartstdio.c + 1 + SW_ROOT/utils/uartstdio.c + + + utils/ustdlib.c + 1 + SW_ROOT/utils/ustdlib.c + + + third_party/fatfs/port/fat_usbmsc.c + 1 + SW_ROOT/third_party/fatfs/port/fat_usbmsc.c + + + third_party/fatfs/src/ff.c + 1 + SW_ROOT/third_party/fatfs/src/ff.c + + + + + SW_ROOT + $%7BPARENT-5-PROJECT_LOC%7D + + + diff --git a/boards/ek-lm4f232/qs-logger/ccs/.settings/org.eclipse.cdt.codan.core.prefs b/boards/ek-lm4f232/qs-logger/ccs/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000..98b6350 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +inEditor=false +onBuild=false diff --git a/boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.bin b/boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.bin new file mode 100644 index 0000000..1b33316 Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.bin differ diff --git a/boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.out b/boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.out new file mode 100644 index 0000000..51e150b Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/ccs/Debug/qs-logger.out differ diff --git a/boards/ek-lm4f232/qs-logger/ccs/macros.ini_initial b/boards/ek-lm4f232/qs-logger/ccs/macros.ini_initial new file mode 100644 index 0000000..31214b5 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/macros.ini_initial @@ -0,0 +1 @@ +SW_ROOT = ../../../../.. diff --git a/boards/ek-lm4f232/qs-logger/ccs/target_config.ccxml b/boards/ek-lm4f232/qs-logger/ccs/target_config.ccxml new file mode 100644 index 0000000..c8d43ba --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/ccs/target_config.ccxml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/boards/ek-lm4f232/qs-logger/clocksetwidget.c b/boards/ek-lm4f232/qs-logger/clocksetwidget.c new file mode 100644 index 0000000..449ee55 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/clocksetwidget.c @@ -0,0 +1,1031 @@ +//***************************************************************************** +// +// clocksetwidget.c - A widget for setting clock date/time. +// +// 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 +#include +#include "inc/hw_types.h" +#include "driverlib/debug.h" +#include "utils/uartstdio.h" +#include "grlib/grlib.h" +#include "grlib/widget.h" +#include "utils/ustdlib.h" +#include "clocksetwidget.h" + +//***************************************************************************** +// +//! \addtogroup clocksetwidget_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// This is a custom widget for setting the date/time of a clock. The widget +// will display the year, month, day, hour and minute on the display. The +// user can highlight the fields with the left/right keys, and can change the +// value of each with the up/down keys. When finished the user highlights +// the OK field on the screen and presses the select button. +// +//***************************************************************************** + +//***************************************************************************** +// +// Define indices for each of the fields used for date and time. +// +//***************************************************************************** +#define FIELD_YEAR 0 +#define FIELD_MONTH 1 +#define FIELD_DAY 2 +#define FIELD_HOUR 3 +#define FIELD_MINUTE 4 +#define FIELD_OK 5 +#define FIELD_CANCEL 6 +#define FIELD_LAST 6 +#define NUM_FIELDS 7 + +//***************************************************************************** +// +//! 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); + } +} + +//***************************************************************************** +// +//! Determine the number of days in a month. +//! +//! \param tm_mon is the month number to use for determining the number of +//! days. The month begins with 0 meaning January and 11 meaning December. +//! +//! This function returns the highest day number for the specified month. +//! It does not account for leap year, so February always returns 28 days. +//! +//! \return Returns the highest day number for the month. +// +//***************************************************************************** +static uint8_t +MaxDayOfMonth(uint8_t tm_mon) +{ + // + // Process the month + // + switch(tm_mon) + { + // + // February returns 28 days + // + case 1: + { + return(28); + } + + // + // April, June, September and November return 30 + // + case 3: + case 5: + case 8: + case 10: + { + return(30); + } + + // + // Remaining months have 31 days. + // + default: + { + return(31); + } + } +} + +//***************************************************************************** +// +//! Handle the UP button event. +//! +//! \param psWidget is a pointer to the clock setting widget on which to +//! operate. +//! +//! This function handles the event when the user has pressed the up button. +//! It will increment the currently highlighted date/time field if it is not +//! already at the maximum value. If the month or day of the month is being +//! changed then it enforces the maximum number of days for the month. +//! +//! \return Returns non-zero if the button event was handled, and 0 if the +//! button event was not handled. +// +//***************************************************************************** +static int32_t +ClockSetKeyUp(tClockSetWidget *psWidget) +{ + // + // Get pointer to the time structure to be modified. + // + struct tm *psTime = psWidget->psTime; + + // + // Determine which field is highlighted. + // + switch(psWidget->ui32Highlight) + { + // + // Increment the year. Cap it at 2037 to keep things simple. + // + case FIELD_YEAR: + { + if(psTime->tm_year+1900 < 2037) + { + psTime->tm_year++; + } + break; + } + + // + // Increment the month. Adjust the day of the month if needed. + // + case FIELD_MONTH: + { + if(psTime->tm_mon < 11) + { + psTime->tm_mon++; + } + if(psTime->tm_mday > MaxDayOfMonth(psTime->tm_mon)) + { + psTime->tm_mday = MaxDayOfMonth(psTime->tm_mon); + } + break; + } + + // + // Increment the day. Cap it at the max number of days for the + // current value of month. + // + case FIELD_DAY: + { + if(psTime->tm_mday < MaxDayOfMonth(psTime->tm_mon)) + { + psTime->tm_mday++; + } + break; + } + + // + // Increment the hour. + // + case FIELD_HOUR: + { + if(psTime->tm_hour < 23) + { + psTime->tm_hour++; + } + break; + } + + // + // Increment the minute. + // + case FIELD_MINUTE: + { + if(psTime->tm_min < 59) + { + psTime->tm_min++; + } + break; + } + + // + // Bad value for field index - ignore. + // + default: + { + break; + } + } + + // + // Since something may have been changed in the clock value, request + // a repaint of the widget. + // + WidgetPaint(&psWidget->sBase); + + // + // Return indication that the button event was handled. + // + return(1); +} + +//***************************************************************************** +// +//! Handle the DOWN button event. +//! +//! \param psWidget is a pointer to the clock setting widget on which to +//! operate. +//! +//! This function handles the event when the user has pressed the down button. +//! It will decrement the currently highlighted date/time field if it is not +//! already at the minimum value. If the month is being changed then it +//! enforces the maximum number of days for the month. +//! +//! \return Returns non-zero if the button event was handled, and 0 if the +//! button event was not handled. +// +//***************************************************************************** +static int32_t +ClockSetKeyDown(tClockSetWidget *psWidget) +{ + // + // Get pointer to the time structure to be modified. + // + struct tm *psTime = psWidget->psTime; + + // + // Determine which field is highlighted. + // + switch(psWidget->ui32Highlight) + { + // + // Decrement the year. Minimum year is 1970. + // + case FIELD_YEAR: + { + if(psTime->tm_year+1900 > 1970) + { + psTime->tm_year--; + } + break; + } + + // + // Decrement the month. If the month has changed, check that the + // day is valid for this month, and enforce the maximum day number + // for this month. + // + case FIELD_MONTH: + { + if(psTime->tm_mon > 0) + { + psTime->tm_mon--; + } + if(psTime->tm_mday > MaxDayOfMonth(psTime->tm_mon)) + { + psTime->tm_mday = MaxDayOfMonth(psTime->tm_mon); + } + break; + } + + // + // Decrement the day + // + case FIELD_DAY: + { + if(psTime->tm_mday > 1) + { + psTime->tm_mday--; + } + break; + } + + // + // Decrement the hour + // + case FIELD_HOUR: + { + if(psTime->tm_hour > 0) + { + psTime->tm_hour--; + } + break; + } + + // + // Decrement the minute + // + case FIELD_MINUTE: + { + if(psTime->tm_min > 0) + { + psTime->tm_min--; + } + break; + } + + // + // Bad value for field index - ignore. + // + default: + { + break; + } + } + + // + // Since something may have been changed in the clock value, request + // a repaint of the widget. + // + WidgetPaint(&psWidget->sBase); + + // + // Return indication that the button event was handled. + // + return(1); +} + +//***************************************************************************** +// +//! Handle the LEFT button event. +//! +//! \param psWidget is a pointer to the clock setting widget on which to +//! operate. +//! +//! This function handles the event when the user has pressed the left button. +//! It will change the highlighted field to the previous field. If it is +//! at the first field in the display, it will wrap around to the last. +//! +//! \return Returns non-zero if the button event was handled, and 0 if the +//! button event was not handled. +// +//***************************************************************************** +static int32_t +ClockSetKeyLeft(tClockSetWidget *psWidget) +{ + // + // If not already at the minimum, decrement the highlighted field index. + // + if(psWidget->ui32Highlight) + { + psWidget->ui32Highlight--; + } + else + { + // + // Already at the first field, so reset to the last field. + // + psWidget->ui32Highlight = FIELD_LAST; + } + + // + // The highlighted field changed, so request a repaint of the widget. + // + WidgetPaint(&psWidget->sBase); + + // + // Return indication that the button event was handled. + // + return(1); +} + +//***************************************************************************** +// +//! Handle the RIGHT button event. +//! +//! \param psWidget is a pointer to the clock setting widget on which to +//! operate. +//! +//! This function handles the event when the user has pressed the right button. +//! It will change the highlighted field to the next field. If it is already +//! at the last field in the display, it will wrap around to the first. +//! +//! \return Returns non-zero if the button event was handled, and 0 if the +//! button event was not handled. +// +//***************************************************************************** +static int32_t +ClockSetKeyRight(tClockSetWidget *psWidget) +{ + // + // If not already at the last field, increment the highlighted field index. + // + if(psWidget->ui32Highlight < FIELD_LAST) + { + psWidget->ui32Highlight++; + } + else + { + // + // Already at the last field, so reset to the first field. + // + psWidget->ui32Highlight = 0; + } + + // + // The highlighted field changed, so request a repaint of the widget. + // + WidgetPaint(&psWidget->sBase); + + // + // Return indication that the button event was handled. + // + return(1); +} + +//***************************************************************************** +// +//! Handle the select button event. +//! +//! \param psWidget is a pointer to the clock setting widget on which to +//! operate. +//! +//! This function handles the event when the user has pressed the select +//! button. If either the OK or CANCEL fields is highlighted, then the +//! function will call the callback function to notify the application that +//! an action has been taken and the widget should be dismissed. +//! +//! \return Returns non-zero if the button event was handled, and 0 if the +//! button event was not handled. +// +//***************************************************************************** +static int32_t +ClockSetKeySelect(tClockSetWidget *psWidget) +{ + bool bOk; + + // + // Determine if the OK text field is highlighted and set a flag. + // + bOk = (psWidget->ui32Highlight == FIELD_OK) ? true : false; + + // + // If there is a callback function installed, and either the OK or CANCEL + // fields is highlighted, then take action. + // + if(psWidget->pfnOnOkClick && ((psWidget->ui32Highlight == FIELD_OK) || + (psWidget->ui32Highlight == FIELD_CANCEL))) + { + // + // Call the callback function and pass the flag to indicate if OK + // was selected (otherwise it was CANCEL). + // + psWidget->pfnOnOkClick(&psWidget->sBase, bOk); + + // + // Set the default highlighted field. This is the field that will + // be highlighted the next time this widget is activated. + // + psWidget->ui32Highlight = FIELD_CANCEL; + + // + // Return to caller, indicating the button event was handled. + // + return(1); + } + else + { + // + // There is no callback function, or neither the OK or CANCEL fields is + // highlighted. In this case ingore the button event. + // + return(0); + } +} + +//***************************************************************************** +// +//! Dispatch button events destined for this widget. +//! +//! \param psWidget is a pointer to the clock setting widget on which to +//! operate. +//! \param ui32Msg is the widget message to process. +//! +//! This function receives button/key event messages that are meant for +//! this widget. It then calls the appropriate function to handle the +//! button event. +//! +//! \return Returns non-zero if the button event was handled, and 0 if the +//! button event was not handled. +// +//***************************************************************************** +static int32_t +ClockSetKeyHandler(tWidget *psWidget, uint32_t ui32Msg) +{ + tClockSetWidget *psClockWidget; + + ASSERT(psWidget); + + // + // Get pointer to the clock setting widget. + // + psClockWidget = (tClockSetWidget *)psWidget; + + // + // Process the key event + // + switch(ui32Msg) + { + // + // Select key + // + case WIDGET_MSG_KEY_SELECT: + { + return(ClockSetKeySelect(psClockWidget)); + } + + // + // Up button + // + case WIDGET_MSG_KEY_UP: + { + return(ClockSetKeyUp(psClockWidget)); + } + + // + // Down button + // + case WIDGET_MSG_KEY_DOWN: + { + return(ClockSetKeyDown(psClockWidget)); + } + + // + // Left button + // + case WIDGET_MSG_KEY_LEFT: + { + return(ClockSetKeyLeft(psClockWidget)); + } + + // + // Right button + // + case WIDGET_MSG_KEY_RIGHT: + { + return(ClockSetKeyRight(psClockWidget)); + } + + // + // This is an unexpected event. Return an indication that the event + // was not handled. + // + default: + { + return(0); + } + } +} + +//***************************************************************************** +// +//! Handles messages for a clock setting widget. +//! +//! \param psWidget is a pointer to the clock set 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 clock set 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 +ClockSetMsgProc(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. + // + ClockSetPaint(psWidget); + + // + // Return one to indicate that the message was successfully + // processed. + // + return(1); + } + + // + // Process any button/key event messages. + // + 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: + { + // + // If the key event is for this widget, then process the key event + // + if((tWidget *)ui32Param1 == psWidget) + { + return(ClockSetKeyHandler(psWidget, ui32Msg)); + } + } + + // + // An unknown request has been sent. + // + default: + { + // + // Let the default message handler process this message. + // + return(WidgetDefaultMsgProc(psWidget, ui32Msg, ui32Param1, + ui32Param2)); + } + } +} + +//***************************************************************************** +// +//! Initializes a clock setting widget. +//! +//! \param psWidget is a pointer to the clock set widget to initialize. +//! \param psDisplay is a pointer to the display on which to draw the widget. +//! \param i32X is the X coordinate of the upper left corner of the widget. +//! \param i32Y is the Y coordinate of the upper left corner of the widget. +//! \param i32Width is the width of the widget. +//! \param i32Height is the height of the widget. +//! \param psFont is the font to use for drawing text on the widget. +//! \param ui32ForegroundColor is the color of the text and lines on the +//! widget. +//! \param ui32BackgroundColor is the color of the widget background. +//! \param psTime is a pointer to the time structure to use for clock fields. +//! \param pfnOnOkClick is a callback function that is called when the user +//! selects the OK field on the display. +//! +//! This function initializes the caller provided clock setting widget. +//! +//! \return None. +// +//***************************************************************************** +void +ClockSetInit(tClockSetWidget *psWidget, const tDisplay *psDisplay, + int32_t i32X, int32_t i32Y, int32_t i32Width, int32_t i32Height, + tFont *psFont, uint32_t ui32ForegroundColor, + uint32_t ui32BackgroundColor, struct tm *psTime, + void (*pfnOnOkClick)(tWidget *psWidget, bool bOk)) +{ + uint32_t ui32Idx; + + // + // Check the arguments. + // + ASSERT(psWidget); + ASSERT(psDisplay); + + // + // Clear out the widget structure. + // + for(ui32Idx = 0; ui32Idx < sizeof(tClockSetWidget); ui32Idx += 4) + { + ((uint32_t *)psWidget)[ui32Idx / 4] = 0; + } + + // + // Set the size of the widget structure. + // + psWidget->sBase.i32Size = sizeof(tClockSetWidget); + + // + // 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->psFont = psFont; + psWidget->ui32ForegroundColor = ui32ForegroundColor; + psWidget->ui32BackgroundColor = ui32BackgroundColor; + psWidget->psTime = psTime; + psWidget->pfnOnOkClick = pfnOnOkClick; + + // + // Use the clock set message handler to process messages to this widget. + // + psWidget->sBase.pfnMsgProc = ClockSetMsgProc; +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/boards/ek-lm4f232/qs-logger/clocksetwidget.h b/boards/ek-lm4f232/qs-logger/clocksetwidget.h new file mode 100644 index 0000000..56134df --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/clocksetwidget.h @@ -0,0 +1,273 @@ +//***************************************************************************** +// +// clocksetwidget.h - Prototypes for a widget to set a clock date/time. +// +// 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. +// +//***************************************************************************** + +#ifndef __CLOCKSETWIDGET_H__ +#define __CLOCKSETWIDGET_H__ + +//***************************************************************************** +// +//! \addtogroup clocksetwidget_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! A structure that represents a clock setting widget. +// +//***************************************************************************** +typedef struct _ClockSetWidget +{ + // + //! The generic widget information. + // + tWidget sBase; + + // + //! The font to use for drawing text on the widget. + // + const tFont *psFont; + + // + //! The foreground color of the widget. This is the color that will be + //! used for drawing text and lines, and will also be used as the highlight + //! color for a selected field on the widget. + // + uint32_t ui32ForegroundColor; + + // + //! The background color of the widget. + // + uint32_t ui32BackgroundColor; + + // + //! An index for the date/time field that is highlighted + // + uint32_t ui32Highlight; + + // + //! A pointer to a time structure that is used for showing and editing + //! the date and time. The application should supply the storage for this + //! structure, and this widget will modify it as the user changes the + //! date/time. + // + struct tm *psTime; + + // + //! A pointer to the function to be called when the OK or cancel button is + //! selected. The OK button is used to indicate the user is done setting + //! the time. The CANCEL button is used to indicate that the user does + //! not want to update the time. The flag bOk is true if the OK button + //! was selected, false otherwise. The callback function can be used by + //! the application to detect when the clock setting widget can be removed + //! from the screen and whether or not to update the time. + // + void (*pfnOnOkClick)(tWidget *psWidget, bool bOk); +} tClockSetWidget; + +//***************************************************************************** +// +//! Declares an initialized strip chart widget data structure. +//! +//! \param psParent is a pointer to the parent widget. +//! \param psNext is a pointer to the sibling widget. +//! \param psChild is a pointer to the first child widget. +//! \param psDisplay is a pointer to the off-screen display on which to draw. +//! \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 psFont is the font used for rendering text on the widget. +//! \param ui32ForegroundColor is the foreground color for the widget. +//! \param ui32BackgroundColor is the background color for the chart. +//! \param psTime is a pointer to storage for the time structure that the +//! widget will modify. +//! \param pfnOnOkClick is a callback function that is called when the user +//! selects the OK or CANCEL button on the widget. +//! +//! This macro provides an initialized clock setting widget data structure, +//! which can be used to construct the widget tree at compile time in global +//! variables (as opposed to run-time via function calls). This must be +//! assigned to a variable, such as: +//! +//! \verbatim +//! tClockSetWidget g_sClockSetter = ClockSetStruct(...); +//! \endverbatim +//! +//! Or, in an array of variables: +//! +//! \verbatim +//! tClockSetWidget g_psClockSetters[] = +//! { +//! ClockSetStruct(...), +//! ClockSetStruct(...) +//! }; +//! \endverbatim +//! +//! \return Nothing; this is not a function. +// +//***************************************************************************** +#define ClockSetStruct(psParent, psNext, psChild, psDisplay, i32X, i32Y, \ + i32Width, i32Height, psFont, ui32ForegroundColor, \ + ui32BackgroundColor, psTime, pfnOnOkClick) \ + { \ + { \ + sizeof(tClockSetWidget), \ + (tWidget *)(psParent), \ + (tWidget *)(psNext), \ + (tWidget *)(psChild), \ + psDisplay, \ + { \ + i32X, \ + i32Y, \ + (i32X) + (i32Width) - 1, \ + (i32Y) + (i32Height) - 1 \ + }, \ + ClockSetMsgProc \ + }, \ + psFont, ui32ForegroundColor, ui32BackgroundColor, 6, psTime, \ + pfnOnOkClick \ + } + +//***************************************************************************** +// +//! Declares an initialized variable containing a clock setting widget data +//! structure. +//! +//! \param sName is the name of the variable to be declared. +//! \param psParent is a pointer to the parent widget. +//! \param psNext is a pointer to the sibling widget. +//! \param psChild is a pointer to the first child widget. +//! \param psDisplay is a pointer to the off-screen display on which to draw. +//! \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 psFont is the font used for rendering text on the widget. +//! \param ui32ForegroundColor is the foreground color for the widget. +//! \param ui32BackgroundColor is the background color for the chart. +//! \param psTime is a pointer to storage for the time structure that the +//! widget will modify. +//! \param pfnOnOkClick is a callback function that is called when the user +//! selects the OK or CANCEL button on the widget. +//! +//! This macro declares a variable containing an initialized clock setting +//! widget data structure, which can be used to construct the widget tree at +//! compile time in global variables (as opposed to run-time via function +//! calls). +//! +//! \return Nothing; this is not a function. +// +//***************************************************************************** +#define ClockSet(sName, psParent, psNext, psChild, psDisplay, i32X, i32Y, \ + i32Width, i32Height, psFont, ui32ForegroundColor, \ + ui32BackgroundColor, psTime, pfnOnOkClick) \ + tClockSetWidget sName = ClockSetStruct(psParent, psNext, psChild, \ + psDisplay, i32X, i32Y, \ + i32Width, i32Height, psFont, \ + ui32ForegroundColor, \ + ui32BackgroundColor, psTime, \ + pfnOnOkClick) + +//***************************************************************************** +// +//! Sets the pointer to the time structure for the clock set widget. +//! +//! \param psClockSetWidget is a pointer to the clock set widget to modify. +//! \param psTime is a pointer to the a time structure to use for clock +//! setting. +//! +//! This function sets the time structure used by the widget. +//! +//! \return None. +// +//***************************************************************************** +#define ClockSetTimePtrSet(psClockSetWidget, psTime) \ + do \ + { \ + (pClockSetWidget)->psTime = (psTime); \ + } \ + while(0) + +//***************************************************************************** +// +//! Sets the callback function to be used when OK or CANCEL is selected. +//! +//! \param pClockSetWidget is a pointer to the clock set widget to modify. +//! \param pfnCB is a pointer to function to call when OK is selected by the +//! user. +//! +//! This function sets the OK click callback function used by the widget. +//! +//! \return None. +// +//***************************************************************************** +#define ClockSetCallbackSet(pClockSetWidget, pfnCB) \ + do \ + { \ + (pClockSetWidget)->pfnOnOkClick = (pfnCB); \ + } while(0) + +//***************************************************************************** +// +// Prototypes for the clock set widget APIs. +// +//***************************************************************************** +extern void ClockSetInit(tClockSetWidget *psWidget, const tDisplay *psDisplay, + int32_t i32X, int32_t i32Y, int32_t i32Width, + int32_t i32Height, tFont *psFont, + uint32_t ui32ForegroundColor, + uint32_t ui32BackgroundColor, struct tm *psTime, + void (*pfnOnOkClick)(tWidget *psWidget, bool bOk)); +extern int32_t ClockSetMsgProc(tWidget *psWidget, uint32_t ui32Msg, + uint32_t ui32Param1, uint32_t ui32Param2); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __CLOCKSETWIDGET_H__ diff --git a/boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.bin b/boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.bin new file mode 100644 index 0000000..d7e5596 Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.bin differ diff --git a/boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.out b/boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.out new file mode 100644 index 0000000..20ce755 Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/ewarm/Exe/qs-logger.out differ diff --git a/boards/ek-lm4f232/qs-logger/flashstore.c b/boards/ek-lm4f232/qs-logger/flashstore.c new file mode 100644 index 0000000..30cbcea --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/flashstore.c @@ -0,0 +1,625 @@ +//***************************************************************************** +// +// flashstore.c - Data logger module to handle storage in flash. +// +// 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 +#include +#include +#include "inc/hw_types.h" +#include "driverlib/debug.h" +#include "driverlib/flash.h" +#include "utils/ustdlib.h" +#include "qs-logger.h" +#include "usbstick.h" +#include "flashstore.h" + +//***************************************************************************** +// +// This module manages the storage of data logger data into flash memory. +// +//***************************************************************************** + +//***************************************************************************** +// +// Define the beginning and end of the flash storage area. You must make sure +// that this area is well clear of any space occupied by the application +// binary, and that this space is not used for any other purpose. +// The start and end addresses must be 1K aligned. The end address is +// exclusive - it is 1 value greater than the last valid location used for +// storage. +// +//***************************************************************************** +#define FLASH_STORE_START_ADDR 0x20000 +#define FLASH_STORE_END_ADDR 0x40000 + +//***************************************************************************** +// +// The next address in flash, that will be used for storing a data record. +// +//***************************************************************************** +static uint32_t g_ui32StoreAddr; + +//***************************************************************************** +// +// A buffer used to assemble a complete record of data prior to storing it +// in the flash. +// +//***************************************************************************** +static uint32_t g_pui32RecordBuf[32]; + +//***************************************************************************** +// +// Initializes the flash storage. This is a stub because there is nothing +// special to do. +// +//***************************************************************************** +void +FlashStoreInit(void) +{ +} + +//***************************************************************************** +// +// Saves data records that are stored in the flash to an externally connected +// USB memory storage device (USB stick). +// The flash memory is scanned for the presence of store data records. When +// records are found they are written in CSV format to the USB stick. This +// function assumes a non-corrupted storage area, and that any records, once +// found, are contiguous with all stored records. It will find the oldest +// record and start with that when storing. +// +//***************************************************************************** +int32_t +FlashStoreSave(void) +{ + uint32_t ui32Addr, ui32OldestRecord, ui32OldestSeconds, ui32Count, + ui32PartialCount; + tLogRecord *psRecord; + + // + // Initialize locals. + // + ui32OldestRecord = FLASH_STORE_START_ADDR; + ui32OldestSeconds = 0xFFFFFFFF; + + // + // Show a message to the user. + // + SetStatusText("SAVE", "SCANNING", "FLASH", 0); + + // + // Start at beginning of flash storage area + // + ui32Addr = FLASH_STORE_START_ADDR; + + // + // Search all of flash area checking every stored record. + // + while(ui32Addr < FLASH_STORE_END_ADDR) + { + // + // If a record signature is found, check for oldest record, then + // increment to the next record + // + if((HWREG(ui32Addr) & 0xFFFFFF00) == 0x53554100) + { + // + // Get a pointer to the data record (account for flash header word) + // + psRecord = (tLogRecord *)(ui32Addr + 4); + + // + // If the seconds in this record are older than any found so far + // then save the seconds value, and the address of this record + // + if(psRecord->ui32Seconds < ui32OldestSeconds) + { + ui32OldestSeconds = psRecord->ui32Seconds; + ui32OldestRecord = ui32Addr; + } + + // + // Advance the address to the next record. + // + ui32Addr += HWREG(ui32Addr) & 0xFF; + } + else + { + // + // A record was not found so just advance to the next location in + // flash + // + ui32Addr += 4; + } + } + + // + // If no "oldest" seconds was found, then there is no valid data stored + // + if(ui32OldestSeconds == 0xFFFFFFFF) + { + SetStatusText("SAVE", "NO RECORDS", "FOUND", "PRESS <"); + return(1); + } + + // + // Open the output file on the USB stick. It will return NULL if there + // was any problem. + // + if(!USBStickOpenLogFile(0)) + { + SetStatusText("SAVE", 0, "USB ERROR", "PRESS <"); + return(1); + } + + // + // Notify user we are saving data to USB + // + SetStatusText("SAVE", "SAVING", "TO USB", 0); + + // + // Start reading records from flash, start at the address of the oldest + // record, as found above. We scan through records, assuming the flash + // store is not corrupted. Continue scanning until a blank space is + // found which should indicate the end of recorded data, or until we + // have read all the records. + // + ui32Addr = ui32OldestRecord; + while(HWREG(ui32Addr) != 0xFFFFFFFF) + { + // + // If a record signature is found (which it should be), extract the + // record data and send it to USB stick. + // + if((HWREG(ui32Addr) & 0xFFFFFF00) == 0x53554100) + { + // + // Get byte count for this record + // + ui32Count = HWREG(ui32Addr) & 0xFF; + + // + // Adjust the count and the address to remove the flash header + // + ui32Count -= 4; + ui32Addr += 4; + + // + // Adjust for memory wrap + // + if(ui32Addr >= FLASH_STORE_END_ADDR) + { + ui32Addr = FLASH_STORE_START_ADDR; + } + + // + // If the contents of this record go past the end of the memory + // storage area, then perform a partial copy first. + // + ui32PartialCount = 0; + if((ui32Addr + ui32Count) >= FLASH_STORE_END_ADDR) + { + // + // Find how many bytes are left on this page + // + ui32PartialCount = FLASH_STORE_END_ADDR - ui32Addr; + + // + // Copy the portion until the end of memory store, adjust + // remaining count and address + // + memcpy(g_pui32RecordBuf, (void *)ui32Addr, ui32PartialCount); + ui32Count -= ui32PartialCount; + ui32Addr = FLASH_STORE_START_ADDR; + } + + // + // Copy entire record (or remaining part of record if memory wrap) + // into record buffer + // + memcpy(&g_pui32RecordBuf[ui32PartialCount / 4], (void *)ui32Addr, + ui32Count); + + // + // Update address pointer to next record + // + ui32Addr += ui32Count; + + // + // Now we have an entire data logger record copied from flash + // storage into a local (contiguous) memory buffer. Pass it + // to the USB file writing function to write the record to the + // USB stick. + // + USBStickWriteRecord((tLogRecord *)g_pui32RecordBuf); + } + else + { + // + // This should not happen, but it means we ended up in a non-blank + // location that is not the start of a record. In this case just + // advance through memory until either a blank location or another + // record is found. + // + // Increment to next word in flash, adjust for memory wrap. + // + ui32Addr += 4; + if(ui32Addr >= FLASH_STORE_END_ADDR) + { + ui32Addr = FLASH_STORE_START_ADDR; + } + } + } + + // + // Close the USB stick file so that any buffers will be flushed. + // + USBStickCloseFile(); + + // + // Inform user that save is complete. + // + SetStatusText("SAVE", "USB SAVE", "COMPLETE", "PRESS <"); + + // + // Return success + // + return(0); +} + +//***************************************************************************** +// +// This is called at the start of logging to prepare space in flash for +// storage of logged data. It searches for the first blank area in the +// flash storage to be used for storing records. +// +// If a starting address is specified then the search is skipped and it goes +// directly to the new address. If the starting address is 0, then it performs +// the search. +// +//***************************************************************************** +int32_t +FlashStoreOpenLogFile(uint32_t ui32StartAddr) +{ + uint32_t ui32Addr; + + // + // If a valid starting address is specified, then just use that and skip + // the search below. + // + if((ui32StartAddr >= FLASH_STORE_START_ADDR) && + (ui32StartAddr < FLASH_STORE_END_ADDR)) + { + g_ui32StoreAddr = ui32StartAddr; + return(0); + } + + // + // Start at beginning of flash storage area + // + ui32Addr = FLASH_STORE_START_ADDR; + + // + // Search until a blank is found or the end of flash storage area + // + while((HWREG(ui32Addr) != 0xFFFFFFFF) && (ui32Addr < FLASH_STORE_END_ADDR)) + { + // + // If a record signature is found, then increment to the next record + // + if((HWREG(ui32Addr) & 0xFFFFFF00) == 0x53554100) + { + ui32Addr += HWREG(ui32Addr) & 0xFF; + } + else + { + // + // Just advance to the next location in flash + // + ui32Addr += 4; + } + } + + // + // If we are at the end of flash that means no blank area was found. + // So reset to the beginning and erase the first page. + // + if(ui32Addr >= FLASH_STORE_END_ADDR) + { + ui32Addr = FLASH_STORE_START_ADDR; + FlashErase(ui32Addr); + } + + // + // When we reach here we either found a blank location, or made a new + // blank location by erasing the first page. + // To keep things simple we are making an assumption that the flash store + // is not corrupted and that the first blank location implies the start + // of a blank area suitable for storing data records. + // + g_ui32StoreAddr = ui32Addr; + + // + // Return success indication to caller + // + return(0); +} + +//***************************************************************************** +// +// This is called each time there is a new data record to log to the flash +// storage area. A simple algorithm is used which rotates programming +// data log records through an area of flash. It is assumed that the current +// page is blank. Records are stored on the current page until a page +// boundary is crossed. If the page boundary is crossed and the new page +// is not blank (testing only the first location), then the new page is +// erased. Finally the entire record is programmed into flash and the +// storage pointers are updated. +// +// While storing and when crossing to a new page, if the flash page is not +// blank it is erased. So this algorithm overwrites old data. +// +// The data is stored in flash as a record, with a flash header prepended, +// and with the record length padded to be a multiple of 4 bytes. The flash +// header is a 3-byte magic number and one byte of record length. +// +//***************************************************************************** +int32_t +FlashStoreWriteRecord(tLogRecord *psRecord) +{ + uint32_t ui32Idx, ui32ItemCount, *pui32Record; + + // + // Check the arguments + // + ASSERT(psRecord); + if(!psRecord) + { + return(1); + } + + // + // Determine how many channels are to be logged + // + ui32Idx = psRecord->ui16ItemMask; + ui32ItemCount = 0; + while(ui32Idx) + { + if(ui32Idx & 1) + { + ui32ItemCount++; + } + ui32Idx >>= 1; + } + + // + // Add 16-bit count equivalent of record header, time stamp, and + // selected items mask. This is the total number of 16 bit words + // of the record. + // + ui32ItemCount += 6; + + // + // Convert the count to bytes, be sure to pad to 32-bit alignment. + // + ui32ItemCount = ((ui32ItemCount * 2) + 3) & ~3; + + // + // Create the flash record header, which is a 3-byte signature and a + // one byte count of bytes in the record. Save it at the beginning + // of the write buffer. + // + ui32Idx = 0x53554100 | (ui32ItemCount & 0xFF); + g_pui32RecordBuf[0] = ui32Idx; + + // + // Copy the rest of the record to the buffer, and get a pointer to + // the buffer. + // + memcpy(&g_pui32RecordBuf[1], psRecord, ui32ItemCount - 4); + pui32Record = g_pui32RecordBuf; + + // + // Check to see if the record is going to cross a page boundary. + // + if(((g_ui32StoreAddr & 0x3FF) + ui32ItemCount) > 0x3FF) + { + // + // Find number of bytes remaining on this page + // + ui32Idx = 0x400 - (g_ui32StoreAddr & 0x3FF); + + // + // Program part of the record on the space remaining on the current + // page + // + FlashProgram(pui32Record, g_ui32StoreAddr, ui32Idx); + + // + // Increment the store address by the amount just written, which + // should make the new store address be at the beginning of the next + // flash page. + // + g_ui32StoreAddr += ui32Idx; + + // + // Adjust the remaining bytes to program, and the pointer to the + // remainder of the record data. + // + ui32ItemCount -= ui32Idx; + pui32Record = &g_pui32RecordBuf[ui32Idx / 4]; + + // + // Check to see if the new page is past the end of store and adjust + // + if(g_ui32StoreAddr >= FLASH_STORE_END_ADDR) + { + g_ui32StoreAddr = FLASH_STORE_START_ADDR; + } + + // + // If new page is not blank, then erase it + // + if(HWREG(g_ui32StoreAddr) != 0xFFFFFFFF) + { + FlashErase(g_ui32StoreAddr); + } + } + + // + // Now program the remaining part of the record (if we crossed a page + // boundary above) or the full record to the current location in flash + // + FlashProgram(pui32Record, g_ui32StoreAddr, ui32ItemCount); + + // + // Increment the storage address to the next location. + // + g_ui32StoreAddr += ui32ItemCount; + + // + // Return success indication to caller. + // + return(0); +} + +//***************************************************************************** +// +// Return the current address being used for storing records. +// +//***************************************************************************** +uint32_t +FlashStoreGetAddr(void) +{ + return(g_ui32StoreAddr); +} + +//***************************************************************************** +// +// Erase the data storage area of flash. +// +//***************************************************************************** +void +FlashStoreErase(void) +{ + uint32_t ui32Addr; + + // + // Inform user we are erasing + // + SetStatusText("ERASE", 0, "ERASING", 0); + + // + // Loop through entire storage area and erase each page. + // + for(ui32Addr = FLASH_STORE_START_ADDR; ui32Addr < FLASH_STORE_END_ADDR; + ui32Addr += 0x400) + { + FlashErase(ui32Addr); + } + + // + // Inform user the erase is done. + // + SetStatusText("SAVE", "ERASE", "COMPLETE", "PRESS <"); +} + +//***************************************************************************** +// +// Determine if the flash block that contains the address is blank. +// +//***************************************************************************** +static int32_t +IsBlockFree(uint32_t ui32BaseAddr) +{ + uint32_t ui32Addr; + + // + // Make sure we start at the beginning of a 1K block + // + ui32BaseAddr &= ~0x3FF; + + // + // Loop through every address in this block and test if it is blank. + // + for(ui32Addr = 0; ui32Addr < 0x400; ui32Addr += 4) + { + if(HWREG(ui32BaseAddr + ui32Addr) != 0xFFFFFFFF) + { + // + // Found a non-blank location, so return indication that block + // is not free. + // + return(0); + } + } + + // + // If we made it to here then every location in this block is erased, + // so return indication that the block is free. + // + return(1); +} + +//***************************************************************************** +// +// Report to the user the amount of free space and used space in the data +// storage area. +// +//***************************************************************************** +void +FlashStoreReport(void) +{ + uint32_t ui32Addr, ui32FreeBlocks, ui32UsedBlocks = 0; + static char pcBufFree[16], pcBufUsed[16]; + + // + // Initialize locals. + // + ui32FreeBlocks = 0; + ui32UsedBlocks = 0; + + // + // Loop through each block of the storage area and count how many blocks + // are free and non-free. + // + for(ui32Addr = FLASH_STORE_START_ADDR; ui32Addr < FLASH_STORE_END_ADDR; + ui32Addr += 0x400) + { + if(IsBlockFree(ui32Addr)) + { + ui32FreeBlocks++; + } + else + { + ui32UsedBlocks++; + } + } + + // + // Report the result to the user via a status display screen. + // + usnprintf(pcBufFree, sizeof(pcBufFree), "FREE: %3uK", ui32FreeBlocks); + usnprintf(pcBufUsed, sizeof(pcBufUsed), "USED: %3uK", ui32UsedBlocks); + SetStatusText("FREE FLASH", pcBufFree, pcBufUsed, "PRESS <"); +} diff --git a/boards/ek-lm4f232/qs-logger/flashstore.h b/boards/ek-lm4f232/qs-logger/flashstore.h new file mode 100644 index 0000000..7b50538 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/flashstore.h @@ -0,0 +1,60 @@ +//***************************************************************************** +// +// flashstore.h - Prototypes and definitions for flash storage module. +// +// 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. +// +//***************************************************************************** +#ifndef __FLASHSTORE_H__ +#define __FLASHSTORE_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Module function prototypes. +// +//***************************************************************************** +extern void FlashStoreInit(void); +extern int32_t FlashStoreOpenLogFile(uint32_t ui32StartAddr); +extern int32_t FlashStoreWriteRecord(tLogRecord *psRecord); +extern int32_t FlashStoreSave(void); +extern void FlashStoreErase(void); +extern void FlashStoreReport(void); +extern uint32_t FlashStoreGetAddr(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __FLASHSTORE_H__ diff --git a/boards/ek-lm4f232/qs-logger/gcc/qs-logger.axf b/boards/ek-lm4f232/qs-logger/gcc/qs-logger.axf new file mode 100644 index 0000000..ecbf290 Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/gcc/qs-logger.axf differ diff --git a/boards/ek-lm4f232/qs-logger/gcc/qs-logger.bin b/boards/ek-lm4f232/qs-logger/gcc/qs-logger.bin new file mode 100644 index 0000000..cf196f3 Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/gcc/qs-logger.bin differ diff --git a/boards/ek-lm4f232/qs-logger/images.c b/boards/ek-lm4f232/qs-logger/images.c new file mode 100644 index 0000000..ae59b95 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/images.c @@ -0,0 +1,865 @@ +//***************************************************************************** +// +// images.c - Data for images used in the user interface. +// +// Copyright (c) 2008-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 +#include +#include "grlib/grlib.h" + +//***************************************************************************** +// +// This image contains the TI logo with black background. +// +//***************************************************************************** +const uint8_t g_pui8Image_TI_Black[] = +{ + IMAGE_FMT_4BPP_COMP, + 96, 0, + 64, 0, + + 15, + 0x00, 0x00, 0x00, + 0x11, 0x11, 0x15, + 0x0d, 0x0a, 0x55, + 0x2d, 0x2d, 0x2d, + 0x18, 0x13, 0xa1, + 0x4c, 0x4c, 0x4c, + 0x23, 0x1c, 0xea, + 0x6b, 0x6b, 0x6b, + 0x87, 0x87, 0x87, + 0x9b, 0x9b, 0x9b, + 0xa8, 0xa8, 0xa8, + 0xb9, 0xb9, 0xb9, + 0xc8, 0xc8, 0xc8, + 0xd7, 0xd7, 0xd7, + 0xe6, 0xe6, 0xe6, + 0xfe, 0xfe, 0xfe, + + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x8f, 0x03, 0x44, 0x44, 0x20, 0x07, + 0x07, 0x77, 0x2f, 0x83, 0x07, 0x66, 0x66, 0x20, 0x02, 0x10, 0x07, 0x07, + 0xe0, 0x77, 0x2f, 0x05, 0x66, 0x66, 0x20, 0x26, 0x20, 0xf8, 0x07, 0x07, + 0x77, 0x2f, 0x05, 0x66, 0x66, 0x20, 0x2f, 0x24, 0x10, 0x03, 0x01, 0x07, + 0x07, 0x77, 0x2f, 0x00, 0x00, 0x66, 0x66, 0x62, 0x24, 0x14, 0x44, 0x20, + 0x07, 0x00, 0x7d, 0xbc, 0xcb, 0xc1, 0x07, 0x07, 0x77, 0x80, 0x2f, 0x66, + 0x66, 0x62, 0x64, 0x26, 0x66, 0x40, 0x00, 0x00, 0x75, 0x3f, 0xc3, 0x85, + 0x33, 0x01, 0x31, 0x01, 0x00, 0x31, 0x00, 0x10, 0x00, 0x05, 0x10, 0x07, + 0xc0, 0xbf, 0x76, 0x66, 0x66, 0x22, 0x64, 0x14, 0x66, 0x00, 0x20, 0x00, + 0x00, 0x0f, 0x90, 0x7e, 0xaa, 0x95, 0x00, 0xfd, 0x08, 0xe3, 0x0a, 0xf1, + 0x03, 0xba, 0xc8, 0xe0, 0x07, 0xbf, 0x73, 0x22, 0x22, 0x22, 0x66, 0x62, + 0x00, 0x02, 0x62, 0x02, 0x66, 0x40, 0x00, 0x00, 0x0f, 0x00, 0x90, 0x8f, + 0x00, 0x50, 0x7f, 0x5a, 0x30, 0x3c, 0x0e, 0xf9, 0x0c, 0xf0, 0x05, 0x05, + 0xcd, 0x97, 0x46, 0x00, 0x66, 0x66, 0x66, 0x64, 0x12, 0x62, 0x24, 0x66, + 0x00, 0x62, 0x00, 0x00, 0x0f, 0x90, 0x7f, 0x8a, 0x70, 0x00, 0x0a, 0xf3, + 0x00, 0x85, 0x5f, 0x05, 0xff, 0xb3, 0xe0, 0x05, 0xcd, 0x97, 0x02, 0x66, + 0x66, 0x66, 0x66, 0x00, 0x24, 0x62, 0x66, 0x66, 0x64, 0x00, 0x00, 0x0f, + 0x00, 0x90, 0x8f, 0x57, 0x30, 0x08, 0xf9, 0x00, 0xd8, 0x07, 0x8f, 0x50, + 0x18, 0xdf, 0x30, 0x04, 0xd4, 0xa7, 0x00, 0x00, 0x00, 0x26, 0x66, 0x66, + 0x66, 0x26, 0x42, 0x00, 0x66, 0x66, 0x64, 0x00, 0x00, 0x0f, 0xa0, 0x8f, + 0x00, 0x00, 0x31, 0x88, 0x3f, 0x73, 0xc7, 0x7e, 0xc7, 0x1c, 0x50, 0x1f, + 0x50, 0x05, 0xcd, 0x97, 0x04, 0x66, 0x00, 0x66, 0x66, 0x26, 0x22, 0x66, + 0x66, 0x64, 0x00, 0x00, 0x00, 0x3d, 0x90, 0x8e, 0xaa, 0xb7, 0xd3, 0x0c, + 0x03, 0xdc, 0x80, 0x09, 0xe9, 0xca, 0xc8, 0x06, 0xc6, 0x80, 0x86, 0x02, + 0x66, 0x22, 0x66, 0x00, 0x00, 0x26, 0x00, 0x64, 0x21, 0x00, 0x00, 0x31, + 0x31, 0x10, 0x33, 0x00, 0x01, 0x10, 0x00, 0x11, 0x00, 0x00, 0x10, 0x03, + 0x70, 0x10, 0x06, 0xc6, 0x87, 0x22, 0x00, 0x46, 0x10, 0x13, 0x00, 0x46, + 0x20, 0x01, 0x3d, 0xa1, 0x07, 0x07, 0xc0, 0x77, 0x2f, 0x00, 0x00, 0x06, + 0x66, 0x66, 0x62, 0x80, 0x02, 0x0f, 0x90, 0x30, 0x01, 0x31, 0x03, 0x51, + 0x00, 0x03, 0x51, 0x53, 0x13, 0x35, 0x00, 0x33, 0x30, 0x00, 0x13, 0x33, + 0x10, 0x00, 0x03, 0x33, 0x15, 0x51, 0x00, 0x13, 0x00, 0x13, 0x13, 0x31, + 0x53, 0x01, 0x53, 0x18, 0x00, 0x00, 0x00, 0xe9, 0xd1, 0x04, 0x66, 0x66, + 0x40, 0x20, 0x9a, 0x0f, 0x81, 0xfd, 0x00, 0xe7, 0x7b, 0x00, 0xab, 0x8a, + 0xbf, 0xa9, 0x7f, 0xba, 0xe5, 0x5f, 0x00, 0x70, 0x3e, 0x39, 0xf3, 0x00, + 0xef, 0x3a, 0xf9, 0x08, 0xb8, 0x5f, 0xb0, 0x1d, 0x69, 0x5b, 0x9c, 0x93, + 0x10, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x01, 0x66, 0x40, 0x66, 0xab, + 0x0f, 0x90, 0xaf, 0xc0, 0x87, 0xf7, 0x00, 0x01, 0x50, 0x3f, 0x01, 0x5f, + 0x30, 0xef, 0x1f, 0x00, 0x30, 0x0b, 0x07, 0xfc, 0x05, 0xfe, 0x09, 0xf0, + 0x00, 0x03, 0x3c, 0xf8, 0x09, 0x70, 0x5f, 0x01, 0xee, 0x06, 0x00, 0x33, + 0x00, 0x00, 0x00, 0xe9, 0xd1, 0x26, 0x20, 0x66, 0x20, 0xa2, 0x0f, 0x90, + 0x95, 0xf9, 0x85, 0x00, 0x8f, 0xf8, 0x00, 0x5f, 0x10, 0x1f, 0x97, 0xc7, + 0x00, 0x1f, 0x30, 0x0b, 0x17, 0xaf, 0x37, 0xbe, 0x08, 0x00, 0xf8, 0xb3, + 0x08, 0x5f, 0x89, 0x10, 0x7f, 0x00, 0x03, 0x3f, 0xfc, 0x30, 0x00, 0x00, + 0x00, 0xe9, 0xd1, 0x10, 0x02, 0x44, 0x20, 0xa2, 0x0f, 0x90, 0xb0, 0x3f, + 0x00, 0xf3, 0x03, 0x8f, 0xc0, 0x5f, 0x10, 0x3f, 0x8b, 0x00, 0xe0, 0x1f, + 0x30, 0x0b, 0x18, 0x5a, 0xf5, 0x5f, 0x00, 0x08, 0xe3, 0x51, 0x1b, 0x07, + 0xfd, 0x00, 0x7f, 0x01, 0x10, 0x00, 0x7b, 0xfb, 0x00, 0x00, 0x00, 0xe9, + 0xc0, 0xd4, 0xa2, 0x0f, 0xa0, 0xc3, 0x07, 0xf7, 0x81, 0x00, 0x0c, 0xe0, + 0x5f, 0x10, 0x3f, 0x10, 0xfb, 0x0f, 0x00, 0x80, 0x5e, 0x09, 0x53, 0xf0, + 0x7f, 0x0a, 0xf0, 0x00, 0x05, 0x7b, 0x00, 0x9f, 0x10, 0x7f, 0x00, 0x87, + 0x07, 0x03, 0xfd, 0x00, 0x00, 0x00, 0xe9, 0xd4, 0xa2, 0x00, 0x3d, 0x93, + 0xc5, 0x00, 0x75, 0x8b, 0xab, 0x30, 0x00, 0x7e, 0x50, 0x5e, 0x70, 0x5f, + 0x75, 0xc9, 0xb5, 0x00, 0x0c, 0x70, 0x70, 0x9d, 0x38, 0xd9, 0xa9, 0x7c, + 0x00, 0x30, 0x08, 0x30, 0x8e, 0x50, 0x5c, 0xac, 0x73, 0x1f, 0x00, 0x00, + 0x00, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xc0, 0x07, 0x07, +}; + +//***************************************************************************** +// +// This image contains a splash screen image. +// +//***************************************************************************** +const uint8_t g_pui8Image_Splash1[] = +{ + IMAGE_FMT_4BPP_COMP, + 96, 0, + 64, 0, + + 15, + 0x00, 0x00, 0x00, + 0x28, 0x28, 0x28, + 0x41, 0x41, 0x41, + 0x55, 0x55, 0x55, + 0x67, 0x67, 0x67, + 0x77, 0x77, 0x77, + 0x86, 0x86, 0x86, + 0x96, 0x96, 0x96, + 0xa7, 0xa7, 0xa7, + 0xb7, 0xb7, 0xb7, + 0xc6, 0xc6, 0xc6, + 0xd8, 0xd8, 0xd8, + 0xe6, 0xe6, 0xe6, + 0xf0, 0xf0, 0xf0, + 0xf9, 0xf9, 0xf9, + 0xff, 0xff, 0xff, + + 0x1f, 0xff, 0xff, 0xff, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xdf, 0x07, 0x06, 0x76, 0x07, 0x07, + 0x77, 0x2f, 0x07, 0x0f, 0xff, 0xff, 0x20, 0x5f, 0x07, 0x07, 0x77, 0x2f, + 0x8f, 0x07, 0xff, 0x36, 0x05, 0x07, 0x07, 0x77, 0x2f, 0x87, 0x07, 0xff, + 0x27, 0xe0, 0x9f, 0x07, 0x07, 0x77, 0xc4, 0x2f, 0x07, 0x26, 0xf6, 0x1f, + 0x03, 0xf8, 0x5f, 0xe8, 0x07, 0x07, 0x77, 0xcd, 0x27, 0xff, 0x36, 0xff, + 0x4e, 0x15, 0x03, 0x70, 0x1c, 0x07, 0x1f, 0x3b, 0xfe, 0x00, 0x42, 0x24, + 0x42, 0x22, 0x35, 0x45, 0xbf, 0xea, 0x00, 0x88, 0x99, 0xab, 0xcf, 0xff, + 0xff, 0x35, 0xff, 0x47, 0x81, 0x02, 0xb2, 0x29, 0x3d, 0x05, 0xcd, 0x97, + 0x00, 0x50, 0x3a, 0xb0, 0x1a, 0xfb, 0x02, 0x63, 0x01, 0x00, 0x11, 0x22, + 0x21, 0x21, 0x11, 0x24, 0x8f, 0x63, 0x00, 0xff, 0xf1, 0x7f, 0xff, 0xff, + 0xf9, 0x06, 0xf9, 0x70, 0x2f, 0x05, 0xcd, 0x96, 0x90, 0x41, 0x7f, 0xf1, + 0x00, 0x8f, 0xf7, 0x1f, 0xff, 0x62, 0xaf, 0xff, 0xff, 0x00, 0xee, 0xc9, + 0x53, 0x22, 0x11, 0xff, 0xf3, 0x3f, 0x8e, 0x51, 0x9f, 0xf6, 0x2f, 0x04, + 0xd4, 0xa6, 0xfa, 0x00, 0x52, 0x08, 0xf5, 0x2f, 0xf1, 0x6f, 0xf3, 0x2f, + 0x40, 0xeb, 0x15, 0xfd, 0x60, 0xaf, 0xf6, 0x1f, 0xff, 0x07, 0xff, 0x16, + 0xff, 0xf2, 0x5f, 0x75, 0x3d, 0x03, 0x00, 0xc5, 0x12, 0x63, 0x1f, 0xf9, + 0x1f, 0xf2, 0x5f, 0x10, 0xf2, 0x4f, 0x63, 0x16, 0xf5, 0x2f, 0xfa, 0x1d, + 0x03, 0xff, 0xf7, 0x1f, 0xff, 0x91, 0xdf, 0x76, 0x36, 0x00, 0xff, 0xff, + 0xb3, 0x12, 0x9f, 0xfd, 0x19, 0xfc, 0x02, 0x1b, 0xf3, 0x4f, 0xf1, 0x6f, + 0x18, 0x17, 0x18, 0x01, 0xff, 0x11, 0x7f, 0xf1, 0x5f, 0xff, 0x15, 0x7f, + 0x80, 0x37, 0xb2, 0x04, 0xcf, 0xff, 0xff, 0x34, 0xff, 0x02, 0x19, 0xf4, + 0x4f, 0xf1, 0xab, 0x1f, 0x0f, 0x71, 0x03, 0xff, 0x32, 0x32, 0x81, 0xef, + 0xf2, 0x7f, 0x3f, 0x10, 0xf4, 0x04, 0xdf, 0x0b, 0x25, 0xf5, 0x3f, 0xe1, + 0x20, 0xc6, 0x3f, 0x0f, 0xf2, 0x4f, 0x62, 0xf9, 0x06, 0x31, 0xfd, 0x12, + 0x87, 0x3e, 0xfb, 0x01, 0xcf, 0x02, 0x00, 0xd1, 0xbf, 0x53, 0xf7, 0x2f, + 0xb1, 0xe3, 0x6f, 0x80, 0x07, 0xfc, 0x0b, 0xf1, 0x14, 0x1f, 0xe0, 0x4f, + 0xc8, 0x87, 0x3e, 0x90, 0x5f, 0x03, 0xf2, 0x5f, 0x92, 0x04, 0xfa, 0x2f, + 0xa2, 0xd1, 0xaf, 0x07, 0xff, 0x43, 0x0c, 0xfb, 0x67, 0xef, 0x15, 0x8f, + 0x46, 0xfb, 0x07, 0x80, 0x04, 0xf5, 0x3f, 0xd1, 0xcd, 0x1f, 0xa2, 0xb1, + 0x50, 0xdf, 0x01, 0xee, 0x04, 0x81, 0xff, 0xff, 0xfd, 0x72, 0x1a, 0x1c, + 0x7c, 0x4b, 0xf0, 0x5f, 0x14, 0xfb, 0x02, 0x1d, 0xf2, 0x7f, 0x1d, 0x93, + 0xa1, 0x02, 0x5a, 0xa7, 0x04, 0x16, 0x01, 0x70, 0xdf, 0x14, 0x74, 0x1a, + 0x40, 0x32, 0x7e, 0x26, 0xf3, 0x4f, 0x1a, 0x94, 0x91, 0xa4, 0x0a, 0xce, + 0x03, 0xf4, 0x2f, 0x01, 0xf1, 0x3f, 0xc8, 0x0e, 0xc5, 0xf9, 0x0c, 0x7e, + 0x52, 0xf6, 0x2f, 0x11, 0x28, 0x85, 0x72, 0x0f, 0xff, 0xc1, 0xaf, 0x01, + 0x32, 0xfe, 0x08, 0x7f, 0x34, 0xf2, 0x3f, 0x06, 0xb1, 0x04, 0xfb, 0x1f, + 0x45, 0x85, 0x72, 0x0d, 0x87, 0xff, 0x2c, 0xff, 0x52, 0x03, 0x61, 0x0e, + 0x3d, 0xc1, 0xbf, 0x81, 0x7e, 0xf2, 0x8f, 0x2d, 0x84, 0x86, 0x72, 0x0d, + 0x04, 0xaa, 0xff, 0xff, 0x22, 0xef, 0x02, 0xf1, 0x4f, 0xd0, 0x06, 0x34, + 0x41, 0x8f, 0xf5, 0x3f, 0x38, 0xa3, 0x24, 0x66, 0x72, 0x12, 0xf7, 0xaf, + 0x01, 0xf9, 0x12, 0x4d, 0xcf, 0x02, 0xf8, 0x1f, 0x06, 0xc4, 0x15, 0x8c, + 0x00, 0xfe, 0xbe, 0xff, 0xfa, 0x1f, 0x55, 0xc3, 0x56, 0x01, 0x82, 0xff, + 0xf7, 0x8f, 0xff, 0xf6, 0xaf, 0x01, 0x00, 0xf3, 0x04, 0xdf, 0xff, 0xff, + 0xfb, 0xbf, 0xff, 0x60, 0x57, 0x03, 0xda, 0xb7, 0xcf, 0xff, 0xff, 0xfe, + 0x40, 0x19, 0x8c, 0xfc, 0x6e, 0xff, 0xff, 0x1b, 0xa2, 0x06, 0xd4, 0x46, + 0x82, 0xff, 0xfb, 0x51, 0x02, 0xf2, 0x00, 0x33, 0xbf, 0xff, 0xff, 0x51, + 0x5c, 0xff, 0x93, 0xc0, 0x8c, 0x59, 0x60, 0x2f, 0xff, 0xff, 0xfc, 0x1a, + 0x90, 0x12, 0xfd, 0x6d, 0x5a, 0x36, 0xf2, 0xb4, 0x37, 0x40, 0xa1, 0x17, + 0xf3, 0x44, 0x9f, 0xff, 0xff, 0x6a, 0x08, 0xff, 0xff, 0xf2, 0xbf, 0x6e, + 0xb1, 0x05, 0xff, 0x00, 0xff, 0xfc, 0x1b, 0xff, 0xff, 0x76, 0xff, 0xfd, + 0x41, 0x9e, 0x62, 0x73, 0xf2, 0x95, 0x36, 0xb1, 0x1e, 0x00, 0xff, 0xf7, + 0x13, 0x5f, 0xff, 0xff, 0xf4, 0x0a, 0x10, 0xff, 0xf3, 0x8f, 0x6e, 0xf3, + 0x22, 0xbf, 0xff, 0x04, 0xfc, 0x1b, 0xff, 0xff, 0xaa, 0x7d, 0xc2, 0xf3, + 0x00, 0x76, 0x35, 0xd1, 0xdf, 0xff, 0xfa, 0xcf, 0xff, 0x00, 0xff, 0xf8, + 0xbf, 0xff, 0xfa, 0x11, 0x0e, 0xff, 0x02, 0xff, 0xf2, 0x03, 0x9f, 0xf3, + 0x6f, 0x0d, 0xff, 0x02, 0xf6, 0x10, 0x6f, 0xff, 0xfd, 0x19, 0x96, 0xc5, + 0x00, 0xef, 0xf1, 0xb6, 0x57, 0x35, 0xf1, 0xbf, 0xff, 0x00, 0xf6, 0xaf, + 0xff, 0xff, 0xf7, 0xbf, 0xff, 0xfc, 0x00, 0x00, 0x02, 0xef, 0xff, 0x78, + 0x91, 0x7f, 0xf5, 0x40, 0x4f, 0x04, 0xff, 0xff, 0xfb, 0x15, 0x2f, 0xff, + 0x20, 0xff, 0x16, 0x91, 0xfc, 0xef, 0xff, 0xfc, 0xbf, 0x00, 0xc8, 0xff, + 0xf3, 0x79, 0x56, 0x34, 0xf1, 0x9f, 0x80, 0x16, 0xfd, 0x13, 0x10, 0x08, + 0xff, 0x72, 0x47, 0x10, 0xff, 0xf8, 0x3f, 0x76, 0xff, 0x26, 0x1b, 0xff, + 0x20, 0xff, 0x43, 0x01, 0xa4, 0xff, 0xff, 0xf8, 0x6f, 0x00, 0xff, 0xff, + 0xf5, 0x4c, 0x45, 0x44, 0xf2, 0x7f, 0x80, 0x14, 0xda, 0xef, 0xfb, 0x2f, + 0x60, 0x00, 0x2d, 0x06, 0xfd, 0xcf, 0xff, 0xfb, 0x3e, 0x74, 0x41, 0x15, + 0x00, 0x17, 0xff, 0xff, 0x91, 0xff, 0xfb, 0xbf, 0xdd, 0x10, 0xff, 0xff, + 0xfe, 0x59, 0xf8, 0x2c, 0x55, 0x43, 0x20, 0xb6, 0x4f, 0x12, 0xfb, 0xdf, + 0xd8, 0xef, 0xf9, 0x05, 0x3b, 0x1b, 0x23, 0x50, 0x9f, 0x49, 0x39, 0x72, + 0x80, 0x52, 0xff, 0x17, 0x15, 0xff, 0xff, 0xf2, 0x4f, 0x20, 0xf7, 0x8f, + 0x7c, 0xc9, 0xfb, 0x2b, 0x43, 0x55, 0x24, 0x89, 0x2f, 0x12, 0xf6, 0xbf, + 0xe1, 0x10, 0x6f, 0x16, 0x35, 0xf8, 0x09, 0x29, 0x44, 0x0c, 0x41, 0x25, + 0x04, 0x33, 0xff, 0xff, 0xfb, 0x0a, 0x8e, 0xa5, 0xff, 0x04, 0x2a, 0x43, + 0x66, 0x4f, 0x1b, 0x16, 0xf2, 0x07, 0x00, 0xf8, 0x0f, 0xff, 0x80, 0xaf, + 0xff, 0xff, 0xa1, 0x8c, 0x76, 0xff, 0x29, 0x61, 0x19, 0x69, 0xb4, 0xff, + 0x00, 0xf7, 0x6f, 0xf8, 0x8f, 0xff, 0xff, 0x44, 0x43, 0x10, 0x26, 0x26, + 0x24, 0x16, 0x10, 0xff, 0xb0, 0x8f, 0x01, 0xff, 0xf6, 0x0f, 0xff, 0xff, + 0xf3, 0x5f, 0x6e, 0x00, 0x50, 0x41, 0xbf, 0xff, 0xff, 0xf8, 0x0a, 0xff, + 0x00, 0xc8, 0xff, 0xfb, 0xbf, 0xf8, 0x8f, 0xff, 0xff, 0x01, 0x23, 0xdd, + 0xab, 0xb7, 0xe1, 0x07, 0xcf, 0x0b, 0x08, 0xb0, 0x26, 0x4b, 0x04, 0xb9, + 0x23, 0xff, 0xff, 0x31, 0xfb, 0x0b, 0x7b, 0x51, 0x81, 0xf1, 0x1f, 0x21, + 0x20, 0xc0, 0x6f, 0x85, 0xf1, 0x2f, 0xff, 0xff, 0xd8, 0x00, 0x23, 0x84, + 0x22, 0x34, 0x6a, 0xcb, 0xb9, 0x63, 0x0a, 0x16, 0xff, 0x40, 0xaf, 0x19, + 0xb0, 0xd9, 0x51, 0x84, 0x05, 0xff, 0xf2, 0x26, 0x12, 0x69, 0x81, 0x01, + 0x80, 0x3a, 0xff, 0xff, 0xf9, 0x00, 0x46, 0x44, 0x33, 0x00, 0x33, 0x7f, + 0xff, 0xd8, 0x53, 0x41, 0x01, 0x00, 0x04, 0x00, 0xbf, 0xff, 0xf5, 0x3f, + 0x19, 0xf5, 0x1f, 0x0c, 0xff, 0xff, 0xf1, 0x5f, 0x03, 0x9a, 0xf2, 0x03, + 0x00, 0x89, 0x51, 0x0f, 0xa0, 0x00, 0x4b, 0xff, 0xff, 0x01, 0xfc, 0x94, + 0x00, 0x9f, 0x97, 0x78, 0x9c, 0x33, 0x00, 0xf2, 0x35, 0xc5, 0x25, 0x0c, + 0xff, 0xff, 0x13, 0x83, 0x9a, 0x11, 0xff, 0xff, 0xfa, 0x1a, 0x53, 0x29, + 0x00, 0x22, 0xf4, 0x4b, 0x20, 0xa9, 0x3c, 0x40, 0x00, 0x02, 0x52, 0x01, + 0x22, 0x10, 0x00, 0x03, 0x56, 0xff, 0x00, 0x33, 0xcb, 0xf8, 0x1f, 0x41, + 0xff, 0xff, 0xe1, 0x41, 0xaf, 0x71, 0xf1, 0x1c, 0xff, 0xff, 0x44, 0x36, + 0x00, 0xf2, 0x10, 0x8f, 0x63, 0xf3, 0x00, 0x02, 0x08, 0x01, 0xff, 0x81, + 0x00, 0x00, 0x02, 0xc0, 0x4f, 0x4d, 0x00, 0xfa, 0x0b, 0x8c, 0xf6, 0x2f, + 0xf1, 0x6f, 0xff, 0x21, 0xf5, 0x3f, 0x7a, 0x40, 0x36, 0xab, 0x14, 0x3d, + 0x00, 0xff, 0xff, 0x93, 0x00, 0x00, 0x00, 0x02, 0x8b, 0x00, 0x2c, 0xfe, + 0xd6, 0x03, 0x90, 0x1c, 0xa9, 0x12, 0x20, 0x88, 0xdf, 0x3c, 0x24, 0xff, + 0xf6, 0x1f, 0xf3, 0x08, 0x0b, 0xff, 0xfa, 0x1f, 0x8a, 0xfd, 0x74, 0x33, + 0x60, 0x5f, 0x4c, 0x1a, 0xc7, 0x44, 0x59, 0xef, 0xf3, 0x00, 0x3f, 0xf4, + 0x04, 0x9f, 0xf0, 0x2b, 0xef, 0xc2, 0x10, 0x32, 0x13, 0xcf, 0x33, 0x61, + 0xff, 0xff, 0x34, 0x07, 0xdf, 0x24, 0xff, 0x65, 0x4a, 0x93, 0x6b, 0xb7, + 0x00, 0xff, 0xff, 0xfb, 0x31, 0xdf, 0xf2, 0x4f, 0xff, 0x01, 0xfa, 0x20, + 0x8f, 0xff, 0xfc, 0x20, 0x2f, 0x03, 0x00, 0xd0, 0x7f, 0xed, 0x74, 0x1a, + 0x83, 0x54, 0x70, 0x70, 0x3b, 0x03, 0x6b, 0xb7, 0xff, 0xfa, 0x13, 0x2a, + 0x00, 0xff, 0xf1, 0x9f, 0xff, 0xff, 0xc3, 0x1a, 0xff, 0x10, 0x90, 0x12, + 0x06, 0x6c, 0x0b, 0x44, 0x23, 0x30, 0x0e, 0x36, 0x22, 0x50, 0x0c, 0x93, + 0x6b, 0xb7, 0xff, 0x04, 0xf4, 0x0b, 0xff, 0xff, 0x51, 0x3a, 0x80, 0x6f, + 0x10, 0xb2, 0x02, 0xbb, 0x04, 0x61, 0x80, 0x11, 0xae, 0x0e, 0x70, 0x21, + 0x15, 0x8f, 0x94, 0x64, 0xa5, 0xfc, 0x04, 0x10, 0x12, 0xb5, 0xa9, 0x0a, + 0x3a, 0xfb, 0x22, 0x20, 0x35, 0x59, 0x05, 0xf5, 0x03, 0x53, 0xef, 0xa1, + 0x38, 0x91, 0x5f, 0x95, 0x5d, 0x24, 0xfa, 0x12, 0x00, 0x12, 0x10, 0x20, + 0x9f, 0x33, 0xf8, 0x7f, 0x06, 0xfe, 0x78, 0x9d, 0xda, 0x96, 0x56, 0x15, + 0x66, 0x82, 0x3c, 0xff, 0x37, 0x07, 0x77, 0x2f, 0x07, 0x07, 0x07, 0x07, + 0xc0, 0x07, 0x07, +}; + +const uint8_t g_pui8Image_Splash2[] = +{ + IMAGE_FMT_4BPP_COMP, + 96, 0, + 64, 0, + + 15, + 0x00, 0x00, 0x00, + 0x28, 0x28, 0x28, + 0x42, 0x42, 0x42, + 0x55, 0x55, 0x55, + 0x65, 0x65, 0x65, + 0x78, 0x78, 0x78, + 0x86, 0x86, 0x86, + 0x96, 0x96, 0x96, + 0xa6, 0xa6, 0xa6, + 0xbb, 0xbb, 0xbb, + 0xcf, 0xcf, 0xcf, + 0xe0, 0xe0, 0xe0, + 0xea, 0xea, 0xea, + 0xf2, 0xf2, 0xf2, + 0xf9, 0xf9, 0xf9, + 0xff, 0xff, 0xff, + + 0x1f, 0xff, 0xff, 0xff, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xfe, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0xff, 0x1f, 0xff, 0xa5, 0xdf, 0x07, 0x07, 0x77, 0x2f, 0x07, + 0x17, 0xff, 0x60, 0x8f, 0x03, 0xbb, 0x07, 0x07, 0x77, 0xcb, 0x2f, 0x02, + 0x52, 0x27, 0x03, 0x21, 0x07, 0x07, 0xe2, 0x77, 0x2f, 0x02, 0x54, 0xf1, + 0x7f, 0x01, 0xf8, 0x3e, 0x03, 0xef, 0x07, 0x07, 0x77, 0x2f, 0x01, 0x62, + 0x23, 0xfa, 0x1b, 0x01, 0xe1, 0x85, 0xaf, 0x07, 0x07, 0x80, 0x75, 0xc6, + 0x67, 0xd7, 0x34, 0x77, 0x69, 0xff, 0x08, 0xff, 0xa9, 0xaa, 0xcf, 0x01, + 0x72, 0xff, 0x62, 0x8e, 0x01, 0x24, 0xf3, 0x9f, 0x07, 0xbf, 0x74, 0xa4, + 0x00, 0x14, 0x63, 0x03, 0x88, 0x14, 0x64, 0x47, 0x41, 0x00, 0x23, 0x33, + 0x22, 0x57, 0x9b, 0xff, 0x92, 0xff, 0x01, 0xf2, 0x7f, 0xff, 0xf8, 0x1f, + 0xf3, 0x9f, 0x06, 0xc0, 0xc6, 0x85, 0xb1, 0x21, 0x9f, 0xfd, 0xae, 0xf6, + 0x00, 0x3f, 0xff, 0x30, 0x49, 0xff, 0xff, 0xf9, 0x43, 0x00, 0x33, 0x34, + 0x41, 0xdf, 0xf8, 0x3f, 0xff, 0xf2, 0x1c, 0x7f, 0xd2, 0xbf, 0x05, 0xcd, + 0x96, 0xb8, 0x05, 0x00, 0xf5, 0x5f, 0xf7, 0xbf, 0xf3, 0x5f, 0xf8, 0x1e, + 0x80, 0x85, 0x51, 0x8f, 0xfc, 0x2c, 0xff, 0xb2, 0xef, 0x70, 0x82, 0x05, + 0xcd, 0x95, 0xf9, 0x43, 0x33, 0x7f, 0x00, 0xf7, 0x2f, 0xf1, 0x8f, 0xf2, + 0x8f, 0xf3, 0x8f, 0x80, 0x05, 0xf8, 0x1f, 0xff, 0x29, 0xff, 0x83, 0xff, + 0x70, 0x34, 0x8d, 0x55, 0x1c, 0xf7, 0x23, 0x6a, 0xfd, 0x00, 0x6f, 0xff, + 0x2a, 0xf2, 0x6f, 0xf2, 0x9f, 0xba, 0x80, 0x07, 0x26, 0xff, 0x31, 0xbf, + 0x73, 0xfb, 0x1b, 0xc2, 0x87, 0x3f, 0xff, 0xfb, 0x21, 0x9f, 0x0a, 0x35, + 0x04, 0xf3, 0x4f, 0xf2, 0xaf, 0x2a, 0x07, 0xa1, 0xef, 0x06, 0x61, 0x2a, + 0x73, 0xf3, 0x3f, 0x87, 0x3f, 0xff, 0x20, 0x70, 0x6f, 0x01, 0x53, 0xff, + 0x82, 0xf7, 0x2f, 0x20, 0xf3, 0xd9, 0x07, 0xff, 0xf3, 0x4f, 0x84, 0xf6, + 0x19, 0x08, 0xf1, 0xaf, 0x87, 0x3f, 0xc3, 0x1a, 0x02, 0x00, 0xa1, 0xef, + 0xb1, 0xfa, 0x1f, 0xf2, 0xf5, 0x3f, 0x81, 0x07, 0xfa, 0x2e, 0xf3, 0x57, + 0x1f, 0x73, 0x8f, 0x90, 0x47, 0xfa, 0x05, 0x03, 0xf3, 0x8f, 0xf2, 0x9f, + 0x08, 0x1d, 0xe2, 0xf3, 0x5f, 0x07, 0xff, 0x45, 0xfe, 0x19, 0x78, 0xcf, + 0x46, 0x8f, 0x47, 0x90, 0x9f, 0x03, 0x00, 0xf6, 0x3f, 0xf4, 0x5f, 0x2a, + 0xd3, 0xf3, 0x8f, 0x15, 0xff, 0xff, 0x99, 0x05, 0x92, 0x01, 0x65, 0xa5, + 0xc8, 0x6d, 0x31, 0xfa, 0x09, 0xc5, 0x2d, 0xf7, 0x3f, 0x01, 0x38, 0xd2, + 0xf2, 0x9f, 0xff, 0xff, 0x89, 0x05, 0x4c, 0x52, 0x01, 0xc2, 0xbf, 0x9d, + 0x65, 0xff, 0xff, 0x20, 0xf1, 0x7f, 0x0d, 0x28, 0xfa, 0x2f, 0x47, 0xd3, + 0x42, 0xe2, 0x06, 0xba, 0xff, 0xfa, 0x1c, 0x01, 0xf3, 0x62, 0x3f, 0x15, + 0x4d, 0xff, 0xff, 0x62, 0x7e, 0x64, 0x00, 0xfe, 0x1f, 0x56, 0xd3, 0xd2, + 0xcf, 0xfa, 0x8f, 0x84, 0x03, 0xa7, 0xff, 0xf2, 0x5f, 0x01, 0xfe, 0x19, + 0xc2, 0x0e, 0x53, 0xba, 0xff, 0xff, 0x1a, 0x7e, 0xa2, 0x00, 0xff, 0x2a, + 0x75, 0xd4, 0xc2, 0xcf, 0xfa, 0x8f, 0xac, 0x05, 0x71, 0x3b, 0x52, 0x0e, + 0x53, 0x60, 0xaf, 0x20, 0xf8, 0x3f, 0x7e, 0xf3, 0x7f, 0x47, 0x94, 0xc4, + 0x00, 0xb2, 0xef, 0xff, 0xff, 0xfe, 0xaf, 0xff, 0x97, 0x93, 0x01, 0x30, + 0x7f, 0x32, 0xf2, 0x9f, 0x06, 0x92, 0x08, 0x80, 0x3f, 0xf5, 0x6f, 0x86, + 0xf5, 0x3f, 0x75, 0x10, 0xb2, 0xb4, 0xb2, 0x11, 0xfc, 0x7e, 0xff, 0xcb, + 0x04, 0xff, 0xa9, 0xf8, 0x37, 0x9f, 0x32, 0xf7, 0x1f, 0xc2, 0x06, 0x92, + 0xa0, 0x2f, 0xf3, 0xaf, 0x86, 0xfa, 0x04, 0x2f, 0x94, 0xd3, 0x84, 0xb3, + 0x16, 0xa8, 0xf4, 0x2c, 0x6f, 0xbf, 0x33, 0x18, 0x06, 0x32, 0x91, 0x2e, + 0x40, 0x92, 0x8f, 0xff, 0x7e, 0xb3, 0xd3, 0x66, 0xa3, 0x80, 0x17, 0xf3, + 0xa5, 0x5f, 0xff, 0xff, 0xf8, 0x49, 0x31, 0xff, 0x82, 0x07, 0x29, 0x70, + 0x1f, 0x54, 0x8f, 0x02, 0xff, 0x95, 0xf3, 0xc4, 0x46, 0xb3, 0x17, 0xf4, + 0x00, 0x77, 0x4f, 0xff, 0xff, 0x22, 0x99, 0xff, 0xf2, 0x41, 0x9f, 0x6f, + 0xff, 0xff, 0x41, 0x1f, 0x46, 0x05, 0x00, 0xf7, 0xbf, 0xff, 0xa2, 0xf3, + 0x95, 0x36, 0xf2, 0x40, 0xcf, 0x12, 0xa9, 0xff, 0xff, 0xba, 0xf7, 0x02, + 0x00, 0x4f, 0xff, 0xfb, 0x49, 0x7e, 0xff, 0xf3, 0x6f, 0xc2, 0x03, 0xdb, + 0xff, 0x12, 0x4f, 0x36, 0x01, 0xf9, 0x00, 0xaf, 0xfb, 0x9f, 0xf8, 0xcc, + 0xbf, 0xf2, 0xb5, 0x00, 0x86, 0x45, 0xf3, 0xaf, 0xff, 0xff, 0x8b, 0xff, + 0x00, 0x87, 0xff, 0xff, 0xa7, 0xf9, 0x00, 0x1f, 0xff, 0x00, 0xff, 0xf2, + 0x09, 0xff, 0xf5, 0x3f, 0xff, 0xff, 0x61, 0xff, 0xe9, 0xd2, 0xf9, 0x21, + 0x3f, 0x36, 0xca, 0x00, 0xaf, 0xfb, 0x7f, 0xff, 0xf8, 0x8f, 0xf4, 0x86, + 0x01, 0x88, 0x25, 0xf3, 0x8f, 0xff, 0xff, 0x9b, 0x03, 0x00, 0xfb, 0x00, + 0x04, 0xff, 0xff, 0xfa, 0xa3, 0x6f, 0x30, 0xf8, 0x2f, 0x8b, 0x63, 0xf7, + 0x12, 0x5f, 0x44, 0x80, 0x94, 0xfd, 0xdf, 0xac, 0xff, 0xf6, 0x77, 0x6a, + 0x10, 0x34, 0xf5, 0x6f, 0x16, 0xfd, 0x46, 0x00, 0x1a, 0x02, 0xff, 0x59, + 0xb0, 0xaf, 0xfc, 0x2c, 0x76, 0xff, 0x00, 0xff, 0xf5, 0x10, 0x9f, 0x63, + 0xff, 0xff, 0xd9, 0x00, 0xff, 0xfb, 0xaf, 0xf7, 0x8f, 0x59, 0xff, 0xf9, + 0x00, 0x46, 0x5b, 0x34, 0xd8, 0x5f, 0xff, 0xf8, 0xaf, 0x10, 0xff, 0xff, + 0xbb, 0x01, 0x3d, 0x90, 0x00, 0x4f, 0x07, 0x82, 0x29, 0xff, 0xff, 0x28, + 0xa1, 0x89, 0xd2, 0x00, 0xf5, 0x21, 0x9f, 0xc2, 0xbf, 0xff, 0xd9, 0xff, + 0x00, 0xfa, 0x8f, 0xfe, 0xdf, 0xff, 0xff, 0xfb, 0x46, 0x02, 0x5b, 0x44, + 0x9c, 0x6f, 0xff, 0xfb, 0xa9, 0x98, 0x00, 0xf9, 0x9f, 0xff, 0x2c, 0x42, + 0x32, 0x21, 0xff, 0x0c, 0xff, 0xff, 0xff, 0x35, 0xda, 0xba, 0xff, 0xff, + 0x05, 0xf7, 0x00, 0x7f, 0xf4, 0x4f, 0xbb, 0xaf, 0x32, 0x04, 0x44, 0x5b, + 0x64, 0x5f, 0x3f, 0x14, 0xf8, 0x9f, 0x02, 0xfa, 0x44, 0x1f, 0x73, 0xf2, + 0x1f, 0x19, 0x53, 0xc0, 0x74, 0x42, 0xf7, 0x35, 0x3f, 0xfc, 0x19, 0xff, + 0x00, 0xfe, 0xef, 0xff, 0xfc, 0xcf, 0x99, 0xfb, 0xaf, 0x00, 0xff, 0x34, + 0x8f, 0xf7, 0x2f, 0x27, 0xff, 0xfc, 0x10, 0x8e, 0xff, 0xab, 0x01, 0xf3, + 0x03, 0xbf, 0x17, 0x2e, 0xff, 0x12, 0xb9, 0x91, 0x99, 0x81, 0xd2, 0xfa, + 0x00, 0x22, 0x1f, 0xff, 0x70, 0xcf, 0xf8, 0x9f, 0xff, 0x00, 0xbc, 0xee, + 0xbb, 0xf9, 0x8f, 0xff, 0x88, 0xa7, 0x00, 0x7b, 0x18, 0x72, 0xff, 0xfd, + 0xaf, 0xff, 0x89, 0x80, 0x01, 0x90, 0x13, 0xe6, 0x1f, 0xff, 0xf1, 0x3f, + 0x0e, 0xff, 0xff, 0xf2, 0x9f, 0x91, 0x79, 0x61, 0xfc, 0x00, 0x04, 0x19, + 0xff, 0xf5, 0x0c, 0xfe, 0xef, 0xff, 0x00, 0x9a, 0x99, 0xf9, 0xdf, 0xff, + 0xff, 0x62, 0x45, 0x08, 0x46, 0xa5, 0xc3, 0x0c, 0x14, 0xf5, 0x00, 0x06, + 0x05, 0x50, 0xbf, 0xff, 0xfd, 0x09, 0xb1, 0x3f, 0x74, 0x81, 0x42, 0x38, + 0x90, 0xdf, 0xff, 0x71, 0xef, 0x02, 0x00, 0xe7, 0xbf, 0xff, 0xf7, 0x0c, + 0xff, 0xff, 0xf9, 0x00, 0x23, 0x61, 0x59, 0xbb, 0xce, 0xcd, 0xfe, 0x74, + 0x0a, 0x20, 0x00, 0x00, 0x2f, 0x41, 0x81, 0x19, 0x17, 0xc0, 0x02, 0xe2, + 0xff, 0xff, 0x90, 0x55, 0x0b, 0xff, 0x20, 0x90, 0x07, 0x85, 0x50, 0x35, + 0x43, 0x32, 0x12, 0x00, 0x8f, 0xfd, 0x64, 0x65, 0x54, 0x45, 0x34, 0x34, + 0x00, 0x94, 0x03, 0x69, 0x13, 0x7c, 0xff, 0xff, 0xf2, 0x06, 0x2f, 0xff, + 0xff, 0xa1, 0xcf, 0x04, 0xd1, 0xf1, 0x00, 0x0f, 0x80, 0x51, 0x45, 0x00, + 0x17, 0xbe, 0xef, 0x00, 0xff, 0xfd, 0xa7, 0x61, 0x0c, 0xf8, 0x66, 0x78, + 0x40, 0xdf, 0x2a, 0xfc, 0xff, 0x17, 0xff, 0xf2, 0x3c, 0x04, 0x4a, 0xb5, + 0x32, 0x4a, 0xff, 0xb1, 0xff, 0xf4, 0x60, 0x2f, 0x5a, 0x3a, 0xff, 0xfc, + 0x00, 0x34, 0xc2, 0x00, 0x67, 0x00, 0x00, 0x10, 0x11, 0x22, 0x33, 0x24, + 0x40, 0x23, 0x57, 0xff, 0xff, 0x26, 0xff, 0xf2, 0x01, 0x00, 0xb8, 0xcf, + 0xff, 0x10, 0x9f, 0xff, 0x90, 0xaf, 0x10, 0xff, 0xff, 0x19, 0x37, 0xff, + 0xb0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x3f, 0x67, + 0x80, 0x1a, 0x43, 0xff, 0xf2, 0x75, 0x15, 0xdf, 0xb8, 0x06, 0x70, 0x0a, + 0xff, 0xf8, 0x08, 0x92, 0x1f, 0xfd, 0x00, 0x52, 0x11, 0x41, 0x00, 0x02, + 0x33, 0xe8, 0xab, 0x40, 0x06, 0x67, 0xff, 0xff, 0xfe, 0xff, 0x71, 0xff, + 0x00, 0xf3, 0x2f, 0xa2, 0x23, 0xa4, 0x31, 0x0b, 0xff, 0x06, 0xff, 0x91, + 0x26, 0xa5, 0x19, 0x27, 0x02, 0xf1, 0x01, 0x04, 0x24, 0x91, 0xff, 0xff, + 0xa0, 0x8f, 0x5f, 0x00, 0xff, 0xfe, 0xff, 0xb1, 0xaf, 0xff, 0x12, 0xcf, + 0x08, 0xf6, 0x13, 0x00, 0x7f, 0x01, 0x93, 0x23, 0xbf, 0xc0, 0x2f, 0x02, + 0x60, 0xbf, 0x38, 0xf2, 0x0d, 0xff, 0x30, 0xf9, 0x09, 0x5f, 0x11, 0xf2, + 0x3f, 0xff, 0xe2, 0x0c, 0x12, 0x9f, 0xb3, 0x5f, 0x67, 0x1f, 0xff, 0xff, + 0x00, 0x14, 0xf8, 0x3f, 0xff, 0x50, 0x8f, 0xff, 0x61, 0x20, 0x11, 0x2a, + 0x17, 0xff, 0xfb, 0x1a, 0xfa, 0x9c, 0x38, 0x44, 0x07, 0x87, 0x3f, 0x01, + 0xf9, 0x1f, 0xf1, 0x00, 0x2f, 0xff, 0xfa, 0x06, 0xff, 0xfc, 0x30, 0x0a, + 0x80, 0x07, 0xff, 0xff, 0x50, 0xae, 0x25, 0x30, 0x19, 0xe0, 0x87, 0x3f, + 0x01, 0xfa, 0x0b, 0xa2, 0x10, 0x9f, 0x02, 0xff, 0x90, 0x9f, 0xf8, 0x12, + 0x05, 0x07, 0xff, 0x03, 0xff, 0xf8, 0x33, 0x30, 0x56, 0xcf, 0x87, 0x3f, + 0x80, 0x02, 0x06, 0xf2, 0x40, 0x1f, 0xff, 0xf7, 0x06, 0x19, 0x3b, 0x90, + 0x2e, 0x07, 0x01, 0xfc, 0x89, 0x97, 0xc0, 0x4f, 0x04, 0x70, 0x96, 0x10, + 0x2f, 0xff, 0xff, 0x0f, 0x60, 0x01, 0x71, 0x5f, 0x07, 0x07, 0x77, 0x2f, + 0x00, 0xff, 0xff, 0xf9, 0x36, 0x42, 0xaf, 0xff, 0xff, 0x1e, 0xfa, 0xce, + 0x89, 0x07, 0x07, 0x77, 0x2f, +}; + +const uint8_t g_pui8Image_Splash3[] = +{ + IMAGE_FMT_4BPP_COMP, + 96, 0, + 64, 0, + + 15, + 0x00, 0x00, 0x00, + 0x2a, 0x2a, 0x2a, + 0x44, 0x44, 0x44, + 0x56, 0x56, 0x56, + 0x67, 0x67, 0x67, + 0x76, 0x76, 0x76, + 0x87, 0x87, 0x87, + 0x97, 0x97, 0x97, + 0xa5, 0xa5, 0xa5, + 0xb7, 0xb7, 0xb7, + 0xc8, 0xc8, 0xc8, + 0xd6, 0xd6, 0xd6, + 0xe2, 0xe2, 0xe2, + 0xec, 0xec, 0xec, + 0xf7, 0xf7, 0xf7, + 0xff, 0xff, 0xff, + + 0x1f, 0xff, 0xff, 0xff, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x02, 0x3e, 0xfb, 0x4e, 0x07, 0x07, 0x77, 0x2f, 0x07, 0xff, + 0x3e, 0xf9, 0x05, 0x07, 0x07, 0x77, 0x2f, 0x07, 0xff, 0x1f, 0xf5, 0x11, + 0xbf, 0x07, 0x07, 0x77, 0x2f, 0x07, 0x1f, 0xf1, 0x84, 0x3f, 0x07, 0x07, + 0x77, 0x2f, 0x07, 0x1e, 0xf1, 0xba, 0x1e, 0x07, 0x07, 0x77, 0x29, 0xdc, + 0x08, 0xd9, 0x77, 0xca, 0x8c, 0x07, 0xff, 0xc1, 0xdf, 0x4e, 0x18, 0x02, + 0xfe, 0xcf, 0x6f, 0x27, 0x03, 0x61, 0x00, 0x31, 0x03, 0x34, 0x01, 0x32, + 0x27, 0xf9, 0x33, 0x08, 0x33, 0x33, 0x12, 0x4b, 0x01, 0xa1, 0xff, 0x24, + 0x8e, 0x01, 0xfa, 0x41, 0x1f, 0x05, 0xcd, 0x95, 0xfe, 0x00, 0x61, 0x08, + 0xf8, 0x1f, 0xff, 0x08, 0xff, 0xa1, 0x00, 0x01, 0x59, 0xab, 0x96, 0x65, + 0x20, 0x13, 0x7f, 0x00, 0xff, 0x92, 0xff, 0x51, 0xff, 0xff, 0xfb, 0x11, + 0x38, 0x72, 0x3f, 0x03, 0xdb, 0xb7, 0xfd, 0x75, 0x31, 0x00, 0x27, 0x9f, + 0xfc, 0x8f, 0xfa, 0x2d, 0xff, 0xa1, 0x40, 0x5f, 0x0a, 0xfe, 0x94, 0x11, + 0x3e, 0xc2, 0xef, 0x01, 0x61, 0xff, 0xff, 0x80, 0x5f, 0xe1, 0xaf, 0x7a, + 0xc0, 0x5a, 0xc6, 0xff, 0xff, 0xe6, 0x22, 0x25, 0x14, 0x00, 0xfe, 0xcf, + 0xf9, 0x6f, 0xfe, 0xef, 0xfa, 0x09, 0x80, 0x15, 0xf9, 0x20, 0x32, 0xdf, + 0x51, 0xff, 0xf8, 0x1c, 0x09, 0xff, 0x22, 0x7d, 0x45, 0x0a, 0xc3, 0x02, + 0x00, 0x7d, 0xff, 0xbc, 0xfe, 0x18, 0xf9, 0x1f, 0xf6, 0x10, 0x8f, 0xfb, + 0xaf, 0x0e, 0xfc, 0x10, 0xcf, 0x33, 0x06, 0xff, 0xa0, 0x9f, 0xf7, 0x0e, + 0x7e, 0x3e, 0xff, 0x00, 0xf4, 0x02, 0xbf, 0xff, 0xfe, 0x1a, 0xff, 0x32, + 0x08, 0xfb, 0x1b, 0xf3, 0x6f, 0x1f, 0xff, 0xff, 0xf2, 0x01, 0x7f, 0x24, + 0xff, 0x14, 0xff, 0x90, 0x9f, 0x6f, 0x88, 0x25, 0xfa, 0x01, 0xcf, 0x01, + 0x41, 0xff, 0x81, 0x08, 0xff, 0x17, 0xf2, 0x7f, 0x1f, 0xff, 0xff, 0xf4, + 0x03, 0x2f, 0x30, 0xda, 0x0f, 0xf6, 0x07, 0x77, 0x2e, 0x20, 0x60, 0x7f, + 0x02, 0xe1, 0x8f, 0xd1, 0xbf, 0x34, 0x20, 0xf1, 0x8f, 0x17, 0xff, 0xff, + 0xfb, 0x1f, 0x60, 0x0c, 0x00, 0x9f, 0x10, 0xaf, 0x77, 0x2d, 0xf5, 0x0b, + 0x81, 0x03, 0xf3, 0x2f, 0xf2, 0x6f, 0x44, 0xf1, 0x17, 0x83, 0x02, 0x34, + 0xf5, 0x37, 0xf1, 0x2f, 0x7f, 0x36, 0x20, 0x50, 0xcf, 0x03, 0xfa, 0x1c, + 0xf4, 0x3f, 0x53, 0x02, 0xf1, 0xbf, 0x39, 0xff, 0xfb, 0x8f, 0x05, 0xfe, + 0x0e, 0x05, 0xff, 0xff, 0x51, 0xa5, 0x6d, 0x31, 0xfa, 0x40, 0x0a, 0x0d, + 0x24, 0xf8, 0x1f, 0x73, 0xd1, 0xed, 0x08, 0x1c, 0xff, 0xfb, 0x7f, 0x05, + 0xf1, 0x1f, 0xff, 0x1d, 0xff, 0xb0, 0xaf, 0x15, 0x65, 0x51, 0x5f, 0x0d, + 0x01, 0x71, 0xfc, 0x1e, 0xa2, 0xb1, 0xf8, 0x1f, 0x05, 0x0b, 0xee, 0xff, + 0xff, 0x21, 0x01, 0xf4, 0x86, 0x4d, 0x10, 0xff, 0xff, 0x61, 0x7e, 0xe1, + 0x9f, 0x19, 0xe1, 0x04, 0x92, 0xf6, 0x2f, 0xe8, 0xef, 0x02, 0xfe, 0x4b, + 0x16, 0xff, 0xf8, 0x0d, 0x02, 0x07, 0x0e, 0xc6, 0x18, 0xa0, 0x0a, 0xb6, + 0x29, 0xf3, 0x4f, 0x26, 0xf2, 0x71, 0x00, 0xf4, 0x3f, 0xd8, 0xef, 0xff, + 0xf5, 0x9f, 0xff, 0x04, 0xfe, 0xcf, 0xff, 0xf1, 0x7f, 0x02, 0x90, 0xef, + 0xe4, 0x02, 0xb2, 0xc4, 0xf9, 0x1e, 0x52, 0xdc, 0xff, 0x00, 0xfc, 0xaf, + 0xf8, 0x2f, 0x53, 0xf2, 0x52, 0xf4, 0x4a, 0x5f, 0x09, 0xfa, 0xdf, 0x02, + 0x81, 0x03, 0xf1, 0x72, 0x4f, 0xcb, 0xa3, 0x52, 0xf4, 0x2f, 0x84, 0xf9, + 0x00, 0x7f, 0xfe, 0x1c, 0x92, 0xf2, 0x52, 0xf3, 0x6f, 0xa6, 0x0f, 0x22, + 0x03, 0xf8, 0x1e, 0x7f, 0x33, 0xf1, 0x10, 0x7f, 0xff, 0x69, 0x75, 0x25, + 0xe2, 0xf3, 0x22, 0x27, 0xf3, 0x7f, 0x0f, 0x16, 0xaf, 0xcc, 0x7f, 0x33, + 0x08, 0xa1, 0xdf, 0xff, 0xbd, 0x75, 0x62, 0xf2, 0xf4, 0x00, 0x13, 0xf2, + 0x7f, 0xff, 0xfc, 0xdf, 0xff, 0xfa, 0x00, 0xaf, 0xff, 0xff, 0xfc, 0x29, + 0x4f, 0xff, 0xff, 0x0d, 0xfe, 0xbe, 0xff, 0x51, 0x15, 0xcd, 0x71, 0x8a, + 0x40, 0xa5, 0x63, 0xb1, 0xe2, 0xb6, 0x13, 0xd2, 0x8f, 0x00, 0xff, 0xf7, + 0x9f, 0xff, 0xf9, 0x8f, 0xfe, 0x6c, 0x00, 0xfa, 0x2a, 0x3f, 0xff, 0xff, + 0x91, 0x14, 0xff, 0x3a, 0xa1, 0xcf, 0x1b, 0xdb, 0xb1, 0x61, 0x92, 0xdb, + 0x00, 0xff, 0xff, 0xd6, 0xef, 0xff, 0xf2, 0xb4, 0x87, 0x10, 0x23, 0xd2, + 0x7f, 0x14, 0xfe, 0xad, 0xfa, 0x2c, 0x00, 0x1b, 0xff, 0xff, 0x45, 0xfb, + 0xef, 0xf1, 0x6f, 0xc1, 0x74, 0x44, 0xff, 0x52, 0xff, 0xff, 0xda, 0x7a, + 0x82, 0xd9, 0xf3, 0x86, 0x68, 0x13, 0xe3, 0x17, 0xfd, 0x00, 0x17, 0x36, + 0xff, 0xff, 0xf7, 0x17, 0xff, 0xf4, 0x61, 0x2f, 0x76, 0x33, 0x32, 0xff, + 0xe9, 0xa7, 0x7d, 0x02, 0xf5, 0x58, 0x47, 0x23, 0xc4, 0x4f, 0x17, 0x10, + 0x00, 0x42, 0xef, 0xff, 0xb9, 0xf9, 0x5f, 0xf8, 0x1f, 0xc2, 0x77, 0x2a, + 0x32, 0xff, 0xd6, 0xef, 0x01, 0x66, 0x00, 0xff, 0xda, 0xef, 0xf9, 0x28, + 0x46, 0x44, 0x97, 0x40, 0x2f, 0x11, 0xfd, 0xdf, 0xff, 0xfc, 0x6e, 0xff, + 0x00, 0x20, 0x21, 0x1f, 0xff, 0x82, 0x60, 0x4f, 0xfc, 0x72, 0x1a, 0x09, + 0x59, 0xd4, 0xff, 0x91, 0x01, 0xfe, 0x00, 0xff, 0xff, 0xcc, 0xff, 0xb6, + 0xff, 0xfd, 0x26, 0x08, 0x47, 0x45, 0x79, 0x1f, 0x11, 0xf8, 0x9f, 0xff, + 0x00, 0xfc, 0x7f, 0xff, 0x22, 0x10, 0x00, 0x8f, 0xf9, 0x0d, 0x5a, 0xff, + 0xff, 0x17, 0x71, 0x59, 0xba, 0xcc, 0x04, 0xd1, 0xaf, 0xff, 0xff, 0xa6, + 0x74, 0xff, 0x26, 0x00, 0x47, 0x56, 0x4d, 0x1c, 0xff, 0xfe, 0x7d, 0xff, + 0x20, 0xff, 0xbd, 0x19, 0x18, 0x40, 0x11, 0x13, 0xdf, 0xa4, 0x31, 0x23, + 0x14, 0x50, 0x9f, 0xc3, 0xf2, 0x3f, 0x10, 0xff, 0xff, 0xed, 0x74, 0xff, + 0x26, 0x44, 0x5a, 0x00, 0x2f, 0x18, 0xff, 0xff, 0xbf, 0xda, 0xff, 0x79, + 0x00, 0xff, 0xff, 0xfd, 0x28, 0x14, 0x94, 0xf5, 0x09, 0xa0, 0x31, 0x61, + 0x14, 0xa0, 0x05, 0xba, 0xb8, 0x9f, 0x10, 0xff, 0xff, 0xfb, 0x6a, 0xf8, + 0x7f, 0xfe, 0x9e, 0x82, 0x31, 0x25, 0x45, 0x8f, 0x5d, 0x53, 0x11, 0xb7, + 0x80, 0x02, 0xf6, 0x39, 0x08, 0x56, 0xff, 0x60, 0xcf, 0x08, 0xff, 0xff, + 0xb1, 0xbf, 0x8a, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x02, 0x51, 0x9f, 0xff, + 0xff, 0x50, 0xff, 0x02, 0xff, 0x87, 0xfc, 0xcf, 0xfd, 0x6e, 0x59, 0x79, + 0x04, 0xfb, 0x8f, 0x52, 0x80, 0xcf, 0x13, 0xff, 0xff, 0x01, 0xf1, 0x10, + 0x24, 0x2f, 0xff, 0xf5, 0x0f, 0xb9, 0x40, 0x5f, 0x74, 0xb7, 0x56, 0x12, + 0x72, 0x04, 0xff, 0x04, 0xff, 0xf2, 0x2f, 0xff, 0xaa, 0x7c, 0xff, 0xb4, + 0x04, 0x22, 0x02, 0x44, 0x71, 0x09, 0x9d, 0x40, 0x00, 0x00, 0x22, 0xdf, + 0xff, 0xff, 0x13, 0xff, 0xff, 0xfa, 0x40, 0x0c, 0x0d, 0xff, 0xf9, 0x01, + 0xf1, 0x3f, 0xff, 0x20, 0xf9, 0x04, 0x8e, 0xfa, 0x07, 0xbe, 0xfd, 0xab, + 0x08, 0x32, 0x41, 0x24, 0xaf, 0x01, 0xfe, 0x81, 0x00, 0x2a, 0x00, 0x3d, + 0x39, 0xb1, 0x99, 0x22, 0x05, 0xff, 0x00, 0xff, 0xf2, 0x37, 0x04, 0xfb, + 0x30, 0x61, 0x1b, 0x80, 0x85, 0xf1, 0x05, 0x66, 0x43, 0x11, 0x4e, 0xff, + 0x00, 0xa5, 0x22, 0x24, 0x46, 0x75, 0x30, 0x00, 0x01, 0x20, 0xa3, 0x5f, + 0x41, 0xf4, 0x1f, 0xff, 0xff, 0xd1, 0x60, 0x9f, 0x04, 0x89, 0x20, 0x43, + 0x11, 0x72, 0x31, 0x20, 0x00, 0x3a, 0x83, 0xd6, 0x02, 0xe6, 0x43, 0x35, + 0x40, 0xaf, 0x29, 0xfa, 0x54, 0x41, 0x00, 0x02, 0x10, 0x10, 0x2f, 0xfb, + 0x1c, 0x4a, 0x06, 0xff, 0xff, 0xf5, 0x60, 0x1f, 0x03, 0x92, 0xf5, 0x01, + 0x01, 0x30, 0x00, 0x00, 0x3c, 0x10, 0x12, 0x22, 0x12, 0x11, 0x32, 0x22, + 0x40, 0x8f, 0x4f, 0xf5, 0x00, 0x7f, 0x35, 0x3d, 0xff, 0x41, 0x23, 0x82, + 0xb0, 0x9f, 0xff, 0xff, 0x18, 0x3f, 0x00, 0xff, 0xa2, 0x00, 0x00, 0x28, + 0xf9, 0x00, 0x00, 0x04, 0x00, 0x00, 0x11, 0x09, 0xdf, 0x57, 0xff, 0xe1, + 0x00, 0x05, 0xf9, 0x1f, 0x61, 0xff, 0xe1, 0x14, 0x6c, 0x01, 0xff, 0xff, + 0xf7, 0x0d, 0xff, 0xff, 0x62, 0x37, 0x80, 0x03, 0xf3, 0x03, 0x10, 0x00, + 0x9f, 0xff, 0x15, 0x80, 0x5f, 0xff, 0xfd, 0x00, 0x7f, 0xf1, 0x6f, 0xf1, + 0x00, 0x7f, 0xfc, 0x67, 0x21, 0x4f, 0xff, 0xff, 0x71, 0x18, 0x58, 0x74, + 0x12, 0x2f, 0x03, 0x20, 0x7f, 0xf0, 0x04, 0x59, 0x16, 0xff, 0xc0, 0x9f, + 0x57, 0xf2, 0x3f, 0x00, 0xff, 0x12, 0xff, 0xfb, 0x08, 0xff, 0xfd, 0x30, + 0x01, 0x1e, 0xff, 0xff, 0xfa, 0x43, 0x44, 0x8f, 0x37, 0x90, 0x02, 0xe1, + 0x06, 0x11, 0xc0, 0x3f, 0xf7, 0x04, 0x40, 0xef, 0x4e, 0xb1, 0xdf, 0xe1, + 0x0c, 0xff, 0xff, 0x07, 0xa1, 0x25, 0x51, 0x00, 0x3f, 0x6e, 0x2e, 0x01, + 0x00, 0x14, 0xff, 0xf0, 0x2f, 0xff, 0xfc, 0x09, 0xff, 0x20, 0x80, 0x06, + 0x1e, 0x80, 0x25, 0x00, 0x8f, 0xff, 0x03, 0xff, 0xfd, 0x77, 0x65, 0x06, + 0xdf, 0x6e, 0x2e, 0x02, 0xff, 0xff, 0xfe, 0x1b, 0xb4, 0x05, 0x51, 0x60, + 0x08, 0x9f, 0x80, 0x01, 0xef, 0x15, 0x50, 0x00, 0x18, 0xb8, 0x04, 0xed, + 0x7d, 0x45, 0x0c, 0x41, 0x21, 0x07, 0x84, 0x11, 0xf8, 0x02, 0x10, 0x0a, + 0x16, 0xed, 0x8d, 0xe1, 0x07, 0xbf, 0x77, 0xff, 0xb0, 0x00, 0x05, 0x0a, + 0x1e, 0xf6, 0x22, 0xcf, 0x07, 0x07, 0x77, 0x2f, 0xff, 0x0f, 0xff, 0xf9, + 0x45, 0xbf, 0x07, 0x07, 0x77, 0x2f, 0xfc, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, +}; + +const uint8_t g_pui8Image_Splash4[] = +{ + IMAGE_FMT_4BPP_COMP, + 96, 0, + 64, 0, + + 15, + 0x00, 0x00, 0x00, + 0x29, 0x29, 0x29, + 0x42, 0x42, 0x42, + 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, + 0x98, 0x98, 0x98, + 0xa5, 0xa5, 0xa5, + 0xb4, 0xb4, 0xb4, + 0xc6, 0xc6, 0xc6, + 0xd8, 0xd8, 0xd8, + 0xe6, 0xe6, 0xe6, + 0xf1, 0xf1, 0xf1, + 0xfa, 0xfa, 0xfa, + 0xff, 0xff, 0xff, + + 0x1f, 0xff, 0xff, 0xff, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xe7, 0x07, 0x07, 0x01, 0xfc, 0xaf, + 0x07, 0x07, 0x77, 0xc7, 0x2f, 0x07, 0xff, 0xf3, 0x0d, 0x07, 0x07, 0x77, + 0xc7, 0x2f, 0x07, 0xff, 0xa1, 0x17, 0x07, 0x07, 0x77, 0xc7, 0x2f, 0x07, + 0xff, 0x45, 0x72, 0x07, 0x07, 0x77, 0xc7, 0x2f, 0x07, 0xff, 0x28, 0xb1, + 0x07, 0x07, 0x77, 0x88, 0x2a, 0xed, 0xff, 0xef, 0x07, 0xff, 0xff, 0xfc, + 0x1c, 0x1b, 0xe1, 0xbf, 0x07, 0x47, 0x07, 0xfd, 0x55, 0x00, 0x42, 0x12, + 0x22, 0x11, 0x18, 0xff, 0xfc, 0xab, 0x21, 0x9a, 0xce, 0x03, 0xf7, 0x1f, + 0xd1, 0xaf, 0x01, 0x70, 0xa8, 0x05, 0xcd, 0x96, 0xb6, 0x50, 0x24, 0x05, + 0x00, 0xcf, 0x51, 0xca, 0x51, 0x54, 0x12, 0x23, 0x33, 0x10, 0x33, 0x33, + 0x5b, 0x01, 0xf4, 0x2f, 0xe1, 0xaf, 0x0e, 0xff, 0xff, 0x83, 0x01, 0x04, + 0xd4, 0xa7, 0xd2, 0x00, 0x03, 0x59, 0xff, 0x6b, 0xff, 0x6a, 0xff, 0xff, + 0x00, 0x10, 0x6e, 0xff, 0xff, 0xdc, 0xb7, 0x31, 0x19, 0x00, 0xff, 0xff, + 0xf2, 0x4f, 0xd1, 0xaf, 0xff, 0xa0, 0x38, 0x1a, 0x25, 0x03, 0xdb, 0xb6, + 0xfb, 0x53, 0x42, 0x00, 0x02, 0xcf, 0xbc, 0xff, 0xff, 0xfc, 0x1b, 0xff, + 0x20, 0xe1, 0x1e, 0x0b, 0xfc, 0x52, 0x14, 0xbf, 0xf2, 0x01, 0x6f, 0xc1, + 0xaf, 0xf6, 0x05, 0xfb, 0x1d, 0x7b, 0xc0, 0x53, 0xb5, 0xf6, 0x11, 0x47, + 0x86, 0x2b, 0xff, 0x01, 0x41, 0xff, 0xff, 0xfa, 0x1f, 0xff, 0x02, 0x16, + 0x00, 0xb4, 0x04, 0xf2, 0x8f, 0x91, 0xdf, 0x50, 0xbf, 0x30, 0xf2, 0x5f, + 0x76, 0x36, 0xfa, 0x11, 0x7f, 0xff, 0x00, 0xff, 0xcc, 0xff, 0xa1, 0xef, + 0x4b, 0xf9, 0x1f, 0x20, 0xfa, 0x2e, 0x17, 0xd2, 0x11, 0x8f, 0x52, 0xf6, + 0x19, 0x0b, 0xff, 0x50, 0x7f, 0x36, 0x30, 0x7f, 0x01, 0x01, 0xf2, 0x8f, + 0xf2, 0x7f, 0x19, 0xf7, 0x2f, 0x1f, 0x80, 0x01, 0x60, 0x8f, 0x27, 0xc0, + 0xaf, 0xf7, 0x0b, 0xc8, 0x6f, 0x25, 0xc0, 0x1d, 0x02, 0xf4, 0x1f, 0xf4, + 0x0c, 0x3f, 0x17, 0xf6, 0x2f, 0x1f, 0x6a, 0x3f, 0x2b, 0x0c, 0x25, 0xff, + 0x30, 0xaf, 0x6f, 0x24, 0xf9, 0x05, 0x80, 0x03, 0xfe, 0x18, 0xf9, 0x1f, + 0x34, 0xf5, 0x2f, 0xc0, 0x1f, 0x01, 0xfa, 0x1d, 0x20, 0x2f, 0xc0, 0x1c, + 0xc8, 0x77, 0x2d, 0xa0, 0x6f, 0x04, 0x32, 0xfd, 0x1d, 0x18, 0x52, 0xf3, + 0x3f, 0x17, 0x01, 0xf7, 0x0f, 0xb4, 0x32, 0xcb, 0x04, 0x7f, 0x35, 0xfb, + 0x07, 0x05, 0x90, 0x06, 0xff, 0x19, 0x92, 0xf2, 0x4f, 0x0f, 0x01, 0x70, + 0x0c, 0x9f, 0xff, 0xf0, 0x7f, 0x7f, 0x35, 0xf1, 0x3f, 0x81, 0xbe, 0x8f, + 0x26, 0xb1, 0xf3, 0x4f, 0x2c, 0x07, 0x01, 0xff, 0xf5, 0x0a, 0xff, 0xff, + 0xf2, 0x5f, 0x87, 0xa0, 0x3d, 0x51, 0x06, 0xf4, 0x3f, 0x53, 0xc1, 0xf4, + 0x20, 0x5b, 0x1f, 0x07, 0xff, 0x70, 0xaf, 0xff, 0xff, 0x34, 0xfa, 0x1b, + 0x87, 0x3d, 0x06, 0x06, 0xf9, 0x1f, 0x04, 0x82, 0xd1, 0xf5, 0x47, 0x2f, + 0x07, 0xfb, 0x08, 0xb2, 0x02, 0x32, 0x87, 0x3c, 0xf9, 0x0e, 0x7f, 0x19, + 0x04, 0xc2, 0xd2, 0xd6, 0x44, 0x3f, 0x01, 0xfd, 0x5c, 0xa3, 0x02, 0xf2, + 0xaa, 0xff, 0xd0, 0x9f, 0x07, 0xbb, 0x90, 0x54, 0xff, 0x6b, 0x21, 0x33, + 0xf1, 0xd2, 0xb8, 0x00, 0x33, 0x6f, 0xd6, 0xdf, 0xff, 0xfe, 0xae, 0xff, + 0x04, 0xfd, 0xef, 0xff, 0xa1, 0xcf, 0x02, 0xf6, 0x2f, 0xe5, 0x03, 0xdb, + 0x82, 0xb0, 0xaf, 0x83, 0xbd, 0x21, 0x00, 0x71, 0xf2, 0xb3, 0xa9, 0x12, + 0x8f, 0xd9, 0xdf, 0x42, 0xf8, 0x69, 0xf5, 0xbf, 0xff, 0x32, 0x03, 0xfd, + 0x74, 0x1a, 0x03, 0xa3, 0x7a, 0x51, 0x8d, 0xf9, 0xbf, 0x00, 0xff, 0xd1, + 0xc3, 0xa4, 0x89, 0x12, 0xaf, 0xff, 0x20, 0xff, 0xf7, 0xe1, 0xfd, 0xef, + 0xff, 0x16, 0xdf, 0xb1, 0x2b, 0x33, 0x04, 0xd4, 0xff, 0xff, 0x32, 0x5b, + 0x00, 0xef, 0xf6, 0x8a, 0xcb, 0x9f, 0xf2, 0x94, 0x85, 0x00, 0x69, 0x02, + 0xcf, 0xfe, 0xef, 0xff, 0xff, 0xf7, 0x02, 0x9f, 0xff, 0xff, 0xfd, 0x18, + 0x2d, 0x01, 0x79, 0x3a, 0xff, 0x81, 0x02, 0xe2, 0xc4, 0x23, 0x31, 0xbf, + 0x00, 0xf6, 0x7f, 0xfb, 0xcf, 0xfb, 0x9f, 0xf4, 0x56, 0x00, 0x76, 0x58, + 0x03, 0xff, 0xe4, 0xbf, 0xff, 0xff, 0x00, 0xf9, 0xaf, 0xf7, 0xbf, 0xfb, + 0x1a, 0x2b, 0xff, 0x00, 0xff, 0xf2, 0x43, 0x5f, 0xf1, 0x9f, 0xff, 0xff, + 0x60, 0xff, 0xe9, 0xd4, 0xff, 0x15, 0xff, 0xff, 0xfa, 0x10, 0x4f, 0xfc, + 0xcf, 0x62, 0xf8, 0x45, 0x68, 0x49, 0x04, 0x03, 0xff, 0xfc, 0xfa, 0x7f, + 0x01, 0xf6, 0xbf, 0x00, 0xfd, 0x06, 0x38, 0xff, 0xff, 0xb1, 0x78, 0xaf, + 0x30, 0xf3, 0x5f, 0x22, 0x02, 0xff, 0xff, 0xeb, 0xad, 0x08, 0xff, 0x16, + 0xff, 0xf9, 0x02, 0xaa, 0xff, 0xfc, 0x00, 0xdf, 0xfc, 0x24, 0x59, 0x3a, + 0x02, 0xff, 0xff, 0x22, 0xfc, 0xaf, 0x03, 0xfd, 0x01, 0x35, 0x41, 0x01, + 0x18, 0xff, 0xf6, 0x3f, 0x8b, 0x62, 0xf7, 0x10, 0x00, 0x08, 0x3f, 0x24, + 0xff, 0xfb, 0x02, 0x87, 0xff, 0xf6, 0x01, 0xaf, 0xff, 0x24, 0x48, 0x39, + 0x12, 0xcf, 0x12, 0x20, 0xfe, 0x7d, 0xe1, 0x10, 0x01, 0xdf, 0xff, 0xe4, + 0x0c, 0x79, 0x3d, 0xfa, 0x1e, 0x72, 0x52, 0xff, 0x20, 0x08, 0x10, 0x00, + 0x11, 0x14, 0x01, 0xfb, 0x7f, 0xa9, 0x80, 0x63, 0x24, 0x49, 0x39, 0x11, + 0xaf, 0xff, 0x89, 0x08, 0xff, 0xff, 0xfe, 0x7c, 0x01, 0x10, 0x00, 0x2d, + 0x03, 0xff, 0xf4, 0x30, 0x3f, 0xff, 0x19, 0x23, 0x01, 0x02, 0xf5, 0x23, + 0x02, 0xa4, 0x02, 0x02, 0x31, 0xfb, 0x08, 0x8f, 0x98, 0xff, 0xfe, 0x51, + 0x25, 0x39, 0x29, 0x00, 0x31, 0x5f, 0xff, 0xbb, 0xff, 0x49, 0xff, 0xff, + 0x00, 0xe7, 0xcf, 0xff, 0x24, 0x20, 0x00, 0x5f, 0xff, 0x0c, 0x71, 0xaf, + 0xff, 0x34, 0x31, 0x19, 0xff, 0xff, 0x00, 0xf2, 0x00, 0x4f, 0xff, 0x11, + 0x30, 0xaf, 0xff, 0x40, 0xfe, 0x7a, 0xf8, 0x9f, 0xff, 0xff, 0x25, 0x9a, + 0x10, 0x2a, 0x42, 0x3f, 0x11, 0xab, 0xff, 0xff, 0xf9, 0x01, 0xcf, 0xfe, + 0x19, 0xf2, 0x01, 0x01, 0xcf, 0x29, 0x60, 0x52, 0x0a, 0xe2, 0xf2, 0x40, + 0x89, 0xdf, 0x30, 0x08, 0x22, 0x4f, 0xff, 0xb5, 0x7a, 0xfd, 0xdf, 0xff, + 0x02, 0xff, 0x25, 0xff, 0xcf, 0x36, 0x2b, 0x12, 0xf6, 0x00, 0xaf, 0xff, + 0xff, 0xfb, 0x1d, 0x80, 0x42, 0xe3, 0x58, 0x0b, 0x29, 0x81, 0x0a, 0x52, + 0xf1, 0x31, 0x50, 0x00, 0x44, 0x12, 0x4c, 0x09, 0xff, 0xdc, 0xff, 0xb6, + 0x80, 0x49, 0xf9, 0xaf, 0xff, 0x33, 0x8b, 0xaf, 0xef, 0x00, 0x44, 0xff, + 0xfc, 0x7e, 0xff, 0xf9, 0xbf, 0xff, 0x01, 0xff, 0xf6, 0x1f, 0x11, 0x35, + 0xff, 0x60, 0xb9, 0x30, 0xd1, 0xaf, 0x11, 0xe9, 0xff, 0xf1, 0x11, 0x83, + 0x00, 0x00, 0x00, 0xcf, 0x50, 0xdf, 0xff, 0xff, 0xdc, 0x00, 0xff, 0xcb, + 0xfe, 0xdc, 0xdf, 0xff, 0x22, 0x16, 0x02, 0x17, 0x56, 0x80, 0x7d, 0xfc, + 0x7e, 0x14, 0x75, 0x00, 0x41, 0x0b, 0xff, 0xf4, 0x0f, 0xff, 0xff, 0xf3, + 0x60, 0x5f, 0x83, 0xb9, 0x21, 0x4f, 0x75, 0x8d, 0xff, 0x20, 0xf5, 0x0d, + 0x0a, 0x96, 0xfc, 0x7f, 0xff, 0xfc, 0x01, 0x12, 0x66, 0x86, 0x72, 0x00, + 0x11, 0x2a, 0x0b, 0x00, 0xfd, 0x21, 0x21, 0xab, 0x52, 0xcf, 0xff, 0x13, + 0x08, 0xff, 0xff, 0xf8, 0x1f, 0x7b, 0xff, 0xff, 0xf7, 0x22, 0x2f, 0x15, + 0x29, 0xf2, 0x12, 0xaf, 0x83, 0xef, 0x00, 0xff, 0xf4, 0x02, 0x65, 0x65, + 0x43, 0x4b, 0xfb, 0x00, 0x31, 0x24, 0x67, 0x8a, 0xcb, 0xa8, 0x50, 0x00, + 0x00, 0x01, 0x2b, 0xf2, 0x4f, 0xff, 0xb0, 0x8f, 0xff, 0x30, 0xff, 0x09, + 0x03, 0xd9, 0x22, 0x43, 0x36, 0x78, 0x02, 0x62, 0x07, 0xf0, 0x02, 0x8b, + 0xef, 0x72, 0xfe, 0x04, 0x10, 0xb9, 0x76, 0x58, 0xae, 0x21, 0x94, 0x33, + 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x22, 0x07, 0xf2, 0x01, 0x5f, 0xff, + 0xf7, 0x0c, 0xff, 0xff, 0x42, 0x12, 0x80, 0xe2, 0x90, 0x38, 0x02, 0x40, + 0x2a, 0x22, 0x10, 0x00, 0x12, 0x00, 0x01, 0x34, 0x43, 0x24, 0x46, 0x61, + 0x40, 0x1c, 0x46, 0xff, 0xf9, 0x05, 0x79, 0x12, 0xff, 0x00, 0xff, 0x61, + 0xf1, 0x6f, 0xff, 0xff, 0x21, 0xff, 0x10, 0xff, 0xc1, 0xaf, 0x3d, 0xfd, + 0x20, 0x00, 0x10, 0x00, 0x13, 0x00, 0x04, 0x82, 0xc9, 0x50, 0x00, 0x04, + 0x18, 0x10, 0x00, 0x0b, 0x55, 0x19, 0xfa, 0x1d, 0xff, 0x00, 0x35, 0xff, + 0xff, 0xd1, 0x00, 0xaf, 0xff, 0xff, 0x04, 0xd0, 0x4f, 0xff, 0xf4, 0x2f, + 0x36, 0xfb, 0x94, 0x00, 0x22, 0x10, 0x24, 0xaf, 0x71, 0xff, 0xf5, 0x03, + 0x08, 0x6b, 0xff, 0xf7, 0x02, 0x56, 0xff, 0xff, 0xf8, 0x01, 0x1f, 0xff, + 0x18, 0xff, 0xff, 0xd0, 0x01, 0x71, 0x06, 0xfb, 0x01, 0xcf, 0xfe, 0x19, + 0x37, 0x03, 0xf0, 0x03, 0x3f, 0xfe, 0x10, 0x01, 0x47, 0xc4, 0x12, 0x3d, + 0x00, 0xf7, 0x1f, 0xff, 0x21, 0xbf, 0xff, 0xfa, 0x6c, 0x86, 0x02, 0xe3, + 0x01, 0x57, 0x16, 0x37, 0x03, 0xfe, 0x01, 0x03, 0xff, 0xa4, 0x10, 0x02, + 0x10, 0x1a, 0x57, 0x01, 0xff, 0xf8, 0x1f, 0xff, 0xf5, 0x02, 0xcf, 0x05, + 0x18, 0xc5, 0x22, 0x5e, 0x37, 0x04, 0xf1, 0x18, 0xdf, 0x08, 0x70, 0x1f, + 0xc5, 0xbf, 0x57, 0xff, 0xff, 0x21, 0x1c, 0xef, 0xb6, 0x10, 0x87, 0x47, + 0x06, 0xfb, 0x23, 0x18, 0x21, 0x00, 0x6f, 0x17, 0x02, 0xf2, 0x07, 0x70, + 0x71, 0x05, 0x7f, 0x37, 0x07, 0xff, 0xc6, 0x29, 0x17, 0x8f, 0x04, 0xa2, + 0x32, 0x7f, 0x77, 0x2f, 0x77, 0x2f, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xe0, 0x07, 0x07, 0x07, +}; + +const uint8_t g_pui8Image_Splash5[] = +{ + IMAGE_FMT_4BPP_COMP, + 96, 0, + 64, 0, + + 15, + 0x00, 0x00, 0x00, + 0x29, 0x29, 0x29, + 0x43, 0x43, 0x43, + 0x57, 0x57, 0x57, + 0x67, 0x67, 0x67, + 0x77, 0x77, 0x77, + 0x86, 0x86, 0x86, + 0x98, 0x98, 0x98, + 0xa9, 0xa9, 0xa9, + 0xba, 0xba, 0xba, + 0xca, 0xca, 0xca, + 0xd8, 0xd8, 0xd8, + 0xe7, 0xe7, 0xe7, + 0xf4, 0xf4, 0xf4, + 0xfb, 0xfb, 0xfb, + 0xff, 0xff, 0xff, + + 0x1f, 0xff, 0xff, 0xff, 0xe9, 0xd4, 0xa7, 0x5f, 0x12, 0x3e, 0xfe, 0x06, + 0x07, 0x07, 0x77, 0x2f, 0x07, 0xff, 0x27, 0xf7, 0x02, 0x03, 0xf6, 0x4f, + 0x07, 0x07, 0x77, 0xc4, 0x2f, 0x01, 0xf2, 0x42, 0x9f, 0x02, 0x30, 0x3f, + 0xf8, 0x07, 0x07, 0x77, 0x2f, 0x01, 0xf1, 0xa5, 0x4f, 0x9f, 0x01, 0xe1, + 0x58, 0xd2, 0x07, 0xa7, 0x5f, 0x17, 0x11, 0xb1, 0xf9, 0x1f, 0x01, 0x22, + 0xf7, 0x3f, 0x07, 0xe0, 0x07, 0x77, 0x2a, 0xb8, 0x64, 0x43, 0x46, 0xac, + 0x00, 0x99, 0xdf, 0xff, 0x91, 0xff, 0x17, 0xff, 0xff, 0x0e, 0xf5, 0x1f, + 0xf5, 0x4f, 0x07, 0xbf, 0x77, 0xff, 0x00, 0xff, 0x94, 0x22, 0x11, 0x23, + 0x44, 0x32, 0x11, 0x00, 0x01, 0x13, 0xaf, 0x72, 0xff, 0x33, 0xff, 0xff, + 0x0e, 0xe0, 0x8f, 0xf3, 0x7f, 0x07, 0xbf, 0x77, 0xf9, 0x08, 0x30, 0x13, + 0x6a, 0xdf, 0x01, 0xfa, 0xaf, 0xc4, 0x00, 0x14, 0x72, 0xff, 0x71, 0xff, + 0xff, 0x43, 0xff, 0x38, 0xb2, 0xef, 0x07, 0xbf, 0x73, 0xd9, 0x53, 0x43, + 0x10, 0x33, 0x20, 0x28, 0x1f, 0xd2, 0x02, 0xff, 0xb1, 0x07, 0xef, 0xfe, + 0x08, 0xff, 0x43, 0x77, 0x2f, 0x03, 0x02, 0x92, 0x12, 0x36, 0x77, 0x76, + 0x7d, 0x1f, 0xff, 0x00, 0xff, 0x60, 0xcf, 0xb1, 0xdf, 0xf4, 0x1f, 0xfe, + 0x70, 0x1a, 0x6f, 0x27, 0x01, 0xfc, 0x42, 0x03, 0xbf, 0xc0, 0x3f, 0x03, + 0xb8, 0xf1, 0x3f, 0xb1, 0xdf, 0xc1, 0x1c, 0x8f, 0xf5, 0x3f, 0x4f, 0x07, + 0x01, 0x90, 0x28, 0x02, 0xef, 0xff, 0xff, 0xb5, 0xff, 0x68, 0x1f, 0xf9, + 0x00, 0x03, 0xfb, 0x1f, 0x71, 0xff, 0x21, 0xff, 0x90, 0x61, 0xbf, 0x6f, + 0x27, 0xff, 0xfe, 0x94, 0x06, 0x52, 0x10, 0xb2, 0xef, 0x26, 0x1f, 0xb0, + 0x6f, 0xfe, 0x1d, 0x06, 0x70, 0x62, 0x0c, 0xf9, 0x07, 0x77, 0x2f, 0xff, + 0x00, 0xfa, 0x21, 0x24, 0xaf, 0xff, 0x87, 0xff, 0x58, 0x10, 0xf2, 0xcf, + 0x17, 0x17, 0x13, 0xff, 0xff, 0x6c, 0x06, 0xe9, 0x53, 0xcf, 0x60, 0x8f, + 0x77, 0x2f, 0xff, 0x20, 0x40, 0x4b, 0x59, 0x71, 0xff, 0x53, 0xf2, 0x9f, + 0x49, 0xad, 0x16, 0xf9, 0x0d, 0x03, 0xf6, 0x0a, 0x7e, 0xc8, 0x3e, 0x01, + 0xd1, 0x1c, 0x22, 0xf1, 0x6f, 0xa2, 0x08, 0xf3, 0x7f, 0xd9, 0xef, 0x01, + 0xc9, 0xff, 0xeb, 0x13, 0xef, 0xf2, 0x2f, 0x03, 0xf3, 0x8f, 0xcb, 0xa3, + 0x90, 0xb6, 0xfa, 0x02, 0x2a, 0xfb, 0xb8, 0x2f, 0xf2, 0x10, 0xc4, 0x6f, + 0x80, 0x0a, 0xa6, 0xff, 0xc6, 0xdf, 0x2e, 0xf0, 0x9f, 0x03, 0xf3, 0xcc, + 0xa3, 0xb6, 0x60, 0x40, 0x7f, 0x2a, 0xfa, 0x0c, 0x37, 0xf2, 0x87, 0x5f, + 0x45, 0x71, 0x0e, 0x91, 0xdf, 0x49, 0x02, 0xf3, 0x23, 0xc8, 0x5e, 0x1b, + 0xf3, 0x0a, 0x6c, 0x25, 0x82, 0xf5, 0x11, 0x59, 0x3f, 0x71, 0x0e, 0x61, + 0xfd, 0x19, 0x02, 0x32, 0xf4, 0x6f, 0x7e, 0x3e, 0xff, 0x20, 0x75, 0xb1, + 0x01, 0x72, 0xfa, 0x38, 0x3f, 0x80, 0xff, 0x98, 0x04, 0x13, 0x71, 0xfa, + 0x1d, 0x02, 0xf5, 0x3f, 0x15, 0xcd, 0xa0, 0x71, 0x0d, 0x75, 0xf2, 0x54, + 0x7f, 0x37, 0x3f, 0x02, 0x81, 0xff, 0x87, 0xff, 0xf7, 0x9f, 0x01, 0x90, + 0x26, 0xfa, 0x1f, 0x02, 0xf7, 0x2f, 0x15, 0xcd, 0xff, 0x10, 0xff, 0xa0, + 0xaf, 0x75, 0xf9, 0x26, 0x2f, 0x45, 0x00, 0x4b, 0xb0, 0xef, 0xff, 0xff, + 0xfb, 0xcf, 0xff, 0x04, 0x89, 0xff, 0x91, 0xfb, 0x1e, 0x02, 0xfa, 0x2f, + 0xc4, 0x15, 0xcd, 0xff, 0xff, 0x13, 0x7c, 0xdf, 0xff, 0x01, 0xff, 0x26, + 0x3d, 0x84, 0x48, 0xd1, 0xcf, 0x03, 0x00, 0x68, 0xff, 0xa1, 0xcf, 0x1b, + 0xff, 0xfa, 0x7c, 0x1c, 0xff, 0xfb, 0x1d, 0x0c, 0xd4, 0x21, 0xf6, 0x0f, + 0x80, 0x7b, 0xf8, 0x6f, 0xff, 0xff, 0x43, 0x56, 0xd3, 0x01, 0x45, 0xe0, + 0xcf, 0xff, 0xff, 0xfc, 0x9f, 0x01, 0x00, 0xf1, 0x8f, 0x17, 0xff, 0x72, + 0x66, 0xff, 0xfb, 0x72, 0x2d, 0x0b, 0xdb, 0xb3, 0xf1, 0x5f, 0x7b, 0xfd, + 0x00, 0xcf, 0xff, 0xff, 0x92, 0x74, 0xf3, 0x25, 0xf1, 0x08, 0xbf, 0xff, + 0xff, 0xf9, 0x6a, 0xf2, 0x1f, 0x52, 0x03, 0xff, 0xb7, 0x9f, 0xff, 0xfa, + 0x1f, 0x0b, 0xdb, 0x90, 0xb3, 0xa0, 0xcf, 0x7f, 0xf1, 0x73, 0xf5, 0x25, + 0x08, 0xe1, 0x9f, 0xff, 0xac, 0x03, 0xf4, 0x04, 0xa1, 0x03, 0xfd, 0x92, + 0x07, 0x8f, 0xf8, 0x2f, 0x0f, 0xbc, 0x40, 0x52, 0x85, 0xfd, 0x5c, 0xff, + 0xf3, 0x64, 0x98, 0x04, 0x25, 0xd1, 0x7f, 0xff, 0x49, 0x03, 0xf5, 0x21, + 0x01, 0x94, 0x8f, 0x23, 0x51, 0x9f, 0xf5, 0x2f, 0x05, 0x90, 0xcd, 0xff, + 0x24, 0x85, 0xfe, 0x9d, 0xff, 0xf6, 0x04, 0x36, 0x6a, 0x34, 0xd2, 0x5f, + 0x03, 0xf8, 0x7f, 0x00, 0xf7, 0x2a, 0x11, 0x6f, 0xb6, 0x57, 0xff, 0xf2, + 0x64, 0x6f, 0x05, 0xcd, 0xff, 0x17, 0x02, 0xf7, 0x8f, 0x81, 0x52, 0xf9, + 0x27, 0x4b, 0x43, 0xb5, 0x2f, 0x03, 0x02, 0xf9, 0x7f, 0xf9, 0x1f, 0xa0, + 0x3f, 0x01, 0xc1, 0x74, 0xbf, 0x83, 0x5b, 0x33, 0x18, 0x02, 0xfb, 0xcb, + 0x40, 0xaf, 0x21, 0xfd, 0x18, 0x4a, 0x53, 0x8b, 0x1f, 0xa2, 0x01, 0x96, + 0x01, 0xfc, 0x1c, 0xd0, 0xaa, 0x42, 0xe0, 0x0a, 0xe2, 0xc5, 0xfd, 0x19, + 0xff, 0xff, 0xfa, 0x08, 0x7f, 0xff, 0xf8, 0x7f, 0x42, 0x17, 0x59, 0x53, + 0x40, 0x4f, 0x81, 0xff, 0xaa, 0xf7, 0xdf, 0xff, 0xfb, 0x17, 0x1e, 0x91, + 0x1d, 0x01, 0x18, 0x42, 0x22, 0xc6, 0x06, 0x17, 0xff, 0xff, 0xfb, 0x8f, + 0x39, 0xda, 0x27, 0x00, 0x68, 0x54, 0x3f, 0x23, 0xff, 0xfb, 0x5f, 0xff, + 0x00, 0xc6, 0xef, 0xff, 0xf9, 0x0f, 0x52, 0x2e, 0xff, 0x17, 0xff, 0xf6, + 0x1f, 0x29, 0xef, 0x09, 0xc9, 0xd4, 0x40, 0x34, 0x9c, 0xfa, 0xcc, 0x7f, + 0xff, 0xff, 0x45, 0x01, 0x68, 0x54, 0x4f, 0x71, 0xff, 0xfc, 0x9f, 0x02, + 0x00, 0xf4, 0x2e, 0x38, 0x1f, 0xff, 0xff, 0xf2, 0x4f, 0xe9, 0x0c, 0xd4, + 0x42, 0x91, 0x7c, 0xf7, 0x8f, 0x39, 0x02, 0x64, 0x89, 0xba, 0xff, 0x90, + 0xbf, 0x04, 0x30, 0x01, 0xf3, 0x78, 0x1f, 0xff, 0xff, 0xf1, 0x9f, 0x0c, + 0xca, 0x64, 0x32, 0xf1, 0x8f, 0x01, 0x9a, 0x54, 0x62, 0x04, 0xff, 0xa8, + 0xf1, 0x20, 0x6f, 0x02, 0xfa, 0x30, 0x01, 0x13, 0x23, 0xe0, 0x1f, 0xff, + 0xff, 0x91, 0x3c, 0xd0, 0x0c, 0xa3, 0xf3, 0x51, 0xff, 0x68, 0xff, 0xff, + 0x00, 0xc7, 0xdf, 0xff, 0xff, 0x72, 0x2c, 0x80, 0x23, 0x00, 0x20, 0x10, + 0x45, 0x45, 0x56, 0x41, 0x12, 0x38, 0x01, 0xf7, 0x03, 0x42, 0x2e, 0xff, + 0xff, 0x63, 0x19, 0xe4, 0x01, 0xd4, 0xa3, 0xfe, 0x17, 0x6c, 0xc5, 0xef, + 0x00, 0xff, 0xff, 0x50, 0x26, 0x36, 0x85, 0x18, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x04, 0x8f, 0xf8, 0x22, 0x07, 0x1f, 0x1a, 0xff, 0xff, 0x35, + 0x1c, 0xd4, 0xa4, 0x20, 0x80, 0x9f, 0x66, 0xfa, 0x01, 0x75, 0x23, 0x11, + 0x00, 0xaf, 0xfb, 0x20, 0x16, 0x79, 0xcf, 0x70, 0x1f, 0x01, 0xfb, 0x1f, + 0x26, 0x46, 0xff, 0xff, 0x26, 0x26, 0x84, 0xc6, 0xff, 0xff, 0x36, 0x16, + 0x66, 0x80, 0x36, 0x00, 0x43, 0x46, 0xbf, 0xff, 0xff, 0xfb, 0x44, 0x54, + 0x01, 0x42, 0x42, 0x2f, 0xfa, 0x1f, 0xb2, 0x53, 0x19, 0xc0, 0x26, 0xc6, + 0xff, 0xf6, 0x2f, 0x50, 0x12, 0x7d, 0x01, 0xfe, 0xff, 0xff, 0xec, 0xb8, + 0x31, 0x19, 0x1e, 0x00, 0xc8, 0x8b, 0xf6, 0x1f, 0xf6, 0x2f, 0xf4, 0x72, + 0x1a, 0x8f, 0xff, 0x35, 0x6e, 0x2a, 0xfe, 0x02, 0xf5, 0x00, 0x06, 0x20, + 0x87, 0x43, 0x03, 0x33, 0x23, 0x34, 0x20, 0x00, 0x4b, 0x27, 0xff, 0xff, + 0xc0, 0x9f, 0xf2, 0x03, 0x3f, 0xf4, 0x8a, 0x0b, 0xff, 0x35, 0x67, 0x1e, + 0x00, 0xf3, 0x38, 0x02, 0xff, 0xf1, 0x1c, 0xc6, 0x09, 0x08, 0xad, 0xe7, + 0x43, 0x3a, 0x1f, 0xff, 0xa0, 0x4f, 0x01, 0xf0, 0x2f, 0xf3, 0x8f, 0x80, + 0x4a, 0x17, 0x6f, 0x80, 0x26, 0xf4, 0x5a, 0x04, 0xff, 0x41, 0xff, 0xfa, + 0x02, 0x13, 0x43, 0x4a, 0xba, 0x42, 0x6f, 0x17, 0xf5, 0x00, 0x01, 0x10, + 0x4f, 0xf3, 0x9f, 0xfb, 0x21, 0x3f, 0xc0, 0x77, 0x2e, 0xf8, 0x01, 0x05, + 0xff, 0x90, 0x8f, 0x01, 0xff, 0xdd, 0xdd, 0x70, 0x2f, 0xf7, 0x07, 0x17, + 0x03, 0xfc, 0x40, 0x35, 0x2f, 0xa1, 0xdf, 0x8f, 0x47, 0x80, 0x31, 0x14, + 0x03, 0xff, 0xf9, 0x11, 0xaf, 0xff, 0x04, 0xff, 0x90, 0x0b, 0xb0, 0x08, + 0x07, 0xff, 0xfb, 0x1c, 0xf3, 0x0d, 0x81, 0x97, 0x4f, 0x02, 0x27, 0x30, + 0x00, 0xcf, 0xff, 0xf5, 0x12, 0x32, 0x33, 0x10, 0x12, 0x20, 0x00, 0x4e, + 0x07, 0xff, 0xff, 0xc0, 0x00, 0x08, 0xe0, 0x97, 0x4f, 0x02, 0x82, 0x60, + 0x8f, 0xff, 0xff, 0x03, 0xe9, 0x9a, 0xa9, 0x86, 0x8d, 0x9b, 0x07, 0x01, + 0x1c, 0xf8, 0x73, 0x5f, 0x8f, 0x47, 0x02, 0xf1, 0x21, 0x7c, 0x2f, 0x3f, + 0x07, 0x77, 0x2f, 0x07, 0xf3, 0x68, 0x7c, 0x0f, 0x07, 0x07, 0x77, 0x2f, + 0x07, 0xf6, 0x4c, 0x7c, 0x1e, 0x07, 0x07, 0x77, 0x2f, 0x07, 0xf9, 0x02, + 0x7c, 0x1f, 0x07, 0x07, 0x77, 0x2f, 0x07, 0xf8, 0x24, 0x7c, 0x1f, 0x07, + 0x07, 0x77, 0x2f, 0x07, 0xf4, 0x56, 0x7c, 0x3f, 0x07, 0x07, 0x77, 0x2f, + 0x07, 0xf1, 0x62, 0x7c, 0xaf, 0x07, 0x07, 0x77, 0x2f, 0x07, 0x71, 0x03, + 0xf8, 0x07, 0x07, 0x77, 0x2f, 0x07, 0xfa, 0x12, 0x0c, 0xf8, 0x07, 0x07, + 0x77, 0x2f, 0x04, 0xfe, 0xff, 0xff, 0x1f, 0x50, 0x01, 0xbf, 0x07, 0x07, + 0x77, 0x2f, 0x06, 0x1f, 0xf5, 0x00, 0x2c, 0x07, 0x07, 0x77, 0x2f, 0x07, + 0x3e, 0xf1, 0x05, 0x07, 0x07, 0x77, 0x2f, 0x07, 0xff, 0x3f, 0xf8, 0x6f, + 0x07, 0x07, 0x77, 0x2f, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0xf0, 0x07, 0x07, 0x07, 0x07, +}; + +const uint8_t *g_ppui8Image_Splash[] = +{ + g_pui8Image_Splash1, g_pui8Image_Splash2, g_pui8Image_Splash3, + g_pui8Image_Splash4, g_pui8Image_Splash5 +}; diff --git a/boards/ek-lm4f232/qs-logger/images.h b/boards/ek-lm4f232/qs-logger/images.h new file mode 100644 index 0000000..b100571 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/images.h @@ -0,0 +1,37 @@ +//***************************************************************************** +// +// images.h - Header file for graphics images. +// +// 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. +// +//***************************************************************************** + +#ifndef __IMAGES_H__ +#define __IMAGES_H__ + +//***************************************************************************** +// +// Prototypes for the globals exported by this driver. +// +//***************************************************************************** +extern const uint8_t g_pui8Image_TI_Black[]; +extern const uint8_t *g_ppui8Image_Splash[]; + +#endif // __IMAGES_H__ + diff --git a/boards/ek-lm4f232/qs-logger/menus.c b/boards/ek-lm4f232/qs-logger/menus.c new file mode 100644 index 0000000..1cf790e --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/menus.c @@ -0,0 +1,704 @@ +//***************************************************************************** +// +// menus.c - Application menus definition and supporting functions. +// +// 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 +#include +#include +#include "inc/hw_types.h" +#include "driverlib/debug.h" +#include "grlib/grlib.h" +#include "grlib/widget.h" +#include "grlib/canvas.h" +#include "utils/ustdlib.h" +#include "drivers/cfal96x64x16.h" +#include "drivers/slidemenuwidget.h" +#include "drivers/stripchartwidget.h" +#include "utils/ustdlib.h" +#include "stripchartmanager.h" +#include "clocksetwidget.h" +#include "qs-logger.h" +#include "acquire.h" +#include "menus.h" + +//***************************************************************************** +// +// This is the menus module of the data logger example application. It +// contains the definitions of all the menus that are used by the application +// and provides some helper functions. +// +//***************************************************************************** + +//***************************************************************************** +// +// Define two offscreen buffers and display structures. These are used for +// off-screen drawing for animation effects. Only limited colors are needed +// so 4bpp buffers are used to save memory. +// +//***************************************************************************** +#define OFFSCREEN_BUF_SIZE GrOffScreen4BPPSize(96, 64) +uint8_t g_pui8OffscreenBufA[OFFSCREEN_BUF_SIZE]; +uint8_t g_pui8OffscreenBufB[OFFSCREEN_BUF_SIZE]; +tDisplay g_sOffscreenDisplayA; +tDisplay g_sOffscreenDisplayB; + +//***************************************************************************** +// +// Create a palette that is used by the on-screen menus and anything else that +// uses the (above) off-screen buffers. This palette should contain any +// colors that are used by any widget using the offscreen buffers. There can +// be up to 16 colors in this palette. +// The numerical values of colors in the list below were selected as colors +// that produced good results on the display and did not already have named +// values. +// +//***************************************************************************** +uint32_t g_pui32Palette[] = +{ + ClrBlack, + ClrWhite, + ClrDarkBlue, + ClrLightBlue, + ClrRed, + ClrDarkGreen, + ClrYellow, + ClrBlue, + ClrGreen, + 0x000040, + ClrLime, + ClrAqua, + 0x004000, + ClrFuchsia, + 0xC00040, + 0x60E080, +}; +#define NUM_PALETTE_ENTRIES (sizeof(g_pui32Palette) / sizeof(uint32_t)) + +//***************************************************************************** +// +// Define the length of text strings used for holding data values. +// +//***************************************************************************** +#define TEXT_FIELD_LENGTH 20 + +//***************************************************************************** +// +// Defines a set of text fields that are used by various widgets for dynamic +// updating of text. +// +//***************************************************************************** +static char g_pcTextFields[NUM_TEXT_ITEMS][TEXT_FIELD_LENGTH]; + +//***************************************************************************** +// +// Defines a set of canvas widgets that are used for showing the temperature +// on a simple screen with an outline and a title. +// +//***************************************************************************** +tCanvasWidget g_sTempContainerCanvas; +Canvas(g_sTempExtValueCanvas, &g_sTempContainerCanvas, 0, 0, + &g_sCFAL96x64x16, 0, 44, 96, 20, (CANVAS_STYLE_OUTLINE | + CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_EXTTEMP], 0, 0); +Canvas(g_sTempIntValueCanvas, &g_sTempContainerCanvas, &g_sTempExtValueCanvas, + 0, &g_sCFAL96x64x16, 0, 24, 96, 20, (CANVAS_STYLE_OUTLINE | + CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_INTTEMP], 0, 0); +Canvas(g_sTempTitleCanvas, &g_sTempContainerCanvas, &g_sTempIntValueCanvas, 0, + &g_sCFAL96x64x16, 0, 0, 96, 24, (CANVAS_STYLE_OUTLINE | + CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, "TEMPERATURE", 0, 0); +Canvas(g_sTempContainerCanvas, 0, 0, &g_sTempTitleCanvas, &g_sCFAL96x64x16, 0, + 0, 96, 64, 0, ClrDarkBlue, ClrWhite, ClrWhite, 0, 0, 0, 0); + +//***************************************************************************** +// +// Defines a set of canvas widgets that are used for showing the accelerometer +// data on a simple screen with an outline and a title. +// +//***************************************************************************** +tCanvasWidget g_sAccelContainerCanvas; +Canvas(g_sAccelZCanvas, &g_sAccelContainerCanvas, 0, 0, &g_sCFAL96x64x16, 0, + 48, 96, 16, (CANVAS_STYLE_TEXT | CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_ACCELZ], 0, 0); +Canvas(g_sAccelYCanvas, &g_sAccelContainerCanvas, &g_sAccelZCanvas, 0, + &g_sCFAL96x64x16, 0, 32, 96, 16, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_ACCELY], 0, 0); +Canvas(g_sAccelXCanvas, &g_sAccelContainerCanvas, &g_sAccelYCanvas, 0, + &g_sCFAL96x64x16, 0, 16, 96, 16, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_ACCELX], 0, 0); +Canvas(g_sAccelTitleCanvas, &g_sAccelContainerCanvas, &g_sAccelXCanvas, 0, + &g_sCFAL96x64x16, 0, 0, 96, 16, (CANVAS_STYLE_OUTLINE | + CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, "ACCEL", 0, 0); +Canvas(g_sAccelContainerCanvas, 0, 0, &g_sAccelTitleCanvas, &g_sCFAL96x64x16, + 0, 0, 96, 64, 0, ClrDarkBlue, ClrWhite, ClrWhite, 0, 0, 0, 0); + +//***************************************************************************** +// +// Defines a set of canvas widgets that are used for showing the analog input +// data on a simple screen with no decorations. +// +//***************************************************************************** +tCanvasWidget g_sAINContainerCanvas; +Canvas(g_sAIN3Canvas, &g_sAINContainerCanvas, 0, 0, &g_sCFAL96x64x16, 0, 48, + 96, 16, (CANVAS_STYLE_TEXT | CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | CANVAS_STYLE_TEXT_VCENTER), + ClrDarkGreen, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_USER3], 0, 0); +Canvas(g_sAIN2Canvas, &g_sAINContainerCanvas, &g_sAIN3Canvas, 0, + &g_sCFAL96x64x16, 0, 32, 96, 16, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkGreen, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_USER2], 0, 0); +Canvas(g_sAIN1Canvas, &g_sAINContainerCanvas, &g_sAIN2Canvas, 0, + &g_sCFAL96x64x16, 0, 16, 96, 16, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkGreen, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_USER1], 0, 0); +Canvas(g_sAIN0Canvas, &g_sAINContainerCanvas, &g_sAIN1Canvas, 0, + &g_sCFAL96x64x16, 0, 0, 96, 16, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkGreen, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_USER0], 0, 0); +Canvas(g_sAINContainerCanvas, 0, 0, &g_sAIN0Canvas, &g_sCFAL96x64x16, 0, 0, 96, + 64, 0, ClrDarkGreen, ClrWhite, ClrWhite, 0, 0, 0, 0); + +//***************************************************************************** +// +// Defines a set of canvas widgets that are used for showing the current +// on a simple screen with an outline and a title. +// +//***************************************************************************** +tCanvasWidget g_sCurrentContainerCanvas; +Canvas(g_sCurrentValueCanvas, &g_sCurrentContainerCanvas, 0, 0, + &g_sCFAL96x64x16, 0, 24, 96, 40, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrBlack, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[LOG_ITEM_CURRENT], 0, 0); +Canvas(g_sCurrentTitleCanvas, &g_sCurrentContainerCanvas, + &g_sCurrentValueCanvas, 0, &g_sCFAL96x64x16, 0, 0, 96, 24, + (CANVAS_STYLE_OUTLINE | CANVAS_STYLE_TEXT | CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | CANVAS_STYLE_TEXT_VCENTER), + ClrBlack, ClrWhite, ClrWhite, &g_sFontFixed6x8, "CURRENT", 0, 0); +Canvas(g_sCurrentContainerCanvas, 0, 0, &g_sCurrentTitleCanvas, + &g_sCFAL96x64x16, 0, 0, 96, 64, 0, ClrBlack, ClrWhite, ClrWhite, 0, 0, + 0, 0); + +//***************************************************************************** +// +// Defines a set of canvas widgets that are used for showing the clock date +// and time. +// +//***************************************************************************** +tCanvasWidget g_sClockContainerCanvas; +Canvas(g_sClockTimeCanvas, &g_sClockContainerCanvas, 0, 0, &g_sCFAL96x64x16, 0, + 38, 96, 16, (CANVAS_STYLE_TEXT | CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[TEXT_ITEM_TIME], 0, 0); +Canvas(g_sClockDateCanvas, &g_sClockContainerCanvas, &g_sClockTimeCanvas, + 0, &g_sCFAL96x64x16, 0, 22, 96, 16, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[TEXT_ITEM_DATE], 0, 0); +Canvas(g_sClockTitleCanvas, &g_sClockContainerCanvas, &g_sClockDateCanvas, 0, + &g_sCFAL96x64x16, 0, 0, 96, 16, (CANVAS_STYLE_OUTLINE | + CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrDarkBlue, ClrWhite, ClrWhite, &g_sFontFixed6x8, "CLOCK", 0, 0); +Canvas(g_sClockContainerCanvas, 0, 0, &g_sClockTitleCanvas, &g_sCFAL96x64x16, + 0, 0, 96, 64, CANVAS_STYLE_OUTLINE, ClrDarkBlue, ClrWhite, ClrWhite, 0, + 0, 0, 0); + +//***************************************************************************** +// +// Defines a set of canvas widgets that are used for showing a status +// screen. It is a simple canvas container that can show a title and 3 +// lines of text. +// +//***************************************************************************** +tCanvasWidget g_sStatusContainerCanvas; +Canvas(g_sStatus3Canvas, &g_sStatusContainerCanvas, 0, 0, &g_sCFAL96x64x16, 1, + 48, 94, 12, (CANVAS_STYLE_TEXT | CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_FILL | CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrRed, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[TEXT_ITEM_STATUS3], 0, 0); +Canvas(g_sStatus2Canvas, &g_sStatusContainerCanvas, &g_sStatus3Canvas, 0, + &g_sCFAL96x64x16, 1, 30, 94, 12, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_FILL | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrRed, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[TEXT_ITEM_STATUS2], 0, 0); +Canvas(g_sStatus1Canvas, &g_sStatusContainerCanvas, &g_sStatus2Canvas, 0, + &g_sCFAL96x64x16, 1, 18, 94, 12, (CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_FILL | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrRed, ClrWhite, ClrWhite, &g_sFontFixed6x8, + g_pcTextFields[TEXT_ITEM_STATUS1], 0, 0); +Canvas(g_sStatusTitleCanvas, &g_sStatusContainerCanvas, &g_sStatus1Canvas, 0, + &g_sCFAL96x64x16, 0, 0, 96, 16, (CANVAS_STYLE_FILL | CANVAS_STYLE_TEXT | + CANVAS_STYLE_TEXT_OPAQUE | + CANVAS_STYLE_TEXT_HCENTER | + CANVAS_STYLE_TEXT_VCENTER), + ClrWhite, ClrWhite, ClrBlack, &g_sFontFixed6x8, + g_pcTextFields[TEXT_ITEM_STATUS_TITLE], 0, 0); +Canvas(g_sStatusContainerCanvas, 0, 0, &g_sStatusTitleCanvas, &g_sCFAL96x64x16, + 0, 0, 96, 64, CANVAS_STYLE_OUTLINE, ClrRed, ClrWhite, ClrWhite, 0, 0, 0, + 0); + +//***************************************************************************** +// +// Allocate space for a time structure that is used with the clock setting +// widget. +// +//***************************************************************************** +struct tm g_sTimeClock; + +//***************************************************************************** +// +// Define a clock setting widget. It is used to allow the user to set the +// RTC (real time clock). +// +//***************************************************************************** +ClockSet(g_sClockSetter, 0, 0, 0, &g_sCFAL96x64x16, 0, 0, 96, 64, + g_psFontFixed6x8, ClrWhite, ClrDarkGreen, &g_sTimeClock, 0); + +//***************************************************************************** +// +// Define the main (root) menu. +// +//***************************************************************************** +tSlideMenu g_sConfigMenu; +tSlideMenu g_sViewMenu; +tSlideMenu g_sConfirmMenu; +tSlideMenuItem g_psMainMenuItems[] = +{ + {"CONFIG", &g_sConfigMenu, 0, 0}, + {"START", 0, &g_sStripChart.sBase, ClrBlack}, + {"VIEW", &g_sViewMenu, 0, 0}, + {"SAVE", 0, &g_sStatusContainerCanvas.sBase, ClrRed}, + {"ERASE", &g_sConfirmMenu, 0, 0} +}; +tSlideMenu g_psMainMenu = +{ + 0, (sizeof(g_psMainMenuItems) / sizeof(tSlideMenuItem)), g_psMainMenuItems, + 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Define the configuration (CONFIG) sub-menu. +// +// (root)-->CONFIG +// +//***************************************************************************** +tSlideMenu g_sChannelsMenu; +tSlideMenu g_sPeriodMenu; +tSlideMenu g_sStorageMenu; +tSlideMenu g_sSleepMenu; +tSlideMenuItem g_psConfigMenuItems[] = +{ + {"CHANNELS", &g_sChannelsMenu, 0, 0}, {"PERIOD", &g_sPeriodMenu, 0, 0}, + {"STORAGE", &g_sStorageMenu, 0, 0}, {"SLEEP", &g_sSleepMenu, 0, 0}, + {"CLOCK", 0, &g_sClockSetter.sBase, ClrDarkGreen} +}; +tSlideMenu g_sConfigMenu = +{ + &g_psMainMenu, (sizeof(g_psConfigMenuItems) / sizeof(tSlideMenuItem)), + g_psConfigMenuItems, 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Define the channel selection sub-menu. +// +// (root)-->CONFIG-->CHANNELS +// +//***************************************************************************** +tSlideMenuItem g_psChannelsMenuItems[] = +{ + {"CHAN 0", 0, 0, 0}, {"CHAN 1", 0, 0, 0}, {"CHAN 2", 0, 0, 0}, + {"CHAN 3", 0, 0, 0}, {"ACCEL X", 0, 0, 0}, {"ACCEL Y", 0, 0, 0}, + {"ACCEL Z", 0, 0, 0}, {"EXT TEMP", 0, 0, 0}, {"INT TEMP", 0, 0, 0}, + {"CURRENT", 0, 0, 0}, +}; +tSlideMenu g_sChannelsMenu = +{ + &g_sConfigMenu, (sizeof(g_psChannelsMenuItems) / sizeof(tSlideMenuItem)), + g_psChannelsMenuItems, 0, 0, 1, 0 +}; + +//***************************************************************************** +// +// Define the logging period sub-menu. +// +// (root)-->CONFIG-->PERIOD +// +//***************************************************************************** +#define MENU_CONFIG_PERIOD_DEFAULT 3 +tSlideMenuItem g_psPeriodMenuItems[] = +{ + {"1/32 sec", 0, 0, 0}, {"1/16 sec", 0, 0, 0}, {"1/8 sec", 0, 0, 0}, + {"1/4 sec", 0, 0, 0}, {"1/2 sec", 0, 0, 0}, {"1 sec", 0, 0, 0}, + {"5 sec", 0, 0, 0}, {"10 sec", 0, 0, 0}, {"1 min", 0, 0, 0}, + {"5 min", 0, 0, 0}, {"10 min", 0, 0, 0}, {"1 hour", 0, 0, 0}, + {"5 hour", 0, 0, 0}, {"10 hour", 0, 0, 0}, {"1 day", 0, 0, 0}, +}; +tSlideMenu g_sPeriodMenu = +{ + &g_sConfigMenu, (sizeof(g_psPeriodMenuItems) / sizeof(tSlideMenuItem)), + g_psPeriodMenuItems, 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Maps items from the period menu to match values for RTC. Lower 8 bits +// is subsecond value, upper 24 bits is seconds. The lower 8 bits represent +// subseconds in 7 bits, right-justififed. So 0x01 is 1/128 of a second. +// The order of the values here needs to match what appears in the PERIOD +// menu in menus.c. +// +//***************************************************************************** +static uint32_t g_pui32LogPeriod[] = +{ + 0x00000004, // 1/32 + 0x00000008, // 1/16 + 0x00000010, // 1/8 + 0x00000020, // 1/4 + 0x00000040, // 1/2 + 0x00000100, // 1s + 0x00000500, // 5s + 0x00000A00, // 10s + 0x00003C00, // 1m - 60s + 0x00012C00, // 5m - 300s + 0x00025800, // 10m - 600s + 0x000E1000, // 1hr - 3600s + 0x00465000, // 5hr - 18000s + 0x008CA000, // 10hr - 36000s + 0x01518000, // 1d - 86400s +}; + +//***************************************************************************** +// +// Define the storage options sub-menu. +// +// (root)-->CONFIG-->STORAGE +// +//***************************************************************************** +tSlideMenuItem g_psStorageMenuItems[] = +{ + {"NONE", 0, 0, 0}, {"USB", 0, 0, 0}, {"HOST PC", 0, 0, 0}, + {"FLASH", 0, 0, 0}, +}; +tSlideMenu g_sStorageMenu = +{ + &g_sConfigMenu, (sizeof(g_psStorageMenuItems) / sizeof(tSlideMenuItem)), + g_psStorageMenuItems, 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Define the sleep option sub-menu. +// +// (root)-->CONFIG-->SLEEP +// +//***************************************************************************** +tSlideMenuItem g_psSleepMenuItems[] = +{ + {"NO", 0, 0, 0}, {"YES", 0, 0, 0}, +}; + +tSlideMenu g_sSleepMenu = +{ + &g_sConfigMenu, (sizeof(g_psSleepMenuItems) / sizeof(tSlideMenuItem)), + g_psSleepMenuItems, 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Define the view options sub-menu. +// +// (root)-->VIEW +// +//***************************************************************************** +tSlideMenuItem g_psViewMenuItems[] = +{ + {"AIN0-3", 0, (tWidget *)&g_sAINContainerCanvas, ClrDarkGreen}, + {"ACCEL", 0, (tWidget *)&g_sAccelContainerCanvas, ClrDarkBlue}, + {"TEMPERATURE", 0, (tWidget *)&g_sTempContainerCanvas, ClrDarkBlue}, + {"CURRENT", 0, (tWidget *)&g_sCurrentContainerCanvas, ClrBlack}, + {"CLOCK", 0, &g_sClockContainerCanvas.sBase, ClrDarkBlue}, + {"FLASH SPACE", 0, &g_sStatusContainerCanvas.sBase, ClrRed}, +}; +tSlideMenu g_sViewMenu = +{ + &g_psMainMenu, (sizeof(g_psViewMenuItems) / sizeof(tSlideMenuItem)), + g_psViewMenuItems, 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Define the ERASE confirmation menu. +// +// (root)-->ERASE +// +//***************************************************************************** +tSlideMenuItem g_sConfirmMenuItems[] = +{ + {"ERASE DATA?", 0, &g_sStatusContainerCanvas.sBase, ClrRed}, +}; +tSlideMenu g_sConfirmMenu = +{ + &g_psMainMenu, (sizeof(g_sConfirmMenuItems) / sizeof(tSlideMenuItem)), + g_sConfirmMenuItems, 0, 0, 0, 0 +}; + +//***************************************************************************** +// +// Define the slide menu widget. This is the wigdet that controls and +// displays all the above menus. +// +//***************************************************************************** +SlideMenu(g_sMenuWidget, WIDGET_ROOT, 0, 0, &g_sCFAL96x64x16, 0, 0, 96, 64, + &g_sOffscreenDisplayA, &g_sOffscreenDisplayB, 16, ClrWhite, ClrRed, + ClrBlack, &g_sFontFixed6x8, &g_psMainMenu, 0); + +//***************************************************************************** +// +// This function allows dynamic text fields to be updated. +// +//***************************************************************************** +void +MenuUpdateText(uint32_t ui32TextID, const char *pcText) +{ + // + // If the text field ID is valid, then update the string for that text + // field. The next time the associated widget is painted, the new text + // will be shown. + // + if(ui32TextID < NUM_TEXT_ITEMS) + { + usnprintf(g_pcTextFields[ui32TextID], TEXT_FIELD_LENGTH, "%s", pcText); + } +} + +//***************************************************************************** +// +// Get the state defined by the configuration menu items. +// This function will query the configuration menus to determine the current +// choices for channels, period, etc. These will be stored in the structure +// that was passed to the function. +// +//***************************************************************************** +void +MenuGetState(tConfigState *psState) +{ + int32_t ui32Temp; + + // + // Check the arguments + // + ASSERT(psState); + + if(!psState) + { + return; + } + + // + // Read the various configuration menus and store their state + // + if(SlideMenuFocusItemGet(&g_sSleepMenu) > 0) + { + psState->bSleep = true; + } + else + { + psState->bSleep = false; + } + ui32Temp = SlideMenuFocusItemGet(&g_sStorageMenu);; + psState->ui8Storage = (uint8_t)ui32Temp; + ui32Temp = SlideMenuSelectedGet(&g_sChannelsMenu); + psState->ui16SelectedMask = (uint16_t)ui32Temp; + ui32Temp = g_pui32LogPeriod[SlideMenuFocusItemGet(&g_sPeriodMenu)]; + psState->ui32Period = ui32Temp; +} + +//***************************************************************************** +// +// Set the configuration menu state. +// This function is used to set the state of the configuration menus. This +// is used to "remember" a prior setting when the application is restarted +// or wakes from sleep. +// +//***************************************************************************** +void +MenuSetState(tConfigState *psState) +{ + uint32_t ui32Idx; + + // + // Check the parameters + // + ASSERT(psState); + ASSERT(psState->ui8Storage < CONFIG_STORAGE_CHOICES); + ASSERT(psState->ui32Period & (psState->ui32Period < 0x2000000)); + + // + // Update each configuration menu item to match the new state + // + SlideMenuFocusItemSet(&g_sSleepMenu, psState->bSleep); + SlideMenuFocusItemSet(&g_sStorageMenu, psState->ui8Storage); + SlideMenuSelectedSet(&g_sChannelsMenu, psState->ui16SelectedMask); + + // + // For the period, search the values table to find the index + // + for(ui32Idx = 0; ui32Idx < (sizeof(g_pui32LogPeriod) / sizeof(uint32_t)); + ui32Idx++) + { + if(psState->ui32Period == g_pui32LogPeriod[ui32Idx]) + { + SlideMenuFocusItemSet(&g_sPeriodMenu, ui32Idx); + + // + // Everything has been updated now so return to caller + // + return; + } + } + + // + // If we get to this point, that means that there was no match for the + // period. In that case, set it to default value. + // + SlideMenuFocusItemSet(&g_sPeriodMenu, MENU_CONFIG_PERIOD_DEFAULT); + psState->ui32Period = g_pui32LogPeriod[MENU_CONFIG_PERIOD_DEFAULT]; +} + +//***************************************************************************** +// +// Set the default values for the menu configuration. +// This function is used to initialize the application state configuration with +// some default values for the menu settings. +// +//***************************************************************************** +void +MenuGetDefaultState(tConfigState *psState) +{ + // + // Check the parameters. + // + ASSERT(psState); + + // + // Set default values for all the menu items + // + if(psState) + { + psState->bSleep = false; + psState->ui8Storage = CONFIG_STORAGE_NONE; + psState->ui16SelectedMask = 0; + psState->ui32Period = 0x00000100; // 1 second + } +} + +//***************************************************************************** +// +// 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); +} diff --git a/boards/ek-lm4f232/qs-logger/menus.h b/boards/ek-lm4f232/qs-logger/menus.h new file mode 100644 index 0000000..c961462 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/menus.h @@ -0,0 +1,83 @@ +//***************************************************************************** +// +// menus.h - Prototypes and definitions for application menus. +// +// 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. +// +//***************************************************************************** + +#ifndef __MENUS_H__ +#define __MENUS_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Declare off-screen displays, buffers and menus for access by the rest of the +// application. +// +//***************************************************************************** +extern uint8_t g_pui8OffscreenBufA[]; +extern uint8_t g_pui8OffscreenBufB[]; +extern tDisplay g_sOffscreenDisplayA; +extern tDisplay g_sOffscreenDisplayB; +extern tSlideMenuWidget g_sMenuWidget; +extern tStripChartWidget g_sStripChart; +extern tSlideMenu g_sChannelsMenu; +extern tSlideMenu g_sPeriodMenu; +extern tCanvasWidget g_sAINContainerCanvas; +extern tCanvasWidget g_sAccelContainerCanvas; +extern tCanvasWidget g_sTempContainerCanvas; +extern tCanvasWidget g_sCurrentContainerCanvas; +extern tCanvasWidget g_sClockContainerCanvas; +extern tCanvasWidget g_sStatusContainerCanvas; +extern tClockSetWidget g_sClockSetter; +extern struct tm g_sTimeClock; + +//***************************************************************************** +// +// Module function prototypes. +// +//***************************************************************************** +extern void MenuInit(void (*pfnActive)(tWidget *, tSlideMenuItem *, bool)); +extern void MenuUpdateText(uint32_t ui32TextID, const char *pcText); +extern void MenuGetState(tConfigState *pState); +extern void MenuSetState(tConfigState *pState); +extern void MenuGetDefaultState(tConfigState *pState); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.c b/boards/ek-lm4f232/qs-logger/qs-logger.c new file mode 100644 index 0000000..e3e7390 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.c @@ -0,0 +1,1260 @@ +//***************************************************************************** +// +// qs-logger.c - Data logger Quickstart application for EK-LM4F232. +// +// 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 +#include +#include +#include +#include "driverlib/adc.h" +#include "driverlib/debug.h" +#include "driverlib/fpu.h" +#include "driverlib/gpio.h" +#include "driverlib/hibernate.h" +#include "driverlib/pin_map.h" +#include "driverlib/rom.h" +#include "driverlib/rom_map.h" +#include "driverlib/sysctl.h" +#include "driverlib/systick.h" +#include "driverlib/uart.h" +#include "grlib/grlib.h" +#include "grlib/widget.h" +#include "grlib/canvas.h" +#include "inc/hw_gpio.h" +#include "inc/hw_hibernate.h" +#include "inc/hw_memmap.h" +#include "inc/hw_sysctl.h" +#include "inc/hw_types.h" +#include "usblib/usblib.h" +#include "utils/ustdlib.h" +#include "drivers/cfal96x64x16.h" +#include "drivers/buttons.h" +#include "drivers/slidemenuwidget.h" +#include "drivers/stripchartwidget.h" +#include "clocksetwidget.h" +#include "qs-logger.h" +#include "images.h" +#include "menus.h" +#include "acquire.h" +#include "usbstick.h" +#include "usbserial.h" +#include "flashstore.h" + +//***************************************************************************** +// +//! \addtogroup example_list +//!

Data Logger (qs-logger)

+//! +//! This example application is a data logger. It can be configured to collect +//! data from up to 10 data sources. The possible data sources are: +//! - 4 analog inputs, 0-20V +//! - 3-axis accelerometer +//! - internal and external temperature sensors +//! - processor current consumption +//! +//! The data logger provides a menu navigation that is operated by the buttons +//! on the EK-LM4F232 board (up, down, left, right, select). The data logger +//! can be configured by using the menus. The following items can be +//! configured: +//! - data sources to be logged +//! - sample rate +//! - storage location +//! - sleep modes +//! - clock +//! +//! Using the data logger: +//! +//! Use the CONFIG menu to configure the data logger. The following choices +//! are provided: +//! +//! - CHANNELS - enable specific channels of data that will be logged +//! - PERIOD - select the sample period +//! - STORAGE - select where the collected data will be stored: +//! - FLASH - stored in the internal flash memory +//! - USB - stored on a connected USB memory stick +//! - HOST PC - transmitted to a host PC via USB OTG virtual serial port +//! - NONE - the data will only be displayed and not stored +//! - SLEEP - select whether or not the board sleeps between samples. Sleep +//! mode is allowed when storing to flash at with a period of 1 second or +//! longer. +//! - CLOCK - allows setting of internal time-of-day clock that is used for +//! time stamping of the sampled data +//! +//! Use the START menu to start the data logger running. It will begin +//! collecting and storing the data. It will continue to collect data until +//! stopped by pressing the left button or select button. +//! +//! While the data logger is collecting data and it is not configured to +//! sleep, a simple strip chart showing the collected data will appear on the +//! display. If the data logger is configured to sleep, then no strip chart +//! will be shown. +//! +//! If the data logger is storing to internal flash memory, it will overwrite +//! the oldest data. If storing to a USB memory device it will store data +//! until the device is full. +//! +//! The VIEW menu allows viewing the values of the data sources in numerical +//! format. When viewed this way the data is not stored. +//! +//! The SAVE menu allows saving data that was stored in internal flash memory +//! to a USB stick. The data will be saved in a text file in CSV format. +//! +//! The ERASE menu is used to erase the internal memory so more data can be +//! saved. +//! +//! When the EK-LM4F232 board running qs-logger is connected to a host PC via +//! the USB OTG connection for the first time, Windows will prompt for a device +//! driver for the board. +//! This can be found in /ti/TivaWare_C_Series-x.x/windows_drivers +//! assuming you installed the software in the default folder. +//! +//! A companion Windows application, logger, can be found in the +//! /ti/TivaWare_C_Series-x.x/tools/bin directory. When the data logger's +//! STORAGE option is set to "HOST PC" and the board is connected to a PC +//! via the USB OTG connection, captured data will be transfered back to the PC +//! using the virtual serial port that the EK board offers. When the logger +//! application is run, it will search for the first connected EK-LM4F232 board +//! and display any sample data received. The application also offers the +//! option to log the data to a file on the PC. +// +//***************************************************************************** + +//***************************************************************************** +// +// The clock rate for the SysTick interrupt and a counter of system clock +// ticks. The SysTick interrupt is used for basic timing in the application. +// +//***************************************************************************** +#define CLOCK_RATE 100 +#define MS_PER_SYSTICK (1000 / CLOCK_RATE) +static volatile uint32_t g_ui32TickCount; +uint32_t g_ui32LastTick = 0; + +//***************************************************************************** +// +// A widget handle of the widget that should receive the focus of any button +// events. +// +//***************************************************************************** +static uint32_t g_ui32KeyFocusWidgetHandle; + +//***************************************************************************** +// +// Tracks the data logging state. +// +//***************************************************************************** +typedef enum +{ + eSTATE_IDLE, + eSTATE_LOGGING, + eSTATE_VIEWING, + eSTATE_SAVING, + eSTATE_ERASING, + eSTATE_FREEFLASH, + eSTATE_CLOCKSET, + eSTATE_CLOCKEXIT, +} tLoggerState; +static tLoggerState g_iLoggerState = eSTATE_IDLE; + +//***************************************************************************** +// +// The configuration of the application. This holds the information that +// will need to be saved if sleeping is used. +// +//***************************************************************************** +static tConfigState g_sConfigState; + +//***************************************************************************** +// +// The current state of USB OTG in the system based on the detected mode. +// +//***************************************************************************** +volatile tUSBMode g_iCurrentUSBMode = eUSBModeNone; + +//***************************************************************************** +// +// The size of the host controller's memory pool in bytes. +// +//***************************************************************************** +#define HCD_MEMORY_SIZE 128 + +//***************************************************************************** +// +// The memory pool to provide to the Host controller driver. +// +//***************************************************************************** +uint8_t g_pui8HCDPool[HCD_MEMORY_SIZE]; + +//***************************************************************************** +// +// Forward declaration of callback function used for clock setter widget. +// +//***************************************************************************** +static void ClockSetOkCallback(tWidget *pWidget, bool bOk); + +//***************************************************************************** +// +// The error routine that is called if the driver library encounters an error. +// +//***************************************************************************** +#ifdef DEBUG +void +__error__(char *pcFilename, uint32_t ui32Line) +{ +} +#endif + +//***************************************************************************** +// +// Provide a simple function so other parts of the application can update +// a status display. +// +//***************************************************************************** +void +SetStatusText(const char *pcTitle, const char *pcLine1, const char *pcLine2, + const char *pcLine3) +{ + static const char pcBlankLine[] = " "; + + // + // Check to see if each parameter was passed, and if so then update its + // text field on the status dislay. + // + pcTitle = pcTitle ? pcTitle : pcBlankLine; + MenuUpdateText(TEXT_ITEM_STATUS_TITLE, pcTitle); + pcLine1 = pcLine1 ? pcLine1 : pcBlankLine; + MenuUpdateText(TEXT_ITEM_STATUS1, pcLine1); + pcLine2 = pcLine2 ? pcLine2 : pcBlankLine; + MenuUpdateText(TEXT_ITEM_STATUS2, pcLine2); + pcLine3 = pcLine3 ? pcLine3 : pcBlankLine; + MenuUpdateText(TEXT_ITEM_STATUS3, pcLine3); + + // + // Force a repaint after all the status text fields have been updated. + // + WidgetPaint(WIDGET_ROOT); + WidgetMessageQueueProcess(); +} +//***************************************************************************** +// +// Handles the SysTick timeout interrupt. +// +//***************************************************************************** +void +SysTickIntHandler(void) +{ + // + // Increment the tick count. + // + g_ui32TickCount++; +} + +//***************************************************************************** +// +// This function returns the number of ticks since the last time this function +// was called. +// +//***************************************************************************** +uint32_t +GetTickms(void) +{ + uint32_t ui32RetVal, ui32Saved; + + ui32RetVal = g_ui32TickCount; + ui32Saved = ui32RetVal; + + if(ui32Saved > g_ui32LastTick) + { + ui32RetVal = ui32Saved - g_ui32LastTick; + } + else + { + ui32RetVal = g_ui32LastTick - ui32Saved; + } + + // + // This could miss a few milliseconds but the timings here are on a + // much larger scale. + // + g_ui32LastTick = ui32Saved; + + // + // Return the number of milliseconds since the last time this was called. + // + return(ui32RetVal * MS_PER_SYSTICK); +} + +//***************************************************************************** +// +// Callback function for USB OTG mode changes. +// +//***************************************************************************** +static void +ModeCallback(uint32_t ui32Index, tUSBMode iMode) +{ + // + // Save the new mode. + // + g_iCurrentUSBMode = iMode; + + // + // Mode-specific handling code could go here. + // + switch(iMode) + { + case eUSBModeHost: + { + break; + } + case eUSBModeDevice: + { + break; + } + case eUSBModeNone: + { + break; + } + default: + { + break; + } + } +} + +//***************************************************************************** +// +// Gets the logger configuration from battery backed memory. +// The configuration is read from the memory in the Hibernate module. +// It is checked for validity. If found to be valid the function returns a +// 0. If not valid, then it returns non-zero. +// +//***************************************************************************** +static int32_t +GetSavedState(tConfigState *psState) +{ + uint32_t ui32StateLen; + uint16_t ui16Crc16; + + // + // Check the arguments + // + ASSERT(psState); + if(!psState) + { + return(1); + } + + // + // Initialize locals. + // + ui32StateLen = sizeof(tConfigState) / 4; + + // + // Read a block from hibernation memory into the application state + // structure. + // + HibernateDataGet((uint32_t *)psState, ui32StateLen); + + // + // Check first to see if the "cookie" value is correct. + // + if(psState->ui32Cookie != STATE_COOKIE) + { + return(1); + } + + // + // Find the 16-bit CRC of the block. The CRC is stored in the last + // location, so subtract 1 word from the count. + // + ui16Crc16 = ROM_Crc16Array(ui32StateLen - 1, (const uint32_t *)psState); + + // + // If the CRC does not match, then the block is not good. + // + if(psState->ui32Crc16 != (uint32_t)ui16Crc16) + { + return(1); + } + + // + // At this point the state structure that was retrieved from the + // battery backed memory has been validated, so return it as a valid + // logger state configuration. + // + return(0); +} + +//***************************************************************************** +// +// Stores the logger configuration to battery backed memory in the +// Hibernation module. The configuration is saved with a cookie value and +// a CRC in order to ensure validity. +// +//***************************************************************************** +static void +SetSavedState(tConfigState *psState) +{ + uint32_t ui32StateLen; + uint16_t ui16Crc16; + + // + // Check the arguments. + // + ASSERT(psState); + + // + // Initialize locals. + // + ui32StateLen = sizeof(tConfigState) / 4; + + if(psState) + { + // + // Write the cookie value to the block + // + psState->ui32Cookie = STATE_COOKIE; + + // + // Find the 16-bit CRC of the block. The CRC is stored in the last + // location, so subtract 1 word from the count. + // + ui16Crc16 = ROM_Crc16Array(ui32StateLen - 1, + (const uint32_t *)psState); + + // + // Save the computed CRC into the structure. + // + psState->ui32Crc16 = (uint32_t)ui16Crc16; + + // + // Now write the entire block to the Hibernate memory. + // + HibernateDataSet((uint32_t *)psState, ui32StateLen); + } +} + +//***************************************************************************** +// +// Populate the application configuration with default values. +// +//***************************************************************************** +static void +GetDefaultState(tConfigState *psState) +{ + // + // Check the arguments + // + ASSERT(psState); + if(psState) + { + // + // get the default values from the menu system + // + MenuGetDefaultState(psState); + + // + // Set the filename to a null string + // + psState->pcFilename[0] = 0; + + // + // Set bogus address for flash storage + // + psState->ui32FlashStore = 0; + + // + // Turn off sleep logging + // + psState->ui32SleepLogging = 0; + } +} + +//***************************************************************************** +// +// Sends a button press message to whichever widget has the button focus. +// +//***************************************************************************** +static void +SendWidgetKeyMessage(uint32_t ui32Msg) +{ + WidgetMessageQueueAdd(WIDGET_ROOT, ui32Msg, g_ui32KeyFocusWidgetHandle, 0, + 1, 1); +} + +//***************************************************************************** +// +// Callback function from the menu widget. This function is called whenever +// the menu is used to activate a child widget that is associated with the +// menu. It is also called when the widget is deactivated and control is +// returned to the menu widget. It can be used to trigger different actions +// depending on which menus are chosen, and to track the state of the +// application and control focus for the user interface. +// +// This function is called in the context of widget tree message processing +// so care should be taken if doing any operation that affects the display +// or widget tree. +// +//***************************************************************************** +static void +WidgetActivated(tWidget *psWidget, tSlideMenuItem *psMenuItem, bool bActivated) +{ + char *pcMenuText; + uint32_t ui32RTC; + + // + // Handle the activation or deactivation of the strip chart. The strip + // chart widget is activated when the user selects the START menu. + // + if(psWidget == &g_sStripChart.sBase) + { + // + // If the strip chart is activated, start the logger running. + // + if(bActivated) + { + // + // Get the current state of the menus + // + MenuGetState(&g_sConfigState); + + // + // Save the state in battery backed memory + // + SetSavedState(&g_sConfigState); + + // + // Start logger and update the logger state + // + AcquireStart(&g_sConfigState); + g_iLoggerState = eSTATE_LOGGING; + } + else + { + // + // If the strip chart is deactivated, stop the logger. + // + AcquireStop(); + g_iLoggerState = eSTATE_IDLE; + } + } + else if((psWidget == &g_sAINContainerCanvas.sBase) || + (psWidget == &g_sAccelContainerCanvas.sBase) || + (psWidget == &g_sCurrentContainerCanvas.sBase) || + (psWidget == &g_sClockContainerCanvas.sBase) || + (psWidget == &g_sTempContainerCanvas.sBase)) + { + // + // Handle the activation or deactivation of any of the container + // canvas that is used for showing the acquired data as a numerical + // display. This happens when the VIEW menu is used. + // + // A viewer has been activated. + // + if(bActivated) + { + static tConfigState sLocalState; + + // + // Get the current menu configuration state and save it in a local + // storage. + // + MenuGetState(&sLocalState); + + // + // Modify the state to set values that are suitable for using + // with the viewer. The acquisition rate is set to 1/2 second + // and all channels are selected. The storage medium is set to + // "viewer" so the acquistion module will write the value of + // acquired data to the appropriate viewing canvas. + // + sLocalState.ui8Storage = CONFIG_STORAGE_VIEWER; + sLocalState.ui32Period = 0x00000040; + sLocalState.ui16SelectedMask = 0x3ff; + + // + // Start the acquisition module running. + // + AcquireStart(&sLocalState); + g_iLoggerState = eSTATE_VIEWING; + } + else + { + // + // The viewer has been deactivated so turn off the acquisition + // module. + // + AcquireStop(); + g_iLoggerState = eSTATE_IDLE; + } + } + else if(psWidget == &g_sStatusContainerCanvas.sBase) + { + // + // Handle the case when a status display has been activated. This can + // occur when any of several menu items are selected. + // + // Get pointer to the text of the current menu item. + // + if(psMenuItem) + { + pcMenuText = psMenuItem->pcText; + } + else + { + return; + } + + // + // If activated from the SAVE menu, then the flash data needs to be + // saved to USB stick. Enter the saving state. + // + if(!strcmp(pcMenuText, "SAVE")) + { + if(bActivated) + { + g_iLoggerState = eSTATE_SAVING; + } + else + { + g_iLoggerState = eSTATE_IDLE; + } + } + else if(!strcmp(pcMenuText, "ERASE DATA?")) + { + // + // If activated from the ERASE menu, then the flash data needs to + // be erased. Enter the erasing state. + // + if(bActivated) + { + g_iLoggerState = eSTATE_ERASING; + } + else + { + g_iLoggerState = eSTATE_IDLE; + } + } + else if(!strcmp(pcMenuText, "FLASH SPACE")) + { + // + // If activated from the FLASH SPACE menu, then the user will be + // shown a report on the amount of free space in flash. Enter the + // reporting state. + // + if(bActivated) + { + g_iLoggerState = eSTATE_FREEFLASH; + } + else + { + g_iLoggerState = eSTATE_IDLE; + } + } + } + else if(psWidget == &g_sClockSetter.sBase) + { + // + // Handle the activation of the clock setting widget. Deactivation is + // handled through a separate callback. + // + // If the clock setter is activated, load the time structure fields. + // + if(bActivated) + { + // + // Get the current time in seconds from the RTC. + // + ui32RTC = HibernateRTCGet(); + + // + // Convert the RTC time to a time structure. + // + ulocaltime(ui32RTC, &g_sTimeClock); + + // + // Set the callback that will be called when the clock setting + // widget is deactivated. Since the clock setting widget needs + // to take over the focus for button events, it uses a separate + // callback when it is finsihed. + // + ClockSetCallbackSet((tClockSetWidget *)psWidget, + ClockSetOkCallback); + + // + // Give the clock setter widget focus for the button events + // + g_ui32KeyFocusWidgetHandle = (uint32_t)psWidget; + g_iLoggerState = eSTATE_CLOCKSET; + } + } +} + +//***************************************************************************** +// +// This function is called when the user clicks OK or CANCEL in the clock +// setting widget. +// +//***************************************************************************** +static void +ClockSetOkCallback(tWidget *psWidget, bool bOk) +{ + uint32_t ui32RTC; + + // + // Only update the RTC if the OK button was selected. + // + if(bOk) + { + // + // Convert the time structure that was altered by the clock setting + // widget into seconds. + // + ui32RTC = umktime(&g_sTimeClock); + + // + // If the conversion was valid, then write the updated clock to the + // Hibernate RTC. + // + if(ui32RTC != (uint32_t)(-1)) + { + HibernateRTCSet(ui32RTC); + } + } + + // + // Set the state to clock exit so some cleanup can be done from the + // main loop. + // + g_iLoggerState = eSTATE_CLOCKEXIT; +} + +//***************************************************************************** +// +// Initialize and operate the data logger. +// +//***************************************************************************** +int +main(void) +{ + tContext sDisplayContext, sBufferContext; + uint32_t ui32HibIntStatus, ui32SysClock, ui32LastTickCount; + bool bSkipSplash; + uint8_t ui8ButtonState, ui8ButtonChanged; + uint_fast8_t ui8X, ui8Y; + + + // + // 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. + // + MAP_FPULazyStackingEnable(); + + // + // Set the clocking to run at 50 MHz. + // + MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | + SYSCTL_OSC_MAIN); + ui32SysClock = MAP_SysCtlClockGet(); + + // + // Initialize locals. + // + bSkipSplash = false; + ui32LastTickCount = 0; + + // + // Initialize the data acquisition module. This initializes the ADC + // hardware. + // + AcquireInit(); + + // + // Enable access to the hibernate peripheral. If the hibernate peripheral + // was already running then this will have no effect. + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); + + // + // Check to see if the hiberate module is already active and if so then + // read the saved configuration state. If both are okay, then proceed + // to check and see if we are logging data using sleep mode. + // + if(HibernateIsActive() && !GetSavedState(&g_sConfigState)) + { + // + // Read the status of the hibernate module. + // + ui32HibIntStatus = HibernateIntStatus(1); + + // + // If this is a pin wake, that means the user pressed the select + // button and we should terminate the sleep logging. In this case + // we will fall out of this conditional section, and go through the + // normal startup below, but skipping the splash screen so the user + // gets immediate response. + // + if(ui32HibIntStatus & HIBERNATE_INT_PIN_WAKE) + { + // + // Clear the interrupt flag so it is not seen again until another + // wake. + // + HibernateIntClear(HIBERNATE_INT_PIN_WAKE); + bSkipSplash = true; + } + + // + // Otherwise if we are waking from hibernate and it was not a pin + // wake, then it must be from RTC match. Check to see if we are + // sleep logging and if so then go through an abbreviated startup + // in order to collect the data and go back to sleep. + // + else if(g_sConfigState.ui32SleepLogging && + (ui32HibIntStatus & HIBERNATE_INT_RTC_MATCH_0)) + { + // + // Start logger and pass the configuration. The logger should + // configure itself to take one sample. + // + AcquireStart(&g_sConfigState); + g_iLoggerState = eSTATE_LOGGING; + + // + // Enter a forever loop to run the acquisition. This will run + // until a new sample has been taken and stored. + // + while(!AcquireRun()) + { + } + + // + // Getting here means that a data acquisition was performed and we + // can now go back to sleep. Save the configuration and then + // activate the hibernate. + // + SetSavedState(&g_sConfigState); + + // + // Set wake condition on pin-wake or RTC match. Then put the + // processor in hibernation. + // + HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC); + HibernateRequest(); + + // + // Hibernating takes a finite amount of time to occur, so wait + // here forever until hibernate activates and the processor + // power is removed. + // + for(;;) + { + } + } + + // + // Otherwise, this was not a pin wake, and we were not sleep logging, + // so just fall out of this conditional and go through the normal + // startup below. + // + } + else + { + // + // In this case, either the hibernate module was not already active, or + // the saved configuration was not valid. Initialize the configuration + // to the default state and then go through the normal startup below. + // + GetDefaultState(&g_sConfigState); + } + + // + // Enable the Hibernate module to run. + // + HibernateEnableExpClk(SysCtlClockGet()); + + // + // The hibernate peripheral trim register must be set per silicon + // erratum 2.1 + // + HibernateRTCTrimSet(0x7FFF); + + // + // Start the RTC running. If it was already running then this will have + // no effect. + // + HibernateRTCEnable(); + + // + // In case we were sleep logging and are now finished (due to user + // pressing select button), then disable sleep logging so it doesnt + // try to start up again. + // + g_sConfigState.ui32SleepLogging = 0; + SetSavedState(&g_sConfigState); + + // + // Initialize the display driver. + // + CFAL96x64x16Init(); + + // + // Initialize the buttons driver. + // + ButtonsInit(); + + // + // Pass the restored state to the menu system. + // + MenuSetState(&g_sConfigState); + + // + // Enable the USB peripheral + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); + + // + // Configure the required pins for USB operation. + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); + MAP_GPIOPinConfigure(GPIO_PG4_USB0EPEN); + MAP_GPIOPinTypeUSBDigital(GPIO_PORTG_BASE, GPIO_PIN_4); + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); + MAP_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7); + MAP_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); + + // + // Erratum workaround for silicon revision A1. VBUS must have pull-down. + // + if(CLASS_IS_TM4C123 && REVISION_IS_A1) + { + HWREG(GPIO_PORTB_BASE + GPIO_O_PDR) |= GPIO_PIN_1; + } + + // + // Initialize the USB stack mode and pass in a mode callback. + // + USBStackModeSet(0, eUSBModeOTG, ModeCallback); + + // + // Initialize the stack to be used with USB stick. + // + USBStickInit(); + + // + // Initialize the stack to be used as a serial device. + // + USBSerialInit(); + + // + // Initialize the USB controller for dual mode operation with a 2ms polling + // rate. + // + USBOTGModeInit(0, 2000, g_pui8HCDPool, HCD_MEMORY_SIZE); + + // + // Initialize the menus module. This module will control the user + // interface menuing system. + // + MenuInit(WidgetActivated); + + // + // Configure SysTick to periodically interrupt. + // + g_ui32TickCount = 0; + MAP_SysTickPeriodSet(ui32SysClock / CLOCK_RATE); + MAP_SysTickIntEnable(); + MAP_SysTickEnable(); + + // + // Initialize the display context and another context that is used + // as an offscreen drawing buffer for display animation effect + // + GrContextInit(&sDisplayContext, &g_sCFAL96x64x16); + GrContextInit(&sBufferContext, &g_sOffscreenDisplayA); + + // + // Show the splash screen if we are not skipping it. The only reason to + // skip it is if the application was in sleep-logging mode and the user + // just waked it up with the select button. + // + if(!bSkipSplash) + { + const uint8_t *pui8SplashLogo = g_pui8Image_TI_Black; + + // + // Draw the TI logo on the display. Use an animation effect where the + // logo will "slide" onto the screen. Allow select button to break + // out of animation. + // + for(ui8X = 0; ui8X < 96; ui8X++) + { + if(ButtonsPoll(0, 0) & SELECT_BUTTON) + { + break; + } + GrImageDraw(&sDisplayContext, pui8SplashLogo, 95 - ui8X, 0); + } + + // + // Leave the logo on the screen for a long duration. Monitor the + // buttons so that if the user presses the select button, the logo + // display is terminated and the application starts immediately. + // + while(g_ui32TickCount < 400) + { + if(ButtonsPoll(0, 0) & SELECT_BUTTON) + { + break; + } + } + + // + // Extended splash sequence + // + if(ButtonsPoll(0, 0) & UP_BUTTON) + { + for(ui8X = 0; ui8X < 96; ui8X += 4) + { + GrImageDraw(&sDisplayContext, + g_ppui8Image_Splash[(ui8X / 4) & 3], + (int32_t)ui8X - 96L, 0); + GrImageDraw(&sDisplayContext, pui8SplashLogo, ui8X, 0); + MAP_SysCtlDelay(ui32SysClock / 12); + } + MAP_SysCtlDelay(ui32SysClock / 3); + pui8SplashLogo = g_ppui8Image_Splash[4]; + GrImageDraw(&sDisplayContext, pui8SplashLogo, 0, 0); + MAP_SysCtlDelay(ui32SysClock / 12); + } + + // + // Draw the initial menu into the offscreen buffer. + // + SlideMenuDraw(&g_sMenuWidget, &sBufferContext, 0); + + // + // Now, draw both the TI logo splash screen (from above) and the initial + // menu on the screen at the same time, moving the coordinates so that + // the logo "slides" off the display and the menu "slides" onto the + // display. + // + for(ui8Y = 0; ui8Y < 64; ui8Y++) + { + GrImageDraw(&sDisplayContext, pui8SplashLogo, 0, -ui8Y); + GrImageDraw(&sDisplayContext, g_pui8OffscreenBufA, 0, 63 - ui8Y); + } + } + + // + // Add the menu widget to the widget tree and send an initial paint + // request. + // + WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sMenuWidget); + WidgetPaint(WIDGET_ROOT); + + // + // Set the focus handle to the menu widget. Any button events will be + // sent to this widget + // + g_ui32KeyFocusWidgetHandle = (uint32_t)&g_sMenuWidget; + + // + // Forever loop to run the application + // + while(1) + { + + // + // Each time the timer tick occurs, process any button events. + // + if(g_ui32TickCount != ui32LastTickCount) + { + // + // Remember last tick count + // + ui32LastTickCount = g_ui32TickCount; + + // + // Read the debounced state of the buttons. + // + ui8ButtonState = ButtonsPoll(&ui8ButtonChanged, 0); + + // + // Pass any button presses through to the widget message + // processing mechanism. The widget that has the button event + // focus (probably the menu widget) will catch these button events. + // + if(BUTTON_PRESSED(SELECT_BUTTON, ui8ButtonState, ui8ButtonChanged)) + { + SendWidgetKeyMessage(WIDGET_MSG_KEY_SELECT); + } + if(BUTTON_PRESSED(UP_BUTTON, ui8ButtonState, ui8ButtonChanged)) + { + SendWidgetKeyMessage(WIDGET_MSG_KEY_UP); + } + if(BUTTON_PRESSED(DOWN_BUTTON, ui8ButtonState, ui8ButtonChanged)) + { + SendWidgetKeyMessage(WIDGET_MSG_KEY_DOWN); + } + if(BUTTON_PRESSED(LEFT_BUTTON, ui8ButtonState, ui8ButtonChanged)) + { + SendWidgetKeyMessage(WIDGET_MSG_KEY_LEFT); + } + if(BUTTON_PRESSED(RIGHT_BUTTON, ui8ButtonState, ui8ButtonChanged)) + { + SendWidgetKeyMessage(WIDGET_MSG_KEY_RIGHT); + } + } + + // + // Tell the OTG library code how much time has passed in milliseconds + // since the last call. + // + USBOTGMain(GetTickms()); + + // + // Call functions as needed to keep the host or device mode running. + // + if(g_iCurrentUSBMode == eUSBModeDevice) + { + USBSerialRun(); + } + else if(g_iCurrentUSBMode == eUSBModeHost) + { + USBStickRun(); + } + + // + // If in the logging state, then call the logger run function. This + // keeps the data acquisition running. + // + if((g_iLoggerState == eSTATE_LOGGING) || + (g_iLoggerState == eSTATE_VIEWING)) + { + if(AcquireRun() && g_sConfigState.ui32SleepLogging) + { + // + // If sleep logging is enabled, then at this point we have + // stored the first data item, now save the state and start + // hibernation. Wait for the power to be cut. + // + SetSavedState(&g_sConfigState); + HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC); + HibernateRequest(); + for(;;) + { + } + } + + // + // If viewing instead of logging then request a repaint to keep + // the viewing window updated. + // + if(g_iLoggerState == eSTATE_VIEWING) + { + WidgetPaint(WIDGET_ROOT); + } + } + + // + // If in the saving state, then save data from flash storage to + // USB stick. + // + if(g_iLoggerState == eSTATE_SAVING) + { + // + // Save data from flash to USB + // + FlashStoreSave(); + + // + // Return to idle state + // + g_iLoggerState = eSTATE_IDLE; + } + + // + // If in the erasing state, then erase the data stored in flash. + // + if(g_iLoggerState == eSTATE_ERASING) + { + // + // Save data from flash to USB + // + FlashStoreErase(); + + // + // Return to idle state + // + g_iLoggerState = eSTATE_IDLE; + } + + // + // If in the flash reporting state, then show the report of the amount + // of used and free flash memory. + // + if(g_iLoggerState == eSTATE_FREEFLASH) + { + // + // Report free flash space + // + FlashStoreReport(); + + // + // Return to idle state + // + g_iLoggerState = eSTATE_IDLE; + } + + // + // If we are exiting the clock setting widget, that means that control + // needs to be given back to the menu system. + // + if(g_iLoggerState == eSTATE_CLOCKEXIT) + { + // + // Give the button event focus back to the menu system + // + g_ui32KeyFocusWidgetHandle = (uint32_t)&g_sMenuWidget; + + // + // Send a button event to the menu widget that means the left + // key was pressed. This signals the menu widget to deactivate + // the current child widget (which was the clock setting wigdet). + // This will cause the menu widget to slide the clock set widget + // off the screen and resume control of the display. + // + SendWidgetKeyMessage(WIDGET_MSG_KEY_LEFT); + g_iLoggerState = eSTATE_IDLE; + } + + // + // Process any new messages that are in the widget queue. This keeps + // the user interface running. + // + WidgetMessageQueueProcess(); + } +} diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.ewd b/boards/ek-lm4f232/qs-logger/qs-logger.ewd new file mode 100644 index 0000000..5e62dcd --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.ewd @@ -0,0 +1,614 @@ + + + + 1 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 15 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + JLINK_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 1 + 1 + 1 + + + + + + + + MACRAIGOR_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OSE\OseEpsilonPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + + diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.ewp b/boards/ek-lm4f232/qs-logger/qs-logger.ewp new file mode 100644 index 0000000..7250522 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.ewp @@ -0,0 +1,845 @@ + + + + 1 + + Debug + + ARM + + 1 + + General + 3 + + 14 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 19 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 5 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Libraries + + $PROJ_DIR$\..\..\..\..\driverlib\ewarm\Exe\driverlib.a + + + $PROJ_DIR$\..\..\..\..\grlib\ewarm\Exe\grlib.a + + + $PROJ_DIR$\..\..\..\..\usblib\ewarm\Exe\usblib.a + + + + Source + + $PROJ_DIR$\acquire.c + + + $PROJ_DIR$\..\drivers\buttons.c + + + $PROJ_DIR$\..\drivers\cfal96x64x16.c + + + $PROJ_DIR$\clocksetwidget.c + + + $PROJ_DIR$\..\..\..\..\third_party\fatfs\port\fat_usbmsc.c + + + $PROJ_DIR$\..\..\..\..\third_party\fatfs\src\ff.c + + + $PROJ_DIR$\flashstore.c + + + $PROJ_DIR$\images.c + + + $PROJ_DIR$\menus.c + + + $PROJ_DIR$\qs-logger.c + + + $PROJ_DIR$\..\drivers\slidemenuwidget.c + + + $PROJ_DIR$\startup_ewarm.c + + + $PROJ_DIR$\stripchartmanager.c + + + $PROJ_DIR$\..\drivers\stripchartwidget.c + + + $PROJ_DIR$\..\..\..\..\utils\uartstdio.c + + + $PROJ_DIR$\usb_serial_structs.c + + + $PROJ_DIR$\usbserial.c + + + $PROJ_DIR$\usbstick.c + + + $PROJ_DIR$\..\..\..\..\utils\ustdlib.c + + + diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.h b/boards/ek-lm4f232/qs-logger/qs-logger.h new file mode 100644 index 0000000..a8d7878 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.h @@ -0,0 +1,180 @@ +//***************************************************************************** +// +// qs-logger.h - Defines data types used in the data logger application. +// +// 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. +// +//***************************************************************************** + +#ifndef __QS_LOGGER_H__ +#define __QS_LOGGER_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// The following defines the order of data items to log. It must match the +// order that they appear in the "CHANNELS" menu (see menus.c), and also +// the order they are stored in the ADC data buffer (see acquire.c). +// +//***************************************************************************** +#define LOG_ITEM_USER0 0 +#define LOG_ITEM_USER1 1 +#define LOG_ITEM_USER2 2 +#define LOG_ITEM_USER3 3 +#define LOG_ITEM_ACCELX 4 +#define LOG_ITEM_ACCELY 5 +#define LOG_ITEM_ACCELZ 6 +#define LOG_ITEM_EXTTEMP 7 +#define LOG_ITEM_INTTEMP 8 +#define LOG_ITEM_CURRENT 9 +#define NUM_LOG_ITEMS 10 + +//***************************************************************************** +// +// These are additional definitions of items that may be displayed on the +// screen that are not acquired data. These are used for updating dynamic +// text screens on the display. +// +//***************************************************************************** +#define TEXT_ITEM_STATUS1 10 +#define TEXT_ITEM_STATUS2 11 +#define TEXT_ITEM_STATUS3 12 +#define TEXT_ITEM_STATUS_TITLE 13 +#define TEXT_ITEM_DATE 14 +#define TEXT_ITEM_TIME 15 +#define NUM_TEXT_ITEMS 16 + +//***************************************************************************** +// +// A structure that defines a data record. This is the binary format of the +// acquired data that will be stored. +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32Seconds; // 32 bits of seconds + uint16_t ui16Subseconds; // 15 bits of subseconds + uint16_t ui16ItemMask; // 16 bits means maximum 16 items + int16_t pi16Items[]; +} +tLogRecord; + +//***************************************************************************** +// +// This structure defines a container to hold the state of all the +// configuration items. It is used both for passing configuration +// between modules and for persistent storage of the configuration. +// +//***************************************************************************** +typedef struct +{ + // + // A value used to identify this structure + // + uint32_t ui32Cookie; + + // + // A flag to indicate if the data logger is current logging data + // using the sleep mode. The data logger uses this to determine if + // it needs to continue taking samples once it wakes from hibernate. + // This is a 32-bit type just to keep the entire struct 32-bit aligned. + // + uint32_t ui32SleepLogging; + + // + // The period for sampling data. It is stored as a 24.8 seconds.frac + // format. The lower 8 bits represent power-of-2 fractional seconds + // with a resolution of 1/128 seconds (only lower 7 bits are used). + // + uint32_t ui32Period; + + // + // Saved location for writing records to flash. + // + uint32_t ui32FlashStore; + + // + // The name of the USB file currently opened for logging + // + char pcFilename[8]; + + // + // The bit mask of the channels selected for logging. + // + uint16_t ui16SelectedMask; + + // + // A flag indicating whether the data logger should sleep between samples. + // + bool bSleep; + + // + // A value that is used to select the storage medium. + // + uint8_t ui8Storage; + + // + // A checksum for the structure + // + uint32_t ui32Crc16; +} +tConfigState; + +#define STATE_COOKIE 0x0355AAC0 + +//***************************************************************************** +// +// The values indicating which storage medium is to be used for logging data. +// +//***************************************************************************** +#define CONFIG_STORAGE_NONE 0 +#define CONFIG_STORAGE_USB 1 +#define CONFIG_STORAGE_HOSTPC 2 +#define CONFIG_STORAGE_FLASH 3 +#define CONFIG_STORAGE_VIEWER 4 +#define CONFIG_STORAGE_CHOICES 5 + +//***************************************************************************** +// +// Function prototypes. +// +//***************************************************************************** +extern void SetStatusText(const char *pcTitle, const char *pcLine1, + const char *pcLine2, const char *pcLine3); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __QS_LOGGER_H__ diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.icf b/boards/ek-lm4f232/qs-logger/qs-logger.icf new file mode 100644 index 0000000..50dc88b --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.icf @@ -0,0 +1,78 @@ +//***************************************************************************** +// +// qs-logger.icf - Linker configuration file for qs-logger. +// +// 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. +// +//***************************************************************************** + +// +// Define a memory region that covers the entire 4 GB addressible space of the +// processor. +// +define memory mem with size = 4G; + +// +// Define a region for the on-chip flash. +// +define region FLASH = mem:[from 0x00000000 to 0x0003ffff]; + +// +// Define a region for the on-chip SRAM. +// +define region SRAM = mem:[from 0x20000000 to 0x20007fff]; + +// +// Define a block for the heap. The size should be set to something other +// than zero if things in the C library that require the heap are used. +// +define block HEAP with alignment = 8, size = 0x00000000 { }; + +// +// Indicate that the read/write values should be initialized by copying from +// flash. +// +initialize by copy { readwrite }; + +// +// Indicate that the noinit values should be left alone. This includes the +// stack, which if initialized will destroy the return address from the +// initialization code, causing the processor to branch to zero and fault. +// +do not initialize { section .noinit }; + +// +// Place the interrupt vectors at the start of flash. +// +place at start of FLASH { readonly section .intvec }; + +// +// Place the remainder of the read-only items into flash. +// +place in FLASH { readonly }; + +// +// Place the RAM vector table at the start of SRAM. +// +place at start of SRAM { section VTABLE }; + +// +// Place all read/write items into SRAM. +// +place in SRAM { readwrite, block HEAP }; diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.ld b/boards/ek-lm4f232/qs-logger/qs-logger.ld new file mode 100644 index 0000000..d76e251 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.ld @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * qs-logger.ld - Linker configuration file for qs-logger. + * + * 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. + * + *****************************************************************************/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH + + .data : AT(ADDR(.text) + SIZEOF(.text)) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM +} diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.sct b/boards/ek-lm4f232/qs-logger/qs-logger.sct new file mode 100644 index 0000000..198f208 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.sct @@ -0,0 +1,47 @@ +;****************************************************************************** +; +; qs-logger.sct - Linker configuration file for qs-logger. +; +; 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. +; +;****************************************************************************** + +LR_IROM 0x00000000 0x00040000 +{ + ; + ; Specify the Execution Address of the code and the size. + ; + ER_IROM 0x00000000 0x00040000 + { + *.o (RESET, +First) + * (InRoot$$Sections, +RO) + } + + ; + ; Specify the Execution Address of the data area. + ; + RW_IRAM 0x20000000 0x00008000 + { + ; + ; Uncomment the following line in order to use IntRegister(). + ; + ;* (vtable, +First) + * (+RW, +ZI) + } +} diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.uvopt b/boards/ek-lm4f232/qs-logger/qs-logger.uvopt new file mode 100644 index 0000000..e848d39 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.uvopt @@ -0,0 +1,555 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + qs-logger + 0x4 + ARM-ADS + + 8000000 + + 1 + 1 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rvmdk\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + + 0 + Data Sheet + DATASHTS\Luminary\TM4C123GH6PGE.PDF + + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 4 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + lmidk-agdi + -O4614 -S3 -FO29 + + + 0 + DLGTARM + + + + 0 + ARMDBGFLAGS + + + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + Source + 1 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\acquire.c + acquire.c + + + 1 + 2 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\drivers\buttons.c + buttons.c + + + 1 + 3 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\drivers\cfal96x64x16.c + cfal96x64x16.c + + + 1 + 4 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\clocksetwidget.c + clocksetwidget.c + + + 1 + 5 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\third_party\fatfs\port\fat_usbmsc.c + fat_usbmsc.c + + + 1 + 6 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\third_party\fatfs\src\ff.c + ff.c + + + 1 + 7 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\flashstore.c + flashstore.c + + + 1 + 8 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\images.c + images.c + + + 1 + 9 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\menus.c + menus.c + + + 1 + 10 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\qs-logger.c + qs-logger.c + + + 1 + 11 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\drivers\slidemenuwidget.c + slidemenuwidget.c + + + 1 + 12 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\startup_rvmdk.S + startup_rvmdk.S + + + 1 + 13 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\stripchartmanager.c + stripchartmanager.c + + + 1 + 14 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\drivers\stripchartwidget.c + stripchartwidget.c + + + 1 + 15 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\utils\uartstdio.c + uartstdio.c + + + 1 + 16 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\usb_serial_structs.c + usb_serial_structs.c + + + 1 + 17 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\usbserial.c + usbserial.c + + + 1 + 18 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + .\usbstick.c + usbstick.c + + + 1 + 19 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\utils\ustdlib.c + ustdlib.c + + + + + Libraries + 1 + 0 + 0 + + 2 + 20 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\driverlib\rvmdk\driverlib.lib + driverlib.lib + + + 2 + 21 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\grlib\rvmdk\grlib.lib + grlib.lib + + + 2 + 22 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\usblib\rvmdk\usblib.lib + usblib.lib + + + + + Documentation + 1 + 0 + 0 + + 3 + 23 + 5 + 0 + 1 + 0 + 0 + 1 + 1 + 0 + .\readme.txt + readme.txt + + 44 + 0 + 1 + + -1 + -1 + + + -1 + -1 + + + 0 + 0 + 729 + 300 + + + + + + + 1 + 0 + + 100 + 0 + + + .\readme.txt + 0 + 1 + 1 + + + + + +
diff --git a/boards/ek-lm4f232/qs-logger/qs-logger.uvproj b/boards/ek-lm4f232/qs-logger/qs-logger.uvproj new file mode 100644 index 0000000..a3150d8 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger.uvproj @@ -0,0 +1,519 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + qs-logger + 0x4 + ARM-ADS + + + TM4C123GH6PGE + Texas Instruments + IRAM(0x20000000-0x20007FFF) IROM(0-0x3FFFF) CLOCK(8000000) CPUTYPE("Cortex-M4") FPU2 + + "STARTUP\Luminary\Startup.s" ("Luminary Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0LM4F_256 -FS00 -FL040000) + 5919 + LM4Fxxxx.H + + + + + + + + + + 0 + + + + Luminary\ + Luminary\ + + 0 + 0 + 0 + 0 + 1 + + .\rvmdk\ + qs-logger + 1 + 0 + 0 + 1 + 1 + .\rvmdk\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rvmdk\qs-logger.bin .\rvmdk\qs-logger.axf + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + + + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + + 0 + 4 + + + + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + + 1 + 0 + 0 + 0 + 1 + 4099 + + BIN\lmidk-agdi.dll + + + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 8 + 1 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + + --c99 + rvmdk PART_TM4C123GH6PGE TARGET_IS_TM4C123_RA1 + + ..;..\..\..\..;..\..\..\..\third_party; + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + qs-logger.sct + + + --entry Reset_Handler + + + + + + + + Source + + + acquire.c + 1 + .\acquire.c + + + buttons.c + 1 + ..\drivers\buttons.c + + + cfal96x64x16.c + 1 + ..\drivers\cfal96x64x16.c + + + clocksetwidget.c + 1 + .\clocksetwidget.c + + + fat_usbmsc.c + 1 + ..\..\..\..\third_party\fatfs\port\fat_usbmsc.c + + + ff.c + 1 + ..\..\..\..\third_party\fatfs\src\ff.c + + + flashstore.c + 1 + .\flashstore.c + + + images.c + 1 + .\images.c + + + menus.c + 1 + .\menus.c + + + qs-logger.c + 1 + .\qs-logger.c + + + slidemenuwidget.c + 1 + ..\drivers\slidemenuwidget.c + + + startup_rvmdk.S + 2 + .\startup_rvmdk.S + + + stripchartmanager.c + 1 + .\stripchartmanager.c + + + stripchartwidget.c + 1 + ..\drivers\stripchartwidget.c + + + uartstdio.c + 1 + ..\..\..\..\utils\uartstdio.c + + + usb_serial_structs.c + 1 + .\usb_serial_structs.c + + + usbserial.c + 1 + .\usbserial.c + + + usbstick.c + 1 + .\usbstick.c + + + ustdlib.c + 1 + ..\..\..\..\utils\ustdlib.c + + + + + Libraries + + + driverlib.lib + 4 + ..\..\..\..\driverlib\rvmdk\driverlib.lib + + + grlib.lib + 4 + ..\..\..\..\grlib\rvmdk\grlib.lib + + + usblib.lib + 4 + ..\..\..\..\usblib\rvmdk\usblib.lib + + + + + Documentation + + + readme.txt + 5 + .\readme.txt + + + + + + + +
diff --git a/boards/ek-lm4f232/qs-logger/qs-logger_ccs.cmd b/boards/ek-lm4f232/qs-logger/qs-logger_ccs.cmd new file mode 100644 index 0000000..f64402c --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/qs-logger_ccs.cmd @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * qs-logger_ccs.cmd - CCS linker configuration file for qs-logger. + * + * 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. + * + *****************************************************************************/ + +--retain=g_pfnVectors + +/* The following command line options are set as part of the CCS project. */ +/* If you are building using the command line, or for some reason want to */ +/* define them here, you can uncomment and modify these lines as needed. */ +/* If you are using CCS for building, it is probably better to make any such */ +/* modifications in your CCS project and leave this file alone. */ +/* */ +/* --heap_size=0 */ +/* --stack_size=256 */ +/* --library=rtsv7M3_T_le_eabi.lib */ + +/* The starting address of the application. Normally the interrupt vectors */ +/* must be located at the beginning of the application. */ +#define APP_BASE 0x00000000 +#define RAM_BASE 0x20000000 + +/* System memory map */ + +MEMORY +{ + /* Application stored in and executes from internal flash */ + FLASH (RX) : origin = APP_BASE, length = 0x00040000 + /* Application uses internal RAM for data */ + SRAM (RWX) : origin = 0x20000000, length = 0x00008000 +} + +/* Section allocation in memory */ + +SECTIONS +{ + .intvecs: > APP_BASE + .text : > FLASH + .const : > FLASH + .cinit : > FLASH + .pinit : > FLASH + .init_array : > FLASH + + .vtable : > RAM_BASE + .data : > SRAM + .bss : > SRAM + .sysmem : > SRAM + .stack : > SRAM +} + +__STACK_TOP = __stack + 1024; diff --git a/boards/ek-lm4f232/qs-logger/readme.txt b/boards/ek-lm4f232/qs-logger/readme.txt new file mode 100644 index 0000000..1877536 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/readme.txt @@ -0,0 +1,93 @@ +Data Logger + +This example application is a data logger. It can be configured to collect +data from up to 10 data sources. The possible data sources are: +- 4 analog inputs, 0-20V +- 3-axis accelerometer +- internal and external temperature sensors +- processor current consumption + +The data logger provides a menu navigation that is operated by the buttons +on the EK-LM4F232 board (up, down, left, right, select). The data logger +can be configured by using the menus. The following items can be +configured: +- data sources to be logged +- sample rate +- storage location +- sleep modes +- clock + +Using the data logger: + +Use the CONFIG menu to configure the data logger. The following choices +are provided: + +- CHANNELS - enable specific channels of data that will be logged +- PERIOD - select the sample period +- STORAGE - select where the collected data will be stored: + - FLASH - stored in the internal flash memory + - USB - stored on a connected USB memory stick + - HOST PC - transmitted to a host PC via USB OTG virtual serial port + - NONE - the data will only be displayed and not stored +- SLEEP - select whether or not the board sleeps between samples. Sleep +mode is allowed when storing to flash at with a period of 1 second or +longer. +- CLOCK - allows setting of internal time-of-day clock that is used for +time stamping of the sampled data + +Use the START menu to start the data logger running. It will begin +collecting and storing the data. It will continue to collect data until +stopped by pressing the left button or select button. + +While the data logger is collecting data and it is not configured to +sleep, a simple strip chart showing the collected data will appear on the +display. If the data logger is configured to sleep, then no strip chart +will be shown. + +If the data logger is storing to internal flash memory, it will overwrite +the oldest data. If storing to a USB memory device it will store data +until the device is full. + +The VIEW menu allows viewing the values of the data sources in numerical +format. When viewed this way the data is not stored. + +The SAVE menu allows saving data that was stored in internal flash memory +to a USB stick. The data will be saved in a text file in CSV format. + +The ERASE menu is used to erase the internal memory so more data can be +saved. + +When the EK-LM4F232 board running qs-logger is connected to a host PC via +the USB OTG connection for the first time, Windows will prompt for a device +driver for the board. +This can be found in /ti/TivaWare_C_Series-x.x/windows_drivers +assuming you installed the software in the default folder. + +A companion Windows application, logger, can be found in the +/ti/TivaWare_C_Series-x.x/tools/bin directory. When the data logger's + STORAGE option is set to "HOST PC" and the board is connected to a PC +via the USB OTG connection, captured data will be transfered back to the PC +using the virtual serial port that the EK board offers. When the logger +application is run, it will search for the first connected EK-LM4F232 board +and display any sample data received. The application also offers the +option to log the data to a file on the PC. + +------------------------------------------------------------------------------- + +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. diff --git a/boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.axf b/boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.axf new file mode 100644 index 0000000..975cc12 Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.axf differ diff --git a/boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.bin b/boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.bin new file mode 100644 index 0000000..7c7687b Binary files /dev/null and b/boards/ek-lm4f232/qs-logger/rvmdk/qs-logger.bin differ diff --git a/boards/ek-lm4f232/qs-logger/startup_ccs.c b/boards/ek-lm4f232/qs-logger/startup_ccs.c new file mode 100644 index 0000000..ae2a97c --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/startup_ccs.c @@ -0,0 +1,305 @@ +//***************************************************************************** +// +// startup_ccs.c - Startup code for use with TI's Code Composer Studio. +// +// 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 +#include "inc/hw_nvic.h" +#include "inc/hw_types.h" + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); + +//***************************************************************************** +// +// External declaration for the reset handler that is to be called when the +// processor is started +// +//***************************************************************************** +extern void _c_int00(void); + +//***************************************************************************** +// +// Linker variable that marks the top of the stack. +// +//***************************************************************************** +extern uint32_t __STACK_TOP; + +//***************************************************************************** +// +// External declarations for the interrupt handlers used by the application. +// +//***************************************************************************** +extern void ADC0SS0Handler(void); +extern void RTCHandler(void); +extern void SysTickIntHandler(void); +extern void USB0OTGModeIntHandler(void); + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000 or at the start of +// the program if located at a start address other than 0. +// +//***************************************************************************** +#pragma DATA_SECTION(g_pfnVectors, ".intvecs") +void (* const g_pfnVectors[])(void) = +{ + (void (*)(void))((uint32_t)&__STACK_TOP), + // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + IntDefaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // SVCall handler + IntDefaultHandler, // Debug monitor handler + 0, // Reserved + IntDefaultHandler, // The PendSV handler + SysTickIntHandler, // The SysTick handler + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + IntDefaultHandler, // GPIO Port C + IntDefaultHandler, // GPIO Port D + IntDefaultHandler, // GPIO Port E + IntDefaultHandler, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + IntDefaultHandler, // SSI0 Rx and Tx + IntDefaultHandler, // I2C0 Master and Slave + IntDefaultHandler, // PWM Fault + IntDefaultHandler, // PWM Generator 0 + IntDefaultHandler, // PWM Generator 1 + IntDefaultHandler, // PWM Generator 2 + IntDefaultHandler, // Quadrature Encoder 0 + ADC0SS0Handler, // ADC Sequence 0 + IntDefaultHandler, // ADC Sequence 1 + IntDefaultHandler, // ADC Sequence 2 + IntDefaultHandler, // ADC Sequence 3 + IntDefaultHandler, // Watchdog timer + IntDefaultHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + IntDefaultHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + IntDefaultHandler, // Analog Comparator 0 + IntDefaultHandler, // Analog Comparator 1 + IntDefaultHandler, // Analog Comparator 2 + IntDefaultHandler, // System Control (PLL, OSC, BO) + IntDefaultHandler, // FLASH Control + IntDefaultHandler, // GPIO Port F + IntDefaultHandler, // GPIO Port G + IntDefaultHandler, // GPIO Port H + IntDefaultHandler, // UART2 Rx and Tx + IntDefaultHandler, // SSI1 Rx and Tx + IntDefaultHandler, // Timer 3 subtimer A + IntDefaultHandler, // Timer 3 subtimer B + IntDefaultHandler, // I2C1 Master and Slave + IntDefaultHandler, // Quadrature Encoder 1 + IntDefaultHandler, // CAN0 + IntDefaultHandler, // CAN1 + 0, // Reserved + 0, // Reserved + RTCHandler, // Hibernate + USB0OTGModeIntHandler, // USB0 + IntDefaultHandler, // PWM Generator 3 + IntDefaultHandler, // uDMA Software Transfer + IntDefaultHandler, // uDMA Error + IntDefaultHandler, // ADC1 Sequence 0 + IntDefaultHandler, // ADC1 Sequence 1 + IntDefaultHandler, // ADC1 Sequence 2 + IntDefaultHandler, // ADC1 Sequence 3 + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // GPIO Port J + IntDefaultHandler, // GPIO Port K + IntDefaultHandler, // GPIO Port L + IntDefaultHandler, // SSI2 Rx and Tx + IntDefaultHandler, // SSI3 Rx and Tx + IntDefaultHandler, // UART3 Rx and Tx + IntDefaultHandler, // UART4 Rx and Tx + IntDefaultHandler, // UART5 Rx and Tx + IntDefaultHandler, // UART6 Rx and Tx + IntDefaultHandler, // UART7 Rx and Tx + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // I2C2 Master and Slave + IntDefaultHandler, // I2C3 Master and Slave + IntDefaultHandler, // Timer 4 subtimer A + IntDefaultHandler, // Timer 4 subtimer B + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // Timer 5 subtimer A + IntDefaultHandler, // Timer 5 subtimer B + IntDefaultHandler, // Wide Timer 0 subtimer A + IntDefaultHandler, // Wide Timer 0 subtimer B + IntDefaultHandler, // Wide Timer 1 subtimer A + IntDefaultHandler, // Wide Timer 1 subtimer B + IntDefaultHandler, // Wide Timer 2 subtimer A + IntDefaultHandler, // Wide Timer 2 subtimer B + IntDefaultHandler, // Wide Timer 3 subtimer A + IntDefaultHandler, // Wide Timer 3 subtimer B + IntDefaultHandler, // Wide Timer 4 subtimer A + IntDefaultHandler, // Wide Timer 4 subtimer B + IntDefaultHandler, // Wide Timer 5 subtimer A + IntDefaultHandler, // Wide Timer 5 subtimer B + IntDefaultHandler, // FPU + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // I2C4 Master and Slave + IntDefaultHandler, // I2C5 Master and Slave + IntDefaultHandler, // GPIO Port M + IntDefaultHandler, // GPIO Port N + IntDefaultHandler, // Quadrature Encoder 2 + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // GPIO Port P (Summary or P0) + IntDefaultHandler, // GPIO Port P1 + IntDefaultHandler, // GPIO Port P2 + IntDefaultHandler, // GPIO Port P3 + IntDefaultHandler, // GPIO Port P4 + IntDefaultHandler, // GPIO Port P5 + IntDefaultHandler, // GPIO Port P6 + IntDefaultHandler, // GPIO Port P7 + IntDefaultHandler, // GPIO Port Q (Summary or Q0) + IntDefaultHandler, // GPIO Port Q1 + IntDefaultHandler, // GPIO Port Q2 + IntDefaultHandler, // GPIO Port Q3 + IntDefaultHandler, // GPIO Port Q4 + IntDefaultHandler, // GPIO Port Q5 + IntDefaultHandler, // GPIO Port Q6 + IntDefaultHandler, // GPIO Port Q7 + IntDefaultHandler, // GPIO Port R + IntDefaultHandler, // GPIO Port S + IntDefaultHandler, // PWM 1 Generator 0 + IntDefaultHandler, // PWM 1 Generator 1 + IntDefaultHandler, // PWM 1 Generator 2 + IntDefaultHandler, // PWM 1 Generator 3 + IntDefaultHandler // PWM 1 Fault +}; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +ResetISR(void) +{ + // + // Jump to the CCS C initialization routine. This will enable the + // floating-point unit as well, so that does not need to be done here. + // + __asm(" .global _c_int00\n" + " b.w _c_int00"); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiSR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/boards/ek-lm4f232/qs-logger/startup_ewarm.c b/boards/ek-lm4f232/qs-logger/startup_ewarm.c new file mode 100644 index 0000000..d95fb5e --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/startup_ewarm.c @@ -0,0 +1,336 @@ +//***************************************************************************** +// +// startup_ewarm.c - Startup code for use with IAR's Embedded Workbench, +// version 5. +// +// 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 +#include "inc/hw_nvic.h" +#include "inc/hw_types.h" + +//***************************************************************************** +// +// Enable the IAR extensions for this source file. +// +//***************************************************************************** +#pragma language=extended + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); + +//***************************************************************************** +// +// External declarations for the interrupt handlers used by the application. +// +//***************************************************************************** +extern void ADC0SS0Handler(void); +extern void RTCHandler(void); +extern void SysTickIntHandler(void); +extern void USB0OTGModeIntHandler(void); + +//***************************************************************************** +// +// The entry point for the application startup code. +// +//***************************************************************************** +extern void __iar_program_start(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +static uint32_t pui32Stack[256] @ ".noinit"; + +//***************************************************************************** +// +// A union that describes the entries of the vector table. The union is needed +// since the first entry is the stack pointer and the remainder are function +// pointers. +// +//***************************************************************************** +typedef union +{ + void (*pfnHandler)(void); + uint32_t ui32Ptr; +} +uVectorEntry; + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000. +// +//***************************************************************************** +__root const uVectorEntry __vector_table[] @ ".intvec" = +{ + { .ui32Ptr = (uint32_t)pui32Stack + sizeof(pui32Stack) }, + // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + IntDefaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // SVCall handler + IntDefaultHandler, // Debug monitor handler + 0, // Reserved + IntDefaultHandler, // The PendSV handler + SysTickIntHandler, // The SysTick handler + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + IntDefaultHandler, // GPIO Port C + IntDefaultHandler, // GPIO Port D + IntDefaultHandler, // GPIO Port E + IntDefaultHandler, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + IntDefaultHandler, // SSI0 Rx and Tx + IntDefaultHandler, // I2C0 Master and Slave + IntDefaultHandler, // PWM Fault + IntDefaultHandler, // PWM Generator 0 + IntDefaultHandler, // PWM Generator 1 + IntDefaultHandler, // PWM Generator 2 + IntDefaultHandler, // Quadrature Encoder 0 + ADC0SS0Handler, // ADC Sequence 0 + IntDefaultHandler, // ADC Sequence 1 + IntDefaultHandler, // ADC Sequence 2 + IntDefaultHandler, // ADC Sequence 3 + IntDefaultHandler, // Watchdog timer + IntDefaultHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + IntDefaultHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + IntDefaultHandler, // Analog Comparator 0 + IntDefaultHandler, // Analog Comparator 1 + IntDefaultHandler, // Analog Comparator 2 + IntDefaultHandler, // System Control (PLL, OSC, BO) + IntDefaultHandler, // FLASH Control + IntDefaultHandler, // GPIO Port F + IntDefaultHandler, // GPIO Port G + IntDefaultHandler, // GPIO Port H + IntDefaultHandler, // UART2 Rx and Tx + IntDefaultHandler, // SSI1 Rx and Tx + IntDefaultHandler, // Timer 3 subtimer A + IntDefaultHandler, // Timer 3 subtimer B + IntDefaultHandler, // I2C1 Master and Slave + IntDefaultHandler, // Quadrature Encoder 1 + IntDefaultHandler, // CAN0 + IntDefaultHandler, // CAN1 + 0, // Reserved + 0, // Reserved + RTCHandler, // Hibernate + USB0OTGModeIntHandler, // USB0 + IntDefaultHandler, // PWM Generator 3 + IntDefaultHandler, // uDMA Software Transfer + IntDefaultHandler, // uDMA Error + IntDefaultHandler, // ADC1 Sequence 0 + IntDefaultHandler, // ADC1 Sequence 1 + IntDefaultHandler, // ADC1 Sequence 2 + IntDefaultHandler, // ADC1 Sequence 3 + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // GPIO Port J + IntDefaultHandler, // GPIO Port K + IntDefaultHandler, // GPIO Port L + IntDefaultHandler, // SSI2 Rx and Tx + IntDefaultHandler, // SSI3 Rx and Tx + IntDefaultHandler, // UART3 Rx and Tx + IntDefaultHandler, // UART4 Rx and Tx + IntDefaultHandler, // UART5 Rx and Tx + IntDefaultHandler, // UART6 Rx and Tx + IntDefaultHandler, // UART7 Rx and Tx + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // I2C2 Master and Slave + IntDefaultHandler, // I2C3 Master and Slave + IntDefaultHandler, // Timer 4 subtimer A + IntDefaultHandler, // Timer 4 subtimer B + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // Timer 5 subtimer A + IntDefaultHandler, // Timer 5 subtimer B + IntDefaultHandler, // Wide Timer 0 subtimer A + IntDefaultHandler, // Wide Timer 0 subtimer B + IntDefaultHandler, // Wide Timer 1 subtimer A + IntDefaultHandler, // Wide Timer 1 subtimer B + IntDefaultHandler, // Wide Timer 2 subtimer A + IntDefaultHandler, // Wide Timer 2 subtimer B + IntDefaultHandler, // Wide Timer 3 subtimer A + IntDefaultHandler, // Wide Timer 3 subtimer B + IntDefaultHandler, // Wide Timer 4 subtimer A + IntDefaultHandler, // Wide Timer 4 subtimer B + IntDefaultHandler, // Wide Timer 5 subtimer A + IntDefaultHandler, // Wide Timer 5 subtimer B + IntDefaultHandler, // FPU + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // I2C4 Master and Slave + IntDefaultHandler, // I2C5 Master and Slave + IntDefaultHandler, // GPIO Port M + IntDefaultHandler, // GPIO Port N + IntDefaultHandler, // Quadrature Encoder 2 + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // GPIO Port P (Summary or P0) + IntDefaultHandler, // GPIO Port P1 + IntDefaultHandler, // GPIO Port P2 + IntDefaultHandler, // GPIO Port P3 + IntDefaultHandler, // GPIO Port P4 + IntDefaultHandler, // GPIO Port P5 + IntDefaultHandler, // GPIO Port P6 + IntDefaultHandler, // GPIO Port P7 + IntDefaultHandler, // GPIO Port Q (Summary or Q0) + IntDefaultHandler, // GPIO Port Q1 + IntDefaultHandler, // GPIO Port Q2 + IntDefaultHandler, // GPIO Port Q3 + IntDefaultHandler, // GPIO Port Q4 + IntDefaultHandler, // GPIO Port Q5 + IntDefaultHandler, // GPIO Port Q6 + IntDefaultHandler, // GPIO Port Q7 + IntDefaultHandler, // GPIO Port R + IntDefaultHandler, // GPIO Port S + IntDefaultHandler, // PWM 1 Generator 0 + IntDefaultHandler, // PWM 1 Generator 1 + IntDefaultHandler, // PWM 1 Generator 2 + IntDefaultHandler, // PWM 1 Generator 3 + IntDefaultHandler // PWM 1 Fault +}; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +ResetISR(void) +{ + // + // Enable the floating-point unit. This must be done here to handle the + // case where main() uses floating-point and the function prologue saves + // floating-point registers (which will fault if floating-point is not + // enabled). Any configuration of the floating-point unit using DriverLib + // APIs must be done here prior to the floating-point unit being enabled. + // + // Note that this does not use DriverLib since it might not be included in + // this project. + // + HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) & + ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) | + NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL); + + // + // Call the application's entry point. + // + __iar_program_start(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiSR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/boards/ek-lm4f232/qs-logger/startup_gcc.c b/boards/ek-lm4f232/qs-logger/startup_gcc.c new file mode 100644 index 0000000..ca5b4d7 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/startup_gcc.c @@ -0,0 +1,352 @@ +//***************************************************************************** +// +// startup_gcc.c - Startup code for use with GNU tools. +// +// 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 +#include "inc/hw_nvic.h" +#include "inc/hw_types.h" + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); + +//***************************************************************************** +// +// External declarations for the interrupt handlers used by the application. +// +//***************************************************************************** +extern void ADC0SS0Handler(void); +extern void RTCHandler(void); +extern void SysTickIntHandler(void); +extern void USB0OTGModeIntHandler(void); + +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +static uint32_t pui32Stack[256]; + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = +{ + (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)), + // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + IntDefaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // SVCall handler + IntDefaultHandler, // Debug monitor handler + 0, // Reserved + IntDefaultHandler, // The PendSV handler + SysTickIntHandler, // The SysTick handler + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + IntDefaultHandler, // GPIO Port C + IntDefaultHandler, // GPIO Port D + IntDefaultHandler, // GPIO Port E + IntDefaultHandler, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + IntDefaultHandler, // SSI0 Rx and Tx + IntDefaultHandler, // I2C0 Master and Slave + IntDefaultHandler, // PWM Fault + IntDefaultHandler, // PWM Generator 0 + IntDefaultHandler, // PWM Generator 1 + IntDefaultHandler, // PWM Generator 2 + IntDefaultHandler, // Quadrature Encoder 0 + ADC0SS0Handler, // ADC Sequence 0 + IntDefaultHandler, // ADC Sequence 1 + IntDefaultHandler, // ADC Sequence 2 + IntDefaultHandler, // ADC Sequence 3 + IntDefaultHandler, // Watchdog timer + IntDefaultHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + IntDefaultHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + IntDefaultHandler, // Analog Comparator 0 + IntDefaultHandler, // Analog Comparator 1 + IntDefaultHandler, // Analog Comparator 2 + IntDefaultHandler, // System Control (PLL, OSC, BO) + IntDefaultHandler, // FLASH Control + IntDefaultHandler, // GPIO Port F + IntDefaultHandler, // GPIO Port G + IntDefaultHandler, // GPIO Port H + IntDefaultHandler, // UART2 Rx and Tx + IntDefaultHandler, // SSI1 Rx and Tx + IntDefaultHandler, // Timer 3 subtimer A + IntDefaultHandler, // Timer 3 subtimer B + IntDefaultHandler, // I2C1 Master and Slave + IntDefaultHandler, // Quadrature Encoder 1 + IntDefaultHandler, // CAN0 + IntDefaultHandler, // CAN1 + 0, // Reserved + 0, // Reserved + RTCHandler, // Hibernate + USB0OTGModeIntHandler, // USB0 + IntDefaultHandler, // PWM Generator 3 + IntDefaultHandler, // uDMA Software Transfer + IntDefaultHandler, // uDMA Error + IntDefaultHandler, // ADC1 Sequence 0 + IntDefaultHandler, // ADC1 Sequence 1 + IntDefaultHandler, // ADC1 Sequence 2 + IntDefaultHandler, // ADC1 Sequence 3 + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // GPIO Port J + IntDefaultHandler, // GPIO Port K + IntDefaultHandler, // GPIO Port L + IntDefaultHandler, // SSI2 Rx and Tx + IntDefaultHandler, // SSI3 Rx and Tx + IntDefaultHandler, // UART3 Rx and Tx + IntDefaultHandler, // UART4 Rx and Tx + IntDefaultHandler, // UART5 Rx and Tx + IntDefaultHandler, // UART6 Rx and Tx + IntDefaultHandler, // UART7 Rx and Tx + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // I2C2 Master and Slave + IntDefaultHandler, // I2C3 Master and Slave + IntDefaultHandler, // Timer 4 subtimer A + IntDefaultHandler, // Timer 4 subtimer B + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // Timer 5 subtimer A + IntDefaultHandler, // Timer 5 subtimer B + IntDefaultHandler, // Wide Timer 0 subtimer A + IntDefaultHandler, // Wide Timer 0 subtimer B + IntDefaultHandler, // Wide Timer 1 subtimer A + IntDefaultHandler, // Wide Timer 1 subtimer B + IntDefaultHandler, // Wide Timer 2 subtimer A + IntDefaultHandler, // Wide Timer 2 subtimer B + IntDefaultHandler, // Wide Timer 3 subtimer A + IntDefaultHandler, // Wide Timer 3 subtimer B + IntDefaultHandler, // Wide Timer 4 subtimer A + IntDefaultHandler, // Wide Timer 4 subtimer B + IntDefaultHandler, // Wide Timer 5 subtimer A + IntDefaultHandler, // Wide Timer 5 subtimer B + IntDefaultHandler, // FPU + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // I2C4 Master and Slave + IntDefaultHandler, // I2C5 Master and Slave + IntDefaultHandler, // GPIO Port M + IntDefaultHandler, // GPIO Port N + IntDefaultHandler, // Quadrature Encoder 2 + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // GPIO Port P (Summary or P0) + IntDefaultHandler, // GPIO Port P1 + IntDefaultHandler, // GPIO Port P2 + IntDefaultHandler, // GPIO Port P3 + IntDefaultHandler, // GPIO Port P4 + IntDefaultHandler, // GPIO Port P5 + IntDefaultHandler, // GPIO Port P6 + IntDefaultHandler, // GPIO Port P7 + IntDefaultHandler, // GPIO Port Q (Summary or Q0) + IntDefaultHandler, // GPIO Port Q1 + IntDefaultHandler, // GPIO Port Q2 + IntDefaultHandler, // GPIO Port Q3 + IntDefaultHandler, // GPIO Port Q4 + IntDefaultHandler, // GPIO Port Q5 + IntDefaultHandler, // GPIO Port Q6 + IntDefaultHandler, // GPIO Port Q7 + IntDefaultHandler, // GPIO Port R + IntDefaultHandler, // GPIO Port S + IntDefaultHandler, // PWM 1 Generator 0 + IntDefaultHandler, // PWM 1 Generator 1 + IntDefaultHandler, // PWM 1 Generator 2 + IntDefaultHandler, // PWM 1 Generator 3 + IntDefaultHandler // PWM 1 Fault +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern uint32_t _etext; +extern uint32_t _data; +extern uint32_t _edata; +extern uint32_t _bss; +extern uint32_t _ebss; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +ResetISR(void) +{ + uint32_t *pui32Src, *pui32Dest; + + // + // Copy the data segment initializers from flash to SRAM. + // + pui32Src = &_etext; + for(pui32Dest = &_data; pui32Dest < &_edata; ) + { + *pui32Dest++ = *pui32Src++; + } + + // + // Zero fill the bss segment. + // + __asm(" ldr r0, =_bss\n" + " ldr r1, =_ebss\n" + " mov r2, #0\n" + " .thumb_func\n" + "zero_loop:\n" + " cmp r0, r1\n" + " it lt\n" + " strlt r2, [r0], #4\n" + " blt zero_loop"); + + // + // Enable the floating-point unit. This must be done here to handle the + // case where main() uses floating-point and the function prologue saves + // floating-point registers (which will fault if floating-point is not + // enabled). Any configuration of the floating-point unit using DriverLib + // APIs must be done here prior to the floating-point unit being enabled. + // + // Note that this does not use DriverLib since it might not be included in + // this project. + // + HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) & + ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) | + NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL); + + // + // Call the application's entry point. + // + main(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiSR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/boards/ek-lm4f232/qs-logger/startup_rvmdk.S b/boards/ek-lm4f232/qs-logger/startup_rvmdk.S new file mode 100644 index 0000000..25f6000 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/startup_rvmdk.S @@ -0,0 +1,361 @@ +; <<< Use Configuration Wizard in Context Menu >>> +;****************************************************************************** +; +; startup_rvmdk.S - Startup code for use with Keil's uVision. +; +; 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. +; +;****************************************************************************** + +;****************************************************************************** +; +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; +;****************************************************************************** +Stack EQU 0x00000400 + +;****************************************************************************** +; +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; +;****************************************************************************** +Heap EQU 0x00000000 + +;****************************************************************************** +; +; Allocate space for the stack. +; +;****************************************************************************** + AREA STACK, NOINIT, READWRITE, ALIGN=3 +StackMem + SPACE Stack +__initial_sp + +;****************************************************************************** +; +; Allocate space for the heap. +; +;****************************************************************************** + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +HeapMem + SPACE Heap +__heap_limit + +;****************************************************************************** +; +; Indicate that the code in this file preserves 8-byte alignment of the stack. +; +;****************************************************************************** + PRESERVE8 + +;****************************************************************************** +; +; Place code into the reset code section. +; +;****************************************************************************** + AREA RESET, CODE, READONLY + THUMB + +;****************************************************************************** +; +; External declarations for the interrupt handlers used by the application. +; +;****************************************************************************** + EXTERN ADC0SS0Handler + EXTERN RTCHandler + EXTERN SysTickIntHandler + EXTERN USB0OTGModeIntHandler + +;****************************************************************************** +; +; The vector table. +; +;****************************************************************************** + EXPORT __Vectors +__Vectors + DCD StackMem + Stack ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NmiSR ; NMI Handler + DCD FaultISR ; Hard Fault Handler + DCD IntDefaultHandler ; The MPU fault handler + DCD IntDefaultHandler ; The bus fault handler + DCD IntDefaultHandler ; The usage fault handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD IntDefaultHandler ; SVCall handler + DCD IntDefaultHandler ; Debug monitor handler + DCD 0 ; Reserved + DCD IntDefaultHandler ; The PendSV handler + DCD SysTickIntHandler ; The SysTick handler + DCD IntDefaultHandler ; GPIO Port A + DCD IntDefaultHandler ; GPIO Port B + DCD IntDefaultHandler ; GPIO Port C + DCD IntDefaultHandler ; GPIO Port D + DCD IntDefaultHandler ; GPIO Port E + DCD IntDefaultHandler ; UART0 Rx and Tx + DCD IntDefaultHandler ; UART1 Rx and Tx + DCD IntDefaultHandler ; SSI0 Rx and Tx + DCD IntDefaultHandler ; I2C0 Master and Slave + DCD IntDefaultHandler ; PWM Fault + DCD IntDefaultHandler ; PWM Generator 0 + DCD IntDefaultHandler ; PWM Generator 1 + DCD IntDefaultHandler ; PWM Generator 2 + DCD IntDefaultHandler ; Quadrature Encoder 0 + DCD ADC0SS0Handler ; ADC Sequence 0 + DCD IntDefaultHandler ; ADC Sequence 1 + DCD IntDefaultHandler ; ADC Sequence 2 + DCD IntDefaultHandler ; ADC Sequence 3 + DCD IntDefaultHandler ; Watchdog timer + DCD IntDefaultHandler ; Timer 0 subtimer A + DCD IntDefaultHandler ; Timer 0 subtimer B + DCD IntDefaultHandler ; Timer 1 subtimer A + DCD IntDefaultHandler ; Timer 1 subtimer B + DCD IntDefaultHandler ; Timer 2 subtimer A + DCD IntDefaultHandler ; Timer 2 subtimer B + DCD IntDefaultHandler ; Analog Comparator 0 + DCD IntDefaultHandler ; Analog Comparator 1 + DCD IntDefaultHandler ; Analog Comparator 2 + DCD IntDefaultHandler ; System Control (PLL, OSC, BO) + DCD IntDefaultHandler ; FLASH Control + DCD IntDefaultHandler ; GPIO Port F + DCD IntDefaultHandler ; GPIO Port G + DCD IntDefaultHandler ; GPIO Port H + DCD IntDefaultHandler ; UART2 Rx and Tx + DCD IntDefaultHandler ; SSI1 Rx and Tx + DCD IntDefaultHandler ; Timer 3 subtimer A + DCD IntDefaultHandler ; Timer 3 subtimer B + DCD IntDefaultHandler ; I2C1 Master and Slave + DCD IntDefaultHandler ; Quadrature Encoder 1 + DCD IntDefaultHandler ; CAN0 + DCD IntDefaultHandler ; CAN1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD RTCHandler ; Hibernate + DCD USB0OTGModeIntHandler ; USB0 + DCD IntDefaultHandler ; PWM Generator 3 + DCD IntDefaultHandler ; uDMA Software Transfer + DCD IntDefaultHandler ; uDMA Error + DCD IntDefaultHandler ; ADC1 Sequence 0 + DCD IntDefaultHandler ; ADC1 Sequence 1 + DCD IntDefaultHandler ; ADC1 Sequence 2 + DCD IntDefaultHandler ; ADC1 Sequence 3 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD IntDefaultHandler ; GPIO Port J + DCD IntDefaultHandler ; GPIO Port K + DCD IntDefaultHandler ; GPIO Port L + DCD IntDefaultHandler ; SSI2 Rx and Tx + DCD IntDefaultHandler ; SSI3 Rx and Tx + DCD IntDefaultHandler ; UART3 Rx and Tx + DCD IntDefaultHandler ; UART4 Rx and Tx + DCD IntDefaultHandler ; UART5 Rx and Tx + DCD IntDefaultHandler ; UART6 Rx and Tx + DCD IntDefaultHandler ; UART7 Rx and Tx + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD IntDefaultHandler ; I2C2 Master and Slave + DCD IntDefaultHandler ; I2C3 Master and Slave + DCD IntDefaultHandler ; Timer 4 subtimer A + DCD IntDefaultHandler ; Timer 4 subtimer B + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD IntDefaultHandler ; Timer 5 subtimer A + DCD IntDefaultHandler ; Timer 5 subtimer B + DCD IntDefaultHandler ; Wide Timer 0 subtimer A + DCD IntDefaultHandler ; Wide Timer 0 subtimer B + DCD IntDefaultHandler ; Wide Timer 1 subtimer A + DCD IntDefaultHandler ; Wide Timer 1 subtimer B + DCD IntDefaultHandler ; Wide Timer 2 subtimer A + DCD IntDefaultHandler ; Wide Timer 2 subtimer B + DCD IntDefaultHandler ; Wide Timer 3 subtimer A + DCD IntDefaultHandler ; Wide Timer 3 subtimer B + DCD IntDefaultHandler ; Wide Timer 4 subtimer A + DCD IntDefaultHandler ; Wide Timer 4 subtimer B + DCD IntDefaultHandler ; Wide Timer 5 subtimer A + DCD IntDefaultHandler ; Wide Timer 5 subtimer B + DCD IntDefaultHandler ; FPU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD IntDefaultHandler ; I2C4 Master and Slave + DCD IntDefaultHandler ; I2C5 Master and Slave + DCD IntDefaultHandler ; GPIO Port M + DCD IntDefaultHandler ; GPIO Port N + DCD IntDefaultHandler ; Quadrature Encoder 2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD IntDefaultHandler ; GPIO Port P (Summary or P0) + DCD IntDefaultHandler ; GPIO Port P1 + DCD IntDefaultHandler ; GPIO Port P2 + DCD IntDefaultHandler ; GPIO Port P3 + DCD IntDefaultHandler ; GPIO Port P4 + DCD IntDefaultHandler ; GPIO Port P5 + DCD IntDefaultHandler ; GPIO Port P6 + DCD IntDefaultHandler ; GPIO Port P7 + DCD IntDefaultHandler ; GPIO Port Q (Summary or Q0) + DCD IntDefaultHandler ; GPIO Port Q1 + DCD IntDefaultHandler ; GPIO Port Q2 + DCD IntDefaultHandler ; GPIO Port Q3 + DCD IntDefaultHandler ; GPIO Port Q4 + DCD IntDefaultHandler ; GPIO Port Q5 + DCD IntDefaultHandler ; GPIO Port Q6 + DCD IntDefaultHandler ; GPIO Port Q7 + DCD IntDefaultHandler ; GPIO Port R + DCD IntDefaultHandler ; GPIO Port S + DCD IntDefaultHandler ; PWM 1 Generator 0 + DCD IntDefaultHandler ; PWM 1 Generator 1 + DCD IntDefaultHandler ; PWM 1 Generator 2 + DCD IntDefaultHandler ; PWM 1 Generator 3 + DCD IntDefaultHandler ; PWM 1 Fault + +;****************************************************************************** +; +; This is the code that gets called when the processor first starts execution +; following a reset event. +; +;****************************************************************************** + EXPORT Reset_Handler +Reset_Handler + ; + ; Enable the floating-point unit. This must be done here to handle the + ; case where main() uses floating-point and the function prologue saves + ; floating-point registers (which will fault if floating-point is not + ; enabled). Any configuration of the floating-point unit using + ; DriverLib APIs must be done here prior to the floating-point unit + ; being enabled. + ; + ; Note that this does not use DriverLib since it might not be included + ; in this project. + ; + MOVW R0, #0xED88 + MOVT R0, #0xE000 + LDR R1, [R0] + ORR R1, #0x00F00000 + STR R1, [R0] + + ; + ; Call the C library enty point that handles startup. This will copy + ; the .data section initializers from flash to SRAM and zero fill the + ; .bss section. + ; + IMPORT __main + B __main + +;****************************************************************************** +; +; This is the code that gets called when the processor receives a NMI. This +; simply enters an infinite loop, preserving the system state for examination +; by a debugger. +; +;****************************************************************************** +NmiSR + B NmiSR + +;****************************************************************************** +; +; This is the code that gets called when the processor receives a fault +; interrupt. This simply enters an infinite loop, preserving the system state +; for examination by a debugger. +; +;****************************************************************************** +FaultISR + B FaultISR + +;****************************************************************************** +; +; This is the code that gets called when the processor receives an unexpected +; interrupt. This simply enters an infinite loop, preserving the system state +; for examination by a debugger. +; +;****************************************************************************** +IntDefaultHandler + B IntDefaultHandler + +;****************************************************************************** +; +; Make sure the end of this section is aligned. +; +;****************************************************************************** + ALIGN + +;****************************************************************************** +; +; Some code in the normal code section for initializing the heap and stack. +; +;****************************************************************************** + AREA |.text|, CODE, READONLY + +;****************************************************************************** +; +; The function expected of the C library startup code for defining the stack +; and heap memory locations. For the C library version of the startup code, +; provide this function so that the C library initialization code can find out +; the location of the stack and heap. +; +;****************************************************************************** + IF :DEF: __MICROLIB + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + ELSE + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap + LDR R0, =HeapMem + LDR R1, =(StackMem + Stack) + LDR R2, =(HeapMem + Heap) + LDR R3, =StackMem + BX LR + ENDIF + +;****************************************************************************** +; +; Make sure the end of this section is aligned. +; +;****************************************************************************** + ALIGN + +;****************************************************************************** +; +; Tell the assembler that we're done. +; +;****************************************************************************** + END diff --git a/boards/ek-lm4f232/qs-logger/stripchartmanager.c b/boards/ek-lm4f232/qs-logger/stripchartmanager.c new file mode 100644 index 0000000..bab6d94 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/stripchartmanager.c @@ -0,0 +1,445 @@ +//***************************************************************************** +// +// stripchartmanager.c - Manages a strip chart widget for the data logger. +// +// 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 +#include +#include +#include "inc/hw_types.h" +#include "grlib/grlib.h" +#include "grlib/widget.h" +#include "grlib/canvas.h" +#include "drivers/cfal96x64x16.h" +#include "drivers/slidemenuwidget.h" +#include "drivers/stripchartwidget.h" +#include "stripchartmanager.h" +#include "clocksetwidget.h" +#include "qs-logger.h" +#include "menus.h" +#include "utils/ustdlib.h" + +//***************************************************************************** +// +// This module manages a strip chart widget for the data logger application. +// It provides functions to make it easy to configure a strip chart for the +// user-selected data series, and to add new data to the strip chart. The +// functions in this module maintain buffers that hold the data for each data +// series that is selected for display on the strip chart. +// +//***************************************************************************** + +//***************************************************************************** +// +// Define a scaling range for each data series. Since multiple kinds of data +// will be shown on the strip chart, no one particular set of units can be +// selected. Instead the strip chart Y axis will just be maintained in units +// of pixels, and the table below maps the Y axis range to min and max values +// for each data series. +// +//***************************************************************************** +typedef struct +{ + int16_t i16Min; + int16_t i16Max; +} tDisplayScaling; + +tDisplayScaling g_psScaling[] = +{ + { 0, 20000 }, // analog channel inputs, + { 0, 20000 }, // 0-20V (20000 mV) + { 0, 20000 }, + { 0, 20000 }, + { -200, 200 }, // accelerometer axes, -2 - 2g + { -200, 200 }, // (units of 1/100g) + { -200, 200 }, + { 0, 500 }, // temperature, 0 - 50C (units of + { 0, 500 }, // 1/10C) + { 0, 400 }, // current, 0 - 40mA (units of + // 100uA) +}; + +//***************************************************************************** +// +// Defines the maximum number of items that are stored in a data series. This +// matches the width of the strip chart in pixels. +// +//***************************************************************************** +#define SERIES_LENGTH 96 + +//***************************************************************************** +// +// Create an array of strip chart data series, one for each channel of data +// that the data logger can acquire. Fields that are unchanging, such as +// the name of each series, are pre-populated here, while other fields that +// may change are updated by functions. These are the data series that get +// added to the strip chart for each item that is selected for logging. +// +//***************************************************************************** +static tStripChartSeries g_psSeries[] = +{ + { 0, "CH0", 0x000040, 1, 1, 0, 0 }, + { 0, "CH1", ClrLime, 1, 1, 0, 0 }, + { 0, "CH2", ClrAqua, 1, 1, 0, 0 }, + { 0, "CH3", ClrRed, 1, 1, 0, 0 }, + { 0, "ACCELX", ClrBlue, 1, 1, 0, 0 }, + { 0, "ACCELY", 0x00A000, 1, 1, 0, 0 }, + { 0, "ACCELZ", ClrFuchsia, 1, 1, 0, 0 }, + { 0, "CURRENT", ClrYellow, 1, 1, 0, 0 }, + { 0, "EXT TEMP", 0xC00040, 1, 1, 0, 0 }, + { 0, "INT TEMP", 0x60E080, 1, 1, 0, 0 }, +}; +#define MAX_NUM_SERIES (sizeof(g_psSeries) / \ + sizeof(tStripChartSeries)) + +//***************************************************************************** +// +// Defines the X-axis for the strip chart. +// +//***************************************************************************** +static tStripChartAxis g_sAxisX = +{ + "X-AXIS", // title of axis + 0, // label for minimum of axis + 0, // label for maximum of axis + 0, // minimum value for the axis + 95, // maximum value for the axis + 10 // grid interval for the axis +}; + +//***************************************************************************** +// +// Defines the Y-axis for the strip chart. +// +//***************************************************************************** +static tStripChartAxis g_sAxisY = +{ + 0, // title of the axis + 0, // label for minimum of axis + 0, // label for maximum of axis + 0, // minimum value for the axis + 63, // maximum value for the axis + 16 // grid interval for the axis +}; + +//***************************************************************************** +// +// Defines the strip chart widget. This structure must be fully initialized +// by calling the function StripChartMgrInit(). +// +//***************************************************************************** +StripChart(g_sStripChart, 0, 0, 0, 0, 0, 0, 96, 64, 0, g_psFontFixed6x8, + ClrBlack, ClrWhite, ClrWhite, ClrDarkGreen, &g_sAxisX, + &g_sAxisY, 0); + +//***************************************************************************** +// +// Creates a buffer space for the values in the data series. The buffer +// must be large enough to hold all of the data for the maximum possible +// number of data items that are selected. If less than the maximum number +// are selected then some of the buffer space will be unused. +// +//***************************************************************************** +static uint8_t g_pui8SeriesData[MAX_NUM_SERIES * SERIES_LENGTH]; + +//***************************************************************************** +// +// The count of data series that are selected for showing on the strip chart. +// This value is set when the client calls the function StripChartConfigure(). +// +//***************************************************************************** +static uint32_t g_ui32SelectedCount; + +//***************************************************************************** +// +// The number of items (per series) that have been added to the strip chart. +// +//***************************************************************************** +static uint32_t g_ui32ItemCount; + +//***************************************************************************** +// +// A bit mask of the specific data items that have been selected for logging. +// +//***************************************************************************** +static uint32_t g_ui32SelectedMask; + +//***************************************************************************** +// +// Configure the strip chart for a selected set of data series. The selected +// series is passed in as a bit mask. Each bit that is set in the bit mask +// represents a selected series. This function will go through the possible +// set of data series and for each that is selected it will be initialized +// and added to the strip chart. +// +//***************************************************************************** +void +StripChartMgrConfigure(uint32_t ui32SelectedMask) +{ + uint32_t ui32Idx, ui32ItemIdx; + tStripChartSeries *psSeries; + + // + // Save the channel mask for later use + // + g_ui32SelectedMask = ui32SelectedMask; + + // + // Determine how many series are to appear in the strip chart. + // + g_ui32SelectedCount = 0; + ui32Idx = ui32SelectedMask; + while(ui32Idx) + { + if(ui32Idx & 1) + { + g_ui32SelectedCount++; + } + ui32Idx >>= 1; + } + + // + // Reset the number of items that have been stored in the series buffers. + // + g_ui32ItemCount = 0; + + // + // Remove any series that were already added to the strip chart. + // + g_sStripChart.psSeries = 0; + + // + // Loop through all series, and configure the selected series and add + // them to the strip chart. + // + ui32ItemIdx = 0; + for(ui32Idx = 0; ui32Idx < MAX_NUM_SERIES; ui32Idx++) + { + // + // Check to see if this series is selected + // + if((1 << ui32Idx) & ui32SelectedMask) + { + // + // Get a pointer to this series. + // + psSeries = &g_psSeries[ui32Idx]; + + // + // Set the stride for this series. It will be the same as the + // number of enabled data items. + // + psSeries->ui8Stride = g_ui32SelectedCount; + + // + // Set the series data pointer to start at the first location + // in the series buffer where this data item will appear. + // + psSeries->pvData = &g_pui8SeriesData[ui32ItemIdx]; + + // + // Add the series to the strip chart. + // + StripChartSeriesAdd(&g_sStripChart, psSeries); + + // + // Increment the index of selected series. + // + ui32ItemIdx++; + } + } +} + +//***************************************************************************** +// +// Scales the input data value to a Y pixel range according to the scaling +// table at the top of this file. +// +//***************************************************************************** +static uint8_t +ScaleDataToPixelY(int16_t i16Data, int16_t i16Min, int16_t i16Max) +{ + int32_t i32Y; + int16_t i16Range; + + // + // Adjust the input value so that the min will be the bottom of display. + // + i16Data -= i16Min; + + // + // Compute the range of the input that will appear on the display + // + i16Range = i16Max - i16Min; + + // + // Scale the input to the Y pixel range of the display + // + i32Y = (int32_t)i16Data * 63L; + + // + // Add in half of divisor to get proper rounding + // + i32Y += (int32_t)i16Range / 2L; + + // + // Apply final divisor to get Y pixel value on display + // + i32Y /= (int32_t)i16Range; + + // + // If the Y coordinate is out of the range of the display, force the + // value to be just off the display, in order to avoid aliasing to a + // bogus Y pixel value when the return value is converted to a smaller + // data type. + // + if((i32Y < 0) || (i32Y > 63)) + { + i32Y = 64; + } + + // + // Return the Y pixel value + // + return((uint8_t)i32Y); +} + +//***************************************************************************** +// +// Add data items to the strip chart and advance the strip chart position. +// This function will add the items pointed to by the parameter to the data +// series buffer and the strip chart will be updated to reflect the newly +// added data items. +// This function will assume that the number of items passed by the pointer +// is the same as was selected by the function StripChartMgrConfigure(). +// up to the caller to ensure that the amount of data passed matches the +// number of items that were selected when the strip chart was configured. +// +//***************************************************************************** +void +StripChartMgrAddItems(int16_t *pi16DataItems) +{ + uint32_t ui32Idx, ui32SelectedMask = g_ui32SelectedMask; + uint8_t *pui8NewData; + + // + // Check for valid input data pointer + // + if(!pi16DataItems) + { + return; + } + + // + // If the number count of items in the strip chart is at the maximum, then + // the items need to "slide down" and new data added to the end of the + // buffer. + // + if(g_ui32ItemCount == SERIES_LENGTH) + { + memmove(&g_pui8SeriesData[0], &g_pui8SeriesData[g_ui32SelectedCount], + SERIES_LENGTH * g_ui32SelectedCount); + + // + // Set the pointer for newly added data to be the end of the series + // buffer. + // + pui8NewData = &g_pui8SeriesData[(SERIES_LENGTH - 1) * + g_ui32SelectedCount]; + } + else + { + + // + // Otherwise, the series data buffer is less than full so compute the + // correct location in the buffer for the new data to be added. + // + pui8NewData = &g_pui8SeriesData[g_ui32ItemCount * + g_ui32SelectedCount]; + + // + // Increment the number of items that have been added to the strip + // chart series data buffer. + // + g_ui32ItemCount++; + + // + // Since the count of data items has changed, it must be updated for + // each series. + // + for(ui32Idx = 0; ui32Idx < MAX_NUM_SERIES; ui32Idx++) + { + g_psSeries[ui32Idx].ui16NumItems = g_ui32ItemCount; + } + } + + // + // Convert each of the input data items being added to the strip chart + // to a scaled Y pixel value. + // + ui32Idx = 0; + while(ui32SelectedMask) + { + // + // Is this data item being added to the chart? + // + if(ui32SelectedMask & 1) + { + // + // Scale the data item and add it to the series buffer + // + *pui8NewData = ScaleDataToPixelY(*pi16DataItems, + g_psScaling[ui32Idx].i16Min, + g_psScaling[ui32Idx].i16Max); + + // + // Increment the from/to pointers + // + pui8NewData++; + pi16DataItems++; + } + ui32Idx++; + ui32SelectedMask >>= 1; + } + + // + // Now that data has been added to the strip chart series buffers, either + // at the end or in the middle, advance the strip chart position by 1. + // Add a request for painting the strip chart widget. + // + StripChartAdvance(&g_sStripChart, 1); + WidgetPaint(WIDGET_ROOT); +} + +//***************************************************************************** +// +// Initializes the strip chart manager. The strip chart needs an on-screen +// and off-screen display for drawing. These are passed using the init +// function. +// +//***************************************************************************** +void +StripChartMgrInit(void) +{ + g_sStripChart.sBase.psDisplay = &g_sCFAL96x64x16; + g_sStripChart.psOffscreenDisplay = &g_sOffscreenDisplayA; +} diff --git a/boards/ek-lm4f232/qs-logger/stripchartmanager.h b/boards/ek-lm4f232/qs-logger/stripchartmanager.h new file mode 100644 index 0000000..11a1c16 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/stripchartmanager.h @@ -0,0 +1,63 @@ +//***************************************************************************** +// +// stripchartmanager.h - Header for data logger strip chart manager. +// +// 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. +// +//***************************************************************************** +#ifndef __STRIPCHARTMANAGER_H__ +#define __STRIPCHARTMANAGER_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Public data. +// +//***************************************************************************** +extern tStripChartWidget g_sStripChart; + +//***************************************************************************** +// +// Function prototypes. +// +//***************************************************************************** +extern void StripChartMgrConfigure(uint32_t ui32SelectedMask); +extern void StripChartMgrAddItems(int16_t *pi16DataItems); +extern void StripChartMgrInit(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __STRIPCHARTMANAGER_H__ diff --git a/boards/ek-lm4f232/qs-logger/usb_serial_structs.c b/boards/ek-lm4f232/qs-logger/usb_serial_structs.c new file mode 100644 index 0000000..f899ce1 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/usb_serial_structs.c @@ -0,0 +1,217 @@ +//***************************************************************************** +// +// usb_serial_structs.c - Data structures defining this CDC USB device. +// +// 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 +#include +#include "inc/hw_types.h" +#include "driverlib/usb.h" +#include "usblib/usblib.h" +#include "usblib/usbcdc.h" +#include "usblib/usb-ids.h" +#include "usblib/device/usbdevice.h" +#include "usblib/device/usbdcdc.h" +#include "usb_serial_structs.h" + +//***************************************************************************** +// +// The languages supported by this device. +// +//***************************************************************************** +const uint8_t g_pui8LangDescriptor[] = +{ + 4, + USB_DTYPE_STRING, + USBShort(USB_LANG_EN_US) +}; + +//***************************************************************************** +// +// The manufacturer string. +// +//***************************************************************************** +const uint8_t g_pui8ManufacturerString[] = +{ + (17 + 1) * 2, + USB_DTYPE_STRING, + 'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0, + 't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0, +}; + +//***************************************************************************** +// +// The product string. +// +//***************************************************************************** +const uint8_t g_pui8ProductString[] = +{ + 2 + (30 * 2), + USB_DTYPE_STRING, + 'S', 0, 't', 0, 'e', 0, 'l', 0, 'l', 0, 'a', 0, 'r', 0, 'i', 0, + 's', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0, 'a', 0, ' ', 0, 'L', 0, + 'o', 0, 'g', 0, 'g', 0, 'e', 0, 'r', 0, ' ', 0, 'C', 0, 'O', 0, + 'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0 +}; + +//***************************************************************************** +// +// The serial number string. +// +//***************************************************************************** +const uint8_t g_pui8SerialNumberString[] = +{ + 2 + (8 * 2), + USB_DTYPE_STRING, + '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0 +}; + +//***************************************************************************** +// +// The control interface description string. +// +//***************************************************************************** +const uint8_t g_pui8ControlInterfaceString[] = +{ + 2 + (21 * 2), + USB_DTYPE_STRING, + 'A', 0, 'C', 0, 'M', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0, + 'r', 0, 'o', 0, 'l', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, + 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0 +}; + +//***************************************************************************** +// +// The configuration description string. +// +//***************************************************************************** +const uint8_t g_pui8ConfigString[] = +{ + 2 + (26 * 2), + USB_DTYPE_STRING, + 'S', 0, 'e', 0, 'l', 0, 'f', 0, ' ', 0, 'P', 0, 'o', 0, 'w', 0, + 'e', 0, 'r', 0, 'e', 0, 'd', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, + 'f', 0, 'i', 0, 'g', 0, 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0, + 'o', 0, 'n', 0 +}; + +//***************************************************************************** +// +// The descriptor string table. +// +//***************************************************************************** +const uint8_t * const g_pui8StringDescriptors[] = +{ + g_pui8LangDescriptor, + g_pui8ManufacturerString, + g_pui8ProductString, + g_pui8SerialNumberString, + g_pui8ControlInterfaceString, + g_pui8ConfigString +}; + +#define NUM_STRING_DESCRIPTORS (sizeof(g_pui8StringDescriptors) / \ + sizeof(uint8_t *)) + +//***************************************************************************** +// +// CDC device callback function prototypes. +// +//***************************************************************************** +uint32_t RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, + void *pvMsgData); +uint32_t TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, + void *pvMsgData); +uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event, + uint32_t ui32MsgValue, void *pvMsgData); + +//***************************************************************************** +// +// The CDC device initialization and customization structures. In this case, +// we are using USBBuffers between the CDC device class driver and the +// application code. The function pointers and callback data values are set +// to insert a buffer in each of the data channels, transmit and receive. +// +// With the buffer in place, the CDC channel callback is set to the relevant +// channel function and the callback data is set to point to the channel +// instance data. The buffer, in turn, has its callback set to the application +// function and the callback data set to our CDC instance structure. +// +//***************************************************************************** +extern const tUSBBuffer g_sTxBuffer; +extern const tUSBBuffer g_sRxBuffer; + +tUSBDCDCDevice g_sCDCDevice = +{ + USB_VID_TI_1CBE, + USB_PID_DATA_LOGGER, + 0, + USB_CONF_ATTR_SELF_PWR, + ControlHandler, + (void *)&g_sCDCDevice, + USBBufferEventCallback, + (void *)&g_sRxBuffer, + USBBufferEventCallback, + (void *)&g_sTxBuffer, + g_pui8StringDescriptors, + NUM_STRING_DESCRIPTORS +}; + +//***************************************************************************** +// +// Receive buffer (from the USB perspective). +// +//***************************************************************************** +uint8_t g_pui8USBRxBuffer[UART_BUFFER_SIZE]; +uint8_t g_pui8RxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE]; +const tUSBBuffer g_sRxBuffer = +{ + false, // This is a receive buffer. + RxHandler, // pfnCallback + (void *)&g_sCDCDevice, // Callback data is our device ptr. + USBDCDCPacketRead, // pfnTransfer + USBDCDCRxPacketAvailable, // pfnAvailable + (void *)&g_sCDCDevice, // pvHandle + g_pui8USBRxBuffer, // pui8Buffer + UART_BUFFER_SIZE, // ui32BufferSize + g_pui8RxBufferWorkspace // pvWorkspace +}; + +//***************************************************************************** +// +// Transmit buffer (from the USB perspective). +// +//***************************************************************************** +uint8_t g_pui8USBTxBuffer[UART_BUFFER_SIZE]; +uint8_t g_pui8TxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE]; +const tUSBBuffer g_sTxBuffer = +{ + true, // This is a transmit buffer. + TxHandler, // pfnCallback + (void *)&g_sCDCDevice, // Callback data is our device ptr. + USBDCDCPacketWrite, // pfnTransfer + USBDCDCTxPacketAvailable, // pfnAvailable + (void *)&g_sCDCDevice, // pvHandle + g_pui8USBTxBuffer, // pi8Buffer + UART_BUFFER_SIZE, // ui32BufferSize + g_pui8TxBufferWorkspace // pvWorkspace +}; diff --git a/boards/ek-lm4f232/qs-logger/usb_serial_structs.h b/boards/ek-lm4f232/qs-logger/usb_serial_structs.h new file mode 100644 index 0000000..6960a45 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/usb_serial_structs.h @@ -0,0 +1,49 @@ +//***************************************************************************** +// +// usb_serial_structs.h - Data structures defining this USB CDC device. +// +// 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. +// +//***************************************************************************** + +#ifndef _USB_SERIAL_STRUCTS_H_ +#define _USB_SERIAL_STRUCTS_H_ + +//***************************************************************************** +// +// The size of the transmit and receive buffers used for the redirected UART. +// This number should be a power of 2 for best performance. 256 is chosen +// pretty much at random though the buffer should be at least twice the size of +// a maxmum-sized USB packet. +// +//***************************************************************************** +#define UART_BUFFER_SIZE 256 + +extern uint32_t RxHandler(void *pvCBData, uint32_t ui32Event, + uint32_t ui32MsgValue, void *pvMsgData); +extern uint32_t TxHandler(void *pvCBData, uint32_t ui32Event, + uint32_t ui32MsgValue, void *pvMsgData); + +extern const tUSBBuffer g_sTxBuffer; +extern const tUSBBuffer g_sRxBuffer; +extern tUSBDCDCDevice g_sCDCDevice; +extern uint8_t g_pui8USBTxBuffer[]; +extern uint8_t g_pui8USBRxBuffer[]; + +#endif diff --git a/boards/ek-lm4f232/qs-logger/usbserial.c b/boards/ek-lm4f232/qs-logger/usbserial.c new file mode 100644 index 0000000..9125626 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/usbserial.c @@ -0,0 +1,459 @@ +//***************************************************************************** +// +// usbserial.c - Data logger module to handle serial device functions. +// +// 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 +#include +#include +#include "driverlib/debug.h" +#include "usblib/usblib.h" +#include "usblib/usbcdc.h" +#include "usblib/device/usbdevice.h" +#include "usblib/device/usbdcdc.h" +#include "usb_serial_structs.h" +#include "qs-logger.h" + +//***************************************************************************** +// +// This module manages the USB serial device function. It is used when the +// eval board is connected to a host PC as a serial device, and can transmit +// data log records to the host PC through a virtual serial port. +// +//***************************************************************************** + +//***************************************************************************** +// +// Global flag indicating that a USB device configuration is made. +// +//***************************************************************************** +static volatile bool g_bUSBDevConnected = false; + +//***************************************************************************** +// +// The line coding parameters for the virtual serial port. Since there is +// no physical port this does not have any real effect, but we have a default +// set of values to report if asked, and will remember whatever the host +// configures. +// +//***************************************************************************** +static tLineCoding g_sLineCoding = +{ + 115200, USB_CDC_STOP_BITS_1, USB_CDC_PARITY_NONE, 8 +}; + +//***************************************************************************** +// +// Set the communication parameters for the virtual serial port. +// +//***************************************************************************** +static bool +SetLineCoding(tLineCoding *psLineCoding) +{ + // + // Copy whatever the host passes into our copy of line parameters. + // + memcpy(&g_sLineCoding, psLineCoding, sizeof(tLineCoding)); + + // + // ALways return success + // + return(true); +} + +//***************************************************************************** +// +// Get the communication parameters in use on the UART. +// +//***************************************************************************** +static void +GetLineCoding(tLineCoding *psLineCoding) +{ + // + // Copy whatever we have stored as the line parameter to the host. + // + memcpy(psLineCoding, &g_sLineCoding, sizeof(tLineCoding)); +} + +//***************************************************************************** +// +// Handles CDC driver notifications related to control and setup of the device. +// +// \param pvCBData is the client-supplied callback pointer for this channel. +// \param ui32Event identifies the event we are being notified about. +// \param ui32MsgValue is an event-specific value. +// \param pvMsgData is an event-specific pointer. +// +// This function is called by the CDC driver to perform control-related +// operations on behalf of the USB host. These functions include setting +// and querying the serial communication parameters, setting handshake line +// states and sending break conditions. +// +// \return The return value is event-specific. +// +//***************************************************************************** +uint32_t +ControlHandler(void *pvCBData, uint32_t ui32Event, + uint32_t ui32MsgValue, void *pvMsgData) +{ + // + // Which event are we being asked to process? + // + switch(ui32Event) + { + // + // We are connected to a host and communication is now possible. + // + case USB_EVENT_CONNECTED: + { + g_bUSBDevConnected = true; + + // + // Flush our buffers. + // + USBBufferFlush(&g_sTxBuffer); + USBBufferFlush(&g_sRxBuffer); + break; + } + + // + // The host has disconnected. + // + case USB_EVENT_DISCONNECTED: + { + g_bUSBDevConnected = false; + break; + } + + // + // Return the current serial communication parameters. + // + case USBD_CDC_EVENT_GET_LINE_CODING: + { + GetLineCoding(pvMsgData); + break; + } + + // + // Set the current serial communication parameters. + // + case USBD_CDC_EVENT_SET_LINE_CODING: + { + SetLineCoding(pvMsgData); + break; + } + + // + // The following line control events can be ignored because there is + // no physical serial port to manage. + // + case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: + case USBD_CDC_EVENT_SEND_BREAK: + case USBD_CDC_EVENT_CLEAR_BREAK: + { + break; + } + + // + // Ignore SUSPEND and RESUME for now. + // + case USB_EVENT_SUSPEND: + case USB_EVENT_RESUME: + { + break; + } + + // + // An unknown event occurred. + // + default: + { + break; + } + } + + // + // Return control to USB stack + // + return(0); +} + +//***************************************************************************** +// +// Handles CDC driver notifications related to the transmit channel (data to +// the USB host). +// +// \param ui32CBData is the client-supplied callback pointer for this channel. +// \param ui32Event identifies the event we are being notified about. +// \param ui32MsgValue is an event-specific value. +// \param pvMsgData is an event-specific pointer. +// +// This function is called by the CDC driver to notify us of any events +// related to operation of the transmit data channel (the IN channel carrying +// data to the USB host). +// +// \return The return value is event-specific. +// +//***************************************************************************** +uint32_t +TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, + void *pvMsgData) +{ + // + // Which event have we been sent? + // + switch(ui32Event) + { + case USB_EVENT_TX_COMPLETE: + { + // + // Since we are using the USBBuffer, we don't need to do anything + // here. + // + break; + } + + // + // We don't expect to receive any other events. + // + default: + { + break; + } + } + return(0); +} + +//***************************************************************************** +// +// Handles CDC driver notifications related to the receive channel (data from +// the USB host). +// +// \param ui32CBData is the client-supplied callback data value for this +// channel. +// \param ui32Event identifies the event we are being notified about. +// \param ui32MsgValue is an event-specific value. +// \param pvMsgData is an event-specific pointer. +// +// This function is called by the CDC driver to notify us of any events +// related to operation of the receive data channel (the OUT channel carrying +// data from the USB host). +// +// \return The return value is event-specific. +// +//***************************************************************************** +uint32_t +RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, + void *pvMsgData) +{ + // + // Which event are we being sent? + // + switch(ui32Event) + { + // + // A new packet has been received. + // + case USB_EVENT_RX_AVAILABLE: + { + // + // We do not ever expect to receive serial data, so just flush + // the RX buffer if any data actually comes in. + // + USBBufferFlush(&g_sRxBuffer); + break; + } + + // + // We are being asked how much unprocessed data we have still to + // process. Since there is no actual serial port and we are not + // processing any RX data, just return 0. + // + case USB_EVENT_DATA_REMAINING: + { + return(0); + } + + // + // We are being asked to provide a buffer into which the next packet + // can be read. We do not support this mode of receiving data so let + // the driver know by returning 0. The CDC driver should not be sending + // this message but this is included just for illustration and + // completeness. + // + case USB_EVENT_REQUEST_BUFFER: + { + return(0); + } + + // + // We don't expect to receive any other events. + // + default: + { + break; + } + } + return(0); +} + +//***************************************************************************** +// +// Initializes the USB serial device. +// +//***************************************************************************** +void +USBSerialInit(void) +{ + // + // Initialize the transmit and receive buffers. + // + USBBufferInit((tUSBBuffer *)&g_sTxBuffer); + USBBufferInit((tUSBBuffer *)&g_sRxBuffer); + + // + // Initialize the USB library CDC device function. + // + USBDCDCInit(0, (tUSBDCDCDevice *)&g_sCDCDevice); +} + +//***************************************************************************** +// +// This is called by the application main loop to perform regular processing. +// This is just a stub here because everything is event or interrupt driven. +// +//***************************************************************************** +void +USBSerialRun(void) +{ +} + +//***************************************************************************** +// +// Write a data record to the serial port. An acquired data record is passed +// in and is composed into a binary packet and sent on the serial port. The +// host PC, if connected will receive this packet via the virtual serial port, +// and can decode and display the data. +// +// The binary packet has the following format: +// - 16-bit header, value 0x5351 +// - 32-bit seconds time stamp +// - 16-bit fractional seconds time stamp (1/32768 resolution) +// - 16-bit data item selection mask (which items are included in the record) +// - multiple 16-bit data item values, per selection mask +// - 16-bit checksum which when added to the 16-bit sum of the entire packet +// will result in 0. +// +// The entire packet is transmitted bytewise over the virtual serial port, +// little-endian format. +// +//***************************************************************************** +int32_t +USBSerialWriteRecord(tLogRecord *psRecord) +{ + uint32_t ui32Idx; + uint16_t ui16Checksum; + uint32_t ui32ItemCount; + uint16_t *pui16Buf; + + // + // Check the arguments + // + ASSERT(psRecord); + if(!psRecord) + { + return(1); + } + + // + // Check state for ready device + // + if(!g_bUSBDevConnected) + { + return(1); + } + + // + // Determine how many channels are to be logged + // + ui32Idx = psRecord->ui16ItemMask; + ui32ItemCount = 0; + while(ui32Idx) + { + if(ui32Idx & 1) + { + ui32ItemCount++; + } + ui32Idx >>= 1; + } + + // + // Add to item count the equivalent number of 16-bit words for timestamp + // and selection mask. + // + ui32ItemCount += 4; + + // + // Put the header word in the USB buffer + // + ui16Checksum = 0x5351; + USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (uint8_t *)&ui16Checksum, 2); + + // + // Compute the checksum over the entire record + // + pui16Buf = (uint16_t *)psRecord; + for(ui32Idx = 0; ui32Idx < ui32ItemCount; ui32Idx++) + { + ui16Checksum += pui16Buf[ui32Idx]; + } + + // + // Convert item count to bytes. This now represents the entire record + // size in bytes, not including the checksum. The header has already + // been sent + // + ui32ItemCount *= 2; + + // + // Transmit the record, which includes the time stamp, selection mask + // and all selected data item, to the USB buffer + // + USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (uint8_t *)pui16Buf, + ui32ItemCount); + + // + // Adjust the checksum so that when added (as uint16_t) to the sum of the + // rest of the packet, the result will be 0 + // + ui16Checksum = (uint16_t)(0x10000L - (uint32_t)ui16Checksum); + + // + // Transmit the checksum which is the end of the packet + // + USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (uint8_t *)&ui16Checksum, 2); + + // + // Return success to the caller + // + return(0); +} diff --git a/boards/ek-lm4f232/qs-logger/usbserial.h b/boards/ek-lm4f232/qs-logger/usbserial.h new file mode 100644 index 0000000..8db33e4 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/usbserial.h @@ -0,0 +1,56 @@ +//***************************************************************************** +// +// usbserial.h - Prototypes and definitions for USB serial module. +// +// 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. +// +//***************************************************************************** +#ifndef __USBSERIAL_H__ +#define __USBSERIAL_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Module function prototypes. +// +//***************************************************************************** +extern void USBSerialInit(void); +extern void USBSerialRun(void); +extern int USBSerialWriteRecord(tLogRecord *psRecord); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __USBSERIAL_H__ diff --git a/boards/ek-lm4f232/qs-logger/usbstick.c b/boards/ek-lm4f232/qs-logger/usbstick.c new file mode 100644 index 0000000..c0c4427 --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/usbstick.c @@ -0,0 +1,814 @@ +//***************************************************************************** +// +// usbstick.c - Data logger module to handle USB mass storage. +// +// 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 +#include +#include +#include "driverlib/debug.h" +#include "driverlib/rom_map.h" +#include "driverlib/sysctl.h" +#include "driverlib/udma.h" +#include "usblib/usblib.h" +#include "usblib/usbmsc.h" +#include "usblib/host/usbhost.h" +#include "usblib/host/usbhmsc.h" +#include "utils/ustdlib.h" +#include "third_party/fatfs/src/ff.h" +#include "qs-logger.h" +#include "usbstick.h" + +//***************************************************************************** +// +// This module manages the USB host mass storage function. It is used when +// there is a USB memory stick attached to the evaluation board. It manages +// the USB connection and stores data log records to the attached mass +// storage device. +// +//***************************************************************************** + +//***************************************************************************** +// +// A line of text that is written to the start of a CSV file, to provide +// column headings. +// +//***************************************************************************** +static const char g_pcCSVHeaderLine[] = + "Time(s),Frac. seconds," \ + "CH0(mV),CH1(mV),CH2(mV),CH3(mV)," \ + "AccelX(.01g),AccelY(.01g),AccelZ(.01g)," \ + "Ext. Temp(.1C),Int. Temp(.1C),Current(100uA)\r\n"; + +//***************************************************************************** +// +// The following are data structures used by FatFs. +// +//***************************************************************************** +static FATFS g_sFatFs; +static FIL g_sFileObject; + +//***************************************************************************** +// +// Holds global flags for the system. +// +//***************************************************************************** +static volatile uint32_t g_ui32Flags = 0; + +//***************************************************************************** +// +// Flag indicating that some USB device is connected. +// +//***************************************************************************** +#define FLAGS_DEVICE_PRESENT 0x00000001 +#define FLAGS_FILE_OPENED 0x00000002 + +//***************************************************************************** +// +// Hold the current state for the application. +// +//***************************************************************************** +volatile enum +{ + // + // No device is present. + // + eSTATE_NO_DEVICE, + + // + // Mass storage device is being enumerated. + // + eSTATE_DEVICE_ENUM, + + // + // Mass storage device is ready. + // + eSTATE_DEVICE_READY, + + // + // An unsupported device has been attached. + // + eSTATE_UNKNOWN_DEVICE, + + // + // A power fault has occurred. + // + eSTATE_POWER_FAULT +} +g_iState; + +//***************************************************************************** +// +// The instance data for the MSC driver. +// +//***************************************************************************** +tUSBHMSCInstance *g_psMSCInstance = 0; + +//***************************************************************************** +// +// Declare the USB Events driver interface. +// +//***************************************************************************** +DECLARE_EVENT_DRIVER(g_sUSBEventDriver, 0, 0, USBHCDEvents); + +//***************************************************************************** +// +// The global that holds all of the host drivers in use in the application. +// In this case, only the MSC class is loaded. +// +//***************************************************************************** +static tUSBHostClassDriver const * const g_ppHostClassDrivers[] = +{ + &g_sUSBHostMSCClassDriver, + &g_sUSBEventDriver +}; + +//***************************************************************************** +// +// This global holds the number of class drivers in the g_ppHostClassDrivers +// list. +// +//***************************************************************************** +static const uint32_t g_ui32NumHostClassDrivers = + sizeof(g_ppHostClassDrivers) / sizeof(tUSBHostClassDriver *); + +//***************************************************************************** +// +// The control table used by the uDMA controller. This table must be aligned +// to a 1024 byte boundary. In this application uDMA is only used for USB, +// so only the first 6 channels are needed. +// +//***************************************************************************** +#if defined(ewarm) +#pragma data_alignment=1024 +tDMAControlTable g_psDMAControlTable[6]; +#elif defined(ccs) +#pragma DATA_ALIGN(g_psDMAControlTable, 1024) +tDMAControlTable g_psDMAControlTable[6]; +#else +tDMAControlTable g_psDMAControlTable[6] __attribute__ ((aligned(1024))); +#endif + +//***************************************************************************** +// +// Initializes the file system module. +// +// \param None. +// +// This function initializes the third party FAT implementation. +// +// \return Returns \e true on success or \e false on failure. +// +//***************************************************************************** +static bool +FileInit(void) +{ + // + // Mount the file system, using logical disk 0. + // + if(f_mount(0, &g_sFatFs) != FR_OK) + { + return(false); + } + return(true); +} + +//***************************************************************************** +// +// This is the callback from the MSC driver. +// +// \param ui32Instance is the driver instance which is needed when +// communicating with the driver. +// \param ui32Event is one of the events defined by the driver. +// \param pvData is a pointer to data passed into the initial call to register +// the callback. +// +// This function handles callback events from the MSC driver. The only events +// currently handled are the MSC_EVENT_OPEN and MSC_EVENT_CLOSE. This allows +// the main routine to know when an MSC device has been detected and +// enumerated and when an MSC device has been removed from the system. +// +// \return None +// +//***************************************************************************** +static void +MSCCallback(tUSBHMSCInstance *psMSCInstance, uint32_t ui32Event, void *pvData) +{ + // + // Determine the event. + // + switch(ui32Event) + { + // + // Called when the device driver has successfully enumerated an MSC + // device. + // + case MSC_EVENT_OPEN: + { + // + // Proceed to the enumeration state. + // + g_iState = eSTATE_DEVICE_ENUM; + + break; + } + + // + // Called when the device driver has been unloaded due to error or + // the device is no longer present. + // + case MSC_EVENT_CLOSE: + { + // + // Go back to the "no device" state and wait for a new connection. + // + g_iState = eSTATE_NO_DEVICE; + + // + // Re-initialize the file system. + // + FileInit(); + + break; + } + + default: + { + break; + } + } +} + +//***************************************************************************** +// +// This is the generic callback from host stack. +// +// pvData is actually a pointer to a tEventInfo structure. +// +// This function will be called to inform the application when a USB event has +// occurred that is outside those related to the mass storage device. At this +// point this is used to detect unsupported devices being inserted and removed. +// It is also used to inform the application when a power fault has occurred. +// This function is required when the g_USBGenericEventDriver is included in +// the host controller driver array that is passed in to the +// USBHCDRegisterDrivers() function. +// +// +//***************************************************************************** +void +USBHCDEvents(void *pvData) +{ + tEventInfo *psEventInfo; + + // + // Cast this pointer to its actual type. + // + psEventInfo = (tEventInfo *)pvData; + + // + // Process each kind of event + // + switch(psEventInfo->ui32Event) + { + // + // An unknown device has been connected. + // + case USB_EVENT_UNKNOWN_CONNECTED: + { + // + // An unknown device was detected. + // + g_iState = eSTATE_UNKNOWN_DEVICE; + break; + } + + // + // The unknown device has been been unplugged. + // + case USB_EVENT_DISCONNECTED: + { + // + // Unknown device has been removed. + // + g_iState = eSTATE_NO_DEVICE; + break; + } + + // + // A bus power fault was detected. + // + case USB_EVENT_POWER_FAULT: + { + // + // No power means no device is present. + // + g_iState = eSTATE_POWER_FAULT; + break; + } + + default: + { + break; + } + } +} + +//***************************************************************************** +// +// Initializes the USB stack for mass storage. +// +//***************************************************************************** +void +USBStickInit(void) +{ + // + // Enable the uDMA controller and set up the control table base. + // The uDMA controller is used by the USB library. + // + MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); + MAP_uDMAEnable(); + MAP_uDMAControlBaseSet(g_psDMAControlTable); + + // + // Initially wait for device connection. + // + g_iState = eSTATE_NO_DEVICE; + + // + // 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 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); + + // + // Run initial pass through USB host stack. + // + USBHCDMain(); + + // + // Initialize the file system. + // + FileInit(); +} + +//***************************************************************************** +// +// This is called by the application main loop to perform regular processing. +// It keeps the USB host stack running and tracks the state of the attached +// device. +// +//***************************************************************************** +void +USBStickRun(void) +{ + // + // Call the USB stack to keep it running. + // + USBHCDMain(); + + // + // Take action based on the application state. + // + switch(g_iState) + { + // + // A device has enumerated. + // + case eSTATE_DEVICE_ENUM: + { + // + // Check to see if the device is ready. If not then stay + // in this state and we will check it again on the next pass. + // + if(USBHMSCDriveReady(g_psMSCInstance) != 0) + { + // + // Wait about 500ms before attempting to check if the + // device is ready again. + // + MAP_SysCtlDelay(MAP_SysCtlClockGet()/3); + break; + } + + // + // If there were no errors reported, we are ready for + // MSC operation. + // + g_iState = eSTATE_DEVICE_READY; + + // + // Set the Device Present flag. + // + g_ui32Flags = FLAGS_DEVICE_PRESENT; + + break; + } + + // + // If there is no device then just wait for one. + // + case eSTATE_NO_DEVICE: + { + if(g_ui32Flags == FLAGS_DEVICE_PRESENT) + { + // + // Clear the Device Present flag. + // + g_ui32Flags &= ~(FLAGS_DEVICE_PRESENT | FLAGS_FILE_OPENED); + } + break; + } + + // + // An unknown device was connected. + // + case eSTATE_UNKNOWN_DEVICE: + { + // + // If this is a new device then change the status. + // + if((g_ui32Flags & FLAGS_DEVICE_PRESENT) == 0) + { + // + // Unknown device is present + // + } + + // + // Set the Device Present flag even though the unknown device + // is not useful to us. + // + g_ui32Flags = FLAGS_DEVICE_PRESENT; + break; + } + + // + // The device is ready and in use. + // + case eSTATE_DEVICE_READY: + { + break; + } + + // + // Something has caused a power fault. + // + case eSTATE_POWER_FAULT: + { + break; + } + + // + // Unexpected USB state. Set back to default. + // + default: + { + g_iState = eSTATE_NO_DEVICE; + g_ui32Flags &= ~(FLAGS_DEVICE_PRESENT | FLAGS_FILE_OPENED); + break; + } + } +} + +//***************************************************************************** +// +// This is called when the data logging is stopped. It performs a sync +// to the file system which should flush any buffered data to the storage +// device. +// +//***************************************************************************** +void +USBStickCloseFile(void) +{ + f_close(&g_sFileObject); + g_ui32Flags &= ~FLAGS_FILE_OPENED; +} + +//***************************************************************************** +// +// Create a file name for the file to be saved on the memory stick. +// This function uses an incrementing numerical search scheme to determine +// an available file name. It tries opening file names in succession until +// it finds a file that does not yet exist. +// The file name will be of the form LOGnnnn.CSV. +// The caller supplies storage for the file name through the pcFilename +// parameter. +// The function will return 0 if successful and non-zero if a file name could +// not be found. +// +//***************************************************************************** +static int32_t +CreateFileName(char *pcFilename, uint32_t ui32Len) +{ + FRESULT iFResult; + uint32_t ui32FileNum = 0; + + // + // Enter loop to search for available file name + // + do + { + // + // Prepare a numerical based file name and attempt to open it + // + usnprintf(pcFilename, ui32Len, "LOG%04d.CSV", ui32FileNum); + iFResult = f_open(&g_sFileObject, pcFilename, FA_OPEN_EXISTING); + + // + // If file does not exist, then we have found a useable file name + // + if(iFResult == FR_NO_FILE) + { + // + // Return to caller, indicating that a file name has been found. + // + return(0); + } + + // + // Otherwise, advance to the next number in the file name sequence. + // + ui32FileNum++; + + } while(ui32FileNum < 1000); + + // + // If we reach this point, it means that no useable file name was found + // after attempting 10000 file names. + // + return(1); +} + +//***************************************************************************** +// +// This is called at the start of logging to open a file on the storage +// device in preparation for saving data. If no file name is specified, then +// a new file will be created. +// +// If a file name is specified, then that will be used instead of searching +// for an available file. The file name that is passed in must be a maximum +// of 8 characters (9 including trailing 0) and represents the first part of +// the file name not including the extension. +// +// The function returns a pointer to the first part of the file name +// (without file extension). It can be up to 8 characters (9 including the +// trailing 0). If there is any error then a NULL pointer is returned. +// +//***************************************************************************** +char * +USBStickOpenLogFile(char *pcFilename8) +{ + FRESULT iFResult; + uint32_t ui32BytesWritten; + static char pcFilename[16]; + uint32_t ui32Len; + + // + // Check state for ready device + // + g_ui32Flags &= ~FLAGS_FILE_OPENED; + if(g_iState == eSTATE_DEVICE_READY) + { + // + // If a file name is specified then open that file + // + if(pcFilename8 && pcFilename8[0]) + { + // + // Copy the filename into local storage and cap at 8 characters + // length. + // + memcpy(pcFilename, pcFilename8, 8); + pcFilename[8] = 0; + + // + // Find the actual length of the string (8 chars or less) so we + // know where to add the extension. + // + ui32Len = strlen(pcFilename); + + // + // Add the extension to the file name. + // + usnprintf(&pcFilename[ui32Len], 5, ".CSV"); + } + + // + // Otherwise no file name was specified so create a new one. + // + else + { + if(CreateFileName(pcFilename, sizeof(pcFilename))) + { + // + // There was a problem creating a file name so return an error + // + return(0); + } + } + + // + // Open the file by name that was determined above. If the file exists + // it will be opened, and if not it will be created. + // + iFResult = f_open(&g_sFileObject, pcFilename, (FA_OPEN_ALWAYS | + FA_WRITE)); + if(iFResult != FR_OK) + { + return(0); + } + + // + // Since it is possible that the file already existed when opened, + // seek to the end of the file so new data will be appended. If this + // is a new file then this will just be the beginning of the file. + // + iFResult = f_lseek(&g_sFileObject, g_sFileObject.fsize); + if(iFResult != FR_OK) + { + return(0); + } + + // + // Set flag to indicate file is now opened. + // + g_ui32Flags |= FLAGS_FILE_OPENED; + + // + // If no file name was specified, then this is a new file so write a + // header line with column titles to the CSV file. + // + if(!pcFilename8 || !pcFilename8[0]) + { + // + // Write a header line to the CSV file + // + iFResult = f_write(&g_sFileObject, g_pcCSVHeaderLine, + sizeof(g_pcCSVHeaderLine), &ui32BytesWritten); + if(iFResult != FR_OK) + { + g_ui32Flags &= ~FLAGS_FILE_OPENED; + return(0); + } + + // + // Since no file name was specified that means a file name was + // created. Terminate the new file name at the '.' separator + // and return it to the caller. We know that created file names + // are always 7 characters. Return the newly created file name + // (the part before the '.') + // + pcFilename[7] = 0; + return(pcFilename); + } + + // + // Otherwise, a file name was specified, so no need to write a + // header row. The caller's file name is unchanged so return the + // same value back. + // + else + { + return(pcFilename8); + } + } + + else + { + // + // Device not ready so return NULL. + // + return(0); + } +} + +//***************************************************************************** +// +// This is called each time there is a new data record to log to the storage +// device. A line of text in CSV format will be written to the file. +// +//***************************************************************************** +int32_t +USBStickWriteRecord(tLogRecord *psRecord) +{ + static char pcBuf[256]; + uint32_t ui32Idx, ui32BufIdx = 0, ui32RecordIdx, ui32Selected; + FRESULT iFResult; + uint32_t ui32BytesWritten; + + // + // Check the arguments + // + ASSERT(psRecord); + if(!psRecord) + { + return(1); + } + + // + // Check state for ready device and opened file + // + if((g_iState != eSTATE_DEVICE_READY) || !(g_ui32Flags & FLAGS_FILE_OPENED)) + { + return(1); + } + + // + // Print time stamp columns + // + ui32BufIdx += usnprintf(&pcBuf[ui32BufIdx], sizeof(pcBuf) - ui32BufIdx, + "%u,%u", psRecord->ui32Seconds, + psRecord->ui16Subseconds); + + // + // Iterate through selected data items and print to CSV buffer + // + ui32RecordIdx = 0; + ui32Selected = psRecord->ui16ItemMask; + for(ui32Idx = 0; ui32Idx < NUM_LOG_ITEMS; ui32Idx++) + { + // + // If this data item is selected, then print a value to the CSV buffer + // + if(ui32Selected & 1) + { + ui32BufIdx += usnprintf(&pcBuf[ui32BufIdx], + (sizeof(pcBuf) - ui32BufIdx), ",%d", + psRecord->pi16Items[ui32RecordIdx]); + ui32RecordIdx++; + } + else + { + // + // Otherwise, this column of data is not selected so emit just a + // comma + // + ui32BufIdx += usnprintf(&pcBuf[ui32BufIdx], + (sizeof(pcBuf) - ui32BufIdx), ","); + } + + // + // Next selected item ... + // + ui32Selected >>= 1; + } + + // + // Append a CRLF to the end + // + ui32BufIdx += usnprintf(&pcBuf[ui32BufIdx], (sizeof(pcBuf) - ui32BufIdx), + "\r\n"); + + // + // Now write the entire buffer to the USB stick file + // + iFResult = f_write(&g_sFileObject, pcBuf, ui32BufIdx, &ui32BytesWritten); + + // + // Check for errors + // + if((iFResult != FR_OK) || (ui32BytesWritten != ui32BufIdx)) + { + // + // Some error occurred + // + g_ui32Flags &= ~FLAGS_FILE_OPENED; + return(1); + } + else + { + // + // No errors occurred, return success + // + return(0); + } +} diff --git a/boards/ek-lm4f232/qs-logger/usbstick.h b/boards/ek-lm4f232/qs-logger/usbstick.h new file mode 100644 index 0000000..d05459a --- /dev/null +++ b/boards/ek-lm4f232/qs-logger/usbstick.h @@ -0,0 +1,58 @@ +//***************************************************************************** +// +// usbstick.h - Prototypes and definitions for USB mass storage module. +// +// 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. +// +//***************************************************************************** +#ifndef __USBSTICK_H__ +#define __USBSTICK_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Module function prototypes. +// +//***************************************************************************** +extern void USBStickInit(void); +extern void USBStickRun(void); +extern void USBStickCloseFile(void); +extern char *USBStickOpenLogFile(char *pcFilename); +extern int32_t USBStickWriteRecord(tLogRecord *psRecord); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __USBSTICK_H__ -- cgit v1.3.1