/******************************************************************************
*                                             COPYRIGHT (c) MOTOROLA 2002   
* FILE NAME: keypad.c     REVISION 1.0                                        
*                                                                           
* PURPOSE: scan a 4x4 keypad
*                                                                           
*******************************************************************************
*                                                                           
* DESCRIPTION: keypad Source File             
*                                                                           
* NOTE: 
*                                                                           
* AUTHOR: jianjian song    LOCATION: OHT     LAST EDIT DATE: 08/08/02  
*                                                                           
* UPDATE HISTORY                                                            
* REV      	AUTHOR      DATE       	DESCRIPTION OF CHANGE                    
* ---      	------      ---------   ---------------------                    
* 1.0      	r9aabe    	03/22/2005	- Original coding 
*                                                                           
******************************************************************************/
#include "keypad.h"

/* Local Variable Declarations */
uchar RxBuff[RxBufSize];		/* receive queue */
uchar TxBuff[TxBufSize];		/* transmit queue */
uchar RxIn;						/* next available location in the Rx queue */
uchar RxOut;					/* next character to be removed from the Rx queue */
uchar TxIn;						/* next available location in the Tx queue */
uchar TxOut;					/* next character to be sent from the Tx queue */
volatile uchar RxBAvail;		/* number of bytes left in the Rx queue */
volatile uchar TxBAvail;		/* number of bytes left in the Tx queue */
uchar XOffSent;					/* flag indicating that an XOff character was sent */
uchar XOffRcvd;					/* flag indicating that an XOff character was received (== 1, XOff was received) */
uchar SendXOff;					/* flag indicating that the TxISR should send an XOff the next time it's called */
uchar SendXOn;

/*Local Prototypes*/

uchar SCIcharAvail(void);
int TERMIO_GetChar(void);
int TERMIO_PutChar(uchar);
uchar InitSCI(ulong);
void RxISR(void);
void TxISR(void);
void sci0_handler(void);
void sci_tos(void);

/*************************************************************************************/

uchar SCIcharAvail(void)
 {
 /* Variable Declarations */

 /* Begin Function SCIcharAvail() */
 
 if (RxBAvail != RxBufSize)		/* if a character is available in the Receive Data buffer */
  return(TRUE);					/* return true */
 else
  return(FALSE);
 
 }	/* end SCIcharAvail */

/*************************************************************************************/

int TERMIO_PutChar (uchar c)
 {
 /* Variable Declarations */

 /* Begin Function putchar() */
 
 while (TxBAvail == 0)			/* if there's no room in the xmit queue */
  ;								/* wait here */
 
 TxBuff[TxIn++] = c;			/* put the char in the buffer, inc buffer index */
 if (TxIn == TxBufSize)			/* buffer index go past the end of the buffer? */
  TxIn = 0;						/* yes. wrap around to the start */
 TxBAvail--;					/* one less character available in the buffer */
 if (XOffRcvd == 0)				/* if an XOff has not been received... */
  Sci0.scicr2.byte |= TIE;      /* enable SCI transmit interrupts */
 return(c);				        /* return the character we sent */
   
 }	/* end putchar */

/*************************************************************************************/
int TERMIO_GetChar (void)
 {
 /* Variable Declarations */
 uchar c;				        /* holds the character we'll return */

 /* Begin Function getchar() */
 
 while (RxBAvail == RxBufSize)	/* if there's no characters in the Rx buffer */
  ;								/* just wait here */
 
 c = RxBuff[RxOut++];			/* get a character from the Rx buffer & advance the Rx index */
 if (RxOut == RxBufSize)		/* index go past the physical end of the buffer? */
  RxOut = 0;					/* yes wrap around to the start */
 RxBAvail++;					/* 1 more byte available in the receive buffer */
 
 if ((XOffSent != 0) && (RxBAvail >= XOnCount))	/* if an XOff was previously sent & the Rx buffer has more than XOnCount bytes available */
  {
   SendXOn = 1;
   Sci0.scicr2.byte |= TIE;     /* enable SCI transmit interrupts */
  }
 
 return(c);			/* return the character retrieved from receive buffer */
   
 }	/* end getchar */

/*************************************************************************************/
uchar InitSCI(ulong baud)
 {  
 /* Variable Declarations */

 /* Begin Function InitSCI() */
   
 RxIn = RxOut = TxIn = TxOut = 0;			/* set the Rx & Tx queue indexes to zero */
 RxBAvail = RxBufSize;						/* the receive buffer is empty */
 TxBAvail = TxBufSize;						/* the transmit buffer is empty */
 XOffSent = 0;
 XOffRcvd = 0;
 Sci0.scibd.word = (uint)((((busclk/16)*1000)/baud)); /* initialize the Baud register */ 
 Sci0.scicr2.byte = TE + RE + RIE;          /* enable both the transmitter & receiver */ 
 return(1);								    /* return */
   
 }	/* end InitSCI */

/*************************************************************************************/
 void RxISR(void)
 {
 /* Variable Declarations */
 uchar c;
 
 /* Begin Function RxISR() */
 // clear RDRF interrupt flag 
 c = Sci0.scisr1.byte;
 c = Sci0.scidrl.byte;

// if (c == XOff)			/* host want us to stop sending data? */
//  {
//   Sci0.scicr2.byte &= ~TIE;        /* yes. disable transmit interrupts */
//   XOffRcvd = 1;					/* let putchar know that it may continue to place */
//   return;                          /* characters in the buffer but not enable Xmit interrupts */
//  }
// else if (c == XOn)			        /* host want us to start sending data? */
//  {
//   if (TxBAvail != TxBufSize)		/* anything left in the Tx buffer? */
//   Sci0.scicr2.byte |= TIE;         /* yes. enable transmit interrupts */
//   XOffRcvd = 0;
//   return;
//  }
// if ((RxBAvail <= XOffCount) && (XOffSent == 0))	/* if the number of bytes available in the Rx buff is < XOffCount & an XOff hasn't been sent */
//  {
//   SendXOff = 1;					/* set flag to send an XOff, stoping the host from sending data */
//   XOffSent = 1;					/* set the flag showing that we've queued up to send an XOff */
//   Sci0.scicr2.byte |= TIE;         /* enable transmit interrupts, so the TxISR will be called next time the TDRE bit is set */
//   }
 
 if (RxBAvail != 0)			/* if there are bytes available in the Rx buffer */
  {
   RxBAvail--;				/* reduce the count by 1 */
   RxBuff[RxIn++] = c;		/* place the received byte in the buffer */
   if (RxIn == RxBufSize)	/* reached the physical end of the buffer? */
    RxIn = 0;				/* yes. wrap around to the start */
  }  
 }	/* end RxISR */

/*************************************************************************************/
 void TxISR(void)
 {
 /* Variable Declarations */
 
 /* Begin Function TxISR() */
  
 if (SendXOn != 0)				        /* request to send an XOn to the host? */
  {
   SendXOn = 0;
   XOffSent = 0;						/* reset the XOff flag */
   Sci0.scidrl.byte = XOn;			    /* send the character */
   if (TxBAvail == TxBufSize)			/* anything in the Tx buffer? */
   Sci0.scicr2.byte &= ~TIE;            /* no. disable transmit interrupts */
   }
 else if (SendXOff != 0)				/* request to send an XOff to the host? */
  {
   SendXOff = 0;				        /* yes, clear the request */
  Sci0.scidrl.byte = XOff;			    /* send the character */
   if (TxBAvail == TxBufSize)			/* anything in the Tx buffer? */
   Sci0.scicr2.byte &= ~TIE;            /* no. disable transmit interrupts */
  }
 else
  {
   Sci0.scidrl.byte = TxBuff[TxOut++];	/* remove a character from the buffer & send it */
   if (TxOut == TxBufSize)				/* reached the physical end of the buffer? */
    TxOut = 0;							/* yes. wrap around to the start */
   if (++TxBAvail == TxBufSize)			/* anything left in the Tx buffer? */
   Sci0.scicr2.byte &= ~TIE; 		    /* no. disable transmit interrupts */
  }
  
 }	/* end TxISR */

 
/**************************************************************************
* Name: SCI0 handler
*  Updates:
**************************************************************************/
 void sci0_handler(void)
 {
 /* Variable Declarations */
  
 /* Begin Function SCIISR() */
 
if (Sci0.scisr1.byte & (RDRF + ORF))
   RxISR();
 if ((Sci0.scicr2.byte & TIE) && (Sci0.scisr1.byte & TDRE))
  TxISR();
 
 }	/* end SCIISR */


/**************************************************************************
* Name: SCI_clear screen
*   returns cursor to top of screen
*  Updates:
**************************************************************************/
void sci_tos(void)
{
int x;
  for (x=0;x<25;x++)
    {
    (void) putchar (0x1b);                                                         
    (void) putchar (0x5b);                                                         
    (void) putchar (0x41);                                                         
    }
}