/** * 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); }
/** * 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, ¤t_dt); rtc_offset_time(¤t_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); }
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); }
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, ¤t_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); }