mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
318 lines
9.1 KiB
C
318 lines
9.1 KiB
C
/* ----------------------------------------------------------------------------
|
|
* ATMEL Microcontroller Software Support
|
|
* ----------------------------------------------------------------------------
|
|
* Copyright (c) 2009, 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.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* Implementation of ADS7843 driver.
|
|
*/
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Headers
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#include "board.h"
|
|
|
|
#ifdef BOARD_TSC_ADS7843
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Definitions
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
/** Delay for pushbutton debouncing (the time-base is 10 ms). */
|
|
#define DEBOUNCE_TIME 6 /* 10 * 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
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* 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 const Pin pinPenIRQ = PIN_TSC_IRQ;
|
|
|
|
/** Global timestamp in milliseconds since start of application. */
|
|
static volatile uint32_t timestamp = 0;
|
|
|
|
/** last time when the pen is pressed on the touchscreen */
|
|
static volatile uint32_t timePress = 0;
|
|
|
|
/** last time when the pen is released */
|
|
static volatile uint32_t timeRelease = 0;
|
|
|
|
/** pen state */
|
|
static volatile e_pen_state penState = STATE_PEN_RELEASED;
|
|
|
|
/** Touch screen initiallized flag */
|
|
static uint32_t tsInitFlag = 0;
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Local functions
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \brief 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.
|
|
*
|
|
* \note External timer interrupt should call it per 10ms.
|
|
*/
|
|
void TSD_TimerHandler( void )
|
|
{
|
|
uint32_t data[2];
|
|
uint32_t timeKeep;
|
|
static uint32_t 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 )
|
|
{
|
|
timeKeep = timestamp;
|
|
timeKeep -= timePress;
|
|
if(timeKeep > 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 )
|
|
{
|
|
timeKeep = timestamp;
|
|
timeKeep -= timeRelease;
|
|
if ( timeKeep > 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]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \breif 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Configure PENIRQ for interrupt.
|
|
*
|
|
* \note Be sure the PIO interrupt management has been initialized by
|
|
* PIO_InitializeInterrupts() before call this function.
|
|
*/
|
|
static void ConfigurePenIRQ( void )
|
|
{
|
|
/* Configure pios */
|
|
PIO_Configure(&pinPenIRQ, PIO_LISTSIZE(pinPenIRQ));
|
|
|
|
/* Initialize interrupts */
|
|
PIO_ConfigureIt(&pinPenIRQ, (void (*)(const Pin *)) ISR_PenIRQ);
|
|
|
|
/* Enable the interrupt */
|
|
PIO_EnableIt(&pinPenIRQ);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Exported functions
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \brief Reads and store a touchscreen measurement in the provided array.
|
|
*
|
|
* \param pData Array where the measurements will be stored
|
|
*/
|
|
extern void TSD_GetRawMeasurement( uint32_t* pdwData )
|
|
{
|
|
/* Get the current position of the pressed pen */
|
|
PIO_DisableIt( &pinPenIRQ ) ;
|
|
ADS7843_GetPosition( &pdwData[0], &pdwData[1] ) ;
|
|
PIO_EnableIt( &pinPenIRQ ) ;
|
|
}
|
|
|
|
/**
|
|
* \brief Wait pen pressed.
|
|
*/
|
|
extern void TSD_WaitPenPressed( void )
|
|
{
|
|
/* Wait for touch & end of conversion */
|
|
while ( penState != STATE_PEN_RELEASED ) ;
|
|
|
|
/* while (penState != STATE_PEN_PRESSED); */
|
|
while ( penState != STATE_PEN_PRESSED )
|
|
{
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Wait pen released.
|
|
*/
|
|
extern void TSD_WaitPenReleased( void )
|
|
{
|
|
/* Wait for contact loss */
|
|
while (penState != STATE_PEN_PRESSED);
|
|
while (penState != STATE_PEN_RELEASED);
|
|
}
|
|
|
|
/**
|
|
* \brief Do calibration.
|
|
*
|
|
* \return 1 if calibration is Ok, 0 else.
|
|
*/
|
|
extern uint8_t TSD_Calibrate( void )
|
|
{
|
|
uint8_t ret = 0 ;
|
|
|
|
/* Calibration is done only once */
|
|
if ( TSDCom_IsCalibrationOk() )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/* Do calibration */
|
|
ret = TSDCom_Calibrate();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* \brief Initializes the touchscreen driver and starts the calibration process. When
|
|
* finished, the touchscreen is operational.
|
|
*
|
|
* \note Important: the LCD driver must have been initialized prior to calling this
|
|
* function.
|
|
*/
|
|
extern void TSD_Initialize( int8_t calEn )
|
|
{
|
|
ADS7843_Initialize();
|
|
ConfigurePenIRQ();
|
|
|
|
tsInitFlag = 1;
|
|
|
|
/* Calibration */
|
|
if(calEn) {
|
|
while (!TSD_Calibrate());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Stop the Touchscreen, disable interrupt.
|
|
*/
|
|
extern void TSD_Reset( void )
|
|
{
|
|
/* Disable SPI 0 */
|
|
ADS7843_Reset() ;
|
|
|
|
/* Disable the interrupt */
|
|
PIO_DisableIt( &pinPenIRQ ) ;
|
|
}
|
|
|
|
#endif /* #ifdef BOARD_TSC_ADS7843 */
|