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 inconsistent behavior when I enable global interrupts

Part Number: MSP430FR2355

Hi all, 

I'm using the MSP430FR2355 to manage the power up / down sequence of several DCDCs converters + I2C communication.

The state machine advances to the following stage based on PG signals as it sends the following EN / Run signal for the following DCDC converter.

The 3.3V Input voltage of the MSP is provided independently on startup.

Probelm: in approximately 1 of 3 times i start the system, the main voltage EN is dropping to 0V and system is not up.

Things i've done:

1. I ruled out that the problem is in the peripheral DCDC circuits by starting them up manually. 

2. Verified the DCDC input voltage is stable when the problem occurs.

3. Starting from scratch - I enabled the DCDCs gradually with time delay. It worked fine.  I then gradually added contents and noticed that the issue is reproduced when I enable the global interrupts by adding the following line: __bis_SR_register(GIE);

When I add this line to the code the problem happens. (1 of 3 times approximately). It happens even if there are no interrupts in the code.

When I remove this line the issue does not occur.

I'd be happy to hear your thoughts. Your help is much appreciated.

Thanks, 

Yaniv.

  • Hi 

    You can refer to the power sequence example. There is example code in it.

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

  • Hi Allen, Thanks for your quick response.

    This is the way our sequencing is working in general. (Based on time interrupts).
    However, as mentioned, the issue is reproduced even when i use a simple code and enable the interrupts (__bis_SR_register(GIE)) , even if there are no interrupts in the code.

    When "__bis_SR_register(GIE); " is removed the issue is not reproduced.

  • Hi,

    Can you post your code and schematic? I can help to review of it.

  • Hi all, 

    In the beginning main looked like this:

    void main(void)

    {

    WDT_A_hold(WDT_A_BASE);

    Configure_GPIOs();

    Configure_I2C_Master();

    Init_I2C_Slave();

    Configure_ADC();

    Configure_TimerOP;

    Configure_UART_A1();

    PM5TL0 &=LOCKLPM5;

    ......

    }

    I moved "PM5TL0 &=LOCKLPM5;" to the line beneath "WDT_A_hold(WDT_A_BASE);" , and issue does not happen anymore.

    Later I saw in other MSP designs that the function "PMM_unlockPM5()" was used few lines after the GPIO configuration and there is no problem in these designs.

    1. Can you please help me understand:

    A. Why did moving PM5TL0 &=LOCKLPM5; had the issue resolved?

    B. What's the difference between this solution and "PMM_unlickPM5();"? 

    C. Where should I place this line PM5TL0 &=LOCKLPM5 /  PMM_unlickPM5()?

     

    Your help is much appreciated,

    Yaniv.

  • You say there are no interrupts in the code but it is not clear exactly what you mean by that. You might mean that you don't think any interrupts are triggered. It can't mean that you have no interrupt service routines and enabled peripheral interrupts. Else, why set GIE? It is possible that initializing peripherals results in immediate interrupts. The UART TXIFG is set on reset (TXBUF being empty) so could cause trouble if you forget that before setting TXIE.

    The documentation is pretty clear about having to clear LOCKLPM5 before clearing the port interrupt flags. If you enabled port interrupts you could have pending interrupts just from setting the edge registers. Which you can't clear if LOCKLPM5 is set. So they cause interrupts that you weren't expecting when you set 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;
      }
    }
    

  • Hi David and everyone, 

    I really appreciate your will to help.

    I ran further tests and noticed the issue is reproduced in certain scenarios .

    Attached a working versions and a non working versions of main files.

    1. I don't understand the difference between them. It's almost identical and i couldnt find a reason why it shouldnt work as the working versions.

    2. I've noticed that the code is working when i comment any of the following

    A. AS mentioned before: commenting the __bis_SR_register(GIE); (Remark: __bis_SR_register(GIE); is also executed within LTC2991_config() few lines before. )

    B.  When i comment the version register update reg_map.Registers.version.Major_Ver = 0x0; , reg_map.Registers.version.Minor_Ver = 0x8; (I have no clue why)

    C. When i comment LTC2991_config().

    D. When i comment the GPIO_setOutputHighOnPin of Either ((N5V2A_EN_PIN, N4VA_EN_PIN) - on stage lv_st_4_pu_seq: of the FSM) OR GPIO_setOutputHighOnPin  of P5V4A_EN_PIN on stage lv_st_5_pu_seq of the FSM.

    I'd really appreciate if you could help me understand. 

    Your help is much appreciated,

    Yaniv.

  • Hi Yaniv,

    I was a little unclear on the symptom on this one - what are you seeing happen after you enable the interrupts?

    Do you add a __no_operation(); after the interrupt enable? (this is recommended best practice). 

    For troubleshooting, have you tried placing a "trap" ISR in the program (basically a dummy interrupt service routine that is set for all unused interrupts in the system, and just does a "while(1)" to capture/stop the execution if it ever enters)? If you do this, you can catch when code gets into this trap ISR, and then go back and dump register settings, states of variables, etc to determine if something got to an unexpected state. 

    Regards,

    Katie

  • Compilers are pretty consistent about inserting NOPs to work around known errata. An examination of the assembly code produced would show if it is a problem. I know that GCC inserts these and the GNU assembler complains if they are missing.

    Depending on the compiler, a dummy ISR may already be in place for all unused interrupts.

  • Hi Yaniv,

    Here are some of my thoughts on your issues:

    A. "__bis_SR_register(GIE)" is needed for enabling interrupt, so you should comment it in initial.

    (Note: PM5CTL0 &= ~LOCKLPM5 is normally after GPIO setting, and before other peripherals setting, because it will lock I/O pins)

    B. Maybe you called version to do some processing. I'm not familiar with it.

    C&D. I have no clue for the reason, maybe you could debug with the different comment and find what makes the voltage EN is dropping to 0V. 

    (Confirm GPIO_OutputHighOnPin function in your analog system, check the I2C transmission bits and whether entering your individual interrupt, or others you think is necessary )

    Best Regards,

    Sal

  • 1. I don't understand the difference between them. It's almost identical and i couldnt find a reason why it shouldnt work as the working versions.

    The Configure_Clocks() has the following, which is commented as selecting the DCO clock frequency as 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

    However, I can't see anything in the code which NWAITSx = 2 which is the required number of FRAM wait states to allow the CPU clock frequency of 24MHz:

    Therefore, perhaps the problem is intermittent operation caused by an insufficient number of FRAM wait states.

  • However, I can't see anything in the code which NWAITSx = 2 which is the required number of FRAM wait states to allow the CPU clock frequency of 24MHz:

    Try adding a call to FRAMCtl_configureWaitStateControl() in the  Configure_Clocks() function prior to setting the FLL:

        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

    Looking at the driverlib code, I can't see anything in the CS Clock System functions which automatically set the number of FRAM wait states, so must be done from the application code.

**Attention** This is a public forum