/*
***********************************************************************************************************************
*                                     		SIMPLE KEYPAD DRIVER FOR AT89S52
*
* Programmer 	: John Leung, TechToys. Hong Kong
* Web presence  : www.TechToys.com.hk
* Note			: 
* Language		: Keil C 7.xx 2K limited version under uVision2 IDE
* Hardware		: AT89S52-gLCD-STK1
* Date			: Version 0.0 (7th June 2006)
***********************************************************************************************************************
*                                         		USER DEFINED CONSTANTS
*
* Note: These #defines would normally reside in your application specific code.
***********************************************************************************************************************
*                                             		DESCRIPTION
*
*    The keypad is assumed to be a non-matrix simple keypad. Only single pin (or a few pins)is/are needed
*
*    xKEY_RPT_DLY             Number of scan times before auto repeat executes the function again
*    xKEY_RPT_START_DLY       Number of scan times before auto repeat function engages
*
*    xKEY_SCAN_TASK_DLY       The number of milliseconds between keyboard scans
*
*
*	 The main task is xKeyScanTask(), should be delayed either in the main() loop for xKEY_SCAN_TASK_DLY, 
*	 or using  timer interrupt to achieve the keypad debounce.
*
* 	 EXAMPLE:
*
*	 main (){
*	
*			unsigned char keyCode;
*
*	 		xKeyInit();						//initialize the keypad module before using it
*			
*		for(;;){
*			DelayMs(xKEY_SCAN_TASK_DLY);	//debounce the keys
*			xKeyScanTask();					//scan for key press
*			if(xKeyHit())
*			{
*				keyCode = xKeyGetKey();
*				if (keyCode == xKEY_UP_FLAG)
*					// do job for key code  == UP key, can be playing a music or any task you want
*				else if (keyCode == xKEY_DN_FLAG)
*					// do job for key code  == Down key;
*				else
*					//Err;
*			}
*		}
*	}
*
***********************************************************************************************************************
*/

/*
***********************************************************************************************************************
* Date : 7th June 2006, ported to AT89S52 
*
* A new scan state 'xKEY_STATE_DOWN' and a global variable xKeyRptEn added
* Functions modified: xKeyInit(void), xKeyScanTask(void).
* One more scan-state in xKeyScanTask(void) as xKEY_STATE_DOWN adds the flexiblity of auto repeat
* enable/disable feature. 
* If xKeyRptEn==FALSE, which is the default condition set by xKeyInit(), no auto repeat engages. 
* On the other hand, if xKeyRptEn==TRUE, auto repeat engages after a scan delay of xKEY_RPT_START_DLY
* Please notice that xKEY_RPT_START_DLY increment by one scan-time because of one more scan-state.
***********************************************************************************************************************
*/

/*
***********************************************************************************************************************
* Date : 7th June 2006, ported to AT89S52
*
* Modification history : Add unsigned int  xKeyGetKeyDownTime(void)
***********************************************************************************************************************
*/

//sbit is compiler specific!
sbit xKEY_DN	=	P1^4;
sbit xKEY_RT	=	P1^5;
sbit xKEY_LT	=	P1^7;
sbit xKEY_UP 	=	P1^6;
sbit xKEY_CTR	=	P3^3;

#define  FALSE 					0
#define  TRUE 					1

#define xKEY_DN_FLAG			1
#define xKEY_RT_FLAG			2
#define xKEY_LT_FLAG			3
#define xKEY_UP_FLAG			4
#define xKEY_CTR_FLAG			5

#define  xKEY_BUF_SIZE			3		/* Size of the KEYPAD Buffer							   */
#define  xKEY_RPT_DLY			5		/* Number of scan times before auto repeat executes again  */
										/* scan time measured in units of xKEY_SCAN_TASK_DLY       */
										/* i.e. (xKEY_RPT_DLY * xKEY_SCAN_TASK_DLY) ms			   */
#define  xKEY_RPT_START_DLY		30		/* Number of scan times before auto repeat function engages*/

#define  xKEY_SCAN_TASK_DLY		50		/* Number of milliseconds between keyboard scans           */

#ifdef	xKEY_GLOBALS
#define xKEY_EXT
#else
#define xKEY_EXT extern
#endif

/*
***********************************************************************************************************************
*                                            		GLOBAL VARIABLES
***********************************************************************************************************************
*/

xKEY_EXT	bit		xKeyRptEn;

/*
***********************************************************************************************************************
*                                          		  FUNCTION PROTOTYPES
***********************************************************************************************************************
*/
void	xKeyScanTask(void);				/* Run in a periodic manner, for key acquired in background					*/
void    xKeyInit(void);                 /* Initialize the keyboard handler, called before using this module 		*/
bit 	xKeyHit(void);					/* See if a key has been pressed (return TRUE if so, FALSE if not) 			*/
unsigned char  xKeyGetKey (void);		/* Get a key code defined as xKEY_XX_FLAG above if one is present, -1 else	*/
unsigned int  xKeyGetKeyDownTime(void);/* Get how long a key has been pressed in millisec							*/
/*
***********************************************************************************************************************
*                                      		  HARDWARE DEPENDENT FUNCTIONS
***********************************************************************************************************************
*/
void    xKeyInitPins(void);			/* Initialize I/O pins												*/
bit		xKeyCheckPins(void);		/* Check individual I/O pins										*/
unsigned char xKeyDecode(void);		/* Get scan code from current key pressed							*/
