diff --git a/main.c b/main.c index abd4442..f2d85ed 100644 --- a/main.c +++ b/main.c @@ -43,6 +43,7 @@ #include "usart.h" // USART utilities #include "usb_cdcacm.h" // USB CDC ACM utilities #include "led_tm1637.h" // TM1637 7-segment controller utilities +#include "rtc_ds1307.h" // DS1307 RTC utilities #define WATCHDOG_PERIOD 10000 /**< watchdog period in ms */ @@ -102,6 +103,7 @@ static void process_command(char* str) printf("available commands:\n"); printf("led [on|off|toggle]\n"); printf("time [HH:MM:SS]\n"); + printf("date [YYYY-MM-DD]\n"); } else if (0==strcmp(word,"led")) { word = strtok(NULL,delimiter); if (!word) { @@ -118,6 +120,41 @@ static void process_command(char* str) } else { goto error; } + } else if (0==strcmp(word,"time")) { + word = strtok(NULL,delimiter); + if (!word) { + printf("current time: %02u:%02u:%02u\n", rtc_ds1307_read_hours(), rtc_ds1307_read_minutes(), rtc_ds1307_read_seconds()); // get and print time from external RTC + } else if (strlen(word)!=8 || word[0]<'0' || word[0]>'2' || word[1]<'0' || word[1]>'9' || word[3]<'0' || word[3]>'5' || word[4]<'0' || word[4]>'9' || word[6]<'0' || word[6]>'5' || word[7]<'0' || word[7]>'9') { // time format is incorrect + goto error; + } else { + if (!rtc_ds1307_write_hours((word[0]-'0')*10+(word[1]-'0')*1)) { + printf("setting hours failed\n"); + } else if (!rtc_ds1307_write_minutes((word[3]-'0')*10+(word[4]-'0')*1)) { + printf("setting minutes failed\n"); + } else if (!rtc_ds1307_write_seconds((word[6]-'0')*10+(word[7]-'0')*1)) { + printf("setting seconds failed\n"); + } else { + rtc_ds1307_oscillator_enable(); // be sure the oscillation is enabled + printf("time set\n"); + } + } + } else if (0==strcmp(word,"date")) { + word = strtok(NULL,delimiter); + if (!word) { + printf("current date: 20%02u-%02u-%02u\n", rtc_ds1307_read_year(), rtc_ds1307_read_month(), rtc_ds1307_read_date()); + } else if (strlen(word)!=10 || word[0]!='2' || word[1]!='0' || word[2]<'0' || word[2]>'9' || word[3]<'0' || word[3]>'9' || word[5]<'0' || word[5]>'1' || word[6]<'0' || word[6]>'9' || word[8]<'0' || word[8]>'3' || word[9]<'0' || word[9]>'9') { + goto error; + } else { + if (!rtc_ds1307_write_year((word[2]-'0')*10+(word[3]-'0')*1)) { + printf("setting year failed\n"); + } else if (!rtc_ds1307_write_month((word[5]-'0')*10+(word[6]-'0')*1)) { + printf("setting month failed\n"); + } else if (!rtc_ds1307_write_date((word[8]-'0')*10+(word[9]-'0')*1)) { + printf("setting day failed\n"); + } else { + printf("date set\n"); + } + } } else { goto error; } @@ -174,16 +211,28 @@ void main(void) } #endif - // setup RTC + // setup internal RTC printf("setup internal RTC: "); rtc_auto_awake(RCC_LSE, 32768-1); // ensure internal RTC is on, uses the 32.678 kHz LSE, and the prescale is set to our tick speed, else update backup registers accordingly (power off the micro-controller for the change to take effect) rtc_interrupt_enable(RTC_SEC); // enable RTC interrupt on "seconds" nvic_enable_irq(NVIC_RTC_IRQ); // allow the RTC to interrupt printf("OK\n"); - + // display uptime uint32_t ticks_time = rtc_get_counter_val(); // get time from internal RTC (since first start/power up) printf("uptime: %lu.%02lu:%02lu:%02lu\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime + // setup external RTC + printf("setup external RTC: "); + rtc_ds1307_setup(); // setup external RTC module + printf("OK\n"); + // verify is external RTC is running + if (rtc_ds1307_oscillator_disabled()) { + printf("/!\\ RTC oscillator is disabled: the battery may be empty\n"); + } + // display date + uint8_t* rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC + printf("current date: 20%02u-%02u-%02u %02u:%02u:%02u\n", rtc_ds1307_time[6], rtc_ds1307_time[5], rtc_ds1307_time[4], rtc_ds1307_time[2], rtc_ds1307_time[1], rtc_ds1307_time[0]); + // setup TM1637 printf("setup 7-segment display: "); led_tm1637_setup(); @@ -210,9 +259,6 @@ void main(void) button_flag = false; // reset button flag char c = '\0'; // to store received character bool char_flag = false; // a new character has been received - if (!led_tm1637_on()) { // switch on display - fprintf(stderr,"could not switch on TM1637\n"); - } while (true) { // infinite loop iwdg_reset(); // kick the dog while (usart_received) { // data received over UART @@ -255,15 +301,18 @@ void main(void) } while (rtc_internal_tick_flag) { // the internal RTC ticked rtc_internal_tick_flag = false; // reset flag - led_toggle(); // toggle LED (good to indicate if main function is stuck) + //led_toggle(); // toggle LED (good to indicate if main function is stuck) ticks_time = rtc_get_counter_val(); // copy time from internal RTC for processing action = true; // action has been performed if ((ticks_time%(60))==0) { // one minute passed printf("uptime: %lu.%02lu:%02lu:%02lu\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime } - if (!led_tm1637_time((ticks_time%(60*60))/60, ticks_time%60)) { + if (!led_tm1637_time(rtc_ds1307_read_minutes(), rtc_ds1307_read_seconds())) { fprintf(stderr,"could not set time on TM1637\n"); } + if (!led_tm1637_on()) { // switch on display + fprintf(stderr,"could not switch on TM1637\n"); + } } if (action) { // go to sleep if nothing had to be done, else recheck for activity action = false;