/*
 * File:   PWM.c
 * Author: Christian Mares
 *
 * Created on 27 de diciembre de 2017, 18:49
 */

#ifndef PWM_H
#define PWM_H

//Temporizador del PWM
#define PWM_Timer 3 // Define el Timer a usar
#if(PWM_Timer == 1)
 #define _Tpwm_CON T1CON
 #define _Tpwm_TMR TMR1
 #define _Tpwm_PR  PR1
 #define _Tpwm_TCKPS T1CONbits.TCKPS
 #define _Tpwm_TON T1CONbits.TON
 #define _T_PWM_Interrupt _T1Interrupt
 #define _Tpwm_IP _T1IP
 #define _Tpwm_IF _T1IF
 #define _Tpwm_IE _T1IE
#elif(PWM_Timer == 2)
 #define _Tpwm_CON T2CON
 #define _Tpwm_TMR TMR2
 #define _Tpwm_PR  PR2
 #define _Tpwm_TCKPS T2CONbits.TCKPS
 #define _Tpwm_TON T2CONbits.TON
 #define _T_PWM_Interrupt _T2Interrupt
 #define _Tpwm_IP _T2IP
 #define _Tpwm_IF _T2IF
 #define _Tpwm_IE _T2IE
#elif(PWM_Timer == 3)
 #define _Tpwm_CON T3CON
 #define _Tpwm_TMR TMR3
 #define _Tpwm_PR  PR3
 #define _Tpwm_TCKPS T3CONbits.TCKPS
 #define _Tpwm_TON T3CONbits.TON
 #define _T_PWM_Interrupt _T3Interrupt
 #define _Tpwm_IP _T3IP
 #define _Tpwm_IF _T3IF
 #define _Tpwm_IE _T3IE
#elif(PWM_Timer == 4)
 #define _Tpwm_CON T4CON
 #define _Tpwm_TMR TMR4
 #define _Tpwm_PR  PR4
 #define _Tpwm_TCKPS T4CONbits.TCKPS
 #define _Tpwm_TON T4CONbits.TON
 #define _T_PWM_Interrupt _T4Interrupt
 #define _Tpwm_IP _T4IP
 #define _Tpwm_IF _T4IF
 #define _Tpwm_IE _T4IE
#elif(PWM_Timer==5)
 #define _Tpwm_CON T5CON
 #define _Tpwm_TMR TMR5
 #define _Tpwm_PR  PR5
 #define _Tpwm_TCKPS T5CONbits.TCKPS
 #define _Tpwm_TON T5CONbits.TON
 #define _T_PWM_Interrupt _T5Interrupt
 #define _Tpwm_IP _T5IP
 #define _Tpwm_IF _T5IF
 #define _Tpwm_IE _T5IE
#elif(PWM_Timer == 0 || PWM_Timer >= 5)
#error ("TIMER PARA PWM NO DEFINIDO")
#endif

#define PWM_P1 40000-1 //Periodo   =  [39999 + 1] * 6.25*10e-8 * 8(prescaler) = 20ms = 50Hz 
                           //PWM Period = [(PRy) + 1] * TCY * (Timer Prescale Value)
#define PWM_P2 4000-1 //Periodo   =  [3999 + 1] * 6.25*10e-8 * 8(prescaler) = 2ms = 500Hz 
                           //PWM Period = [(PRy) + 1] * TCY * (Timer Prescale Value)
#define PWM_P3 2048-1 //Periodo   =  [2047 + 1] * 6.25*10e-8 * 8(prescaler) = 1.0245ms = 976.08Hz 
                           //PWM Period = [(PRy) + 1] * TCY * (Timer Prescale Value)
#define PWM_P4 1024-1 //Periodo   =  [1023 + 1] * 6.25*10e-8  = 0.064ms = 15625Hz 
                           //PWM Period = [(PRy) + 1] * TCY * (Timer Prescale Value)
#define PWM_Period_Select 4
#if PWM_Period_Select == 1
    #define PWM_Period PWM_P1
#elif PWM_Period_Select == 2
    #define PWM_Period PWM_P4
#elif PWM_Period_Select == 3
    #define PWM_Period PWM_P3
#elif PWM_Period_Select == 4
    #define PWM_Period PWM_P4
#endif

//#define POSTCALER_MAX 0b11111111111111110000000000000000
extern const uint32_t Postcaler_max;
#define POSTCALER_MAX  Postcaler_max
#define POSTCALER_INCREMENT PWM_Period

extern volatile uint32_t _Tpwm_postcaler;
#define _Tpwm_Postcaler _Tpwm_postcaler
#define _Pwm_POSTMR ((uint32_t)_Tpwm_TMR)+_Tpwm_Postcaler

extern int show;
#define SHOW show

/**
  @Summary
    Inicializar PWM.
*/
void Inic_PWM(void);
/**
  @Summary
    Inicializar timer del PWM (Timer 3).
*/
void Inic_Timer_PWM(void);

/**
  @Summary
    Leer ciclo de trabajo.
  @Description
    Obtener el valor de OCXR del OC seleccionado.
  @Param
    int index = Seleccionar OC.
*/
int get_dutyCycle(int);
/**
  @Summary
    Establecer ciclo de trabajo.
  @Description
    Establecer ciclo de trabajo del OC1.
  @Param
    int dutyCycle = nuevo ciclo de trabajo.
*/
void set_dutyCicle_1(int);
/**
  @Summary
    Establecer ciclo de trabajo.
  @Description
    Establecer ciclo de trabajo del OC2.
  @Param
    int dutyCycle = nuevo ciclo de trabajo.
*/
void set_dutyCicle_2(int);
/**
  @Summary
    Establecer ciclo de trabajo.
  @Description
    Establecer ciclo de trabajo del OC3.
  @Param
    int dutyCycle = nuevo ciclo de trabajo.
*/
void set_dutyCicle_3(int);
/**
  @Summary
    Establecer ciclo de trabajo.
  @Description
    Establecer ciclo de trabajo del OC4.
  @Param
    int dutyCycle = nuevo ciclo de trabajo.
*/
void set_dutyCicle_4(int);

/**
  @Summary
    Establecer ciclo de trabajo a 0.
  @Description
    Establecer ciclo de trabajo del OC1 a 0.
*/
void zero_dutyCicle_1(void);
/**
  @Summary
    Establecer ciclo de trabajo a 0.
  @Description
    Establecer ciclo de trabajo del OC2 a 0.
*/
void zero_dutyCicle_2(void);
/**
  @Summary
    Establecer ciclo de trabajo a 0.
  @Description
    Establecer ciclo de trabajo del OC3 a 0.
*/
void zero_dutyCicle_3(void);
/**
  @Summary
    Establecer ciclo de trabajo a 0.
  @Description
    Establecer ciclo de trabajo del OC4 a 0.
*/
void zero_dutyCicle_4(void);

#endif