📄 gui_touch_driveranalog.c
字号:
/*
*********************************************************************************************************
* uC/GUI
* Universal graphic software for embedded applications
*
* (c) Copyright 2002, Micrium Inc., Weston, FL
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
* 礐/GUI is protected by international copyright laws. Knowledge of the
* source code may not be used to write a similar product. This file may
* only be used in accordance with a license and should not be redistributed
* in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File : GUITOUCH.C
Purpose : Touch screen manager
----------------------------------------------------------------------
This module handles the touch screen. It is configured in the file
GUITouch.conf.h (Should be located in the Config\ directory).
----------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LCD_Private.h" /* private modul definitions & config */
#include "GUI_Protected.h"
/* Generate code only if configuration says so ! */
#if GUI_SUPPORT_TOUCH
#include "GUITouchconf.h" /* Located in GUIx, will include GUITouch.conf.h */
#include "44b.h"
/*
**********************************************************************
*
* Config defaults
*
**********************************************************************
*/
#ifndef GUI_TOUCH_AD_LEFT /* max value returned by AD-converter */
#define GUI_TOUCH_AD_LEFT 30
#endif
#ifndef GUI_TOUCH_AD_RIGHT /* min value returned by AD-converter */
#define GUI_TOUCH_AD_RIGHT 220
#endif
#ifndef GUI_TOUCH_AD_TOP /* max value returned by AD-converter */
#define GUI_TOUCH_AD_TOP 30
#endif
#ifndef GUI_TOUCH_AD_BOTTOM /* min value returned by AD-converter */
#define GUI_TOUCH_AD_BOTTOM 220
#endif
#ifndef GUI_TOUCH_SWAP_XY /* Is XY of touch swapped ? */
#define GUI_TOUCH_SWAP_XY 0
#endif
#ifndef GUI_TOUCH_MIRROR_X
#define GUI_TOUCH_MIRROR_X 0
#endif
#ifndef GUI_TOUCH_MIRROR_Y
#define GUI_TOUCH_MIRROR_Y 0
#endif
#ifndef GUI_TOUCH_YSIZE
#define GUI_TOUCH_YSIZE LCD_YSIZE
#endif
#ifndef GUI_TOUCH_XSIZE
#define GUI_TOUCH_XSIZE LCD_XSIZE
#endif
/*********************************************************************
*
* Config check
*
**********************************************************************
*/
/****************************************************************
*
* Static data
*
*****************************************************************
*/
typedef struct {int Min; int Max; } tMinMax;
static int xPhys, yPhys;
static tMinMax xyMinMax[2] = {
#if ((GUI_TOUCH_SWAP_XY==0) && (GUI_TOUCH_MIRROR_X==0)) || ((GUI_TOUCH_SWAP_XY) && (GUI_TOUCH_MIRROR_Y==0))
{ GUI_TOUCH_AD_LEFT, GUI_TOUCH_AD_RIGHT },
#else
{ GUI_TOUCH_AD_RIGHT, GUI_TOUCH_AD_LEFT },
#endif
#if ((GUI_TOUCH_SWAP_XY==0) && (GUI_TOUCH_MIRROR_Y==0)) || ((GUI_TOUCH_SWAP_XY) && (GUI_TOUCH_MIRROR_X==0))
{ GUI_TOUCH_AD_TOP, GUI_TOUCH_AD_BOTTOM }
#else
{ GUI_TOUCH_AD_BOTTOM, GUI_TOUCH_AD_TOP }
#endif
};
#ifndef WIN32
static int xMin;
static int xMax;
static int yMin;
static int yMax;
#endif
/**********************************************************
*
*
*/
void TOUCH_X_ActivateY(void){
int delaytime=10 ;
rADCPSR=21;
rPUPE=0x0ff;
rPCONE=((rPCONE & 0x300FF) | 0x0500); /* PE5,4 OUT, 7,6 INPUT */
rPDATE= 0x10; /* PE4, high, PE5 low */
for( ; delaytime<1; delaytime-- ) ; /* AN0 input x+ AN0 ADC */
}
int TOUCH_X_MeasureY(void){
int i;//,sum;
// rADCPSR=20;
//rADCCON=0x0|(0x05<<2); //setup channel.
//for(i=0;i<4;i++) //min. 15us
//{
rADCCON=0x1|(0x02<<2); //Start A/D conversion
while(rADCCON &0x1); //To avoid The first FLAG error case.
//(The START bit is cleared in one ADC clock.)
while(!(rADCCON & 0x40));
for(i=0;i<10;i++); //To avoid The second FLAG error case
// sum+=(rADCDAT&0x3ff);
// }
//return (sum/i);
return (rADCDAT&0x3ff);
}
void TOUCH_X_ActivateX(void){
int delaytime=10 ;
rADCPSR=21;
rPUPE=0x0ff;
rPCONE=((rPCONE & 0x00FF) | 0x5000); /* PE7,6 OUT, 5,4 INPUT */
rPDATE= 0x40; /* PE7, low, PE6 high */
for( ; delaytime<1; delaytime-- ) ; /* AN0 input Y+ /AN1 ADC */
}
int TOUCH_X_MeasureX(void){
int i;//sum;
//rADCCON=0x0|(0x03<<2); //setup channel
//for(i=0;i<4;i++); //min. 15us
// {
rADCCON=0x1|(0x03<<2); //Start A/D conversion
while(rADCCON &0x1); //To avoid The first FLAG error case.
//(The START bit is cleared in one ADC clock.)
while(!(rADCCON & 0x40));
for(i=0;i<10;i++); //To avoid The second FLAG error case
//sum+=(rADCDAT&0x3ff);
// }
//return (sum/i);
return (rADCDAT&0x3ff);
}
/*********************************************************************
*
* Convert physical value into (logical) coordinates
*/
int AD2X(int adx) {
I32 r = adx - xyMinMax[GUI_COORD_X].Min;
r *= GUI_TOUCH_XSIZE - 1;
return r / (xyMinMax[GUI_COORD_X].Max - xyMinMax[GUI_COORD_X].Min);
}
int AD2Y(int ady) {
I32 r = ady - xyMinMax[GUI_COORD_Y].Min;
r *= GUI_TOUCH_YSIZE - 1;
return r/(xyMinMax[GUI_COORD_Y].Max - xyMinMax[GUI_COORD_Y].Min);
}
/*********************************************************************
*
* Diagnostic routines
*/
int GUI_TOUCH_GetxPhys(void) {
return xPhys;
}
int GUI_TOUCH_GetyPhys(void) {
return yPhys;
}
/*********************************************************************
*
* SetDefaultCalibration
*/
void GUI_TOUCH_SetDefaultCalibration(void) {
xyMinMax[0].Min = GUI_TOUCH_AD_LEFT;
xyMinMax[0].Max = GUI_TOUCH_AD_RIGHT;
xyMinMax[1].Min = GUI_TOUCH_AD_TOP;
xyMinMax[1].Max = GUI_TOUCH_AD_BOTTOM;
}
/*********************************************************************
*
* Calibration
*/
static int Log2Phys(int l, I32 l0, I32 l1, I32 p0, I32 p1) {
return p0+ ((p1-p0) * (l-l0)) / (l1-l0);
}
int GUI_TOUCH_Calibrate(int Coord, int Log0, int Log1, int Phys0, int Phys1) {
int l0 = 0;
int l1 = (Coord==GUI_COORD_X) ? LCD_XSIZE-1 : LCD_YSIZE-1;
if (labs(Phys0-Phys1) < 20)
return 1;
if (labs(Log0-Log1) < 20)
return 1;
xyMinMax[Coord].Min = Log2Phys(l0, Log0, Log1, Phys0, Phys1);
xyMinMax[Coord].Max = Log2Phys(l1, Log0, Log1, Phys0, Phys1);
return 0;
}
void GUI_TOUCH_GetCalData(int Coord, int* pMin,int* pMax) {
*pMin = xyMinMax[Coord].Min;
*pMax = xyMinMax[Coord].Max;
}
/*********************************************************************
*
* GUI_TOUCH_Exec
*/
void GUI_TOUCH_Exec(void) {
#ifndef WIN32
static U8 ReadState;
int x,y,po,flag;
rPUPE=0x00; /*不使用上拉 */
rPCONE=0x0500;//(rPCONE & 0x300ff) | 0x0400; /*pe5(touch_yh)out, pe467 input */
rPDATE=0x0;(rPDATE & 0x0f) | 0x0; /* data low 4,6,7 ( 5= low out ) */
for(po=0 ; po<10; po++ ) ;
flag= rPDATE&0x80;
if(flag==0)
{
/* calculate Min / Max values */
if (xyMinMax[GUI_COORD_X].Min < xyMinMax[GUI_COORD_X].Max) {
xMin = xyMinMax[GUI_COORD_X].Min;
xMax = xyMinMax[GUI_COORD_X].Max;
} else {
xMax = xyMinMax[GUI_COORD_X].Min;
xMin = xyMinMax[GUI_COORD_X].Max;
}
if (xyMinMax[GUI_COORD_Y].Min < xyMinMax[GUI_COORD_Y].Max) {
yMin = xyMinMax[GUI_COORD_Y].Min;
yMax = xyMinMax[GUI_COORD_Y].Max;
} else {
yMax = xyMinMax[GUI_COORD_Y].Min;
yMin = xyMinMax[GUI_COORD_Y].Max;
}
/* Execute the state machine which reads the touch */
switch (ReadState) {
case 0:
TOUCH_X_ActivateY(); /* Prepare X- measurement */
yPhys = TOUCH_X_MeasureY();
ReadState++;
break;
default:
TOUCH_X_ActivateX(); /* Prepare Y- measurement */
xPhys = TOUCH_X_MeasureX();
/* Convert values into logical values */
#if !GUI_TOUCH_SWAP_XY /* Is X/Y swapped ? */
x = xPhys;
y = yPhys;
#else
x = yPhys;
y = xPhys;
#endif
if ((x <xMin) | (x>xMax) | (y <yMin) | (y>yMax)) {
GUI_TOUCH_StoreUnstable(-1,-1);
} else {
x = AD2X(x);
y = AD2Y(y);
GUI_TOUCH_StoreUnstable(x,y);
}
/* Reset state machine */
ReadState=0;
break;
}
}
else
GUI_TOUCH_StoreUnstable(-1,-1);
#endif /* WIN32 */
}
#else
void GUI_TOUCH_DriverAnalog_C(void) {}
#endif /* defined(GUI_SUPPORT_TOUCH) && GUI_SUPPORT_TOUCH */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -