Beispiel #1
0
/**
 * Parse and then execute the "S" command from the user, which sets the time.
 */
void command_set(char *command)
{
  uint8_t rc;
  rtc_datetime_24h_t dt;

  rc = rtc_clock_stop(rtc);
  printf_P(PSTR("Halted clock, rc=%i\n"), rc);

  rtc_sqw_enable(rtc);
  rtc_sqw_rate(rtc, 1);

  rc = rtc_read(rtc, &dt);

  sscanf_P(command,
      PSTR("S %04d-%02hhd-%02hhd %02hhd:%02hhd:%02hhd\n"),
      &dt.year, &dt.month, &dt.date,
      &dt.hour, &dt.minute, &dt.second);

  dt.day_of_week = rtc_find_dow(dt.year, dt.month, dt.date);

  printf_P(PSTR("Setting time to %04i-%02i-%02i %02i:%02i:%02i (%s)\n"),
      dt.year, dt.month, dt.date,
      dt.hour, dt.minute, dt.second,
      rtc_dow_names[dt.day_of_week]);

  printf_P(PSTR("Trying to write RTC...\n"));
  rc = rtc_write(rtc, &dt);
  printf_P(PSTR("Wrote RTC, rc=%i\n"), rc);

  rc = rtc_clock_start(rtc);
  printf_P(PSTR("Started clock, rc=%i\n"), rc);
}
Beispiel #2
0
/**
 * MCU: Atmega328
 * Fuses: Oscilador interno a 8 Mhz (sin dividir por 8)
 * 		-U lfuse:w:0xe2:m -U hfuse:w:0xd1:m -U efuse:w:0x07:m
 */
int main(void) {
	adc_init();

	timer0_init(timer0_callback);

	i2c_init();

	rtc_init(rtc);
	rtc_sqw_rate(rtc, 1);
	rtc_sqw_enable(rtc);
	rtc_clock_start(rtc);

	eMBInit(MB_RTU, 0x03, 0, 9600, MB_PAR_NONE);
	eMBSetSlaveID(0x3, TRUE, (UCHAR*) "demeter", 8);
	eMBEnable();

	blinkenlight(5, 100);

	parameters_init();

	ports_init();

	f_mount(&fs, "", 0);
	update_log_filename();

	while (1) {
		eMBPoll();
		update_state();

		_delay_ms(100);
	}

	return (0);
}
int main(void)
{
  uart_t *u0;
  uint8_t rc;
  rtc_device_t *rtc = &rtc_ds1307;
  rtc_datetime_24h_t current_dt, offset_dt;

  _delay_ms(1000);

  u0 = uart_init("0", UART_BAUD_SELECT(38400, F_CPU));
  uart_init_stdout(u0);

  i2c_init();

  DDRC = _BV(PC0) | _BV(PC1);
  PORTC = _BV(PC0) | _BV(PC1);

  sei();

  printf("\n\nBooted up!\n");

  rc = rtc_init(rtc);
  printf("Inited RTC, rc=%i\n", rc);

  rc = rtc_sqw_rate(rtc, 1);
  printf("Set sqw rate, rc=%i\n", rc);

  rc = rtc_sqw_enable(rtc);
  printf("Set sqw enable, rc=%i\n", rc);

  rc = rtc_clock_start(rtc);
  printf("Started clock, rc=%i\n", rc);

  _delay_ms(1000);

  while(1)
  {
    rc = rtc_read(rtc, &current_dt);

    rtc_offset_time(&current_dt, &offset_dt, -7);

    printf("rc = %i, %04i-%02i-%02i %02i:%02i:%02i %i offset: %04i-%02i-%02i %02i:%02i:%02i %i\n",
        rc,
        current_dt.year, current_dt.month, current_dt.date,
        current_dt.hour, current_dt.minute, current_dt.second,
        current_dt.day_of_week,
        offset_dt.year, offset_dt.month, offset_dt.date,
        offset_dt.hour, offset_dt.minute, offset_dt.second,
        offset_dt.day_of_week
    );

    _delay_ms(1000);
  }

  return(0);
}
Beispiel #4
0
void command_set_from_gps(void)
{
  uint8_t rc;

  if(update_gps())
    return;

  if(gps_data.gps_signal_strength < 3)
  {
    printf_P(PSTR("GPS signal strength (%d) is unreliable. Aborting sync!\n"),
        gps_data.gps_signal_strength);
    return;
  }

  if(gps_data.dt.second < (59 - gps_leap_second_offset))
  {
    /* Adjust to the edge of the next second, don't deal with rollover */
    printf_P(PSTR("Sleeping for %d ms to synchronize...\n"),
        1000 - gps_data.dt.millisecond - 1);
    wait_ms(1000 - gps_data.dt.millisecond - 1);
    gps_data.dt.second += 1 + gps_leap_second_offset;
    gps_data.dt.millisecond = 0;
  }

  rc = rtc_clock_stop(rtc);
  printf_P(PSTR("Halted clock, rc=%i\n"), rc);

  rtc_sqw_enable(rtc);
  rtc_sqw_rate(rtc, 1);

  printf_P(PSTR("Setting time to %04i-%02i-%02i %02i:%02i:%02i (%s)\n"),
      gps_data.dt.year, gps_data.dt.month, gps_data.dt.date,
      gps_data.dt.hour, gps_data.dt.minute, gps_data.dt.second,
      rtc_dow_names[gps_data.dt.day_of_week]);

  printf_P(PSTR("Trying to write RTC...\n"));
  rc = rtc_write(rtc, &gps_data.dt);
  printf_P(PSTR("Wrote RTC, rc=%i\n"), rc);

  rc = rtc_clock_start(rtc);
  printf_P(PSTR("Started clock, rc=%i\n"), rc);
}
Beispiel #5
0
int main(void)
{
  uart_t *u0;

  /* Delay for one second to avoid multiple resets during programming. */
  _delay_ms(1000);

  /* Initialize USART0 and set up stdout to write to it. */
  u0 = uart_init("0", UART_BAUD_SELECT(38400, F_CPU));
  uart_init_stdout(u0);
  uart_set_rx_callback(u0, notice_uart_input);

  i2c_init();

  /*
   * Test if pullup is required on the I2C pins, and enable if the pins are
   * reading low. This allows external pullups to optionally be used, so that
   * for example the I2C bus can be pulled up to 3.3V to allow communication
   * between 3.3V and 5V devices at 3.3V.
   */
  if((PINC & (_BV(PC0) | _BV(PC1))) == 0)
  {
    DDRC  = _BV(PC0) | _BV(PC1);
    PORTC = _BV(PC0) | _BV(PC1);
  }

  sei();

  printf_P(PSTR("\n\nBooted!\n"));

  printf_P(PSTR("Reading saved configuration...\n\n"));
  configuration_restore();

  printf_P(PSTR(
    "Configuration:\n"
    "  tz_offset:  %2i\n"
    "  dst_offset: %2i\n"
    "\n"
  ), configuration.tz_offset, configuration.dst_offset);

  printf_P(PSTR(
    "Commands:\n"
    "  Get the current time:\n"
    "    G\n"
    "  Set the current time:\n"
    "    S YYYY-MM-DD hh:mm:ss\n"
    "  Set the timezone offset from UTC:\n"
    "    O <tz_offset> <dst_offset>\n"
    "  Set the time from GPS (if available):"
    "    s\n"
    "\n"
  ));

  rtc_init(rtc);
  rtc_sqw_enable(rtc);
  rtc_sqw_rate(rtc, 1);

  /* Enable pullup and interrupt for PC6/PCINT22, DS1307 SQW pin. */
  PORTC  |= _BV(PC6);
  PCMSK2 |= _BV(PCINT22);
  PCICR  |= _BV(PCIE2);

  /* Initialize the sequencer with 1000Hz tick rate. */
  led_sequencer_init(1000);

  /* Initialize and load the LED Analog Clock LED display. */
  led_charlieplex_init(&LED_DISPLAY);
  led_sequencer_push_front_matrix("c", &LED_DISPLAY);

  /*
   * Add empty sequences for hour, minute, second, hourly show, and minutely
   * show.
   */
  led_sequencer_push_back_sequence("h");
  led_sequencer_push_back_sequence("m");
  led_sequencer_push_back_sequence("s");
  led_sequencer_push_back_sequence("H");
  led_sequencer_push_back_sequence("M");

  /*
   * Initially read the time, set last_* for use later, and push a sequencer
   * step into the second, minute, and hour sequences.  The steps pushed
   * below are never removed, as they are modified in place in update_hms()
   * with each time change.
   */
  rtc_read(rtc, &current_time);
  last_hour   = current_time.hour;
  last_minute = current_time.minute;
  last_second = current_time.second;
  step_hour   = led_sequencer_sequence_push_back_step("h", LED_SEQUENCER_STEP_SHOW, "c", led_mapping_qhour[((current_time.hour % 12) * 4) + (current_time.minute / 15)], 255);
  step_minute = led_sequencer_sequence_push_back_step("m", LED_SEQUENCER_STEP_SHOW, "c", led_mapping_minute[current_time.minute], 255);
  step_second = led_sequencer_sequence_push_back_step("s", LED_SEQUENCER_STEP_SHOW, "c", led_mapping_minute[current_time.second], 255);

  enqueue_hourly_show();

  led_sequencer_run();

  srand(current_time.hour * current_time.minute * current_time.second);

  /*
   * Main infinite loop.
   */
  while(1)
  {
    /* Handle UART input when ready. */
    if(ready_flags & READY_UART_DATA)
    {
      ready_flags &= ~READY_UART_DATA;
      handle_uart_input(u0);
    }

    /* A time change has occurred, update the clock display. */
    if(ready_flags & READY_UPDATE_HMS)
    {
      ready_flags &= ~READY_UPDATE_HMS;
      update_hms();
    }

    /*
     * Run one loop through the current sequence, with interrupts disabled.
     */
    cli();
    led_sequencer_display();
    sei();
  }

  /* Never reached. */
  return(0);
}