From 4493f34d229053f41ec6301e89818406fbf09fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Thu, 5 May 2016 23:26:21 +0200 Subject: [PATCH] add time recording and decoding --- lib/rtc_dcf77.c | 95 ++++++++++++++++++++++++++++++++++++++++--------- lib/rtc_dcf77.h | 4 +++ 2 files changed, 83 insertions(+), 16 deletions(-) diff --git a/lib/rtc_dcf77.c b/lib/rtc_dcf77.c index ad4559c..856aecb 100644 --- a/lib/rtc_dcf77.c +++ b/lib/rtc_dcf77.c @@ -23,8 +23,6 @@ #include // standard integer types #include // general utilities -#include - /* STM32 (including CM3) libraries */ #include // real-time control clock library #include // general purpose input output library @@ -37,6 +35,7 @@ #include "global.h" // common methods volatile bool rtc_dcf77_time_flag = false; +volatile uint64_t rtc_dcf77_frame = 0; /**< the received DCF77 frame bits */ void rtc_dcf77_setup(void) { @@ -72,36 +71,100 @@ void rtc_dcf77_off(void) gpio_set(RTC_DCF77_ENABLE_PORT, RTC_DCF77_ENABLE_PIN); // disable module by pull pin high } +uint8_t* rtc_dcf77_time(void) +{ + static uint8_t to_return[6] = {0}; // arrays with date values to return + uint8_t parity = 0; // to check parity + if (rtc_dcf77_frame==0) { // no time received yet + return NULL; + } + if (!(rtc_dcf77_frame&(1<<20))) { // start of encode time should always be 1 + return NULL; + } + // check minute parity + parity = 0; + for (uint8_t bit=21; bit<29; bit++) { + if (rtc_dcf77_frame&(1<>21)&(0x1))+2*((rtc_dcf77_frame>>22)&(0x1))+4*((rtc_dcf77_frame>>23)&(0x1))+8*((rtc_dcf77_frame>>24)&(0x1))+10*((rtc_dcf77_frame>>25)&(0x1))+20*((rtc_dcf77_frame>>26)&(0x1))+40*((rtc_dcf77_frame>>27)&(0x1)); // read minute (00-59) + // check hour parity + parity = 0; + for (uint8_t bit=29; bit<35; bit++) { + if (rtc_dcf77_frame&(1<>29)&(0x1))+2*((rtc_dcf77_frame>>30)&(0x1))+4*((rtc_dcf77_frame>>31)&(0x1))+8*((rtc_dcf77_frame>>32)&(0x1))+10*((rtc_dcf77_frame>>33)&(0x1))+20*((rtc_dcf77_frame>>34)&(0x1)); // read hour (00-23) + // check date parity + parity = 0; + for (uint8_t bit=36; bit<57; bit++) { + if (rtc_dcf77_frame&(1<>36)&(0x1))+2*((rtc_dcf77_frame>>37)&(0x1))+4*((rtc_dcf77_frame>>38)&(0x1))+8*((rtc_dcf77_frame>>39)&(0x1))+10*((rtc_dcf77_frame>>40)&(0x1))+20*((rtc_dcf77_frame>>34)&(0x41)); // read day of the month (01-31) + to_return[3] = 1*((rtc_dcf77_frame>>42)&(0x1))+2*((rtc_dcf77_frame>>43)&(0x1))+4*((rtc_dcf77_frame>>44)&(0x1)); // read day of the week (1=Monday - 7=Sunday) + to_return[4] = 1*((rtc_dcf77_frame>>45)&(0x1))+2*((rtc_dcf77_frame>>46)&(0x1))+4*((rtc_dcf77_frame>>47)&(0x1))+8*((rtc_dcf77_frame>>48)&(0x1))+10*((rtc_dcf77_frame>>49)&(0x1)); // read month of the year (01-12) + to_return[5] = 1*((rtc_dcf77_frame>>50)&(0x1))+2*((rtc_dcf77_frame>>51)&(0x1))+4*((rtc_dcf77_frame>>52)&(0x1))+8*((rtc_dcf77_frame>>53)&(0x1))+10*((rtc_dcf77_frame>>54)&(0x1))+20*((rtc_dcf77_frame>>55)&(0x1))+40*((rtc_dcf77_frame>>56)&(0x1))+80*((rtc_dcf77_frame>>57)&(0x1)); // read year of the century (00-99) + return to_return; +} + /** @brief interrupt service routine called when signal edge is detected */ void RTC_DCF77_SIGNAL_ISR(void) { exti_reset_request(RTC_DCF77_SIGNAL_EXTI); // reset interrupt static uint16_t old_state = 0; // save last port state to detect difference static uint8_t pulse = 0; // next pulse number in the DCF77 frame - //static uint16_t pulse_rising = 0, pulse_falling = 0; // time on when the last pulse edge has been detected - static uint16_t pulse_rising = 0; + static uint16_t pulse_edge = 0; // time on when the last pulse (rising edge) has been detected + static uint64_t rtc_dcf77_frame_tmp = 0; // the DCF77 frame bits as they get filled uint16_t time = timer_get_counter(RTC_DCF77_TIMER); // get timer value uint16_t new_state = gpio_get(RTC_DCF77_SIGNAL_PORT, RTC_DCF77_SIGNAL_PIN); // save last port state to detect difference if (old_state!=new_state) { // pulse edge detected + time = (uint32_t)(time-pulse_edge)*RTC_DCF77_TIMER_MAX_TIME/(1<<16); // get time since last rising edge (integer underflow possible) if (new_state) { // rising edge - time = (uint32_t)(time-pulse_rising)*RTC_DCF77_TIMER_MAX_TIME/(1<<16); // get time since last rising edge (integer underflow possible) - if (time < 900) { // ignore glitches - goto end; - } else if (time < 1100) { // a normal pulse - pulse = (pulse+1)%59; // go to next pulse (there should be no more than 59) - } else if (time < 1900) { // ignore glitch - goto end; - } else if (time < 2100) { // first pulse of a frame + if (time < 980) { // glitch + goto end; // ignore glitch + } else if (time < 1030) { // a normal pulse + pulse++; // go to next pulse + if (pulse>58) { // something wrong happened + pulse = 0; // restart + } + } else if (time < 1980) { // glitch + goto end; // ignore glitch + } else if (time < 2130) { // first pulse of a frame + if (pulse==58) { // full frame received + rtc_dcf77_frame = rtc_dcf77_frame_tmp; // save received complete frame + rtc_dcf77_time_flag = true; // notify user + } pulse = 0; } else { // something is wrong, restart pulse = 0; } - led_toggle(); - pulse_rising = 0; // save new edge + pulse_edge = 0; // save new edge timer_set_counter(RTC_DCF77_TIMER, 0); // reset timer to count - printf("%u\n", pulse); - } + } else { // falling edge + if (time < 90) { // glitch + goto end; // ignore glitch + } else if (time < 120) { // 0 received + rtc_dcf77_frame_tmp &= ~((uint64_t)1<