use RTC square wave output to sync on seconds
This commit is contained in:
parent
ed8d8f985a
commit
bbc66e3c82
84
main.c
84
main.c
|
@ -49,9 +49,12 @@
|
|||
/** @defgroup main_flags flag set in interrupts to be processed in main task
|
||||
* @{
|
||||
*/
|
||||
volatile bool rtc_internal_tick_flag = false; /**< flag set when internal RTC ticked */
|
||||
volatile bool rtc_tick_flag = false; /**< flag set when RTC ticked */
|
||||
/** @} */
|
||||
|
||||
#define SQUARE_WAVE_PORT B /**< port connected to RTC DS1307 square wave output */
|
||||
#define SQUARE_WAVE_PIN 0 /**< pin connected to RTC DS1307 square wave output */
|
||||
|
||||
/** user input command */
|
||||
static char command[32] = {0};
|
||||
/** user input command index */
|
||||
|
@ -199,32 +202,42 @@ void main(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
// 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
|
||||
// disable internal RTC
|
||||
printf("disable internal RTC: ");
|
||||
rcc_periph_clock_enable(RCC_PWR); // enable power domain clock
|
||||
rcc_periph_clock_enable(RCC_BKP); // enable backup domain clock
|
||||
pwr_disable_backup_domain_write_protect(); // enable write on backup domain (including RTC)
|
||||
RCC_BDCR &= ~RCC_BDCR_RTCEN; // disable RTC
|
||||
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: %u.%02u:%02u:%02u\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
|
||||
// enable square wave output and configure input interrupt
|
||||
rtc_ds1307_write_square_wave(1); // enable 1 Hz square wave output to sync on seconds
|
||||
rcc_periph_clock_enable(RCC_GPIO(SQUARE_WAVE_PORT)); // enable clock for GPIO
|
||||
gpio_set_mode(GPIO(SQUARE_WAVE_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(SQUARE_WAVE_PIN)); // set button pin to input
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt
|
||||
exti_select_source(EXTI(SQUARE_WAVE_PIN), GPIO(SQUARE_WAVE_PORT)); // mask external interrupt of this pin only for this port
|
||||
exti_set_trigger(EXTI(SQUARE_WAVE_PIN), EXTI_TRIGGER_FALLING); // trigger on falling edge of square wave (this is also when the RTC register are updated)
|
||||
exti_enable_request(EXTI(SQUARE_WAVE_PIN)); // enable external interrupt
|
||||
nvic_enable_irq(NVIC_EXTI_IRQ(SQUARE_WAVE_PIN)); // enable interrupt
|
||||
printf("OK\n");
|
||||
|
||||
// display date
|
||||
uint8_t* rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
||||
uint8_t rtc_seconds = 0; // count the number of seconds passed and sync time on minute
|
||||
if (rtc_ds1307_time==NULL) {
|
||||
printf("could not get time from DS1307\n");
|
||||
} else {
|
||||
rtc_seconds = rtc_ds1307_time[0]; // remember seconds of minute
|
||||
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]);
|
||||
}
|
||||
// verify is external RTC is running
|
||||
if (rtc_ds1307_oscillator_disabled()) {
|
||||
printf("/!\\ RTC oscillator is disabled: the battery may be empty\n");
|
||||
rtc_ds1307_oscillator_enable(); // enable oscillator again
|
||||
}
|
||||
// display date
|
||||
uint8_t* rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
||||
if (rtc_ds1307_time==NULL) {
|
||||
printf("could not get time from DS1307\n");
|
||||
} else {
|
||||
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 and MAX7219 7-segments displays
|
||||
printf("setup 7-segment displays: ");
|
||||
|
@ -306,26 +319,23 @@ void main(void)
|
|||
}
|
||||
button_flag = false; // reset flag
|
||||
}
|
||||
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)
|
||||
ticks_time = rtc_get_counter_val(); // copy time from internal RTC for processing
|
||||
while (rtc_tick_flag) { // the external RTC ticked
|
||||
rtc_tick_flag = false; // reset flag
|
||||
action = true; // action has been performed
|
||||
if ((ticks_time%(60))==0) { // one minute passed
|
||||
printf("uptime: %u.%02u:%02u:%02u\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime
|
||||
}
|
||||
rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
||||
if (rtc_ds1307_time==NULL) {
|
||||
printf("could not get time from DS1307: resetting\n");
|
||||
rtc_ds1307_setup(); // resetting periph
|
||||
} else {
|
||||
if (!led_tm1637_time(rtc_ds1307_time[1], rtc_ds1307_time[0])) {
|
||||
printf("could not set time on TM1637\n");
|
||||
led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
||||
rtc_seconds++; // increment number of seconds passed
|
||||
if (rtc_seconds>=60) { // one minute passed
|
||||
rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
||||
if (rtc_ds1307_time==NULL) {
|
||||
printf("could not get time from DS1307: resetting\n");
|
||||
rtc_ds1307_setup(); // resetting periph
|
||||
} else {
|
||||
rtc_seconds = rtc_ds1307_time[0]; // get actual number of seconds
|
||||
if (0==rtc_ds1307_time[1] && 0==rtc_ds1307_time[2]) { // new day arrived
|
||||
led_max7219_number(20000000+rtc_ds1307_time[6]*10000+rtc_ds1307_time[5]*100+rtc_ds1307_time[4], 0x14, 1); // display date on 2nd display
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!led_tm1637_on()) { // switch on display
|
||||
printf("could not switch on TM1637\n");
|
||||
}
|
||||
}
|
||||
if (action) { // go to sleep if nothing had to be done, else recheck for activity
|
||||
action = false;
|
||||
|
@ -335,9 +345,9 @@ void main(void)
|
|||
} // main loop
|
||||
}
|
||||
|
||||
/** @brief interrupt service routine called when tick passed on RTC */
|
||||
void rtc_isr(void)
|
||||
void EXTI_ISR(SQUARE_WAVE_PIN)(void)
|
||||
{
|
||||
rtc_clear_flag(RTC_SEC); // clear flag
|
||||
rtc_internal_tick_flag = true; // notify to show new time
|
||||
exti_reset_request(EXTI(SQUARE_WAVE_PIN)); // reset interrupt
|
||||
rtc_tick_flag = true; // perform button action
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue