Beispiel #1
0
static void MovingLightModel_Tasks() {
  if (g_moving_light.lamp_state == LAMP_STRIKE &&
      CoarseTimer_HasElapsed(g_moving_light.lamp_strike_time,
                             LAMP_STRIKE_DELAY)) {
    g_moving_light.lamp_state = LAMP_ON;
    g_moving_light.lamp_strikes++;
  }

  if (CoarseTimer_HasElapsed(g_moving_light.clock_timer, ONE_SECOND)) {
    g_moving_light.clock_timer = CoarseTimer_GetTime();
    g_moving_light.second++;
    if (g_moving_light.second >= 60u) {
      g_moving_light.second = 0u;
      g_moving_light.minute++;
    }
    if (g_moving_light.minute >= 60u) {
      g_moving_light.minute = 0u;
      g_moving_light.hour++;
    }
    if (g_moving_light.hour >= 24u) {
      g_moving_light.hour = 0u;
      g_moving_light.day++;
    }
    if (g_moving_light.day >
        DaysInMonth(g_moving_light.year, g_moving_light.month)) {
      g_moving_light.day = 1u;
      g_moving_light.month++;
    }
    if (g_moving_light.month > 12u) {
      g_moving_light.month = 1u;
      g_moving_light.year++;
    }
  }
}
/*
 * @brief We generate status messages for each device, based on a periodic
 * timer. This makes it easier to reproduce problems (and test!).
 */
static void DimmerModel_Tasks() {
  // The cycle counter is used to generate status messages for each sub device.
  static uint8_t cycle = 0u;
  static uint16_t complete_cycles = 0u;

  if (g_root_device.running_self_test &&
      CoarseTimer_HasElapsed(
          g_root_device.self_test_timer,
          SELF_TESTS[g_root_device.running_self_test - 1].duration)) {
    // Queue a status message for the root.
    QueueStatusMessage(
        &g_root_device.status_message, SUBDEVICE_ROOT, STATUS_ADVISORY,
        (uint16_t) (g_root_device.running_self_test == 1u ?
            STS_OLP_SELFTEST_PASSED : STS_OLP_SELFTEST_FAILED),
        g_root_device.running_self_test, 0u);

    g_root_device.running_self_test = 0u;
  }

  if (!CoarseTimer_HasElapsed(g_root_device.status_message_timer,
                             STATUS_MESSAGE_TRIGGER_INTERVAL)) {
    return;
  }

  g_root_device.status_message_timer = CoarseTimer_GetTime();

  unsigned int subdevice_index = 0u;
  for (; subdevice_index < NUMBER_OF_SUB_DEVICES; subdevice_index++) {
    DimmerSubDevice *subdevice = &g_subdevices[subdevice_index];

    if (subdevice->index == 1u) {
      // The cycle for the first device is:
      //  - 0, NOOP
      //  - 1, Queue breaker trip warning
      //  - 2, NOOP
      //  - 3, Clear breaker trip warning
      //  - 4, NOOP
      if (cycle == 1) {
        // Queue a message
        QueueSubDeviceStatusMessage(subdevice, STATUS_WARNING,
                                    STS_BREAKER_TRIP, 0u, 0u);
      } else if (cycle == 3u) {
        if (subdevice->status_message.is_active) {
          // The previous message is still in the queue, cancel it.
          subdevice->status_message.is_active = false;
        } else {
          // Queue a 'cleared' message
          QueueSubDeviceStatusMessage(subdevice, STATUS_WARNING_CLEARED,
                                      STS_BREAKER_TRIP, 0u, 0u);
        }
      }
    } else if (subdevice->index == 3u) {
      // This subdevice just queues a manufacturer-defined advisory message
      // each cycle.
      QueueSubDeviceStatusMessage(subdevice, STATUS_ADVISORY,
                                  (uint16_t) STS_OLP_TESTING,
                                  complete_cycles, cycle);
    }
  }
  cycle++;
  cycle %= 5u;
  if (cycle == 0u) {
    complete_cycles++;
  }
}