Example #1
0
/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * MAIN: main routine
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */

//int main(void) __attribute__((noreturn)); /* saves some Bytes but produces warning */
int
main (void)
{
  static DATETIME  datetime;  

  uart_init();                                                                  // initialize uart
  log_main("Init...\n");

  wcEeprom_init();

# if (DCF_PRESENT == 1)
    dcf77_init ();                                                              // initialize dcf77
# endif

  display_init ();                                                              // initialize display

  { // local to save stack
    uint8_t     i2c_errorcode;
    uint8_t     i2c_status;
    if (! i2c_rtc_init (&i2c_errorcode, &i2c_status))                           // initialize rtc
    {
      log_main("RTC init failed\n");
      // TODO: error handling
    }
  }

  ldr_init ();                                                                  // initialize ldr
  pwm_init ();                                                                  // initialize pwm
  irmp_init ();                                                                 // initialize irmp
  timer_init ();                                                                // initialize timer
  user_init();

  sei ();                                                                       // enable interrupts

  pwm_on ();                                                                    // switch on pwm

  //pwm_set_base_brightness_step(MAX_PWM_STEPS-1); /// @todo remove if ldr stuff is working


  log_main("Init finished\n");

  for (;;)
  {
    handle_brightness ();
    handle_datetime (&datetime);                                                // check & display new time, if necessary
    handle_ir_code ();                                                          // handle ir user interaction

#   if (DCF_PRESENT == 1)
      if (dcf77_getDateTime (&datetime))                                        // handle dcf77 examination (enable_dcf77_ISR must be TRUE to enable analysis)
      {
        i2c_rtc_write (&datetime);
        soft_seconds = datetime.ss;
        user_setNewTime (&datetime);
      }
#   endif  /** (DCF_PRESENT == 1) */
  }
}
Example #2
0
/*---------------------------------------------------------------------------------------------------------------------------------------------------
 * MAIN: check date & time
 *
 * This function uses a softclock to avoid extensive calls of i2c_rtc_read() by
 * reading the RTC only READ_DATETIME_INTERVAL seconds.
 *
 * fm: This softclock algorithm adjusts itself:
 * - if the RC oscillator is too slow, handle_datetime() will call i2c_rtc_read() every second in the last part
 *   of a minute in order to reach the next full minute as close as possible.
 * - if the RC oscillator is too fast, the softclock will be slowdowned by updating the softclock every
 *   READ_DATETIME_INTERVAL - softclock_too_fast_seconds
 *---------------------------------------------------------------------------------------------------------------------------------------------------
 */
static void
handle_datetime (DATETIME * datetimep)
{
  static uint8_t    last_hour = 0xff;                                             // value of last hour
  static uint8_t    last_minute = 0xff;                                           // value of minutes evaluated last call
  static uint8_t    last_seconds = 0xff;                                          // value of seconds evaluated last call
  static uint8_t    next_read_seconds = 0;                                        // time in seconds when to read RTC again
  uint8_t           softclock_too_fast_seconds = 0;                               // if softclock is too fast, store difference of seconds
  uint8_t           rtc;

  if (last_seconds != soft_seconds)                                               // time changed?
  {                                                                               // yes...
    if (soft_seconds >= next_read_seconds)                                        // next time (to read RTC) reached?
    {                                                                             // yes...
      rtc = i2c_rtc_read (datetimep);                                             // read RTC now!
    }
    else
    {                                                                             // next time not reached...
      datetimep->ss = soft_seconds;                                               // update only seconds
      rtc = TRUE;
    }

    if (rtc)
    {
      if (last_minute != datetimep->mm)                                           // minute change?
      {                                                                           // yes...
        user_setNewTime (datetimep);                                              // display current time
        last_minute = datetimep->mm;                                              // store current minute as last minute

        if (last_hour != datetimep->hh)
        {
#         if (DCF_PRESENT == 1)
            enable_dcf77_ISR = TRUE;                                              // enable DCF77 every hour
#         endif  /** (DCF_PRESENT == 1) */
          last_hour = datetimep->hh;                                              // store current hour as last hour
        }
      }

      if (last_seconds != 0xff && soft_seconds > datetimep->ss)
      {
        softclock_too_fast_seconds = soft_seconds - datetimep->ss;
      }

      last_seconds = soft_seconds = datetimep->ss;                                // store actual value of seconds for softclock

      if (softclock_too_fast_seconds > 0)
      {                                                                           // set next time we have to read RTC again (with correction)
        next_read_seconds = soft_seconds + READ_DATETIME_INTERVAL - softclock_too_fast_seconds;
      }
      else
      {
        next_read_seconds = soft_seconds + READ_DATETIME_INTERVAL;                // set next time we have to read RTC again
      }

      if (next_read_seconds >= 60)                                                // we have to read it in the next minute...
      {
        next_read_seconds = 0;                                                    // reset next time: read at next full minute
      }
    }
    else
    {
      log_main("RTC error\n");
    }
  }
  else
  {
    rtc = TRUE;                                                                   // time not changed, do nothing
  }
}
Example #3
0
/**
 * @brief Handles the given user command
 *
 * This handles the given user command (user_command_t) either by processing
 * it directly, or by passing it over to the actual handler using
 * UserState_HandleUserCommand().
 *
 * g_eepromSaveDelay and g_checkIfAutoOffDelay get reset every time this
 * function is called to make sure the appropriate functionality works as
 * intended.
 *
 * @param user_command The user command that should be handled
 *
 * @see UserState_HandleUserCommand()
 * @see g_eepromSaveDelay
 * @see g_checkIfAutoOffDelay
 */
void handle_user_command(user_command_t user_command)
{

    if (UC_ONOFF == user_command) {

        log_state("OF\n");

        if (user_power_state < UPS_AUTO_OFF) {

            user_power_state = UPS_MANUAL_OFF;
            pwm_off();

        } else {

            if (user_power_state == UPS_MANUAL_OFF) {

                user_power_state = UPS_NORMAL_ON;

            } else {

                user_power_state = UPS_OVERRIDE_ON;

            }

            pwm_on();
            user_setNewTime(NULL);

        }

        preferences_save();

    } else {

        int8_t i;
        bool handled = false;

        for (i = g_topOfStack - 1; i >= 0 && !handled; --i) {

            handled |= UserState_HandleUserCommand(g_stateStack[i], user_command);

        }

        if (!handled) {

            if (UC_BRIGHTNESS_UP == user_command) {

                log_state("B+\n");
                pwm_increase_brightness();

            } else if (UC_BRIGHTNESS_DOWN == user_command) {

                log_state("B-\n");
                pwm_decrease_brightness();

            } else if (UC_NORMAL_MODE == user_command) {

                addSubState(-1, MS_normalMode, (void*)1);

            } else if (UC_SET_TIME == user_command) {

                addState(MS_setSystemTime, NULL);

            } else if (UC_SET_ONOFF_TIMES == user_command) {

                addState(MS_setOnOffTime, NULL);

            } else if (UC_DEMO_MODE == user_command) {

                menu_state_t curTop = user_get_current_menu_state();

                log_state("BS\n");

                if (MS_demoMode == curTop) {

                    quitMyself(MS_demoMode, NULL);

                } else {

                    addState(MS_demoMode, NULL);

                }

            } else if (UC_CALIB_BRIGHTNESS == user_command) {

                pwm_modifyLdrBrightness2pwmStep();

                // Indicate the change to user
                if (pwm_is_enabled()) {

                    pwm_off();
                    _delay_ms(USER_VISUAL_INDICATION_TOGGLE_MS);
                    pwm_on();

                }

            } else if (UC_PULSE_MODE == user_command) {

                menu_state_t curTop = user_get_current_menu_state();

                log_state("PLS\n");

                if (MS_pulse == curTop) {

                    leaveSubState(g_topOfStack - 1);

                } else {

                    if ((MS_normalMode == curTop)
                    #if (ENABLE_RGB_SUPPORT == 1)
                        || (MS_hueMode == curTop)
                    #endif
                    ) {

                        addState(MS_pulse, NULL);

                    }

                }

                DISPLAY_SPECIAL_USER_COMMANDS_HANDLER

                #if (ENABLE_RGB_SUPPORT == 1)

                    } else if (UC_HUE_MODE == user_command) {

                        log_state("HM");

                        addSubState(-1, MS_hueMode, NULL);

                #endif

                #if (ENABLE_DCF_SUPPORT == 1)

                    } else if (UC_DCF_GET_TIME == user_command) {

                        log_state("DCF\n");

                        dcf77_enable();

                #endif

                #if (ENABLE_AMBILIGHT_SUPPORT == 1)

                    } else if (UC_AMBILIGHT == user_command) {

                        log_state("AL\n");

                        PIN(USER_AMBILIGHT) |= _BV(BIT(USER_AMBILIGHT));

                #endif

                #if (ENABLE_BLUETOOTH_SUPPORT == 1)

                    } else if (UC_BLUETOOTH == user_command) {

                        log_state("BT\n");

                        PIN(USER_BLUETOOTH) |= _BV(BIT(USER_BLUETOOTH));

                #endif

                #if (ENABLE_AUXPOWER_SUPPORT == 1)

                    } else if (UC_AUXPOWER == user_command) {

                        log_state("AUX\n");

                        PIN(USER_AUXPOWER) |= _BV(BIT(USER_AUXPOWER));

                #endif

                    } else {

                        return;

                    }

        }