//#############################################################################
// $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/source/sys_main.c
//! \brief  This project is used to control two motor and pfc with one MCU
//!         Support for dualmtrpfc board with F28002x/F28003x/F280013x
//!

//
// include the related header files
//
#if defined(SYSCONFIG_EN)
#include "user.h"
#include "board.h"
#endif  // SYSCONFIG_EN

#include "sys_settings.h"
#include "sys_main.h"
#include "systems.h"
#include "math.h"
#include "string.h"

//Global
unsigned int cpuTimer1IntCount=0;
unsigned int cpuTimer2IntCount=0;
unsigned int b=0;
unsigned char compressor1motorFlag = false;
static unsigned char ucRxBuff[10]={0};
//
// Globals
//
volatile bool rx_flag=0;
volatile bool tx_flag=0;
//extern volatile bool cx_flag;
volatile uint8_t CompressorStartFlag=0;
unsigned int uiRxByteCntr=0;
char ucRxStatus = 'H';
char ucRxStatus1;

//unsigned int uiRxByteLen=4;
unsigned int uiRxByteLenCntr=0;
#define ODU_HEADER  '$'
// Send data for SCI-A
char sDataA[] = "RR120.50#";
// Received data for SCI-A
uint16_t rDataA[1];
char rxflag=0;
static unsigned char rx_data;
static unsigned char rx_data_save;
unsigned int uiTempValue = 0;
unsigned int uiTempValue1 = 0;
// Used for checking the received data
uint16_t rDataPointA;
// Function Prototypes
//
__interrupt void INT_SCI_COM_TX_ISR(void);
__interrupt void INT_SCI_COM_RX_ISR(void);
void initSCIAFIFO(void);
void error(void);
volatile SYSTEM_Vars_t systemVars;
#pragma DATA_SECTION(systemVars,"user_data");

#if defined(EPWMDAC_MODE)
HAL_PWMDACData_t pwmDACData;
#pragma DATA_SECTION(pwmDACData,"user_data");
#endif  // EPWMDAC_MODE

#if defined(DAC128S_ENABLE)
#if defined(DAC80504_SEL)
DAC80504_Handle  dac128sHandle;       //!< the DAC80504 interface handle
DAC80504_Obj     dac128s;             //!< the DAC80504 interface object
#else   // DAC128S805
DAC128S_Handle   dac128sHandle;        //!< the DAC128S interface handle
DAC128S_Obj      dac128s;              //!< the DAC128S interface object
#endif  // DAC128S805

#pragma DATA_SECTION(dac128sHandle,"sys_data");
#pragma DATA_SECTION(dac128s,"sys_data");
//#define DACTEST_EN
#if defined(DACTEST_EN)
float32_t dacTestValue[4];
#pragma DATA_SECTION(dacTestValue,"sys_data");
#endif  // DACTEST
#endif  // DAC128S_ENABLE

//------------------ADDED-09-02-2024------------------------------
#define ADC_RESOLUTION_VALUE                (4096.0f) //(4896.0f) //(4096.0f)   //(400.0f)
#define LOG_10_E                            (0.434294f)
#define TEMP_T_25_K                         (298.15f)//kevin
//air temperature
#define TEMP_AIR_RES_T_25                   (10000.0f)//(10000U)//Ohm
#define TEMP_AIR_BETA                       (3950.0f)
#define TEMP_AIR_RES_GND                    (10000.0f)//Ohm
volatile float fTempValue;
unsigned int tempnewvalue1,tempnewvalue2,tempnewvalue3;
//float32_t Temp_Sensor_Ambient,Temp_Sensor1,value,Temp_Sensor_coils,Temp_Sensor_Pipes;
static float ntc_sensor_get_temp(float res, uint16_t res_25, uint16_t beta);
__interrupt void INT_CPU_TIMER1_ISR(void);
void configCPUTimer(uint32_t, float, float);

// **************************************************************************
// the functions
//INT_MTR1_EMI_1_ISR

void main(void)
{
    unsigned char *msg;
    ucRxStatus ='H';
      // Clear memory for system and controller
    // The variables must be assigned to these sector if need to be cleared to zero
    HAL_clearDataRAM((void *)loadStart_est_data, (uint16_t)loadSize_est_data);
    HAL_clearDataRAM((void *)loadStart_user_data, (uint16_t)loadSize_user_data);
    HAL_clearDataRAM((void *)loadStart_sys_data, (uint16_t)loadSize_sys_data);
    HAL_clearDataRAM((void *)loadStart_foc_data, (uint16_t)loadSize_foc_data);
    HAL_clearDataRAM((void *)loadStart_pfc_data, (uint16_t)loadSize_pfc_data);
    HAL_clearDataRAM((void *)loadStart_motor_data, (uint16_t)loadSize_motor_data);
    HAL_clearDataRAM((void *)loadStart_dmaBuf_data, (uint16_t)loadSize_dmaBuf_data);
    HAL_clearDataRAM((void *)loadStart_vibc_data, (uint16_t)loadSize_vibc_data);
    HAL_clearDataRAM((void *)loadStart_sfra_data, (uint16_t)loadSize_sfra_data);
    HAL_clearDataRAM((void *)loadStart_datalog_data, (uint16_t)loadSize_datalog_data);
    HAL_clearDataRAM((void *)loadStart_dbgc_data, (uint16_t)loadSize_dbgc_data);

    uint16_t* read_ADC_Value=(uint16_t*) 0x00000B40;
    uint16_t* read_ADC_Value1=(uint16_t*) 0x00000B41;
    uint16_t* read_ADC_Value2=(uint16_t*) 0x00000B42;
//    AdcData1 = *read_ADC_Value;
//    AdcData2 = *read_ADC_Value1;
#if defined(DMCPFC_REV3P2)
    systemVars.boardKit = BOARD_DMCPFC_REV3P2;      // DMCPFC_REV3P1 for F28002x/3x/13x-64pin
#elif defined(DMCPFC_REV3P1)
    systemVars.boardKit = BOARD_DMCPFC_REV3P1;      // DMCPFC_REV3P1 for F28002x-64pin
#elif defined(HVMTRPFC_REV1P1)
    systemVars.boardKit = BOARD_HVMTRPFC_REV1P1;    // HVMTRPFC_REV1P1 for F28002x
#elif defined(BSXL8323RH_REVB)
    systemVars.boardKit = BOARD_BSXL8323RH_REVB;    // BSXL8323RH_REVA for F28002x
#else
#error Not select a right board for this project
#endif

#if defined(MOTOR1_DISABLE) && defined(MOTOR2_DISABLE) && defined(PFC_DISABLE)
#error Need to enable at least one function of PFC, MOTOR1, or MOTOR2
#endif //

#if defined(MOTOR1_DISABLE)
    systemVars.estType_M1 = EST_TYPE_NO_OBSERVER;   // this motor is disable
#elif defined(MOTOR1_FAST) && defined(MOTOR1_ESMO)
    systemVars.estType_M1 = EST_TYPE_FAST_ESMO;    // the estimator is FAST and ESMO
#elif defined(MOTOR1_FAST)
    systemVars.estType_M1 = EST_TYPE_FAST;         // the estimator is only FAST
#elif defined(MOTOR1_ESMO)
    systemVars.estType_M1 = EST_TYPE_ESMO;         // the estimator is only ESMO
#else   // !MOTOR1_FAST & !MOTOR1_ESMO
#error Not select a right estimator for motor 1 in this project
#endif  // !MOTOR1_FAST & !MOTOR1_ESMO

#if defined(MOTOR2_DISABLE)
    systemVars.estType_M2 = EST_TYPE_NO_OBSERVER;   // this motor is disable
#elif defined(MOTOR2_FAST) && defined(MOTOR2_ESMO)
    systemVars.estType_M2 = EST_TYPE_FAST_ESMO;     // the estimator is FAST and ESMO
#elif defined(MOTOR2_FAST)
    systemVars.estType_M2 = EST_TYPE_FAST;          // the estimator is only FAST
#elif defined(MOTOR2_ESMO)
    systemVars.estType_M2 = EST_TYPE_ESMO;          // the estimator is only ESMO
#else   //  !MOTOR2_FAST & !MOTOR2_ESMO
#error Not select a right estimator for motor 2 in this project
#endif  //  !MOTOR2_FAST & !MOTOR2_ESMO

#if defined(MOTOR1_FAST) && defined(MOTOR1_ESMO) && \
    defined(MOTOR2_FAST) && defined(MOTOR2_ESMO) && defined(_F28002x)
#error Limit to the RAM size for copy the program to run in RAM. FAST and ESMO
    can not on dual motor at the same. Only support one motor runs FAST and ESMO
    in parallel, and another motor run FAST or ESMO.
#endif  //  MOTOR1_FAST & MOTOR1_ESMO & MOTOR2_FAST & MOTOR2_ESMO

#if defined(MOTOR1_DCLINKSS)
    systemVars.currentSenseType_M1 = CURSEN_TYPE_SINGLE_SHUNT;
#else
    systemVars.currentSenseType_M1 = CURSEN_TYPE_THREE_SHUNT;
#endif  // Current Sense Type of Motor 1

#if defined(MOTOR2_DCLINKSS)
    systemVars.currentSenseType_M2 = CURSEN_TYPE_SINGLE_SHUNT;
#else
    systemVars.currentSenseType_M2 = CURSEN_TYPE_THREE_SHUNT;
#endif  // Current Sense Type of Motor 2

// ** above codes are only for checking the settings, not occupy the memory

    // Initialize device clock and peripherals
    Device_init();                  // call the function in device.c

    // Disable pin locks and enable internal pullups.
    Device_initGPIO();              // call the function in device.c

    // GPIO28 is the SCI Rx pin.
       //
       GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIRXDC);
       GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCIRXDC, GPIO_DIR_MODE_IN);
       GPIO_setPadConfig(DEVICE_GPIO_PIN_SCIRXDC, GPIO_PIN_TYPE_STD);
       GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCIRXDC, GPIO_QUAL_ASYNC);
       //
       // GPIO29 is the SCI Tx pin.
       //
       GPIO_setPinConfig(DEVICE_GPIO_CFG_SCITXDC);
       GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCITXDC, GPIO_DIR_MODE_OUT);

       GPIO_setPadConfig(DEVICE_GPIO_PIN_SCITXDC, GPIO_PIN_TYPE_STD);
       GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCITXDC, GPIO_QUAL_ASYNC);
       //
    // Initializes PIE and clears PIE registers. Disables CPU interrupts.
    Interrupt_initModule();         // call the function in driverlib.lib

    // Initializes the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    Interrupt_initVectorTable();    // call the function in driverlib.lib

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //07042024
    Interrupt_register(INT_SCIC_RX, INT_SCI_COM_RX_ISR);
    Interrupt_register(INT_SCIC_TX, INT_SCI_COM_TX_ISR);

    //
    // Initialize the Device Peripherals:
    //
    initSCIAFIFO();


   // SYS_TX_init();
    Interrupt_register(INT_TIMER1, INT_CPU_TIMER1_ISR);  //NEW ADD

#if !defined(_SIMPLE_FAST_LIB)
    // false->enable motor identification, true->disable motor identification
    userParams[MTR_1].flag_bypassMotorId = true;
    userParams[MTR_2].flag_bypassMotorId = true;
#endif  // !(_SIMPLE_FAST_LIB)

#if defined(SYSCONFIG_EN)
    // disable the ePWM module time base clock sync signal
    // to synchronize all of the PWMs
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    Board_init();
    //CPUTimer_enableInterrupt(CPU_TIMER1_BASE); //new add
    configCPUTimer(CPUTIMER1_BASE, DEVICE_SYSCLK_FREQ, 119047);// 5000000
    CPUTimer_enableInterrupt(CPU_TIMER1_BASE);
    Interrupt_enable(INT_TIMER1);
    CPUTimer_startTimer(CPU_TIMER1_BASE); //new add
    // initialize the driver
    halHandle = HAL_init(&hal, sizeof(hal));

    // set the driver parameters
    HAL_setParams(halHandle);

    // set the control parameters for PFC
    initPFCCtrlParameters();

    // set the control parameters for motor 1
    initMotor1CtrlParameters();

    // set the control parameters for motor 2
    initMotor2CtrlParameters();

    // set the handle in hal for motors and pfc
    HAL_initMtrHandle(halHandle, halMtrHandle[MTR_1], halMtrHandle[MTR_2]);
    HAL_initPFCHandle(halHandle, halPFCHandle);

    // set PWM phase shift between motor and pfc
    HAL_setupPWMsPhaseShift(halHandle);

    // enable the ePWM module time base clock sync signal
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//-----------------------------ADD Communication purpose 12032024-------------------
//    for(i = 0; i < 2; i++)
//        {
//            sDataA[i] = i;
//        }

        rDataPointA = sDataA[0];
//        Interrupt_enable(INT_SCIA_RX);
//        Interrupt_enable(INT_SCIA_TX);
//        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
//-----------------------------------------end communication 12032024----------

#else   // !SYSCONFIG_EN
    // initialize the driver
    halHandle = HAL_init(&hal, sizeof(hal));

    // set the driver parameters
    HAL_setParams(halHandle);

    // set the control parameters for PFC
    initPFCCtrlParameters();

    // set the control parameters for motor 1
    initMotor1CtrlParameters();

    // set the control parameters for motor 2
    initMotor2CtrlParameters();

    // set the handle in hal for motors and pfc
    HAL_initMtrHandle(halHandle, halMtrHandle[MTR_1], halMtrHandle[MTR_2]);
    HAL_initPFCHandle(halHandle, halPFCHandle);

    // set PWM phase shift between motor and pfc
    HAL_setupPWMsPhaseShift(halHandle);

    // initialize the interrupt vector table
    HAL_initIntVectorTable(halHandle);

    // enable the ADC/PWM interrupts for control
    // enable interrupts to trig DMA
    HAL_enableCtrlInts(halHandle);
#endif  // !SYSCONFIG_EN

    motorVars[MTR_1].speedRef_Hz = 30.0f;
    motorVars[MTR_2].speedRef_Hz = 30.0f;

    systemVars.speedComp_Hz = 60.0f;
    systemVars.speedFan_Hz = 50.0f;


#if !defined(HVMTRPFC_REV1P1)
#if defined(EPWMDAC_MODE)
#error Only HVMTRPFC_REV1P1 supports the EPWMDAC function.
#endif  // EPWMDAC_MODE
#else   // HVMTRPFC_REV1P1
#if defined(EPWMDAC_MODE)
    // set DAC parameters
    pwmDACData.periodMax =
            PWMDAC_getPeriod(halHandle->pwmDACHandle[PWMDAC_NUMBER_1]);

#if defined(PWMDAC_MOTOR) && defined(PWMDAC_PFC)
    pwmDACData.ptrData[0] = &adcDataPFC.IacBus;
    pwmDACData.ptrData[1] = &adcDataPFC.VacBus;
    pwmDACData.ptrData[2] = &angleFOCM1_rad;
    pwmDACData.ptrData[3] = &adcData[MTR_1].I_A.value[0];

    pwmDACData.offset[0] = 0.5f;
    pwmDACData.offset[1] = 0.5f;
    pwmDACData.offset[2] = 0.5f;
    pwmDACData.offset[3] = 0.5f;

    pwmDACData.gain[0] = 1.0f;
    pwmDACData.gain[1] = 1.0f;
    pwmDACData.gain[2] = 1.0f / MATH_TWO_PI;
    pwmDACData.gain[3] = 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
#elif defined(PWMDAC_MOTOR) && !defined(PWMDAC_PFC)
    pwmDACData.ptrData[0] = &angleESTM1_rad;
    pwmDACData.ptrData[1] = &adcData[MTR_1].I_A.value[0];
    pwmDACData.ptrData[2] = &adcData[MTR_1].V_V.value[0];
    pwmDACData.ptrData[3] = &angleFOCM1_rad;

    pwmDACData.offset[0] = 0.5f;
    pwmDACData.offset[1] = 0.5f;
    pwmDACData.offset[2] = 0.5f;
    pwmDACData.offset[3] = 0.5f;

    pwmDACData.gain[0] = 1.0f / MATH_TWO_PI;
    pwmDACData.gain[1] = 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    pwmDACData.gain[2] = 1.0f / USER_M1_ADC_FULL_SCALE_VOLTAGE_V;
    pwmDACData.gain[3] = 1.0f / MATH_TWO_PI;
#elif defined(PWMDAC_PFC) && !defined(PWMDAC_MOTOR)
    pwmDACData.ptrData[0] = &adcDataPFC.IacBus;
    pwmDACData.ptrData[1] = &adcDataPFC.VacBus;
    pwmDACData.ptrData[2] = &pfcVars.IacRef;
    pwmDACData.ptrData[3] = &pfcVars.IacError;

    pwmDACData.offset[0] = 0.0f;
    pwmDACData.offset[1] = 0.0f;
    pwmDACData.offset[2] = 0.0f;
    pwmDACData.offset[3] = 0.0f;

    pwmDACData.gain[0] = 1.0f;
    pwmDACData.gain[1] = 1.0f;
    pwmDACData.gain[2] = 1.0f;
    pwmDACData.gain[3] = 1.0f;

#elif !defined(PWMDAC_PFC) && !defined(PWMDAC_MOTOR)
    // No EPWMDAC supporting
#else
#error Only PWMDAC_PFC or PWMDAC_MOTOR can be supported at the same time
#endif  // PWMDAC_PFC or PWMDAC_MOTOR
#endif  // EPWMDAC_MODE
#endif  // !HVMTRPFC_REV1P1

#if defined(DATALOGF2_EN)
//#warning No enough memory if use datalog, so may disable the VIB_COMP
    // Initialize Datalog
    datalogHandle = DATALOGIF_init(&datalog, sizeof(datalog));
    DATALOG_Obj *datalogObj = (DATALOG_Obj *)datalogHandle;

    HAL_setupDMAforDLOG(halHandle, 0, &datalogBuff1[0], &datalogBuff1[1]);
    HAL_setupDMAforDLOG(halHandle, 1, &datalogBuff2[0], &datalogBuff2[1]);

    // set datalog parameters
    datalogObj->iptr[0] = &angleFOCM1_rad;
    datalogObj->iptr[1] = &adcData[MTR_1].I_A.value[0];

#endif // DATALOGF2_EN


#if defined(DAC128S_ENABLE)
#if defined(DAC80504_SEL)
    // initialize the DAC80504
    dac128sHandle = DAC80504_init(&dac128s);

#if !defined(SYSCONFIG_EN)
    // setup SPI for DAC80504
    DAC80504_setupSPI(dac128sHandle);
#else  // SYSCONFIG_EN
    SPI_setTxFifoTransmitDelay(DAC_SPI_BASE, 0x04);
    SPI_clearInterruptStatus(DAC_SPI_BASE, SPI_INT_TXFF);
#endif  // SYSCONFIG_EN

    DAC80504_writeCommand(dac128sHandle);

#else   // DAC128S805
    // initialize the DAC128S05
    dac128sHandle = DAC128S_init(&dac128s);

#if !defined(SYSCONFIG_EN)
    // setup SPI for DAC128S05
    DAC128S_setupSPI(dac128sHandle);
#else  // SYSCONFIG_EN
    SPI_setTxFifoTransmitDelay(DAC_SPI_BASE, 0x04);
    SPI_clearInterruptStatus(DAC_SPI_BASE, SPI_INT_TXFF);
#endif  // SYSCONFIG_EN

    DAC128S_writeCommand(dac128sHandle);

#endif  // DAC128S805



    // The following settings are for output the values of different variables
    // in each build level for debug. The User can select one of these groups in
    // different build level as commented note

// DAC_LEVEL1_DACTEST
// DAC_LEVEL4_DCLINK, DAC_LEVEL4_ALL,  DAC_LEVEL2_MOTOR_IS, DAC_LEVEL4_MOTORS
// DAC_LEVEL4_VIBCOMP, DAC_LEVEL_TEST, DAC_LEVEL4_PFC
// DAC_LEVEL2_MOTOR1_IS, DAC_LEVEL2_MOTOR1_VS, DAC_LEVEL3_MOTOR1_EST
// DAC_LEVEL2_MOTOR2_IS, DAC_LEVEL2_MOTOR2_VS, DAC_LEVEL3_MOTOR2_EST
// DAC_LEVEL4_MOTOR1_EST, DAC_LEVEL4_SMOM1, DAC_LEVEL4_FASTM1, DAC_LEVEL4_DSMOM1
// DAC_LEVEL4_MOTOR2_EST, DAC_LEVEL4_SMOM2, DAC_LEVEL4_FASTM2, DAC_LEVEL4_DSMOM2

#define DAC_LEVEL4_ALL        // define the DAC level

#if defined(DAC_LEVEL4_DCLINK)
    // Using in build Level_4 to debug single shunt
    dac128s.ptrData[0] = &angleFOCM1_rad;           // CH_A
    dac128s.ptrData[1] = &adcData[0].I_A.value[0];  // CH_B
    dac128s.ptrData[2] = &adcData[0].I_A.value[1];  // CH_C
    dac128s.ptrData[3] = &adcData[0].I_A.value[2];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f * 2.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[2] = 4096.0f * 2.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 2.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.0f * 4096.0f);
#elif defined(DAC_LEVEL4_PFC)
    // Using in build Level_4 to monitor the rotor angles of motor 1 and 2,
    // and the sensing AC current and voltage for PFC
    dac128s.ptrData[0] = &adcDataPFC.IacBus;    // CH_A
    dac128s.ptrData[1] = &adcDataPFC.VacBus;    // CH_B
    dac128s.ptrData[2] = &adcDataPFC.VdcBus;    // CH_C
    dac128s.ptrData[3] = &adcDataPFC.IacBus;    // CH_D

    dac128s.gain[0] = 4096.0f;
    dac128s.gain[1] = 4096.0f;
    dac128s.gain[2] = 4096.0f;
    dac128s.gain[3] = 4096.0f;

    dac128s.offset[0] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.0f * 4096.0f);
#elif defined(DAC_LEVEL4_ALL)
    // Using in build Level_4 to monitor the rotor angles of motor 1 and 2,
    // and the sensing AC current and voltage for PFC
    dac128s.ptrData[0] = &adcDataPFC.IacBus;    // CH_A
    dac128s.ptrData[1] = &adcDataPFC.VacBus;    // CH_B
    dac128s.ptrData[2] = &angleFOCM1_rad;       // CH_C
    dac128s.ptrData[3] = &angleFOCM2_rad;       // CH_D

    dac128s.gain[0] = 4096.0f;
    dac128s.gain[1] = 4096.0f;
    dac128s.gain[2] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[3] = 4096.0f / MATH_TWO_PI;

    dac128s.offset[0] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL2_MOTOR_IS)
    // Using in build level 2: Verify motor_2 current sensing signals
    dac128s.ptrData[0] = &adcData[0].I_A.value[0];        // CH_A
    dac128s.ptrData[1] = &adcData[1].I_A.value[0];        // CH_B
    dac128s.ptrData[2] = &angleFOCM1_rad;                 // CH_C
    dac128s.ptrData[3] = &angleFOCM2_rad;                 // CH_D

    dac128s.gain[0] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[2] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[3] = 4096.0f / MATH_TWO_PI;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL2_MOTOR1_IS)
    // Using in build Level 2: Verify motor_1 current sensing signals
    dac128s.ptrData[0] = &angleFOCM1_rad;                 // CH_D
    dac128s.ptrData[1] = &adcData[0].I_A.value[0];        // CH_A
    dac128s.ptrData[2] = &adcData[0].I_A.value[1];        // CH_B
    dac128s.ptrData[3] = &adcData[0].I_A.value[2];        // CH_C

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL2_MOTOR1_VS)
    // Using in build level 2: Verify motor_1 voltage sensing signals
    dac128s.ptrData[0] = &angleFOCM1_rad;                 // CH_A
    dac128s.ptrData[1] = &adcData[0].V_V.value[0];        // CH_B
    dac128s.ptrData[2] = &adcData[0].V_V.value[1];        // CH_C
    dac128s.ptrData[3] = &adcData[0].V_V.value[2];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_VOLTAGE_V;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_VOLTAGE_V;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_VOLTAGE_V;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL3_MOTOR1_EST)
    // Using in build Level 2 and 3: Verify motor_1 estimation angle
    dac128s.ptrData[0] = &angleGenM1_rad;                 // CH_A
    dac128s.ptrData[1] = &angleESTM1_rad;                 // CH_B
    dac128s.ptrData[2] = &adcData[0].I_A.value[0];        // CH_C
    dac128s.ptrData[3] = &adcData[0].V_V.value[0];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_VOLTAGE_V;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL2_MOTOR2_IS)
    // Using in build level 2: Verify motor_2 current sensing signals
    dac128s.ptrData[0] = &adcData[1].I_A.value[0];        // CH_A
    dac128s.ptrData[1] = &adcData[1].I_A.value[1];        // CH_B
    dac128s.ptrData[2] = &adcData[1].I_A.value[2];        // CH_C
    dac128s.ptrData[3] = &angleFOCM2_rad;                 // CH_D

    dac128s.gain[0] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f / MATH_TWO_PI;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL2_MOTOR2_VS)
    // Using in build level 2: Verify motor_2 voltage sensing signals
    dac128s.ptrData[0] = &angleFOCM2_rad;                 // CH_D
    dac128s.ptrData[1] = &adcData[1].V_V.value[0];        // CH_A
    dac128s.ptrData[2] = &adcData[1].V_V.value[1];        // CH_B
    dac128s.ptrData[3] = &adcData[1].V_V.value[2];        // CH_C

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_VOLTAGE_V;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_VOLTAGE_V;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_VOLTAGE_V;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL3_MOTOR2_EST)
    // Using in build level 2 and 3: Verify motor_2 estimation angle
    dac128s.ptrData[0] = &angleGenM2_rad;                 // CH_A
    dac128s.ptrData[1] = &angleESTM2_rad;                 // CH_B
    dac128s.ptrData[2] = &adcData[1].I_A.value[0];        // CH_C
    dac128s.ptrData[3] = &adcData[1].V_V.value[0];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_VOLTAGE_V;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_MOTOR2_EST)
    // Using in build level 2 and 3: Verify motor_2 estimation angle
    dac128s.ptrData[0] = &angleESTM2_rad;                 // CH_A
    dac128s.ptrData[1] = &adcData[1].I_A.value[0];        // CH_B
    dac128s.ptrData[2] = &adcData[1].V_V.value[0];        // CH_C
    dac128s.ptrData[3] = &adcData[1].I_A.value[1];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_VOLTAGE_V;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_MOTORS)
    // Using in build level 3 and 4: Verify motor_1 & motor_2 closed-loop
    dac128s.ptrData[0] = &angleFOCM1_rad;                 // CH_A
    dac128s.ptrData[1] = &angleFOCM2_rad;                 // CH_B
    dac128s.ptrData[2] = &adcData[0].I_A.value[0];        // CH_C
    dac128s.ptrData[3] = &adcData[1].I_A.value[0];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_SMOM1)
    // Using in build level 2 and 3: Verify motor_2 estimation angle
    dac128s.ptrData[0] = &adcData[0].I_A.value[0];        // CH_A
    dac128s.ptrData[1] = &adcData[0].I_A.value[0];        // CH_B
    dac128s.ptrData[2] = &anglePLLM1_rad;                 // CH_C
//    dac128s.ptrData[3] = &angleESTM1_rad;               // CH_D
    dac128s.ptrData[3] = &angleFOCM1_rad;                 // CH_D

    dac128s.gain[0] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[1] = 4096.0f * 1.0f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[2] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[3] = 4096.0f / MATH_TWO_PI;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_FASTM2)
    // Using in build level 2 and 3: Verify motor_2 estimation angle
    dac128s.ptrData[0] = &angleFOCM2_rad;                 // CH_A
    dac128s.ptrData[1] = &angleESTM2_rad;                 // CH_B
    dac128s.ptrData[2] = &adcData[1].I_A.value[0];        // CH_C
    dac128s.ptrData[3] = &adcData[1].I_A.value[1];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_SMOM2)
    // Using in build level 2 and 3: Verify motor_2 estimation angle
    dac128s.ptrData[0] = &angleFOCM2_rad;                 // CH_C
    dac128s.ptrData[1] = &anglePLLM2_rad;                 // CH_A
    dac128s.ptrData[2] = &adcData[1].I_A.value[0];        // CH_C
    dac128s.ptrData[3] = &adcData[1].I_A.value[1];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_DSMOM2)
    // Using in build level 2 and 3: Verify motor_2 estimation angle
    dac128s.ptrData[0] = &angleFOCM2_rad;                 // CH_C
    dac128s.ptrData[1] = &anglePLLM2_rad;                 // CH_A
    dac128s.ptrData[2] = &angleESTM2_rad;                 // CH_B
    dac128s.ptrData[3] = &adcData[1].I_A.value[0];        // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[3] = 4096.0f * 1.0f / USER_M2_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL4_VIBCOMP)
    // Using in build level 4: for vibration compensation debug
    dac128s.ptrData[0] = &vibComp.angleMechPoles_rad;                // CH_A
    dac128s.ptrData[1] = &angleFOCM1_rad;                       // CH_B
    dac128s.ptrData[2] = &vibComp.Iq_comp_A;                    // CH_C
    dac128s.ptrData[3] = &Idq_in_A[0].value[1];                 // CH_D

    dac128s.gain[0] = 4096.0f / MATH_TWO_PI / USER_MOTOR1_NUM_POLE_PAIRS;
    dac128s.gain[1] = 4096.0f / MATH_TWO_PI;
    dac128s.gain[2] = 4096.0f * 0.5f / USER_M1_ADC_FULL_SCALE_CURRENT_A;
    dac128s.gain[3] = 4096.0f * 0.5f / USER_M2_ADC_FULL_SCALE_CURRENT_A;

    dac128s.offset[0] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.5f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.5f * 4096.0f);
#elif defined(DAC_LEVEL_TEST) && defined(DACTEST_EN)
    // Using in build level 4: for vibration compensation debug
    dac128s.ptrData[0] = &dacTestValue[0];         // CH_A
    dac128s.ptrData[1] = &dacTestValue[1];         // CH_B
    dac128s.ptrData[2] = &dacTestValue[2];         // CH_C
    dac128s.ptrData[3] = &dacTestValue[3];         // CH_D

    dac128s.gain[0] = 4096.0f;
    dac128s.gain[1] = 4096.0f;
    dac128s.gain[2] = 4096.0f;
    dac128s.gain[3] = 4096.0f;

    dac128s.offset[0] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[1] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[2] = (uint16_t)(0.0f * 4096.0f);
    dac128s.offset[3] = (uint16_t)(0.0f * 4096.0f);
#else
#error Not assign the variables to the DAC object
#endif  //DAC_LEVEL
#endif  // DAC128S_ENABLE

#if defined(SFRA_ENABLE) &&  (SFRA_TEST_TYPE == SFRA_TEST_PFC)
    // Plot GH & H plots using SFRA_GUI
    configureSFRA(SFRA_GUI_PLOT_GH_H, PFC_SAMPLING_FREQ_HZ);

    sfraTestLoop = SFRA_TEST_PFC_CURRENT;

    sfraCollectStart = false;       // disable SFRA data collection
#endif  // SFRA_ENABLE && SFRA_TEST_PFC

#if defined(SFRA_ENABLE) && (SFRA_TEST_TYPE == SFRA_TEST_MOTOR1)
    // Plot GH & H plots using SFRA_GUI, GH & CL plots using SFRA_GUI_MC
    configureSFRA(SFRA_GUI_PLOT_GH_H, USER_M1_SAMPLING_FREQ_Hz);

    sfraTestLoop = SFRA_TEST_MOTOR1_IQ;

    sfraCollectStart = false;       // disable SFRA data collection
#endif  // SFRA_ENABLE && SFRA_TEST_MOTOR1

#if defined(SFRA_ENABLE) && ( SFRA_TEST_TYPE == SFRA_TEST_MOTOR2)
    // Plot GH & H plots using SFRA_GUI, GH & CL plots using SFRA_GUI_MC
    configureSFRA(SFRA_GUI_PLOT_GH_H, MOTOR2_SAMPLING_FREQ_Hz);

    sfraTestLoop = SFRA_TEST_MOTOR2_IQ;

    sfraCollectStart = false;       // disable SFRA data collection
#endif  // SFRA_ENABLE && SFRA_TEST_MOTOR2

    systemVars.flagEnableSystem = false;

    compressor1motorFlag = false;    //add 10032024

#if(PFC_BUILDLEVEL >= PFC_LEVEL_2)
    pfcVars.flagEnableOffsetCalc = false;
    motorVars[MTR_1].flagEnableOffsetCalc = true;
    motorVars[MTR_2].flagEnableOffsetCalc = true;
#else
    pfcVars.flagEnableOffsetCalc = true;
    motorVars[MTR_1].flagEnableOffsetCalc = true;
    motorVars[MTR_2].flagEnableOffsetCalc = true;
#endif  // PFC_BUILDLEVEL == PFC_LEVEL_1

    systemVars.powerRelayWaitTime_ms = POWER_RELAY_WAIT_TIME_ms;    //6s
    systemVars.timerBase_1ms = 0;
    systemVars.flagEnableExtCmd = false;
    systemVars.flagEnableSystem = false;

    // Waiting for enable system flag to be set
    while(systemVars.flagEnableSystem == false)
    {
        if(HAL_getCPUTimerStatus(halHandle, HAL_CPU_TIMER0) == true)
        {
            // read the ADC data with offsets
            HAL_readPFCADCData(&adcDataPFC);

            // convert dc bus voltage from pu to SI unit
            pfcVars.VdcBusLPF = pfcVars.VdcBusLPF +
                    (adcDataPFC.VdcBus - pfcVars.VdcBusLPF) * pfcVars.lpfVdcCoeff;

            pfcVars.VdcBusLPF_V = pfcVars.VdcBusLPF * USER_PFC_ADC_FULL_SCALE_DC_VOLTAGE_V;

        #if(PFC_BUILDLEVEL > PFC_LEVEL_4)
            if(pfcVars.VdcBusLPF_V >= POWER_RELAY_ON_VOLTAGE_V)
            {
                systemVars.timerBase_1ms++;
            }
        #else
            systemVars.timerBase_1ms++;
        #endif

            if(systemVars.timerBase_1ms > systemVars.powerRelayWaitTime_ms)
            {
                systemVars.flagEnableSystem = true;
                systemVars.timerBase_1ms = 0;

                // Turn on the power relay
                HAL_turnOnPowerRelay(ACPOWER_RELAY_GPIO);
                HAL_turnOnPowerRelay(ACPOWER_RELAY_GPIO);

                // Turn on the FWV relay which is used for power relay
                // on the new board for F280015x
                HAL_turnOnPowerRelay(FOURWAY_RELAY_GPIO);
                HAL_turnOnPowerRelay(FOURWAY_RELAY_GPIO);
            }

            HAL_clearCPUTimerFlag(halHandle, HAL_CPU_TIMER0);
        }
    }
    // Turn on the power relay
    HAL_turnOnPowerRelay(ACPOWER_RELAY_GPIO);
    //HAL_turnOnPowerRelay(ACPOWER_RELAY_GPIO39);

    //ACPOWER_RELAY1_GPIO =1;
    systemVars.flagEnableSystem = false;
    systemVars.timerBase_1ms = 0;
    systemVars.powerRelayWaitTime_ms = OFFSET_CHECK_WAIT_TIME_ms; //4s

    // Waiting for enable system flag to be set
    while(systemVars.flagEnableSystem == false)
    {
        if(HAL_getCPUTimerStatus(halHandle, HAL_CPU_TIMER0) == true)
        {
            systemVars.timerBase_1ms++;

            if(systemVars.timerBase_1ms > systemVars.powerRelayWaitTime_ms)
            {
                systemVars.flagEnableSystem = true;
                systemVars.timerBase_1ms = 0;
            }

            HAL_clearCPUTimerFlag(halHandle, HAL_CPU_TIMER0);
        }
    }

    systemVars.flagEnableSystem = true;

    // Turn on the power relay
    HAL_turnOnPowerRelay(ACPOWER_RELAY_GPIO);

#ifndef PFC_DISABLE
    // run offset calibration for PFC
    runPFCOffsetsCalculation();
#endif  // PFC_DISABLE

#ifndef MOTOR1_DISABLE
    // run offset calibration for motor 1
    runMotor1OffsetsCalculation();
#endif  // !MOTOR1_DISABLE

#ifndef MOTOR2_DISABLE
    // run offset calibration for motor 2
    runMotor2OffsetsCalculation();
#endif  // !MOTOR2_DISABLE

    // enable global interrupts
    HAL_enableGlobalInts(halHandle);

    // enable debug interrupts
    HAL_enableDebugInt(halHandle);

    systemVars.flagEnableSystem = true;

    HAL_clearCPUTimerFlag(halHandle, HAL_CPU_TIMER0);

    motorVars[0].flagEnableRunAndIdentify = false;
    motorVars[1].flagEnableRunAndIdentify = false;
    compressor1motorFlag = false;

//    msg = "@ Welcome VOEPL Team @";
//    SCI_writeCharArray(SCIC_BASE, (uint16_t*)msg, 22);
    msg = "@ Welcome To Voepl @";
    SCI_writeCharArray(SCIC_BASE, (uint16_t*)msg, 20);
    msg = "@ Welcome To Mr.Babaji @";
       SCI_writeCharArray(SCIC_BASE, (uint16_t*)msg, 24);
    Interrupt_enable(INT_SCIC_RX);
    Interrupt_enable(INT_SCIC_TX);

    Interrupt_register(INT_SCIC_TX, INT_SCI_COM_TX_ISR);    //ok
    systemVars.powerRelayWaitTime_ms1 = OFFSET_CHECK_WAIT_TIME_ms1; //10s

    compressor1motorFlag = true;

    while(systemVars.flagEnableSystem == true)
    {
//        Interrupt_register(INT_SCIA_TX, INT_SCI_COM_TX_ISR);    //ok
            tempnewvalue1 = (*read_ADC_Value);
            fTempValue = (float)(ADC_RESOLUTION_VALUE - tempnewvalue1);//value
            fTempValue *= (TEMP_AIR_RES_GND / tempnewvalue1);
            Temp_Sensor_coils = (float)ntc_sensor_get_temp(fTempValue, TEMP_AIR_RES_T_25, TEMP_AIR_BETA);
        //--------------------------------------Ambient sensor-------------------------------------------------
            tempnewvalue2 = (*read_ADC_Value1);
            fTempValue = (float)(ADC_RESOLUTION_VALUE - tempnewvalue2);//value
            fTempValue *= (TEMP_AIR_RES_GND / tempnewvalue2);
            Temp_Sensor_Ambient = (float)ntc_sensor_get_temp(fTempValue, TEMP_AIR_RES_T_25, TEMP_AIR_BETA);
//---------------------------------Discharge_Sensor-------------------------------------------------------------
            tempnewvalue3 = (*read_ADC_Value2);
            fTempValue = (float)(ADC_RESOLUTION_VALUE - tempnewvalue3);//value
            fTempValue *= (TEMP_AIR_RES_GND / tempnewvalue3);
            Temp_Sensor_Discharge = (float)ntc_sensor_get_temp(fTempValue, TEMP_AIR_RES_T_25, TEMP_AIR_BETA);
//-------------------------------------------NEW---ADD---END------------------------------------------------------

//            systemVars.timerBase_1ms = 0;
//            systemVars.powerRelayWaitTime_ms1 = OFFSET_CHECK_WAIT_TIME_ms1; //10s
//          while(tx_flag == false)
//           {
//            if(HAL_getCPUTimerStatus(halHandle, HAL_CPU_TIMER0) == true)
//                   {
////                     systemVars.powerRelayWaitTime_ms1 = OFFSET_CHECK_WAIT_TIME_ms1; //10s
//                       systemVars.timerBase_1ms++;
//                       if(systemVars.timerBase_1ms > systemVars.powerRelayWaitTime_ms1)//10000
//                       {
//                           //systemVars.flagEnableSystem = true;
//                           tx_flag = 1;
//                           systemVars.timerBase_1ms = 0;
//                       }
//
//                       HAL_clearCPUTimerFlag(halHandle, HAL_CPU_TIMER0);
//                   }
//           }

//            if(tx_flag == true)
//            {
//                msg = "$0025,0020#";
//                SCI_writeCharArray(SCIC_BASE, (uint16_t*)msg, 11);
//                tx_flag = false;
//            }
            if(rx_flag ==true)
            {

               // unsigned char ucTempValue = 0;
//                uiTempValue = (ucRxBuff[0] & 0x0F) << 3;  // Thousands digit (shift left by 3, which is equivalent to multiplying by 8)
//                uiTempValue += (ucRxBuff[1] & 0x0F) << 2;  // Hundreds digit (shift left by 2, equivalent to multiplying by 4)
//                uiTempValue += (ucRxBuff[2] & 0x0F) << 1;  // Tens digit (shift left by 1, equivalent to multiplying by 2)
//                uiTempValue += (ucRxBuff[3] & 0x0F);       // Units digit (no shift, equivalent to multiplying by 1)
//                rx_flag = 0;
//                unsigned int uiTempValue=0;
                uiTempValue = (ucRxBuff[1] & 0x0F);
                uiTempValue *= 1000;
                uiTempValue += ((ucRxBuff[2] & 0x0F) * 100);
                uiTempValue += ((ucRxBuff[3] & 0x0F) * 10);
                uiTempValue += ((ucRxBuff[4] & 0x0F) * 1);
//                Temp_Sensor_Ambient=(float)uiTempValue;
//                IDU_Ambiet_Temp=(float)uiTempValue;
                IDU_Ambiet_Temp=uiTempValue;

                uiTempValue1 = (ucRxBuff[5] & 0x0F);
                uiTempValue1 *= 1000;
                uiTempValue1 += ((ucRxBuff[6] & 0x0F) * 100);
                uiTempValue1 += ((ucRxBuff[7] & 0x0F) * 10);
                uiTempValue1 += ((ucRxBuff[8] & 0x0F) * 1);
                IDU_set_Temp=uiTempValue1;
                ucRxStatus1 = '^';
                //motorVars[MTR_2].CompressorStartFlag = true;
                CompressorStartFlag=true;
                rx_flag=false;

//                cx_flag=true;
            }
            if(tx_flag == true)
            {
                msg = "$0025,0020#";
                SCI_writeCharArray(SCIC_BASE, (uint16_t*)msg, 11);
                tx_flag = false;
            }
        // loop while the enable system flag is true
        // 1ms time base
        if(HAL_getCPUTimerStatus(halHandle, HAL_CPU_TIMER0) == true)
        {
            systemVars.timerBase_1ms++;
            HAL_clearCPUTimerFlag(halHandle, HAL_CPU_TIMER0);
            SYS_processFault();
      if( compressor1motorFlag == true)   //     this is compressor flagRunIdentAndOnLine added by bn
       {
            SYS_updateCtrlState();
            motorVars[MTR_1].flagEnableRunAndIdentify = true;
            compressor1motorFlag = false;
        }
            switch(systemVars.timerBase_1ms)
            {
                // 5ms time base
                case 1:     // motor 1 protection check
                #ifndef MOTOR1_DISABLE
                    calculateRMSData(MTR_1);
                    runMotorMonitor(MTR_1);
                 #endif  // !MOTOR1_DISABLE
                    break;

                case 2:     // motor 2 protection check
                #if !defined(MOTOR2_DISABLE)    // single motor on high voltage kit
                    calculateRMSData(MTR_2);
                    runMotorMonitor(MTR_2);
                #endif  // !MOTOR2_DISABLE
                    break;

                case 3:     // pfc protection check
                #if !defined(PFC_DISABLE)
                    runPFCMonitor();
                #endif  // PFC_DISABLE
                    break;

                case 4:     // calculate motor and pfc protection value
                #if !defined(MOTOR1_DCLINKSS)
                    calcMotorOverCurrentThreshold(MTR_1);
                #elif !defined(MOTOR1_DISABLE)   // MOTOR1_DCLINKSS
                    calcMotorDCLinkOverCurrentThreshold(MTR_1);
                #endif  // MOTOR1_DCLINKSS

                #if !defined(MOTOR2_DISABLE) && !defined(MOTOR2_DCLINKSS)
                    calcMotorOverCurrentThreshold(MTR_2);
                #elif !defined(MOTOR2_DISABLE)   // MOTOR2_DCLINKSS
                    calcMotorDCLinkOverCurrentThreshold(MTR_2);
                #endif  // !MOTOR2_DISABLE & MOTOR2_DCLINKSS

                #if !defined(PFC_DISABLE)
                    calcPFCOverCurrentThreshold();
                #endif  // PFC_DISABLE

                #if defined(MOTOR1_FWC)
                    updateFWCParams();
                #endif  // MOTOR1_FWC

                #if defined(MOTOR1_MTPA)
                    updateMTPAParams();
                #endif  // MOTOR1_MTPA
                    break;

                case 5:     // system control
                    systemVars.timerBase_1ms = 0;
                    systemVars.timerCnt_5ms++;

                    SYS_displayFault();     // 5ms

                #if defined(MOTOR2_ESMO) && !defined(MOTOR2_DISABLE)
                    if(motorVars[MTR_2].motorState >= MOTOR_CTRL_RUN)
                    {
                        ESMO_updateFilterParams(esmoM2Handle);
                        ESMO_updatePLLParams(esmoM2Handle);
                    }
                #endif  // MOTOR2_ESMO

                #if defined(MOTOR1_ESMO) && !defined(MOTOR1_DISABLE)
                    if(motorVars[MTR_1].motorState >= MOTOR_CTRL_RUN)
                    {
                        ESMO_updateFilterParams(esmoM1Handle);
                        ESMO_updatePLLParams(esmoM1Handle);
                    }
                #endif  // MOTOR2_ESMO
                    break;

                default:
                    break;
            }

            #if defined(SFRA_ENABLE)
            // SFRA test
            SFRA_F32_runBackgroundTask(&sfra1);
            SFRA_GUI_runSerialHostComms(&sfra1);
            #endif  // SFRA_ENABLE

        }
    #ifndef MOTOR1_DISABLE
        // run control for motor 1
        runMotor1Control();
    #endif  // !MOTOR1_DISABLE
    #if !defined(MOTOR2_DISABLE)
        // run control for motor 2
        runMotor2Control();
    #endif  // !MOTOR2_DISABLE

    #if !defined(PFC_DISABLE)
        // run control for PFC
        runPFCMainControl();
    #endif  // PFC_DISABLE

        if(systemVars.flagEnableExtCmd == true)
        {
            if(GPIO_readPin(TEST_SWITCH_GPIO) == 0)
            {
                motorVars[MTR_2].flagEnableRunAndIdentify = true;
                motorVars[MTR_2].speedRef_Hz = systemVars.speedFan_Hz;
            }
            else
            {
                motorVars[MTR_2].flagEnableRunAndIdentify = false;
            }
        }

    } // end of while() loop

#ifndef MOTOR1_DISABLE
    // disable the PWM for stopping the motor 1
    HAL_disableMTRPWM(halMtrHandle[0]);
#endif  // !MOTOR1_DISABLE

    // disable the PWM for stopping the motor 1
#if !defined(MOTOR2_DISABLE)
    HAL_disableMTRPWM(halMtrHandle[1]);
#endif  // !MOTOR2_DISABLE

} // end of main() function

static float ntc_sensor_get_temp(float res, uint16_t res_25, uint16_t beta)
{
    float temp = 1 / (1 / TEMP_T_25_K + (log10((float)res/res_25) / LOG_10_E / beta));
    temp -= 273.15;
    return temp;
}

__interrupt void INT_MTR1_EMI_1_ISR(void)
{
//    ADC_clearInterruptStatus(MTR1_EMI_BASE, ADC_INT_NUMBER1);
//    if(true==ADC_getInterruptOverflowStatus(MTR1_EMI_BASE, ADC_INT_NUMBER1))
 //   {
 //       ADC_clearInterruptOverflowStatus(MTR1_EMI_BASE, ADC_INT_NUMBER1);
 //       ADC_clearInterruptStatus(MTR1_EMI_BASE, ADC_INT_NUMBER1);
 //   }
 //   Interrupt_clearACKGroup(INT_MTR1_EMI_1_INTERRUPT_ACK_GROUP);
 }
//
//-- end of this file ----------------------------------------------------------

void
configCPUTimer(uint32_t cpuTimer, float freq, float period)
{
        uint32_t temp;
        temp = (uint32_t)((freq / 1000000) * period);
        CPUTimer_setPeriod(CPU_TIMER1_BASE, 119047U);
        CPUTimer_setPreScaler(CPU_TIMER1_BASE, 1000U);
        CPUTimer_reloadTimerCounter(CPU_TIMER1_BASE);
        CPUTimer_setEmulationMode(CPU_TIMER1_BASE, CPUTIMER_EMULATIONMODE_RUNFREE);
        CPUTimer_enableInterrupt(CPU_TIMER1_BASE);
        if(cpuTimer == CPUTIMER1_BASE)
        {
        cpuTimer1IntCount = 0;
        }
}

__interrupt void INT_CPU_TIMER1_ISR(void) //INT_CPU_TIMER1_ISR
{
    if(CompressorStartFlag == true)
//    if( (ucRxStatus1 == '^'))
       {
           b++;
           cpuTimer1IntCount++;
           if(cpuTimer1IntCount >= 181)
           {
//               if( (ucRxStatus1 == '^'))
//                 {
                   compressor1motorFlag = true;
                   motorVars[MTR_1].flagEnableRunAndIdentify = true;
//               cpuTimer1IntCount=0;
//               cx_flag=false;
                   cpuTimer1IntCount=0;
                   CompressorStartFlag = false;
             }

           }
    cpuTimer2IntCount++;
    if(cpuTimer2IntCount == 10)
    {
        tx_flag =true;
        cpuTimer2IntCount=0;
    }

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
void error(void)
{
    asm("     ESTOP0"); // Test failed!! Stop!
    for (;;);
}
__interrupt void INT_SCI_COM_TX_ISR(void)
{
//    uint16_t i;
//     SCI_writeCharArray(SCIA_BASE, sDataA, 9);
//
//
//        SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF);
//        // Issue PIE ACK
//        //
//        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
//        // SCI_enableInterrupt(uint32_t base, uint32_t intFlags);
}
__interrupt void INT_SCI_COM_RX_ISR(void)
{
    ASSERT(SCI_isBaseValid(SCIC_BASE));
    if(SCI_isFIFOEnabled(SCIC_BASE))
    {
        while(SCI_getRxFIFOStatus(SCIC_BASE) == SCI_FIFO_RX15)
        {
        }
        //rx_data =(HWREGH(SCIC_BASE + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
        rx_data = (HWREGH(SCIC_BASE + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
    }

        rx_data_save = rx_data;

        if(ucRxStatus == 'H')
        {
            if(rx_data == '$')
            {
                uiRxByteCntr = 0;
                ucRxBuff[uiRxByteCntr++] = rx_data_save;
                ucRxStatus = 'A';
            }
            else
            {
                uiRxByteCntr = 0;
                ucRxStatus = 'H';
            }
        }
        else if(ucRxStatus == 'A')
        {
            if(rx_data == '*')  //
            {
                ucRxBuff[uiRxByteCntr++] = rx_data_save;
                rx_flag = 1;
//                cx_flag = 1;
                ucRxStatus = 'H';
            }
            else
            {
                ucRxBuff[uiRxByteCntr++] = rx_data_save;
            }
        }
        else
        {
            ucRxStatus = 'H';
            uiRxByteCntr = 0;
        }
//-------------------------New added end------------------
    SCI_clearOverflowStatus(SCIC_BASE);
    SCI_clearInterruptStatus(SCIC_BASE, SCI_INT_RXFF);
        // Issue PIE ack
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

void initSCIAFIFO()
{
    //
    // 8 char bits, 1 stop bit, no parity. Baud rate is 9600.
    //
    SCI_setConfig(SCIC_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 |
                                                     SCI_CONFIG_STOP_ONE |
                                                        SCI_CONFIG_PAR_NONE));
    SCI_enableModule(SCIC_BASE);
   SCI_enableLoopback(SCIC_BASE);
    SCI_resetChannels(SCIC_BASE);
    SCI_disableFIFO(SCIC_BASE);
    // RX and TX FIFO Interrupts Enabled
    SCI_enableInterrupt(SCIC_BASE, (SCI_INT_RXFF | SCI_INT_TXFF));
    SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXERR);
    // The transmit FIFO generates an interrupt when FIFO status
    // bits are less than or equal to 2 out of 16 words
    // The receive FIFO generates an interrupt when FIFO status
    // bits are greater than equal to 2 out of 16 words
    SCI_setFIFOInterruptLevel(SCIC_BASE, SCI_FIFO_TX2, SCI_FIFO_RX2);
    SCI_performSoftwareReset(SCIC_BASE);
    SCI_resetTxFIFO(SCIC_BASE);//
    SCI_resetRxFIFO(SCIC_BASE);//
    SCI_resetChannels(SCIC_BASE);
}


