/**************************************************************************
 *
 *                Microchip USB C18 Firmware Version 1.0
 *
 **************************************************************************
 * FileName:        user.c
 * Processor:       PIC18
 *************************************************************************/

/** I N C L U D E S *******************************************************/
#include "p18f2550.h"
#include "user.h"
#include "timers.h"
#include "usart.h"
#include "string.h"
#include "reset.h"
#include "portb.h"
#include "memoire.h"
#include "user.h"
#include "delays.h"
#include "interrupt.h"

#pragma code
//**********************************************************************
// Utilisé pour connaitre le nb de jours dans le mois
//**********************************************************************
unsigned char jourmois(void){
//Tableau du nombre de jours dans le mois pour calcul date
const byte JOURS[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 if(((yyyy%4==0) && (yyyy%100!=0)) || (yyyy%400==0)) 
   if (mm==2)
      return (29);
   else
      return (JOURS[mm]);
 else
   return (JOURS[mm]);
}


/************************************************************************
 * Procedure de service d'interruption
 ***********************************************************************/
#pragma code
#pragma interrupt isr
void isr(void) {
unsigned char ptr;
 
 //==================================================================
 // Interruption du Timer 1
 //==================================================================
 if (PIR1bits.TMR1IF) {
   //Recharge timerH pour 1 sec
   TMR1H = 0x80;

   //Fait clignotement led Rouge (attente d'une premiere clé connue)
   if (etat & MODELEARN1) LATA ^= LEDROUGE;
   //Fait clignotement led Verte (attente d'une premiere clé connue)
   if (etat & MODELEARN2) LATA ^= LEDVERTE;

   //Augmente compteur temps PUSH appuyée (de 1 a 5)
   if (!I_PUSH) {
     if (pushlen<5)
       pushlen++;
     else {
       //Signale ordre entrée en mode LEARN nouvelle clé
   	   //Si c'est premiere clé en mémoire -> pret à stocker de suite !
       if (!memcmppgm(&cles[0],&clevide,5)) {
        etat = MODELEARN2;
        O_LEDV = 1;
        O_LEDR = 0; }
       else {
        etat = MODELEARN1;
        O_LEDV = 0;
        O_LEDR = 1; }
    }
   } 
   else
    pushlen=0;

  //Si reception timeout , raz le dataptr de trame RFID recue
  //pour etre sur de retomber au début pour chaque clé.
  if (rectimeout>0) {
    rectimeout--;
    if (rectimeout==0) dataptr=0;
  }

  //Augmente l'heure & la date
  secs++;
  if (secs==60) {
	secs=0;  mins++;
	if (mins==60) {
	  mins=0; hrs++;
	  if (hrs==24) {
		hrs=0;  dd++;
		if (dd>jourmois()) {
		  dd=1;  mm++;
		  if (mm>12) {
			mm=1;
			yyyy++;
		  }
		}
      }
	}
  }

  //Diminue le temps de led allumée
  //Si 0 eteint les leds et le relais
  if (leds_on) {
	leds_on--;
    if (!leds_on) O_LEDV = O_LEDR = O_RELAIS =0;
  }

  //Reset l'it du timer 1
  PIR1bits.TMR1IF=0;
 }


//==================================================================
// Interruption de l'USART
//==================================================================
 if (PIR1bits.RCIF) {

  //Plus d'erreur
  if (RCSTA & 0b00000110) {
    RCSTAbits.CREN = 0;
    RCSTAbits.CREN = 0;
    dataptr =0;
  }

  //Stocke un octet dans le buffer rec[]
  rec[dataptr++] = ReadUSART();
  //Incr le time-out de recption -> raz dataptr si plus rien 
  rectimeout=2;

 //Voit si une trame entiere a été recue
 if (dataptr >= FRAME_LEN) {
   //repointe en debut du buffer
   dataptr = 0;
   //Si pas trop rapide, Calcule le CRC sur 16 bits
   if (leds_on==0) {
     CRC = ZAdr = 0;
     for (NByte=1;NByte<=9;NByte++,ZAdr++) {
    	C=(CRC>>8)^rec[ZAdr];
    	C=C<<8;
    	for (i=0;i<8;i++)
    	  if (C&0x8000) C=(C<<1)^0x1021;
    	  else C=C<<1;
    	CRC = C^(CRC<<8);
     }
     //Teste le CRC
     if ( ((CRC>>8)==rec[9]) 
      && ((CRC&0xff)==rec[10]) )
    	etat |= RFIDOK;				// un vrai RFID est passé
     else
    	etat |= LEDROUGE;			// clé bidon...
   }
  }
 }
}
//===============================================================
