// inclusion
#include "axiom.h"

// augmenter la valeur si rebond multiples, diminuer si des pressions sont perdues
#define REBOND	0x40        
#define DELAI	0x10

// Prototypes
void clavier_init();
char scrute_clavier();
char recherche_touche();
void clignote();
void keywakeup(void);


// Constantes 
const char touche[17] = ".123A456B789C*0#D";		// clavier MATRICE 4x4

// Variables
unsigned char nouvelle, ancienne;

/********************************************/
void clavier_init()
{

// PortP[0-3] = output
// PortP[4-7] = input avec pull-down 
	
    DDRP = 0x0F;    	// direction (0=input, 1=output)
    PPSP = 0xF0;    	// front d'activation: rise=1 et fall=0
    PERP = 0xF0;    	// active resistance ce tirage
    
    nouvelle=0; 
    ancienne=0; 			// remise à 0 des variables
}
 /********************************************/
char scrute_clavier()
{
 	// renvoi 0 si aucune touche n'est pressée
    // sinon on retourne le code associé
	
	unsigned char colonne, compte_touche, statut_touche, retard;

    PTP = 0x0F;     	//mise à 1 de toutes les colonnes
    statut_touche = PTP;    	// passage de variable
    statut_touche &= 0xF0;  	// masque sur les lignes
    
    if(statut_touche != 0){ 	// si une touche est enfoncée

    	compte_touche=0;    
    
    	for(colonne = 0x01; colonne < 0x10; compte_touche++);
           {
            PTP = 0;    								// mise à 0 de toutes les colonnes
            PTP = colonne;   							// passage de variable
            for(retard=0x20; retard > 0; retard--);		// temporisation   
            statut_touche = PTH;    
            statut_touche &= 0xF0;  					// masque les lignes
            if(statut_touche != 0)
              { 										// si la touche fait partie de la colonne
                statut_touche >>= 4;
                if(statut_touche == 0x04)
                  { statut_touche = 3;  }
                if(statut_touche == 0x08)
                  { statut_touche = 4;  }
                return(touche[(compte_touche*4) + statut_touche]);
              }
        }
    }
    return 0;   // aucune touche activée 

}
/********************************************/
char recherche_touche()
{
    long compte;  

    do{ nouvelle = scrute_clavier();   		// 
      }while(nouvelle == ancienne);   		// 

    for(compte=0; compte < REBOND ; compte ++)
       {   
         nouvelle = scrute_clavier();
         if(nouvelle == 0 || nouvelle != ancienne)
           {  compte=0; 					// remise à 0 du compteur
           }
        ancienne = nouvelle;    				// sauve la touche pour le prochain balayage
       }
    
    return(nouvelle);
}
/********************************************/
void clignote()
{
int i,j;
    
  COPCTL = 0x00;     // disable COP 
  DDRP |= 0x01;
  
  while(1)
       { PTP |= 0x01;  // LED is on
	     for(j=0;j<=60000;j++)
	        { /* attendre*/ }
         PTP &= ~0x01; // LED is off
	     for(j=0;j<=20000;j++)
	        { /* attendre*/ }
       }
}
/********************************************/
char clavier;

void keywakeup(void)
{  
   char next;
   
   clavier = 0xFF;
   DDRP |=0x0F;		// sorties -> mise à 1: PP[0,3]pour les lignes 
   DDRH &=0x0F;		// entrées -> mise à 0: PH[4,7]pour les colonnes
   PTP  = 0x0F;		// scrute les lignes
   PIFH = 0xFF;		// efface le flag d'interruption
   PPSH = 0xF0;		// detection : actif sur front montant
   PERH = 0x00;		// désactive les pulldowns
   PIEH = 0xF0;		// local enable on colonne inputs
   asm( "cli" );
   for(;;)
      { while (clavier == 0xFF);
	  	next = clavier; 
   		clavier = 0xFF;
      }
 
}

/********************************************/
// #pragma interrupt_handler clavier_ISR()

void clavier_ISR(void)
{
 	 char temp;
	 
	 PIEH = 0x00;	  		 // local disable
	 temp = getASCII();
	 
	 if(temp != 0x00)
	   {
	   }
	 
	 PIFH = PIFH;	   		 // acknowlegdge all interrups
	 PIEH |= 0xF0;	   		 // local enable on columns inputs
}

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

void main(void)
{
	 	
//PTH: EQU REGBS+$260 ;portH data register
//PTIH: EQU REGBS+$261 ;portH input register
//DDRH: EQU REGBS+$262 ;portH direction register
//RDRH: EQU REGBS+$263 ;portH reduced drive register
//PERH: EQU REGBS+$264 ;portH pull device enable
//PPSH: EQU REGBS+$265 ;portH pull polarity select
//PIEH: EQU REGBS+$266 ;portH interrupt enable register
//PIFH: EQU REGBS+$267 ;portH interrupt flag register
		
		
		PIEH=0xFF			// efface tous les flags	
		DDRP=				// fixe les directions 			  
		PERH=0xFF;			// configuration avec pull-up sur H
		PIEH=0x0F;			// active l'interruption sur H[0,3]				  
		
			   
	    clignote();
}

