
#include  "system.h"
#include  "key.h"

#define  KEY_SCAN_NUM			2

u16 xdata TK_buff[16];		//按键量化缓存
u16 xdata TK_zero[16];   //0   1    2   3   4   5   6   7    8   9   10  11  12  13  14  15
u16 xdata TK_th_val[16]= {280,300,9000,300,300,300,300,300,9000,9000,300,300,300,500,300,300};	//触摸阈值
												// 1   5    -   J   2   3   6   9    -   -    8   4   0   L   X   7
											 
 
bool  B_TK_Lowpass= FALSE;		//低通滤波使能标志
bool  bReadKeyOk= FALSE;	    //按键扫描完成标志
bool  bPassFlag= FALSE;

u8  WakeUpkey= 0;
u8  gKeyMode= 0;

bool  errflag= FALSE;

/** 触摸中断服务，由common_isr() interrupt 13调用
**
***********************************************************************/
void  TouchKeyIsr(void)
{
		u8	result;
	
		result = TSSTA2;

		if(result & 0x40)	//数据溢出, 错误处理(略)
		{
				TSSTA2 |= 0x40;	//写1清零
				errflag= TRUE;
		}
		if(result & 0x80)	//扫描完成
		{
				TSSTA2 |= 0x80;	//写1清零
				result &= 0x0f;
				TK_buff[result] = TSDAT;
			
				if(result == 15)		
				{
						//TSCTRL &= ~BIT7;
						bReadKeyOk = TRUE;	//读完一次循环
				}
			
				
				WakeUpkey= result;
				bPassFlag= TRUE;
		}
}

/** 初始化触摸按键端口
**
*********************************************************************/
void  InitTkPort(void)
{
		P1IE = ~(BIT0+BIT1+BIT3+BIT4+BIT5+BIT6+BIT7);			//禁止触摸按键的数字输入
	  P5IE = ~(BIT2+BIT3);								//禁止触摸按键的数字输入
	  P0IE = ~(BIT0+BIT1+BIT2+BIT3);			//禁止触摸按键的数字输入
	
		P0M1|= (BIT0+BIT1+BIT2+BIT3);
		P0M0&= ~(BIT0+BIT1+BIT2+BIT3);
	
		P1M1|= (BIT0+BIT1+BIT3+BIT4+BIT5+BIT6+BIT7);
		P1M0&= ~(BIT0+BIT1+BIT3+BIT4+BIT5+BIT6+BIT7);
		
		P5M1|= (BIT2+BIT3);
		P5M0&= ~(BIT2+BIT3);
}

/** 初始化触摸按键

********************************************************************/
void  InitTk(void)
{
  //初始化按键端口
		InitTkPort();
	//配置触摸按键
		P_SW2 |= 0x80;	  //允许访问XSFR(扩展特殊功能寄存器)
		TSRT = 0x00;			//禁止LED分时扫描
		TSCHEN1 = (BIT0+BIT1+BIT3+BIT4+BIT5+BIT6+BIT7);//	TK0-TK7   
    TSCHEN2 = (BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);		//TK8~TK15
	 
	
	//开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
		//TSCFG1  = (7<<4) + 7;	
		TSCFG1  = (3<<4) + 3;	
	//配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4)  1(1/2)  2(5/8)  3(3/4)
		TSCFG2  = 3;		
		//TSCTRL = 0xA0;			//开始自动扫描, 无平均, B7: TSGO,  B6: SINGLE,  B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
	//设置触摸中断优先级，优先级不够会导致中断异常，使触摸功能不能正常进入中断，特别在使用printf()打钱函数时	
		IP2H|= BIT7;  //PTKSUH  //中断优先级最高
		IP2|= BIT7;		//PTKSU
	//开中断
	  TSWUTC = 0x80;  //唤醒扫描频率 
		IE2 |= 0x80;			//使能触摸中断
		EA = 1;		
		
		IRC32KCR = 0x80;         //启动内部32K IRC
    while (!(IRC32KCR & 1)); //等待时钟稳定

		gKeyResetFlag= FALSE;
		gKeyInitDelay= 100;  //上电延时后在主循环中执行ResetKey();
	  //ResetKey();
}

/**校准按键（自动定时校准 或者长按超时后校准 或唤醒后无操作自动校准）
**
*********************************************************************/
void  ResetKey(void)
{
	  u8  i;
		u8  timeout= 0;
	
 
		for(i=0;i<40;i++)
		{
				TSCTRL = (1<<7) +KEY_SCAN_NUM;	//开始扫描, 4次平均  // + (1<<6)
				while(!bReadKeyOk)
				{
						DelayMs(1);
						timeout++;
						if (timeout>100)
						{
								break;
						}
				}
				bReadKeyOk = FALSE;
		}

		for(i=0;i<16;i++) TK_zero[i]= TK_buff[i];

		//唤醒门限值
		TSTH00= TK_zero[2]-TK_th_val[2];
		TSTH01= TK_zero[2]-TK_th_val[2];
		//TSTH02H= TK_zero[2]-TK_th_val[2];
		TSTH03 = TK_zero[2]-TK_th_val[2];
		TSTH04= TK_zero[2]-TK_th_val[2];
		TSTH05= TK_zero[2]-TK_th_val[2];
		TSTH06 = TK_zero[2]-TK_th_val[2];
		TSTH07 = TK_zero[2]-TK_th_val[2];
		//TSTH08H= TK_zero[8]-TK_th_val[8];
		//TSTH09H= TK_zero[9]-TK_th_val[9];
		TSTH10 = TK_zero[2]-TK_th_val[2];
		TSTH11 = TK_zero[2]-TK_th_val[2];
		TSTH12 = TK_zero[2]-TK_th_val[2];
		TSTH13 = TK_zero[2]-TK_th_val[2];
		TSTH14 = TK_zero[2]-TK_th_val[2];
		TSTH15 = TK_zero[2]-TK_th_val[2];
		
		
		for(i=0;i<16;i++) prtf("tk_zero[%db]= %ds\n", i, TK_zero[i]);	
		prtf("key reset ok\n");
		prtf("\n");
		 
}

/**常规模式按键扫描
**
*********************************************************************/
static u8  old_key= 0;
u16  KeyScan(void)
{
		u16  key= 0;
		u16  DiffVal;
		u8  i;
	
		if (!bReadKeyOk)  return  key;
 
		for(i=0;i<16;i++)
		{
				if ((i==2)||(i==8)||(i==9))  continue;
				DiffVal= TK_zero[i]-TK_th_val[i];
				if(TK_buff[i]< DiffVal)  key|= GetBit(i);
				///prtf("TK_buff[%db]=%ds  DiffVal= %ds  key=%ds\n",i, TK_buff[i], DiffVal, key);
		}
		//prtf("\n");
		
		bReadKeyOk=  FALSE;
		TSCTRL = (1<<7) + KEY_SCAN_NUM;  
		//TSCTRL = (1<<7)+ (1<<6) + KEY_SCAN_NUM;
		
		if ((key==0)&&(old_key!=0))  old_key= 0;
		return  key;
}

/**低功耗唤醒后进入常规扫描模式
**
*********************************************************************/
void  KeyWkup(void)
{
		bReadKeyOk= FALSE;
		TSCTRL = 0;
		
	//TSCTRL:
	//TSGO  SINGLE TSWAIT TSWUCS TSDCEN TSWUEN  TSSAMP[1:0]
	//TSGO  0 进入省电模式
	//SINGLE 位为 0 做连续不停扫描，配置 TSWAIT 为 0
	//TSWUCS，决定唤醒控制器的时钟来源是外部 32KHz 晶振或内部 32KHz IRC
	//TSDCEN=1 使能内部数字比较功能
	//使能 TSWUEN=1，设置 TSPD=1 以关闭 TSU 模块模拟电源
	//TSSAMP[1:0]以决定每一个信道的扫描采样次数
		TSCTRL = (1<<7) + KEY_SCAN_NUM;	//开始扫描, 4次平均
	
		//TSCTRL = (1<<7) + (1<<6) + KEY_SCAN_NUM;	//开始扫描, 4次平均
}

/**按键掉电休眠
**
*********************************************************************/
void  KeySleep(void)
{
	//TSCTRL:
	//TSGO  SINGLE TSWAIT TSWUCS TSDCEN TSWUEN  TSSAMP[1:0]
	//TSGO  0 进入省电模式
	//SINGLE 位为 0 做连续不停扫描，配置 TSWAIT 为 0
	//TSWUCS，决定唤醒控制器的时钟来源是外部 32KHz 晶振或内部 32KHz IRC
	//TSDCEN=1 使能内部数字比较功能
	//使能 TSWUEN=1，设置 TSPD=1 以关闭 TSU 模块模拟电源
	//TSSAMP[1:0]以决定每一个信道的扫描采样次数
		
	//TSCFG1: 7    6    5    4    3     2     1     0
	//				-      SCR[2:0]     -       DT[2:0]  
	//					开关频率 SCR[2:0]    放电时间 DT[2:0]
	//TSCFG2:
	//				-    -    -    -    -     -    TSVR[1:0]
	//										内部比较器参考电压 TSVR[1:0]
	
	//TSSTA1  触摸按键状态寄存器 1     LEDWK  -  -  -  TSWKCHN[3:0]  
	//TSSTA2  触摸按键状态寄存器 2     TSIF  TSDOV  -  -  TSDNCHN[3:0]  
 
		TSCTRL &=	~BIT7;
		TSCTRL = (1<<3) + (1<<2) + 0;//使能数字比较器 + 低功耗唤醒使能
		bPassFlag= FALSE;
 
}

/**低功耗唤醒后获取键值
**
*********************************************************************/
u16  GetSleepKey(void)
{
		TSCTRL = (1<<7) + (1<<3) + (1<<2) + 0;
		if(bPassFlag)
		{
				bPassFlag= FALSE;
				return  (1<<WakeUpkey);
		}
		return  0;
}

 
 
