//#############################################################################
// $Copyright:
// Copyright (C) 2017-2023 Texas Instruments Incorporated - http://www.ti.com/
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//   Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the
//   distribution.
//
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################


//! \file   /solutions/tidm_02010_dmpfc/common/include/pfc_ctrl.h
//!
//! \brief  header file to be included in all labs
//!         support for dualmtrpfc board with F28002x/F28003x/F280013x
//!


#ifndef PFC_CTRL_H
#define PFC_CTRL_H


//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif

//*****************************************************************************
//
//! \defgroup PFC_CTRL PFC_CTRL
//! @{
//
//*****************************************************************************

// includes
#ifdef __TMS320C28XX_CLA__
#include "libraries/math/include/CLAmath.h"
#else
#include "libraries/math/include/math.h"
#include <math.h>
#endif

#include "userParams.h"

// DCL header files
#include "DCL.h"
#include "DCLF32.h"

#if !defined(__TMS320C28XX_CLA__)
#include "user.h"
#include "hal.h"
#endif

#include "power_meas_fast.h"
#include "filter_notch.h"

//*****************************************************************************
//=============================================================================
// Comp Settings; adaptive current loop coefficients
//-----------------------------------------------------------------------------
#define ACTIVE_COMP             1

#define CNTL_2p2z_B0_1  0.4104341549f
#define CNTL_2p2z_B1_1 -0.3822445616f
#define CNTL_2p2z_B2_1  0.0712511235f
#define CNTL_2p2z_A1_1 -1.1159959670f
#define CNTL_2p2z_A2_1  0.1159959670f

#define CNTL_2p2z_A1_2 -0.9999998212f
#define CNTL_2p2z_A2_2 -0.0000001788f
#define CNTL_2p2z_B0_2 1.0239908909f
#define CNTL_2p2z_B1_2 -0.4166883042f
#define CNTL_2p2z_B2_2 -0.0000000745f

#define CNTL_2p2z_A1_3 -0.9999998212f
#define CNTL_2p2z_A2_3 -0.0000001788f
#define CNTL_2p2z_B0_3 1.5359818835f
#define CNTL_2p2z_B1_3 -0.6250306444f
#define CNTL_2p2z_B2_3 -0.0000001117f

#define CNTL_2p2z_A1_4 -1.3479999276f
#define CNTL_2p2z_A2_4 0.3479999276f
#define CNTL_2p2z_B0_4 0.6304931601f
#define CNTL_2p2z_B1_4 -0.3200911809f
#define CNTL_2p2z_B2_4 0.0143992349f

#define CNTL_2p2z_A1_5 -0.9999998212f
#define CNTL_2p2z_A2_5 -0.0000001788f
#define CNTL_2p2z_B0_5 0.7824251528f
#define CNTL_2p2z_B1_5 -0.4449240626f
#define CNTL_2p2z_B2_5 -0.0000000795f

#define CNTL_2p2z_A1_6 -0.9999998212f
#define CNTL_2p2z_A2_6 -0.0000001788f
#define CNTL_2p2z_B0_6 1.0239908909f
#define CNTL_2p2z_B1_6 -0.4166883042f
#define CNTL_2p2z_B2_6 -0.0000000745f

#define CNTL_2p2z_A1_7 -0.9999998212f
#define CNTL_2p2z_A2_7 -0.0000001788f
#define CNTL_2p2z_B0_7 1.5979869793f
#define CNTL_2p2z_B1_7 -0.1597843239f
#define CNTL_2p2z_B2_7 -0.0000000286f

#define CNTL_2p2z_A1_8 -1.5000116470f
#define CNTL_2p2z_A2_8 0.5000116470f
#define CNTL_2p2z_B0_8 3.9819395248f
#define CNTL_2p2z_B1_8 -2.1179877593f
#define CNTL_2p2z_B2_8 0.2080011570f

#define CNTL_2p2z_A1_9 -1.5000116470f
#define CNTL_2p2z_A2_9 0.5000116470f
#define CNTL_2p2z_B0_9 1.9909697624f
#define CNTL_2p2z_B1_9 -1.0589938796f
#define CNTL_2p2z_B2_9 0.1040005785f
//
#define CNTL_2p2z_A1_10 1.0000000000f
#define CNTL_2p2z_A2_10 0.0000000000f
#define CNTL_2p2z_B0_10 0.2505000000f
#define CNTL_2p2z_B1_10 -0.2495000000f
#define CNTL_2p2z_B2_10 0.0000000000f

//=============================================================================
#define P_OVER_VOLTAGE_AC_BIT       0x0001    // AC Bus Over Voltage Fault
#define P_UNDER_VOLTAGE_AC_BIT      0x0002    // AC Bus Under Voltage Fault
#define P_OVER_VOLTAGE_DC_BIT       0x0004    // DC Bus Over Voltage Fault
#define P_UNDER_VOLTAGE_DC_BIT      0x0008    // DC Bus Under Voltage Fault

#define P_MODULE_OVER_CURRENT_BIT   0x0010    // Hardware Over Current Fault
#define P_OVER_PEAK_CURRENT_BIT     0x0020    // internal CMPSS Over Current Fault
#define P_MOTOR_OVER_LOAD_BIT       0x0040    // Over Load Error
#define P_MULTI_OVER_CURRENT_BIT    0x0080    // Multiple times over current

#define P_MODULE_OVER_TEMPER_BIT    0x0100    // Module over temperature Fault
#define P_SHUNT_DOWN_VOLTAGE_BIT    0x0200    // Over voltage to shut down
#define P_RESERVE_10_BIT            0x0400    // Reserved for further use
#define P_RESERVE_11_BIT            0x0400    // Reserved for further use

#define P_RESERVE_12_BIT            0x1000    // Reserved for further use
#define P_RESERVE_13_BIT            0x2000    // Reserved for further use
#define P_RESERVE_14_BIT            0x4000    // Reserved for further use
#define P_RESERVE_15_BIT            0x8000    // Reserved for further use

#define P_MASK_ALL_FAULT_BITS       0x0000
#define P_ENABLE_ALL_FAULT_BITS     0xFFFF

#define P_OVER_CURRENT_BITS         P_MODULE_OVER_CURRENT_BIT                  \
                                  + P_OVER_PEAK_CURRENT_BIT                    \
                                  + P_MOTOR_OVER_LOAD_BIT                      \
                                  + P_MULTI_OVER_CURRENT_BIT

#define P_OVER_VOLTAGE_BITS         P_OVER_VOLTAGE_AC_BIT                      \
                                  + P_UNDER_VOLTAGE_AC_BIT                     \
                                  + P_OVER_VOLTAGE_DC_BIT                      \
                                  + P_UNDER_VOLTAGE_DC_BIT                     \
                                  + P_SHUNT_DOWN_VOLTAGE_BIT

//
// Block all fault protection except current, voltage and temperature faults
//
#define PFC_FAULT_ENABLE_OC             P_MODULE_OVER_CURRENT_BIT              \
                                      + P_OVER_PEAK_CURRENT_BIT                \
                                      + P_MODULE_OVER_TEMPER_BIT

#define PFC_FAULT_ENABLE_OC_DCOUV       P_OVER_VOLTAGE_DC_BIT                  \
                                      + P_UNDER_VOLTAGE_DC_BIT                 \
                                      + P_MODULE_OVER_CURRENT_BIT              \
                                      + P_OVER_PEAK_CURRENT_BIT

#define PFC_FAULT_ENABLE_OC_OUV         P_OVER_VOLTAGE_AC_BIT                  \
                                      + P_UNDER_VOLTAGE_AC_BIT                 \
                                      + P_OVER_VOLTAGE_DC_BIT                  \
                                      + P_UNDER_VOLTAGE_DC_BIT                 \
                                      + P_MODULE_OVER_CURRENT_BIT              \
                                      + P_OVER_PEAK_CURRENT_BIT
//
// Enable all fault protection
//
#define PFC_FAULT_ENABLE_ALL            P_OVER_VOLTAGE_AC_BIT                  \
                                      + P_UNDER_VOLTAGE_AC_BIT                 \
                                      + P_OVER_VOLTAGE_DC_BIT                  \
                                      + P_UNDER_VOLTAGE_DC_BIT                 \
                                      + P_MODULE_OVER_CURRENT_BIT              \
                                      + P_OVER_PEAK_CURRENT_BIT                \
                                      + P_MOTOR_OVER_LOAD_BIT                  \
                                      + P_MULTI_OVER_CURRENT_BIT               \
                                      + P_MODULE_OVER_TEMPER_BIT

#define PFC_FAULT_DISABLE_ALL         0x0000

#if defined(BSXL8320RS_REVA) || defined(DRV8312KIT_REVD)
#define PFC_FAULT_MASK_SET          PFC_FAULT_DISABLE_ALL
#else
#if (PFC_BUILDLEVEL <= PFC_LEVEL_2)
#define PFC_FAULT_MASK_SET          PFC_FAULT_ENABLE_OC
#else   // (PFC_BUILDLEVEL >= PFC_LEVEL_3)
#define PFC_FAULT_MASK_SET          PFC_FAULT_ENABLE_ALL
#endif  // (PFC_BUILDLEVEL > PFC_LEVEL_2)
#endif //  !(BSXL8320RS_REVA || DRV8312KIT_REVD)

//
//! \brief typedefs for the fault
//
typedef struct _FAULT_PFC_BITS_
{             // bits  description
    uint16_t overVoltageAC:1;       // 0  AC Bus Over Voltage Fault
    uint16_t underVoltageAC:1;      // 1  AC Bus Under Voltage Fault
    uint16_t overVoltageDC:1;       // 2  DC Bus Over Voltage Fault
    uint16_t underVoltageDC:1;      // 3  DC Bus Under Voltage Fault

    uint16_t moduleOverCurrent:1;   // 4  Hardware Over Current Fault Flag
    uint16_t overPeakCurrent:1;     // 5  internal CMPSS Over Current Fault Flag
    uint16_t overLoad:1;            // 6  Over Load Error
    uint16_t multiOverCurrent:1;    // 7  Multiple times over current

    uint16_t moduleOverTemp:1;      // 8  Power module over temperature Fault
    uint16_t shutDownVoltage:1;     // 9  DC bus over voltage to shut down PFC
    uint16_t reserve10:1;           // 10 Reserved
    uint16_t reserve11:1;           // 11 Reserved

    uint16_t reserve12:1;           // 12 Reserved
    uint16_t reserve13:1;           // 13 Reserved
    uint16_t reserve14:1;           // 14 Reserved
    uint16_t reserve15:1;           // 15 Reserved
} FAULT_PFC_BITS;

typedef union _FAULT_PFC_t
{
    uint16_t        all;
    FAULT_PFC_BITS  bit;
}FAULT_PFC_t;

//******************************************************************************
// typedefs
typedef struct _PFC_Vars_t_
{
    float32_t lpfVdcCoeff;

    float32_t VdcBus_V;
    float32_t VdcBus_pu;
    float32_t VdcBusLPF;
    float32_t VdcBusNotch;
    float32_t VdcBusShutDown;
    float32_t VdcBusLPF_V;
    float32_t VdcBusOverOff_V;

    float32_t currentBus_A;
    float32_t overCurrent_A;
    float32_t dutyOutMaxSet;
    float32_t IdcRefMaxSet;

    float32_t IacPeak_pu;
    float32_t VacComp_V;
    float32_t IacCompFactor;
    float32_t IdcmCompFactor;
    float32_t IacSen;
    float32_t IacError;

    float32_t VacRms_pu;
    float32_t IacRms_pu;

    float32_t VacRms_V;
    float32_t IacRms_A;
    float32_t PowerRms_W;
    float32_t FreqAc_Hz;
    float32_t FreqGrid_Hz;
    float32_t TsFilter_sec;

    float32_t VacRmsGainThs_V;
    float32_t IdcRefGainThsHV;
    float32_t IdcRefGainThsLV;

    float32_t invRmsSqrVminOverVmax;
    float32_t invRmsSqrVmin;
    float32_t IacRefVmaxOverVmin;
    float32_t invRmsSqrCoef;

    float32_t VinvSqr;
    float32_t IdcRefOut;
    float32_t IdcRef;
    float32_t IacRef;

    float32_t IdcRefSwILOff;
    float32_t IdcRefSwILOn;

    float32_t dutyOut;
    float32_t giOut;

    float32_t VdcSet_V;
    float32_t VdcTrajTraget;
    float32_t VdcTrajInt;
    float32_t VdcTrajRate;

    uint32_t ISRCount;
    uint32_t timerCnt_5ms;

#ifdef DEBUG_MONITOR_EN
    float32_t VdcBusMax_V;
    float32_t VdcBusMin_V;
    uint16_t  flagClearRecord;
#endif  // DEBUG_MONITOR_EN

    uint16_t  dacCMPValH;
    uint16_t  dacCMPValL;

    uint16_t  counterVoltage;
    uint16_t  indexCurrentGain;
    uint16_t  indexVoltageGain;

    FAULT_PFC_t faultPFCNow;
    FAULT_PFC_t faultPFCUse;
    FAULT_PFC_t faultPFCMask;
    FAULT_PFC_t faultPFCPrev;

    bool flagEnablePFC;
    bool flagEnableCurrentLoop;
    bool flagEnableVoltageLoop;
    bool flagFirstVoltageLoop;
    bool flagStatePFC;

    bool flagEnableILMode;
    bool flagEnableOffsetCalc;
    bool flagEnableChangeGain;

    bool flagClearFaults;
}PFC_Vars_t;

typedef struct _PFC_CtrlVars_t_
{
    float32_t overVoltageFault_ACV;
    float32_t overVoltageNorm_ACV;
    float32_t underVoltageFault_ACV;
    float32_t underVoltageNorm_ACV;

    float32_t overVoltageFault_DCV;
    float32_t overVoltageNorm_DCV;
    float32_t underVoltageFault_DCV;
    float32_t underVoltageNorm_DCV;

    float32_t overCurrentFault_A;
    float32_t overLoadFault_W;

    uint16_t voltageAcFaultTimeSet;
    uint16_t voltageDcFaultTimeSet;
    uint16_t overLoadFaultTimeSet;

    uint16_t overCurrentFaultTimesSet;

    uint16_t overVoltageAcTimeCnt;
    uint16_t underVoltageAcTimeCnt;
    uint16_t overVoltageDcTimeCnt;
    uint16_t underVoltageDcTimeCnt;
    uint16_t overLoadTimeCnt;

    uint16_t overCurrentFaultTimesCnt;
}PFC_CtrlVars_t;

//*****************************************************************************
extern volatile PFC_Vars_t pfcVars;
extern volatile PFC_CtrlVars_t pfcCtrlVars;

extern HAL_PFC_ADCData_t adcDataPFC;
extern HAL_PFC_PWMData_t pwmDataPFC;

extern HAL_PFC_Handle halPFCHandle;
extern HAL_PFC_Obj    halPFC;

extern DCL_DF22 gi;
extern DCL_PI   gv;

extern POWER_MEAS_FAST measPower;

#if defined(NOTCH_FILTER)
// notch filter
extern FILTER_NOTCH_Obj    filterNotch;
extern FILTER_NOTCH_Handle filterNotchHandle;

extern FILTER_COEFF_Obj    filterCoeff;
extern FILTER_COEFF_Handle filterCoeffHandle;
#endif  // NOTCH_FILTER


//*****************************************************************************
//! \brief initialize PFC control parameters
extern void initPFCCtrlParameters(void);

//! \brief run PFC control in main loop
extern void runPFCMainControl(void);

//! \brief run PFC monitor in main loop timer
extern void runPFCMonitor(void);

//! \brief run offset calibration for PFC
extern void runPFCOffsetsCalculation(void);

//! \brief calculate PFC over current threshold
static inline void calcPFCOverCurrentThreshold(void)
{
    int16_t cmpValue = (int16_t)(pfcVars.overCurrent_A *
            (USER_PFC_CURRENT_INV_SF * MATH_SQRT_TWO));

    pfcVars.IacPeak_pu = pfcVars.overCurrent_A *
            (MATH_SQRT_TWO / USER_PFC_ADC_FULL_SCALE_CURRENT_A);

    pfcVars.dacCMPValH = PFC_CMPSS_OFFSET_VALUE + cmpValue;

    if(pfcVars.dacCMPValH > 4095)
    {
        pfcVars.dacCMPValH = 4095;
    }

    pfcVars.dacCMPValL = 4095U -
            ((uint16_t)(pfcVars.VdcBusOverOff_V * (4096.0f / USER_PFC_ADC_FULL_SCALE_AC_VOLTAGE_V)));

    return;
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif // extern "C"

#endif // end of PFC_CTRL_H definition
