sdk7a400_ts_driver.c
来自「Sharp LH7A400 BSP平台无关部分的代码,有很高的参考价值,尤其是系」· C语言 代码 · 共 622 行 · 第 1/2 页
C
622 行
/***********************************************************************
* $Workfile: sdk7a400_ts_driver.c $
* $Revision: 1.2 $
* $Author: WellsK $
* $Date: Apr 26 2004 15:31:18 $
*
* Project: SDK7A400 Touchscreen driver
*
* Description:
* This file contains driver support for the Touchscreen
* interface on the SDK7A400 EVB.
*
* Notes:
* There are 2 ways to operate this driver defined below:
* POLLED MODE (easiest to implement):
* In this mode, the touchscreen controller is completely
* polled. The pen down status of the ADS7843 chip is used to
* determine if a touchscreen event occured.
* PENDOWN INTERRUPT MODE (Best response):
* This mode will provide the snappiest response to a pendown
* event on the touchscreen. In this mode, when the touchscreen
* is touched, a pendown event will trigger a pendown interrupt.
* The pendown interrupt will get the touchscreen data from
* the AD7843 touchscreen controller. A user defined function
* can be specified to be called when the data has been
* received.
* After a sample is converted and read, the interrupt needs to be
* reset before another sample can be read (or another interrupt can
* occur). Use the TS_ENABLE_INT ioctl argument to re-enable the
* interrupt after reading a sample. This is needed to slow down
* the sample rate during interrupt mode.
*
* The touchscreen interrupt is shared with the ethernet interrupt
* and should not be called directly by the interrupt router.
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a400/bsps/sdk7a400/source/sdk7a400_ts_driver.c-arc $
*
* Rev 1.2 Apr 26 2004 15:31:18 WellsK
* Updated touchscreen controller read logic with various fixes.
* Added multiple reads to improve accuracy.
*
* Rev 1.1 Mar 12 2004 15:37:18 WellsK
* Various corrections to interface logic.
*
* Rev 1.0 Dec 03 2003 13:52:12 WellsK
* Initial revision.
*
*
***********************************************************************
* SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
* OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
* AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
* SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
*
* SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
* FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
* SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
* FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
**********************************************************************/
#include "sdk7a400_ts_driver.h"
#include "sdk7a400_cpld_driver.h"
/***********************************************************************
* Touchscreen driver private data and types
**********************************************************************/
/* ADS7843 command Start bit */
#define TSC_START 0x80
/* ADS7843 command X measure request */
#define TSC_MEASURE_X 0x10
/* ADS7843 command y measure request */
#define TSC_MEASURE_Y 0x50
/* ADS7843 command differential measurement request */
#define TSC_DIFF 0x00
/* ADS7843 command single-ended measurement request */
#define TSC_SINGLE 0x04
/* ADS7843 command 12-bit conversion request */
#define TSC_CONVBITS 0x00
/* ADS7843 command power down between conversion request */
#define TSC_PDBC 0x00
/* ADS7843 command PEN interrupt enable request */
#define TSC_NOPENIRQ 0x01
/* ADS7843 command power stays on between conversion request */
#define TSC_PDON 0x03
/* SPI data register macro */
#define SPIDATA * (volatile UNS_16 *) SPIDAT_REG_BASE
/* SPI control register macro */
#define SPICON * (volatile UNS_16 *) SPICON_REG_BASE
/* Size of touchscreen driver data queue */
#define TSQ_SIZE 8
/* Touchscreen configuration structure type */
typedef struct
{
BOOL_32 init; /* Driver initialized/open flag */
PFV tscb_func; /* Pointer to touchscreen callback function
that is called when a interrupt is
complete */
INT_32 rx_head; /* Receive queue head pointer */
INT_32 rx_tail; /* Receive queue tail pointer */
TS_DATA_T queue[TSQ_SIZE]; /* Touchscreen data queue */
} TS_CFG_T;
/* Touchscreen configuration driver data */
STATIC TS_CFG_T tscfg;
/* Dummy read function - this function is needed between consecutive
reads or writes of data on the CPLD SPI interface so the nCS and
nOE signals strobe. Important note: This address must point to a
valid uncached address in external memory so the chip is forced
to deassert nCS and nOE between consecutive reads. */
#define DUMMY_RD {volatile UNS_16 dmy = * (UNS_16 *) 0x00000000; \
(void) dmy;}
/***********************************************************************
* Touchscreen driver private functions
**********************************************************************/
/***********************************************************************
*
* Function: ts_command
*
* Purpose: Issue a touchscreen controller command
*
* Processing:
* This function is used to read a touchscreen controller value
* and is based on the programming sequence detailed in the LPD
* hardware I/O specification.
*
* Parameters:
* cmd: Touchscreen command to perform
*
* Outputs: None
*
* Returns: The value read from the touchscreen controller
*
* Notes: None
*
**********************************************************************/
UNS_16 ts_command(UNS_16 cmd)
{
UNS_16 temphi, templo, temp;
/* Issue command to the touchscreen controller via the CPLD SPI
interface */
SPIDATA = SPIDAT_DATA(cmd);
SPICON = (SPICON_TOUCH_SEL | SPICON_START);
/* Wait until word has been loaded into the SPI register */
while ((SPICON & SPICON_LOAD_DONE) == 0)
{
DUMMY_RD
}
/* Wait for data to return from controller */
SPICON = SPICON_TOUCH_SEL;
while ((SPICON & SPICON_ACCESS_DONE) == 0)
{
DUMMY_RD
}
/* Strobe SPI and wait for data to load */
SPICON = (SPICON_TOUCH_SEL | SPICON_READ_SEL | SPICON_START);
DUMMY_RD
while ((SPICON & SPICON_LOAD_DONE) == 0)
{
DUMMY_RD
}
SPICON = (SPICON_TOUCH_SEL | SPICON_READ_SEL);
DUMMY_RD
while ((SPICON & SPICON_ACCESS_DONE) == 0)
{
DUMMY_RD
}
/* Get upper 7 bits of data from SPI */
DUMMY_RD
temphi = SPIDATA;
/* Strobe SPI and wait for data to load */
SPICON = (SPICON_TOUCH_SEL | SPICON_READ_SEL | SPICON_START);
DUMMY_RD
while ((SPICON & SPICON_LOAD_DONE) == 0)
{
DUMMY_RD
}
SPICON = (SPICON_TOUCH_SEL | SPICON_READ_SEL);
DUMMY_RD
while ((SPICON & SPICON_ACCESS_DONE) == 0)
{
DUMMY_RD
}
/* Get lower 5 bits of data from SPI */
DUMMY_RD
templo = SPIDATA;
/* Deselect touchscreen */
SPICON = 0;
/* Justify and mask word to make raw coordinate data */
temp = ((temphi & 0x007F) << 5) | ((templo & 0x00F8) >> 3);
return temp;
}
/***********************************************************************
*
* Function: ts_sample_data
*
* Purpose: Sample the touchscreen data
*
* Processing:
* Check the status of the touchscreen controller interrupt. If it
* is not pending, set the current queue pendown state entry to
* FALSE. If the interrupt is pending, get the current X and Y
* coorindates by calling the ts_command function. Disable the
* touchscreen controller interrupt in the CPLD. Increment the
* queue head pointer. If the head pointer exceeds the size of the
* queue, reset the head pointer to 0.
*
* Parameters:
* tscptr: Pointer to the touchscreen configuration structure
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void ts_sample_data(TS_CFG_T *tscptr)
{
volatile UNS_16 tmp;
/* Place pendown state first in queue first */
if (cpld_ts_int_pending() == TRUE)
{
/* Clear pendown interrupt per LPD sequence */
* (volatile UNS_16 *) INTMSK_REG_BASE =
* (volatile UNS_16 *) INTMSK_REG_BASE & ~INTMSK_PENIRQ_IN;
/* Get X coordinate a few times - the first few coordinates
allow for more settling time */
tmp = ts_command(TSC_START |
TSC_MEASURE_X | TSC_DIFF | TSC_CONVBITS | TSC_PDON);
tmp = ts_command(TSC_START |
TSC_MEASURE_X | TSC_DIFF | TSC_CONVBITS | TSC_PDON);
tscptr->queue[tscptr->rx_head].xraw = ts_command(TSC_START |
TSC_MEASURE_X | TSC_DIFF | TSC_CONVBITS | TSC_PDON);
/* Get Y coordinate a few times - the first few coordinates
allow for more settling time */
tmp = ts_command(TSC_START |
TSC_MEASURE_Y | TSC_DIFF | TSC_CONVBITS | TSC_PDON);
tmp = ts_command(TSC_START |
TSC_MEASURE_Y | TSC_DIFF | TSC_CONVBITS | TSC_PDON);
tscptr->queue[tscptr->rx_head].yraw = ts_command(TSC_START |
TSC_MEASURE_Y | TSC_DIFF | TSC_CONVBITS | TSC_PDBC);
tscptr->queue[tscptr->rx_head].pendown = TRUE;
/* Clear pendown interrupt per LPD sequence */
* (volatile UNS_16 *) INTMSK_REG_BASE =
* (volatile UNS_16 *) INTMSK_REG_BASE | INTMSK_PENIRQ_IN;
/* Disable interrupt in CPLD - this is performed here so the
interrupt won't go 'wild' and continuously request service.
The interrupt needs to be turned back on later, preferrably
at some predefined rate of time (ie, 100Hz). */
cpld_ts_int_enable(FALSE);
}
else
{
tscptr->queue[tscptr->rx_head].pendown = FALSE;
}
/* Increment head pointer for the queue and bound it */
tscptr->rx_head++;
if (tscptr->rx_head >= TSQ_SIZE)
{
tscptr->rx_head = 0;
}
}
/***********************************************************************
* Touchscreen driver public functions
**********************************************************************/
/***********************************************************************
*
* Function: ts_open
*
* Purpose: Open the touchscreen interface
*
* Processing:
* If init is not FALSE, return NULL to the caller. Otherwise, set
* init to TRUE, initialize the touchscreen data queues, disable
* the touchscreen interrupt, and set the default callback function
* pointer to NULL. Call the ts_sample_data function to set
* up the initial state of the ADS7843 device. Return a pointer to
* the touchscreen config structure to the caller.
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?