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
|
/** @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 */
|
/** user input command */
|
||||||
static char command[32] = {0};
|
static char command[32] = {0};
|
||||||
/** user input command index */
|
/** user input command index */
|
||||||
|
@ -199,32 +202,42 @@ void main(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setup internal RTC
|
// disable internal RTC
|
||||||
printf("setup internal RTC: ");
|
printf("disable 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)
|
rcc_periph_clock_enable(RCC_PWR); // enable power domain clock
|
||||||
rtc_interrupt_enable(RTC_SEC); // enable RTC interrupt on "seconds"
|
rcc_periph_clock_enable(RCC_BKP); // enable backup domain clock
|
||||||
nvic_enable_irq(NVIC_RTC_IRQ); // allow the RTC to interrupt
|
pwr_disable_backup_domain_write_protect(); // enable write on backup domain (including RTC)
|
||||||
|
RCC_BDCR &= ~RCC_BDCR_RTCEN; // disable RTC
|
||||||
printf("OK\n");
|
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
|
// setup external RTC
|
||||||
printf("setup external RTC: ");
|
printf("setup external RTC: ");
|
||||||
rtc_ds1307_setup(); // setup external RTC module
|
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");
|
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
|
// verify is external RTC is running
|
||||||
if (rtc_ds1307_oscillator_disabled()) {
|
if (rtc_ds1307_oscillator_disabled()) {
|
||||||
printf("/!\\ RTC oscillator is disabled: the battery may be empty\n");
|
printf("/!\\ RTC oscillator is disabled: the battery may be empty\n");
|
||||||
rtc_ds1307_oscillator_enable(); // enable oscillator again
|
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
|
// setup TM1637 and MAX7219 7-segments displays
|
||||||
printf("setup 7-segment displays: ");
|
printf("setup 7-segment displays: ");
|
||||||
|
@ -306,26 +319,23 @@ void main(void)
|
||||||
}
|
}
|
||||||
button_flag = false; // reset flag
|
button_flag = false; // reset flag
|
||||||
}
|
}
|
||||||
while (rtc_internal_tick_flag) { // the internal RTC ticked
|
while (rtc_tick_flag) { // the external RTC ticked
|
||||||
rtc_internal_tick_flag = false; // reset flag
|
rtc_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
|
|
||||||
action = true; // action has been performed
|
action = true; // action has been performed
|
||||||
if ((ticks_time%(60))==0) { // one minute passed
|
led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
||||||
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_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
|
rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
||||||
if (rtc_ds1307_time==NULL) {
|
if (rtc_ds1307_time==NULL) {
|
||||||
printf("could not get time from DS1307: resetting\n");
|
printf("could not get time from DS1307: resetting\n");
|
||||||
rtc_ds1307_setup(); // resetting periph
|
rtc_ds1307_setup(); // resetting periph
|
||||||
} else {
|
} else {
|
||||||
if (!led_tm1637_time(rtc_ds1307_time[1], rtc_ds1307_time[0])) {
|
rtc_seconds = rtc_ds1307_time[0]; // get actual number of seconds
|
||||||
printf("could not set time on TM1637\n");
|
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
|
if (action) { // go to sleep if nothing had to be done, else recheck for activity
|
||||||
action = false;
|
action = false;
|
||||||
|
@ -335,9 +345,9 @@ void main(void)
|
||||||
} // main loop
|
} // main loop
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief interrupt service routine called when tick passed on RTC */
|
void EXTI_ISR(SQUARE_WAVE_PIN)(void)
|
||||||
void rtc_isr(void)
|
|
||||||
{
|
{
|
||||||
rtc_clear_flag(RTC_SEC); // clear flag
|
exti_reset_request(EXTI(SQUARE_WAVE_PIN)); // reset interrupt
|
||||||
rtc_internal_tick_flag = true; // notify to show new time
|
rtc_tick_flag = true; // perform button action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue