📄 tsc2046.c
字号:
/**********************************************************************
* $Id$ tsc2046.c 2012-03-13
*//**
* @file tsc2046.c
* @brief Contains all functions to control TSC2046 using SPI
* @version 1.0
* @date 13. March. 2012
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, NXP Semiconductor
* All rights reserved.
*
***********************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
**********************************************************************/
#include "bsp.h"
#ifdef __BUILD_WITH_EXAMPLE__
#include "lpc177x_8x_libcfg.h"
#else
#include "lpc177x_8x_libcfg_default.h"
#endif /* __BUILD_WITH_EXAMPLE__ */
#if (_CUR_USING_LCD == _RUNNING_LCD_QVGA_TFT)
#ifdef _SSP
#include "LPC177x_8x.h"
#include "lpc177x_8x_ssp.h"
#include "lpc177x_8x_pinsel.h"
#include "lpc177x_8x_gpio.h"
#include "tsc2046.h"
#include "bsp.h"
#if (TSC2046_CONVERSION_BITS == 12)
#define TSC2046_X_COORD_MAX (0xFFF)
#define TSC2046_Y_COORD_MAX (0xFFF)
#define TSC2046_DELTA_X_VARIANCE (0x50)
#define TSC2046_DELTA_Y_VARIANCE (0x50)
#else
#define TSC2046_X_COORD_MAX (0xFF)
#define TSC2046_Y_COORD_MAX (0xFF)
#define TSC2046_DELTA_X_VARIANCE (0x05)
#define TSC2046_DELTA_Y_VARIANCE (0x05)
#endif
#define COORD_GET_NUM (3)
/** SSP Configuration */
#define TSC2046_SSP_PORT (LPC_SSP0)
#define TSC2046_CS_PORT_NUM (LCD_CS_PORT_NUM)
#define TSC2046_CS_PIN_NUM (LCD_CS_PIN_NUM)
#define CS_ON (GPIO_ClearValue(TSC2046_CS_PORT_NUM, (1<<TSC2046_CS_PIN_NUM)))
#define CS_OFF (GPIO_SetValue(TSC2046_CS_PORT_NUM, (1<<TSC2046_CS_PIN_NUM)))
/** Local variables */
static uint16_t X_Points[COORD_GET_NUM];
static uint16_t Y_Points[COORD_GET_NUM];
static TSC2046_Init_Type TSC_Config;
/*********************************************************************//**
* @brief Enable Touch Screen Controller.
* @param[in] None
* @return None
**********************************************************************/
static void EnableTS(void)
{
uint8_t cmd;
SSP_DATA_SETUP_Type sspCfg;
#if (TSC2046_CONVERSION_BITS == 8)
cmd = START_BIT | CHANNEL_SELECT(Y_MEASURE)|CONVERT_MODE_8_BITS|DFR_MODE|PD_ENABLED;
#else
cmd = START_BIT | CHANNEL_SELECT(Y_MEASURE)|CONVERT_MODE_12_BITS|DFR_MODE|PD_ENABLED;
#endif
sspCfg.tx_data = &cmd;
sspCfg.rx_data = NULL;
sspCfg.length = 1;
CS_ON;
SSP_ReadWrite (TSC2046_SSP_PORT, &sspCfg, SSP_TRANSFER_POLLING);
CS_OFF;
}
/*********************************************************************//**
* @brief Initialize TSC2046.
* @param[in] pConfig TSC Configuration
* @return None
**********************************************************************/
void InitTSC2046(TSC2046_Init_Type *pConfig)
{
SSP_CFG_Type SSP_ConfigStruct;
// PIN config SSP
PINSEL_ConfigPin(0, 15, 2);
//PINSEL_ConfigPin(0, 16, 2); // Use another pin for CS
PINSEL_ConfigPin(0, 17, 2);
PINSEL_ConfigPin(0, 18, 2);
PINSEL_ConfigPin(TSC2046_CS_PORT_NUM, TSC2046_CS_PIN_NUM, 0);
GPIO_SetDir(TSC2046_CS_PORT_NUM,(1<<TSC2046_CS_PIN_NUM),1);
// initialize SSP configuration structure to default
SSP_ConfigStructInit(&SSP_ConfigStruct);
// set clock rate
SSP_ConfigStruct.ClockRate = TSC2046_SSP_CLOCK;
SSP_ConfigStruct.CPHA = SSP_CPHA_SECOND;
SSP_ConfigStruct.CPOL = SSP_CPOL_LO;
// Initialize SSP peripheral with parameter given in structure above
SSP_Init(TSC2046_SSP_PORT, &SSP_ConfigStruct);
// Enable SSP peripheral
SSP_Cmd(TSC2046_SSP_PORT, ENABLE);
// Enable Touch Screen Controller
EnableTS();
TSC_Config = *pConfig;
}
/*********************************************************************//**
* @brief Send/Receive data to/from TSC2046.
* @param[in] channel It should be
* X_MEASURE
* Y_MEASURE
* Z1_MEASURE
* Z2_MEASURE
* @param[out] data Received data
* @return None
**********************************************************************/
static void ReadWriteTSC2046(uint8_t channel, uint16_t* data)
{
uint8_t cmd;
uint32_t tmp;
SSP_DATA_SETUP_Type sspCfg;
uint8_t first, second;
CS_ON;
#if (TSC2046_CONVERSION_BITS == 8)
cmd = START_BIT | CHANNEL_SELECT(channel)|CONVERT_MODE_8_BITS|DFR_MODE|REF_OFF_ADC_ON;
#else
cmd = START_BIT | CHANNEL_SELECT(channel)|CONVERT_MODE_12_BITS|DFR_MODE|REF_OFF_ADC_ON;
#endif
sspCfg.tx_data = &cmd;
sspCfg.rx_data = NULL;
sspCfg.length = 1;
SSP_ReadWrite (TSC2046_SSP_PORT, &sspCfg, SSP_TRANSFER_POLLING);
for(tmp = 0x100; tmp;tmp--);
// Read High byte
sspCfg.tx_data = NULL;
sspCfg.rx_data = &first;
sspCfg.length = 1;
SSP_ReadWrite (TSC2046_SSP_PORT, &sspCfg, SSP_TRANSFER_POLLING);
for(tmp = 0x10; tmp;tmp--);
// Read Low byte
sspCfg.tx_data = NULL;
sspCfg.rx_data = &second;
sspCfg.length = 1;
SSP_ReadWrite (TSC2046_SSP_PORT, &sspCfg, SSP_TRANSFER_POLLING);
#if (TSC2046_CONVERSION_BITS == 8)
*data = (((first&0x7F) <<8) | (second>>0)) >> 7;
#else
*data = (((first&0x7F) <<8) | (second>>0)) >> 3;
#endif
CS_OFF;
for(tmp = 0x10; tmp;tmp--);
}
/*********************************************************************//**
* @brief Evaluate the coords received from TSC.
* @param[in] pPoints list of coords
* @param[in] PointNum the number of entries in above list
* @param[in] MaxVal the maximum value of a coord
* @param[in] MaxDelta the maximum delta between coords
* @return -1: Invalid coords, coord in case it is valid.
**********************************************************************/
static int16_t EvalCoord(uint16_t* pPoints, uint32_t PointNum, uint16_t MaxVal, uint16_t MaxDelta)
{
uint32_t i;
int16_t diff = 0, coord = 0;
for(i = 0; i < PointNum; i++)
{
if(pPoints[i] > MaxVal)
return -1;
if(i > 0)
diff = pPoints[i] - pPoints[i-1];
if(diff < 0)
diff = 0 - diff;
if(diff > MaxDelta)
return -1;
coord += pPoints[i];
}
return coord/PointNum;
}
/*********************************************************************//**
* @brief convert the coord received from TSC to a value on truly LCD.
* @param[in] Coord received coord
* @param[in] MinVal the minimum value of a coord
* @param[in] MaxVal the maximum value of a coord
* @param[in] TrueSize the size on LCD
* @return the coord after converting.
**********************************************************************/
static int16_t ConvertCoord(int16_t Coord, int16_t MinVal, int16_t MaxVal, int16_t TrueSize)
{
int16_t tmp;
int16_t ret;
uint8_t convert = 0;
if(MinVal > MaxVal) // Swap value
{
tmp = MaxVal;
MaxVal = MinVal;
MinVal = tmp;
convert = 1;
}
ret = (Coord - MinVal)*TrueSize/(MaxVal-MinVal);
if(convert)
ret = TrueSize - ret;
return ret;
}
/*********************************************************************//**
* @brief Get Touch coordinates.
* @param[out] pX X-Coord
* @param[out] pY Y-Coord
* @return None
**********************************************************************/
void GetTouchCoord(int16_t *pX, int16_t* pY)
{
uint16_t i, tmp;
int16_t coord, x=-1, y=-1;
coord = 0;
// Get X-Coordinate
for(i = 0; i < COORD_GET_NUM; i++)
{
ReadWriteTSC2046(X_MEASURE,&tmp);
X_Points[i] = tmp;
}
coord = EvalCoord(X_Points,COORD_GET_NUM,TSC2046_X_COORD_MAX,TSC2046_DELTA_X_VARIANCE);
if(coord > 0)
x = coord;
// Get Y-Coordinate
for(i = 0; i < COORD_GET_NUM; i++)
{
ReadWriteTSC2046(Y_MEASURE,&tmp);
Y_Points[i] = tmp;
}
coord = EvalCoord(Y_Points,COORD_GET_NUM,TSC2046_Y_COORD_MAX,TSC2046_DELTA_Y_VARIANCE);
if(coord > 0)
y = coord;
// Swap, adjust to truly size of LCD
if((x >= 0) && (y >= 0))
{
if(TSC_Config.swap_xy)
{
*pY = ConvertCoord(x,TSC_Config.ad_top,TSC_Config.ad_bottom,TSC_Config.lcd_v_size);
*pX = ConvertCoord(y,TSC_Config.ad_left,TSC_Config.ad_right,TSC_Config.lcd_h_size);
}
else
{
*pX = ConvertCoord(x,TSC_Config.ad_top,TSC_Config.ad_bottom,TSC_Config.lcd_v_size);
*pY = ConvertCoord(y,TSC_Config.ad_left,TSC_Config.ad_right,TSC_Config.lcd_h_size);
}
}
}
#endif
#endif /*_CUR_USING_LCD == _RUNNING_LCD_QVGA_TFT)*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -