This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR2355:当我启用全局中断时、MSP 的行为不一致

Guru**** 2522930 points
Other Parts Discussed in Thread: MSP430FR2355

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1104686/msp430fr2355-msp-inconsistent-behavior-when-i-enable-global-interrupts

器件型号:MSP430FR2355

大家好、  

我使用 MSP430FR2355来管理多个 DCDC 转换器+ I2C 通信的加电/断电序列。

状态机根据 PG 信号前进至下一级、因为它为以下直流/直流转换器发送以下 EN/运行信号。

MSP 的3.3V 输入电压在启动时独立提供。

探测:在我启动系统的大约3次中的1次中、主电压 EN 下降至0V、系统未启动。

我所做的事情:

1.我已通过手动启动外设直流/直流电路排除了问题。  

2.已验证出现问题时 DCDC 输入电压是否稳定。

3.从头开始-我逐渐启用了 DCDC,但时间延迟。 它工作正常。  然后、我逐渐添加了内容、并注意到当我通过添加以下行启用全局中断时、这个问题再次出现:_bis_SR_register (GIE);

当我将这一行添加到代码中时、问题就会发生。 (约为3倍)。 即使代码中没有中断、也会发生这种情况。

当我删除此行时、不会出现问题。

我很高兴听到您的想法。 非常感谢您的帮助。

谢谢、  

Yaniv。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好  

    您可以参阅电源序列示例。 其中有示例代码。

    https://training.ti.com/power-sequencing?context=1147398-1147608-1148601

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Allen、您好、感谢您的快速响应。

    这就是我们的定序工作方式。 (基于时间中断)。
    但是、如前所述、即使我使用简单代码并启用中断(_bis_SR_register (GIE))、即使代码中没有中断、也会重现此问题。

    当"_bis_SR_register (GIE);"被删除时、问题不会重现。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您能否发布您的代码和原理图? 我可以帮助回顾一下它。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、  

    在开头的 main 中看起来像这样:

    void main (void)

    WDT_A_HOLD (WDT_A_base);

    CONFIG_GPIOs();

    CONFIG_U2C_Master();

    init_i2C_Slave ();

    CONFIG_ADC();

    CONFIG_TimerOP;

    CONFIG_UART_A1();

    PM5TL0 &=LOCKLPM5;

    我将 "PM5TL0 &=LOCKLPM5;"移动到"WDT_A_HOLD (WDT_A_base);"下方的行中,问题不再发生。

    后来、我在其他 MSP 设计中看到、在 GPIO 配置之后使用了几行"PMM_unlockPM5()"函数、这些设计中没有问题。

    1.您能帮助我理解以下内容吗:

    a.为什么移动 PM5TL0 &=LOCKLPM5;问题是否已解决?

    b.此解决方案与"PMM_unlickPM5();"有何区别?  

    c.应该将这行 PM5TL0 &=LOCKLPM5/PMM_unlickPM5  ()放在哪里?

     

    非常感谢您的帮助、

    Yaniv。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您说代码中没有中断、但并不清楚您的意思。 您可能意味着您认为不会触发任何中断。 这并不意味着您没有中断服务例程并启用了外设中断。 否则、为什么要设置 GIE? 初始化外设可能会导致立即中断。 UART TXIFG 在复位时置1 (TXBUF 为空)、因此如果您在置1 TXIE 之前忘记了这一点、可能会导致问题。

    该文档非常清楚在清除端口中断标志之前必须清除 LOCKLPM5。 如果您启用端口中断、则可以在设置边沿寄存器后有挂起的中断。 如果 LOCKLPM5被置位、您无法将其清除。 因此、它们会导致您在设置 GIE 时所期望的中断。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    //Not working version
    #include <driverlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    
    #include "PINOUT_BOARD.h"
    #include "register_map.h"
    #include "uart_func.h"
    
    
    void Configure_Clocks(void);
    void Configure_UART_A1(void);//for TE - test equipment
    //void Configure_TimerB(void);
    void Configure_I2C_Master(void);//for external ADC and temperature sensor
    void Init_I2C_Slave();
    void I2C_Slave_ProcessCMD(uint8_t cmd);
    void I2C_Slave_TransactionDone(uint8_t cmd);
    //for IFD communication
    void Configure_ADC(void);//for IFD communication
    void Read_Ext_ADC(void); //by i2c,  also for reading the temperature sensors
    void Configure_Timer(void);
    void LTC2991_Read_All_Channels(uint8_t sensor_addr,uint8_t channel);
    void LTC2991_config();
    void Delay_Func(uint8_t delayCNT);
    #define TIMER_PERIOD            600
    #define MAX_BUFFER_SIZE         20
    
    //MSP430 I2C Slave address
    #define SLAVE_OWN_ADDR          0x48
    
    //  TMP102 a and b REGISTERS ADDRESSES
    #define TMP102_TMP_REG          0x00
    #define TMP102_CONFIG_REG       0x01
    #define TMP102_TLOW_REG         0x02
    #define TMP102_THIGH_REG        0x03
    #define TMPa_ADDRESS            0x48
    #define TMPb_ADDRESS            0x4B
    //  LTC2991 Registers
    #define LTC2991_DV              0x8000
    #define LTC2991_SIGN            0x4000
    #define LTC2991_DATA_MASK       0X3FFF
    #define LTC2991_ADDRESS         0x92
    #define LTC2991_WR_ADDRESS      0x49
    
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    
    
    enum M_CMD {M_NO_CMD,M_MODE_SELECT,M_WRITE_REG,M_READ_REG};
    enum M_CMD MASTER_CMD = M_NO_CMD;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    I2C_Mode SlaveMode = RX_REG_ADDRESS_MODE;
    
    I2C_Mode I2C_Master_WriteReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    I2C_Mode I2C_Master_ReadReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    uint16_t TMP102_Read_Temp_Reg(uint8_t sensor_addr);
    uint16_t temp_mode;
    
    float LTC2991_DATA_SCALE = 0.30518;
    uint16_t temp_float = 0;
    uint8_t CHANNEL_EN_LTC2991[1] = {0xF8};
    uint8_t CONTROL_06_REG_LTC2991[1] = {0x88};
    uint8_t CONTROL_07_REG_LTC2991[1] = {0x88};
    uint8_t CONTROL_08_REG_LTC2991[1] = {0x10};
    uint8_t value_in;
    uint32_t clockValue;
    //uint8_t address_ptr = 1;
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    //LV_PU_FSM:
    enum LV_PU_FSM
    {
        lv_st_idle = 0,
        lv_st_1_pu_seq = 1,
        lv_st_2_pu_seq = 2,
        lv_st_3_pu_seq = 3,
        lv_st_4_pu_seq = 4,
        lv_st_5_pu_seq = 5,
        lv_st_finish   = 6
    };
    enum LV_PU_FSM lv_pu_fsm = lv_st_idle;
    
    enum HV_PU_FSM
    {
        hv_st_idle = 0,
        hv_st_1_pu_seq = 1,
        hv_st_2_pu_seq = 2,
        hv_st_3_pu_seq = 3,
        hv_st_finish   = 4
    };
    enum HV_PU_FSM hv_pu_fsm = hv_st_idle;
    
    uint8_t timer_tick = 0;
    //uint8_t index = 0;
    //INTERNAL ADC:
    uint16_t adc_data[13];
    uint16_t adc_timer = 0;
    uint8_t timer_flag = 0;
    uint8_t adc_index = 12;
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    uint8_t ReceiveRegAddr = 0;
    
    uint8_t SlaveReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t SlaveRXByteCtr = 0;
    uint8_t SlaveReceiveIndex = 0;
    uint8_t SlaveTransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t SlaveTXByteCtr = 0;
    uint8_t SlaveTransmitIndex = 0;
    
    uint8_t I2C_Slave_counter = 0;
    
    //I2C_1_MASTER:
    //uint8_t Slave_Address = 0x92;
    //EXT ADC
    uint16_t EXT_ADC_DATA[9] = {0};
    uint8_t EXT_ADC_DATA_REGISTERS[30] = {0};
    uint8_t reg_place = 0;
    bool Rx_Finish_Flag = 0;
    
    unsigned int counterWrite = 0, counter = 0;
    
    uint8_t I2C_RXData;
    uint8_t I2C_RXData_LTC2991;
    
    
    void main(void)
    {
    
    WDT_A_hold(WDT_A_BASE);
    PM5CTL0 &= ~LOCKLPM5;
    Configure_GPIOs();
    
    
    
       Configure_Clocks();
       Configure_I2C_Master();
       Init_I2C_Slave();
       Configure_ADC();
       Configure_Timer();
       Configure_UART_A1();
    
    
       LTC2991_config();
    
    
    
    
    
        //////////////////////////////////////////////
        //////////////Version////////////////////////
        reg_map.Registers.version.Major_Ver = 0x0;
        reg_map.Registers.version.Minor_Ver = 0x8;
        // 0.6 = Debug mode including Slave I2C.
        // 0.7 = Default MODE_OPERATIONAL_5 (Based on 0.6)
                 //Fixed the power down sequence for LV and HV
        // 0.8 - Including Voltage startup fix.
        /////////////////////////////////////////////
    
    
        //__enable_interrupt();
       // PMM_unlockLPM5();
    
        __bis_SR_register(GIE);
    
        while(1)
        {
    
            if (timer_tick == 1)
            {
    
                       timer_tick = 0;
    
                       switch (work_mode_fsm)
                       {
                       case MODE_DEBUG:
                           /*
                           strcpy(TX_UART,"Hello World");
                           uart_string_tx();
                          // __delay_cycles(160000);
    
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x1c);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0xD);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0xA);
    
                           __delay_cycles(160000);
    */
    
    
                       break;
    
                       case MODE_OPERATIONAL_5:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                           //strcpy(TX_UART,"Operational 5 Mode");
                           //uart_string_tx();
                       break;
                       case MODE_OPERATIONAL_16:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                       break;
                       case MODE_OPERATIONAL_25:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                       break;
                       case MODE_OPERATIONAL_33:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                       break;
                       case MODE_MEMORY_UPLOADING:
                       break;
                       case MODE_RXONLY:
                       break;
                       case DSS1:
                       break;
                       case DSS2:
                       break;
                       case MODE_OPERATIONAL_0:  // 11
                           //reg_map.Registers.Status.LV_Power_En = 1;
                           //if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           //{
                           //    reg_map.Registers.Status.HV_Power_En = 1;
                           //}
                           strcpy(TX_UART,"Mode Operational 0\r\n");
                           uart_string_tx();
                       break;
                       }
    
    
                       switch(lv_pu_fsm)
                       {
                       case lv_st_idle:
                           reg_map.Registers.Status.HV_Power_En = 0;  // for any case shuts down the HV because we are about to start LV PU sequences
    
                           GPIO_setOutputLowOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Disable P12VA
                           GPIO_setOutputLowOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Disable P12VD
                           GPIO_setOutputLowOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputLowOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
    
                           //strcpy(TX_UART,"lv_st_idle\r\n");
                           //uart_string_tx();
    
                           if (reg_map.Registers.Status.LV_Power_En)
                           {
                               lv_pu_fsm = lv_st_1_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_idle; // stay here if PD seq is enable
                           }
                       break;
    
                       case lv_st_1_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputLowOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputLowOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
                           // add here a condition for the IFD to continue for the rest of the low voltages PU seq
    
                           //strcpy(TX_UART,"lv_st_1_pu_seq\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P12VA_PG_PORT ,P12VA_PG_PIN) && reg_map.Registers.Status.LV_Power_En)  //notice that the P12VD-PG is not poart of the PU seq -> can be changes if needed
                           {
                             // CHANGE BACK TO THIS!
                               lv_pu_fsm = lv_st_2_pu_seq;
                               // Skipping 3.7V PGOOD AS A CONDITION straight to 3rd stage instead of 2nd (for damaged boards)
                               //lv_pu_fsm = lv_st_3_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_idle;
                           }
                       break;
    
                       case lv_st_2_pu_seq:
    
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputLowOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
                           //strcpy(TX_UART,"lv_st_2_pu_seq:\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P3V7A_PG_PORT ,P3V7A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
    
                           {
                               lv_pu_fsm = lv_st_3_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_1_pu_seq;
                           }
                       break;
                       case lv_st_3_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputHighOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
    
                           //strcpy(TX_UART,"lv_st_3_pu_seq:\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P1V5A_PG_PORT ,P1V5A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
                           {
                               lv_pu_fsm = lv_st_4_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_2_pu_seq;
                           }
                       break;
                       case lv_st_4_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputHighOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputHighOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputHighOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
                           //strcpy(TX_UART,"lv_st_4_pu_seq:\r\n");
                           //uart_string_tx();
    
                           //if (GPIO_getInputPinValue(N5V2A_PG_PORT ,N5V2A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
                           //{
                               lv_pu_fsm = lv_st_5_pu_seq;
                           //}
                           //else if (reg_map.Registers.Status.LV_Power_En == 0)
                           //{
                           //    lv_pu_fsm = lv_st_3_pu_seq;
                           //}
                       break;
                       case lv_st_5_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputHighOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputHighOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputHighOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputHighOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
    
                           //strcpy(TX_UART,"lv_st_5_pu_seq:\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P5V4A_PG_PORT ,P5V4A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
                           {
                               lv_pu_fsm = lv_st_finish;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_4_pu_seq;
                           }
                       break;
                       case lv_st_finish:
                           //reg_map.Registers.Status.HV_Power_En = 1;   //Enable for HV PU wii be from the main FSM
                           reg_map.Registers.Status.LV_Power_Up_Done = 1;  // done LV PU seq
    
                           //strcpy(TX_UART,"lv_st_finish:\r\n");
                           //uart_string_tx();
    
                           if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               reg_map.Registers.Status.LV_Power_Up_Done = 0;
                               lv_pu_fsm = lv_st_5_pu_seq;
                           }
                       break;
                       }
    
                       switch(hv_pu_fsm)
                       {
                       case hv_st_idle:
    
                           GPIO_setOutputLowOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputLowOnPin(P36VA_EN_PORT, P36VA_EN_PIN);
                           //GPIO_setOutputLowOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
    
                           if (reg_map.Registers.Status.HV_Power_En == 1)
                           {
                               hv_pu_fsm = hv_st_1_pu_seq;
                           }
                           else
                           {
                               hv_pu_fsm = hv_st_idle;
                           }
                       break;
                       case hv_st_1_pu_seq:
                           GPIO_setOutputHighOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputLowOnPin(P36VA_EN_PORT, P36VA_EN_PIN);
                           //GPIO_setOutputLowOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
    
                           if ((reg_map.Registers.EXT_P7V3 > 6500) && reg_map.Registers.Status.HV_Power_En)
                           {
                               hv_pu_fsm = hv_st_2_pu_seq;
                           }
                           else if (reg_map.Registers.Status.HV_Power_En == 0)
                           {
                               hv_pu_fsm = hv_st_1_pu_seq;
                           }
                       break;
                       case hv_st_2_pu_seq:
                           GPIO_setOutputHighOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputHighOnPin(P36VA_EN_PORT, P36VA_EN_PIN); // not in the game
                           //GPIO_setOutputHighOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
    
                           if ((reg_map.Registers.EXT_36VA > 28000) && reg_map.Registers.Status.HV_Power_En)
                           {
                               hv_pu_fsm = hv_st_3_pu_seq;
                           }
                           else if (reg_map.Registers.Status.HV_Power_En == 0)
                           {
                               hv_pu_fsm = hv_st_2_pu_seq;
                           }
                       break;
                       case hv_st_3_pu_seq:
                           GPIO_setOutputHighOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputHighOnPin(P36VA_EN_PORT, P36VA_EN_PIN); // not in the game
                           //GPIO_setOutputHighOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
                       break;
                       case hv_st_finish:
                           reg_map.Registers.Status.HV_Power_Up_Done = 1;
                       break;
                       }
    
    
    
                }
    
        }
    
    
    }
    
    void Configure_Clocks(void)
    {
        CS_initClockSignal(CS_FLLREF,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);     //  Set DCO FLL reference = REFO
        CS_initClockSignal(CS_MCLK,CS_DCOCLKDIV_SELECT,CS_CLOCK_DIVIDER_1);     //  Set MCLK sourced from DCOCLKDIV
        CS_initClockSignal(CS_SMCLK,CS_DCOCLKDIV_SELECT,CS_CLOCK_DIVIDER_8);  //  Set SMCLK = MCLK/8
        CS_initClockSignal(CS_ACLK,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);       //  Set ACLK = REFO ~= 32.85kHz
        CS_initFLLParam param = {0};                                            //  Create struct variable to store proper software trim values
        CS_initFLLCalculateTrim(24000,731,&param);                              //  Set Ratio/Desired MCLK Frequency, initialize DCO, save trim values
        CS_initFLLSettle(24000,731);                                            //  For demonstration purpose, change DCO clock freq to 24MHz
        CS_initFLLLoadTrim(24000,731,&param);                                   //  Reload DCO trim values that were calculated earlier
    }
    
    void Configure_UART_A1(void)
    {
    
        EUSCI_A_UART_initParam param = {0};
        param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
        param.clockPrescalar = 1;   //UCBR
        //param.clockPrescalar = 2;
        param.firstModReg = 10;
        param.secondModReg = 0x01;
        param.parity = EUSCI_A_UART_NO_PARITY;
        param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
        param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
        param.uartMode = EUSCI_A_UART_MODE;
        //param.overSampling = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;
        param.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
    
        EUSCI_A_UART_init(EUSCI_A1_BASE, &param);
        EUSCI_A_UART_enable(EUSCI_A1_BASE);
        EUSCI_A_UART_clearInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT+EUSCI_A_UART_TRANSMIT_INTERRUPT);
        // Enable USCI_A1 RX interrupt
        EUSCI_A_UART_enableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT+EUSCI_A_UART_TRANSMIT_INTERRUPT);
    }
    
    void Configure_Timer(void){
        TB0CCTL0 |= CCIE;                                             // TBCCR0 interrupt enabled
        TB0CCR0 = 10000;
        TB0CTL = TBSSEL__SMCLK | MC__UP;
        TB0CCTL0 &= ~CCIFG;
    }
    
    void Configure_I2C_Master(void)//for external ADC and temperature sensor
    {
    
        UCB1CTLW0 = UCSWRST;                                    // Enable SW reset
        UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
        UCB1BRW = 10;                                           // fSCL = SMCLK/50 = ~60kHz
        UCB1CTLW0 &= ~UCSWRST;                                  // Clear SW reset, resume operation
        UCB1IE |= UCNACKIE;
    
    }
    
    void Read_Ext_ADC(void)
    {
        strcpy(TX_UART,"READ LTC2991 Data - Start\r\n");
        uart_string_tx();
        EUSCI_B_I2C_setSlaveAddress (EUSCI_B1_BASE, LTC2991_ADDRESS);
        EUSCI_B_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
        EUSCI_B_I2C_enable(EUSCI_B1_BASE);
        EUSCI_B_I2C_clearInterrupt(EUSCI_B1_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT);
        EUSCI_B_I2C_enableInterrupt(EUSCI_B1_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT);
        //while (Rx_Finish_Flag == 0); //wait for end of read data from I2C.
        //Rx_Finish_Flag = 0;
        EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, 0x12);
        //while (EUSCI_B_I2C_isBusBusy(EUSCI_B1_BASE)) ;
        I2C_RXData_LTC2991 = EUSCI_B_I2C_slaveGetData(EUSCI_B1_BASE);
        sprintf(TX_UART, "%d", I2C_RXData_LTC2991);
        strcat(TX_UART, " - P1V5 Value\n");
        uart_string_tx();
    
    }
    
    I2C_Mode I2C_Master_ReadReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB1I2CSA = dev_addr;
        UCB1IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB1IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB1IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB1CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    
    }
    
    I2C_Mode I2C_Master_WriteReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
    
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB1I2CSA = dev_addr;
        UCB1IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB1IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB1IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB1CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(GIE);                 // enable global interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    void LTC2991_config()
    {
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x01, CHANNEL_EN_LTC2991, 1);     // 0x48 is ADC address, 0x01 is channel enable register, 0xF8 enables all channels and VCC, sends 1 byte
        __delay_cycles(4000);
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x06, CONTROL_06_REG_LTC2991, 1);
        __delay_cycles(4000);
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x07, CONTROL_07_REG_LTC2991, 1);  //Enable Channel Filters
        __delay_cycles(4000);
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x08, CONTROL_08_REG_LTC2991, 1);  //Enable Channel Filters
        __no_operation();
    }
    
    void LTC2991_Read_All_Channels(uint8_t sensor_addr,uint8_t channel)
    {
        int i;
        uint8_t temp_reg_array[20] = {0};
        //uint16_t temp_reg_16bit[8] = {0};
        I2C_Master_ReadReg_B1(sensor_addr, channel, 20);
    
        __delay_cycles(3700+14000);                     // time delay for i2c transmission to end:
                                                        //
                                                        // time for writing command and receiving first channel data - (50/330kHz)*24MHz ~ 3700 cycles
                                                        // time for the rest of the channel data - for 7 channels each containing 20 bits: (140/330kHz)*24MHz ~ 11000 cycles
    
    
        CopyArray(ReceiveBuffer, temp_reg_array, 20);
        for(i=0; i<10; i++)
        {
            reg_map.Registers.Ext_ADC[i] = ((temp_reg_array[2*i] << 8) | temp_reg_array[2*i+1] );
        }
    }
    
    uint16_t TMP102_Read_Temp_Reg(uint8_t sensor_addr)
    {
        //uint8_t TMP102_ADDR = 0x00;
        uint8_t temp_reg_array[2] = {0};
        uint16_t temp_reg_16bit = 0;
        I2C_Master_ReadReg_B1(sensor_addr, TMP102_TMP_REG, 2);
    
        __delay_cycles(8000);
    
        CopyArray(ReceiveBuffer, temp_reg_array, 2);
        temp_reg_16bit = ((temp_reg_array[0] << 4) | (temp_reg_array[1] >> 4));
        return temp_reg_16bit;
    }
    
    void Delay_Func(uint8_t delayCNT)
    {
       while (delayCNT >0)
       {
           delayCNT--;
       }
    }
    
    void Init_I2C_Slave()
    {
        UCB0CTLW0 = UCSWRST;                      // Software reset enabled
        UCB0CTLW0 |= UCMODE_3 | UCSYNC;           // I2C mode, sync mode
        UCB0CTLW0 &= ~UCTR;                       // Receive mode
        UCB0I2COA0 = SLAVE_OWN_ADDR | UCOAEN;     // Own Address and enable
        UCB0CTLW0 &= ~UCSWRST;                    // clear reset register
        UCB0IE |= UCRXIE + UCTXIE + UCSTPIE;
    }
    
    void I2C_Slave_ProcessCMD(uint8_t cmd)      // Process the command
    {
        SlaveReceiveIndex = 0;
        SlaveTransmitIndex = 0;
        SlaveRXByteCtr = 0;
        SlaveTXByteCtr = 0;
    
        switch (cmd)
        {
            case (M_NO_CMD):                            //-- No command
                SlaveMode = RX_REG_ADDRESS_MODE;
                //UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
                //UCB0IE |= UCRXIE;                       // Enable RX interrupt
                break;
            case (M_MODE_SELECT):                       //-- Master selects the operation mode
                SlaveMode = RX_DATA_MODE;
                SlaveRXByteCtr = 1;
                //UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
                //UCB0IE |= UCRXIE;                       // Enable RX interrupt
                break;
            case (M_WRITE_REG):                         //-- Master writes directly to command registers
                SlaveMode = RX_DATA_MODE;
                SlaveRXByteCtr = 2;                          //-- first byte selects the register to write, second byte contains the data to write
                //UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
                //UCB0IE |= UCRXIE;                       // Enable RX interrupt
                break;
            case (M_READ_REG):                          //-- Master reads data from registers
                SlaveMode = RX_DATA_MODE;
                SlaveRXByteCtr = 1;
                break;
            default:
                __no_operation();
                break;
        }
    }
    
    
    void I2C_Slave_TransactionDone(uint8_t cmd)     // Execute the command
    {
        //strcpy(TX_UART,"Done Recieving Byte\r\n");
        //uart_string_tx();
        int i;
        switch (cmd)
        {
    
            case (M_NO_CMD):                            // No command
                for(i = 0; i<MAX_BUFFER_SIZE;i++)
                {
                    SlaveReceiveBuffer[i] = 0;
                }
            //strcpy(TX_UART,"No Command\r\n");
            //uart_string_tx();
            break;
    
            case (M_MODE_SELECT):                       // mode select is written to the MODE_SELECT
                work_mode_fsm = SlaveReceiveBuffer[0];
                for(i = 0; i<MAX_BUFFER_SIZE;i++)
                    {
                        SlaveReceiveBuffer[i] = 0;
                    }
                do_getmode();
                break;
                /*
            case (M_WRITE_REG):                         //Send slave device location (This device's location)
                switch(SlaveReceiveBuffer[0])
                {
                case 0:
                    reg_map.Registers.Command.reg.MSP_EMERG_EN = SlaveReceiveBuffer[1];
                    break;
                case 1:
                    reg_map.Registers.Command.reg.MSP_BOOST_EN = SlaveReceiveBuffer[1];
                    break;
                case 2:
                    reg_map.Registers.Command.reg.SMCC_ETH_PWDn = SlaveReceiveBuffer[1];
                    break;
                case 3:
                    reg_map.Registers.Command.reg.MAIN_BKUPn_EN = SlaveReceiveBuffer[1];
                    break;
                case 4:
                    reg_map.Registers.Command.reg.MSP_SMCC_HV_EN = SlaveReceiveBuffer[1];
                    break;
                default:
                    break;
    
                    for(i = 0; i<MAX_BUFFER_SIZE;i++)
                    {
                        SlaveReceiveBuffer[i] = 0;
                    }
                }
                break;
                */
    
            case (M_READ_REG):
                    for(i = 0; i<MAX_BUFFER_SIZE;i++)
                    {
                        SlaveTransmitBuffer[i] = 0;
                    }
                    switch(SlaveReceiveBuffer[0])
                    {
                    case 0:         // Read external ADC regs
                        SlaveTXByteCtr = 20;
                        SlaveTransmitBuffer[0] = reg_map.Registers.EXT_N5V2A;
                        SlaveTransmitBuffer[1] = reg_map.Registers.EXT_N5V2A >> 8;
                        SlaveTransmitBuffer[2] = reg_map.Registers.EXT_N4VA;
                        SlaveTransmitBuffer[3] = reg_map.Registers.EXT_N4VA >> 8;
                        SlaveTransmitBuffer[4] = reg_map.Registers.EXT_VCC_HIGH;
                        SlaveTransmitBuffer[5] = reg_map.Registers.EXT_VCC_HIGH >> 8;
                        SlaveTransmitBuffer[6] = reg_map.Registers.EXT_VCC_LOW;
                        SlaveTransmitBuffer[7] = reg_map.Registers.EXT_VCC_LOW >> 8;
                        SlaveTransmitBuffer[8] = reg_map.Registers.EXT_P1V5;
                        SlaveTransmitBuffer[9] = reg_map.Registers.EXT_P1V5 >> 8;
                        SlaveTransmitBuffer[10] = reg_map.Registers.EXT_P7V3;
                        SlaveTransmitBuffer[11] = reg_map.Registers.EXT_P7V3 >> 8;
                        SlaveTransmitBuffer[12] = reg_map.Registers.EXT_36VA;
                        SlaveTransmitBuffer[13] = reg_map.Registers.EXT_36VA >> 8;
                        SlaveTransmitBuffer[14] = reg_map.Registers.EXT_GND;
                        SlaveTransmitBuffer[15] = reg_map.Registers.EXT_GND >> 8;
                        SlaveTransmitBuffer[16] = reg_map.Registers.EXT_TMP;
                        SlaveTransmitBuffer[17] = reg_map.Registers.EXT_TMP >> 8;
                        SlaveTransmitBuffer[18] = reg_map.Registers.EXT_VCC;
                        SlaveTransmitBuffer[19] = reg_map.Registers.EXT_VCC >> 8;
                        break;
                    case 1:         // Read internal ADC regs
                        SlaveTXByteCtr = 14;
                        SlaveTransmitBuffer[0] = reg_map.Registers.ADC0;
                        SlaveTransmitBuffer[1] = reg_map.Registers.ADC0 >> 8;
                        SlaveTransmitBuffer[2] = reg_map.Registers.ADC1;
                        SlaveTransmitBuffer[3] = reg_map.Registers.ADC1 >> 8;
                        SlaveTransmitBuffer[4] = reg_map.Registers.ADC4;
                        SlaveTransmitBuffer[5] = reg_map.Registers.ADC4 >> 8;
                        SlaveTransmitBuffer[6] = reg_map.Registers.ADC5;
                        SlaveTransmitBuffer[7] = reg_map.Registers.ADC5 >> 8;
                        SlaveTransmitBuffer[8] = reg_map.Registers.INT_TEMP;
                        SlaveTransmitBuffer[9] = reg_map.Registers.INT_TEMP >> 8;
                        SlaveTransmitBuffer[10] = reg_map.Registers.TMP102_A;
                        SlaveTransmitBuffer[11] = reg_map.Registers.TMP102_A >> 8;
                        SlaveTransmitBuffer[12] = reg_map.Registers.TMP102_B;
                        SlaveTransmitBuffer[13] = reg_map.Registers.TMP102_B >> 8;
                        break;
                    default:
                        break;
                    }
                break;
    //*/
            //default:
               // __no_operation();
              //  break;
        }
    }
    
    //******************************************************************************
    //
    //This is the USCI_A1 interrupt vector service routine. UART.
    //
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A1_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_A1_VECTOR)))
    #endif
    void EUSCI_A1_ISR(void)
    {
        switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))
        {
            case USCI_NONE: break;
            case USCI_UART_UCRXIFG:
                RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
                RX_buff[i++] = RXData;
                // Check value
                if (RXData == '\r' || RXData == '\n')
                {
                    EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 13);
                    EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 10);
                    RX_buff[--i] = '\0';
                    memcpy(cmd_in, RX_buff,sizeof(RX_buff));
                    split_cmd();
                    for (i = 0;i<sizeof(RX_buff); i++)
                        RX_buff[i] = 0;
                    i=0;
                    P3OUT ^= 0x10;
                }
                check =1;
                break;
           case USCI_UART_UCTXIFG: break;
           case USCI_UART_UCSTTIFG: break;
           case USCI_UART_UCTXCPTIFG: break;
        }
    }
    
    
    //******************************************************************************
    //
    //This is the Timer B0 interrupt vector service routine.
    //
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=TIMERB0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(TIMERB0_VECTOR)))
    #endif
    void TIMERB0_ISR (void)
    {
        uint16_t temp_reg;
        //if (timer_flag == 0)
        //{
        adc_timer++;
        timer_tick = 1;
        //}
        GPIO_toggleOutputOnPin(MSP_LED_PORT, MSP_LED_PIN);
        //update PGOOD inputs:
        /*
        reg_map.Registers.Status.N4VA_PG = GPIO_getInputPinValue(N4VA_PG_PORT, N4VA_PG_PIN);
        reg_map.Registers.Status.P12VD_PG = GPIO_getInputPinValue(P12VD_PG_PORT, P12VD_PG_PIN);
        reg_map.Registers.Status.P12VA_PG = GPIO_getInputPinValue(P12VA_PG_PORT, P12VA_PG_PIN);
        reg_map.Registers.Status.P1V5A_PG = GPIO_getInputPinValue(P1V5A_PG_PORT, P1V5A_PG_PIN);
        reg_map.Registers.Status.P3V7A_PG = GPIO_getInputPinValue(P3V7A_PG_PORT, P3V7A_PG_PIN);
        reg_map.Registers.Status.N5V2A_PG = GPIO_getInputPinValue(N5V2A_PG_PORT, N5V2A_PG_PIN);
        reg_map.Registers.Status.P5V4A_PG = GPIO_getInputPinValue(P5V4A_PG_PORT, P5V4A_PG_PIN);
         */
    
        if (adc_timer == 500)
        {
            if (I2C_Slave_counter == 4)
            {
                I2C_Slave_counter = 0;
            }
            else
            {
                I2C_Slave_counter += 1;
            }
                //timer_flag = 1;
    
                //Read_Ext_ADC();
            switch (I2C_Slave_counter)
            {
                case 0:
                {
                    //if (UCB1STATW != UCBBUSY)
                    //{
                        reg_map.Registers.TMP102_A = TMP102_Read_Temp_Reg(TMPa_ADDRESS) * TMP102_SF_TMP * 1000;
                    //}
                }
                break;
                case 1:
                {
                    //if (UCB1STATW != UCBBUSY)
                    //{
                        reg_map.Registers.TMP102_B = TMP102_Read_Temp_Reg(TMPb_ADDRESS) * TMP102_SF_TMP * 1000;
                    //}
                }
                case 2:
                {
                   if (UCB1STATW != UCBBUSY)
                   {
                       LTC2991_Read_All_Channels(LTC2991_WR_ADDRESS,0x0A);        // read all adc channels starting from V1 (0x0A)
    
                       if (reg_map.Registers.Ext_ADC[0] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[0] & LTC2991_SIGN)
                           {reg_map.Registers.EXT_N5V2A    = 0;}
                           else
                           {reg_map.Registers.EXT_N5V2A    = (reg_map.Registers.Ext_ADC[0] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_N5V2A;}
                       }
                       else
                       {reg_map.Registers.EXT_N5V2A    = 0;}
                       if (reg_map.Registers.Ext_ADC[1] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[1] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_N4VA     = 0;}
                           else
                           {reg_map.Registers.EXT_N4VA = (reg_map.Registers.Ext_ADC[1] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_N4VA;}
                       }
                       else
                       {reg_map.Registers.EXT_N4VA = 0;}
                       if (reg_map.Registers.Ext_ADC[2] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[2] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_VCC_HIGH = 0;}
                           else
                           {reg_map.Registers.EXT_VCC_HIGH = (reg_map.Registers.Ext_ADC[2] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_VCC_HIGH;}
                       }
                       else
                       {reg_map.Registers.EXT_VCC_HIGH = 0;}
                       if (reg_map.Registers.Ext_ADC[3] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[3] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_VCC_LOW  = 0;}
                           else
                           {reg_map.Registers.EXT_VCC_LOW = (reg_map.Registers.Ext_ADC[3] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_VCC_LOW;}
                       }
                       else
                       {reg_map.Registers.EXT_VCC_LOW = 0;}
                       if (reg_map.Registers.Ext_ADC[4] & LTC2991_DV) {
                           if (reg_map.Registers.Ext_ADC[4] & LTC2991_SIGN)
                            {reg_map.Registers.EXT_P1V5     = 0;}
                           else
                           {reg_map.Registers.EXT_P1V5 = (reg_map.Registers.Ext_ADC[4] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE;}
                       }
                       else{reg_map.Registers.EXT_P1V5 = 0;}
                       if (reg_map.Registers.Ext_ADC[5] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[5] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_P7V3     = 0;}
                           else
                           {reg_map.Registers.EXT_P7V3 = (reg_map.Registers.Ext_ADC[5] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_P7V3;}
                       }
                       else
                       {reg_map.Registers.EXT_P7V3 = 0;}
                       if (reg_map.Registers.Ext_ADC[6] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[6] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_36VA     = 0;}
                           else
                           {reg_map.Registers.EXT_36VA = (reg_map.Registers.Ext_ADC[6] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_36VA;}
                       }
                       else
                       {reg_map.Registers.EXT_36VA = 0;}
                       if (reg_map.Registers.Ext_ADC[7] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[7] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_GND      = 0;}
                           else
                           {
                               reg_map.Registers.EXT_GND = (reg_map.Registers.Ext_ADC[7] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE;
                           }
                       }
                       else
                       {
                           reg_map.Registers.EXT_GND = 0;
                       }
                   }
                   //reg_map.Registers.EXT_TMP      = (reg_map.Registers.Ext_ADC[8] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_TMP;
                   reg_map.Registers.EXT_TMP      = (reg_map.Registers.Ext_ADC[8] & LTC2991_DATA_MASK) *  LTC2991_SF_TMP * 1000;
                   reg_map.Registers.EXT_VCC      = ((reg_map.Registers.Ext_ADC[9] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE) + 2500;
               }
                break;
                case 3:
                {
                    ADC_startConversion(ADC_BASE,ADC_SEQOFCHANNELS);
    
                }
                break;
    
            }
    
            //Delay_Func(1000);
    
            adc_timer = 0;
                //timer_flag = 0;
        }
    
        TB0CTL &= ~TBIFG;
    }
    
    
    void Configure_ADC(void)
    {
    
        ADC_init(ADC_BASE, ADC_SAMPLEHOLDSOURCE_SC, ADC_CLOCKSOURCE_ACLK,ADC_CLOCKDIVIDER_1);
        ADC_setResolution(ADC_BASE, ADC_RESOLUTION_12BIT);
        ADC_enable(ADC_BASE);
        //ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_16_CYCLES,ADC_MULTIPLESAMPLESENABLE);
        ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_16_CYCLES,ADC_MULTIPLESAMPLESENABLE);
        //ADC_configureMemory(ADC_BASE, ADC_INPUT_TEMPSENSOR, ADC_VREFPOS_AVCC,ADC_VREFNEG_AVSS);
        ADC_configureMemory(ADC_BASE, ADC_INPUT_TEMPSENSOR, ADC_VREFPOS_INT,ADC_VREFNEG_AVSS);
        //ADC_configureMemory(ADC_BASE, ADC_INPUT_A9, ADC_VREFPOS_AVCC,ADC_VREFNEG_AVSS);
    
        ADC_clearInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
        ADC_enableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
        PMM_enableInternalReference();
        //PMMCTL2 |= REFVSEL_2;
        PMMCTL0_H = PMMPW_H;
        PMMCTL2  |= TSENSOREN + REFVSEL_2;
    
        /*
        ADCCTL0 |= ADCSHT_8 | ADCON;                                  // ADC ON,sample period>30us
        ADCCTL1 |= ADCSHP;                                            // s/w trig, single ch/conv, MODOSC
        ADCCTL2 &= ~ADCRES;                                           // clear ADCRES in ADCCTL
        ADCCTL2 |= ADCRES_2;                                          // 12-bit conversion results
        ADCMCTL0 |= ADCSREF_1 | ADCINCH_12;                           // ADC input ch A12 => temp sense
        ADCIE |=ADCIE0;                                               // Enable the Interrupt request for a completed ADC_B conversion
    
        // Configure reference
        PMMCTL0_H = PMMPW_H;                                          // Unlock the PMM registers
        PMMCTL2 |= REFVSEL_2;
        PMMCTL2 |=  INTREFEN | TSENSOREN;                              // Enable internal reference and temperature sensor
    
        __delay_cycles(400);                                          // Delay for reference settling
        */
    }
    
    //******************************************************************************
    //ADC10 interrupt service routine
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(ADC_VECTOR)))
    #endif
    void ADC_ISR (void){
        //uint16_t adc_data;
        switch (__even_in_range(ADCIV,12)){
            case  0: break; //No interrupt
            case  2: break; //conversion result overflow
            case  4: break; //conversion time overflow
            case  6: break; //ADCHI
            case  8: break; //ADCLO
            case 10: break; //ADCIN
            case 12:        //ADCIFG0
    
                //reg_map.Registers.TMP102_A = TMP102_Read_Temp_Reg(0);
                //Automatically clears ADCIFG0 by reading memory buffer
                adc_data[adc_index] = ADC_getResults(ADC_BASE);
                //adc_data = ADCMEM0;
                //reg_map.value[sizeof(reg_map.value) - adc_index] = adc_data;
                //reg_map.value[sizeof(reg_map.value) - adc_index - 1] = adc_data >> 8;
                //reg_map[128 - adc_index] = ADCMEM0;
                if(adc_index == 0){
                    //reg_map.Registers.TMP102_A = TMP102_Read_Temp_Reg(0);
                    //reg_map.Registers.TMP102_B = TMP102_Read_Temp_Reg(1);
                    adc_index = 12;
                    reg_map.Registers.ADC0 = adc_data[0] * 48.5 * 0.61;
                    reg_map.Registers.ADC1 = adc_data[1] * 48.5 * 0.61;
                    reg_map.Registers.ADC4 = adc_data[4] * 48.5 * 0.61;
                    reg_map.Registers.ADC5 = adc_data[5] * 48.5 * 0.61;
                    reg_map.Registers.ADC8 = adc_data[8] * 5.75 * 0.61;
                    reg_map.Registers.ADC9 = adc_data[9] * 5.75 * 0.61;
                    reg_map.Registers.INT_TEMP = adc_data[12];
                    ADC_disableConversions(ADC_BASE, ADC_COMPLETECONVERSION);
                }
                else    adc_index--;
                __bic_SR_register_on_exit(CPUOFF);
                break;
            default: break;
        }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB0RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
    
                rx_val = UCB0RXBUF;
                switch (SlaveMode)
                {
                case (RX_REG_ADDRESS_MODE):
                    ReceiveRegAddr = rx_val;
                    I2C_Slave_ProcessCMD(ReceiveRegAddr);
                    break;
                case (RX_DATA_MODE):
                      SlaveReceiveBuffer [SlaveReceiveIndex++] = rx_val;
                      SlaveRXByteCtr--;
                      if (SlaveRXByteCtr == 0)
                      {
                          //Done Receiving MSG
                          SlaveMode = RX_REG_ADDRESS_MODE;
                          UCB0CTLW0 &= ~UCTR;
                          //UCB0IE &= ~(UCTXIE);
                          //UCB0IE |= UCRXIE;                          // Enable RX interrupt
                          I2C_Slave_TransactionDone(ReceiveRegAddr);
                      }
                      break;
                  default:
                      __no_operation();
                      break;
                }
    
    
            break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    
                UCB0TXBUF = SlaveTransmitBuffer[SlaveTransmitIndex++];
                SlaveTXByteCtr--;
                if (SlaveTXByteCtr == 0)
                {
                    //Done Transmitting MSG
                    UCB0CTLW0 &= ~UCTR;
                    //UCB0IE &= ~(UCTXIE);
                    //UCB0IE |= UCRXIE;                          // Enable RX interrupt
                }
    
            break;
        default: break;
      }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB1RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
    
                rx_val = UCB1RXBUF;
                if (RXByteCtr)
                {
                    ReceiveBuffer[ReceiveIndex++] = rx_val;
                    RXByteCtr--;
                }
    
                if (RXByteCtr == 1)
                {
                    UCB1CTLW0 |= UCTXSTP;
                }
                else if (RXByteCtr == 0)
                {
                    UCB1IE &= ~UCRXIE;
                    MasterMode = IDLE_MODE;
                }
    
            break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    
                switch (MasterMode)
                {
                case TX_REG_ADDRESS_MODE:
                    UCB1TXBUF = TransmitRegAddr;
                    if (RXByteCtr)
                        MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                    else
                        MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                    break;
    
                case SWITCH_TO_RX_MODE:
                    UCB1IE |= UCRXIE;              // Enable RX interrupt
                    UCB1IE &= ~UCTXIE;             // Disable TX interrupt
                    UCB1CTLW0 &= ~UCTR;            // Switch to receiver
                    MasterMode = RX_DATA_MODE;    // State state is to receive data
                    UCB1CTLW0 |= UCTXSTT;          // Send repeated start
                    if (RXByteCtr == 1)
                    {
                        //Must send stop since this is the N-1 byte
                        while((UCB1CTLW0 & UCTXSTT));
                        UCB1CTLW0 |= UCTXSTP;      // Send stop condition
                    }
                    break;
    
                case TX_DATA_MODE:
                    if (TXByteCtr)
                    {
                        UCB1TXBUF = TransmitBuffer[TransmitIndex++];
                        TXByteCtr--;
                    }
                    else
                    {
                        //Done with transmission
                        UCB1CTLW0 |= UCTXSTP;     // Send stop condition
                        MasterMode = IDLE_MODE;
                        UCB1IE &= ~UCTXIE;                       // disable TX interrupt
                    }
                    break;
    
                default:
                    __no_operation();
                    break;
                }
    
            break;
        default: break;
      }
    }
    
    //Working Version
    
    #include <driverlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    
    #include "PINOUT_BOARD.h"
    #include "register_map.h"
    #include "uart_func.h"
    
    
    void Configure_Clocks(void);
    void Configure_UART_A1(void);//for TE - test equipment
    //void Configure_TimerB(void);
    void Configure_I2C_Master(void);//for external ADC and temperature sensor
    void Init_I2C_Slave();
    void I2C_Slave_ProcessCMD(uint8_t cmd);
    void I2C_Slave_TransactionDone(uint8_t cmd);
    //for IFD communication
    void Configure_ADC(void);//for IFD communication
    void Read_Ext_ADC(void); //by i2c,  also for reading the temperature sensors
    void Configure_Timer(void);
    void LTC2991_Read_All_Channels(uint8_t sensor_addr,uint8_t channel);
    void LTC2991_config();
    void Delay_Func(uint8_t delayCNT);
    #define TIMER_PERIOD            600
    #define MAX_BUFFER_SIZE         20
    
    //MSP430 I2C Slave address
    #define SLAVE_OWN_ADDR          0x48
    
    //  TMP102 a and b REGISTERS ADDRESSES
    #define TMP102_TMP_REG          0x00
    #define TMP102_CONFIG_REG       0x01
    #define TMP102_TLOW_REG         0x02
    #define TMP102_THIGH_REG        0x03
    #define TMPa_ADDRESS            0x48
    #define TMPb_ADDRESS            0x4B
    //  LTC2991 Registers
    #define LTC2991_DV              0x8000
    #define LTC2991_SIGN            0x4000
    #define LTC2991_DATA_MASK       0X3FFF
    #define LTC2991_ADDRESS         0x92
    #define LTC2991_WR_ADDRESS      0x49
    
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    
    
    enum M_CMD {M_NO_CMD,M_MODE_SELECT,M_WRITE_REG,M_READ_REG};
    enum M_CMD MASTER_CMD = M_NO_CMD;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    I2C_Mode SlaveMode = RX_REG_ADDRESS_MODE;
    
    I2C_Mode I2C_Master_WriteReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    I2C_Mode I2C_Master_ReadReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    uint16_t TMP102_Read_Temp_Reg(uint8_t sensor_addr);
    uint16_t temp_mode;
    
    float LTC2991_DATA_SCALE = 0.30518;
    uint16_t temp_float = 0;
    uint8_t CHANNEL_EN_LTC2991[1] = {0xF8};
    uint8_t CONTROL_06_REG_LTC2991[1] = {0x88};
    uint8_t CONTROL_07_REG_LTC2991[1] = {0x88};
    uint8_t CONTROL_08_REG_LTC2991[1] = {0x10};
    uint8_t value_in;
    uint32_t clockValue;
    //uint8_t address_ptr = 1;
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    //LV_PU_FSM:
    enum LV_PU_FSM
    {
        lv_st_idle = 0,
        lv_st_1_pu_seq = 1,
        lv_st_2_pu_seq = 2,
        lv_st_3_pu_seq = 3,
        lv_st_4_pu_seq = 4,
        lv_st_5_pu_seq = 5,
        lv_st_finish   = 6
    };
    enum LV_PU_FSM lv_pu_fsm = lv_st_idle;
    
    enum HV_PU_FSM
    {
        hv_st_idle = 0,
        hv_st_1_pu_seq = 1,
        hv_st_2_pu_seq = 2,
        hv_st_3_pu_seq = 3,
        hv_st_finish   = 4
    };
    enum HV_PU_FSM hv_pu_fsm = hv_st_idle;
    
    uint8_t timer_tick = 0;
    //uint8_t index = 0;
    //INTERNAL ADC:
    uint16_t adc_data[13];
    uint16_t adc_timer = 0;
    uint8_t timer_flag = 0;
    uint8_t adc_index = 12;
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    uint8_t ReceiveRegAddr = 0;
    
    uint8_t SlaveReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t SlaveRXByteCtr = 0;
    uint8_t SlaveReceiveIndex = 0;
    uint8_t SlaveTransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t SlaveTXByteCtr = 0;
    uint8_t SlaveTransmitIndex = 0;
    
    uint8_t I2C_Slave_counter = 0;
    
    //I2C_1_MASTER:
    //uint8_t Slave_Address = 0x92;
    //EXT ADC
    uint16_t EXT_ADC_DATA[9] = {0};
    uint8_t EXT_ADC_DATA_REGISTERS[30] = {0};
    uint8_t reg_place = 0;
    bool Rx_Finish_Flag = 0;
    
    unsigned int counterWrite = 0, counter = 0;
    
    uint8_t I2C_RXData;
    uint8_t I2C_RXData_LTC2991;
    
    
    void main(void)
    {
    WDT_A_hold(WDT_A_BASE);
    PM5CTL0 &= ~LOCKLPM5;
       Configure_GPIOs();
       Configure_Clocks();
       Configure_I2C_Master();
       Init_I2C_Slave();
       Configure_ADC();
       Configure_Timer();
       Configure_UART_A1();
    
    
       LTC2991_config();
    
        //__enable_interrupt();
        __bis_SR_register(GIE);
        //////////////////////////////////////////////
        //////////////Version////////////////////////
        reg_map.Registers.version.Major_Ver = 0x0;
        reg_map.Registers.version.Minor_Ver = 0x9;
        // 0.6 = Debug mode including Slave I2C.
        // 0.7 = Default MODE_OPERATIONAL_5 (Based on 0.6)
                 //Fixed the power down sequence for LV and HV
        /////////////////////////////////////////////
    
    
    
        while(1)
        {
    
            if (timer_tick == 1)
            {
    
                       timer_tick = 0;
    
                       switch (work_mode_fsm)
                       {
                       case MODE_DEBUG:
                           /*
                           strcpy(TX_UART,"Hello World");
                           uart_string_tx();
                          // __delay_cycles(160000);
    
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x1c);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x55);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0xD);
                           __delay_cycles(1600);
                           EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0xA);
    
                           __delay_cycles(160000);
    */
    
    
                       break;
    
                       case MODE_OPERATIONAL_5:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                           //strcpy(TX_UART,"Operational 5 Mode");
                           //uart_string_tx();
                       break;
                       case MODE_OPERATIONAL_16:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                       break;
                       case MODE_OPERATIONAL_25:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                       break;
                       case MODE_OPERATIONAL_33:
                           reg_map.Registers.Status.LV_Power_En = 1;
                           if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           {
                               reg_map.Registers.Status.HV_Power_En = 1;
                           }
                       break;
                       case MODE_MEMORY_UPLOADING:
                       break;
                       case MODE_RXONLY:
                       break;
                       case DSS1:
                       break;
                       case DSS2:
                       break;
                       case MODE_OPERATIONAL_0:  // 11
                           //reg_map.Registers.Status.LV_Power_En = 1;
                           //if ((reg_map.Registers.Status.LV_Power_Up_Done == 1) && (reg_map.Registers.Status.HV_Power_Up_Done == 0))
                           //{
                           //    reg_map.Registers.Status.HV_Power_En = 1;
                           //}
                           strcpy(TX_UART,"Mode Operational 0\r\n");
                           uart_string_tx();
                       break;
                       }
    
    
                       switch(lv_pu_fsm)
                       {
                       case lv_st_idle:
                           reg_map.Registers.Status.HV_Power_En = 0;  // for any case shuts down the HV because we are about to start LV PU sequences
    
                           GPIO_setOutputLowOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Disable P12VA
                           GPIO_setOutputLowOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Disable P12VD
                           GPIO_setOutputLowOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputLowOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
    
                           //strcpy(TX_UART,"lv_st_idle\r\n");
                           //uart_string_tx();
    
                           if (reg_map.Registers.Status.LV_Power_En)
                           {
                               lv_pu_fsm = lv_st_1_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_idle; // stay here if PD seq is enable
                           }
                       break;
    
                       case lv_st_1_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputLowOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputLowOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
                           // add here a condition for the IFD to continue for the rest of the low voltages PU seq
    
                           //strcpy(TX_UART,"lv_st_1_pu_seq\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P12VA_PG_PORT ,P12VA_PG_PIN) && reg_map.Registers.Status.LV_Power_En)  //notice that the P12VD-PG is not poart of the PU seq -> can be changes if needed
                           {
                             // CHANGE BACK TO THIS!
                               lv_pu_fsm = lv_st_2_pu_seq;
                               // Skipping 3.7V PGOOD AS A CONDITION straight to 3rd stage instead of 2nd (for damaged boards)
                               //lv_pu_fsm = lv_st_3_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_idle;
                           }
                       break;
    
                       case lv_st_2_pu_seq:
    
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputLowOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
                           //strcpy(TX_UART,"lv_st_2_pu_seq:\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P3V7A_PG_PORT ,P3V7A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
    
                           {
                               lv_pu_fsm = lv_st_3_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_1_pu_seq;
                           }
                       break;
                       case lv_st_3_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputHighOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputLowOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputLowOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
    
                           //strcpy(TX_UART,"lv_st_3_pu_seq:\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P1V5A_PG_PORT ,P1V5A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
                           {
                               lv_pu_fsm = lv_st_4_pu_seq;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_2_pu_seq;
                           }
                       break;
                       case lv_st_4_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputHighOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputHighOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputHighOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputLowOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
                           //strcpy(TX_UART,"lv_st_4_pu_seq:\r\n");
                           //uart_string_tx();
    
                           //if (GPIO_getInputPinValue(N5V2A_PG_PORT ,N5V2A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
                           //{
                               lv_pu_fsm = lv_st_5_pu_seq;
                           //}
                           //else if (reg_map.Registers.Status.LV_Power_En == 0)
                           //{
                           //    lv_pu_fsm = lv_st_3_pu_seq;
                           //}
                       break;
                       case lv_st_5_pu_seq:
                           GPIO_setOutputHighOnPin(P12VA_EN_PORT, P12VA_EN_PIN);  // Enable P12VA
                           GPIO_setOutputHighOnPin(P12VD_EN_PORT, P12VD_EN_PIN); // Enable P12VD
                           GPIO_setOutputHighOnPin(P3V7A_EN_PORT, P3V7A_EN_PIN);
                           GPIO_setOutputHighOnPin(P1V5A_EN_PORT, P1V5A_EN_PIN);
                           GPIO_setOutputHighOnPin(N5V2A_EN_PORT, N5V2A_EN_PIN);
                           GPIO_setOutputHighOnPin(N4VA_EN_PORT, N4VA_EN_PIN);
                           GPIO_setOutputHighOnPin(P5V4A_EN_PORT, P5V4A_EN_PIN);
    
                           //strcpy(TX_UART,"lv_st_5_pu_seq:\r\n");
                           //uart_string_tx();
    
                           if (GPIO_getInputPinValue(P5V4A_PG_PORT ,P5V4A_PG_PIN) && reg_map.Registers.Status.LV_Power_En)
                           {
                               lv_pu_fsm = lv_st_finish;
                           }
                           else if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               lv_pu_fsm = lv_st_4_pu_seq;
                           }
                       break;
                       case lv_st_finish:
                           //reg_map.Registers.Status.HV_Power_En = 1;   //Enable for HV PU wii be from the main FSM
                           reg_map.Registers.Status.LV_Power_Up_Done = 1;  // done LV PU seq
    
                           //strcpy(TX_UART,"lv_st_finish:\r\n");
                           //uart_string_tx();
    
                           if (reg_map.Registers.Status.LV_Power_En == 0)
                           {
                               reg_map.Registers.Status.LV_Power_Up_Done = 0;
                               lv_pu_fsm = lv_st_5_pu_seq;
                           }
                       break;
                       }
    
                       switch(hv_pu_fsm)
                       {
                       case hv_st_idle:
    
                           GPIO_setOutputLowOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputLowOnPin(P36VA_EN_PORT, P36VA_EN_PIN);
                           //GPIO_setOutputLowOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
    
                           if (reg_map.Registers.Status.HV_Power_En == 1)
                           {
                               hv_pu_fsm = hv_st_1_pu_seq;
                           }
                           else
                           {
                               hv_pu_fsm = hv_st_idle;
                           }
                       break;
                       case hv_st_1_pu_seq:
                           GPIO_setOutputHighOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputLowOnPin(P36VA_EN_PORT, P36VA_EN_PIN);
                           //GPIO_setOutputLowOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
    
                           if ((reg_map.Registers.EXT_P7V3 > 6500) && reg_map.Registers.Status.HV_Power_En)
                           {
                               hv_pu_fsm = hv_st_2_pu_seq;
                           }
                           else if (reg_map.Registers.Status.HV_Power_En == 0)
                           {
                               hv_pu_fsm = hv_st_1_pu_seq;
                           }
                       break;
                       case hv_st_2_pu_seq:
                           GPIO_setOutputHighOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputHighOnPin(P36VA_EN_PORT, P36VA_EN_PIN); // not in the game
                           //GPIO_setOutputHighOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputLowOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
    
                           if ((reg_map.Registers.EXT_36VA > 28000) && reg_map.Registers.Status.HV_Power_En)
                           {
                               hv_pu_fsm = hv_st_3_pu_seq;
                           }
                           else if (reg_map.Registers.Status.HV_Power_En == 0)
                           {
                               hv_pu_fsm = hv_st_2_pu_seq;
                           }
                       break;
                       case hv_st_3_pu_seq:
                           GPIO_setOutputHighOnPin(P7V3A_EN_PORT, P7V3A_EN_PIN);
                           GPIO_setOutputHighOnPin(P36VA_EN_PORT, P36VA_EN_PIN); // not in the game
                           //GPIO_setOutputHighOnPin(P36V_EN_DSCHRG_PORT, P36V_EN_DSCHRG_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q4_EN_PORT, P28VA_Q4_EN_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q3_EN_PORT, P28VA_Q3_EN_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q2_EN_PORT, P28VA_Q2_EN_PIN);
                           GPIO_setOutputHighOnPin(P28VA_Q1_EN_PORT, P28VA_Q1_EN_PIN);
                       break;
                       case hv_st_finish:
                           reg_map.Registers.Status.HV_Power_Up_Done = 1;
                       break;
                       }
    
                }
    
        }
    
    }
    
    void Configure_Clocks(void)
    {
        CS_initClockSignal(CS_FLLREF,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);     //  Set DCO FLL reference = REFO
        CS_initClockSignal(CS_MCLK,CS_DCOCLKDIV_SELECT,CS_CLOCK_DIVIDER_1);     //  Set MCLK sourced from DCOCLKDIV
        CS_initClockSignal(CS_SMCLK,CS_DCOCLKDIV_SELECT,CS_CLOCK_DIVIDER_8);  //  Set SMCLK = MCLK/8
        CS_initClockSignal(CS_ACLK,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);       //  Set ACLK = REFO ~= 32.85kHz
        CS_initFLLParam param = {0};                                            //  Create struct variable to store proper software trim values
        CS_initFLLCalculateTrim(24000,731,&param);                              //  Set Ratio/Desired MCLK Frequency, initialize DCO, save trim values
        CS_initFLLSettle(24000,731);                                            //  For demonstration purpose, change DCO clock freq to 24MHz
        CS_initFLLLoadTrim(24000,731,&param);                                   //  Reload DCO trim values that were calculated earlier
    }
    
    void Configure_UART_A1(void)
    {
    
        EUSCI_A_UART_initParam param = {0};
        param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
        param.clockPrescalar = 1;   //UCBR
        //param.clockPrescalar = 2;
        param.firstModReg = 10;
        param.secondModReg = 0x01;
        param.parity = EUSCI_A_UART_NO_PARITY;
        param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
        param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
        param.uartMode = EUSCI_A_UART_MODE;
        //param.overSampling = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;
        param.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
    
        EUSCI_A_UART_init(EUSCI_A1_BASE, &param);
        EUSCI_A_UART_enable(EUSCI_A1_BASE);
        EUSCI_A_UART_clearInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT+EUSCI_A_UART_TRANSMIT_INTERRUPT);
        // Enable USCI_A1 RX interrupt
        EUSCI_A_UART_enableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT+EUSCI_A_UART_TRANSMIT_INTERRUPT);
    }
    
    void Configure_Timer(void){
        TB0CCTL0 |= CCIE;                                             // TBCCR0 interrupt enabled
        TB0CCR0 = 10000;
        TB0CTL = TBSSEL__SMCLK | MC__UP;
        TB0CCTL0 &= ~CCIFG;
    }
    
    void Configure_I2C_Master(void)//for external ADC and temperature sensor
    {
    
        UCB1CTLW0 = UCSWRST;                                    // Enable SW reset
        UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
        UCB1BRW = 10;                                           // fSCL = SMCLK/50 = ~60kHz
        UCB1CTLW0 &= ~UCSWRST;                                  // Clear SW reset, resume operation
        UCB1IE |= UCNACKIE;
    
    }
    
    void Read_Ext_ADC(void)
    {
        strcpy(TX_UART,"READ LTC2991 Data - Start\r\n");
        uart_string_tx();
        EUSCI_B_I2C_setSlaveAddress (EUSCI_B1_BASE, LTC2991_ADDRESS);
        EUSCI_B_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
        EUSCI_B_I2C_enable(EUSCI_B1_BASE);
        EUSCI_B_I2C_clearInterrupt(EUSCI_B1_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT);
        EUSCI_B_I2C_enableInterrupt(EUSCI_B1_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT);
        //while (Rx_Finish_Flag == 0); //wait for end of read data from I2C.
        //Rx_Finish_Flag = 0;
        EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, 0x12);
        //while (EUSCI_B_I2C_isBusBusy(EUSCI_B1_BASE)) ;
        I2C_RXData_LTC2991 = EUSCI_B_I2C_slaveGetData(EUSCI_B1_BASE);
        sprintf(TX_UART, "%d", I2C_RXData_LTC2991);
        strcat(TX_UART, " - P1V5 Value\n");
        uart_string_tx();
    
    }
    
    I2C_Mode I2C_Master_ReadReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB1I2CSA = dev_addr;
        UCB1IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB1IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB1IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB1CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    
    }
    
    I2C_Mode I2C_Master_WriteReg_B1(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
    
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB1I2CSA = dev_addr;
        UCB1IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB1IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB1IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB1CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(GIE);                 // enable global interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    void LTC2991_config()
    {
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x01, CHANNEL_EN_LTC2991, 1);     // 0x48 is ADC address, 0x01 is channel enable register, 0xF8 enables all channels and VCC, sends 1 byte
        __delay_cycles(4000);
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x06, CONTROL_06_REG_LTC2991, 1);
        __delay_cycles(4000);
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x07, CONTROL_07_REG_LTC2991, 1);  //Enable Channel Filters
        __delay_cycles(4000);
        I2C_Master_WriteReg_B1(LTC2991_WR_ADDRESS, 0x08, CONTROL_08_REG_LTC2991, 1);  //Enable Channel Filters
        __no_operation();
    }
    
    void LTC2991_Read_All_Channels(uint8_t sensor_addr,uint8_t channel)
    {
        int i;
        uint8_t temp_reg_array[20] = {0};
        //uint16_t temp_reg_16bit[8] = {0};
        I2C_Master_ReadReg_B1(sensor_addr, channel, 20);
    
        __delay_cycles(3700+14000);                     // time delay for i2c transmission to end:
                                                        //
                                                        // time for writing command and receiving first channel data - (50/330kHz)*24MHz ~ 3700 cycles
                                                        // time for the rest of the channel data - for 7 channels each containing 20 bits: (140/330kHz)*24MHz ~ 11000 cycles
    
    
        CopyArray(ReceiveBuffer, temp_reg_array, 20);
        for(i=0; i<10; i++)
        {
            reg_map.Registers.Ext_ADC[i] = ((temp_reg_array[2*i] << 8) | temp_reg_array[2*i+1] );
        }
    }
    
    uint16_t TMP102_Read_Temp_Reg(uint8_t sensor_addr)
    {
        //uint8_t TMP102_ADDR = 0x00;
        uint8_t temp_reg_array[2] = {0};
        uint16_t temp_reg_16bit = 0;
        I2C_Master_ReadReg_B1(sensor_addr, TMP102_TMP_REG, 2);
    
        __delay_cycles(8000);
    
        CopyArray(ReceiveBuffer, temp_reg_array, 2);
        temp_reg_16bit = ((temp_reg_array[0] << 4) | (temp_reg_array[1] >> 4));
        return temp_reg_16bit;
    }
    
    void Delay_Func(uint8_t delayCNT)
    {
       while (delayCNT >0)
       {
           delayCNT--;
       }
    }
    
    void Init_I2C_Slave()
    {
        UCB0CTLW0 = UCSWRST;                      // Software reset enabled
        UCB0CTLW0 |= UCMODE_3 | UCSYNC;           // I2C mode, sync mode
        UCB0CTLW0 &= ~UCTR;                       // Receive mode
        UCB0I2COA0 = SLAVE_OWN_ADDR | UCOAEN;     // Own Address and enable
        UCB0CTLW0 &= ~UCSWRST;                    // clear reset register
        UCB0IE |= UCRXIE + UCTXIE + UCSTPIE;
    }
    
    void I2C_Slave_ProcessCMD(uint8_t cmd)      // Process the command
    {
        SlaveReceiveIndex = 0;
        SlaveTransmitIndex = 0;
        SlaveRXByteCtr = 0;
        SlaveTXByteCtr = 0;
    
        switch (cmd)
        {
            case (M_NO_CMD):                            //-- No command
                SlaveMode = RX_REG_ADDRESS_MODE;
                //UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
                //UCB0IE |= UCRXIE;                       // Enable RX interrupt
                break;
            case (M_MODE_SELECT):                       //-- Master selects the operation mode
                SlaveMode = RX_DATA_MODE;
                SlaveRXByteCtr = 1;
                //UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
                //UCB0IE |= UCRXIE;                       // Enable RX interrupt
                break;
            case (M_WRITE_REG):                         //-- Master writes directly to command registers
                SlaveMode = RX_DATA_MODE;
                SlaveRXByteCtr = 2;                          //-- first byte selects the register to write, second byte contains the data to write
                //UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
                //UCB0IE |= UCRXIE;                       // Enable RX interrupt
                break;
            case (M_READ_REG):                          //-- Master reads data from registers
                SlaveMode = RX_DATA_MODE;
                SlaveRXByteCtr = 1;
                break;
            default:
                __no_operation();
                break;
        }
    }
    
    
    void I2C_Slave_TransactionDone(uint8_t cmd)     // Execute the command
    {
        //strcpy(TX_UART,"Done Recieving Byte\r\n");
        //uart_string_tx();
        int i;
        switch (cmd)
        {
    
            case (M_NO_CMD):                            // No command
                for(i = 0; i<MAX_BUFFER_SIZE;i++)
                {
                    SlaveReceiveBuffer[i] = 0;
                }
            //strcpy(TX_UART,"No Command\r\n");
            //uart_string_tx();
            break;
    
            case (M_MODE_SELECT):                       // mode select is written to the MODE_SELECT
                work_mode_fsm = SlaveReceiveBuffer[0];
                for(i = 0; i<MAX_BUFFER_SIZE;i++)
                    {
                        SlaveReceiveBuffer[i] = 0;
                    }
                do_getmode();
                break;
                /*
            case (M_WRITE_REG):                         //Send slave device location (This device's location)
                switch(SlaveReceiveBuffer[0])
                {
                case 0:
                    reg_map.Registers.Command.reg.MSP_EMERG_EN = SlaveReceiveBuffer[1];
                    break;
                case 1:
                    reg_map.Registers.Command.reg.MSP_BOOST_EN = SlaveReceiveBuffer[1];
                    break;
                case 2:
                    reg_map.Registers.Command.reg.SMCC_ETH_PWDn = SlaveReceiveBuffer[1];
                    break;
                case 3:
                    reg_map.Registers.Command.reg.MAIN_BKUPn_EN = SlaveReceiveBuffer[1];
                    break;
                case 4:
                    reg_map.Registers.Command.reg.MSP_SMCC_HV_EN = SlaveReceiveBuffer[1];
                    break;
                default:
                    break;
    
                    for(i = 0; i<MAX_BUFFER_SIZE;i++)
                    {
                        SlaveReceiveBuffer[i] = 0;
                    }
                }
                break;
                */
    
            case (M_READ_REG):
                    for(i = 0; i<MAX_BUFFER_SIZE;i++)
                    {
                        SlaveTransmitBuffer[i] = 0;
                    }
                    switch(SlaveReceiveBuffer[0])
                    {
                    case 0:         // Read external ADC regs
                        SlaveTXByteCtr = 20;
                        SlaveTransmitBuffer[0] = reg_map.Registers.EXT_N5V2A;
                        SlaveTransmitBuffer[1] = reg_map.Registers.EXT_N5V2A >> 8;
                        SlaveTransmitBuffer[2] = reg_map.Registers.EXT_N4VA;
                        SlaveTransmitBuffer[3] = reg_map.Registers.EXT_N4VA >> 8;
                        SlaveTransmitBuffer[4] = reg_map.Registers.EXT_VCC_HIGH;
                        SlaveTransmitBuffer[5] = reg_map.Registers.EXT_VCC_HIGH >> 8;
                        SlaveTransmitBuffer[6] = reg_map.Registers.EXT_VCC_LOW;
                        SlaveTransmitBuffer[7] = reg_map.Registers.EXT_VCC_LOW >> 8;
                        SlaveTransmitBuffer[8] = reg_map.Registers.EXT_P1V5;
                        SlaveTransmitBuffer[9] = reg_map.Registers.EXT_P1V5 >> 8;
                        SlaveTransmitBuffer[10] = reg_map.Registers.EXT_P7V3;
                        SlaveTransmitBuffer[11] = reg_map.Registers.EXT_P7V3 >> 8;
                        SlaveTransmitBuffer[12] = reg_map.Registers.EXT_36VA;
                        SlaveTransmitBuffer[13] = reg_map.Registers.EXT_36VA >> 8;
                        SlaveTransmitBuffer[14] = reg_map.Registers.EXT_GND;
                        SlaveTransmitBuffer[15] = reg_map.Registers.EXT_GND >> 8;
                        SlaveTransmitBuffer[16] = reg_map.Registers.EXT_TMP;
                        SlaveTransmitBuffer[17] = reg_map.Registers.EXT_TMP >> 8;
                        SlaveTransmitBuffer[18] = reg_map.Registers.EXT_VCC;
                        SlaveTransmitBuffer[19] = reg_map.Registers.EXT_VCC >> 8;
                        break;
                    case 1:         // Read internal ADC regs
                        SlaveTXByteCtr = 18;
                        SlaveTransmitBuffer[0] = reg_map.Registers.ADC0;
                        SlaveTransmitBuffer[1] = reg_map.Registers.ADC0 >> 8;
                        SlaveTransmitBuffer[2] = reg_map.Registers.ADC1;
                        SlaveTransmitBuffer[3] = reg_map.Registers.ADC1 >> 8;
                        SlaveTransmitBuffer[4] = reg_map.Registers.ADC4;
                        SlaveTransmitBuffer[5] = reg_map.Registers.ADC4 >> 8;
                        SlaveTransmitBuffer[6] = reg_map.Registers.ADC5;
                        SlaveTransmitBuffer[7] = reg_map.Registers.ADC5 >> 8;
                        SlaveTransmitBuffer[8] = reg_map.Registers.INT_TEMP;
                        SlaveTransmitBuffer[9] = reg_map.Registers.INT_TEMP >> 8;
                        SlaveTransmitBuffer[10] = reg_map.Registers.TMP102_A;
                        SlaveTransmitBuffer[11] = reg_map.Registers.TMP102_A >> 8;
                        SlaveTransmitBuffer[12] = reg_map.Registers.TMP102_B;
                        SlaveTransmitBuffer[13] = reg_map.Registers.TMP102_B >> 8;
    					SlaveTransmitBuffer[14] = reg_map.Registers.ADC8;
    					SlaveTransmitBuffer[15] = reg_map.Registers.ADC8 >> 8;;
    					SlaveTransmitBuffer[16] = reg_map.Registers.ADC9;
    					SlaveTransmitBuffer[17] = reg_map.Registers.ADC9 >> 8;;
                        break;
    				/*
    				case 2:         // Read Status Regs -- TBD
                        SlaveTXByteCtr = 18;
                        SlaveTransmitBuffer[0] = reg_map.Registers.ADC0;
                        SlaveTransmitBuffer[1] = reg_map.Registers.ADC0 >> 8;
                        SlaveTransmitBuffer[2] = reg_map.Registers.ADC1;
                        SlaveTransmitBuffer[3] = reg_map.Registers.ADC1 >> 8;
                        SlaveTransmitBuffer[4] = reg_map.Registers.ADC4;
                        SlaveTransmitBuffer[5] = reg_map.Registers.ADC4 >> 8;
                        SlaveTransmitBuffer[6] = reg_map.Registers.ADC5;
                        SlaveTransmitBuffer[7] = reg_map.Registers.ADC5 >> 8;	
    					break;
    				*/	
    					
                    default:
                        break;
                    }
                break;
    //*/
            //default:
               // __no_operation();
              //  break;
        }
    }
    
    //******************************************************************************
    //
    //This is the USCI_A1 interrupt vector service routine. UART.
    //
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A1_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_A1_VECTOR)))
    #endif
    void EUSCI_A1_ISR(void)
    {
        switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))
        {
            case USCI_NONE: break;
            case USCI_UART_UCRXIFG:
                RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
                RX_buff[i++] = RXData;
                // Check value
                if (RXData == '\r' || RXData == '\n')
                {
                    EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 13);
                    EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 10);
                    RX_buff[--i] = '\0';
                    memcpy(cmd_in, RX_buff,sizeof(RX_buff));
                    split_cmd();
                    for (i = 0;i<sizeof(RX_buff); i++)
                        RX_buff[i] = 0;
                    i=0;
                    P3OUT ^= 0x10;
                }
                check =1;
                break;
           case USCI_UART_UCTXIFG: break;
           case USCI_UART_UCSTTIFG: break;
           case USCI_UART_UCTXCPTIFG: break;
        }
    }
    
    
    
    
    void Configure_ADC(void)
    {
    
        ADC_init(ADC_BASE, ADC_SAMPLEHOLDSOURCE_SC, ADC_CLOCKSOURCE_ACLK,ADC_CLOCKDIVIDER_1);
        ADC_setResolution(ADC_BASE, ADC_RESOLUTION_12BIT);
        ADC_enable(ADC_BASE);
        //ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_16_CYCLES,ADC_MULTIPLESAMPLESENABLE);
        ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_16_CYCLES,ADC_MULTIPLESAMPLESENABLE);
        //ADC_configureMemory(ADC_BASE, ADC_INPUT_TEMPSENSOR, ADC_VREFPOS_AVCC,ADC_VREFNEG_AVSS);
        ADC_configureMemory(ADC_BASE, ADC_INPUT_TEMPSENSOR, ADC_VREFPOS_INT,ADC_VREFNEG_AVSS);
        //ADC_configureMemory(ADC_BASE, ADC_INPUT_A9, ADC_VREFPOS_AVCC,ADC_VREFNEG_AVSS);
    
        ADC_clearInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
        ADC_enableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
        PMM_enableInternalReference();
        //PMMCTL2 |= REFVSEL_2;
        PMMCTL0_H = PMMPW_H;
        PMMCTL2  |= TSENSOREN + REFVSEL_2;
    
        /*
        ADCCTL0 |= ADCSHT_8 | ADCON;                                  // ADC ON,sample period>30us
        ADCCTL1 |= ADCSHP;                                            // s/w trig, single ch/conv, MODOSC
        ADCCTL2 &= ~ADCRES;                                           // clear ADCRES in ADCCTL
        ADCCTL2 |= ADCRES_2;                                          // 12-bit conversion results
        ADCMCTL0 |= ADCSREF_1 | ADCINCH_12;                           // ADC input ch A12 => temp sense
        ADCIE |=ADCIE0;                                               // Enable the Interrupt request for a completed ADC_B conversion
    
        // Configure reference
        PMMCTL0_H = PMMPW_H;                                          // Unlock the PMM registers
        PMMCTL2 |= REFVSEL_2;
        PMMCTL2 |=  INTREFEN | TSENSOREN;                              // Enable internal reference and temperature sensor
    
        __delay_cycles(400);                                          // Delay for reference settling
        */
    }
    
    
    
    
    
    
    
    //******************************************************************************
    //
    //This is the Timer B0 interrupt vector service routine.
    //
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=TIMERB0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(TIMERB0_VECTOR)))
    #endif
    void TIMERB0_ISR (void)
    {
        uint16_t temp_reg;
        //if (timer_flag == 0)
        //{
        adc_timer++;
        timer_tick = 1;
        //}
        GPIO_toggleOutputOnPin(MSP_LED_PORT, MSP_LED_PIN);
        //update PGOOD inputs:
        /*
        reg_map.Registers.Status.N4VA_PG = GPIO_getInputPinValue(N4VA_PG_PORT, N4VA_PG_PIN);
        reg_map.Registers.Status.P12VD_PG = GPIO_getInputPinValue(P12VD_PG_PORT, P12VD_PG_PIN);
        reg_map.Registers.Status.P12VA_PG = GPIO_getInputPinValue(P12VA_PG_PORT, P12VA_PG_PIN);
        reg_map.Registers.Status.P1V5A_PG = GPIO_getInputPinValue(P1V5A_PG_PORT, P1V5A_PG_PIN);
        reg_map.Registers.Status.P3V7A_PG = GPIO_getInputPinValue(P3V7A_PG_PORT, P3V7A_PG_PIN);
        reg_map.Registers.Status.N5V2A_PG = GPIO_getInputPinValue(N5V2A_PG_PORT, N5V2A_PG_PIN);
        reg_map.Registers.Status.P5V4A_PG = GPIO_getInputPinValue(P5V4A_PG_PORT, P5V4A_PG_PIN);
         */
    
        if (adc_timer == 500)
        {
            if (I2C_Slave_counter == 4)
            {
                I2C_Slave_counter = 0;
            }
            else
            {
                I2C_Slave_counter += 1;
            }
                //timer_flag = 1;
    
                //Read_Ext_ADC();
            switch (I2C_Slave_counter)
            {
                case 0:
                {
                    //if (UCB1STATW != UCBBUSY)
                    //{
                        reg_map.Registers.TMP102_A = TMP102_Read_Temp_Reg(TMPa_ADDRESS) * TMP102_SF_TMP * 1000;
                    //}
                }
                break;
                case 1:
                {
                    //if (UCB1STATW != UCBBUSY)
                    //{
                        reg_map.Registers.TMP102_B = TMP102_Read_Temp_Reg(TMPb_ADDRESS) * TMP102_SF_TMP * 1000;
                    //}
                }
                case 2:
                {
                   if (UCB1STATW != UCBBUSY)
                   {
                       LTC2991_Read_All_Channels(LTC2991_WR_ADDRESS,0x0A);        // read all adc channels starting from V1 (0x0A)
    
                       if (reg_map.Registers.Ext_ADC[0] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[0] & LTC2991_SIGN)
                           {reg_map.Registers.EXT_N5V2A    = 0;}
                           else
                           {reg_map.Registers.EXT_N5V2A    = (reg_map.Registers.Ext_ADC[0] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_N5V2A;}
                       }
                       else
                       {reg_map.Registers.EXT_N5V2A    = 0;}
                       if (reg_map.Registers.Ext_ADC[1] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[1] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_N4VA     = 0;}
                           else
                           {reg_map.Registers.EXT_N4VA = (reg_map.Registers.Ext_ADC[1] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_N4VA;}
                       }
                       else
                       {reg_map.Registers.EXT_N4VA = 0;}
                       if (reg_map.Registers.Ext_ADC[2] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[2] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_VCC_HIGH = 0;}
                           else
                           {reg_map.Registers.EXT_VCC_HIGH = (reg_map.Registers.Ext_ADC[2] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_VCC_HIGH;}
                       }
                       else
                       {reg_map.Registers.EXT_VCC_HIGH = 0;}
                       if (reg_map.Registers.Ext_ADC[3] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[3] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_VCC_LOW  = 0;}
                           else
                           {reg_map.Registers.EXT_VCC_LOW = (reg_map.Registers.Ext_ADC[3] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_VCC_LOW;}
                       }
                       else
                       {reg_map.Registers.EXT_VCC_LOW = 0;}
                       if (reg_map.Registers.Ext_ADC[4] & LTC2991_DV) {
                           if (reg_map.Registers.Ext_ADC[4] & LTC2991_SIGN)
                            {reg_map.Registers.EXT_P1V5     = 0;}
                           else
                           {reg_map.Registers.EXT_P1V5 = (reg_map.Registers.Ext_ADC[4] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE;}
                       }
                       else{reg_map.Registers.EXT_P1V5 = 0;}
                       if (reg_map.Registers.Ext_ADC[5] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[5] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_P7V3     = 0;}
                           else
                           {reg_map.Registers.EXT_P7V3 = (reg_map.Registers.Ext_ADC[5] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_P7V3;}
                       }
                       else
                       {reg_map.Registers.EXT_P7V3 = 0;}
                       if (reg_map.Registers.Ext_ADC[6] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[6] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_36VA     = 0;}
                           else
                           {reg_map.Registers.EXT_36VA = (reg_map.Registers.Ext_ADC[6] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_36VA;}
                       }
                       else
                       {reg_map.Registers.EXT_36VA = 0;}
                       if (reg_map.Registers.Ext_ADC[7] & LTC2991_DV){
                           if (reg_map.Registers.Ext_ADC[7] & LTC2991_SIGN)
                               {reg_map.Registers.EXT_GND      = 0;}
                           else
                           {
                               reg_map.Registers.EXT_GND = (reg_map.Registers.Ext_ADC[7] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE;
                           }
                       }
                       else
                       {
                           reg_map.Registers.EXT_GND = 0;
                       }
                   }
                   //reg_map.Registers.EXT_TMP      = (reg_map.Registers.Ext_ADC[8] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE * SF_TMP;
                   reg_map.Registers.EXT_TMP      = (reg_map.Registers.Ext_ADC[8] & LTC2991_DATA_MASK) *  LTC2991_SF_TMP * 1000;
                   reg_map.Registers.EXT_VCC      = ((reg_map.Registers.Ext_ADC[9] & LTC2991_DATA_MASK) * LTC2991_DATA_SCALE) + 2500;
               }
                break;
                case 3:
                {
                    ADC_startConversion(ADC_BASE,ADC_SEQOFCHANNELS);
    
                }
                break;
    
            }
    
            //Delay_Func(1000);
    
            adc_timer = 0;
                //timer_flag = 0;
        }
    
        TB0CTL &= ~TBIFG;
    }
    //******************************************************************************
    //ADC10 interrupt service routine
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(ADC_VECTOR)))
    #endif
    void ADC_ISR (void){
        //uint16_t adc_data;
        switch (__even_in_range(ADCIV,12)){
            case  0: break; //No interrupt
            case  2: break; //conversion result overflow
            case  4: break; //conversion time overflow
            case  6: break; //ADCHI
            case  8: break; //ADCLO
            case 10: break; //ADCIN
            case 12:        //ADCIFG0
    
                //reg_map.Registers.TMP102_A = TMP102_Read_Temp_Reg(0);
                //Automatically clears ADCIFG0 by reading memory buffer
                adc_data[adc_index] = ADC_getResults(ADC_BASE);
                //adc_data = ADCMEM0;
                //reg_map.value[sizeof(reg_map.value) - adc_index] = adc_data;
                //reg_map.value[sizeof(reg_map.value) - adc_index - 1] = adc_data >> 8;
                //reg_map[128 - adc_index] = ADCMEM0;
                if(adc_index == 0){
                    //reg_map.Registers.TMP102_A = TMP102_Read_Temp_Reg(0);
                    //reg_map.Registers.TMP102_B = TMP102_Read_Temp_Reg(1);
                    adc_index = 12;
                    reg_map.Registers.ADC0 = adc_data[0] * 48.5 * 0.61;
                    reg_map.Registers.ADC1 = adc_data[1] * 48.5 * 0.61;
                    reg_map.Registers.ADC4 = adc_data[4] * 48.5 * 0.61;
                    reg_map.Registers.ADC5 = adc_data[5] * 48.5 * 0.61;
                    reg_map.Registers.ADC8 = adc_data[8] * 5.75 * 0.61;
                    reg_map.Registers.ADC9 = adc_data[9] * 5.75 * 0.61;
                    reg_map.Registers.INT_TEMP = adc_data[12];
                    ADC_disableConversions(ADC_BASE, ADC_COMPLETECONVERSION);
                }
                else    adc_index--;
                __bic_SR_register_on_exit(CPUOFF);
                break;
            default: break;
        }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB0RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
    
                rx_val = UCB0RXBUF;
                switch (SlaveMode)
                {
                case (RX_REG_ADDRESS_MODE):
                    ReceiveRegAddr = rx_val;
                    I2C_Slave_ProcessCMD(ReceiveRegAddr);
                    break;
                case (RX_DATA_MODE):
                      SlaveReceiveBuffer [SlaveReceiveIndex++] = rx_val;
                      SlaveRXByteCtr--;
                      if (SlaveRXByteCtr == 0)
                      {
                          //Done Receiving MSG
                          SlaveMode = RX_REG_ADDRESS_MODE;
                          UCB0CTLW0 &= ~UCTR;
                          //UCB0IE &= ~(UCTXIE);
                          //UCB0IE |= UCRXIE;                          // Enable RX interrupt
                          I2C_Slave_TransactionDone(ReceiveRegAddr);
                      }
                      break;
                  default:
                      __no_operation();
                      break;
                }
    
    
            break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    
                UCB0TXBUF = SlaveTransmitBuffer[SlaveTransmitIndex++];
                SlaveTXByteCtr--;
                if (SlaveTXByteCtr == 0)
                {
                    //Done Transmitting MSG
                    UCB0CTLW0 &= ~UCTR;
                    //UCB0IE &= ~(UCTXIE);
                    //UCB0IE |= UCRXIE;                          // Enable RX interrupt
                }
    
            break;
        default: break;
      }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB1RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
    
                rx_val = UCB1RXBUF;
                if (RXByteCtr)
                {
                    ReceiveBuffer[ReceiveIndex++] = rx_val;
                    RXByteCtr--;
                }
    
                if (RXByteCtr == 1)
                {
                    UCB1CTLW0 |= UCTXSTP;
                }
                else if (RXByteCtr == 0)
                {
                    UCB1IE &= ~UCRXIE;
                    MasterMode = IDLE_MODE;
                }
    
            break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    
                switch (MasterMode)
                {
                case TX_REG_ADDRESS_MODE:
                    UCB1TXBUF = TransmitRegAddr;
                    if (RXByteCtr)
                        MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                    else
                        MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                    break;
    
                case SWITCH_TO_RX_MODE:
                    UCB1IE |= UCRXIE;              // Enable RX interrupt
                    UCB1IE &= ~UCTXIE;             // Disable TX interrupt
                    UCB1CTLW0 &= ~UCTR;            // Switch to receiver
                    MasterMode = RX_DATA_MODE;    // State state is to receive data
                    UCB1CTLW0 |= UCTXSTT;          // Send repeated start
                    if (RXByteCtr == 1)
                    {
                        //Must send stop since this is the N-1 byte
                        while((UCB1CTLW0 & UCTXSTT));
                        UCB1CTLW0 |= UCTXSTP;      // Send stop condition
                    }
                    break;
    
                case TX_DATA_MODE:
                    if (TXByteCtr)
                    {
                        UCB1TXBUF = TransmitBuffer[TransmitIndex++];
                        TXByteCtr--;
                    }
                    else
                    {
                        //Done with transmission
                        UCB1CTLW0 |= UCTXSTP;     // Send stop condition
                        MasterMode = IDLE_MODE;
                        UCB1IE &= ~UCTXIE;                       // disable TX interrupt
                    }
                    break;
    
                default:
                    __no_operation();
                    break;
                }
    
            break;
        default: break;
      }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、David、  

    非常感谢您的帮助意愿。

    我运行了进一步的测试,并注意到该问题在某些情况下重现。

    附加了主文件的工作版本和非工作版本。

    1.我不明白两者之间的区别。 它几乎是相同的、我找不到不能作为工作版本工作的原因。

    2.我注意到、在我注释以下任何内容时、代码正常工作

    a.如前所述:注释 _bis_SR_register (GIE);(备注:__bis_SR_register (GIE); 也在前面几行的 LTC2991_config()内执行。)

    b: 当我注释版本寄存器更新 reg_map.Registers.version.main_ver = 0x0;、 reg_map.Registers.version.minir_ver = 0x8;(我不知道原因)

    c.当我注释  LTC2991_config()时。

    d.当我评论 GPIO_setOutputHighOnPin (((N5V2A_EN_PIN、 N4VA_EN_PIN)-在 FSM 的 LV_st_4_pu_seq:上)或    FSM 的 LV_st_5_pu_seq 上 P5V4A_EN_PIN 的 GPIO_setOutputHighOnPin 时。

    如果您能帮助我理解、我将不胜感激。  

    非常感谢您的帮助、

    Yaniv。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Yaniv、您好!

    我对这个问题的症状有点不清楚-启用中断后、您会看到什么情况?

    是否在中断启用后添加了__no_operation()? (这是推荐的最佳做法)。  

    为了进行故障排除、您是否曾尝试在程序中放置一个"陷阱"ISR (基本上是一个针对系统中所有未使用的中断而设置的虚拟中断服务例程、并且只要"while (1)"能够捕捉/停止执行(如果它进入)? 如果执行此操作、您可以捕获代码何时进入此陷阱 ISR、然后返回并转储寄存器设置、变量状态等、以确定某项操作是否进入意外状态。  

    此致、

    Katie

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    编译器在插入 NOP 时非常一致、以解决已知的勘误表问题。 检查生成的汇编代码将显示是否存在问题。 我知道 GCC 会插入这些内容、GNU 汇编器会抱怨这些内容是否缺失。

    根据编译器的不同、可能已经为所有未使用的中断准备了一个虚拟 ISR。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Yaniv、您好!

    以下是我对您的问题的一些看法:

    答:启用中断需要"_bis_SR_register (GIE)"、因此您应该在初始化时对其进行注释。

    (注:PM5CTL0 &=~LOCKLPM5通常在 GPIO 设置之后、在其他外设设置之前、因为它将锁定 I/O 引脚)

    B.您可能会调用版本来进行一些处理。 我不熟悉这个。

    C&D 我不知道原因、也许您可以使用 不同的注释进行调试、并找到使电压 EN 下降到0V 的原因。  

    (确认模拟系统中的 GPIO_OutputHighOnPin 功能,检查 I2C 传输位,以及是否进入单独的中断或您认为有必要的其他中断 )

    此致、

    SAL

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [~引脚 userid="522705" URL"μ C/support/microcontrollers/msp-low-power-microcontrollers-group/msp44686/msp430fr2355-msp-inconsistor-when -I-enable-global-interrupts/4108879#4108879"]1. 我不理解它们之间的差异。 它几乎是相同的、我找不到它不能作为工作版本工作的原因。

     Configure_Clocks()具有以下内容,注释为将 DCO 时钟频率选择为24MHz:

        CS_initFLLParam param = {0};                                            //  Create struct variable to store proper software trim values
        CS_initFLLCalculateTrim(24000,731,&param);                              //  Set Ratio/Desired MCLK Frequency, initialize DCO, save trim values
        CS_initFLLSettle(24000,731);                                            //  For demonstration purpose, change DCO clock freq to 24MHz
        CS_initFLLLoadTrim(24000,731,&param);                                   //  Reload DCO trim values that were calculated earlier

    但是、我在代码中看不到 NWAITSx = 2的任何内容、这是允许24MHz CPU 时钟频率所需的 FRAM 等待状态数:

    因此、问题可能是 由 FRAM 等待状态数量不足引起的间歇性操作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="91588" URL"~μ C/support/microcontrollers/msp-low-power-microcontrollers-group/msp430-low-power-microcontroller-forum/1104666/msp430fr2355-MSP-inconsisturity-when -I-enable-global-interrupts/4123529#4123529"]但是、我无法 在引用的 FWAx 代码中看到 CPU 频率为2 MHz 时钟数[引用以下哪一个时钟频率]。

    在   设置 FLL 之前,尝试在 Configure_Clocks()函数中向 FRAMCtl_configureWaitStateControl()添加调用:

        FRAMCtl_configureWaitStateControl (FRAMCTL_ACCESS_TIME_CYCLES_2);       //  Two wait states required for a CPU frequency of 24 MHz
        CS_initFLLParam param = {0};                                            //  Create struct variable to store proper software trim values
        CS_initFLLCalculateTrim(24000,731,&param);                              //  Set Ratio/Desired MCLK Frequency, initialize DCO, save trim values
        CS_initFLLSettle(24000,731);                                            //  For demonstration purpose, change DCO clock freq to 24MHz
        CS_initFLLLoadTrim(24000,731,&param);                                   //  Reload DCO trim values that were calculated earlier

    查看 driverlib 代码、我在 CS 时钟系统函数中看不到任何自动设置 FRAM 等待状态数的东西、因此必须从应用代码中完成。