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.

Compiler: Use a code for MSP430f427aIn a MSP430f425 to use the led pulse and LCD

Other Parts Discussed in Thread: MSP430F425, MSP430F4794

Tool/software: TI C/C++ Compiler

hi

haw i can Use a code for MSP430f427a In a MSP430F425 to use the led pulse 

i make the change pin config pulse but when i download the code in the board the led stay off. please help me to toggle the led pulse.

the code 

slac488 (

i make the modification in the pins :

my schematic board

main and strat fichier

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

/*! \file emeter-structs.h */

//  MSP430 setup routines for e-meters.
//
//  This software is appropriate for single phase and three phase e-meters
//  using a voltage sensor plus CT or shunt resistor current sensors, or
//  a combination of a CT plus a shunt. 
//
#include <stdint.h>
#include <string.h>
#if !defined(__MSP430__)
#include <stdio.h>
#include <stdlib.h>
#endif
#if defined(__GNUC__)
#include <signal.h>
#endif
#include <io.h>
#include <emeter-toolkit.h>

#include "emeter-metrology.h"
#include "emeter-template.h"
#include "emeter-app.h"
#include "emeter-rtc.h"
#include "emeter-lcd.h"

#if defined(MESH_NET_SUPPORT)
#include "mesh_structure.h"
#endif

#if defined(__MSP430__)
void system_setup(void)
{
  
    #if defined(__MSP430_HAS_DCO__)
    /* Set up the DCO clock */
 WDTCTL = WDTPW+WDTHOLD;  
 P1DIR |= 0x04; 
 P1OUT &= ~0x04;
   BCSCTL1 |= (RSEL0 | RSEL1 | RSEL2); /* Select the highest nominal freq */
    BCSCTL2 |= DCOR;                    /* Select the external clock control resistor pin */
    DCOCTL = 0xFF;                      /* Select the highest speed. */
    #endif
    
////MM Added below (BC2) for AFE device
    #if defined (__MSP430_HAS_BC2__)
    volatile unsigned int i=0;   
    WDTCTL = (WDTCTL & 0xFF) | WDTPW | WDTHOLD;     
    BCSCTL1 &= ~XT1OFF;                       // Activate XT2 high freq xtal
      BCSCTL3 |= XT2S_2+LFXT1S_2;               // 3 � 16MHz crystal or resonator
      do
      {

        IFG1 &= ~OFIFG;                         // Clear OSCFault flag
        for (i = 0xFFF; i > 0; i--);            // Time for flag to set
      }
      while (IFG1 & OFIFG);                     // OSCFault flag still set?
      BCSCTL2 |= SELS+SELM_2;                   // MCLK = XT2 HF XTAL (safe)  
   #endif


    #if defined(__MSP430_HAS_FLLPLUS__)  ||  defined(__MSP430_HAS_FLLPLUS_SMALL__)
    //FLL_CTL0 |= XCAP18PF;               /* Configure load caps */
    FLL_CTL0 |= OSCCAP_3;               /* Configure load caps */
        #if defined(XT2OFF)
    FLL_CTL1 |= XT2OFF;
        #endif
    SCFI0 = SCFI0_LOW;
    SCFQCTL = SCFQCTL_LOW;
    FLL_CTL0 |= DCOPLUS;
    /* There seems no benefit in waiting for the FLL to settle at this point. */
    #endif
    #if defined (__MSP430_HAS_AUX_SUPPLY__)
        AUX3CHCTL = AUXCHKEY | AUXCHC_1 | AUXCHV_1 | AUXCHEN;  // Enable Charger for AUX3 to enable RTC
    #endif
    #if defined(__MSP430_HAS_UCS__)
    __bis_SR_register(SCG0);                        /* Disable the FLL control loop */
    UCSCTL6 = (UCSCTL6 | XT1DRIVE_3);               /* Highest drive setting for XT1 startup */
    while (SFRIFG1 & OFIFG)
    {
        /* Check OFIFG fault flag */
        UCSCTL7 &= ~(DCOFFG | XT1LFOFFG | XT2OFFG); /* Clear OSC fault flags */
        SFRIFG1 &= ~OFIFG;                          /* Clear OFIFG fault flag */
    }
    UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3));            /* Reduce drive to something weaker */

    UCSCTL1 = DCORSEL_5;                            /* Set RSELx for DCO = 16 MHz */
    UCSCTL2 = FLLD_1 + 255;                         /* Set DCO Multiplier for 8MHz */
                                                    /* (N + 1) * FLLRef = Fdco */
                                                    /* (63 + 1) * 32768 = 2MHz */
                                                    /* Set FLL Div = fDCOCLK/2 */
    __bic_SR_register(SCG0);                        /* Enable the FLL control loop */

    UCSCTL5 |= DIVS__1;
    UCSCTL4 = SELM__DCOCLK | SELS__DCOCLK | SELA__XT1CLK;     //16MHz MCLK, 16MHz SMCLK, 32KHz ACLK

    /* Suitable settings for a 6736 */
    PJDIR = BIT0 | BIT1 | BIT3;     /* SMCLK, MCLK, ACLK */
    PJSEL = BIT0 | BIT1 | BIT3;     /* SMCLK, MCLK, ACLK */
    #endif

    #if defined(__MSP430_HAS_BT__)  ||  defined(__MSP430_HAS_BT_RTC__)
    /* Basic timer setup */
    /* Set ticker to 32768/(256*256) */
        #if defined(__MSP430_HAS_BT__)
    BTCTL = BT_fLCD_DIV64 | BT_fCLK2_DIV128 | BT_fCLK2_ACLK_DIV256;
        #else
    BTCTL = BT_fCLK2_DIV128 | BT_fCLK2_ACLK_DIV256;
        #endif
    /* Enable the 1 second counter interrupt */
    IE2 |= BTIE;

    /* We want a real watchdog function, but it doesn't have to be fast. */
    /* Use the longest timer - 1s */
        #if defined(USE_WATCHDOG)
    kick_watchdog();    /* Set the watchdog timer to exactly 1s */
        #else
    WDTCTL = (WDTCTL & 0xFF) | WDTPW | WDTHOLD;
        #endif
    #elif defined(__MSP430_HAS_SFR__)
    SFRIE1 |= WDTIE;            /* Enable the WDT interrupt */
    #else
    IE1 |= WDTIE;               /* Enable the WDT interrupt */
    #endif

    #if defined(P1OUT_INIT)
    P1OUT = P1OUT_INIT;
    #endif
    #if defined(P1DIR_INIT)
    P1DIR = P1DIR_INIT;
    #endif
    #if defined(P1SEL_INIT)
    P1SEL = P1SEL_INIT;
    #endif

    #if defined(P2OUT_INIT)
    P2OUT = P2OUT_INIT;
    #endif
    #if defined(P2DIR_INIT)
    P2DIR = P2DIR_INIT;
    #endif
    #if defined(P2SEL_INIT)
    P2SEL = P2SEL_INIT;
    #endif

    #if defined(P3OUT_INIT)
    P3OUT = P3OUT_INIT;
    #endif
    #if defined(P3DIR_INIT)
    P3DIR = P3DIR_INIT;
    #endif
    #if defined(P3SEL_INIT)
    P3SEL = P3SEL_INIT;
    #endif

    #if defined(P4OUT_INIT)
    P4OUT = P4OUT_INIT;
    #endif
    #if defined(P4DIR_INIT)
    P4DIR = P4DIR_INIT;
    #endif
    #if defined(P4SEL_INIT)
    P4SEL = P4SEL_INIT;
    #endif

    #if defined(P5OUT_INIT)
    P5OUT = P5OUT_INIT;
    #endif
    #if defined(P5DIR_INIT)
    P5DIR = P5DIR_INIT;
    #endif
    #if defined(P5SEL_INIT)
    P5SEL = P5SEL_INIT;
    #endif

    #if defined(P6OUT_INIT)
    P6OUT = P6OUT_INIT;
    #endif
    #if defined(P6DIR_INIT)
    P6DIR = P6DIR_INIT;
    #endif
    #if defined(P6SEL_INIT)
    P6SEL = P6SEL_INIT;
    #endif

    #if defined(P7OUT_INIT)
    P7OUT = P7OUT_INIT;
    #endif
    #if defined(P7DIR_INIT)
    P7DIR = P7DIR_INIT;
    #endif
    #if defined(P7SEL_INIT)
    P7SEL = P7SEL_INIT;
    #endif

    #if defined(P8OUT_INIT)
    P8OUT = P8OUT_INIT;
    #endif
    #if defined(P8DIR_INIT)
    P8DIR = P8DIR_INIT;
    #endif
    #if defined(P8SEL_INIT)
    P8SEL = P8SEL_INIT;
    #endif

    #if defined(P9OUT_INIT)
    P9OUT = P9OUT_INIT;
    #endif
    #if defined(P9DIR_INIT)
    P9DIR = P9DIR_INIT;
    #endif
    #if defined(P9SEL_INIT)
    P9SEL = P9SEL_INIT;
    #endif

    #if defined(P10OUT_INIT)
    P10OUT = P10OUT_INIT;
    #endif
    #if defined(P10DIR_INIT)
    P10DIR = P10DIR_INIT;
    #endif
    #if defined(P10SEL_INIT)
    P10SEL = P10SEL_INIT;
    #endif

    #if (defined(BASIC_LCD_SUPPORT)  ||  defined(CUSTOM_LCD_SUPPORT))
    LCDinit();
    #endif

    #if defined(BASIC_LCD_SUPPORT)
    display_startup_message();
    #endif

    #if defined(IO_EXPANDER_SUPPORT)
    set_io_expander(0, 0);
    #endif
    
    #if defined(LIMP_MODE_SUPPORT)
    samples_per_second = LIMP_SAMPLES_PER_10_SECONDS/10;
    #else
    samples_per_second = SAMPLES_PER_10_SECONDS/10;
    #endif

    #if defined(__MSP430_HAS_TA3__)  &&  defined(__MSP430_HAS_SD16_3__)
    /* Use timer A to control the ADC sampling interval in limp mode. */
    /* CCR0 determines the sample period - 1024Hz */
    TAR = 0;
    TACCR0 = 32 - 1;
    TACCTL0 = 0;
    TACCTL1 = OUTMOD_3;
    TACTL = TACLR | MC_1 | TASSEL_1;
    #endif

    metrology_disable_analog_front_end();

   // #if defined(POWER_UP_BY_SUPPLY_SENSING)
    /* Set up comparator A to monitor a drooping voltage within the
       e-meter's main power supply. This is an early warning of power
       fail, so we can get to low power mode before we start burning the
       battery. */
   // CACTL1 = CAREF_1;
  //  CACTL2 = P2CA1 | CAF;
    //P1SEL |= BIT7;
  //  CAPD |= BIT7;
  //  #endif

    comms_setup(); 

    meter_status &= ~(STATUS_REVERSED | STATUS_EARTHED | STATUS_PHASE_VOLTAGE_OK);
    clr_normal_indicator();
    clr_earthed_indicator();
    clr_reverse_current_indicator();
    #if defined(total_active_energy_pulse_end)
    total_active_energy_pulse_end();
    #endif
    #if defined(total_reactive_energy_pulse_end)
    total_reactive_energy_pulse_end();
    #endif
    #if defined(PER_PHASE_ACTIVE_ENERGY_SUPPORT)
        #if !defined(SINGLE_PHASE)
    phase_active_energy_pulse_end(0);
    phase_active_energy_pulse_end(1);
    phase_active_energy_pulse_end(2);
        #else
    phase_active_energy_pulse_end();
        #endif
    #endif

    metrology_init_from_nv_data();
    //temperature_in_celsius = 0; MM put back

    #if defined(RTC_SUPPORT)
    rtc_init();
    #endif
    #if defined(EXTERNAL_EEPROM_SUPPORT)
    external_eeprom_init();
    #endif

    #if defined(IEC62056_21_SUPPORT)
    /* Configure the USART and 38kHz output bits */
    P2SEL |= (BIT5 | BIT4 | BIT3);
    P2DIR |= (BIT4 | BIT5);

    /* Configure the bit that powers the 38kHz receiver */
    P1DIR |= (BIT5);
    P1OUT |= (BIT5);

        #if defined(INFRA_RED_38K_FROM_TIMER_A)
    /* Program TA0 to output a 38kHz clock, based on the core frequency */
    TAR = 0;
    TACCR1 = IR_38K_DIVISOR - 1;        /* Load period register */
    TACCTL1 = OUTMOD_4;                 /* Set outmode 4 for toggle */
    TACTL = TACLR | MC_1 | TASSEL_2;    /* Start TIMER_B up mode, SMCLK as input clock */
        #endif
        #if defined(INFRA_RED_38K_FROM_TIMER_B)
    /* Program TB2 to output a 38kHz clock, based on the core frequency */
    TBR = 0;
    TBCCR1 = IR_38K_DIVISOR - 1;        /* Load period register */
    TBCCR2 = IR_38K_DIVISOR - 10;
    TBCCTL2 = OUTMOD_4;                 /* Set outmode 4 for toggle */
    TBCTL = TBCLR | MC_1 | TBSSEL_2;    /* Start TIMER_B up mode, SMCLK as input clock */
        #endif
    #endif

    __enable_interrupt();

    #if defined(POWER_DOWN_SUPPORT)
    /* Now go to lower power mode, until we know we should do otherwise */
    switch_to_powerfail_mode();
    #else
        #if defined(__MSP430_HAS_SVS__)
    /* Before we go to high speed we need to make sure the supply voltage is 
       adequate. If there is an SVS we can use that. There should be no wait
       at this point, since we should only have been woken up if the supply
       is healthy. However, it seems better to be cautious. */
    SVSCTL |= 0x60;
    /* Wait for adequate voltage to run at full speed */
    while (!(SVSCTL & SVSON))
        /* dummy loop */;
    while ((SVSCTL & SVSOP))
        /* dummy loop */;
    /* The voltage should now be OK to run the CPU at full speed. Now it should
       be OK to use the SVS as a reset source. */
    SVSCTL |= PORON;
        #endif

    /* Take control of the EEPROM signals. */
#if defined(EXTERNAL_EEPROM_SUPPORT)
    enable_eeprom_port();
#endif
        #if defined(__MSP430_HAS_FLLPLUS__)  ||  defined(__MSP430_HAS_FLLPLUS_SMALL__)
    /* Speed up the clock to 8.388608MHz */
    SCFI0 = SCFI0_HIGH;
    SCFQCTL = SCFQCTL_HIGH;
#if 0
    {
        int i;
        for (i = 0xFFFF;  i;  i--);
            _NOP();
        __bis_SR_register(SCG0);
    } 
    SCFQCTL |= SCFQ_M;
    SCFI0 &= ~0x03;
    SCFI1 &= ~0x07;
    SCFI1 += 8;
#endif
    /* There seems no benefit in waiting for the FLL to settle at this point. */
        #endif

    kick_watchdog();
    switch_to_normal_mode();
    #endif
    #if defined(MESH_NET_SUPPORT)
    meshnet_init();
    #endif
    metrology_switch_to_normal_mode();
}
#else
void system_setup(void)
{
    #if !defined(SINGLE_PHASE)
    struct phase_parms_s *phase;
    int j;
    #endif

    #if !defined(SINGLE_PHASE)
    phase = chan;
    for (j = 0;  j < NUM_PHASES;  j++)
    {
    #endif
        /* Prime the DC estimates for quick settling */
    #if defined(NEUTRAL_MONITOR_SUPPORT)
        dc_filter_current_init(phase->metrology.neutral.I_dc_estimate, phase_nv->current.initial_dc_estimate);
    #endif
        dc_filter_current_init(phase->metrology.current.I_dc_estimate, phase_nv->current.initial_dc_estimate);
        dc_filter_voltage_init(phase->metrology.V_dc_estimate[0], phase_nv->initial_v_dc_estimate[0]);
        //phase->metrology.V_dc_estimate[1] = phase_nv->initial_v_limp_dc_estimate;
    #if defined(MAINS_FREQUENCY_SUPPORT)
        phase->metrology.mains_period = ((SAMPLES_PER_10_SECONDS*6554)/MAINS_NOMINAL_FREQUENCY) << 8;
    #endif
    #if !defined(SINGLE_PHASE)
        phase++;
    }
    #endif

    samples_per_second = SAMPLES_PER_10_SECONDS/10;
    #if defined(TEMPERATURE_SUPPORT)
    temperature = 0;
    #endif
}
#endif

#if !defined(ESP_SUPPORT)
int align_hardware_with_calibration_data(void)
{
#if !defined(SINGLE_PHASE)
    int ch;
    static struct phase_parms_s *phase;
    static struct phase_nv_parms_s const *phase_nv;
#endif

    metrology_disable_analog_front_end();
    metrology_init_analog_front_end_normal_mode();

    #if !defined(SINGLE_PHASE)
    for (ch = 0;  ch < NUM_PHASES;  ch++)
    {
        phase = &chan[ch];
        phase_nv = &nv_parms.seg_a.s.chan[ch];
    #endif
    #if !defined(ESP_SUPPORT)
        #if defined(SINGLE_PHASE)
        set_sd_phase_correction(&phase->metrology.current.in_phase_correction, 0, phase_nv->current.phase_correction);
            #if defined(NEUTRAL_MONITOR_SUPPORT)
        set_sd_phase_correction(&phase->metrology.neutral.in_phase_correction, 1, phase_nv->neutral.phase_correction);
            #endif
        #else
        set_sd_phase_correction(&phase->metrology.current.in_phase_correction, ch, phase_nv->current.phase_correction);
        #endif
    #endif
    #if !defined(SINGLE_PHASE)
    }
    #endif
    return 0;
}
#endif

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

/*! \file emeter-structs.h */

#include <stdint.h>
#include <stdlib.h>
#if !defined(__MSP430__)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#if defined(__GNUC__)
#include <signal.h>
#endif
#include <math.h>
#include <io.h>
#include <emeter-toolkit.h>
#define __MAIN_PROGRAM__

#if defined(TRNG_PURITY_TESTS)
#include "fips_tests.h"
#endif

#include "emeter-metrology.h"

#include "emeter-template.h"
#include "emeter-app.h"
#include "emeter-rtc.h"
#include "emeter-basic-display.h"

#if defined(MESH_NET_SUPPORT)
#include "mesh_structure.h"
#endif

#if defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
uint8_t total_active_energy_pulse_remaining_time;
power_t total_active_power;
int32_t total_active_power_counter;
    #if TOTAL_ENERGY_PULSES_PER_KW_HOUR < 1000
int16_t extra_total_active_power_counter;
    #endif
uint32_t total_consumed_active_energy;
#endif

#if defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
uint8_t total_reactive_energy_pulse_remaining_time;
power_t total_reactive_power;
int32_t total_reactive_power_counter;
    #if TOTAL_ENERGY_PULSES_PER_KW_HOUR < 1000
int16_t extra_total_reactive_power_counter;
    #endif
uint32_t total_consumed_reactive_energy;
#endif

#if 0 //CUSTOM_LCD_SUPPORT
/* Keep the toolkit library happy */
const int lcd_cells = LCD_CELLS;
const int lcd_pos_base = LCD_POS_BASE;
const int lcd_pos_step = LCD_POS_STEP;
#endif

#if defined(TEMPERATURE_SUPPORT)
uint16_t temperature_in_celsius;
/* 16 byte salt for DLMS authentication exchanges */
uint8_t salt[16];
int salt_counter = 0;
#endif

/* Meter status flag bits. */
uint16_t meter_status;

/* Current operating mode - normal, limp, power down, etc. */
//MM changing it to an int from uint8_t seems to fix problems.
int operating_mode;

/* Persistence check counters for anti-tamper measures. */
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)
int8_t current_reversed;
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
int8_t current_unbalanced;
#endif
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
int8_t magnetic_interference_persistence;
#endif

/* The main per-phase working parameter structure */
#if !defined(SINGLE_PHASE)
struct phase_parms_s chan[NUM_PHASES];
    #if defined(NEUTRAL_MONITOR_SUPPORT)
struct neutral_parms_s neutral;
    #endif
#else
struct phase_parms_s chan1;
#endif

/* The main per-phase non-volatile parameter structure */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(nv_parms, ".infoA")
#endif
#if !defined(OVERWRITE_INFOMEM)
__infomem__ __no_init const struct info_mem_s nv_parms;
#else
__infomem__ const struct info_mem_s nv_parms =
{
    {
    {
        0xFFFF,
#if defined(SELF_TEST_SUPPORT)
        0xFFFF,
        0xFFFF,
#endif
#if !defined(SINGLE_PHASE)
        {
#endif
            {
                {
#if defined(LIMP_MODE_SUPPORT)
                    {
                        DEFAULT_I_DC_ESTIMATE_A,
                        DEFAULT_I_DC_LIMP_ESTIMATE_A
                    },
#else
                    DEFAULT_I_DC_ESTIMATE_A,
#endif
                    DEFAULT_I_AC_OFFSET_A,
#if defined(PHASE_CORRECTION_SUPPORT)
                    DEFAULT_BASE_PHASE_A_CORRECTION,
#endif
#if defined(IRMS_SUPPORT)
                    DEFAULT_I_RMS_SCALE_FACTOR_A,
    #if defined(LIMP_MODE_SUPPORT)
                    DEFAULT_I_RMS_LIMP_SCALE_FACTOR_A,
    #endif
#endif
                    DEFAULT_P_SCALE_FACTOR_A,
                },
#if defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)
                /* This is for monitoring of the neutral lead in single phase anti-tamper meters */
                {
#if defined(LIMP_MODE_SUPPORT)
                    {
                        DEFAULT_I_DC_ESTIMATE_NEUTRAL,
                        DEFAULT_I_DC_LIMP_ESTIMATE_NEUTRAL
                    },
#else
                    DEFAULT_I_DC_ESTIMATE_NEUTRAL,
#endif
                    DEFAULT_I_AC_OFFSET_NEUTRAL,
    #if defined(PHASE_CORRECTION_SUPPORT)
                    DEFAULT_BASE_NEUTRAL_PHASE_CORRECTION,
    #endif
    #if defined(IRMS_SUPPORT)
                    DEFAULT_I_RMS_SCALE_FACTOR_NEUTRAL,
        #if defined(LIMP_MODE_SUPPORT)
                    DEFAULT_I_RMS_LIMP_SCALE_FACTOR_NEUTRAL,
        #endif
    #endif
                    DEFAULT_P_SCALE_FACTOR_NEUTRAL,
                },
#endif
#if defined(LIMP_MODE_SUPPORT)
                /* Actual estimates */
                {
                    DEFAULT_V_DC_ESTIMATE_A,
                    DEFAULT_V_LIMP_DC_ESTIMATE_A
                },
                /* Lower bounds */
                {
                    DEFAULT_V_DC_ESTIMATE_A - 100,
                    DEFAULT_V_LIMP_DC_ESTIMATE_A - 100
                },
                /* Upper bounds */
                {
                    DEFAULT_V_DC_ESTIMATE_A + 100,
                    DEFAULT_V_LIMP_DC_ESTIMATE_A + 100
                },
#else
                DEFAULT_V_DC_ESTIMATE_A,
#endif
                DEFAULT_V_AC_OFFSET_A,
#if defined(VRMS_SUPPORT)
                DEFAULT_V_RMS_SCALE_FACTOR_A,
                #if  defined (__MSP430F425) && defined(PHASE_CORRECTION_SUPPORT)
                  DEFAULT_VOLTAGE_PRELOAD,  
                #endif 
    #if defined(LIMP_MODE_SUPPORT)
                DEFAULT_V_RMS_LIMP_SCALE_FACTOR_A,
    #endif
#endif
            },
#if !defined(SINGLE_PHASE)
            {
                {
                    DEFAULT_I_DC_ESTIMATE_B,
                    DEFAULT_I_AC_OFFSET_B,
    #if defined(PHASE_CORRECTION_SUPPORT)
                    DEFAULT_BASE_PHASE_B_CORRECTION,
    #endif
    #if defined(IRMS_SUPPORT)
                    DEFAULT_I_RMS_SCALE_FACTOR_B,
    #endif
                    DEFAULT_P_SCALE_FACTOR_B,
                },
                DEFAULT_V_DC_ESTIMATE_B,
                DEFAULT_V_AC_OFFSET_B,
    #if defined(VRMS_SUPPORT)
                DEFAULT_V_RMS_SCALE_FACTOR_B,
    #endif
            },
            {
                {
                    DEFAULT_I_DC_ESTIMATE_C,
                    DEFAULT_I_AC_OFFSET_C,
    #if defined(PHASE_CORRECTION_SUPPORT)
                    DEFAULT_BASE_PHASE_C_CORRECTION,
    #endif
    #if defined(IRMS_SUPPORT)
                    DEFAULT_I_RMS_SCALE_FACTOR_C,
    #endif
                    DEFAULT_P_SCALE_FACTOR_C,
                },
                DEFAULT_V_DC_ESTIMATE_C,
                DEFAULT_V_AC_OFFSET_C,
    #if defined(VRMS_SUPPORT)
                DEFAULT_V_RMS_SCALE_FACTOR_C,
    #endif
            }
        },
#endif
#if !defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)
        {
            DEFAULT_I_DC_ESTIMATE_NEUTRAL,
            DEFAULT_I_AC_OFFSET_NEUTRAL,
    #if defined(PHASE_CORRECTION_SUPPORT)
            DEFAULT_BASE_NEUTRAL_PHASE_CORRECTION,
    #endif
    #if defined(IRMS_SUPPORT)
            DEFAULT_I_RMS_SCALE_FACTOR_NEUTRAL,
    #endif
            0,  /* Dummy value for what is the power scaling factor entry for the other current sensors */
        },
#endif
#if defined(TEMPERATURE_SUPPORT)
        25,
        DEFAULT_TEMPERATURE_OFFSET,
        DEFAULT_TEMPERATURE_SCALING,
#endif
#if 0
#if defined(CORRECTED_RTC_SUPPORT)
        0,
#endif
        {
            0,
            0,
            0,
            0,
            0,
            0
        },
        0,
        "",
        "",
        ""
#endif
    }
    }
};
#endif

#if defined(x__MSP430__)
    #if defined(BASIC_KEYPAD_SUPPORT)  ||  defined(CUSTOM_KEYPAD_SUPPORT)
        #if defined(sense_key_1_up)
static uint8_t debounce_key_1;
static int16_t key_timer_1;
        #endif
        #if defined(sense_key_2_up)
static uint8_t debounce_key_2;
static int16_t key_timer_2;
        #endif
        #if defined(sense_key_3_up)
static uint8_t debounce_key_3;
static int16_t key_timer_3;
        #endif
        #if defined(sense_key_4_up)
static uint8_t debounce_key_4;
static int16_t key_timer_4;
        #endif
uint8_t key_states;
    #endif
#endif

#if !defined(__IAR_SYSTEMS_ICC__)  &&  !defined(__TI_COMPILER_VERSION__)
static __inline__ long int labs(long int __x);
static __inline__ long int labs(long int __x)
{
    return (__x < 0) ? -__x : __x;
}
#endif

#if defined(SELF_TEST_SUPPORT)
int record_meter_failure(int type)
{
    /* The error type should be a value between 0 and 15, specifying the unrecoverable error
       type to be recorded in the failures word in flash. */
    /* Don't worry about the time taken to write to flash - we are recording a serious
       error condition! */
    flash_write_int16((int *) &(nv_parms.seg_a.s.meter_failures), nv_parms.seg_a.s.meter_failures & ~(1 << type));
    flash_secure();
    return TRUE;
}

int record_meter_warning(int type)
{
    /* The warning type should be a value between 0 and 15, specifying the warning type to be
       recorded in the recoverable failures word in flash. */
    /* Don't worry about the time taken to write to flash - we are recording a serious
       problem! */
    flash_write_int16((int *) &(nv_parms.seg_a.s.meter_warnings), nv_parms.seg_a.s.meter_warnings & ~(1 << type));
    flash_secure();
    return TRUE;
}
#endif

#if defined(BATTERY_MONITOR_SUPPORT)
void test_battery(void)
{
    P3DIR |= (BIT1);
    P3OUT &= ~(BIT1);
    battery_countdown = 1000;
}
#endif

#if defined(IO_EXPANDER_SUPPORT)
/* This routine supports the use of a device like the 74HC595 to expand the number of
   output bits available on the lower pin count MSP430s. */
void set_io_expander(int what, int which)
{
    static uint8_t io_state = 0;
    int i;
    int j;

    if (what < 0)
        io_state &= ~which;
    else if (what > 0)
        io_state |= which;
    else
        io_state = which;
    /* Pump the data into the shift register */
    for (i = 8, j = io_state;  i > 0;  i--)
    {
        P1OUT &= ~BIT4;
        if ((j & 0x80))
            P1OUT |= BIT7;
        else
            P1OUT &= ~BIT7;
        P1OUT |= BIT4;
        j <<= 1;
    }
    /* Clock the data into the output register */
    P1OUT &= ~BIT5;
    P1OUT |= BIT5;
}
#endif

/* This keypad debounce code provides for 1 to 4 keys, with debounce + long
   press detect, of debounce + auto-repeat on long press selectable for each
   key. Definitions in emeter.h control this. A long press means >2s.
   Auto-repeat means holding the key >1s starts repeats at 3 per second. */
#if defined(x__MSP430__)  &&  (defined(BASIC_KEYPAD_SUPPORT)  ||  defined(CUSTOM_KEYPAD_SUPPORT))
static __inline__ int keypad_debounce(void)
{
    int kick_foreground;
    
    kick_foreground = FALSE;
    #if defined(sense_key_1_up)
    switch (debounce(&debounce_key_1, sense_key_1_up()))
    {
    case DEBOUNCE_JUST_RELEASED:
        key_timer_1 = 0;
        break;
    case DEBOUNCE_JUST_HIT:
        #if defined(KEY_1_LONG_DOWN)
        /* Start a 2s timer to detect mode change request */
        key_timer_1 = samples_per_second << 1;
        #elif defined(KEY_1_REPEAT_DOWN)
        /* Start an initial 1s timeout for repeats */
        key_timer_1 = samples_per_second;
        #endif
        key_states |= KEY_1_DOWN;
        kick_foreground = TRUE;
        break;
    case DEBOUNCE_HIT:
        if (key_timer_1  &&  --key_timer_1 == 0)
        {
        #if defined(KEY_1_LONG_DOWN)
            key_states |= KEY_1_LONG_DOWN;
        #elif defined(KEY_1_REPEAT_DOWN)
            /* Start a 1/3s timeout for repeats */
            #if defined(LIMP_MODE_SUPPORT)
            if (operating_mode == OPERATING_MODE_LIMP)
                key_timer_1 = 273;
            else
            #endif
                key_timer_1 = 1092;
            key_states |= KEY_1_REPEAT_DOWN;
        #endif
            kick_foreground = TRUE;
        }
        break;
    }
    #endif
    #if defined(sense_key_2_up)
    switch (debounce(&debounce_key_2, sense_key_2_up()))
    {
    case DEBOUNCE_JUST_RELEASED:
        key_timer_2 = 0;
        break;
    case DEBOUNCE_JUST_HIT:
        #if defined(KEY_2_LONG_DOWN)
        /* Start a 2s timer to detect mode change request */
        key_timer_2 = samples_per_second << 1;
        #elif defined(KEY_2_REPEAT_DOWN)
        /* Start an initial 1s timeout for repeats */
        key_timer_2 = samples_per_second;
        #endif
        key_states |= KEY_2_DOWN;
        kick_foreground = TRUE;
        break;
    case DEBOUNCE_HIT:
        if (key_timer_2  &&  --key_timer_2 == 0)
        {
        #if defined(KEY_2_LONG_DOWN)
            key_states |= KEY_2_LONG_DOWN;
        #elif defined(KEY_2_REPEAT_DOWN)
            /* Start a 1/3s timeout for repeats */
            key_timer_2 = 1092;
            key_states |= KEY_2_REPEAT_DOWN;
        #endif
            kick_foreground = TRUE;
        }
        break;
    }
    #endif
    #if defined(sense_key_3_up)
    switch (debounce(&debounce_key_3, sense_key_3_up()))
    {
    case DEBOUNCE_JUST_RELEASED:
        key_timer_3 = 0;
        break;
    case DEBOUNCE_JUST_HIT:
        #if defined(KEY_3_LONG_DOWN)
        /* Start a 2s timer to detect mode change request */
        key_timer_3 = samples_per_second << 1;
        #elif defined(KEY_3_REPEAT_DOWN)
        /* Start an initial 1s timeout for repeats */
        key_timer_3 = samples_per_second;
        #endif
        key_states |= KEY_3_DOWN;
        kick_foreground = TRUE;
        break;
    case DEBOUNCE_HIT:
        if (key_timer_3  &&  --key_timer_3 == 0)
        {
        #if defined(KEY_3_LONG_DOWN)
            key_states |= KEY_3_LONG_DOWN;
        #elif defined(KEY_3_REPEAT_DOWN)
            /* Start a 1/3s timeout for repeats */
            key_timer_3 = 1092;
            key_states |= KEY_3_REPEAT_DOWN;
        #endif
            kick_foreground = TRUE;
        }
        break;
    }
    #endif
    #if defined(sense_key_4_up)
    switch (debounce(&debounce_key_4, sense_key_4_up()))
    {
    case DEBOUNCE_JUST_RELEASED:
        key_timer_4 = 0;
        break;
    case DEBOUNCE_JUST_HIT:
        #if defined(KEY_4_LONG_DOWN)
        /* Start a 2s timer to detect mode change request */
        key_timer_4 = samples_per_second << 1;
        #elif defined(KEY_4_REPEAT_DOWN)
        /* Start an initial 1s timeout for repeats */
        key_timer_4 = samples_per_second;
        #endif
        key_states |= KEY_4_DOWN;
        kick_foreground = TRUE;
        break;
    case DEBOUNCE_HIT:
        if (key_timer_4  &&  --key_timer_4 == 0)
        {
        #if defined(KEY_4_LONG_DOWN)
            key_states |= KEY_3_LONG_DOWN;
        #elif defined(KEY_4_REPEAT_DOWN)
            /* Start a 1/3s timeout for repeats */
            key_timer_4 = 1092;
            key_states |= KEY_4_REPEAT_DOWN;
        #endif
            kick_foreground = TRUE;
        }
        break;
    }
    #endif
    return  kick_foreground;
}
#endif 

#if defined(__AQCOMPILER__)  ||  defined(__IAR_SYSTEMS_ICC__)  ||  defined(__TI_COMPILER_VERSION__)
void main(void)
#else
int main(int argc, char *argv[])
#endif
{
#if !defined(SINGLE_PHASE)
    int ch;
    static struct phase_parms_s *phase;
    static struct phase_nv_parms_s const *phase_nv;
#endif
#if defined(TEMPERATURE_SUPPORT)
    uint16_t randy;
#endif
#if defined(TRNG_PURITY_TESTS)
    int fips_result;
#endif
    static int32_t x;

#if !defined(__MSP430__)
    if (start_host_environment(argc, argv) < 0)
        exit(2);
#endif
    system_setup();
#if defined(TRNG_PURITY_TESTS)
    fips_init();
    fips_result = -1;
#endif

#if defined(ESP_SUPPORT)
    esp_init();
    esp_start_measurement();
#endif

#if defined(MULTI_RATE_SUPPORT)
    tariff_initialise();
#endif
    for (;;)
    {
        kick_watchdog();
#if defined(TRNG_PURITY_TESTS)
        /* Perform FIPS testing of the rtue random number generator */
        if (trng(&randy) == 0)
        {
            if ((fips_result = fips_test(randy)) != -1)
            {
                for (;;);
            }
        }
#else
//        if (trng(&randy) == 0)
//        {
//            /* Roll around the 16 byte salt buffer, updating it little by little */
//            salt[salt_counter++] = randy >> 8;
//            salt[salt_counter++] = randy;
//            if (salt_counter >= 16)
//                salt_counter = 0;
//        }
#endif
#if !defined(__MSP430__)
        /* In the host environment we need to simulate interrupts here */
        adc_interrupt();
#endif
#if !defined(SINGLE_PHASE)
        phase = chan;
        phase_nv = nv_parms.seg_a.s.chan;

        for (ch = 0;  ch < NUM_PHASES;  ch++)
        {
#endif
            /* Unless we are in normal operating mode, we should wait to be
               woken by a significant event from the interrupt routines. */
#if 0 //defined(__MSP430__)
            if (operating_mode != OPERATING_MODE_NORMAL)
                _BIS_SR(LPM0_bits);
#endif
#if defined(POWER_DOWN_SUPPORT)
            if (operating_mode == OPERATING_MODE_POWERFAIL)
                switch_to_powerfail_mode();
#endif
#if defined(LIMP_MODE_SUPPORT)  &&  defined(IEC1107_SUPPORT)
            if (nv_parms.seg_a.s.meter_uncalibrated)
                enable_ir_receiver();
#endif
            if ((phase->status & NEW_LOG))
            {
                /* The background activity has informed us that it is time to
                   perform a block processing operation. */
                phase->status &= ~NEW_LOG;
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
                if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD))
                {
                    /* The meter is suffering magnetic tampering, so continuously
                       charge for a great deal of electricity. */
                    x = phase->readings.V_rms*MAGNETIC_INTERFERENCE_CURRENT/(10*100);
                }
                else
#endif
                if (operating_mode == OPERATING_MODE_NORMAL)
                {
                    /* We can only do real power assessment in full operating mode */
#if defined(SINGLE_PHASE)
                    x = calculate_readings();
#else
                    x = calculate_readings(phase, phase_nv, ch);
#endif
                }
#if defined(LIMP_MODE_SUPPORT)
                else if (operating_mode == OPERATING_MODE_LIMP)
                {
#if defined(SINGLE_PHASE)
                    x = calculate_limp_readings();
#else
                    x = calculate_limp_readings(phase, phase_nv, ch);
#endif
                }
#endif
                if (labs(x) < RESIDUAL_POWER_CUTOFF  ||  (phase->status & V_OVERRANGE))
                {
                    x = 0;
#if defined(IRMS_SUPPORT)
                    /* Avoid displaying a residual current, which is nothing more
                       than integrated noise. */
                    phase->readings.I_rms = 0;
#endif
                    /* Turn off the LEDs, regardless of the internal state of the
                       reverse and imbalance assessments. */
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)
                    meter_status &= ~STATUS_REVERSED;
                    clr_reverse_current_indicator();
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
                    meter_status &= ~STATUS_EARTHED;
                    clr_earthed_indicator();
#endif
                }
                else
                {
                    if (operating_mode == OPERATING_MODE_NORMAL)
                    {
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(PHASE_REVERSED_IS_TAMPERING)
                        if ((phase->status & PHASE_REVERSED))
                        {
                            meter_status |= STATUS_REVERSED;
                            set_reverse_current_indicator();
                        }
                        else
                        {
                            meter_status &= ~STATUS_REVERSED;
                            clr_reverse_current_indicator();
                        }
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
                        if ((phase->status & PHASE_UNBALANCED))
                        {
                            meter_status |= STATUS_EARTHED;
                            set_earthed_indicator();
                        }
                        else
                        {
                            meter_status &= ~STATUS_EARTHED;
                            clr_earthed_indicator();
                        }
#endif
                    }
#if defined(LIMP_MODE_SUPPORT)
                    else
                    {
    #if defined(PHASE_REVERSED_DETECTION_SUPPORT)
                        /* We cannot tell forward from reverse current in limp mode,
                           so just say it is not reversed. */
                        meter_status &= ~STATUS_REVERSED;
                        clr_reverse_current_indicator();
    #endif
    #if defined(POWER_BALANCE_DETECTION_SUPPORT)
                        /* We are definitely in the unbalanced state, but only set
                           the indicator if we have persistence checked, and the current
                           is sufficient to sustain operation. */
                        if ((phase->status & PHASE_UNBALANCED)  &&  phase->readings.I_rms >= LIMP_MODE_MINIMUM_CURRENT)
                        {
                            meter_status |= STATUS_EARTHED;
                            set_earthed_indicator();
                        }
                        else
                        {
                            meter_status &= ~STATUS_EARTHED;
                            clr_earthed_indicator();
                        }
    #endif
                        /* Only run the IR interface if we are sure there is enough power from the
                           supply to support the additional current drain. If we have not yet been
                           calibrated we had better keep the IR port running so we can complete the
                           calibration. */
#if defined(LIMP_MODE_SUPPORT)  &&  defined(IEC1107_SUPPORT)
                        if (phase->I_rms >= LIMP_MODE_MINIMUM_CURRENT_FOR_IR
                            ||
                            nv_parms.seg_a.s.meter_uncalibrated)
                        {
                            enable_ir_receiver();
                        }
                        else
                        {
                            disable_ir_receiver();
                        }
#endif
                    }
#endif
                }
                //x /= 10;
#if defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
    #if defined(SINGLE_PHASE)
                total_active_power = x;
    #else
                total_active_power = chan[0].readings.active_power
                                   + chan[1].readings.active_power
                                   + chan[2].readings.active_power;
    #endif
#endif
#if defined(PER_PHASE_ACTIVE_ENERGY_SUPPORT)
                phase->active_energy_counter += x*phase->metrology.dot_prod_logged.sample_count;
                while (phase->active_energy_counter > ENERGY_WATT_HOUR_THRESHOLD)
                {
                    phase->active_energy_counter -= ENERGY_WATT_HOUR_THRESHOLD;
                    phase->consumed_active_energy++;
                }
#endif
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
    #if !defined(SINGLE_PHASE)
                if (ch == 0)
    #endif
                {
                    if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD))
                    {
                        if (phase->sample_count_logged/magnetic_sensor_count_logged < MAGNETIC_INTERFERENCE_SAMPLE_RATIO)
                        {
                            if (--magnetic_interference_persistence <= -MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK)
                            {
                                meter_status &= ~STATUS_HIGH_MAGNETIC_FIELD;
                                magnetic_interference_persistence = 0;
                            }
                        }
                        else
                        {
                            magnetic_interference_persistence = 0;
                        }
                    }
                    else
                    {
                        if (phase->sample_count_logged/magnetic_sensor_count_logged >= MAGNETIC_INTERFERENCE_SAMPLE_RATIO)
                        {
                            if (++magnetic_interference_persistence >= MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK)
                            {
                                meter_status |= STATUS_HIGH_MAGNETIC_FIELD;
                                magnetic_interference_persistence = 0;
                            }
                        }
                        else
                        {
                            magnetic_interference_persistence = 0;
                        }
                    }
                }
#endif
            }
#if defined(LIMP_MODE_SUPPORT)
            metrology_limp_normal_detection();
#endif

#if !defined(SINGLE_PHASE)
            phase++;
            phase_nv++;
        }
#endif
#if !defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)  &&  defined(IRMS_SUPPORT)
        if ((neutral.status & NEW_LOG))
        {
            /* The background activity has informed us that it is time to
               perform a block processing operation. */
            neutral.status &= ~NEW_LOG;
            calculate_neutral_readings();
        }
#endif

#if defined(MULTI_RATE_SUPPORT)
        tariff_management();
#endif

        /* Do display and other housekeeping here */
        if ((meter_status & TICKER))
        {
            /* Two seconds have passed */
            /* We have a 2 second tick */
            meter_status &= ~TICKER;
#if defined(__MSP430__)  &&  defined(BASIC_LCD_SUPPORT)
            /* Update the display, cycling through the phases */
            update_display();
#endif
            custom_2second_handler();
#if (defined(RTC_SUPPORT)  ||  defined(CUSTOM_RTC_SUPPORT))  &&  defined(CORRECTED_RTC_SUPPORT)
            correct_rtc();
#endif
        }
        custom_keypad_handler();
        custom_mainloop_handler();
#if defined(MESH_NET_SUPPORT)
        if (rf_service)
        {
            rf_service = 0;
            rf_tick_service();
        }
#endif
    }
#if !defined(__IAR_SYSTEMS_ICC__)  &&  !defined(__TI_COMPILER_VERSION__)
    return  0;
#endif
}

#if defined(PRECALCULATED_PARAMETER_SUPPORT)
int32_t current_consumed_active_energy(int ph)
{
#if defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
    if (ph == FAKE_PHASE_TOTAL)
        return total_consumed_active_energy;
#endif
#if defined(PER_PHASE_ACTIVE_ENERGY_SUPPORT)
#if defined(SINGLE_PHASE)
    return chan1.consumed_active_energy;
#else
    return chan[ph].consumed_active_energy;
#endif
#else
    return 0;
#endif
}

power_t current_active_power(int ph)
{
    if (ph == FAKE_PHASE_TOTAL)
    #if defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
        return total_active_power;
    #else
        return 0;
    #endif
#if defined(SINGLE_PHASE)
    return chan1.readings.active_power;
#else
    return chan[ph].readings.active_power;
#endif
}

#if defined(REACTIVE_POWER_SUPPORT)
int32_t current_consumed_reactive_energy(int ph)
{
#if defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
    if (ph == FAKE_PHASE_TOTAL)
        return total_consumed_reactive_energy;
#endif
#if defined(PER_PHASE_REACTIVE_ENERGY_SUPPORT)
#if defined(SINGLE_PHASE)
    return chan1.consumed_reactive_energy;
#else
    return chan[ph].consumed_reactive_energy;
#endif
#else
    return 0;
#endif
}

power_t current_reactive_power(int ph)
{
    if (ph == FAKE_PHASE_TOTAL)
        return total_reactive_power;
#if defined(SINGLE_PHASE)
    return chan1.readings.reactive_power;
#else
    return chan[ph].readings.reactive_power;
#endif
}
#endif

#if defined(APPARENT_POWER_SUPPORT)
power_t current_apparent_power(int ph)
{
#if defined(SINGLE_PHASE)
    return chan1.readings.apparent_power;
#else
    return chan[ph].readings.apparent_power;
#endif
}
#endif

#if defined(FUNDAMENTAL_ACTIVE_POWER_SUPPORT)
power_t current_fundamental_active_power(int ph)
{
#if defined(SINGLE_PHASE)
    return chan1.readings.fundamental_active_power;
#else
    return chan[ph].readings.fundamental_active_power;
#endif
}
#endif

#if defined(FUNDAMENTAL_REACTIVE_POWER_SUPPORT)
power_t current_fundamental_reactive_power(int ph)
{
#if defined(SINGLE_PHASE)
    return chan1.readings.fundamental_reactive_power;
#else
    return chan[ph].readings.fundamental_reactive_power;
#endif
}
#endif

#if defined(POWER_FACTOR_SUPPORT)
int32_t current_power_factor(int ph)
{
    return chan[ph].readings.power_factor;
}
#endif

#if defined(VRMS_SUPPORT)
rms_voltage_t current_rms_voltage(int ph)
{
    int32_t x;

#if defined(SINGLE_PHASE)
    if (chan1.readings.V_rms == 0xFFFF)
        x = -1;
    else
        x = chan1.readings.V_rms;
#else
    if (chan[ph].readings.V_rms == 0xFFFF)
        x = -1;
    else
        x = chan[ph].readings.V_rms;
#endif
    return x;
}
#endif

#if defined(IRMS_SUPPORT)
rms_current_t current_rms_current(int ph)
{
    rms_current_t x;

#if !defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)
    if (ph == 3)
        x = neutral.readings.I_rms;
    else
#endif
#if defined(SINGLE_PHASE)
        x = chan1.readings.I_rms;
#else
        x = chan[ph].readings.I_rms;
#endif
    return x;
}
#endif

#if defined(MAINS_FREQUENCY_SUPPORT)
int32_t current_mains_frequency(int ph)
{
#if defined(SINGLE_PHASE)
     return chan1.readings.frequency;
#else
     return chan[ph].readings.frequency;
#endif
}
#endif
#else
int32_t current_consumed_active_energy(int ph)
{
    retirm chan[ph].consumed_active_energy;
}

int32_t current_active_power(int ph)
{
    if (ph == FAKE_PHASE_TOTAL)
        return total_active_power;
    return active_power(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}

#if defined(REACTIVE_POWER_SUPPORT)
int32_t current_consumed_reactive_energy(int ph)
{
    return chan[ph].consumed_active_energy;
}

power_t current_reactive_power(int ph)
{
    if (ph == FAKE_PHASE_TOTAL)
        return total_reactive_power;
    return reactive_power(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(APPARENT_POWER_SUPPORT)
power_t current_apparent_power(int ph)
{
    return apparent_power(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(FUNDAMENTAL_ACTIVE_POWER_SUPPORT)
power_t current_fundamental_active_power(int ph)
{
    //if (ph == FAKE_PHASE_TOTAL)
    //    return total_fundamental_active_power;
    return fundamental_active_power(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(FUNDAMENTAL_REACTIVE_POWER_SUPPORT)
power_t current_fundamental_reactive_power(int ph)
{
    //if (ph == FAKE_PHASE_TOTAL)
    //    return total_fundamental_reactive_power;
    return fundamental_reactive_power(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(POWER_FACTOR_SUPPORT)
int32_t current_power_factor(int ph)
{
    return power_factor(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(VRMS_SUPPORT)
rms_voltage_t current_rms_voltage(int ph)
{
    return voltage(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(IRMS_SUPPORT)
rms_current_t current_rms_current(int ph)
{
    return current(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif

#if defined(MAINS_FREQUENCY_SUPPORT)
int32_t current_mains_frequency(int ph)
{
    return frequency(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
#endif
#endif

void switch_to_normal_mode(void)
{
    set_normal_indicator();
    /* The LCD might need to be revived */
#if defined(__MSP430__)  &&  defined(BASIC_LCD_SUPPORT)
    LCDawaken();
#else
    /* Tell the world we are ready to start */
#endif
#if defined(IEC1107_SUPPORT)
    enable_ir_receiver();
#endif
}

void switch_to_limp_mode(void)
{
    clr_normal_indicator();
    clr_reverse_current_indicator();
#if defined(IEC1107_SUPPORT)
    disable_ir_receiver();
#endif
}

void switch_to_powerfail_mode(void)
{
}

//MM changed so compatible with different EVMs.
#if defined(PER_PHASE_ACTIVE_ENERGY_SUPPORT)
   // #if defined(SINGLE_PHASE)
void phase_active_energy_pulse_start(void)
{
   P1SEL = BIT2;
  P1DIR |= BIT2;
  P1DIR = 0x01;

P1OUT = 0x01;
    //P1OUT &= ~BIT6;
 // #ifdef __MSP430F6736
      P1OUT &= BIT2; 
 // #elif defined( __MSP430AFE253)
      // P1OUT &= ~BIT1;
  //#endif 
}

void phase_active_energy_pulse_end(void)
{
   P1SEL = BIT2;
  P1DIR |= BIT2;
  P1DIR = 0x01;

P1OUT = 0x01;
   // P1OUT |= BIT6;
   //#ifdef __MSP430F425
   // P1OUT |= BIT6;
  // #elif defined(__MSP430AFE253) 
   P1OUT |=  ~ BIT2; 
  // #endif
}
   // #else
//void phase_active_energy_pulse_start(int ph)
//{
//    switch (ph)
//    {
//    case 0:
//        P5OUT &= ~BIT5;
//        break;
//    case 1:
//        P5OUT &= ~BIT6;
//        break;
//    case 2:
//        P5OUT &= ~BIT7;
//        break;
//    }
// #ifdef __MSP430F6736
 // switch (ph)
    //{
   // case 0:
  //      P8OUT &= ~BIT6;
   //     break;
  //  case 1:
     //   P5OUT &= ~BIT5;
     //   break;
  //  case 2:
   //     P5OUT &= ~BIT6;
   //     break;
  //  }
//  #endif
    
//}

//void phase_active_energy_pulse_end(int ph)
//{
//    switch (ph)
//    {
//    case 0:
//        P5OUT |= BIT5;
//        break;
//    case 1:
//        P5OUT |= BIT6;
//        break;
//    case 2:
//        P5OUT |= BIT7;
//        break;
//    }
  
 //  #ifdef __MSP430F6736
 // switch (ph)
  //  {
  //  case 0:
   //     P8OUT |= BIT6;
    //    break;
  //  case 1:
    //    P5OUT |= BIT5;
     //   break;
  //  case 2:
   //     P5OUT |= BIT6;
  //      break;
 //   }
 // #endif
//}
    //#endif
#endif

//#if defined(PER_PHASE_REACTIVE_ENERGY_SUPPORT)
  //  #if defined(SINGLE_PHASE)
//void phase_reactive_energy_pulse_start(void)
//{
 // P1DIR = 0x01;

//P1OUT = 0x01;
 //   #ifdef __MSP430F6736
  //  P1OUT |= BIT7;
  //#elif defined(__MSP430AFE253) 
  //  P1OUT &= ~BIT0;
 // #endif
//}

//void phase_reactive_energy_pulse_end(void)
//{
 // P1DIR = 0x01;

//P1OUT = 0x01;
 //  #ifdef __MSP430F6736
  //  P1OUT &= ~BIT7;
  //#elif defined(__MSP430AFE253)  
  //  P1OUT |= BIT0;
 // #endif
//}
    //#else
void phase_reactive_energy_pulse_start(int j)
{
}

void phase_reactive_energy_pulse_end(int j)
{
}
    //#endif
//#endif

#if defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
void total_active_energy_pulse_start(void)
{
    P1SEL = BIT2;
  P1DIR |= BIT2;

P1OUT = 0x01;
     #ifdef __MSP430F425
      P1OUT |= BIT2;
   //#elif defined(__MSP430AFE253)
      //P1OUT &= ~BIT1;
#endif   
}

void total_active_energy_pulse_end(void)
{
   // P1DIR = 0x01;

//P1OUT = 0x01;
   // #ifdef __MSP430F425
   // P1OUT &= ~BIT2;
  //#elif defined(__MSP430AFE253) 
    //P1OUT |= BIT1;
   //#endif
}
#endif

#if defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
void total_reactive_energy_pulse_start(void)
{ P1SEL = BIT2;
  P1DIR |= BIT2;
   P1OUT |= BIT2;
    //#ifdef __MSP430F6736
  //  P1OUT |= BIT0;
  //#elif defined(__MSP430AFE253) 
   // P1OUT &= ~BIT0;
  #endif
}

void total_reactive_energy_pulse_end(void)
{ P1SEL = BIT2;
  P1DIR |= BIT2;
    //#ifdef __MSP430F6736
  //  P1OUT &= ~BIT0;
 // #elif defined(__MSP430AFE253)  
   // P1OUT |= BIT0;
  //#endif
}
//#endif

  • Hello Arfaoui,

    The best way to debug this would be to attach the debugger when running your code and having a break point to where you are supposed to pulse the LED. From here, you can look at the register view to make sure you have your pin setup correctly, and you are changing the output register. Beyond this, you will need to double check your physical connection to make sure the GPIO you are toggling is connected toy our LED.
  • hi

    i make the change in GPIO P1.0 to  GPIO p1.2 To toggle the led but nothing change the led stay off.

    if you have an idea to change the library slac488 for using in the msp430f425 to toggle the led pulse in GPIO P1.2 help me please.

  • Hello arfoui,

    Have you tried debugging via the method I mentioned earlier? Also, you say you are moving the LED from P1.0 to P1.2 from chip to chip. Is the LED been physically moved on the board to accommodate this? The pinout between these two devices are the same, and the same code will work between the two for they are different memory spins of each other. Although there maybe some errata difference between the chips as you have indicated you are using the newer F427a version and an older F425 chip. The ending "a" here usually indicates a major revision of the part with the non-a versions are not recommended for new designs.
  • hello 

    Now i have a problem in the size memory .

    Watch I use the TI slac488 library msp430f4794 .MY MSP is MSP430F425 when i downlood the program:
    Error [e16]: Segment DATA16_Z (size: 0x2dc align: 0x1) is too long for segment definition. At least 0xdc more bytes needed. The Problem
    "-Z (DATA) DATA16_I, DATA16_Z, DATA16_N, TLS16_I = 0200-03FF", where at the time of placement the available memory ranges were "CODE: 200-3ff"
        Reserved ranges relevant to this placement:
        200-3ff DATA16_I
    If you have an idea if this program can work with MSP430F425 or there is another code compatible with MSP430F425 which allows the measurement of single-phase energy !!!
    There is a solution to avoid the mistake of memory space !!
    help please.

  • Hello,

    It seems you have also posted with the following thread with this same question. e2e.ti.com/.../576209

    Your question will be answered in that thread. For future reference, please do not double post questions like this.

**Attention** This is a public forum