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.

TIDA-010042: TIDA-010042 Not charging battery

Part Number: TIDA-010042
Other Parts Discussed in Thread: TIDA-00120

Hi,

I replaced the 4 buck converter mosfets with T0-220 package, uploaded code using spy-bi-wire, shorted pins 1 and 2 on header J3 to provide 3.3V to MSP430 but my battery is not charging. I am using a 4W solar panel to test that has a Isc current of 220mA, is this too small? I noticed the battery provides power to the TIDA-010042 by supplying 14mA of current. I am seeing gate signals on the mosfets but the buck converter is not adjusting the solar panel voltage to its maximum power point, it remains at 21V. I know the MPP for my panel is 17V

Also, I see in main.c the min battery current can be changed, how does 3 in the code correspond to 0.5A minimum charging current? I need to set the minimum battery charging current to 20mA for testing.

Thanks,

  • Hi Amar,

    As the current sensing on this design is tuned for higher currents, it may be difficult for the circuit to arrive at MPP with low currents. The effect of change in current may be way too low to sense with the low power panel you are using. For lower currents, the hardware itself has to be modified (esp. the current sense).

    Regards,

    Salil

  • I have changed the buck lower threshold from 400 to 520 in the code and my panel is able to send power to my battery. Can someone please explain what these threshold values (BUCK_LOWER_THRESHOLD AND BUCK_UPPER_THRESHOLD) map too and represent? Also, how they were calculated to obtain a certain duty cycle range the buck converter would operate in?

  • Hi Amar,

    The PWM timer is configured to run in UP count and is configured with a value of 700. (based on 128Mhz clk / 182 Khz switching frequency). Based on this number the duty cycle's lower and upper limits are configured in the software. You can change the lower threshold, but ultimately depending on MPP the duty cycle will change and converge to a optimum value based on where it is initialized (which is done by DUTY_START variable). You can observe the change by placing the variable in a watch window. Please let us know if you have any further questions.

    Thank you

  • Ok many thanks. I am able to access files GUI.c and Config.c through the TIDA-00120 software. Where does the RespndtoGUI(); function call go in main.c?

    Regards

  • /* ****************************************************************************************************** *
     * main.c                                                                                                 *
     *                                                                                                        *
     *  Created on: Jun 25, 2018                                                                              *
     *      Author: a0233200                                                                                  *
     *                                                                                                        *
     * Copyright (c) 2018, Texas Instruments Incorporated                                                     *
     * All rights reserved.                                                                                   *
     *                                                                                                        *
     * Redistribution and use in source and binary forms, with or without                                     *
     * modification, are permitted provided that the following conditions                                     *
     * are met:                                                                                               *
     *                                                                                                        *
     * *  Redistributions of source code must retain the above copyright                                      *
     *    notice, this list of conditions and the following disclaimer.                                       *
     *                                                                                                        *
     * *  Redistributions in binary form must reproduce the above copyright                                   *
     *    notice, this list of conditions and the following disclaimer in the                                 *
     *    documentation and/or other materials provided with the distribution.                                *
     *                                                                                                        *
     * *  Neither the name of Texas Instruments Incorporated nor the names of                                 *
     *    its contributors may be used to endorse or promote products derived                                 *
     *    from this software without specific prior written permission.                                       *
     *                                                                                                        *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"                            *
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,                                  *
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR                                 *
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR                                       *
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,                                  *
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,                                    *
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;                            *
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,                               *
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR                                *
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,                                         *
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                     *
     *                                                                                                        *
     * -------------------------- PIN MAP --------------------------                                          *
     *                      __________________________                                                        *
     *                     |                          |                                                       *
     *               AVCC -| 1               (P3.6) 38|-                                                      *
     *   Battery Status 2 -| 2 (PJ.4)        (P3.5) 37|- Buzzer                                               *
     *   Battery Status 3 -| 3 (PJ.5)               36|- RESET                                                *
     *               AVSS -| 4                      35|- TEST                                                 *
     *      Panel_V_Sense -| 5 (P1.0)        (P3.3) 34|- Panel_Enable                                         *
     *    Battery_V_Sense -| 6 (P1.1)        (P3.2) 33|- Load_Enable                                          *
     *      Panel_I_Sense -| 7 (P1.2)        (PJ.6) 32|-                                                      *
     *    Battery_I_Sense -| 8 (P1.3)               31|- DVCC                                                 *
     *      OPT3001 (SDA) -| 9 (P1.4)               30|- DVSS                                                 *
     *      OPT3001 (SCL) -|10 (P1.5) MSP430        29|-                                                      *
     *       Load_I_Sense -|11 (PJ.0)  F5132 (P3.1) 28|-                                                      *
     *                    -|12 (PJ.1)        (P3.0) 27|-                                                      *
     *                    -|13 (PJ.2)        (P2.7) 26|- LED 4                                                *
     *   Battery Status 1 -|14 (PJ.3)        (P2.6) 25|- LED 3                                                *
     *      OPT3001 (INT) -|15 (P1.6)        (P2.5) 24|- LED 2/RX                                             *
     *  Buck (Low-Side 1) -|16 (P1.7)        (P2.4) 23|- LED 1/TX                                             *
     * Buck (High-Side 1) -|17 (P2.0)               22|- DVSS                                                 *
     * Temperature Sensor -|18 (P2.1)               21|-                                                      *
     *  Buck (Low-Side 2) -|19 (P2.2)        (P2.3) 20|- Buck (High-Side 2)                                   *
     *                     |__________________________|                                                       *
     *                                                                                                        *
     * ****************************************************************************************************** */
    //-----------------------------------------------------------------------------------------//
    //-------------------------------------- Notes/Revisions ----------------------------------//
    //-----------------------------------------------------------------------------------------//
    // 1. Diode Emulation mode added to prevent boosting of panel side voltage as a protection feature
    // 2. TimerA interrupt added. Refer the sections on TimerA_ISR
    // 3. Include only main.c in build and exclude other files
    
    
    
    //-----------------------------------------------------------------------------------------//
    //-------------------------------------- Definitions --------------------------------------//
    //-----------------------------------------------------------------------------------------//
    
    //-------------------------------User Settings---------------------------------------------//
    //#define USE_FLOAT   // Uncomment to use floating-point calculations
    
    #include <main.h>
    #include <GUI.h>
    #define GUI
    // MAKE SURE ONLY ONE OF THE FOLLOWING IS UNCOMMENTED
    #define SYS12       // Uncomment if using 12-V battery system
    //#define SYS24       // Uncomment if using 24-V battery system
    //#define SYS48       // Uncomment if using 48-V battery system
    //-----------------------------------------------------------------------------------------//
    
    #define BUCK_DISABLE    TD0CCTL1 = TD0CCTL2 = OUTMOD_0;\
                            TD1CCTL1 = TD1CCTL2 = OUTMOD_0;     // Turn PWM outputs off
    #define BUCK_ENABLE     TD0CCTL1 = TD1CCTL1 = OUTMOD_2;\
                            TD0CCTL2 = TD1CCTL2 = OUTMOD_6;     // TDx.1 OUTPUT MODE = TOGGLE/RESET, TDx.2 OUTPUT MODE = TOGGLE/SET in Buck mode
    
    #define CUTOFF_COUNTER_THRESHOLD        10  // 0.05 second delay
    #define RECONNECT_COUNTER_THRESHOLD     10  // 0.05 second delay
    #define OC_TRIGGERED_COUNTER_THRESHOLD  100 // 0.5 second delay
    
    #define DEADBAND    80 // Difference between the two PWM phases in order to implement a deadband so that no H/L-side pair are turned on at the same time
    
    #define BUCK_LOWER_THRESHOLD    540
    #define BUCK_UPPER_THRESHOLD    940
    
    #define P_V     3       // Setting indices for ADC_Readings vector
    #define B_V     2
    #define P_I     1
    #define B_I     0
    
    #define REF_AVG_MPPT_COUNTER    8 // MPPT control done with 8 sample average
    #define REF_INST_PROT_COUNTER 2 //Protection running with 2 sample average
    
    #ifdef USE_FLOAT
    #define PANEL_UPPER_LIMIT       60.0    // Maximum panel voltage of 60V
    #define MIN_BATTERY_CURRENT     0.0     // Minimum battery current of 0.5A (change as needed for battery)
    #else
    #define PANEL_UPPER_LIMIT       830     // Maximum panel voltage of 60V
    #define MIN_BATTERY_CURRENT     3       // Minimum battery current of 0.5A (change as needed for battery)
    #endif
    
    #define PANEL_ENABLE    P3OUT |= BIT3   // Set to enable panel *** P3.3
    #define PANEL_DISABLE   P3OUT &= ~BIT3  // Reset to disable panel
    #define LOAD_ENABLE     P3OUT |= BIT2   // Set to enable load *** P3.2
    #define LOAD_DISABLE    P3OUT &= ~BIT2  // Reset to disable load
    
    #define LOOP_EXIT_LIMIT     10         // 1 second delay
    
    #define DUTY_START          740
    
    #define SLAVE_ADDR          0x44        // set Slave Address for Ambient Light Sensor to 44h (ADDR pin is connected to GND)
    //#define SLAVE_ADDR          0x45        // set Slave Address for Ambient Light Sensor to 45h (ADDR pin is connected to VDD)
    //#define SLAVE_ADDR          0x46        // set Slave Address for Ambient Light Sensor to 46h (ADDR pin is connected to SDA)
    //#define SLAVE_ADDR          0x47        // set Slave Address for Ambient Light Sensor to 47h (ADDR pin is connected to SCL)
    
    //-----------------------------------------------------------------------------------------//
    //--------------------------------- Variable Declarations ---------------------------------//
    //-----------------------------------------------------------------------------------------//
    
    
    // Variables for flags
    
    unsigned int OC_Triggered = 0;
    
    unsigned int GUI_Battery_Charge_Previous_State;
    
    uint16_t    System_reset_mode_ON, Load_monitor_mode_ON,     // Flags for load current comparator ISR
    //            OC_Triggered = 0,
                OC_Triggered_Counter = 0,     // Flags for load overcurrent protection
                CV_Mode = 0,
                Read_Done,
                Wait_State = 0,
                Start_Delay = 0,
                Is_Load_On = 0,
                MPPT_Loop = 1,
                Phase_Shifting_Done = 0,
                Hysteresis_ON = 0;
    
    // Variables for counters
    uint16_t    Wait_Counter = 0,
                Battery_Current_Counter = 0,
                Cutoff_Counter = 0,
                Reconnect_Counter = 0,
                MPP_Loop_Exit_Counter = 0,
                CC_Loop_Exit_Counter = 0,
                maxFlips =0, // Keep track for semi Global Search
                protection_count =0; // Counter to add reliability for protection trip
    
    uint32_t    Panel_Voltage_inst = 0,
                Battery_Voltage_inst = 0,
                Panel_Current_inst = 0,
                Battery_Current_inst = 0;
    
    // Variables for ADC
    uint16_t    ADC_Readings[4],
                Avg_MPPT_Counter = 0,
                inst_prot_Counter=0;
    
    //This buffer stores MPPT control variables
    uint32_t    Panel_Voltage_Buffer = 0,
                Battery_Voltage_Buffer = 0,
                Panel_Current_Buffer = 0,
                Battery_Current_Buffer = 0;
    
    //This buffer stores protection releated variables
    uint32_t    Panel_Voltage_inst_Buffer = 0,
                Battery_Voltage_inst_Buffer = 0,
                Panel_Current_inst_Buffer = 0,
                Battery_Current_inst_Buffer = 0;
    
    unsigned int Mode_sel = 0; //selects between Diode Emulation mode & normal synchronous operation
    unsigned int boot_count = 0;
    unsigned int boot_flag = 0;
    
    // Variables for calculations
    #ifdef USE_FLOAT
    float       Panel_Voltage = 0.0,
                Battery_Voltage = 0.0,
                Panel_Current = 0.0,
                Battery_Current = 0.0,
                Prev_Battery_Current = 0.0,
                Panel_Power = 0.0,
                Prev_Panel_Power = 0.0;
    #else
    uint16_t    Panel_Voltage = 0,
                Battery_Voltage = 0,
                Panel_Current = 0,
                Battery_Current = 0,
                Prev_Battery_Current = 0,
                Panel_Power = 0,
                Prev_Panel_Power = 0;
    
    #endif
    
    // Variables for MPPT
    int16_t     MPPT_Direction = 1;
    uint16_t    Duty = DUTY_START;
    uint16_t    REF_Battery_Charge_Current_State;
    
    /**********************Needs to be changed with different Batteries*******************************************/
    #ifdef USE_FLOAT
    const float CC_LIMIT           =   20.0;        // Set the maximum charging current
    
    #ifdef SYS12
    // Typical battery threshold values             // System Voltage   | 12V       | 24V       | 48V       ||
    const float CC_TO_CV_LIMIT     =   12;        //                  | 14.2V       | 28.4V     | 56.8V     ||
    const float FLOAT_VOLTAGE      =   13.8;        //                  | 13.8V     | 27.6V     | 55.2V     ||
    const float BATTERY_CUTOFF     =   10.2;        //                  | 10.2V     | 20.4V     | 40.8V     ||
    const float BATTERY_RECONNECT  =   11.2;        //                  | 11.2V     | 22.4V     | 44.8V     ||
    #endif
    
    #ifdef SYS24
    const float CC_TO_CV_LIMIT     =   24;
    const float FLOAT_VOLTAGE      =   18;
    const float BATTERY_CUTOFF     =   20.4;
    const float BATTERY_RECONNECT  =   22.4;
    #endif
    
    #ifdef SYS48
    const float CC_TO_CV_LIMIT     =   48;
    const float FLOAT_VOLTAGE      =   37;
    const float BATTERY_CUTOFF     =   40.8;
    const float BATTERY_RECONNECT  =   44.8;
    #endif
    
    #else
                                                     // System Current   | 10A   | 15A   | 20A   ||
    unsigned int CC_LIMIT           =   305;         //                  | 305   | 457   | 610   ||
    
                                                          // System Current   | 10A   | 15A   | 20A   ||
    //const uint16_t CC_LIMIT           =   305;          //                  | 305   | 457   | 610   ||
    
    #ifdef SYS12
    // Typical battery threshold values                 // System Voltage   | 12V           | 24V           | 48V           ||
    unsigned int CC_TO_CV_LIMIT     =   201;          //       14.4           | 219 (14.2V)   | 436 (28.4V)   |     (56.8V)   ||
    unsigned int FLOAT_VOLTAGE      =   213;          //                  | 213 (13.8V)   | 424 (27.6V)   |     (55.2V)   ||
    unsigned int BATTERY_CUTOFF     =   158;          //                  | 158 (10.2V)   | 314 (20.4V)   | 627 (40.8V)   ||
    unsigned int BATTERY_RECONNECT  =   173;          //                  | 173 (11.2V)   | 345 (22.4V)   | 688 (44.8V)   ||
    #endif
    
    #ifdef SYS24
    const uint16_t CC_TO_CV_LIMIT     =   436;
    const uint16_t FLOAT_VOLTAGE      =   424;
    const uint16_t BATTERY_CUTOFF     =   314;
    const uint16_t BATTERY_RECONNECT  =   345;
    #endif
    
    #ifdef SYS48
    const uint16_t CC_TO_CV_LIMIT     =   870;  // Needs to be checked
    const uint16_t FLOAT_VOLTAGE      =   846;  // Needs to be checked
    const uint16_t BATTERY_CUTOFF     =   627;
    const uint16_t BATTERY_RECONNECT  =   688;
    #endif
    #endif
    /*************************************************************************************************************/
    
    //-----------------------------------------------------------------------------------------//
    //---------------------------------- Function Prototypes ----------------------------------//
    //-----------------------------------------------------------------------------------------//
    
    //void Init_IO(void);
    //void Init_ADC(void);
    //void Init_WDT(void);
    //void Init_Comparator(void);
    //void Init_Timer(void);
    //void Init_I2C(void);
    //void Init_Clocks(void);
    //void SetVcoreUp(uint16_t level);
    //void MPPT(void);
    //void Battery_Charge_Profiling(void);
    //void Load_Management(void);
    //void Average_MPPT_ADC_Values();
    //void Mode_Select(int Mode_sel);
    //void init_TimerA(void);
    //void Inst_protection_Values(void);
    
    
    
    //-----------------------------------------------------------------------------------------//
    //--------------------------------------- Functions ---------------------------------------//
    //-----------------------------------------------------------------------------------------//
    void main(void)
    {
        WDTCTL = WDTPW + WDTHOLD;       // Stop WDT
        __bic_SR_register(GIE);
        __delay_cycles(2000000);        // Allow system to settle before initializations
        Init_Clocks();                  // Initialize clocks for 25MHz
    
        PANEL_DISABLE;
        LOAD_DISABLE;
    
        // Initialize parameters from GUI
        Init_GUI_Parameters_GUI();
    
        Init_Comparator();              // Initialize comparator for load overcurrent protection
        Init_Timer();                   // Initialize timer for buck converter gate signals
    
        __bis_SR_register(GIE);
        while(Phase_Shifting_Done);     // Wait until the phase shifting of the interleaved buck is done
    
        BUCK_DISABLE;
    
        Init_IO();                      // Set MCU input/output pins
    
        /* Debug Bits */
        P3OUT |= BIT5; // Initialize Buzzer (check J1.7) as LOW, used to check if duty cycle at HIGHEST
    
        PJOUT &= ~BIT3; // Initialize PJ.3 (check J2.4) as LOW, used to check if Panel Voltage is high enough
        PJOUT &= ~BIT4; // Initialize PJ.4 (check J2.3) as LOW, used to check if MPPT() is executed continuously
        PJOUT &= ~BIT5; // Initialize PJ.5 (check J2.2) to LOW, used to check if duty cycle at LOWEST
    
    
    
        _delay_cycles (500);
    
        __bic_SR_register(GIE);
        //Init_I2C();                     // Initialize I2C for ambient light sensor
        Init_ADC();                     // Initialize ADC for panel and battery voltage and current monitoring
        Init_WDT();                     // Initialize watchdog timer for timing of ADC captures
        init_TimerA();                  // Initializing TimerA
        __bis_SR_register(GIE);         // Enable global interrupts
    
    
        while(1)
        {
    
            if(Read_Done)
            {
    /*
    // Protection with instantaneous values of variables. 2 Sample averaging is implemented. This is currently commented as it can cause momentary tripping in MPPT operation
    
                if (inst_prot_Counter == REF_INST_PROT_COUNTER){
                    Inst_protection_Values();
                    if (Panel_Voltage_inst > PANEL_UPPER_LIMIT || Battery_Voltage_inst > CC_TO_CV_LIMIT + 20){
                        protection_count++; //This variable is just added to deal with momentary spikes which might trigger shutdown
                        if (proection_count > 3){
                            PANEL_DISABLE;
                            BUCK_DISABLE;
                            protection_count = 0;
                        }
    
                    }
                }
    
    */
    
                if(Avg_MPPT_Counter == REF_AVG_MPPT_COUNTER)
                {
                    Average_MPPT_ADC_Values();
    
                    REF_Battery_Charge_Current_State = 1;
    
                    #ifdef GUI
                        GUI_Battery_Charge_Previous_State=GUI_Battery_Charge_Current_State;
                    #endif
    
                    #ifndef GUI
                        GUI_Battery_Charge_Current_State =1;
                    #endif
    
    
                    /* Battery charging only occurs when:
                     * 1. The panel voltage is greater than the battery voltage
                     * 2. The panel voltage is less than the predefined maximum threshold
                     */
                    if((Panel_Voltage > (Battery_Voltage-30)) && (Panel_Voltage < PANEL_UPPER_LIMIT) && (!Wait_State) && (REF_Battery_Charge_Current_State) && (GUI_Battery_Charge_Current_State))
                    {       // Since we meet all specifications for battery charging, commence creating PWM signals for gate drivers
    
    
                        PJOUT |= BIT3; //Set PJ.3 (check J2.4) as HIGH
    
                        BUCK_ENABLE;
                        PANEL_ENABLE;
    
                        if(MPPT_Loop == 1){
                            MPPT();                     // Calculate the MPP if the battery current and voltage are below maximum ratings
                        }else {
                            Battery_Charge_Profiling(); // Otherwise, maintain the battery current and voltage in a Float stage
                        }
    
    
                        TD0CCTL0 &= ~CCIFG;             // Wait until the timer completes its current cycle
                        while(!(TD0CCTL0 & CCIFG));
    
                        TD0CCR1 = TD1CCR1 = Duty;       // Set the duty cycle for the buck
                        TD0CCR2 = TD1CCR2 = Duty - DEADBAND;
    
    
    
                    } // end if
    
                    // Since the battery current is falling under the minimum charging current, we shut off the panel and buck controller
                    if(((Battery_Current < MIN_BATTERY_CURRENT) && (!Wait_State)) || (!GUI_Battery_Charge_Current_State))
                    {
                        Battery_Current_Counter++;      // Count how many times this statement is entered
                        if((Battery_Current_Counter > 10) || (Panel_Voltage > PANEL_UPPER_LIMIT) || (!GUI_Battery_Charge_Current_State))
                        {
                            // Once current has fallen for some time, disable panel and buck and go into a waiting state
                            PANEL_DISABLE;
                            BUCK_DISABLE;
                            Duty = BUCK_LOWER_THRESHOLD;
                            Wait_State = 1;
                            Wait_Counter = 0;
                        } // end if
                    } // end if
    
                    // Go to diode emulation mode(DEM) / Synchronous buck mode
                    // If boot_flag is set in DEM go to synchronous buck mode for 1ms to charge boot strap capacitor
                    else if((Battery_Current >= MIN_BATTERY_CURRENT) && (Battery_Current < 10))
                        {
                        if (boot_flag == 1){
                            BUCK_ENABLE;
                            Mode_Select(1);
                            Wait_State = 1;
                            Wait_Counter = 0;
                        }
                        else{
                            BUCK_ENABLE;
                            Mode_Select(0);
                            Wait_State = 1;
                            Wait_Counter = 0;
                        }
                        }
                    // Sync buck mode
                    else if((Battery_Current >= 10)){
                        BUCK_ENABLE;
                        Mode_Select(1);
                        Wait_State = 1;
                        Wait_Counter = 0;
                    }
    
                else
                    Battery_Current_Counter = 0; // end if-else
    
    
    
    
                    if(Wait_State)
                    {
                        // Wait in this statement until sufficient power is running through the system, checking every ~5 seconds
                        Wait_Counter++;
                        if(Wait_Counter > 50)
                        {
                            Wait_State = 0;
                            Battery_Current_Counter = 0;
                        } // end if
                    } // end if
                    Read_Done = 0;
    
                } // end if
                #ifdef GUI
                    /* If GUI is enabled, then system variables are updated from GUI*/
                    RespndToGUI();
                    if( Is_Cal_Load_Management)
                        Load_Management();
                #endif
    
                #ifndef GUI
                    // If GUI is not used , Load management is done all the time
                    Load_Management();
                #endif
    
            //    Load_Management();
    
            } // end if
        } // end while
    
    
    } // end main
    
    /* *************************************************************************************** *
     * Call this function to initialize all pins and ports for the various system signals      *
     * *************************************************************************************** */
    void Init_IO(void)
    {
        P1SEL |= BIT7;                  // P1.7/TD0.1 selected
        P1DIR |= BIT7;                  // P1.7 set as output for Timer D0.1
        P2SEL |= BIT0 + BIT2 + BIT3;    // P2.0/TD0.2, P2.2/TD1.1, and P2.3/TD1.2 selected
        P2DIR |= BIT0 + BIT2 + BIT3;    // P2.0, P2.2, P2.3 set as output for Timer D0.2, 1.1, 1.2
    
        PMAPPWD = 0x02D52;              // Enable write-access to modify port mapping registers
        PMAPCTL = PMAPRECFG;            // Allow reconfiguration during runtime
        P1MAP0 |= PM_ANALOG;            // Modify all PxMAPy registers
        P1MAP1 |= PM_ANALOG;            // Modify all PxMAPy registers
        P1MAP2 |= PM_ANALOG;            // Modify all PxMAPy registers
        P1MAP3 |= PM_ANALOG;            // Modify all PxMAPy registers
        P1MAP4 |= PM_UCB0SCL;           // Modify all PxMAPy registers
        P1MAP5 |= PM_UCB0SDA;           // Modify all PxMAPy registers
        PMAPPWD = 0;                    // Disable write-access to modify port mapping registers
        P1SEL |= BIT0 + BIT1 + BIT2 + BIT3; // P1.0, P1.1, P1.2, P1.3 set for panel and battery current and voltage sensing
        P1SEL |= BIT4 + BIT5;           // P1.4, P1.5 set to I2C for OPT3001
    
        P3DIR |= BIT2 + BIT3;           // P3.2, P3.3 set as output for Panel, Load enable
        PJDIR |= BIT3 + BIT4 + BIT5;    // PJ.3, PJ.4, PJ.5 set as output for Battery Status Indicators
        P2DIR &= ~BIT1;                 // P2.1 set as input for Temperature Sensor
        P2DIR |= BIT6 + BIT7;           // P2.6, P2.7 set as output for LED Indicators
        P3DIR |= BIT5;                  // P3.5 set as output for Buzzer
    } // end Init_IO
    
    /* *************************************************************************************** *
     * Call this function to initialize ADC pins for current and voltage sense of the          *
     *  solar panel (P_I, P_V) and battery (B_I, B_V)                                          *
     *  P1.0 (A0), P1.1 (A1), P1.2 (A2), and P1.3 (A3) are used for these signals              *
     * *************************************************************************************** */
    void Init_ADC(void)
    {
        ADC10CTL0 = ADC10SHT_2 + ADC10MSC + ADC10ON;    // 8 clock cycles, single trigger, conversion disabled
        ADC10CTL1 = ADC10SHP + ADC10CONSEQ_1;           // Sampling timer, sequence of channels
        ADC10CTL2 |= ADC10RES;                          // 10-bit conversion results
        ADC10MCTL0 = ADC10INCH_3;                       // A0, A1, A2, A3 (EoS), Vref+ = AVcc, Vref- = gnd
    
        DMACTL0 = DMA0TSEL_24;                          // ADC10IFG trigger
        __data16_write_addr((unsigned short) &DMA0SA, (unsigned long) &ADC10MEM0);          // Setting source address
        __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) &ADC_Readings[0]);    // Setting destination array address
        DMA0SZ = 0x04;                                  // 5 words (conversion results) transferred
        DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN + DMAIE;   // Source unchanged, destination increments, enable DMA, enable DMA interrupts
    } // end Init_ADC
    
    /* *************************************************************************************** *
     * Call this function to initialize the Watchdog Timer, used in gathering of analog data   *
     *  The Watchdog timer is set to trigger an interrupt every 1.3ms                          *
     * *************************************************************************************** */
    void Init_WDT(void)
    {
        WDTCTL = WDT_MDLY_32;   // WDT set to 32ms for SMCLK = 1MHz; since we are using SMCLK = 25MHz, timer interval is 1.3ms
        SFRIE1 |= WDTIE;        // Enable WDT interrupt
    } // end Init_WDT
    
    /* *************************************************************************************** *
     * Call this function to initialize the comparator for load current (L_I) monitoring       *
     *  Since over-discharge of the battery can shorten the expected battery life and lead to  *
     *  severe damage, the load needs to be disabled if overcurrent occurs                     *
     * *************************************************************************************** */
    void Init_Comparator(void)
    {
        CBCTL0 |= CBIPEN + CBIPSEL_6;   // Enable V+, input channel CB6
        CBCTL1 |= CBPWRMD_1;            // Normal power mode
        switch(Load_I_Limit & 0x03)     // Load current limit = .103125 * (CBREF + 1) / (Amp_Gain * Shunt_Resistance)
        {
            case 0x00:      // 5A -- actual 4.13A
                CBCTL2 = CBRS_1 + CBRSEL + CBREF1_3 + CBREF0_3;
                break;
            case 0x01:      // 10A -- actual 9.28A
                CBCTL2 = CBRS_1 + CBRSEL + CBREF1_8 + CBREF0_8;
                break;
            case 0x02:      // 15A -- actual 14.44A
                CBCTL2 = CBRS_1 + CBRSEL + CBREF1_13 + CBREF0_13;
                break;
            case 0x03:      // 20A -- actual 19.59A
                CBCTL2 = CBRS_1 + CBRSEL + CBREF1_18 + CBREF0_18;
                break;
            default: break;
        } // end switch
        CBCTL3 |= BIT6;             // Input buffer disable at PJ.0/CB6
        __delay_cycles(7500);       // Delay for the reference to settle
        CBINT &= ~(CBIFG + CBIIFG); // Clear any errant interrupts
        CBINT |= CBIE;              // Enable comparator B interrupt on rising edge of CBIFG
        CBCTL1 |= CBON;             // Enable comparator B
    } // end Init_Comparator
    
    /* *************************************************************************************** *
     * Call this function to initialize Timer D for PWM generation                             *
     *  PWM signals are used to drive the interleaved buck gates to control the battery        *
     *  charging current                                                                       *
     * *************************************************************************************** */
    void Init_Timer(void)
    {
        struct s_TLV_Timer_D_Cal_Data * pTD0CAL;    // Structure initialized in tlv.h
        uint8_t bTD0CAL_bytes;
        // Configure TimerD in Hi-Res Free Running mode
        Get_TLV_Info(TLV_TIMER_D_CAL, 0, &bTD0CAL_bytes, (uint16_t **) &pTD0CAL);   // Get TimerD0 cal values (instance 0)
        if(bTD0CAL_bytes == 0x0)
        {
            while(1);                               // loop here since no TimerD free running cal data found
        } // end if
        TD0CTL0 = TDSSEL_2;                         // TDCLK = SMCLK = 25MHz = Hi-Res input clk select
    
        TD0HCTL1 = pTD0CAL->TDH0CTL1_128;         // Read the 256Mhz TimerD TLV Data
    
        TD0CTL1 |= TDCLKM_1;                        // Select Hi-res local clock
        TD0HCTL0 = TDHEN + TDHM_0;                  // CALEN = 0 => free running mode; enable Hi-res mode
                                                    // TDHM_0 => clk = 8 * TDCLK = 200MHz, TDHM_1 => clk = 16 * TDCLK = 400MHz
    
        TD0CCR0 = 700;                            // 128M/700 = 182.8Khz is the operating frequency of the buck stage
    
        TD0CCTL0 |= CCIE;                         // interrupt is enabled to adjust phase
        TD0CCR1 = Duty;
        TD0CCR2 = Duty - DEADBAND;                // Pprovide Dead Band
        TD0CCTL1 |= OUTMOD_2;                     // TD0CCR1, Reset/Set
        TD0CCTL2 |= OUTMOD_6;                     // TD0CCR2, Set/reset
    
        TD1CCR0 = 700;                            //
        TD1CCR1 = Duty;
        TD1CCR2 = Duty - DEADBAND;
        TD1CCTL1 |= OUTMOD_2;                     // TD1CCR1, Reset/Set
        TD1CCTL2 |= OUTMOD_6;                     // TD1CCR2, Set/reset
        TD1CTL1 = TDCLKM_2;                       // TD1 clock = Auxiliary clock source from master timer instance
    
        // Syncronize master (TD0) and slave (TD1) timer instances
        TEC1XCTL2 |= TECAXCLREN;            // Enable synchronized clear by enabling Aux clear of slave timer
    
        TD0CTL0 |= MC_1 + TDCLR;                  // up-mode, clear TDR, Start timer
    
    } // end Init_Timer
    
    /* *************************************************************************************** *
     * Call this function to initialize the I2C bus to communicate with the OPT3001            *
     * *************************************************************************************** */
    void Init_I2C(void)
    {
        UCB0CTL1 |= UCSWRST;                    // Enable SW reset
        UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;   // I2C Master, synchronous mode
        UCB0CTL1 = UCSSEL_2 + UCSWRST;          // Use SMCLK, keep SW reset
        UCB0BR0 = 250;                          // fSCL = SMCLK/250 = 100kHz
        UCB0BR1 = 0;
        UCB0I2CSA = SLAVE_ADDR;                 // Slave Address is 044h
        UCB0CTL1 &= ~UCSWRST;                   // Clear SW reset, resume operation
        UCB0IE |= UCTXIE;                       // Enable interrupt on a receive
    } // end Init_I2C
    
    /* *************************************************************************************** *
     * Call this function to initialize the main system clock                                  *
     * *************************************************************************************** */
    void Init_Clocks(void)
    {
        SetVcoreUp(0x01);
        SetVcoreUp(0x02);
        SetVcoreUp(0x03);
    
        // Configure DCO = 25Mhz
        UCSCTL3 = SELREF_2;                         // Set DCO FLL reference = REFO
        UCSCTL4 |= SELA_2;                          // Set ACLK = REFO
        __bis_SR_register(SCG0);                    // Disable the FLL control loop
        UCSCTL0 = 0x0000;                           // Set lowest possible DCOx, MODx
        UCSCTL1 = DCORSEL_7;                        // Select DCO range 50MHz operation
        UCSCTL2 = FLLD_1 + 762;                     // Set DCO Multiplier for 25MHz
                                                    // (N + 1) * FLLRef = Fdco
                                                    // (762 + 1) * 32768 = 25MHz
                                                    // Set FLL Div = fDCOCLK/2
        __bic_SR_register(SCG0);                    // Enable the FLL control loop
    
        // Worst-case settling time for the DCO when the DCO range bits have been
        // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
        // UG for optimization.
        // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
        __delay_cycles(782000);
    
        // Loop until Xt1 & DCO stabilizes - In this case only DCO has to stabilize
        do
        {
            UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG + DCOFFG);   // Clear XT1,DCO fault flags
            SFRIFG1 &= ~OFIFG;                              // Clear fault flags
        }while (SFRIFG1&OFIFG);                             // Test oscillator fault flag
    } // end Init_Clocks
    
    void SetVcoreUp(uint16_t level)
    {
        PMMCTL0_H = PMMPW_H;                            // Open PMM registers for write
        SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;    // Set SVS/SVM high side new level
        SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;   // Set SVM low side to new level
        while ((PMMIFG & SVSMLDLYIFG) == 0);            // Wait till SVM is settled
        PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);              // Clear already set flags
        PMMCTL0_L = PMMCOREV0 * level;                  // Set VCore to new level
        if ((PMMIFG & SVMLIFG))                         // Wait till new level reached
        {
            while ((PMMIFG & SVMLVLRIFG) == 0);         // Set SVS/SVM low side to new level
        } // end if
        SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
        PMMCTL0_H = 0x00;                               // Lock PMM registers for write access
    } // end SetVcoreUp
    
    /* *************************************************************************************** *
     * Call this function to calculate the maximum power point                                 *
     *  The TIDA-010042 uses the perturb-and-observe method of MPPT                            *
     *  The panel power is calculated each time this function is called and compared to the    *
     *  previous power value, then the power point and PWM duty are adjusted accordingly       *
     *  until the maximum value is found                                                       *
     * *************************************************************************************** */
    void MPPT(void)
    {
        static uint8_t dutyChange=2;
        Prev_Panel_Power = Panel_Power;                     // Store the previous panel power
        Panel_Power = Panel_Voltage * Panel_Current;        // Calculate current panel power
    
        // Check if this is reached
        PJOUT |= BIT4; // Set PJ.4 (Check J2.3) to HIGH
    
    //    if((Battery_Current < Prev_Battery_Current) || (Panel_Power < Prev_Panel_Power))
        if(Panel_Power < Prev_Panel_Power)
        {
            MPPT_Direction = MPPT_Direction * -1;
            //Check for steady state
            maxFlips+=1;
    
            if(maxFlips==50)
            {
                dutyChange =1;
            }
    
        } // end if
    
    
        if(MPPT_Direction == 1)
        {
    
            Duty+=dutyChange;
    
            if(Duty > BUCK_UPPER_THRESHOLD)
            {
                Duty = BUCK_UPPER_THRESHOLD;
    
                P3OUT &= ~BIT5; // Set Buzzer (check J1.7) HIGH
            } // end if
        }
        else
        {
    
            Duty-=dutyChange;
    
            if(Duty < BUCK_LOWER_THRESHOLD)
            {
                Duty = BUCK_LOWER_THRESHOLD;
    
                PJOUT |= BIT5; // Set PJ.5 (check J2.2) to HIGH
            } // end if
        } // end if-else
    
        if((Battery_Current >= CC_LIMIT) || (Battery_Voltage >= CC_TO_CV_LIMIT))
        {
            MPP_Loop_Exit_Counter++;
            if(MPP_Loop_Exit_Counter > LOOP_EXIT_LIMIT)
            {
    
                MPPT_Loop = 0;
    
                PJOUT &= ~BIT4; // Set PJ.4 (check J2.3) to LOW
    
                MPP_Loop_Exit_Counter = 0;
                CC_Loop_Exit_Counter = 0;
                if (Battery_Voltage > CC_TO_CV_LIMIT)
                    CV_Mode = 1;
                else
                    CV_Mode = 0;
            } // end if
        } // end if
        else
            MPP_Loop_Exit_Counter = 0;
    
    } // end MPPT
    
    
    
    
    /* *************************************************************************************** *
     * Call this function to hold the battery in a FLOAT state when the battery has reached    *
     *  its float voltage                                                                      *
     * *************************************************************************************** */
    void Battery_Charge_Profiling(void)
    {
    
     static uint8_t delay =0;
     static uint8_t exitCV =0;
     delay+=1;
    
    #if 1
    switch (CV_Mode)
    {
    case 0: //cc mode
    
        if(Battery_Current>=(CC_LIMIT-5) && Battery_Current<CC_LIMIT+2 ) //dont exit loop
        {
            //
            Duty+=MPPT_Direction;
        }
        else if(Battery_Current>CC_LIMIT+3)
        {
            Duty-=MPPT_Direction;
        }
        else if(Battery_Current<CC_LIMIT-5)
        {
            MPPT_Loop=1; //pump more power
        }
    
        if(Battery_Voltage>=CC_TO_CV_LIMIT)
        {
            CV_Mode =1;
        }
    
    break;
    
    case 2: //handle soft CV
    
    
        break;
    
    case 1: //Full Chargerd
        if(Battery_Voltage>=(CC_TO_CV_LIMIT-5) && Battery_Voltage<CC_TO_CV_LIMIT+2 ) //dont exit loop
          {
              //
              Duty+=MPPT_Direction;
          }
          else if(Battery_Voltage>CC_TO_CV_LIMIT+3)
          {
              Duty-=MPPT_Direction;
          }
          else if(Battery_Voltage<CC_TO_CV_LIMIT-5 && Battery_Current<CC_LIMIT-5)
          {
    
              MPPT_Loop=1; //pump more power
          }
    
          if(Battery_Current>=CC_LIMIT+1)
          {
              exitCV+=1;
              if(exitCV==10)
              {
                  CV_Mode =0;
              }
    
          }
          else
          {
              exitCV=0;
          }
        break;
    default:
        break;
    }
    
    //Sanity
    if (Duty > BUCK_UPPER_THRESHOLD)
               {
                   Duty = BUCK_UPPER_THRESHOLD;
               }
    
    if (Duty < BUCK_LOWER_THRESHOLD)
                {
                    Duty = BUCK_LOWER_THRESHOLD;
                }
    
    
    #endif
    } // end Battery_Charge_Profiling
    
    /* *************************************************************************************** *
     * Call this function to disable the load if the battery voltage is too low                *
     *  (below BATTERY_CUTOFF) to prevent over-discharging of the battery                      *
     *  The battery is reconnected once sufficient charge (above BATTERY_RECONNECT) is reached *
     *  If an load overcurrent is triggered with Comparator B, then the load is disabled until *
     *  the OC_Triggered_Count has reached the OC_TRIGGERED_COUNTER_THRESHOLD                  *
     * *************************************************************************************** */
    void Load_Management(void)
    {
        if((!Hysteresis_ON) && (Battery_Voltage < BATTERY_CUTOFF) && (!OC_Triggered))
        {
            Cutoff_Counter++;
            if (Cutoff_Counter > CUTOFF_COUNTER_THRESHOLD)
            {
                LOAD_DISABLE;
                Hysteresis_ON = 1;
                Reconnect_Counter = 0;
            } // end if
        }
        else
            Cutoff_Counter = 0; // end if-else
    
        if((Hysteresis_ON) && (Battery_Voltage > BATTERY_RECONNECT) && (!OC_Triggered))
        {
            Reconnect_Counter++;
            if (Reconnect_Counter > RECONNECT_COUNTER_THRESHOLD)
            {
                LOAD_ENABLE;
                Hysteresis_ON = 0;
                Cutoff_Counter = 0;
            } // end if
        }
        else
            Reconnect_Counter = 0; // end if-else
    
        if ((OC_Triggered) && (!Hysteresis_ON)) // OC triggered at 8.40 A
        {
            OC_Triggered_Counter++;
            if (OC_Triggered_Counter > OC_TRIGGERED_COUNTER_THRESHOLD)
            {
                LOAD_ENABLE;
                OC_Triggered_Counter = 0;
                OC_Triggered = 0;
            } // end if
        } // end if
    } // end Load_Management
    
    /* *************************************************************************************** *
     * Call this function to calculate the average of each ADC channel and convert the ADC     *
     *  values to reflect actual voltage and currents in volts and amps, respectively; the     *
     *  following equations are used and may need to be recalibrated:                          *
     *  * Panel_Voltage = (PV_ADC + 14.021) / 13.985                                           *
     *  * Battery_Voltage = (BV_ADC - 0.0659) / 15.446                                         *
     *  * Panel_Current = (PI_ADC + 1.4595) / 30.581                                           *
     *  * Battery_Current = (BI_ADC + 0.6037) / 30.567                                         *
     * *************************************************************************************** */
    void Average_MPPT_ADC_Values()
    {
        Avg_MPPT_Counter    = 0;
        Prev_Battery_Current = Battery_Current;
    
    #ifdef USE_FLOAT
        Panel_Voltage       = ((float)((Panel_Voltage_Buffer >> 6) + 15) * (1. / 13.985));
        Battery_Voltage     = ((float)((Battery_Voltage_Buffer >> 6)) * (1. / 15.446));
        Panel_Current       = ((float)((Panel_Current_Buffer >> 6) + 2) * (1. / 30.581));
        Battery_Current     = ((float)((Battery_Current_Buffer >> 6)) * (1. / 30.567));
    #else
        Panel_Voltage       = (Panel_Voltage_Buffer >> 3);
        Battery_Voltage     = (Battery_Voltage_Buffer >> 3);
        Panel_Current       = (Panel_Current_Buffer >> 3);
        Battery_Current     = (Battery_Current_Buffer >> 3);
    #endif
    
        Panel_Voltage_Buffer    = 0;
        Battery_Voltage_Buffer  = 0;
        Panel_Current_Buffer    = 0;
        Battery_Current_Buffer  = 0;
    } // end Average_MPPT_ADC_Values
    
    
    void Inst_protection_Values(){
    
        inst_prot_Counter = 0;
    
        Panel_Voltage_inst       = (Panel_Voltage_inst_Buffer >> 1);
        Battery_Voltage_inst     = (Battery_Voltage_inst_Buffer >> 1);
        Panel_Current_inst       = (Panel_Current_inst_Buffer >> 1);
        Battery_Current_inst     = (Battery_Current_inst_Buffer >> 1);
    
        Panel_Voltage_inst_Buffer    = 0;
        Battery_Voltage_inst_Buffer  = 0;
        Panel_Current_inst_Buffer    = 0;
        Battery_Current_inst_Buffer  = 0;
    }
    
    
    
    //-----------------------------------------------------------------------------------------//
    //------------------------------ Interrupt Service Routines -------------------------------//
    //-----------------------------------------------------------------------------------------//
    #pragma vector=DMA_VECTOR
    __interrupt void DMA0_ISR(void)
    {
        switch(__even_in_range(DMAIV,16))
        {
            case  0: break;                         // No interrupt
            case  2:                                // Sequence of conversions complete
                SFRIE1 &= ~TAIE;                    // Timer Interrupt; Use WDTIE if watch dog is used
                ADC10CTL0 &= ~ADC10ENC;             // Disable conversion
    
                Panel_Voltage_inst_Buffer += ADC_Readings [P_V];
                Battery_Voltage_inst_Buffer += ADC_Readings [B_V];
                Panel_Current_inst_Buffer += ADC_Readings [P_I];
                Battery_Current_inst_Buffer += ADC_Readings [B_I];
    
                Panel_Voltage_Buffer += ADC_Readings [P_V];
                Battery_Voltage_Buffer += ADC_Readings [B_V];
                Panel_Current_Buffer += ADC_Readings [P_I];
                Battery_Current_Buffer += ADC_Readings [B_I];
    
                Avg_MPPT_Counter++;
                inst_prot_Counter++;
                Read_Done = 1;
                SFRIE1 |= TAIE;      // Timer Interrupt; Use WDTIE if watch dog is used
                break;                              // DMA0IFG
            case  4: break;                         // DMA1IFG
            case  6: break;                         // DMA2IFG
            case  8: break;                         // reserved
            case 10: break;                         // reserved
            case 12: break;                         // reserved
            case 14: break;                         // reserved
            case 16: break;                         // reserved
            default: break;
        } // end switch
    } // end DMA interrupt
    
    
    #pragma vector=WDT_VECTOR
    __interrupt void WDT_ISR(void)
    {
    // enable this section (lines 944 and 945) if the interrupt is done through Watch dog
    
    //    __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) &ADC_Readings[0]);
    //    ADC10CTL0 |= ADC10ENC + ADC10SC + ADC10ON;        // (ADC10ON) Start ADC sampling and conversion
    
      //  WDTCTL = WDT_MDLY_32;   // WDT set to 32ms for SMCLK = 1MHz; since we are using SMCLK = 25MHz, timer interval is 1.3ms
        //   SFRIE1 |= WDTIE;
    } // end WDT interrupt
    
    
    #pragma vector=COMP_B_VECTOR
    __interrupt void Comp_B_ISR(void)
    {
        LOAD_DISABLE;           // Interrupt triggered in event of load overcurrent, disable load
        CBINT &= ~CBIFG;        // Clear Comparator B interrupt flag
        OC_Triggered = 1;
        OC_Triggered_Counter = 0;
    } // end Comparator interrupt
    
    #pragma vector=TIMER0_D0_VECTOR
    __interrupt void TIMER0_D0_ISR(void)
    {
        //TODO - Adjust delay time for 180
        __delay_cycles(55);                     // Delay Adjusted for perfect 180 deg Phase shift
        TD1CTL0 |= TDCLR; //MC_3 +
        TD0CCTL0 &= ~CCIE;
        Phase_Shifting_Done = 1;
    } // end Timer D0 interrupt
    
    #pragma vector=TIMER0_D1_VECTOR
    __interrupt void TIMER0_D1_ISR(void)
    {
        switch(__even_in_range(TD0IV, 30))
        {
            case  0: break;                 // No interrupt
            case  2: break;                 // CCR1 not used
            case  4: break;                 // CCR2 not used
            case  6: break;                 // reserved
            case  8: break;                 // reserved
            case 10: break;                 // reserved
            case 12: break;                 // reserved
            case 14: break;
            case 16: break;
            case 18:                        // Clock fail low
                while(1);                   // Input reference clock frequency too low; trap here
            case 20:                        // Clock fail high
                while(1);                   // Input reference clock frequency too high; trap here
            case 22:                        // Hi-res frequency locked
                P1SEL |= BIT7;                  // P1.7/TD0.1 selected
                P1DIR |= BIT7;                  // P1.7 set as output
                P2SEL |= BIT0 + BIT2 + BIT3;    // P2.0/TD0.2, P2.2/TD1.1, and P2.3/TD1.2 selected
                P2DIR |= BIT0 + BIT2 + BIT3;    // P2.0, P2.2, P2.3 set as output
                __bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main
                break;
            case 24: break;                 // Hi-res frequency unlocked
            case 26: break;                 // reserved
            case 28: break;                 // reserved
            case 30: break;                 // reserved
            default: break;
        } // end switch
    } // end Timer D1 interrupt
    
    #pragma vector=USCI_B0_VECTOR
    __interrupt void I2C_TX_ISR(void)
    {
        switch(__even_in_range(UCB0IV, 12))
        {
            case  0:    break;          // No interrupt
            case  2:    break;          // I2C Arbitration Lost not used
            case  4:    break;          // I2C Not-Acknowledge not used
            case  6:    break;          // I2C Start Condition not used
            case  8:    break;          // I2C Stop Condition not used
            case 10:    break;          // I2C Receive
            case 12:    break;          // I2C Transmit
            default:    break;
        }
    }
    
    void Mode_Select(int Mode_sel) {
        static unsigned char prev_state = 2;
    
        if (prev_state != Mode_sel){
    
    
            if (Mode_sel == 0) {
    
                TD0CCTL0 &= ~CCIFG; // wait till the timer completes its current cycle
    
                while(!(TD0CCTL0 & CCIFG));
    
                TD0CCR1 = TD1CCR1 = Duty;       // Set the duty cycle for the buck
                TD0CCR2 = TD1CCR2 = Duty - DEADBAND;
    
                TD0CCTL0 &= ~CCIFG; // wait till the timer completes its current cycle
    
                while(!(TD0CCTL0 & CCIFG));
                P2OUT &= ~BIT2;
                P1OUT &= ~BIT7;
                P2SEL &= ~BIT2;
                P2DIR |= BIT2;
    
    
                P1SEL &= ~BIT7;
                P1DIR |= BIT7;
    
    
                P2SEL |= BIT0;
                P2DIR |= BIT0;
                P2OUT |= BIT0;
    
                P2SEL |= BIT3;
                P2DIR |= BIT3;
                P2OUT |= BIT3;
            }
    
            else {
                TD0CCTL0 &= ~CCIFG; // wait till the timer completes its current cycle
    
                while(!(TD0CCTL0 & CCIFG));
                P2SEL |= BIT2;
                P2DIR |= BIT2;
                P2OUT |= BIT2;
    
                P1SEL |= BIT7;
                P1DIR |= BIT7;
                P1OUT |= BIT7;
    
                P2SEL |= BIT0;
                P2DIR |= BIT0;
                P2OUT |= BIT0;
    
                P2SEL |= BIT3;
                P2DIR |= BIT3;
                P2OUT |= BIT3;
    
                TD0CCTL0 &= ~CCIFG; // wait till the timer completes its current cycle
    
                while(!(TD0CCTL0 & CCIFG));
    
                TD0CCR1 = TD1CCR1 = Duty;       // Set the duty cycle for the buck
                TD0CCR2 = TD1CCR2 = Duty - DEADBAND;
    
    
            }
            prev_state = Mode_sel;
    
    
    }
    
    }
    
    void init_TimerA(void) {
    
        TA0CCTL0 = CCIE;                             // CCR0 interrupt enabled
        TA0CCR0 = 5000;                              // Frequency of ISR (25Mhz/50000) 0.2ms
        TA0CTL = TASSEL_2 + MC_1 +TAIE;              // SMCLK, countmode; Interrupt enable
    
    }
    
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void TIMER0_A0_ISR(void) {
    
        P2DIR |= BIT7; // Sanity check to see if interrupt occurs
        P2OUT ^= BIT7;
        __data16_write_addr((unsigned short) &DMA0DA, (unsigned long) &ADC_Readings[0]);
        ADC10CTL0 |= ADC10ENC + ADC10SC + ADC10ON;        // Start ADC sampling and conversion
        boot_flag = 0;              // Start initially in diode emulation
    
        boot_count++;
    
        if (boot_count >= 500)      // Change is count value to control ON time of Bottom FET in Diode Emulation Mode
        {
            boot_count = 0;
            if (Mode_sel == 0){
    
                boot_flag = 1;     //Flag which sets the turning on instance of FET in DEM
            }
    
        }
            TA0CCTL0 &= ~CCIFG;     //Clear flag
            TA0CTL &= ~TAIFG;
    }
    
    main.h
    /*
    * TEXAS INSTRUMENTS TEXT FILE LICENSE
    *
    * Copyright (c) [2012] - [2018] Texas Instruments Incorporated
    *
    * All rights reserved not granted herein.
    *
    * Limited License.
    *
    * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive license under copyrights and patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell ("Utilize") this software subject to the terms herein.  With respect to the foregoing patent license, such license is granted  solely to the extent that any such patent is necessary to Utilize the software alone.  The patent license shall not apply to any combinations which include this software, other than combinations with devices manufactured by or for TI ("TI Devices").  No hardware patent is licensed hereunder.
    *
    * Redistributions must preserve existing copyright notices and reproduce this license (including the above copyright notice and the disclaimer and (if applicable) source code license limitations below) in the documentation and/or other materials provided with the distribution
    *
    * Redistribution and use in binary form, without modification, are permitted provided that the following conditions are met:
    *
    * - No reverse engineering, decompilation, or disassembly of this software is permitted with respect to any software provided in binary form.
    *
    * - any redistribution and use are licensed by TI for use only with TI Devices.
    *
    * - Nothing shall obligate TI to provide you with source code for the software licensed and provided to you in object code.
    *
    * If software source code is provided to you, modification and redistribution of the source code are permitted provided that the following conditions are met:
    *
    * - any redistribution and use of the source code, including any resulting derivative works, are licensed by TI for use only with TI Devices.
    *
    * - any redistribution and use of any object code compiled from the source code and any resulting derivative works, are licensed by TI for use only with TI Devices.
    *
    * Neither the name of Texas Instruments Incorporated nor the names of its suppliers may be used to endorse or promote products derived from this software without specific prior written permission.
    *
    * DISCLAIMER.
    *
    * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    
    #define GUI
    #ifdef GUI
    #include "msp430f5132.h"
    #include<string.h>
    
    #include<main.h>
    #include<GUI.h>
    //#include<Config.h>
    
    //#define TRUE 1
    //#define FALSE 0
    //#define TX 1
    //#define RX 2
    //#define DATA_LENGTH 10
    //#define FRAME_LENGTH 15
    //#define LOAD_DISABLE        P3OUT |= BIT2
    //#define LOAD_ENABLE         P3OUT &= ~BIT2
    //
    //extern unsigned int CC_LIMIT;
    //extern unsigned int CC_TO_CV_LIMIT;
    //extern unsigned int FLOAT_VOLTAGE;
    //extern unsigned int BATTERY_CUTOFF;
    //
    //extern unsigned int Panel_Voltage,
    //                    Battery_Voltage,
    //                    Panel_Current,
    //                    Battery_Current;
    //
    //extern unsigned int Is_Load_On,
    //                    GUI_Battery_Charge_Current_State,
    //                    GUI_Battery_Charge_Previous_State,
    //                    Is_Cal_Load_Management,
    //                    Load_I_Limit;
    //
    //extern unsigned char    Hysterisis_ON ,
    //                        OC_Triggered,
    //                        Start_Delay,
    //                        Battery_Current_Counter;
    //
    //
    //void Init_UART (void);
    //void Interrupt_enable(int IE);
    //void Create_Frame(void);
    //void Send_Frame(void);
    //void Init_GUI_Parameters();
    //
    //void Calculate_CRC(void);
    //void UnpackReceivedFrame(void);
    //void RespndToGUI();
    
    #define LOAD_ENABLE     P3OUT |= BIT2   // Set to enable load *** P3.2
    #define LOAD_DISABLE    P3OUT &= ~BIT2  // Reset to disable load
    
    char CRC_Generator[]={0x80,0x21};
    char copy[13];
    unsigned int testVar=258;
    int size;
    char FrameToSend[15];
    char ReceivedFrame[15];
    char CRC_buffer[13];
    
    
    unsigned int GUI_Battery_Charge_Current_State;
    unsigned int Is_Cal_Load_Management;
    
    // Variables for user settings
    unsigned int    Load_I_Limit = 0x01;        // Defining load overcurrent limit: 0x00 = 5A, 0x01 = 10A, 0x02 = 15A, 0x03 = 20A
    
    
    unsigned int Hysterisis_ON;
    //unsigned int OC_Triggered = 0;
    
    
    unsigned int Stat_U,Stat_L;
    unsigned int Bat_Const_I,Bat_Const_V,Float_V,System_Voltage,GUI_Commands;
    int isFrameReceived =FALSE ;
    unsigned int prev_Load_Limit = 0x02; // default 9A
    
    /*Here all the initialization required to establish link with GUI are done.
     * When GUI is not used all the system data variables are initialized in this function.  */
    void Init_GUI_Parameters_GUI()
    {
        Init_UART();
        Interrupt_enable(RX);
        GUI_Battery_Charge_Current_State = 1;
        Is_Cal_Load_Management =1;
    //    Load_I_Limit = 2;
    
    }
    
    
    void Init_UART(void)
    {
        // select secondary fun
            P2SEL |= (BIT4|BIT5); // 4-RX, 5-TX
            P2DIR |= (BIT5); //TX output
            P2REN |= (BIT4); // RX pull up reg
    
            PMAPKEYID = 0x02D52;
            PMAPCTL = PMAPRECFG;
            P2MAP4= PM_UCA0RXD;
            P2MAP5 = PM_UCA0TXD;
    
            UCA0CTL1=0X0C1; // SETTING UCSWRST source clock = SMCLK = 25Mhz
            UCA0CTL0=0X00;
            UCA0BR0=44; // BAUD RATE for 9600
            UCA0BR1=10;
            UCA0MCTL=UCBRS_1+UCBRF_0; // MODULATION not needed
            UCA0CTL1 &= ~0X01;// RESETTING UCSWRST;
    
    }
    
    void Create_Frame(void)
    {
        int j;
        FrameToSend[0]='*'; // header
        FrameToSend[1]=0x01; // msg ID
        FrameToSend[2] = (Panel_Voltage>>8) & 0xFF;
        FrameToSend[3]= Panel_Voltage & 0xFF;
        FrameToSend[4]= (Panel_Current >> 8) & 0xFF;
        FrameToSend[5]= (Panel_Current) & 0xFF;
        FrameToSend[6] = (Battery_Voltage >> 8) & 0xFF;
        FrameToSend[7] = (Battery_Voltage) & 0xFF;
        FrameToSend[8] = (Battery_Current >> 8) & 0xFF;
        FrameToSend[9]= (Battery_Current) & 0xFF;
        FrameToSend[10] = (Stat_U ) & 0xFF;
        FrameToSend[11]= (Stat_L) & 0xFF;
        FrameToSend[12] = 0; // initially CRC bits are 0
        FrameToSend[13]= 0; // initially CRC bits are 0
        FrameToSend[14]='#'; // footer
    
        for(j=1;j<14;j++)
                    CRC_buffer[j-1]= ReceivedFrame[j];
        Calculate_CRC();
    
        FrameToSend[12] = CRC_buffer[0];
        FrameToSend[13]= CRC_buffer[1];
    }
    
    void Send_Frame(void)
    {
        int i;
        for(i=0;i<=14;i++)
             {
                   UCA0TXBUF=FrameToSend[i];
                   while(!(UCA0IFG & BIT1));
             }
    }
    void Interrupt_enable(int IE)
    {
        if(IE==1)
            UCA0IE |= BIT1;
        else
            UCA0IE |= BIT0;
    }
    
    void RespndToGUI()
    {
        int j;
        int Is_Valid_Frame = 1;
        if(isFrameReceived == TRUE)
        {
            isFrameReceived =FALSE;
            // put values in CRC buffer
            for(j=1;j<14;j++)
                CRC_buffer[j-1]= ReceivedFrame[j];
            Calculate_CRC();
    
            // check if CRC is correct
            if(!((CRC_buffer[0] ==0)&& (CRC_buffer[1]==0)))
                Is_Valid_Frame = 0;
            // check header , footer and msg ID
            if((ReceivedFrame[0] != 0x42 )||(ReceivedFrame[14] != 0x35)|| (ReceivedFrame[1] != 0x0A))
                Is_Valid_Frame = 0;
            if(Is_Valid_Frame)
            {
    
                UnpackReceivedFrame();
    
                CC_LIMIT = Bat_Const_I;
                CC_TO_CV_LIMIT = Bat_Const_V;
                FLOAT_VOLTAGE =Float_V;
    
                if(prev_Load_Limit != Load_I_Limit)
                {
                    prev_Load_Limit = Load_I_Limit;
                    CBCTL1 &= ~CBON; // first turn off
                    switch(Load_I_Limit & 0x03)
                        {
                            case 0x00: // 3 Amps
                                CBCTL2 = CBRS_1 + CBRSEL + CBREF1_0 + CBREF0_0;     // VCC applied to R-ladder;
                                        break;
                            case 0x01: // 6 Amps
                                CBCTL2 = CBRS_1 + CBRSEL+ CBREF1_1 + CBREF0_1;     // VCC applied to R-ladder;
                                        break;
                            case 0x02: // 9 Amps
                                CBCTL2 = CBRS_1 + CBRSEL + CBREF1_2 + CBREF0_2;     // VCC applied to R-ladder;
                                        break;
                            case 0x03: // 12 Amps
                                CBCTL2 = CBRS_1 + CBRSEL +CBREF1_3 + CBREF0_3;     // VCC applied to R-ladder;
                                        break;
                            default:
                                break;
                        }
                    CBCTL1 |= CBON; //  turn on
                }
    
                if(((Is_Load_On==1) && Hysterisis_ON)||((Is_Load_On==0) && Battery_Voltage < BATTERY_CUTOFF ))
                    Stat_L |= 0xFF;
                else
                    Stat_L &=0x00;
    
                if(OC_Triggered)
                    Stat_U |= 0xFF;
                else
                    Stat_U &=0x00;
    
                Create_Frame();
                Send_Frame();
    
    
    
                if(Is_Load_On)
                {
                        if((Hysterisis_ON == 0) && (OC_Triggered == 0))
                        LOAD_ENABLE;
                        Is_Cal_Load_Management = 1;
                }
                else
                {
                    Is_Cal_Load_Management = 0;
                        LOAD_DISABLE;
                }
                if((GUI_Battery_Charge_Current_State != GUI_Battery_Charge_Previous_State) && (GUI_Battery_Charge_Current_State))
                {
                    Start_Delay =0; // no delay needed
                    Battery_Current_Counter=0;
                }
                }
        }
    }
    void UnpackReceivedFrame()
    {
        Bat_Const_I=(ReceivedFrame[2]<<8)|ReceivedFrame[3];
        Bat_Const_V=(ReceivedFrame[4]<<8)|ReceivedFrame[5];
        Float_V=(ReceivedFrame[6]<<8)|ReceivedFrame[7];
        Load_I_Limit=(ReceivedFrame[8]<<8)|ReceivedFrame[9];
        System_Voltage=ReceivedFrame[10];
        GUI_Commands=ReceivedFrame[11];
    
        if(GUI_Commands & 0x0F)
            Is_Load_On =1;
         else
             Is_Load_On =0;
    
         if(GUI_Commands & 0xF0)
             GUI_Battery_Charge_Current_State =1;
         else
             GUI_Battery_Charge_Current_State=0;
    }
    #pragma vector=USCI_A0_VECTOR
    __interrupt void TX_RX_interrupt(void)
    {
        static int index=0;
        if(UCA0IFG & BIT0) // if due to RX
        {
    
            ReceivedFrame[index++]=UCA0RXBUF;
            UCA0IFG &= ~BIT0; // clear flag
        }
    
        if(index==15)
        {
            isFrameReceived = TRUE;
            index=0;
        }
    }
    void Calculate_CRC(void)
    {
    
        int i,k;
    
            for(i=0;i<(11*8);i++)
            {
                if(CRC_buffer[0] & 0x80)
                 {
                    // xor
                    CRC_buffer[0] = CRC_buffer[0]  ^ CRC_Generator[0];
    
                    CRC_buffer[1] = CRC_buffer[1]  ^ CRC_Generator[1];
                 }
                    // shifting
                 for(k=0;k<13;k++)
                {
                    CRC_buffer[k] = CRC_buffer[k] << 1;
                    if(k!=12)
                    if(CRC_buffer[k+1] & 0x80)
                    CRC_buffer[k] |= 0x01;
                 }
            }
    }
    #endif
    
    
    
    GUI.h
    //*******************************************************************************
    //  Provides Functions to Read the TLV Data Section of the MSP430 Devices
    //    File: hal_TLV.c
    //
    //    Texas Instruments
    //
    //    Version 1.0
    //    10/17/10
    //
    //    V1.0  Initial Version
    //====================================================================
    
    /* ***********************************************************
    * THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
    * REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
    * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
    * FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
    * COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
    * TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
    * POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
    * INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
    * YOUR USE OF THE PROGRAM.
    *
    * IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
    * CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
    * THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
    * OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
    * OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
    * EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
    * REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
    * OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
    * USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
    * AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
    * YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
    * (U.S.$500).
    *
    * Unless otherwise stated, the Program written and copyrighted
    * by Texas Instruments is distributed as "freeware".  You may,
    * only under TI's copyright in the Program, use and modify the
    * Program without any charge or restriction.  You may
    * distribute to third parties, provided that you transfer a
    * copy of this license to the third party and the third party
    * agrees to these terms by its first use of the Program. You
    * must reproduce the copyright notice and any other legend of
    * ownership on each copy or partial copy, of the Program.
    *
    * You acknowledge and agree that the Program contains
    * copyrighted material, trade secrets and other TI proprietary
    * information and is protected by copyright laws,
    * international copyright treaties, and trade secret laws, as
    * well as other intellectual property laws.  To protect TI's
    * rights in the Program, you agree not to decompile, reverse
    * engineer, disassemble or otherwise translate any object code
    * versions of the Program to a human-readable form.  You agree
    * that in no event will you alter, remove or destroy any
    * copyright notice included in the Program.  TI reserves all
    * rights not specifically granted under this license. Except
    * as specifically provided herein, nothing in this agreement
    * shall be construed as conferring by implication, estoppel,
    * or otherwise, upon you, any license or other right under any
    * TI patents, copyrights or trade secrets.
    *
    * You may not use the Program in non-TI devices.
    * ********************************************************* */
    
    
    #include "msp430f5172.h"
    #include "hal_TLV.h"
    
    //====================================================================
    /**
      * Get Information out of the TLV Table
      *
      * \param tag: Tag of the TLV entry
      * \param instance: Instance of the Tag of the TLV entry
      * \param *length: return: Length of the information if found
      * \param **data_address: return: start pointer of Data
      */
    void Get_TLV_Info(uint8_t tag, uint8_t instance, uint8_t *length, uint16_t ** data_address)
    {
      char *TLV_address = (char *)TLV_START;          // TLV Structure Start Address
    
      while((TLV_address < ( char *)TLV_END)
            && ((*TLV_address != tag) || instance)   // check for tag and instance
            && (*TLV_address != TLV_TAGEND) )        // do range check first
      {
        if (*TLV_address == tag)(instance--);        // repeat till requested instance is reached
        TLV_address += *(TLV_address+1) + 2;         // add (Current TAG address + LENGTH) + 2
      }
      if (*TLV_address == tag)                       // Check if Tag match happened..
      {
        *length = *(TLV_address+1);                  // Return length = Address + 1
        *data_address = (uint16_t *)(TLV_address+2); // Return address of first data/value info = Address + 2
      }
      else                                           // If there was no tag match and the end of TLV structure was reached..
      {
        *length = 0;                                 // Return 0 for TAG not found
        *data_address = 0;                           // Return 0 for TAG not found
      }
    }
    
    //====================================================================
    /**
      * Get Device Type out of the TLV Table
      *
      * \return device_type - either F5438 or F5438A, depending on device
      */
    uint16_t Get_Device_Type(void)
    {
      uint16_t *pDeviceType = (uint16_t *)DEVICE_ID_0;
      return (pDeviceType[0]);                       // Return Value from TLV Table
    }
    
    //====================================================================
    /**
      * Get Memory Info out of the TLV Table
      *
      * \param instance: Index of the Instance [0..]
      * \return Memory Data found
      */
    uint16_t Get_TLV_Memory(uint8_t instance)
    {
        uint8_t * pPDTAG;
        uint8_t bPDTAG_bytes;
        uint16_t count;
    
        instance *= 2;                               // set tag for word access comparison
        // TLV access Function Call
        Get_TLV_Info(TLV_PDTAG, 0, &bPDTAG_bytes, (uint16_t **) &pPDTAG); // Get Peripheral data pointer
        for(count=0;count<=instance;count+=2)
        {
          if (pPDTAG[count] == 0) return 0;          // Return 0 if end reached
          if (count == instance) return (pPDTAG[count] | pPDTAG[count+1]<<8);
        }
        return 0;                                    // Return 0: not found
    }
    
    //====================================================================
    /**
      * Get Peripheral Info out of the TLV Table
      *
      * \param tag: Tag of the TLV entry
      * \param instance: Index of the Instance [0..]
      * \return Peripheral Data found
      */
    uint16_t Get_TLV_Peripheral(uint8_t tag, uint8_t instance)
    {
        uint8_t * pPDTAG;
        uint8_t bPDTAG_bytes;
        uint16_t count = 0;
        uint16_t pcount = 0;
    
    
        Get_TLV_Info(TLV_PDTAG, 0, &bPDTAG_bytes, (uint16_t **) &pPDTAG); // Get Peripheral data pointer
        // read memory configuration from TLV to get offset for Peripherals
        while(Get_TLV_Memory(count))
        { count++; }
    
        pcount = pPDTAG[count*2 + 1];                // get number of Peripheral entries
        count++;                                     // inc count to first Periperal
        pPDTAG += count*2;                           // adjust point to first address of Peripheral
        count = 0;                                   // set counter back to 0
    
        pcount *= 2;                                 // align pcount for work comparision
    
        // TLV access Function Call
        for(count=0;count<=pcount;count+=2)
        {
          if (pPDTAG[count+1] == tag)                // test if required Peripheral is found
            if(instance > 0) {                       // test if required instance is found
              instance--;
            }else{
              return (pPDTAG[count] | pPDTAG[count+1]<<8); // Return found data
            }
        }
        return 0;                                    // Return 0: not found
    }
    
    //====================================================================
    /**
      * Get Interrupt Info out of the TLV Table
      *
      * \param tag: Tag of the TLV entry
      * \return Interrupt Data found
      */
    uint8_t Get_TLV_Interrupt(uint8_t tag)
    {
        uint8_t * pPDTAG;
        uint8_t bPDTAG_bytes;
        uint16_t count = 0;
        uint16_t pcount = 0;
    
    
        Get_TLV_Info(TLV_PDTAG, 0, &bPDTAG_bytes, (uint16_t **) &pPDTAG); // Get Peripheral data pointer
        // read memory configuration from TLV to get offset for Peripherals
        while(Get_TLV_Memory(count))
        {
          count++;
        }
    
        pcount = pPDTAG[count*2 + 1];
        count++;                                     // inc count to first Periperal
        pPDTAG += (pcount+count)*2;                  // adjust point to first address of Peripheral
        count = 0;                                   // set counter back to 0
    
        // TLV access Function Call
        for(count=0;count<=tag;count+=2)
        {
          if (pPDTAG[count] == 0) return 0;          // Return 0: not found/end of table
          if (count == tag) return (pPDTAG[count]);  // Return found data
        }
        return 0;                                    // Return 0: not found
    }
    
    hal_tlv.h

    Here is the code I have so far. I am getting nothing out of the recieve/transmit pins on my MCU. The __interrupt void TX_RX_interrupt(void) is not triggering

  • The RecievedFrame message is not correct. In other words, when the GUI sends data, Is_Valid_Frame gets set at zero because the CRC fails and the reciveved data does not match the header, message id, and footer.

    Could this be caused by the cable I am using? It is found here https://www.adafruit.com/product/954. Does the GUI need to be fixed? Is the source code available for the GUI?

    The CRCcheck is failing and I`m trying to understand why!

    Also, if I comment/bypass the two if statements in the code below, I am able to view the battery voltage on the GUI but it is not accurate. A 12V battery reads 8.16V

  • Hi Amar,

    We could not get help from anyone involved in the GUI design. It looks like the TIDA-00120 GUI may not work with TIDA-010042.

    Regards,

    Salil