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

#include "main.h"

typedef enum{
    CALIBRADO,
    TAKE_MIN,
    TAKE_MAX
} Estado;

const uint32_t Postcaler_max = 0xffffffff | !(PWM_Period);
volatile uint32_t _Tpwm_postcaler;

void Inic_PWM(void)
{
    
    Inic_Timer_PWM();
    
    OC1CON = 0;// Izquierdo atras
        OC1CONbits.OCM = 0b000; // Deshabilita módulo Output Compare
        OC1R = 0; // Escribe el duty cycle para el primer pulso PWM
        OC1RS = 0; // Escribe el duty cycle para el segundo pulso PWM
        OC1CONbits.OCTSEL = PWM_Timer%2; // Selecciona el timer: 1 = Timer 3 y 0 = Timer 2
        OC1CONbits.OCM = 0b110; // Selecciona el modo PWM sin protección
    OC2CON = 0;// Derecho atras
        OC2CONbits.OCM = 0b000; // Deshabilita módulo Output Compare
        OC2R = 0; // Escribe el duty cycle para el primer pulso PWM
        OC2RS = 0; // Escribe el duty cycle para el segundo pulso PWM
        OC2CONbits.OCTSEL = PWM_Timer%2; // Selecciona el timer: 1 = Timer 3 y 0 = Timer 2
        OC2CONbits.OCM = 0b110; // Selecciona el modo PWM sin protección
    OC3CON = 0;//Izquierdo Adelante
        OC3CONbits.OCM = 0b000; // Deshabilita módulo Output Compare
        OC3R = 0; // Escribe el duty cycle para el primer pulso PWM
        OC3RS = 0; // Escribe el duty cycle para el segundo pulso PWM
        OC3CONbits.OCTSEL = PWM_Timer%2; // Selecciona el timer: 1 = Timer 3 y 0 = Timer 2
        OC3CONbits.OCM = 0b110; // Selecciona el modo PWM sin protección
    OC4CON = 0;//Derecho adelante
        OC4CONbits.OCM = 0b000; // Deshabilita módulo Output Compare
        OC4R = 0; // Escribe el duty cycle para el primer pulso PWM
        OC4RS = 0; // Escribe el duty cycle para el segundo pulso PWM
        OC4CONbits.OCTSEL = PWM_Timer%2; // Selecciona el timer: 1 = Timer 3 y 0 = Timer 2
        OC4CONbits.OCM = 0b110; // Selecciona el modo PWM sin protección
        
    _OC1IP = 0;
    _OC1IF = 0;
    _OC1IE = 0; // Borra flag interrupción
}
void Inic_Timer_PWM(void)
{
    _Tpwm_TMR = 0; // Borra el timer
    _Tpwm_CON = 0;
    
    _Tpwm_PR = PWM_Period;

    _Tpwm_TCKPS = 0;//Valor del prescaler 0 -> x1

    _Tpwm_IF = 0; // Borra flag interrupción
    _Tpwm_IE = 1; // Habilita Interrupción 

    _Tpwm_TON = 1; // Activa Timer del PWM
    
    _Tpwm_Postcaler = 0;//0xfffff000; 
}

int get_dutyCycle(int index){
    switch (index){
        case 1: return OC1R;
        case 2: return OC2R;
        case 3: return OC3R;
        case 4: return OC4R;
       default: return -1;
    }
}
void set_dutyCicle_1(int dutyCycle)
{
    OC1RS = dutyCycle;
    pwm_cf.DCC = 1;
}
void set_dutyCicle_2(int dutyCycle)
{
    OC2RS = dutyCycle;
    pwm_cf.DCC = 1;
}
void set_dutyCicle_3(int dutyCycle)
{
    OC3RS = dutyCycle;
    pwm_cf.DCC = 1;
}
void set_dutyCicle_4(int dutyCycle)
{
    OC4RS = dutyCycle;
    pwm_cf.DCC = 1;
}

void zero_dutyCicle_1(void)
{
    OC1RS = 0;
    pwm_cf.DCC = 1;
}
void zero_dutyCicle_2(void)
{
    OC2RS = 0;
    pwm_cf.DCC = 1;
}
void zero_dutyCicle_3(void)
{
    OC3RS = 0;
    pwm_cf.DCC = 1;
}
void zero_dutyCicle_4(void)
{
    OC4RS = 0;
    pwm_cf.DCC = 1;
}


void __attribute__((interrupt(auto_psv))) _T_PWM_Interrupt(void){    
    _Tpwm_Postcaler+=POSTCALER_INCREMENT;
            
    _Tpwm_IF = 0; // Borra flag interrupción
}