/* Archivos incluidos */
#include <xc.h>         /* XC8 General Include File */
#include "main.h"
//-----------------------------------------------------------------------------------------
/* Servicio de interrupcion */
//aca el servicio de interrup se implementa como una funcion con el calificador
//interrupt, es del tipo void y no toma parametros
//isr es el nombre de la interrupcion pero puede ser cualquiera
//aca estas variables se define como static porque se va a usar solamente en la
//interrupcion y como es static se inicializa solo al comienzo y mantiene su valor
//a lo largo de todo el programa
///////////////////////////////////////////////////////////////////////////////////////////
void interrupt isr(void)
{
    if(INTCONbits.T0IF)
    {

INTCONbits.T0IF=0;//borro el flag de interuupcion
TMR0+=9;       //sumar al registro siempre asi(esto no hacerlo TMR0=TMR0 + 9)
/////////////////////////////////////////////////////////// CADA 62,5 us
//ANTIRREBOTE DE SW ACTIVA HIGH pISw==1 ACTIVA LOW pISw==0
if(pISw1==0) //cambiar el valor  segun corresponda high o low
    {if(cntSw1<250){if(++cntSw1==250){SWbits.fSw1=1;}}}
else
   {if(cntSw1!=0){if(--cntSw1==0){SWbits.fSw1=0;}}}
///////////////////////////////////////////////////////////////////////////
if(pISw2==0) //cambiar el valor  segun corresponda high o low
    {if(cntSw2<250){if(++cntSw2==250){SWbits.fSw2=1;}}}
else
   {if(cntSw2!=0){if(--cntSw2==0){SWbits.fSw2=0;}}}
///////////////////////////////////////////////////////////////////////////
if(pISw3==0) //cambiar el valor  segun corresponda high o low
    {if(cntSw3<250){if(++cntSw3==250){SWbits.fSw3=1;}}}
else
   {if(cntSw3!=0){if(--cntSw3==0){SWbits.fSw3=0;}}}
///////////////////////////////////////////////////////////////////////////
if(pISw4==0) //cambiar el valor  segun corresponda high o low
    {if(cntSw4<250){if(++cntSw4==250){SWbits.fSw4=1;}}}
else
   {if(cntSw4!=0){if(--cntSw4==0){SWbits.fSw4=0;}}}
///////////////////////////////////////////////////////////////////////////
if(!FLAGbits.fStrobo)   //pregunta si el strobo es on si es off solo hace moduladores
{
//estos tres moduladores estan funcionando a una frecuencia aproximada
//de 78hz
//modulador 100Hz del ROJO
    if(cntPwmRojo>=AuxPwmRojo)	//Comienzo Pwm
        {pORojo=0;   // asi como esta el  ciclo util de actividad esta en high
        }                      //para ciclo util de actividad en low invertir las salidas
        else
        {pORojo=1;
        }
            if(++cntPwmRojo>=127) // cantidad de pasos de modulador entre 0 y 127
            {
                cntPwmRojo=0;
                AuxPwmRojo=DmxRojo;	//DmxRojo se carga en la tarea
            }//Fin Pwm Rojo
//-----------------------------------------------
//modulador 100Hz del VERDE
      if(cntPwmVerde>=AuxPwmVerde)	//Comienzo Pwm
        {pOVerde=0;    // asi como esta el  ciclo util de actividad esta en high
        }                   //para ciclo util de actividad en low invertir las salidas
        else
        {pOVerde=1;
        }
        if(++cntPwmVerde>=127) // cantidad de pasos de modulador entre 0 y 127
            {cntPwmVerde=0;
             AuxPwmVerde=DmxVerde; //DmxVerde se carga en la tarea
            }//Fin Pwm VERDE
//-----------------------------------------------
//modulador 100Hz del AZUL
      if(cntPwmAzul>=AuxPwmAzul)	//Comienzo Pwm
        { pOAzul=0;             // asi como esta el  ciclo util de actividad esta en high
        }                               //para ciclo util de actividad en low invertir las salidas
        else
        {pOAzul=1;
        }
        if(++cntPwmAzul>=127) // cantidad de pasos de modulador entre 0 y 127
            {cntPwmAzul=0;
             AuxPwmAzul=DmxAzul;	//DmxAzul se carga en la tarea
            }//Fin Pwm AZUL
            }
            else //apaga salidas de los leds cuando comienza Strobo haciendolo ciclicamente
            {
            pORojo=0;
            pOVerde=0;
            pOAzul=0;
            }
   ////Comienzo Pwm back light--------------------------------------------------------------
  if(cntPwmBK>=PwmAuxBK){pOBK=0;} // para ciclo util de actividad en low invertir
                      //las salidas asi como esta, el  ciclo util de actividad esta en high
	else
	{pOBK=1;}
		++cntPwmBK;
	if(cntPwmBK==255) //aca pongo cantidad de pasos de modulador que,
                                   //en este caso va a estar dividido en 255 partes iguales
      {cntPwmBK=0;
		PwmAuxBK=PwmDutyBK;}//valor es el registro que se carga en la tarea
	 //Fin Pwm
 /////////////////////////////////////////////////////////////////////////
   if( -- Tic1ms==0){Tic1ms=BASE1MS;if(Tiempo1ms>0){--Tiempo1ms;}
/////////////////////////////////////////////////////////// CADA 1ms
   if(--Tic10ms==0){Tic10ms=BASE10MS;if(Tiempo10ms>0){--Tiempo10ms;}
/////////////////////////////////////////////////////////// CADA 10ms
    if((vTramaDmx[STROBO]>>0)>FRAC)
        {if((vTramaDmx[STROBO]>>0)>110)   // VALOR ORIGINAL 110 NO 150
            {AuxTramaDmx=110;    // VALOR ORIGINAL 110 NO 150
            }
            else
            {AuxTramaDmx=vTramaDmx[STROBO]>>0;}
             cntStrobo-=FRAC;
             if(cntStrobo<=AuxTramaDmx)
            {cntStrobo=127;
             FLAGbits.fStrobo=~FLAGbits.fStrobo;
             }}
              else
             {FLAGbits.fStrobo=0;
              }}}
//-----------------------------------------------
  if(--Tic100ms==0){Tic100ms=BASE100MS;if(Tiempo100ms>0){--Tiempo100ms;}
/////////////////////////////////////////////////////////// CADA 100ms
  if(--Tic1seg==0){Tic1seg=BASE1SEG;if(Tiempo1seg>0){--Tiempo1seg;}
/////////////////////////////////////////////////////////// CADA 1seg
  //-----------------------------------------------
  }}}

/////////////////////////////////////////////////////////////////////////////////////////////////
//LECTURA DEL PROTOCOLO DMX512 MEDIANTE INTERRUPCION
//DE LA USART
    else if (PIR1bits.RCIF) //hay un dato pendiente de procesar
    {
	 cRCSTAbits.cRCSTA = RCSTA; //Hacemos una copia del registro RCSTA porque
     //sus bits cambian de valor al leer RCREG y tambien al modificar CREN
     DatoRx = RCREG; //En RCREG está el dato que acaba de recibir la USART

     if (cRCSTAbits.fOERR) // Si se reciben más de 3 bytes sin haberlos procesado, se
	 {                             // produce un error de Overrun. En este caso, se borra el
	   CREN=0;              // error reiniciando CREN y dejamos  la interrupción preparada
	   CREN=1;             // para procesar la siguiente trama DMX
	   DmxEstado = DMX_ESPERA_BYTE;
	   return;
	 }// Máquina de estados
	 switch (DmxEstado)
	 {
//-----------------------------------------------
	   case DMX_ESPERA_BYTE:	// si estamos en este estado y hay error FRAME
		// significa que estamos en el medio de un Byte. Hay que seguir esperando
		// hasta que desaparezca el error.
            if (!cRCSTAbits.fFERR)
            // Ha llegado un byte en forma correcta. Ahora esperaremos la señal Break
            DmxEstado = DMX_ESPERA_BREAK;
            break;
//-----------------------------------------------
	   case DMX_ESPERA_BREAK:	// estamos esperando la señal Break
	     // Esta señal se identifica porque es un pulso en cero demaciado largo
         // para la usart y entonces detecta que el bit de stop nunca llego y pone a 1 FERR
         // para indicarnos que hubo error de Frame
	     if (cRCSTAbits.fFERR)
	       // Tras recibir el error de frame podemos suponer que es el break para lo cual
           // nos aseguramos preguntando por el valor que hay en DatoRx ya que todos sus
           // bits deben ser cero, de lo contrario siguimos esperando
           if (!DatoRx)
	         DmxEstado = DMX_ESPERA_START;
	     break;
//-----------------------------------------------
	   case DMX_ESPERA_START: // ya hemos recibido el Break y ahora hay que
	   	 // esperar el byte cero de la trama el cual debe contener el valor 0, que será la
         // la  señal de Start.
	     // Mientras tanto, si recibimos un error de Frame, hay que volver a
	     // empezar para recibir la señal desde el comienzo de la trama.
            if (cRCSTAbits.fFERR)
	         DmxEstado = DMX_ESPERA_BYTE;
            else {
            if (!DatoRx)
            {
	         // Llegados a este punto, ya hemos recibido el Byte Start=0
	         // entonces comenzamos la lectura de la trama de valores DMX.
	         iTramaDmx = 0; //inicializo las variables para leer la tramaDmx
             cntCanales=0;
	         DmxEstado = DMX_RECEPCION_DATOS;
            } else
            // Si el dato recibido no es 0, volvemos a empezar
	         DmxEstado = DMX_ESPERA_BREAK;
	     }
	     break;
//-----------------------------------------------
	   case DMX_RECEPCION_DATOS:
	     // En este estado estamos recibiendo la trama de datos DMX
        // Si se detecta un error de Frame es que ha habido un error y
        // comenzamos nuevamente desde el principio.
	     if (cRCSTAbits.fFERR)
         {
          if (!DatoRx)
          DmxEstado = DMX_ESPERA_START; // si DatoRx=0 voy a Start
          else
          DmxEstado = DMX_ESPERA_BYTE; //si DatoRx!=0 voy a Byte
          }
          else // apartir de aca biscamos el comienzo del canal seleccionado
          {       // guardamos en un vector la cantidad de canales que posee el dispositivo
          if(CanalInicio) //si el canal seleccionado es cero no hago nada (solo para dip)
          {
           if(++cntCanales>=CanalInicio)
           {
           if(iTramaDmx<NUMERO_CANALES)
           {
           vTramaDmx[iTramaDmx++]=DatoRx;
           }
           else
           {
            if(cntCanales>=TOTAL_CANALES)
            {
            DmxEstado = DMX_ESPERA_BREAK;
            }
            }
            }
            }
             else
             {
             DmxEstado = DMX_ESPERA_BREAK;
             }
	         }
	         break;
}//switch
}//usart
}//isr