/* Keypad interface  Rob Chapman  Dec 8, 1996 */


 /* Keypad input algorithm:  The keypad has inputs and outputs.  The

    keypad machine drives the outputs and looks for an input.  When

    a key press is detected, it is debounced, an application keypad

    machine is called and if the key is held down, the call is made

    periodically.


    Since the port has pull up resistors, all external values are

    inverted.  An input is a zer0 value.  An output is a zero value.    

  */

 

#include <stdio.h>

#include <string.h>

#include <hc12.h>

#include "maxrtos.h"

#include "keypad.h"


/* Keypad interface */

Machine key_handler; /* points to current keypad handler */


TIMEOUT(30 MSEC, kptimeout);	/* debounce time */

TIMEOUT(300 MSEC, kprepeat_timeout); /* time between key repeats */


Byte repeated_key;	/* key is repeating flag */

Byte keyin;			/* the key that is pressed */


Byte repeat_key(void)	/* is the key a repeat key? */

{

	return repeated_key;

}


Flag kphit(void)  /* scan keyboard and return key hit or zero */

{

	/* fill in keypad scan algorithm here */

	return 0;

}


Cell kpdata(void)  /* return value of pressed key */

{	

	return kphit();

}


void keypad_is(Machine k)  /* set a new keypad handler to process keys */

{

	key_handler = k;

}

	

Flag keypad_query(Machine k)  /* ask if k is the current keypad handler */

{

	return(key_handler == k);

}


/* keypad state machine:

	keypad - looking for key press;

	kpwait - waiting for a debounce time

    kpreleased - key pressed, waiting for release */


void kpreleased(void)  /* state waiting for key to be released */

{

	if(kphit())

	{

		if (timed_out(kprepeat_timeout))

		{

			repeated_key = min(254,++repeated_key);	/* count up to 254 */

			key_handler();

			start_timeout(kprepeat_timeout);

		}

		run(kpreleased);

	}

	else

		run(keypad);

}


void kpwait(void)  /* debounce the key */

{

	if (timed_out(kptimeout))

	{

		if (kphit() != 0)

		{

			keyin = kpdata();

			repeated_key = 0;

			key_handler();	/* call keypad function */

			run(kpreleased);

			start_timeout(kprepeat_timeout);

		}

		else

			run(keypad);

	}

	else

		run(kpwait);

}


void keypad(void)  /* state waiting for a key press */

{

	if(kphit())

	{

		start_timeout(kptimeout);

		run(kpwait);

	}

	else

		run(keypad);

}

   

void run_keypad(void)  /* startup the keypad machine */

{

	PUCR |= 0x80;					/* enable pin pullups on port H */

	run(keypad);					/* keypad machine */

}

