/*-------------------------------------------------------------------------
   ISR GPIO function copy right information

   Copyright (C) 2006-2008. Lin, Rongrong <woody@palmmicro.com>
                            Lin, Guofeng  <alanda@palmmicro.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-------------------------------------------------------------------------*/

#include "version.h"
#include "sfr_gpio.h"
#include "type.h"
#include "core.h"
#include "apps.h"

#include "ar168.h"

#ifdef KEY_4X4
extern volatile UCHAR _p4x4_KeyVals[KEY_4X4_SIZE];
extern volatile BOOLEAN _b4x4_Key;
#endif

#ifdef KEY_5X5
extern volatile UCHAR _p5x5_KeyVals[KEY_5X5_SIZE];
extern volatile BOOLEAN _b5x5_Key;
#endif

#ifdef KEY_5X6
extern volatile UCHAR _p5x6_KeyVals[KEY_5X6_SIZE];
extern volatile BOOLEAN _b5x6_Key;
#endif

#ifdef KEY_7X8
extern volatile UCHAR _p7x8_KeyVals[KEY_7X8_SIZE];
extern volatile BOOLEAN _b7x8_Key;
#endif

#if defined HOOK_GPIO || defined SLIC_79R70
volatile BOOLEAN _bHook;
volatile UCHAR _iGPIO_Hook;		// use GPIO C2 as hook when ADC key not used
#endif

volatile UCHAR _iCTC;
volatile BOOLEAN _bTimer;
volatile ULONG Sys_lTicker;
volatile ULONG Sys_lCurrentTime;
volatile USHORT Sys_sDebug;			// temp debug use
volatile UCHAR Sys_iDebugVal;		// temp debug use

#if defined KEY_5X6 || defined KEY_7X8
UCHAR _Check_B_By_B(UCHAR iAndMask)		// pull low
{
	UCHAR iVal, iOrMask;

	iOrMask = ~iAndMask;
	rGPIO_B_Input_Enable &= iAndMask;
	rGPIO_B_Output_Enable |= iOrMask;	
	rGPIO_B |= iOrMask;
	iVal = rGPIO_B;
	iVal &= iAndMask;
	rGPIO_B &= iAndMask;
	rGPIO_B_Output_Enable &= iAndMask;	
	rGPIO_B_Input_Enable |= iOrMask;

	return iVal;
}
#endif

#ifdef KEY_5X6

UCHAR _Check_D_By_D(UCHAR iAndMask)
{
	UCHAR iVal, iOrMask;

	iOrMask = ~iAndMask;
	rGPIO_D_Input_Enable &= iAndMask;
	rGPIO_D_Output_Enable |= iOrMask;	
	rGPIO_D |= iOrMask;
	iVal = rGPIO_D;
	iVal &= iAndMask;
	rGPIO_D &= iAndMask;
	rGPIO_D_Output_Enable &= iAndMask;	
	rGPIO_D_Input_Enable |= iOrMask;

	return iVal;
}

UCHAR _Check_D_By_B(UCHAR iAndMask)
{
	UCHAR iVal, iOrMask;

	iOrMask = ~iAndMask;
	rGPIO_B_Input_Enable &= iAndMask;
	rGPIO_B_Output_Enable |= iOrMask;	
	rGPIO_B |= iOrMask;
	iVal = rGPIO_D;
	rGPIO_B &= iAndMask;
	rGPIO_B_Output_Enable &= iAndMask;	
	rGPIO_B_Input_Enable |= iOrMask;

	return iVal;
}

UCHAR _Check_B_By_D(UCHAR iAndMask)
{
	UCHAR iVal, iOrMask;

	iOrMask = ~iAndMask;
	rGPIO_D_Input_Enable &= iAndMask;
	rGPIO_D_Output_Enable |= iOrMask;	
	rGPIO_D |= iOrMask;
	iVal = rGPIO_B;
	rGPIO_D &= iAndMask;
	rGPIO_D_Output_Enable &= iAndMask;	
	rGPIO_D_Input_Enable |= iOrMask;

	return iVal;
}

void _Check5x6_Keys()
{
	_b5x6_Key = TRUE;

	_p5x6_KeyVals[0] = _Check_D_By_D(0xdf);	// 11011111B, D5 output
	_p5x6_KeyVals[1] = _Check_D_By_D(0xef);	// 11101111B, D4 output

	_p5x6_KeyVals[2] = _Check_D_By_B(0xdf);	// 11011111B, B5 output
	_p5x6_KeyVals[3] = _Check_D_By_B(0xef);	// 11101111B, B4 output
	_p5x6_KeyVals[4] = _Check_D_By_B(0xfb);	// 11111011B, B2 output
	_p5x6_KeyVals[5] = _Check_D_By_B(0xfe);	// 11111110B, B0 output

	_p5x6_KeyVals[6] = _Check_B_By_D(0xdf);	// 11011111B, D5 output
	_p5x6_KeyVals[7] = _Check_B_By_D(0xef);	// 11101111B, D4 output

	_p5x6_KeyVals[8] = _Check_B_By_B(0xdf);	// 11011111B, B5 output
	_p5x6_KeyVals[9] = _Check_B_By_B(0xef);	// 11101111B, B4 output
	_p5x6_KeyVals[10] = _Check_B_By_B(0xfb);	// 11111011B, B2 output
	_p5x6_KeyVals[11] = _Check_B_By_B(0xfe);	// 11111110B, B0 output
}
#endif

#ifdef KEY_7X8
void _Check7x8_Keys()
{
	_b7x8_Key = TRUE;

	_p7x8_KeyVals[0] = _Check_B_By_B(0xfe);	// 11111110B, B0 output
	_p7x8_KeyVals[1] = _Check_B_By_B(0xfd);	// 11111101B, B1 output
	_p7x8_KeyVals[2] = _Check_B_By_B(0xfb);	// 11111011B, B2 output
	_p7x8_KeyVals[3] = _Check_B_By_B(0xf7);	// 11110111B, B3 output
	_p7x8_KeyVals[4] = _Check_B_By_B(0xef);	// 11101111B, B4 output
	_p7x8_KeyVals[5] = _Check_B_By_B(0xdf);	// 11011111B, B5 output
	_p7x8_KeyVals[6] = _Check_B_By_B(0xbf);	// 10111111B, B6 output
	_p7x8_KeyVals[7] = _Check_B_By_B(0x7f);	// 01111111B, B7 output
}
#endif

#ifdef KEY_5X5
UCHAR _Check_K_By_D(UCHAR iAndMask)
{
	UCHAR iVal;

	rGPIO_D_Output_Enable |= ~iAndMask;	
	rGPIO_D |= ~iAndMask;
	iVal = rGPIO_K;
	rGPIO_D &= iAndMask;
	rGPIO_D_Output_Enable &= iAndMask;	

	return iVal;
}

UCHAR _Check_K_By_K(UCHAR iAndMask)
{
	UCHAR iVal;

	rGPIO_K_Enable &= iAndMask;
	rGPIO_K |= ~iAndMask;
	NOP;
	NOP;
	NOP;
	iVal = rGPIO_K;
	rGPIO_K &= iAndMask;
	rGPIO_K_Enable |= ~iAndMask;

	return iVal;
}

void _Check5x5_Keys()
{
	_b5x5_Key = TRUE;

	_p5x5_KeyVals[0] = _Check_K_By_K(0xdf);	// 11011111B, K5 output
	_p5x5_KeyVals[1] = _Check_K_By_K(0xbf);	// 10111111B, K6 output
	_p5x5_KeyVals[2] = _Check_K_By_K(0x7f);	// 01111111B, K7 output
	_p5x5_KeyVals[3] = _Check_K_By_D(0xef);	// 11101111B, D4 output
	_p5x5_KeyVals[4] = _Check_K_By_D(0xdf);	// 11011111B, D5 output
}

#endif

#ifdef KEY_4X4
UCHAR _Check_B_By_B(UCHAR iAndMask)		// pull high
{
	UCHAR iVal, iOrMask;

	iOrMask = ~iAndMask;
//	rGPIO_B_Input_Enable &= iAndMask;
	rGPIO_B_Output_Enable |= iOrMask;	
	rGPIO_B &= iAndMask;
	iVal = rGPIO_B;
	iVal |= iOrMask;
	rGPIO_B |= iOrMask;
	rGPIO_B_Output_Enable &= iAndMask;	
//	rGPIO_B_Input_Enable |= iOrMask;

	return iVal;
}

void _Check4x4_Keys()
{
	_b4x4_Key = TRUE;

	_p4x4_KeyVals[0] = _Check_B_By_B(0xef);	// 11101111B, B4 output
	_p4x4_KeyVals[1] = _Check_B_By_B(0xdf);	// 11011111B, B5 output
	_p4x4_KeyVals[2] = _Check_B_By_B(0xbf);	// 10111111B, B6 output
	_p4x4_KeyVals[3] = _Check_B_By_B(0x7f);	// 01111111B, B7 output
}
#endif

void _10msCounter()
{
	_iCTC ++;
	if (_iCTC == 100)
	{
		Sys_lCurrentTime ++;
		_bTimer = TRUE;
		_iCTC = 0;
	}
	Sys_lTicker += 10;	// 10ms timer

#ifdef KEY_ADC
	_CheckADC_Keys();
#endif
#ifdef KEY_5X5
	_Check5x5_Keys();
#endif
#ifdef KEY_4X4
	_Check4x4_Keys();
#endif
#ifdef KEY_5X6
	_Check5x6_Keys();
#endif
#ifdef KEY_8X5
	_Check8x5_Keys();
#endif
#ifdef KEY_7X8
	_Check7x8_Keys();
#endif
#ifdef HOOK_GPIO
	_bHook = TRUE;
	_iGPIO_Hook = rGPIO_C;	// use GPIO C2 as hook when ADC key not used
#endif
#ifdef SLIC_79R70
	_bHook = TRUE;
	_iGPIO_Hook = rGPIO_D;	// use GPIO D4 as hook in gateway utility
#endif
}

