From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- drivers/tsd/tsd.dir | 42 +++++ drivers/tsd/tsd.h | 74 ++++++++ drivers/tsd/tsd_ads7843.c | 438 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/tsd/tsd_com.c | 390 +++++++++++++++++++++++++++++++++++++++++ drivers/tsd/tsd_com.h | 48 +++++ drivers/tsd/tsd_tsadc.c | 269 ++++++++++++++++++++++++++++ 6 files changed, 1261 insertions(+) create mode 100644 drivers/tsd/tsd.dir create mode 100644 drivers/tsd/tsd.h create mode 100644 drivers/tsd/tsd_ads7843.c create mode 100644 drivers/tsd/tsd_com.c create mode 100644 drivers/tsd/tsd_com.h create mode 100644 drivers/tsd/tsd_tsadc.c (limited to 'drivers/tsd') diff --git a/drivers/tsd/tsd.dir b/drivers/tsd/tsd.dir new file mode 100644 index 0000000..c72fa6f --- /dev/null +++ b/drivers/tsd/tsd.dir @@ -0,0 +1,42 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \dir +/// +/// !!!Contents +/// +/// This directory contains the source code of the touchscreen driver. tsd.h +/// contains all the interface functions definitions. tsd_tsadc.c contains the +/// implementation of the driver for the chip that have the peripheral ip TSADC. +/// tsd_ads7843.c contains the driver implementation for board that have the +/// external component ads7843 (the chip has not the peripheral ip TSDADC). +/// tds_com.c contains all the common function for the two driver implementations +/// (calibration functions). +//------------------------------------------------------------------------------ diff --git a/drivers/tsd/tsd.h b/drivers/tsd/tsd.h new file mode 100644 index 0000000..22a4930 --- /dev/null +++ b/drivers/tsd/tsd.h @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \unit +/// +/// !!!Purpose +/// +/// This unit provides a very powerful touchscreen driver which handles all the +/// complexity. This includes touchscreen calibration, retrieving measurements, +/// configuring the TSADC, etc. +/// +/// !!!Usage +/// +/// -# Call TSD_Initialize() whenever the touchscreen should start the +/// calibration process (as it is done in the function). +/// -# Declare a global TSD_PenPressed function anywhere in your code. This +/// function will get called every time the pen is pressed on the screen. +/// -# Declare a global TSD_PenMoved function, which will get called whenever +/// the pen stays in contact with the screen but changes position. +/// -# Declare a global TSD_PenReleased function, which will be invoked as the +/// pen is lifted from the screen. +//------------------------------------------------------------------------------ + +#ifndef TSD_H +#define TSD_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "tsd_com.h" + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +extern void TSD_Initialize(void *pLcdBuffer); + +extern unsigned char TSD_Calibrate(void *pLcdBuffer); + +extern void TSD_Reset(void); + +#ifdef at91sam3u +extern void TSD_TimerHandler(void); +#endif + +#endif //#ifndef TSD_H diff --git a/drivers/tsd/tsd_ads7843.c b/drivers/tsd/tsd_ads7843.c new file mode 100644 index 0000000..3800a5f --- /dev/null +++ b/drivers/tsd/tsd_ads7843.c @@ -0,0 +1,438 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +#ifdef BOARD_TSC_ADS7843 + +#include "tsd.h" +#include "tsd_com.h" +#include +#include +#include +#if defined(cortexm3) +#include +#else +#include +#endif +#include +#include +#include +#include + +#include + +//------------------------------------------------------------------------------ +// Local definitions +//------------------------------------------------------------------------------ + +/// PIT period value in µseconds. +#define PIT_PERIOD 10000 // 10 ms + +/// Delay for pushbutton debouncing (in PIT_PERIOD time-base). +#define DEBOUNCE_TIME 6 // PIT_PERIOD * 6 = 60 ms + +/// Color of calibration points. +#define POINTS_COLOR 0x0000FF + +/// Size in pixels of calibration points. +#define POINTS_SIZE 4 + +/// Maximum difference in pixels between the test point and the measured point. +#define POINTS_MAX_ERROR 5 + +//------------------------------------------------------------------------------ +// Local types +//------------------------------------------------------------------------------ + +/// pen state +typedef enum { + STATE_PEN_RELEASED = 0, + STATE_PEN_PRESSED = 1, + STATE_PEN_DEBOUNCE = 2 +} e_pen_state; + + +//------------------------------------------------------------------------------ +// Local variables +//------------------------------------------------------------------------------ + +/// Pins used by Interrupt Signal for Touch Screen Controller +static Pin pinPenIRQ = PIN_TCS_IRQ; + +/// Global timestamp in milliseconds since start of application. +static volatile unsigned int timestamp = 0; + +/// last time when the pen is pressed on the touchscreen +static volatile unsigned int timePress = 0; + +/// last time when the pen is released +static volatile unsigned int timeRelease = 0; + +/// pen state +static volatile e_pen_state penState = STATE_PEN_RELEASED; + +/// Touch screen initiallized flag +static unsigned int tsInitFlag = 0; + +//------------------------------------------------------------------------------ +// External functions +//------------------------------------------------------------------------------ + +extern void TSD_PenPressed(unsigned int x, unsigned int y); +extern void TSD_PenMoved(unsigned int x, unsigned int y); +extern void TSD_PenReleased(unsigned int x, unsigned int y); + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ +extern void TSD_GetRawMeasurement(unsigned int *pData); + +#if defined(cortexm3) +//------------------------------------------------------------------------------ +/// Timer handler for touch screen. Increments the timestamp counter. +/// Determine the state "Pen Pressed" or "Pen Released". To change state, +/// the penIRQ has to keep the same value during DEBOUNCE_TIME. +/// For AT91SAM3, SysTick interrupt should call it per 10ms. +//------------------------------------------------------------------------------ +void TSD_TimerHandler(void) +{ + unsigned int data[2]; + static unsigned int point[2]; + + if (!tsInitFlag) return; + + timestamp++; + // Get the current position of the pen if penIRQ has low value (pen pressed) + if (PIO_Get(&pinPenIRQ) == 0) { + + // Get the current position of the pressed pen + if(TSDCom_IsCalibrationOk()) { + TSD_GetRawMeasurement(data); + TSDCom_InterpolateMeasurement(data, point); + } + + // call the callback function + if(penState == STATE_PEN_PRESSED) { + if(TSDCom_IsCalibrationOk()) { + TSD_PenMoved(point[0], point[1]); + } + } + } + + // Determine the pen state + if (PIO_Get(&pinPenIRQ) == 0) { + + // reinit the last time when release + timeRelease = timestamp; + + if(penState == STATE_PEN_DEBOUNCE) { + + if( (timestamp - timePress) > DEBOUNCE_TIME) { + + // pen is pressed during an enough time : the state change + penState = STATE_PEN_PRESSED; + // call the callback function + if(TSDCom_IsCalibrationOk()) { + TSD_PenPressed(point[0], point[1]); + } + } + } + } + else { + // reinit the last time when release + timePress = timestamp; + + if(penState == STATE_PEN_DEBOUNCE) { + + if( (timestamp - timeRelease) > DEBOUNCE_TIME) { + + // pen is released during an enough time : the state change + penState = STATE_PEN_RELEASED; + // call the callback function + if(TSDCom_IsCalibrationOk()) { + TSD_PenReleased(point[0], point[1]); + } + } + } + } +} + +#else // For SAM7/SAM9 + +//------------------------------------------------------------------------------ +/// Handler for PIT interrupt. Increments the timestamp counter. +/// Determine the state "Pen Pressed" or "Pen Released". To change state, +/// the penIRQ has to keep the same value during DEBOUNCE_TIME. +//------------------------------------------------------------------------------ +static void ISR_Pit(void) +{ + unsigned int status; + unsigned int data[2]; + static unsigned int point[2]; + + // Read the PIT status register + status = PIT_GetStatus() & AT91C_PITC_PITS; + if (status != 0) { + + // Read the PIVR to acknowledge interrupt and get number of ticks + timestamp += (PIT_GetPIVR() >> 20); + } + + // Get the current position of the pen if penIRQ has low value (pen pressed) + if (PIO_Get(&pinPenIRQ) == 0) { + + // Get the current position of the pressed pen + PIO_DisableIt(&pinPenIRQ); + ADS7843_GetPosition(&data[0], &data[1]); + PIO_EnableIt(&pinPenIRQ); + + TSD_GetRawMeasurement(data); + TSDCom_InterpolateMeasurement(data, point); + + // call the callback function + if(penState == STATE_PEN_PRESSED) { + if(TSDCom_IsCalibrationOk()) { + TSD_PenMoved(point[0], point[1]); + } + } + } + + // Determine the pen state + if (PIO_Get(&pinPenIRQ) == 0) { + + // reinit the last time when release + timeRelease = timestamp; + + if(penState == STATE_PEN_DEBOUNCE) { + + if( (timestamp - timePress) > DEBOUNCE_TIME) { + + // pen is pressed during an enough time : the state change + penState = STATE_PEN_PRESSED; + // call the callback function + if(TSDCom_IsCalibrationOk()) { + TSD_PenPressed(point[0], point[1]); + } + } + } + } + else { + // reinit the last time when release + timePress = timestamp; + + if(penState == STATE_PEN_DEBOUNCE) { + + if( (timestamp - timeRelease) > DEBOUNCE_TIME) { + + // pen is released during an enough time : the state change + penState = STATE_PEN_RELEASED; + // call the callback function + if(TSDCom_IsCalibrationOk()) { + TSD_PenReleased(point[0], point[1]); + } + } + } + } +} +#endif + +//------------------------------------------------------------------------------ +/// Interrupt handler for Touchscreen. +//------------------------------------------------------------------------------ +static void ISR_PenIRQ(void) +{ + // Check if the pen has been pressed + if (!PIO_Get(&pinPenIRQ)) { + + if(penState == STATE_PEN_RELEASED) { + + timePress = timestamp; + penState = STATE_PEN_DEBOUNCE; + } + } + else { + + if(penState == STATE_PEN_PRESSED) { + + timeRelease = timestamp; + penState = STATE_PEN_DEBOUNCE; + } + } +} + +#if !defined(cortexm3) +//------------------------------------------------------------------------------ +/// Configure the periodic interval timer to generate an interrupt every 10 ms +//------------------------------------------------------------------------------ +static void ConfigurePit(void) +{ + // Initialize the PIT to the desired frequency + PIT_Init(PIT_PERIOD, BOARD_MCK / 1000000); + + // Configure interrupt on PIT + IRQ_DisableIT(AT91C_ID_SYS); + IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit); + IRQ_EnableIT(AT91C_ID_SYS); + PIT_EnableIT(); + + // Enable the pit + PIT_Enable(); +} +#endif + +//----------------------------------------------------------------------------- +/// Configure PENIRQ for interrupt +//----------------------------------------------------------------------------- +void ConfigurePenIRQ(void) +{ + // Configure pios + PIO_Configure(&pinPenIRQ, PIO_LISTSIZE(pinPenIRQ)); + + // Initialize interrupts +#if defined(cortexm3) + PIO_InitializeInterrupts(0); +#else // For SAM7/SAM9 + PIO_InitializeInterrupts(AT91C_AIC_PRIOR_HIGHEST); +#endif + PIO_ConfigureIt(&pinPenIRQ, (void (*)(const Pin *)) ISR_PenIRQ); + + // Enable the interrupt + PIO_EnableIt(&pinPenIRQ); +} + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Reads and store a touchscreen measurement in the provided array. +/// \param pData Array where the measurements will be stored +//------------------------------------------------------------------------------ +void TSD_GetRawMeasurement(unsigned int *pData) +{ +#if defined(cortexm3) + // Get the current position of the pressed pen + PIO_DisableIt(&pinPenIRQ); + ADS7843_GetPosition(&pData[0], &pData[1]); + PIO_EnableIt(&pinPenIRQ); +#else + // Get the current position of the pressed pen + PIO_DisableIt(&pinPenIRQ); + ADS7843_GetPosition(&pData[0], &pData[1]); + PIO_EnableIt(&pinPenIRQ); +#endif +} + +//------------------------------------------------------------------------------ +/// Wait pen pressed +//------------------------------------------------------------------------------ +void TSD_WaitPenPressed(void) +{ + // Wait for touch & end of conversion + while (penState != STATE_PEN_RELEASED); + while (penState != STATE_PEN_PRESSED); +} + +//------------------------------------------------------------------------------ +/// Wait pen released +//------------------------------------------------------------------------------ +void TSD_WaitPenReleased(void) +{ + // Wait for contact loss + while (penState != STATE_PEN_PRESSED); + while (penState != STATE_PEN_RELEASED); +} + +//------------------------------------------------------------------------------ +/// Do calibration +/// \param pLcdBuffer LCD buffer to use for displaying the calibration info. +/// \return 1 if calibration is Ok, 0 else +//------------------------------------------------------------------------------ +unsigned char TSD_Calibrate(void *pLcdBuffer) +{ + unsigned char ret = 0; + + // Calibration is done only once + if(TSDCom_IsCalibrationOk()) { + return 1; + } + + // Do calibration + ret = TSDCom_Calibrate(pLcdBuffer); + + return ret; +} + +//------------------------------------------------------------------------------ +/// Initializes the touchscreen driver and starts the calibration process. When +/// finished, the touchscreen is operational. +/// +/// Important: the LCD driver must have been initialized prior to calling this +/// function. +/// \param pBuffer LCD buffer to use for displaying the calibration info. +//------------------------------------------------------------------------------ +void TSD_Initialize(void *pLcdBuffer) +{ + ADS7843_Initialize(); + ConfigurePenIRQ(); +#if !defined(cortexm3) + ConfigurePit(); +#endif + tsInitFlag = 1; + + // Calibration + if(pLcdBuffer) { + while (!TSD_Calibrate(pLcdBuffer)); + } +} + +//------------------------------------------------------------------------------ +/// Stop the Touchscreen, disable interrupt and stop Pit +//------------------------------------------------------------------------------ +void TSD_Reset(void) +{ + // Disable SPI 0 + ADS7843_Reset(); + + // Disable the interrupt + PIO_DisableIt(&pinPenIRQ); + +#if !defined(cortexm3) + // Stop Pit interrupt + PIT_DisableIT(); + IRQ_DisableIT(AT91C_ID_SYS); +#endif +} + +#endif //#ifdef BOARD_TSC_ADS7843 diff --git a/drivers/tsd/tsd_com.c b/drivers/tsd/tsd_com.c new file mode 100644 index 0000000..a930cc9 --- /dev/null +++ b/drivers/tsd/tsd_com.c @@ -0,0 +1,390 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "tsd.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Local definitions +//------------------------------------------------------------------------------ + +/// Size in pixels of calibration points. +#define POINTS_SIZE 4 +/// Maximum difference in pixels between the test point and the measured point. +#define POINTS_MAX_ERROR 8 + +/// Delay at the end of calibartion for result display (positive or negative) +#define DELAY_RESULT_DISPLAY 4000000 + +//------------------------------------------------------------------------------ +// Local types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Point used during the touchscreen calibration process. +//------------------------------------------------------------------------------ +typedef struct _CalibrationPoint { + + /// Coordinate of point along the X-axis of the screen. + unsigned int x; + /// Coordinate of point along the Y-axis of the screen. + unsigned int y; + /// Calibration data of point. + unsigned int data[2]; + +} CalibrationPoint; + +//------------------------------------------------------------------------------ +// Local variables +//------------------------------------------------------------------------------ + +/// indicates if the touch screen has been calibrated. +/// If not, Callback functions are not called +static volatile unsigned char bCalibrationOk = 0; +/// Slope for interpoling touchscreen measurements along the X-axis. +static signed int xSlope; +/// Slope for interpoling touchscreen measurements along the Y-axis. +static signed int ySlope; + +/// Calibration points +static CalibrationPoint calibrationPoints[] = { + + // Top-left corner calibration point + { + BOARD_LCD_WIDTH / 10, + BOARD_LCD_HEIGHT / 10, + {0, 0} + }, + // Top-right corner calibration point + { + BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10, + BOARD_LCD_HEIGHT / 10, + {0, 0} + }, + // Bottom-right corner calibration point + { + BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10, + BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10, + {0, 0} + }, + // Bottom-left corner calibration point + { + BOARD_LCD_WIDTH / 10, + BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10, + {0, 0} + } +}; + +/// Test point +static const CalibrationPoint testPoint = { + BOARD_LCD_WIDTH / 2, + BOARD_LCD_HEIGHT / 2, + {0, 0} +}; + +//------------------------------------------------------------------------------ +// External functions +//------------------------------------------------------------------------------ + +extern void TSD_GetRawMeasurement(unsigned int *pData); +extern void TSD_WaitPenPressed(void); +extern void TSD_WaitPenReleased(void); + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Display a calibration point on the given buffer. +/// \param pLcdBuffer LCD buffer to draw on. +/// \param pPoint Calibration point to display. +//------------------------------------------------------------------------------ +static void DrawCalibrationPoint( + void *pLcdBuffer, + const CalibrationPoint *pPoint) +{ + LCDD_DrawRectangle(pLcdBuffer, + pPoint->x - POINTS_SIZE / 2, + pPoint->y - POINTS_SIZE / 2, + POINTS_SIZE, + POINTS_SIZE, + COLOR_RED); +} + +//------------------------------------------------------------------------------ +/// Clears a calibration point from the given buffer. +/// \param pLcdBuffer LCD buffer to draw on. +/// \param pPoint Calibration point to clear. +//------------------------------------------------------------------------------ +static void ClearCalibrationPoint( + void *pLcdBuffer, + const CalibrationPoint *pPoint) +{ + LCDD_DrawRectangle(pLcdBuffer, + pPoint->x - POINTS_SIZE / 2, + pPoint->y - POINTS_SIZE / 2, + POINTS_SIZE, + POINTS_SIZE, + COLOR_WHITE); +} + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Indicates if the calibration of the touch screen is Ok +/// \return 1 calibration Ok, 0 if not +//------------------------------------------------------------------------------ +unsigned char TSDCom_IsCalibrationOk(void) +{ + if (bCalibrationOk == 1) { + return 1; + } else { + return 0; + } +} + +//------------------------------------------------------------------------------ +/// Interpolates the provided raw measurements using the previously calculated +/// slope. The resulting x and y coordinates are stored in an array. +/// \param pData Raw measurement data, as returned by TSD_GetRawMeasurement(). +/// \param pPoint Array in which x and y will be stored. +//------------------------------------------------------------------------------ +void TSDCom_InterpolateMeasurement(const unsigned int *pData, unsigned int *pPoint) +{ + pPoint[0] = calibrationPoints[0].x + - (((signed int) calibrationPoints[0].data[0] - (signed int) pData[0]) * 1024) + / xSlope; + + pPoint[1] = calibrationPoints[0].y + - (((signed int) calibrationPoints[0].data[1] - (signed int) pData[1]) * 1024) + / ySlope; + + if(pPoint[0] & 0x80000000) // Is pPoint[0] negative ? + { + pPoint[0] = 0; + } + + if(pPoint[0] > BOARD_LCD_WIDTH) // Is pPoint[0] bigger than the LCD width ? + { + pPoint[0] = BOARD_LCD_WIDTH; + } + + if(pPoint[1] & 0x80000000) // Is pPoint[1] negative ? + { + pPoint[1] = 0; + } + + if(pPoint[1] > BOARD_LCD_HEIGHT) // Is pPoint[1] bigger than the LCD width ? + { + pPoint[1] = BOARD_LCD_HEIGHT; + } +} + +//------------------------------------------------------------------------------ +/// Performs the calibration process using the provided buffer to display +/// information. +/// \param pLcdBuffer LCD buffer to display. +/// \return True if calibration was successful; otherwise false. +//------------------------------------------------------------------------------ +unsigned char TSDCom_Calibrate(void *pLcdBuffer) +{ +#ifdef AT91C_ID_LCDC + void *pOldLcdBuffer; +#endif + volatile unsigned int i; // to keep the tempo with gcc code optimisation + signed int slope1, slope2; + CalibrationPoint measuredPoint; + unsigned char xOk, yOk; + signed int xDiff, yDiff; + + // Calibration setup + LCDD_Fill(pLcdBuffer, COLOR_WHITE); + LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK); + LCDD_DrawString(pLcdBuffer, 1, 100, " Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE); +#ifdef AT91C_ID_LCDC + pOldLcdBuffer = LCDD_DisplayBuffer(pLcdBuffer); +#endif + + // Calibration points + for (i=0; i < 4; i++) { + + DrawCalibrationPoint(pLcdBuffer, &calibrationPoints[i]); + + // Wait for touch & end of conversion + TSD_WaitPenPressed(); + TSD_GetRawMeasurement(calibrationPoints[i].data); + ClearCalibrationPoint(pLcdBuffer, &calibrationPoints[i]); + + // Wait for contact loss + TSD_WaitPenReleased(); + } + + // Calculate slopes using the calibration data + // Theory behind those calculations: + // - We suppose the touchscreen measurements are linear, so the following equations are true (simple + // linear regression) for any two 'a' and 'b' points of the screen: + // dx = (a.data[0] - b.data[0]) / (a.x - b.x) + // dy = (a.data[1] - b.data[1]) / (a.y - b.y) + // + // - We calculate dx and dy (called xslope and yslope here) using the calibration points. + // + // - We can then use dx and dy to infer the position of a point 'p' given the measurements performed + // by the touchscreen ('c' is any of the calibration points): + // dx = (p.data[0] - c.data[0]) / (p.x - c.x) + // dy = (p.data[1] - c.data[1]) / (p.y - c.y) + // Thus: + // p.x = c.x - (p.data[0] - c.data[0]) / dx + // p.y = c.y - (p.data[1] - c.data[1]) / dy + // + // - Since there are four calibration points, dx and dy can be calculated twice, so we average + // the two values. + slope1 = ((signed int) calibrationPoints[0].data[0]) - ((signed int) calibrationPoints[1].data[0]); + slope1 *= 1024; + slope1 /= ((signed int) calibrationPoints[0].x) - ((signed int) calibrationPoints[1].x); + slope2 = ((signed int) calibrationPoints[2].data[0]) - ((signed int) calibrationPoints[3].data[0]); + slope2 *= 1024; + slope2 /= ((signed int) calibrationPoints[2].x) - ((signed int) calibrationPoints[3].x); + xSlope = (slope1 + slope2) / 2; + + slope1 = ((signed int) calibrationPoints[0].data[1]) - ((signed int) calibrationPoints[2].data[1]); + slope1 *= 1024; + slope1 /= ((signed int) calibrationPoints[0].y) - ((signed int) calibrationPoints[2].y); + slope2 = ((signed int) calibrationPoints[1].data[1]) - ((signed int) calibrationPoints[3].data[1]); + slope2 *= 1024; + slope2 /= ((signed int) calibrationPoints[1].y) - ((signed int) calibrationPoints[3].y); + ySlope = (slope1 + slope2) / 2; + + // Test point + LCDD_Fill(pLcdBuffer, 0xFFFFFF); + LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK); + LCDD_DrawString(pLcdBuffer, 1, 100, " Touch the point to\nvalidate calibration", COLOR_DARKBLUE); + DrawCalibrationPoint(pLcdBuffer, &testPoint); + + // Wait for touch & end of conversion + TSD_WaitPenPressed(); + + TSD_GetRawMeasurement(measuredPoint.data); + TSDCom_InterpolateMeasurement(measuredPoint.data, (unsigned int *) &measuredPoint); + DrawCalibrationPoint(pLcdBuffer, &measuredPoint); + + // Check resulting x and y + xDiff = (signed int) measuredPoint.x - (signed int) testPoint.x; + yDiff = (signed int) measuredPoint.y - (signed int) testPoint.y; + xOk = (xDiff >= -POINTS_MAX_ERROR) && (xDiff <= POINTS_MAX_ERROR); + yOk = (yDiff >= -POINTS_MAX_ERROR) && (yDiff <= POINTS_MAX_ERROR); + + // Wait for contact loss + TSD_WaitPenReleased(); + + // Check calibration result + if (xOk && yOk) { + + bCalibrationOk = 1; + LCDD_Fill(pLcdBuffer, COLOR_WHITE); + LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK); + LCDD_DrawString(pLcdBuffer, 80, 100, "Success !", COLOR_GREEN); + + } + else { + + bCalibrationOk = 0; + LCDD_Fill(pLcdBuffer, COLOR_WHITE); + LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK); + LCDD_DrawString(pLcdBuffer, 40, 100, "Error too big", COLOR_RED); + } + + // Slight delay + for (i = 0; i < DELAY_RESULT_DISPLAY; i++); + +#ifdef AT91C_ID_LCDC + // Restore old LCD buffer + LCDD_DisplayBuffer(pOldLcdBuffer); +#endif + + return (xOk && yOk); +} + +//------------------------------------------------------------------------------ +/// Read calibrate data to buffer. +/// \param pBuffer Data buffer. +/// \param size Size of data buffer in bytes. +//------------------------------------------------------------------------------ +void TSDCom_ReadCalibrateData(void *pBuffer, unsigned int size) +{ + unsigned char *pDest = (unsigned char *)pBuffer; + + SANITY_CHECK((sizeof(bCalibrationOk) + sizeof(xSlope) + + sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size); + + memcpy(pDest, (void const *)&bCalibrationOk, sizeof(bCalibrationOk)); + pDest += sizeof(bCalibrationOk); + memcpy(pDest, &xSlope, sizeof(xSlope)); + pDest += sizeof(xSlope); + memcpy(pDest, &ySlope, sizeof(ySlope)); + pDest += sizeof(ySlope); + memcpy(pDest, &calibrationPoints[0].data, sizeof(calibrationPoints[0].data)); + pDest += sizeof(calibrationPoints[0].data); +} + +//------------------------------------------------------------------------------ +/// Restore calibrate data with buffer data. +/// \param pBuffer Data buffer. +/// \param size Size of data buffer in bytes. +//------------------------------------------------------------------------------ +void TSDCom_RestoreCalibrateData(void *pBuffer, unsigned int size) +{ + unsigned char *pSrc = (unsigned char *)pBuffer; + + SANITY_CHECK((sizeof(bCalibrationOk) + sizeof(xSlope) + + sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size); + + memcpy((void *)&bCalibrationOk, pSrc, sizeof(bCalibrationOk)); + pSrc += sizeof(bCalibrationOk); + memcpy(&xSlope, pSrc, sizeof(xSlope)); + pSrc += sizeof(xSlope); + memcpy(&ySlope, pSrc, sizeof(ySlope)); + pSrc += sizeof(ySlope); + memcpy(&calibrationPoints[0].data, pSrc, sizeof(calibrationPoints[0].data)); + pSrc += sizeof(calibrationPoints[0].data); +} + diff --git a/drivers/tsd/tsd_com.h b/drivers/tsd/tsd_com.h new file mode 100644 index 0000000..91e99c6 --- /dev/null +++ b/drivers/tsd/tsd_com.h @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +#ifndef TSD_COM_H +#define TSD_COM_H + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +extern void TSDCom_InterpolateMeasurement( + const unsigned int *pData, + unsigned int *pPoint); + +unsigned char TSDCom_Calibrate(void *pLcdBuffer); + +unsigned char TSDCom_IsCalibrationOk(void); + +void TSDCom_ReadCalibrateData(void *pBuffer, unsigned int size); +void TSDCom_RestoreCalibrateData(void *pBuffer, unsigned int size); + +#endif //#ifndef TSD_COM_H diff --git a/drivers/tsd/tsd_tsadc.c b/drivers/tsd/tsd_tsadc.c new file mode 100644 index 0000000..bb9106a --- /dev/null +++ b/drivers/tsd/tsd_tsadc.c @@ -0,0 +1,269 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +#ifdef AT91C_BASE_TSADC + +#include "tsd.h" +#include "tsd_com.h" +#include +#include +#include +#include +#include +#include + +#include + +//------------------------------------------------------------------------------ +// Local definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Local types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Local variables +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// External functions +//------------------------------------------------------------------------------ + +extern void TSD_PenPressed(unsigned int x, unsigned int y); +extern void TSD_PenMoved(unsigned int x, unsigned int y); +extern void TSD_PenReleased(unsigned int x, unsigned int y); + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ +extern void TSD_GetRawMeasurement(unsigned int *pData); + +//------------------------------------------------------------------------------ +/// Interrupt handler for the TSADC. Handles pen press, pen move and pen release +/// events by invoking three callback functions. +//------------------------------------------------------------------------------ +static void InterruptHandler(void) +{ + unsigned int status; + unsigned int data[2]; + static unsigned int newPoint[2]; + static unsigned int point[2]; + static unsigned char report = 0; + + // Retrieve TADC status + // Bug fix: two step operation so IAR doesn't complain that the order of + // volatile access is unspecified. + status = AT91C_BASE_TSADC->TSADC_SR; + status &= AT91C_BASE_TSADC->TSADC_IMR; + + // Pen release + if ((status & AT91C_TSADC_NOCNT) == AT91C_TSADC_NOCNT) { + + // Invoke PenReleased callback + if(TSDCom_IsCalibrationOk()) { + TSD_PenReleased(point[0], point[1]); + } + + // Stop periodic trigger mode + TSADCC_SetDebounceTime(BOARD_TOUCHSCREEN_DEBOUNCE); + AT91C_BASE_TSADC->TSADC_IDR = AT91C_TSADC_EOC3 | AT91C_TSADC_NOCNT; + + TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PENDET_TRIGGER); + TSD_GetRawMeasurement(data); // Clear data registers + AT91C_BASE_TSADC->TSADC_SR; + AT91C_BASE_TSADC->TSADC_IER = AT91C_TSADC_PENCNT; + } + // Pen press + else if ((status & AT91C_TSADC_PENCNT) == AT91C_TSADC_PENCNT) { + + // Invoke PenPressed callback with (x,y) coordinates + while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_EOC3) != AT91C_TSADC_EOC3); + TSD_GetRawMeasurement(data); + TSDCom_InterpolateMeasurement(data, point); + + // Invoke PenPressed callback + if(TSDCom_IsCalibrationOk()) { + TSD_PenPressed(point[0], point[1]); + } + + // Configure TSADC for periodic trigger + TSADCC_SetDebounceTime(10); // 1ns + AT91C_BASE_TSADC->TSADC_IER = AT91C_TSADC_EOC3 | AT91C_TSADC_NOCNT; + AT91C_BASE_TSADC->TSADC_IDR = AT91C_TSADC_PENCNT; + TSADCC_SetTriggerPeriod(10000000); // 10ms + TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PERIODIC_TRIGGER); + report = 0; + } + // Pen move + else if ((status & AT91C_TSADC_EOC3) == AT91C_TSADC_EOC3) { + + // Invoke callback with LAST value measured + // Explanation: the very last value that will be measured (just as the + // pen is released) might be corrupted and there is no way to know. So + // we just discard it. + + if (report) { + + memcpy(point, newPoint, sizeof(newPoint)); + // Invoke PenMoved callback + if(TSDCom_IsCalibrationOk()) { + TSD_PenMoved(point[0], point[1]); + } + report = 0; + } + + TSD_GetRawMeasurement(data); + TSDCom_InterpolateMeasurement(data, newPoint); + if ((newPoint[0] != point[0]) || (newPoint[1] != point[1])) { + + report = 1; + } + } +} + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Reads and store a touchscreen measurement in the provided array. +/// The value stored are: +/// - data[0] = CDR3 * 1024 / CDR2 +/// - data[1] = CDR1 * 1024 / CDR0 +/// \param pData Array where the measurements will be stored +//------------------------------------------------------------------------------ +void TSD_GetRawMeasurement(unsigned int *pData) +{ + pData[0] = (AT91C_BASE_TSADC->TSADC_CDR3 * 1024); + pData[0] /= AT91C_BASE_TSADC->TSADC_CDR2; + pData[1] = (AT91C_BASE_TSADC->TSADC_CDR1 * 1024); + pData[1] /= AT91C_BASE_TSADC->TSADC_CDR0; +} + +//------------------------------------------------------------------------------ +/// Wait pen pressed +//------------------------------------------------------------------------------ +void TSD_WaitPenPressed(void) +{ + // Wait for touch & end of conversion + while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_PENCNT) != AT91C_TSADC_PENCNT); + while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_EOC3) != AT91C_TSADC_EOC3); +} + +//------------------------------------------------------------------------------ +/// Wait pen released +//------------------------------------------------------------------------------ +void TSD_WaitPenReleased(void) +{ + // Wait for contact loss + while ((AT91C_BASE_TSADC->TSADC_SR & AT91C_TSADC_NOCNT) != AT91C_TSADC_NOCNT); +} + +//------------------------------------------------------------------------------ +/// Do calibration +/// \param pLcdBuffer LCD buffer to use for displaying the calibration info. +/// \return 1 if calibration is Ok, 0 else +//------------------------------------------------------------------------------ +unsigned char TSD_Calibrate(void *pLcdBuffer) +{ + unsigned char ret = 0; + + // Calibration is done only once + if(TSDCom_IsCalibrationOk()) { + return 1; + } + + // Enable trigger + TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PENDET_TRIGGER); + + // Do calibration + ret = TSDCom_Calibrate(pLcdBuffer); + + // Disable trigger + TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_NO_TRIGGER); + + // Configure interrupt generation + // Do it only if the calibration is Ok. + if(ret) { + TSADCC_SetTriggerMode(AT91C_TSADC_TRGMOD_PENDET_TRIGGER); + IRQ_ConfigureIT(AT91C_ID_TSADC, 0, InterruptHandler); + IRQ_EnableIT(AT91C_ID_TSADC); + AT91C_BASE_TSADC->TSADC_IER = AT91C_TSADC_PENCNT; + } + + return ret; +} + +//------------------------------------------------------------------------------ +/// Initializes the touchscreen driver and starts the calibration process. When +/// finished, the touchscreen is operational. +/// The configuration is taken from the board.h of the device being compiled. +/// +/// Important: the LCD driver must have been initialized prior to calling this +/// function. +/// \param pLcdBuffer LCD buffer to use for displaying the calibration info. +//------------------------------------------------------------------------------ +void TSD_Initialize(void *pLcdBuffer) +{ + const Pin pins[] = {PINS_TSADCC}; + + // Configuration + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TSADC; + PIO_Configure(pins, PIO_LISTSIZE(pins)); + TSADCC_SetOperatingMode(AT91C_TSADC_TSAMOD_TS_ONLY_MODE); + TSADCC_SetPenDetect(1); + TSADCC_SetAdcFrequency(BOARD_TOUCHSCREEN_ADCCLK, BOARD_MCK); + TSADCC_SetStartupTime(BOARD_TOUCHSCREEN_STARTUP); + TSADCC_SetTrackAndHoldTime(BOARD_TOUCHSCREEN_SHTIM); + TSADCC_SetDebounceTime(BOARD_TOUCHSCREEN_DEBOUNCE); + + // Do calibration if the LCd buffer is not a null pointer + if(pLcdBuffer) { + // Calibration + while (!TSD_Calibrate(pLcdBuffer)); + } +} + +//------------------------------------------------------------------------------ +/// Reset/stop the touchscreen +//------------------------------------------------------------------------------ +void TSD_Reset(void) +{ + IRQ_DisableIT(AT91C_ID_TSADC); + AT91C_BASE_PMC->PMC_PCDR = 1 << AT91C_ID_TSADC; +} + +#endif //#ifdef AT91C_BASE_TSADC -- cgit v1.2.3