/********************************************************************
* Copyright (C) 2016 Microchip Technology Inc. and its subsidiaries
* (Microchip).  All rights reserved.
*
* You are permitted to use the software and its derivatives with Microchip
* products. See the license agreement accompanying this software, if any, for
* more info about your rights and obligations.
*
* SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
* PURPOSE. IN NO EVENT SHALL MICROCHIP, SMSC, OR ITS LICENSORS BE LIABLE OR
* OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH
* OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY FOR ANY DIRECT OR INDIRECT
* DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES, OR OTHER SIMILAR COSTS. To the fullest
* extend allowed by law, Microchip and its licensors liability will not exceed
* the amount of fees, if any, that you paid directly to Microchip to use this
* software.
*************************************************************************
*
*                           HardwareProfile.c
*
* Hardware Profile source file
*
*
* Hardware:
*  Flyback SMPS using PIC16F1769
*
* Author                          Date            Ver     Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Turcan Gheorghe M15725          2016.10.12      0.6       MPLABX V3.30  XC8 V1.37
******************************************************************************/

#include "HardwareProfile.h"

void Flyback_Init()
{
    //___________________Core CIP register settings_______________________________
    
    //OSCCON: OSCILLATOR CONTROL REGISTER
    OSCCON = 	0b01110000;     // Internal Oscillator Frequency = 8MHz // 32MHz if PLL is enable

    //Configure CCP1 for base switching frequency of the SMPS
    CCPTMRS =   0b00000000;     //CCP1 and CCP2 are based off Timer2 in PWM mode
    T2CLKCON =  0b00000001;     //Timer 2 clock source is Fosc/4
    T2CON =     0b10000000;     //Timer 2 on
    PR2 =       0x3F;           //125kHz frequency - 0x3F 
    
    CCP1CON =   0b10001100;     //CCP1 on in PWM mode
    CCPR1H =    0x00;
    CCPR1L =    0xF0;           //This value sets the Slope Compensation beginning
    
    //CCP2 is used for maximum duty-cycle limiting
    CCP2CON =   0b10001100;     //CCP2 on in PWM mode
    CCPR2H =    0x00;
    CCPR2L =    0x02;           //Duty-cycle limit -changed later in software for soft start   
    
    //CLC1 configured for Ramp Rising Event - Slope Delay Function
    CLC1CON =   0b10000010;     //CLC1 configured as an 4 input - AND / enabled
    CLC1POL =   0b00001100;     //Gate 3 and 4 are Inverse Polarity
    
    CLC1SEL0 =  0b00001011;     //Connect COG1A_out to CLC1 Data1
    CLC1SEL1 =  0b00001111;     //Connect CCP1_out out to CLC1 Data2
    
    CLC1GLS0  = 0b00000001;     //CLC1 Gate1 will use Data1 Negated  
    CLC1GLS1  = 0b00000001;     //CLC1 Gate2 will use Data1 Negated  
    CLC1GLS2  = 0b00000100;     //CLC1 Gate3 will use Data2 Negated  
    CLC1GLS3  = 0b00000100;     //CLC1 Gate4 will use Data2 Negated  
    RB5PPS    = 0b00000001;     //CLC1 Out is set to be connected at RB5
    
    //Programmable Ramp Generator to implement a Slope Compensator
    PRG1CON0 =  0b10110000;     //PRG enable                               
    PRG1CON1 =  0b00000001;     //Rising polarity is active low  
    PRG1INS =   0x01;           //Voltage input source is set to PRG1IN1--RC3
    PRG1CON2 =  0x01;           //Slope Rate is set to 0.2V/us
    PRG1RTSS =  0b00001001;     //Rising time from CCP1_out negated
    PRG1FTSS =  0b00000100;     //Falling time from PRG1F PIN
    
    PRG1FPPS =  0b00001101;     //PRG1F is set to RB5 (CLC1_Out)
    PRG1CON0 |=  0b00000001;    //Enable slope  
    
       
    //CMxCON: COMPARATOR Cx CONTROL REGISTER for Peak Current Mode Detection
    CM2CON0 =   0b10000000;     //Comparator is enabled, Comparator output non-inverted
    CM2CON1 =   0b00000000;     //No interrupts are enabled
    CM2NSEL =   0b00000001;     //Comparator Negative input connected to C2IN1-/RC1
    CM2PSEL =   0b00001000;     //Comparator Positive input connected to PRG1_output
     
    //Configure COG for 1 output, CCP1 rise, CCP2, C1&C3 fall
    COG1CON0 =  0b00001000;     //COG disabled, COG clock is Fosc, steered PWM mode
    COG1CON1 =  0b00000000;     //Active output high
    COG1RIS0 =  0b00100000;     //CCP1 as rising event
    COG1RSIM0 = 0b00100000;     //CCP1 low-to-high transition will cause a rising event
    COG1FIS0 =  0b01001100;     //CCP2, Comparator 3 and Comparator 2 is used as falling event
    COG1FSIM0 = 0b01000000;     //Comparator 2 and 3 level will cause a falling event, CCP2 high to low transition will cause a falling event
    COG1STR =   0b00000001;     //Polarity control from POLA bit
    RC0PPS =        0b00000100;     //COG1A output to pin C0 
    
    //FVR is configured as reference for the OPAMP positive input
    FVRCON =    0b11001000;     //fvr BUFFER 2 is set to 2X Gain  
    
    //DAC configuration for primary side current control
    DAC1CON0 =  0b10000000;     //DAC enabled, VDD as + source, VSS as - source
    DAC1REFH = 0x01;
    DAC1REFL =  0x6A;
    DACLD   =   0x01;
    
    //Configure OPA1 as CM3 reference for Maximum Current limiting//Ramp repeater
    OPA1CON =   0b10010000;     // Enable, unity gain
   // OPA1NCHS =  0b00001000;     // OPA1IN0- is selected as negative input
    OPA1PCHS =  0b00001000;     // FVR_Buffer 2 is selected as positive input//PRG1Out--RC3
    
    //CMxCON: COMPARATOR Cx CONTROL REGISTER for Maximum Current limiting
    CM3CON0 =   0b10000000;     //Comparator is enabled, Comparator output non-inverted
    CM3CON1 =   0b00000000;     //No interrupts are enabled
    CM3NSEL =   0b00000001;     //Comparator Negative input connected to C3IN1--RC1
    CM3PSEL =   0b00001010;     //Comparator Positive input connected to DAC1_out 
   
#if (ShortCircuitProtection == ON )
    //Configure DAC4 as Comp4 positive input for Short Circuit protection
    DAC4CON0 =  0b10000000;     //DAC enabled, VDD as + source, VSS as - source
    DAC4REF =   ShortCircuitDetectValue;     

    //CMxCON: COMPARATOR Cx CONTROL REGISTER for Short Circuit protection
    CM4CON0 =   0b10010010;     //Comparator is enabled, Comparator output inverted
    CM4NSEL =   0b00000011;     //Comparator Negative input connected to CxIN3-
    CM4PSEL =   0b00001101;     //Comparator Positive input connected to DAC4_output

    INTCON |=   0b11000000;     //Enable Global I
#endif

    //Port A configuration
    TRISA = 	0b11111011;
    ANSELA = 	0b11110011;
    LATA2 = 1;                  //RC2 Configured to Supply the Current Sensing Offset

    //Port B configuration
    TRISB = 	0b11010000;
    ANSELB = 	0b11010000;

    //Port C configuration
    TRISC = 	0b01101010;
    ANSELC = 	0b01101010;   

    __delay_ms(0.1);
    
   
#if (SoftStartFunction == OFF )
    COG1CON0 |=      0b10000000;     //COG Enabled
    
#if (MaxDutyCycleLimit == OFF )
    CCPR2L	=       0x85;
#else
    CCPR2L	=       MaxDutyCycleValue;
#endif
        
#if ( ShortCircuitProtection == ON )
        __delay_ms(10);
        PIR2bits.C4IF = 0;
        PIE2bits.C4IE = 1;          //CM4 interrupt enabled
        CM4CON1bits.C4INTP = 1;
        
        if(CM4CON0bits.C4OUT == 1)
            {
                PIR2bits.C4IF = 1;
            }
        
#endif
#endif        
}

#if ( SoftStartFunction == ON )
void Flyback_SoftStart()
{
    COG1CON0 =      0b10000000;     //COG Enabled
    
    // CCP2 limiting the maximum duty cycle for implementing a SoftStart function
    __delay_ms(0.2);
    CCPR2L	=       0x06;
    __delay_ms(0.4);
    CCPR2L	=       0x0A;
    __delay_ms(0.4);
    CCPR2L	=       0x0F;
    __delay_ms(0.2);
    CCPR2L	=       0x12;
    __delay_ms(0.2);
    CCPR2L	=       0x15;
    __delay_ms(0.2);
    CCPR2L	=       0x25;
    __delay_ms(0.2);
    CCPR2L	=       0x3A;
    __delay_ms(0.2); 
    
    #if ( MaxDutyCycleLimit == OFF ) 
        CCPR2L	=       0xCA;
    #else
        CCPR2L = MaxDutyCycleValue;
    #endif
    
    #if ( ShortCircuitProtection == ON )

        __delay_ms(10);

        PIR2bits.C4IF = 0;
        PIE2bits.C4IE = 1;          //CM4 interrupt enabled
        CM4CON1bits.C4INTP = 1;
        
        if(CM4CON0bits.C4OUT == 1)
            {
                PIR2bits.C4IF = 1;
            }   

    #endif
}
#endif

#if ( ShortCircuitProtection == ON )

#if ( ShortCircuitLimitedRetry == ON )
    static volatile int count = 1;
#endif
    
void  interrupt SC_ISR()
{
    if ((PIR2bits.C4IF)&&(PIE2bits.C4IE))
    {
        CM4CON1bits.C4INTP = 0;
        PIR2bits.C4IF = 0;        //Clear interrupt flag
        COG1ASD0 =  0b10001000;     //Shut Down COG 
        LATB5 = 0;                  //Stop Power delivery to RC4
        OSCCON =    0b01000000;     //OSC Frequency changed to 125kHz
        __delay_ms(SCTimeBetweenRetries*16);
        
        #if ( ShortCircuitLimitedRetry == ON )
                if (count < ShortCircuitRetryTimes)
                {
        #endif

        OSCCON =    0b01110000;     //OSC Frequency changed to 8MHz
        LATB5 = 1;                  //Deliver Power to RC4
        CCPR2L	=       0x02;
        COG1ASD0 =  0b00001000;     //Start COG

        #if ( SoftStartFunction == ON )
                Flyback_SoftStart();
        #else

            #if (MaxDutyCycleLimit == OFF )
                CCPR2L	=       0x90;
            #else
                CCPR2L	=       MaxDutyCycleValue;
            #endif

            __delay_ms(10);
            PIR2bits.C4IF = 0;
            PIE2bits.C4IE = 1;          //CM4 interrupt enabled
            CM4CON1bits.C4INTP = 1;

            if(CM4CON0bits.C4OUT == 1)
                {
                    PIR2bits.C4IF = 1;
                }

        #endif

        #if ( ShortCircuitLimitedRetry == ON )
                }
                else
                {
                    // Add your own code to handle short-circuit
                }

                count ++;
        #endif
    }
}
#endif

