Exemplo n.º 1
0
void SysTick_Handler(void) {
  tick += 1;
  kick_watchdog();
  update_pwm();
  coilBuzzer();
  toggle_dripper();
}
Exemplo n.º 2
0
void namco_c117_device::register_w(int whichcpu, offs_t offset, uint8_t data)
{
	int reg = (offset >> 9) & 0xf;
	bool unknown_reg = false;

	switch (reg)
	{
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
			bankswitch(whichcpu, reg, offset & 1, data);
			break;
		case 8:  // F000 - SUBRES (halt/reset everything but main CPU)
			if (whichcpu == 0)
			{
				m_subres = data & 1;
				m_subres_cb(m_subres ? CLEAR_LINE : ASSERT_LINE);
			}
			else
				unknown_reg = true;
			break;
		case 9:  // F200 - kick watchdog
			kick_watchdog(whichcpu);
			break;
//      case 10: // F400 - unknown but used
//          break;
		case 11: // F600 - IRQ ack
			m_cpuexec[whichcpu]->set_input_line(M6809_IRQ_LINE, CLEAR_LINE);
			break;
		case 12: // F800 - FIRQ ack
			m_cpuexec[whichcpu]->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE);
			break;
		case 13: // FA00 - assert FIRQ on sub CPU
			if (whichcpu == 0)
				m_cpuexec[1]->set_input_line(M6809_FIRQ_LINE, ASSERT_LINE);
			else
				unknown_reg = true;
			break;
		case 14: // FC00 - set initial ROM bank for sub CPU
			if (whichcpu == 0)
			{
				m_offsets[1][7] = 0x600000 | (data * 0x2000);
				m_cpudirect[1]->force_update();
			}
			else
				unknown_reg = true;
			break;
		default:
			unknown_reg = true;
	}
	if (unknown_reg)
		logerror("'%s' writing to unknown CUS117 register %04X = %02X\n", (whichcpu ? m_subcpu_tag : m_maincpu_tag), offset, data);
}
uint8_t WaiteForState( uint8_t bState, uint32_t ulTimeOut)
{
   kick_watchdog();
   SetTimeoutValue( ulTimeOut );
   while ( GetTimeoutValue() )
   {
      if (mbRadioStatus == bState)
         return 0;                                    // 0 = alles ok - gewünschter State ist erreicht
   }
   return 1;                                          // 1 = Timeout abgelaufen
}
Exemplo n.º 4
0
void external_eeprom_init(void)
{
#if 0
    CACTL1 = CAREF_2 | CAEX | CAON;
    CACTL2 = P2CA1 | CAF;
    P1SEL |= BIT7;
    CAPD |= BIT7;

    while ((CACTL2 & CAOUT))
        kick_watchdog();
#endif

    iicEEPROM_init();
    external_eeprom_startup();
}
Exemplo n.º 5
0
static void *
watchdog_handler() {

  /* Start watchdog in manual mode */
  start_watchdog(0);

  /* Set watchdog to persistent mode so timer expiry will happen independent
   * of this process's liveliness.
   */
  set_persistent_watchdog(WATCHDOG_SET_PERSISTENT);

  while(1) {

    sleep(5);

    /*
     * Restart the watchdog countdown. If this process is terminated,
     * the persistent watchdog setting will cause the system to reboot after
     * the watchdog timeout.
     */
    kick_watchdog();
  }
}
Exemplo n.º 6
0
static int external_eeprom_startup(void)
{
#if defined(SELF_TEST_SUPPORT)
    int error;
    int i;
#endif
#if 0
    int j;
    int k;
    uint16_t buf[64];
#endif

#if 0
    while ((CACTL2 & CAOUT))
        kick_watchdog();
#endif

#if 0
    /* EEPROM interface test */
    /* Go to 8MHz */
    SCFI0 = FN_3 | FLLD_4;
    SCFQCTL = 64 - 1;

    WDTCTL = (WDTCTL & 0xFF) | WDTPW | WDTHOLD;
    for (k = 0;  k < 32767;  k++)
    {
        LCDdec16(k, FIRST_POSITION + 1, NUMBER_WIDTH - 2, 0);
        for (j = 0;  j < 8192;  j += 128)
        {
            for (i = 0;  i < 64;  i++)
                buf[i] = j + (i << 1);
            if (!iicEEPROM_write(j, buf, 128))
            {
                LCDdec16(9991, FIRST_POSITION + 1, NUMBER_WIDTH - 2, 0);
                for (;;);
            }
        }
        for (j = 0;  j < 8192;  j += 128)
        {
            if (!iicEEPROM_read(j, buf, 128))
            {
                LCDdec16(9992, FIRST_POSITION + 1, NUMBER_WIDTH - 2, 0);
                for (;;);
            }
            for (i = 0;  i < 64;  i++)
            {
                if (buf[i] != j + (i << 1))
                {
                    LCDdec16(9993, FIRST_POSITION + 1, NUMBER_WIDTH - 2, 0);
                    for (;;);
                }
            }
        }
    }
#endif

#if defined(SELF_TEST_SUPPORT)
    error = 0;
    /* Allow several retries of reading the EEPROM */
    for (i = 0;  i < 5;  i++)
    {
    }
    if (error)
    {
        record_meter_failure(METER_FAILURE_EEPROM_COMMUNICATION);
        return TRUE;
    }
    if (error)
        record_meter_failure(METER_FAILURE_EEPROM_CONTENTS);
#endif
    return TRUE;
}
Exemplo n.º 7
0
int main(int argc, char **argv) {
  /* Sensor values */

#if defined(CONFIG_WEDGE)
  int intake_temp;
  int exhaust_temp;
  int switch_temp;
  int userver_temp;
#else
  float intake_temp;
  float exhaust_temp;
  float userver_temp;
#endif

  int fan_speed = fan_high;
  int bad_reads = 0;
  int fan_failure = 0;
  int fan_speed_changes = 0;
  int old_speed;

  int fan_bad[FANS];
  int fan;

  unsigned log_count = 0; // How many times have we logged our temps?
  int opt;
  int prev_fans_bad = 0;

  struct sigaction sa;

  sa.sa_handler = fand_interrupt;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);

  sigaction(SIGTERM, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);
  sigaction(SIGUSR1, &sa, NULL);

  // Start writing to syslog as early as possible for diag purposes.

  openlog("fand", LOG_CONS, LOG_DAEMON);

#if defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
  if (is_two_fan_board(false)) {
    /* Alternate, two fan configuration */
    total_fans = 2;
    fan_offset = 2; /* fan 3 is the first */

    fan_low = SIXPACK_FAN_LOW;
    fan_medium = SIXPACK_FAN_MEDIUM;
    fan_high = SIXPACK_FAN_HIGH;
    fan_max = SIXPACK_FAN_MAX;
    fan_speed = fan_high;
  }
#endif

  while ((opt = getopt(argc, argv, "l:m:h:b:t:r:v")) != -1) {
    switch (opt) {
    case 'l':
      fan_low = atoi(optarg);
      break;
    case 'm':
      fan_medium = atoi(optarg);
      break;
    case 'h':
      fan_high = atoi(optarg);
      break;
    case 'b':
      temp_bottom = INTERNAL_TEMPS(atoi(optarg));
      break;
    case 't':
      temp_top = INTERNAL_TEMPS(atoi(optarg));
      break;
    case 'r':
      report_temp = atoi(optarg);
      break;
    case 'v':
      verbose = true;
      break;
    default:
      usage();
      break;
    }
  }

  if (optind > argc) {
    usage();
  }

  if (temp_bottom > temp_top) {
    fprintf(stderr,
            "Should temp-bottom (%d) be higher than "
            "temp-top (%d)?  Starting anyway.\n",
            EXTERNAL_TEMPS(temp_bottom),
            EXTERNAL_TEMPS(temp_top));
  }

  if (fan_low > fan_medium || fan_low > fan_high || fan_medium > fan_high) {
    fprintf(stderr,
            "fan RPMs not strictly increasing "
            "-- %d, %d, %d, starting anyway\n",
            fan_low,
            fan_medium,
            fan_high);
  }

  daemon(1, 0);

  if (verbose) {
    syslog(LOG_DEBUG, "Starting up;  system should have %d fans.",
           total_fans);
  }

  for (fan = 0; fan < total_fans; fan++) {
    fan_bad[fan] = 0;
    write_fan_speed(fan + fan_offset, fan_speed);
    write_fan_led(fan + fan_offset, FAN_LED_BLUE);
  }

#if defined(CONFIG_YOSEMITE)
  /* Ensure that we can read from sensors before proceeding. */

  int found = 0;
  userver_temp = 100;
  while (!found) {
    for (int node = 1; node <= TOTAL_1S_SERVERS && !found; node++) {
      if (!yosemite_sensor_read(node, BIC_SENSOR_SOC_THERM_MARGIN,
                               &userver_temp) &&
          userver_temp < 0) {
        syslog(LOG_DEBUG, "SOC_THERM_MARGIN first valid read of %f.",
               userver_temp);
        found = 1;
      }
      sleep(5);
    }
    // XXX:  Will it ever be a problem that we don't exit this until
    //       we see a valid value?
  }
#endif

  /* Start watchdog in manual mode */
  start_watchdog(0);

  /* Set watchdog to persistent mode so timer expiry will happen independent
   * of this process's liveliness. */
  set_persistent_watchdog(WATCHDOG_SET_PERSISTENT);

  sleep(5);  /* Give the fans time to come up to speed */

  while (1) {
    int max_temp;
    old_speed = fan_speed;

    /* Read sensors */

#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
    read_temp(INTAKE_TEMP_DEVICE, &intake_temp);
    read_temp(EXHAUST_TEMP_DEVICE, &exhaust_temp);
    read_temp(CHIP_TEMP_DEVICE, &switch_temp);
    read_temp(USERVER_TEMP_DEVICE, &userver_temp);

    /*
     * uServer can be powered down, but all of the rest of the sensors
     * should be readable at any time.
     */

    if ((intake_temp == BAD_TEMP || exhaust_temp == BAD_TEMP ||
         switch_temp == BAD_TEMP)) {
      bad_reads++;
    }
#else
    intake_temp = exhaust_temp = userver_temp = BAD_TEMP;
    if (yosemite_sensor_read(FRU_SPB, SP_SENSOR_INLET_TEMP, &intake_temp) ||
        yosemite_sensor_read(FRU_SPB, SP_SENSOR_OUTLET_TEMP, &exhaust_temp))
      bad_reads++;

    /*
     * There are a number of 1S servers;  any or all of them
     * could be powered off and returning no values.  Ignore these
     * invalid values.
     */
    for (int node = 1; node <= TOTAL_1S_SERVERS; node++) {
      float new_temp;
      if (!yosemite_sensor_read(node, BIC_SENSOR_SOC_THERM_MARGIN,
			        &new_temp)) {
        if (userver_temp < new_temp) {
          userver_temp = new_temp;
        }
      }

      // Since the yosemite_sensor_read() times out after 8secs, keep WDT from expiring
      kick_watchdog();
    }
#endif

    if (bad_reads > BAD_READ_THRESHOLD) {
      server_shutdown("Some sensors couldn't be read");
    }

    if (log_count++ % report_temp == 0) {
      syslog(LOG_DEBUG,
#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
             "Temp intake %d, t2 %d, "
             " userver %d, exhaust %d, "
             "fan speed %d, speed changes %d",
#else
             "Temp intake %f, max server %f, exhaust %f, "
             "fan speed %d, speed changes %d",
#endif
             intake_temp,
#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
             switch_temp,
#endif
             userver_temp,
             exhaust_temp,
             fan_speed,
             fan_speed_changes);
    }

    /* Protection heuristics */

    if (intake_temp > INTAKE_LIMIT) {
      server_shutdown("Intake temp limit reached");
    }

#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
    if (switch_temp > SWITCH_LIMIT) {
      server_shutdown("T2 temp limit reached");
    }
#endif

    if (userver_temp + USERVER_TEMP_FUDGE > USERVER_LIMIT) {
      server_shutdown("uServer temp limit reached");
    }

    /*
     * Calculate change needed -- we should eventually
     * do something more sophisticated, like PID.
     *
     * We should use the intake temperature to adjust this
     * as well.
     */

#if defined(CONFIG_YOSEMITE)
    /* Use tables to lookup the new fan speed for Yosemite. */

    int intake_speed = temp_to_fan_speed(intake_temp, intake_map,
                                         INTAKE_MAP_SIZE);
    int cpu_speed = temp_to_fan_speed(userver_temp, cpu_map, CPU_MAP_SIZE);

    if (fan_speed == fan_max && fan_failure != 0) {
      /* Don't change a thing */
    } else if (intake_speed > cpu_speed) {
      fan_speed = intake_speed;
    } else {
      fan_speed = cpu_speed;
    }
#else
    /* Other systems use a simpler built-in table to determine fan speed. */

    if (switch_temp > userver_temp + USERVER_TEMP_FUDGE) {
      max_temp = switch_temp;
    } else {
      max_temp = userver_temp + USERVER_TEMP_FUDGE;
    }

    /*
     * If recovering from a fan problem, spin down fans gradually in case
     * temperatures are still high. Gradual spin down also reduces wear on
     * the fans.
     */
    if (fan_speed == fan_max) {
      if (fan_failure == 0) {
        fan_speed = fan_high;
      }
    } else if (fan_speed == fan_high) {
      if (max_temp + COOLDOWN_SLOP < temp_top) {
        fan_speed = fan_medium;
      }
    } else if (fan_speed == fan_medium) {
      if (max_temp > temp_top) {
        fan_speed = fan_high;
      } else if (max_temp + COOLDOWN_SLOP < temp_bottom) {
        fan_speed = fan_low;
      }
    } else {/* low */
      if (max_temp > temp_bottom) {
        fan_speed = fan_medium;
      }
    }
#endif

    /*
     * Update fans only if there are no failed ones. If any fans failed
     * earlier, all remaining fans should continue to run at max speed.
     */

    if (fan_failure == 0 && fan_speed != old_speed) {
      syslog(LOG_NOTICE,
             "Fan speed changing from %d to %d",
             old_speed,
             fan_speed);
      fan_speed_changes++;
      for (fan = 0; fan < total_fans; fan++) {
        write_fan_speed(fan + fan_offset, fan_speed);
      }
    }

    /*
     * Wait for some change.  Typical I2C temperature sensors
     * only provide a new value every second and a half, so
     * checking again more quickly than that is a waste.
     *
     * We also have to wait for the fan changes to take effect
     * before measuring them.
     */

    sleep(5);

    /* Check fan RPMs */

    for (fan = 0; fan < total_fans; fan++) {
      /*
       * Make sure that we're within some percentage
       * of the requested speed.
       */
      if (fan_speed_okay(fan + fan_offset, fan_speed, FAN_FAILURE_OFFSET)) {
        if (fan_bad[fan] > FAN_FAILURE_THRESHOLD) {
          write_fan_led(fan + fan_offset, FAN_LED_BLUE);
          syslog(LOG_CRIT,
                 "Fan %d has recovered",
                 fan);
        }
        fan_bad[fan] = 0;
      } else {
        fan_bad[fan]++;
      }
    }

    fan_failure = 0;
    for (fan = 0; fan < total_fans; fan++) {
      if (fan_bad[fan] > FAN_FAILURE_THRESHOLD) {
        fan_failure++;
        write_fan_led(fan + fan_offset, FAN_LED_RED);
      }
    }

    if (fan_failure > 0) {
      if (prev_fans_bad != fan_failure) {
        syslog(LOG_CRIT, "%d fans failed", fan_failure);
      }

      /*
       * If fans are bad, we need to blast all of the
       * fans at 100%;  we don't bother to turn off
       * the bad fans, in case they are all that is left.
       *
       * Note that we have a temporary bug with setting fans to
       * 100% so we only do fan_max = 99%.
       */

      fan_speed = fan_max;
      for (fan = 0; fan < total_fans; fan++) {
        write_fan_speed(fan + fan_offset, fan_speed);
      }

#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
      /*
       * On Wedge, we want to shut down everything if none of the fans
       * are visible, since there isn't automatic protection to shut
       * off the server or switch chip.  On other platforms, the CPUs
       * generating the heat will automatically turn off, so this is
       * unnecessary.
       */

      if (fan_failure == total_fans) {
        int count = 0;
        for (fan = 0; fan < total_fans; fan++) {
          if (fan_bad[fan] > FAN_SHUTDOWN_THRESHOLD)
            count++;
        }
        if (count == total_fans) {
          server_shutdown("all fans are bad for more than 12 cycles");
        }
      }
#endif

      /*
       * Fans can be hot swapped and replaced; in which case the fan daemon
       * will automatically detect the new fan and (assuming the new fan isn't
       * itself faulty), automatically readjust the speeds for all fans down
       * to a more suitable rpm. The fan daemon does not need to be restarted.
       */
    }

    /* Suppress multiple warnings for similar number of fan failures. */
    prev_fans_bad = fan_failure;

    /* if everything is fine, restart the watchdog countdown. If this process
     * is terminated, the persistent watchdog setting will cause the system
     * to reboot after the watchdog timeout. */
    kick_watchdog();
  }
}
Exemplo n.º 8
0
/* Main function */
int main(void) {
  sc_time_t     my_timer;  
  int32_t value; 

  dint();

#if USE_WATCHDOG
    init_watchdog(); 
#else
    WDTCTL = WDTCTL_INIT;               //Init watchdog timer
#endif
    
  init_ports();
  init_clock();
  sc_init_timer();

  scandal_init(); 

  config_read(); 

  {volatile int i; 
    for(i=0; i<100; i++)
      ;
  }

  /* Below here, we assume we have a config */ 

  /* Send out the error that we've reset -- it's not fatal obviously, 
     but we want to know when it happens, and it really is an error, 
     since something that's solar powered should be fairly constantly 
     powered */ 
  scandal_do_user_err(UNSWMPPTNG_ERROR_WATCHDOG_RESET); 
    
    /* Make sure our variables are set up properly */ 
    tracker_status = 0;     
    
  /* Initialise FPGA (or, our case, CPLD) stuff */ 
  fpga_init(); 

  /* Starts the ADC and control loop interrupt */
  control_init(); 

  /* Initialise the PV tracking mechanism */ 
  pv_track_init(); 

  eint();

  my_timer = sc_get_timer(); 

  while (1) {
    sc_time_t timeval; 

    timeval = sc_get_timer();

    handle_scandal(); 
    
    /* pv_track sends data when it feels like it */ 
    pv_track_send_data(); 

    /* Periodically send out the values recorded by the ADC */ 
    if(timeval >= my_timer + TELEMETRY_UPDATE_PERIOD){
        my_timer = timeval;
        toggle_yellow_led();
#if USE_WATCHDOG
	kick_watchdog(); 
#endif
        
        mpptng_do_errors(); 

        pv_track_send_telemetry(); 
        /* We send the Input current and voltage from 
            within the pvtrack module */ 

        /*  scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_IN_VOLTAGE, 
                        sample_adc(MEAS_VIN1));
            scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_IN_CURRENT, 
                        sample_adc(MEAS_IIN1));*/ 

        scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_OUT_VOLTAGE, 
                    sample_adc(MEAS_VOUT));
        scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_HEATSINK_TEMP, 
                    sample_adc(MEAS_THEATSINK));
        scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_15V, 
                    sample_adc(MEAS_15V));
        scandal_send_channel(TELEM_LOW, UNSWMPPTNG_STATUS, 
                    tracker_status); 

        /* Pre-scale for the temperature */ 
        {
            int32_t degC = sample_adc(MEAS_TAMBIENT); 
            degC = (((degC - 1615)*704*1000)/4095);
            scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_AMBIENT_TEMP, 
                                        degC);
        }

#if DEBUG >= 1
        scandal_send_channel(TELEM_LOW, 134, output);	
        scandal_send_channel(TELEM_LOW, 136, fpga_nFS()); 
#endif
    } 

    /*  If we're not tracking, 
        check to see that our start-up criteria are satisfied, and then
        initialise the control loops and restart tracking */ 
    if((tracker_status & STATUS_TRACKING) == 0){
        /* Check the input voltage */
        value = sample_adc(MEAS_VIN1); 
        scandal_get_scaled_value(UNSWMPPTNG_IN_VOLTAGE, &value);
        if(value < config.min_vin)
            continue; 

        /* Check the output voltage */
        value = sample_adc(MEAS_VOUT);
        scandal_get_scaled_value(UNSWMPPTNG_OUT_VOLTAGE, &value); 
        if(value > config.max_vout)
            continue; 

        tracker_status |= STATUS_TRACKING; 

        /* Initialise the tracking algorithm */ 
        //      pv_track_init(); 

        /* Reset the FPGA */ 	 
        fs_reset(); 

        /* Initialise the control loop */ 
        control_start(); 

        /* Enable the FPGA */ 
        fpga_enable(FPGA_ON); 
    }
  }
}
Exemplo n.º 9
0
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
    static int32_t x;
    int i;

#if !defined(__MSP430__)
    if (start_host_environment(argc, argv) < 0)
        exit(2);
#endif
    system_setup();

#if !defined(ESP_SUPPORT)  &&  defined(PHASE_CORRECTION_SUPPORT)  &&  !defined(DYNAMIC_PHASE_CORRECTION_SUPPORT)
    #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(__MSP430_HAS_ADC12__)  ||  defined(__MSP430_HAS_ADC10__)
        set_phase_correction(&phase->metrology.current.in_phase_correction[0], phase_nv->current.phase_correction[0]);
        #if GAIN_STAGES > 1
        set_phase_correction(&phase->metrology.current.in_phase_correction[1], phase_nv->current.phase_correction[1]);
        #endif
        #if defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)
        set_phase_correction(&phase->neutral.in_phase_correction[0], nv_parms.seg_a.s.neutral.phase_correction[0]);
            #if GAIN_STAGES > 1
        set_phase_correction(&phase->neutral.in_phase_correction[1], nv_parms.seg_a.s.neutral.phase_correction[1]);
            #endif
        #endif
    #else
        #if defined(SINGLE_PHASE)
        set_sd16_phase_correction(&phase->metrology.current.in_phase_correction[0], 0, phase_nv->current.phase_correction[0]);
            #if defined(NEUTRAL_MONITOR_SUPPORT)
        set_sd16_phase_correction(&phase->metrology.neutral.in_phase_correction[0], 1, nv_parms.seg_a.s.neutral.phase_correction[0]);
            #endif
        #else
        set_sd16_phase_correction(&phase->metrology.current.in_phase_correction[0], ch, phase_nv->current.phase_correction[0]);
        #endif
    #endif
    #if !defined(SINGLE_PHASE)
    }
    #endif
#endif

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

#if defined(MULTI_RATE_SUPPORT)
    tariff_initialise();
#endif
    send_message(0, 1);

    for (;;)
    {
        kick_watchdog();
#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  1 //// 0 //defined(__MSP430__)
////            if (operating_mode != OPERATING_MODE_NORMAL)
#ifdef USE_LPM
                _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
             
          
          
  //MM Added for LCD Fix; Start     
         
    
    
     #if defined(IHD430_SUPPORT)
         
               RF_Tx[12]=total_active_power_array.uint8[0];
               RF_Tx[13]=total_active_power_array.uint8[1];
               RF_Tx[14]=total_active_power_array.uint8[2];
               RF_Tx[15]=total_active_power_array.uint8[3]; 
               RF_Tx[16] =0x28 ^ RF_Tx[12] ^ RF_Tx[13] ^ RF_Tx[14] ^ RF_Tx[15];
               for (i=0; i<17; i++)
               {
                  UCA2TXBUF=RF_Tx[i];
                  while(!(UCA2IFG&UCTXIFG));
               }               
         #endif
    lcd_display_mode++;
     switch( lcd_display_mode ) 
              {
                  case DISPLAY_VOLTAGE:
                      change_display=1;
                      temp= phase->readings.V_rms;
                       if (temp <0) temp=0;
                       LCDM1=0xC;
                       LCDM2=0x29;
                      break;
                  case DISPLAY_CURRENT:
                       change_display=1;
                       temp= phase->readings.I_rms;
                       if (temp <0) temp=0;
                       LCDM1=0x9C;
                       LCDM2=0x1;
                       //MM Take care of different decimal.
                      break;
                  case DISPLAY_ACTIVE_POWER:
                     change_display=1;
                      temp= phase->readings.active_power;
                      if (temp <0) temp=0;
                      LCDM1=0xCF;
                       LCDM2=0x1;
                      break;
                  case DISPLAY_REACTIVE_POWER:
                      change_display=1;
                       temp= phase->readings.reactive_power;
                       if (temp <0) temp=0;
                       LCDM1=0xC7;
                       LCDM2=0x3;
                      break;
                  case DISPLAY_APPARENT_POWER:
                      change_display=1;
                       temp= phase->readings.apparent_power;
                       if (temp <0) temp=0;
                       LCDM1=0xB7;
                       LCDM2=0x1;
                      break;
                  case DISPLAY_FREQUENCY:
                      change_display=1;
                       temp= phase->readings.frequency;
                       if (temp <0) temp=0;
                       LCDM1=0x8F;
                       LCDM2=0x1;
                      break;  
                  case DISPLAY_POWER_FACTOR:
                      change_display=1;
                       temp= phase->readings.power_factor/10;
                       LCDM1=0x8F;
                       LCDM2=0x50;
                       if (temp < 0)
                       {
                          temp*= -1;
                         LCDM3=0x1C;
                       }
                       else
                       {
                          LCDM3= 0x9C; 
                       }
                       LCDM3constant=1;
                       //Take negative and positive case for inductive and capacitive
                      break;                  
                 case    DISPLAY_ACCUMULATED_POWER_TOTAL: 
                      change_display=1;
                      temp= phase->consumed_active_energy/10;
                      LCDM1=0x9F;
                       LCDM2=0x1;
                      break; 
              default:
                change_display=0;
                break;
                
                                     
            }
     //temp=12345;
         //total_active_power=0x12345;
// MM    Comment back in to display active power
//            if (total_active_power <0)
//            temp=-(total_active_power);
//          else
//            temp=total_active_power;
    
//MM Comment in two lines below  for counter test         //temp=12345;
//          temp2++;
//          temp=temp2;
         
            if(change_display)
            {
//               LCDM1 = 0;
//          LCDM2 = 0;          
          
             if(!LCDM3constant)
             {
               LCDM3 = 0;             
             }
             else
             {
               LCDM3constant=0;
             }
               
          LCDM4 = 0;
          LCDM5 = 0;
          LCDM6 = 0;
          LCDM7 = 0;
          LCDM8 = 0;
          LCDM9 = 0;
          LCDM10 = 0;
          LCDM11 = 0;
          LCDM12 = 0;          
          LCDM13 = 0;
          LCDM14 = 0;
          LCDM15 = 0;
          LCDM16 = 0;
          LCDM17 = 0;
          LCDM18 = 0;
          LCDM19 = 0;
          LCDM20 = 0;
          
         
       thou_thou=0;
         hun_thou=0;       
        ten_thou=0;
    thou=0;
    hun=0;
    ten=0;
    unit=0; 
                while (temp >=1000000)
                {
                    thou_thou++;
                    temp-=1000000;
                }
                 while (temp >=100000)
                {
                    hun_thou++;
                    temp-=100000;
                }
                while (temp >=10000)
                {
                    ten_thou++;
                    temp-=10000;
                }
                while (temp >=1000)
                {
                    thou++;
                    temp-=1000;
                }
                while (temp >=100)
                {
                    hun++;
                    temp-=100;
                }
                while (temp >=10)
                {
                    ten++;
                    temp-=10;
                }
                while (temp >=1)
                {
                    unit++;
                    temp--;
                }
               
                //MM: LCD fix to display higher active power readings
                if(thou_thou)
                {
                  LCDM11 = LCD_Char_Map[hun];
                  LCDM9 = LCD_Char_Map[thou];
                  //LCDM8 = 0x1;
                  LCDM7 = LCD_Char_Map[ten_thou];
                  LCDM5 = LCD_Char_Map[hun_thou];
                  LCDM3 = LCD_Char_Map[thou_thou];          
                }
                else if(hun_thou)
                {        
                  
                  LCDM11 = LCD_Char_Map[ten];
                  if (lcd_display_mode==DISPLAY_CURRENT) LCDM8 = 0x1;      
                  else if(lcd_display_mode!=DISPLAY_ACCUMULATED_POWER_TOTAL) LCDM10 = 0x1; //MM do nothing    
                  LCDM9 = LCD_Char_Map[hun];
                  LCDM7 = LCD_Char_Map[thou];
                  LCDM5 = LCD_Char_Map[ten_thou];
                  LCDM3 = LCD_Char_Map[hun_thou]; 
                }
                else
                {
                  LCDM11 = LCD_Char_Map[unit];
                  LCDM9 = LCD_Char_Map[ten];
                  if (lcd_display_mode==DISPLAY_CURRENT || lcd_display_mode==DISPLAY_POWER_FACTOR) 
                  {
                    LCDM6 = 0x1;
                  }
                  else if(lcd_display_mode==DISPLAY_ACCUMULATED_POWER_TOTAL) 
                  {
                    
                    LCDM10 = 0x1;
                      
                  }
                  else
                  {
                                       LCDM8 = 0x1; 
                  }
                     
                  if (lcd_display_mode!=DISPLAY_POWER_FACTOR) 
                     {
                       
                       LCDM3 = LCD_Char_Map[ten_thou];
 
                     }

                  LCDM7 = LCD_Char_Map[hun];
                  LCDM5 = LCD_Char_Map[thou];
                 
                }
                if (lcd_display_mode==DISPLAY_ACCUMULATED_POWER_TOTAL)
                {
                    lcd_display_mode=-2; 
                }
               
            }  
            
          //MM end        
                  
                if (operating_mode == OPERATING_MODE_NORMAL)
                {
                    /* We can only do real power assessment in full operating mode */
#if !defined(SINGLE_PHASE)
                    x = active_power(phase, phase_nv);
    #if defined(PRECALCULATED_PARAMETER_SUPPORT)
        #if defined(IRMS_SUPPORT)
                    phase->readings.I_rms = current(phase, phase_nv, ch);
        #endif
        #if defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage(phase, phase_nv);
        #endif
    #endif
#else
                    x = active_power();
                    
    #if defined(PRECALCULATED_PARAMETER_SUPPORT)
        #if defined(IRMS_SUPPORT)
                    phase->readings.I_rms = current();
        #endif
        #if defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage();
        #endif
    #endif
#endif
                }
#if defined(LIMP_MODE_SUPPORT)
                else if (operating_mode == OPERATING_MODE_LIMP)
                {
                    /* In limp mode we must assess estimated power from only the measured current. */
                    /* We cannot properly determine current reversal in this mode. Also, current
                       imbalance is really just a measure of which lead is still connected.
                       Just treat both the imbalance and reversal conditions as OK */
    #if !defined(SINGLE_PHASE)
                    x = current(phase, phase_nv, ch);
        #if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage(phase, phase_nv);
        #endif
    #else
                    x = current();
        #if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage();
        #endif
    #endif
    #if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(IRMS_SUPPORT)
                    phase->readings.I_rms = x;
    #endif
                    x = x*MAINS_NOMINAL_VOLTAGE/10;
                }
#endif
                if (labs(x) < RESIDUAL_POWER_CUTOFF  ||  (phase->status & V_OVERRANGE))
                {
                    x = 0;
#if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(IRMS_SUPPORT)
                    /* Avoid displaying a residual current, which is nothing more
                       than integrated noise. */
                    //phase->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(SINGLE_PHASE)  &&  defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
                total_active_power = x;
#else
                total_active_power += (x - phase->readings.active_power);
#endif
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(PHASE_REVERSED_IS_GENERATION)
#endif
               #if defined(IHD430_SUPPORT)
                total_active_power_array.uint32=total_active_power;

                #endif
                phase->readings.active_power = x;
#if defined(PRECALCULATED_PARAMETER_SUPPORT)
    #if defined(REACTIVE_POWER_SUPPORT)
        #if defined(SINGLE_PHASE)
                x = reactive_power();
        #else
                x = reactive_power(phase, phase_nv);
        #endif
        #if defined(SINGLE_PHASE)  &&  defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
                total_reactive_power = x;
        #else
                total_reactive_power += (x - phase->readings.reactive_power);
        #endif
                phase->readings.reactive_power = x;
    #endif
    #if defined(APPARENT_POWER_SUPPORT)
        #if defined(SINGLE_PHASE)
                phase->readings.apparent_power = apparent_power();
        #else
                phase->readings.apparent_power = apparent_power(phase, phase_nv);
        #endif
    #endif
    #if defined(POWER_FACTOR_SUPPORT)
                /* The power factor should be calculated last */
        #if defined(SINGLE_PHASE)
                phase->readings.power_factor = power_factor();
        #else
                phase->readings.power_factor = power_factor(phase, phase_nv);
        #endif
    #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(PRECALCULATED_PARAMETER_SUPPORT)  && defined(MAINS_FREQUENCY_SUPPORT)
    #if defined(SINGLE_PHASE)
                phase->readings.frequency = frequency();
    #else
                phase->readings.frequency = frequency(phase, phase_nv);
    #endif
#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)
            /* The voltage channel DC estimate will never move very much when the
               meter is operating normally. If it does move, there must be some
               tampering, such as a diode between the grid and the meter. */
            if (operating_mode == OPERATING_MODE_NORMAL)
            {
                if (phase->readings.V_rms < LIMP_MODE_VOLTAGE_THRESHOLD*100
                    ||
                    phase->metrology.V_dc_estimate[0] > UPPER_TAMPER_V_DC_ESTIMATE
                    ||
                    phase->metrology.V_dc_estimate[0] < LOWER_TAMPER_V_DC_ESTIMATE)
                {
                    switch_to_limp_mode();
                }
            }
            else if (operating_mode == OPERATING_MODE_LIMP)
            {
                if (phase->readings.V_rms >= NORMAL_MODE_VOLTAGE_THRESHOLD*100
                    &&
                    phase->metrology.V_dc_estimate[1] <= UPPER_LIMP_TAMPER_V_DC_ESTIMATE
                    &&
                    phase->metrology.V_dc_estimate[1] >= LOWER_LIMP_TAMPER_V_DC_ESTIMATE)
                {
                    /* The LCD might need to be revived */
    #if defined(__MSP430__)
                    LCDawaken();
    #else
                    /* Tell the world we are ready to start */
    #endif
                    switch_to_normal_mode();
                }
            }
#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;
            neutral.readings.I_rms = neutral_current();
        }
#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(__AQCOMPILER__)  &&  !defined(__IAR_SYSTEMS_ICC__)
    return  0;
#endif
}
Exemplo n.º 10
0
int32_t assess_rtc_speed(void)
{
    int32_t period;
    uint16_t this_capture;
    uint16_t last_capture;
    uint16_t step;
    int32_t counter;
    int limit;

    /* The fast clock should be an exact multiple of the crystal clock, once the FLL has
        settled. If we capture many cycles of an accurate external 32768Hz clock, using
        timer A (or B), we can measure the speed difference between the MSP430's crystal
        and the external clock in a reasonable time. */
    /* The SM clock should be running at 244*32768Hz at this time. */
    _DINT();
    /* Change timer A to running fast, and sampling the external 32768Hz reference. */
    P2SEL |= BIT0;
    TACCR0 = 0xFFFF;
    TACCTL0 = CAP | CCIS_0 | CM_1;
    TACCTL2 = CAP | CCIS_0 | CM_1 | SCS;
    TACTL = TACLR | MC_2 | TASSEL_2;    /* start TIMER_A up mode, SMCLK as input clock */
    period = 0;
    last_capture = TACCR2;
    limit = -1;
    TACCTL2 &= ~CCIFG;
    for (counter = 0;  counter < 32768*5 + 1;  counter++)
    {
        limit = 1000;
        while (!(TACCTL2 & CCIFG))
        {
            if (--limit <= 0)
                break;
        }
        if (limit <= 0)
            break;
        TACCTL2 &= ~CCIFG;
        this_capture = TACCR2;
        step = this_capture - last_capture;
        last_capture = this_capture;
        /* Skip the first sample, as it will be meaningless */
        if (counter)
        {
    #if 0
            if (step < (244 - 5)  ||  step > (244 + 5))
            {
                limit = -2;
                break;
            }
    #endif
            period += step;
        }
        kick_watchdog();
    }
    if (limit <= 0)
        period = limit;
    TACTL = TACLR | MC_1 | TASSEL_1;
    TACCTL0 = CCIE;
    P2SEL &= ~BIT0;
    _EINT();
    return  period;
}
Exemplo n.º 11
0
void system_setup(void)
{

    #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 */
    kick_watchdog();    /* Set the watchdog timer to exactly 1s */
    #else
    IE1 |= WDTIE;               /* Enable the WDT interrupt */
    #endif

    LCDinit();
    custom_lcd_init();
        #if defined(LCD_INIT)  &&  defined(__MSP430_HAS_LCD4__)
    LCDCTL = LCD_INIT;
        #endif
        #if defined(LCDACTL_INIT)  &&  defined(__MSP430_HAS_LCD_A__)
    LCDACTL = LCDACTL_INIT;
    LCDAPCTL0 = LCDAPCTL0_INIT;
    LCDAPCTL1 = LCDAPCTL1_INIT;
    LCDAVCTL0 = LCDAVCTL0_INIT;
    LCDAVCTL1 = LCDAVCTL1_INIT;
        #endif

    P1OUT = P1OUT_INIT;
    P1DIR = P1DIR_INIT;
    P1SEL = P1SEL_INIT;

    P2OUT = P2OUT_INIT;
    P2DIR = P2DIR_INIT;
    P2SEL = P2SEL_INIT;

    P3OUT = P3OUT_INIT;
    P3DIR = P3DIR_INIT;
    P3SEL = P3SEL_INIT;

    P4OUT = P4OUT_INIT;
    P4DIR = P4DIR_INIT;
    P4SEL = P4SEL_INIT;

    P5OUT = P5OUT_INIT;
    P5DIR = P5DIR_INIT;
    P5SEL = P5SEL_INIT;

    P6OUT = P6OUT_INIT;
    P6DIR = P6DIR_INIT;
    P6SEL = P6SEL_INIT;

    #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(IO_EXPANDER_SUPPORT)
    set_io_expander(0, 0);
    #endif
    
    display_startup_message();

    #if defined(__MSP430_HAS_DCO__)
    /* Set up the DCO clock */
    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
    #if defined(__MSP430_HAS_FLLPLUS__)  ||  defined(__MSP430_HAS_FLLPLUS_SMALL__)
    FLL_CTL0 |= XCAP10PF;               /* Configure load caps */
        #if defined(XT2OFF)
    FLL_CTL1 |= XT2OFF;
        #endif
    SCFI0 = FLLD_1;                     /* Freq = 1.024MHz */
    SCFQCTL = 32 - 1;
    FLL_CTL0 |= DCOPLUS;
    /* There seems no benefit in waiting for the FLL to settle at this point. */
    #endif

    samples_per_second = LIMP_SAMPLES_PER_10_SECONDS/10;

    #if defined(__MSP430_HAS_TA3__)  &&  defined(__MSP430_HAS_ADC12__)
    /* Use timer A to control the ADC sampling interval, and the ADC on/off timing. */
    /* TACCR0 determines the sample period */
    TAR = 0;
    TACCR0 = (SAMPLE_PERIOD*LIMP_SAMPLING_RATIO) - 1;
    TACCR1 = (SAMPLE_PERIOD*LIMP_SAMPLING_RATIO) - 3;
    TACCR2 = (SAMPLE_PERIOD*LIMP_SAMPLING_RATIO) - 4;
    TACCTL0 = 0;
    TACCTL1 = OUTMOD_3;
    TACTL = TACLR | MC_1 | TASSEL_1;
    #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


    disable_analog_front_end();


        #if defined(__MSP430_HAS_UART0__)
    /* Configure UART0 */
    UCTL0 = CHAR;                       /* 8-bit character */
    /* 9600 Rx doesn't work very well from 32768Hz. Use the fast clock. */
    UTCTL0 = SSEL1;                     /* UCLK = SMCLK */
    UBR00 = 0x69;
    UBR10 = 0x3;
    UMCTL0 = 0x77;

    U0ME |= (UTXE0 | URXE0);            /* Enable USART0 TXD/RXD */
    U0IE |= URXIE0;
    /* If you do not initially kick the Tx port the TXEPT bit is not set. */
    TXBUF0 = 0;
        #endif
    
        #if defined(__MSP430_HAS_UART1__)
    /* Configure UART1 */
    //UCTL1 = PENA | PEV;               /* 7-bit + even parity character */
    UCTL1 = CHAR;                       /* 8-bit character */
    //UCTL1 = PENA | PEV | CHAR;        /* 8-bit + even parity character */
            #if USART1_BAUD_RATE == 9600
    /* 9600 Rx doesn't work very well from 32768Hz. Use the fast clock. */
    UTCTL1 = SSEL1;                     /* UCLK = SMCLK */
    UBR01 = 0x69;
    UBR11 = 0x3;
    UMCTL1 = 0x77;
            #elif USART1_BAUD_RATE == 4800
    UTCTL1 = SSEL0;                     /* UCLK = ACLK */
    UBR01 = 6;                          /* 32k/4800 - 6.8266 */
    UBR11 = 0;
    UMCTL1 = 0x6F;
            #elif USART1_BAUD_RATE == 2400
    UTCTL1 = SSEL0;                     /* UCLK = ACLK */
    UBR01 = 13;                         /* 32k/2400 - 13.653 */
    UBR11 = 0;
    UMCTL1 = 0x6B;
            #else
    UTCTL1 = SSEL0;                     /* UCLK = ACLK */
    UBR01 = 27;                         /* 32k/1200 - 27.307 */
    UBR11 = 0;
    UMCTL1 = 0x03;
            #endif

    ME2 |= (UTXE1 | URXE1);            /* Enable USART1 TXD/RXD */
    IE2 |= URXIE1;
    /* If you do not initially kick the Tx port, the TXEPT bit is not set. */
    TXBUF1 = 0;
        #endif

    /* Configure the IR receiver control line - we need to be able to power it down
       in limp mode, to conserve current. */
    disable_ir_receiver();

    meter_status &= ~(STATUS_REVERSED | STATUS_EARTHED | STATUS_PHASE_VOLTAGE_OK);
    clr_normal_indicator();
    clr_earthed_indicator();
    clr_reverse_current_indicator();
    clr_total_energy_pulse_indicator();
    clr_total_reactive_energy_pulse_indicator();
    clr_energy_pulse_indicator();

        /* Prime the DC estimates for quick settling */
        phase->current.I_dc_estimate[0] = phase_nv->current.initial_dc_estimate;
        phase->current.I_endstops = ENDSTOP_HITS_FOR_OVERLOAD;
        phase->current.I_dc_estimate[1] = phase_nv->current.initial_dc_estimate;
        phase->V_dc_estimate[0] = phase_nv->initial_v_dc_estimate;
        phase->V_dc_estimate[1] = phase_nv->initial_v_limp_dc_estimate;
        phase->V_endstops = ENDSTOP_HITS_FOR_OVERLOAD;

    temperature = 0;
    if (!check_rtc_sumcheck())
    {
        rtc.year = 7;
        rtc.month = 6;
        rtc.day = 11;
        rtc.hour = 12;
        rtc.minute = 0;
        rtc.second = 0;
        set_rtc_sumcheck();
    }
    custom_initialisation();

    _EINT();

        #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 |= (SVSON | 0x60);
    /* Wait for adequate voltage to run at full speed */
    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(__MSP430_HAS_FLLPLUS__)  ||  defined(__MSP430_HAS_FLLPLUS_SMALL__)
    /* Speed up the clock to 8.388608MHz */
    SCFI0 = FN_3 | FLLD_4;
    SCFQCTL = 64 - 1;
#if 0
    {
        int i;
        for (i = 0xFFFF;  i;  i--);
            _NOP();
        _BIS_SR(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

        #if defined(__MSP430_HAS_TA3__)  &&  defined(__MSP430_HAS_ADC12__)
    /* Enable the TIMER_A0 interrupt */
    TACTL = TACLR | MC_1 | TASSEL_1;
    TACCTL0 = CCIE;
        #endif

    kick_watchdog();
    switch_to_normal_mode();
}
Exemplo n.º 12
0
/* timeout: maximum interval between 2 timer interrupts */
int main(int argc, char **argv)
{
	int wd_fd, opt;
	fd_set set;
	int n, ret, timeout = EXTTIMER_DEFAULT_TIMEOUT, wd_timeout;
	int pre_timeout = WATCHDOG_TIME_BETWEEN_WARN_AND_RESET;
	int options;

	/* Start logging here */
	LOG_INIT(LOG_TAG);
	LOGW("Watchdog daemon starting\n");

	/* Look through the options */
	while ((opt = getopt(argc, argv, "t:")) != -1) {
		switch (opt) {
			case 't':
				timeout = atoi(optarg);
				break;
			default:
				LOGE("invalid parameters\n");
				exit (-1);
		}
	}

	wd_timeout = timeout + pre_timeout + WATCHDOG_EXTRA_MARGIN;

	/* Real job from here */
	LOGW("Watchdog Timer set to timer=%d margin=%d extra_margin=%d\n",
	     timeout,
	     WATCHDOG_TIME_BETWEEN_WARN_AND_RESET,
	     WATCHDOG_EXTRA_MARGIN);

	wd_fd = open(WATCHDOG_DEVICE, O_RDWR | O_NONBLOCK | O_SYNC | O_EXCL);
	if (wd_fd == -1) {
		LOGE("unable to open the wd device (ERRNO=%d)\n",errno);
		goto error_nop;
	}

	/* Stopping the watchdog */
	options = WDIOS_DISABLECARD;
	ret = ioctl(wd_fd, WDIOC_SETOPTIONS, &options);
	if (ret) {
		LOGE("Unable to stop the watchdog\n");
		goto error_open_watchdog;
	}

	/* Setting the kernel watchdog timeout */
	ret = ioctl(wd_fd, WDIOC_SETTIMEOUT, &wd_timeout);
	if (ret) {
		LOGE("Unable to Set Watchdog Timer Threshold\n");
		goto error_open_watchdog;
	}

	/* Setting the kernel watchdog pretimeout */
	ret = ioctl(wd_fd, WDIOC_SETPRETIMEOUT, &pre_timeout);
	if (ret) {
		LOGE("Unable to set the watchdog pretimeout\n");
		goto error_open_watchdog;
	}

	/* Setting the timer timeout */
	ret = ioctl(wd_fd, WDIOC_SETTIMERTIMEOUT, &timeout);
	if (ret) {
		LOGE("Unable to set the watchdog timer_timeout\n");
		goto error_open_watchdog;
	}

	/* Restarting the watchdog */
	options = WDIOS_ENABLECARD;
	ret = ioctl(wd_fd, WDIOC_SETOPTIONS, &options);
	if (ret) {
		LOGE("Unable to restart the watchdog\n");
		goto error_open_watchdog;
	}

	/* Then looping for ever */
	for (;;) {
		FD_ZERO(&set);
		FD_SET(wd_fd, &set);

		LOGI("waiting for a timer interrupt\n");

		/* Waiting for an event (timer_msi or watchdog_msi) */
		n = select(wd_fd+1, &set, NULL, NULL, NULL);
		if (n == -1) {
			LOGE("select system call failed\n");
			sleep(5);
			continue;
		} else if (n == 0) {
			LOGE("select returned 0: abnormal\n");
			sleep(5);
			continue;
		}

		/* Do we have a timer_msi ? */
		if (FD_ISSET(wd_fd, &set)) {
			LOGD("Timer interrupt\n");

			/* kicking the watchdog device */
			ret = kick_watchdog(wd_fd);
			if (ret <= 0)
				LOGE("Unable to refresh Watchdog Timer\n");
		}
	}
	LOGW("Watchdog daemon exiting\n");
	return 0;

error_open_watchdog:
	close(wd_fd);
error_nop:
	LOGE("Watchdog daemon exiting\n");
	return 1;
}