#include <18f4550.h>
#fuses WDT,NOPROTECT,NOCPD,NOLVP,NOPBADEN,INTRC_IO,MCLR,BROWNOUT,BORV20,NOPUT
#use fast_io (A)
#use fast_io (B)
#use fast_io (C)
#use fast_io (D)
#use delay(clock=4000000)
#byte RCON=0xFD0
#bit SBOREN=RCON.6                                  // Activa la ejecución del Brown Out Reset
#bit IPEN=RCON.7                                    // Habilita la prioridad de las interrupciones
#bit POR=RCON.1                                     // Bit de la bandera del Power On Reset
#bit TO=RCON.3                                      // Bit de la bandera del Perro Guardian
#bit BOR=RCON.0                                     // Bit de la bandera del Brown Out Reset

//Declaracion de funciones
void funcion_leer_teclado(void);
void funcion_detectar_causa_reseteo(void);
//void funcion_intr(void);
void deshaint0(void);
void deshaint1(void);
void deshatodas(void);

//Interrupción por RB0
#INT_EXT
EXT_isr()
{
   output_d(0x00);                                  // Limpio el puerto d
   output_d(0x06);                                  // Mando el 1 al display
}

//Interrupción por RB1
#int_ext1
void interrupt_service_rutine_ext1(void)
{
   output_d(0x00);                                 // Limpio el puerto d
   output_d(0x5B);                                 // Mando el 2 al display
}

void main(void)
{
         enable_interrupts(int_ext1);               // Habilito la interrupción externa de RB1
         ext_int_edge (H_TO_L);                     // Flag INTF si flanco de bajada.
         ext_int_edge(1,H_TO_L);                    // Flag INTF si flanco de bajada.
         SBOREN=1;
         IPEN=0;
         set_tris_b (0x0F);                         // Configura puerto b como entrada y salida
         set_tris_d (0x00);                         // Configura puerto d como salida
         set_tris_a (0xF0);                         // Configura los pines RA6 - RA4 como entradas y RA3 - RA0 como salidas
         set_tris_c (0x00);                         // Configura puerto c como salida
         output_c (0x00);                           // Limpio el puerto C
         //output_b (0x00);                           // Limpio el puerto B
         output_d (0x00);                           // Limpio el puerto d
         output_a (0x00);                           // Limpio el puerto A
         output_c(0x01);

funcion_detectar_causa_reseteo();
while(true)
{
     funcion_leer_teclado();
     //funcion_intr();
     if(input(PIN_B5)==0)                       // Deshabilito la INT0?
            {
             deshaint0();                           // Si la deshabilito.
            }

         else
         {
            enable_interrupts(int_ext);               // Activa máscara INTE
         }

         if(input(PIN_B6)==0)                         // Deshabilito la INT1?
            {
            deshaint1();
            }
         else
         {
            enable_interrupts(int_ext1);              // Habilito la interrupción externa de RB1
         }

         if(input(PIN_B7)==0)                         // Deshabilito todas las interrupciones?
            {
            deshatodas();
            }
         else
         {
            enable_interrupts(global);                //Habilita máscara global de int.
         }
}

}

//Funciones
//void funcion_intr(void)
//{

//}

void funcion_leer_teclado(void)
   {

//RUTINA DEL TECLADO.... Espero que algun botón sea pulsado

    //Verificando las columnas 1,4,7,*
               output_a (0xFB);                     // Desactiva todas las columnas y activo solo la columna 1,4,7,*

               if(input(pin_A6)==0)                 // RA6 está en 0? (Ascii =1)
                  {
                     delay_ms(20);                  // verifica sino es rebote
                     if(input(pin_A6)==0)           // verifico otra vez si RA6 está en 0 (Ascii =1)
                        {
                          output_d(0x06);           // Mando el 1 al display
                        }
                  }
               if(input(pin_A5)==0)                 //RA5 está en 0? (Ascii =4)
                  {
                     delay_ms(20);                  // verifica sino es rebote
                     if(input(pin_A5)==0)           // verifico otra vez si RA5 está en 0 (Ascii =4)
                        {
                          output_d(0x66);           // Mando el 4 al display
                        }
                  }
               if(input(pin_A4)==0)                 //RA4 está en 0? (Ascii =7)
                  {
                     delay_ms(20);                  // verifica sino es rebote
                     if(input(pin_A4)==0)           // verifico otra vez si RA4 está en 0 (Ascii =7)
                        {
                          output_d(0x07);           // Mando el 7 al display
                        }
                  }
               if(input(pin_A3)==0)                 //RA3 está en 0? (Ascii =*)
                  {
                     delay_ms(20);                  // verifica sino es rebote
                     if(input(pin_A3)==0)           // verifico otra vez si RA3 está en 0 (Ascii =*)
                        {
                          output_d(0x77);           // Mando LA A del display(va a hacer el papel del *) al display
                        }
                  }
//Verificando las columnas 2,5,8,0
               output_a (0xFD);                     // Desactiva todas las columnas y activo solo la columna 2,5,8,0

               if(input(pin_A6)==0)                 //RA6 está en 0? (Ascii =2)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                    if(input(pin_A6)==0)            // verifico otra vez si RA6 está en 0 (Ascii =2)
                       {
                         output_d(0x5B);            // Mando el 2 al display
                       }
                  }
               if(input(pin_A5)==0)                 //RA5 está en 0? (Ascii =5)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                     if(input(pin_A5)==0)           // verifico otra vez si RA5 está en 0 (Ascii =5)
                        {
                          output_d(0x6D);           // Mando el 5 al display
                        }
                  }
               if(input(pin_A4)==0)                 // verifico si RA4 está en 0 (Ascii =8)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                    if(input(pin_A4)==0)            // verifico otra vez si RA4 está en 0 (Ascii =8)
                       {
                         output_d(0x7F);            // Mando el 8 al display
                       }
                  }
               if(input(pin_A3)==0)                 // verifico si RA3 está en 0 (Ascii =0)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                    if(input(pin_A3)==0)            // verifico otra vez si RA3 está en 0 (Ascii =0)
                       {
                         output_d(0x3F);            // Mando el 0 al display
                       }
                  }
//Verificando las columnas 3,6,9,#
               output_a (0xFE);                     // Desactiva todas las columnas y activo solo la columna 3,6,9,#

               if(input(pin_A6)==0)                 // verifico si RA6 está en 0 (Ascii =3)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                    if(input(pin_A6)==0)            // verifico otra vez si RA6 está en 0 (Ascii =3)
                       {
                         output_d(0x4F);            // Mando el 3 al display
                       }
                  }
               if(input(pin_A5)==0)                    // verifico si RA5 está en 0 (Ascii =6)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                    if(input(pin_A5)==0)            // verifico otra vez si RA5 está en 0 (Ascii =6)
                       {
                         output_d(0x7C);            // Mando el 6 al display
                       }
                  }
               if(input(pin_A4)==0)                 // verifico si RA4 está en 0 (Ascii =9)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                    if(input(pin_A4)==0)            // verifico otra vez si RA4 está en 0 (Ascii =9)
                       {
                         output_d(0x67);            // Mando el 7 al display
                       }
                  }
               if(input(pin_A3)==0)                 // verifico si RA3 está en 0 (Ascii =#)
                  {
                    delay_ms(20);                   // verifica sino es rebote
                     if(input(pin_A3)==0)           // verifico otra vez si RA3 está en 0 (Ascii =#)
                        {
                          output_d(0x37);           // Mando LA N del display(va a hacer el papel del #) al display
                        }
                  }
       }
void funcion_detectar_causa_reseteo(void)
   {
     switch(restart_cause())
   {
      case WDT_TIMEOUT:
      {
         output_d(0x73);
         break;
      }

      case MCLR_FROM_RUN:
       {
         output_d(0x39);
         break;
       }

      case BROWNOUT_RESTART:
       {
         output_d(0xFC);
         break;
       }
   }
   if(POR==0)
   {
       output_d(0x72);
   }
   setup_wdt(WDT_ON);
}

void deshaint0(void)
   {
     disable_interrupts(int_ext);                     // Deshabilito la interrupción externa de RB0
   }

void deshaint1(void)
   {
     disable_interrupts(int_ext1);                    // Deshabilito la interrupción externa de RB1
   }

void deshatodas(void)
   {
      disable_interrupts(global);                     // Deshabilito todas las interrupciones
   }