/* * Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu * Copyright (c) 2012, 2013, Andrew Hannam aka inmarket * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * This demo demonstrates the use of the GADC module using it read both a microphone, * an analogue dial wheel and a temperature sensor. * The microphone gets read at high frequency to display a very simple oscilloscope. * The dial and temperature gets read at a low frequency to just print when * it changes value. * * It also demonstrates how to write your own custom GWIN window type. */ #include "gfx.h" /* Include our custom gwin oscilloscope */ #include "gwinosc.h" /* * Match these to your hardware * If you don't have a DIAL device or a TEMP device - just don't define it. */ #define MY_MIC_DEVICE GADC_PHYSDEV_MICROPHONE #define MY_DIAL_DEVICE GADC_PHYSDEV_DIAL #define MY_TEMP_DEVICE GADC_PHYSDEV_TEMPERATURE #define MY_DIAL_JITTER 1 #define MY_TEMP_JITTER 3 /* Specify our timing parameters */ #define MY_MIC_FREQUENCY 4000 /* 4khz */ #define MY_LS_DELAY 200 /* 200ms (5 times per second) for the dial and temperature */ /* The desired size for our scope window */ #define SCOPE_CX 64 #define SCOPE_CY 64 /* Data */ static GScopeObject gScopeWindow; static GConsoleObject gTextWindow; static GTimer lsTimer; #ifdef MY_DIAL_DEVICE static adcsample_t dialvalue; static adcsample_t lastdial = -(MY_DIAL_JITTER+1); /** * We have got a dial reading - handle it */ static void GotDialReading(adcsample_t *buffer, void *param) { (void) buffer; /* Buffer should always point to "dialvalue" anyway */ /* Remove jitter from the value */ if ((dialvalue > lastdial && dialvalue - lastdial > MY_DIAL_JITTER) || (lastdial > dialvalue && lastdial - dialvalue > MY_DIAL_JITTER)) { /* Write the value */ gwinPrintf((GHandle)param, "DIAL: %u\n", dialvalue); /* Save for next time */ lastdial = dialvalue; } } #endif #ifdef MY_TEMP_DEVICE static adcsample_t tempvalue; static adcsample_t lasttemp = -(MY_TEMP_JITTER+1); /** * We have got a temperature reading - handle it */ static void GotTempReading(adcsample_t *buffer, void *param) { (void) buffer; /* Buffer should always point to "tempvalue" anyway */ /* Remove jitter from the value */ if ((tempvalue > lasttemp && tempvalue - lasttemp > MY_TEMP_JITTER) || (lasttemp > tempvalue && lasttemp - tempvalue > MY_TEMP_JITTER)) { /* Write the value */ gwinPrintf((GHandle)param, "TEMP: %u\n", tempvalue); /* Save for next time */ lasttemp = tempvalue; } } #endif #if defined(MY_DIAL_DEVICE) || defined(MY_TEMP_DEVICE) /** * Start a read of the dial and temperature */ static void LowSpeedTimer(void *param) { /* We are not checking for an error here - but who cares, this is just a demo */ #ifdef MY_DIAL_DEVICE gadcLowSpeedStart(MY_DIAL_DEVICE, &dialvalue, GotDialReading, param); #endif #ifdef MY_TEMP_DEVICE gadcLowSpeedStart(MY_TEMP_DEVICE, &tempvalue, GotTempReading, param); #endif } #endif /* * Application entry point. */ int main(void) { GHandle ghScope; gCoord swidth, sheight; #if defined(MY_DIAL_DEVICE) || defined(MY_TEMP_DEVICE) GHandle ghText; gFont font; #endif gfxInit(); /* Get the screen dimensions */ swidth = gdispGetWidth(); sheight = gdispGetHeight(); #if defined(MY_DIAL_DEVICE) || defined(MY_TEMP_DEVICE) /* Set up the console window we use for dial readings */ font = gdispOpenFont("UI2"); gwinSetDefaultFont(font); { GWindowInit wi; gwinClearInit(&wi); wi.show = gTrue; wi.x = wi.y = 0; wi.width = swidth-SCOPE_CX; wi.height = sheight; ghText = gwinConsoleCreate(&gTextWindow, &wi); } gwinSetBgColor(ghText, GFX_BLACK); gwinSetColor(ghText, GFX_YELLOW); gwinClear(ghText); /* Start our timer for reading the dial */ gtimerInit(&lsTimer); gtimerStart(&lsTimer, LowSpeedTimer, ghText, gTrue, MY_LS_DELAY); #endif /** * Allocate buffers for the high speed GADC device - eg. 4 x 128 byte buffers. * You may need to increase this for slower cpu's. * You may be able to decrease this for low latency operating systems. * 4 x 128 seems to work on the really slow Olimex SAM7EX256 board (display speed limitation) * If your oscilloscope display stops but the low speed reading keep going then it is likely that * your high speed timer has stalled due to running out of free buffers. Increase the number * of buffers.. * If you make the buffers too large with a slow sample rate you may not allow enough time for all * the low speed items to occur in which case your memory will fill up with low speed requests until * you run out of memory. */ gfxBufferAlloc(4, 128); /* Set up the scope window in the top right on the screen */ { GWindowInit wi; gwinClearInit(&wi); wi.show = gTrue; wi.x = swidth-SCOPE_CX; wi.y = 0; wi.width = SCOPE_CX; wi.height = SCOPE_CY; ghScope = gwinScopeCreate(&gScopeWindow, &wi, MY_MIC_DEVICE, MY_MIC_FREQUENCY); } gwinSetBgColor(ghScope, GFX_WHITE); gwinSetColor(ghScope, GFX_RED); gwinClear(ghScope); /* Just keep displaying the scope traces */ while (1) { /** * The function below internally performs a wait thus giving the timer thread a * chance to run. */ gwinScopeWaitForTrace(ghScope); } }