⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsc2046.c

📁 NXPl788上lwip的无操作系统移植,基于Embest开发板
💻 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 + -