dcf routines for microbit

Fork of microbit-dcf by Kurt Schuster

Revision:
4:eda8c18d0564
Parent:
3:baecb5137d1a
--- a/dcf.cpp	Fri Feb 24 07:52:08 2017 +0000
+++ b/dcf.cpp	Sat Feb 25 16:57:37 2017 +0000
@@ -1,7 +1,10 @@
-// dcf V0.3 170224 qrt@qland.de
+// dcf V0.6 170225 qrt@qland.de
 //
 // V0.1     initial version
 // V0.3     automatic sec correction
+// V0.4     refined sec correction
+// V0.5     returned to simple sec correction, added lost signal sync
+// V0.6     ticker and timer use
 
 #include "dcf.h"
 
@@ -26,20 +29,15 @@
 uint8_t Dcf::status;               
 uint8_t Dcf::bit;               
 uint8_t Dcf::parity;               
-uint16_t Dcf::secMs;
+
+uint32_t Dcf::dt;
 
-uint32_t Dcf::nextSec;
-uint32_t Dcf::secStart;
-uint32_t Dcf::secStartL;
-uint32_t Dcf::bitEnd;
-uint32_t Dcf::incStart;
-uint32_t Dcf::ct;
-uint32_t Dcf::dt;
+Ticker ticker;
+Timer timer;
 
 void Dcf::init(MicroBit *_uBit)
 {
     uBit = _uBit;
-    secMs = 1000;
 }
 
 void Dcf::receive()
@@ -56,51 +54,51 @@
 
     uBit->io.P16.eventOn(MICROBIT_PIN_EVENT_ON_EDGE);
 
-    while(true){
-        ct = uBit->systemTime();
+    ticker.attach(&service, 1);                             // attach sec ticker
+    timer.start();                                          // start sec timer                               
+
+    while(true)
+        fiber_sleep(1000);                                  // sleep 
+}
 
-        if(ct >= nextSec){                                  // wait for next second
-            incStart = ct;                                  // store current time
-            nextSec += secMs;                               // next second start
-            incTime();                                      // increment time
+void Dcf::service()
+{
+    incTime();
 
-            if(status&SYNCDAV && min==58 && sec==50)        // hourly sync, no new sync while data not verified
-                status &= SYNCRES;                          
-        }
-
-        fiber_sleep(SYSTEM_TICK_PERIOD_MS);                 // sleep with shortest interval (defined in MicroBitConfig.h)
-    }
+    if(status&SYNCDAV && min==58 && sec==50)                // no new sync while data not verified                  
+        status &= SYNCRES;                                  // hourly sync, lost signal sync after LOSIGT ms
 }
 
 void Dcf::secPulse(MicroBitEvent e)
 {
-    secStart = uBit->systemTime();
+    dt = timer.read_ms();                                   // get last timer
+    timer.reset();                                          // restart
 
     if(!(status & SYNCINI)){                                // ignore first pulses after poweron
-        if(++parity == 10)                                  // parity used as init counter
+        if(++parity == IGNOPU)                              // parity used as init counter
             status |= SYNCINI;      
     }       
     else if(!(status & SYNCSEC)){                           // sec sync
-        nextSec = secStart + secMs;       
+        ticker.detach();                                    // detach ticker        
+        ticker.attach(&service, 1);                         // attach
         status |= SYNCSEC;      
     }       
     else if(!(status & SYNC59)){                            // sec 59 sync
-        dt = secStart - secStartL;        
-
-        if(dt>1950 && dt<2050){     
+        if(dt>1950 && dt<2050){                             // 2000 ms +- 50 ms
             hsec = 0;                                       // start data capture
             parity = 0;
             status |= SYNC59;
         }
     }
     else if((status & (SYNCDAR | SYNCDAT)) == SYNCDAR){     // data ready, but not taken
-        nextSec = secStart + secMs;                         // prepare next second
+        ticker.detach();                                    // detach ticker        
         takeData();                                         // take data
+        ticker.attach(&service, 1);                         // attach ticker
         status |= SYNCDAT;                                  // data taken
 
         hsec = 0;                                           // start data verify
         parity = 0;
-        status &= ~SYNCDAR;
+        status &= ~SYNCDAR;             
     }
     else if((status & (SYNCDAR | SYNCDAV)) == SYNCDAR){     // data ready, but not verified                          
         if(verifyData())                                    // verify data
@@ -108,50 +106,8 @@
         else
             status |= SYNCDAV;                              // data verified
     }
-
-    if(status & SYNCSEC){                                   // sec sync correction
-        if(secStart>incStart && secStart-incStart>secMs/2)
-            incStart += secMs;
-
-        if(secStart > incStart){ 
-            nextSec += SYSTEM_TICK_PERIOD_MS; 
-            if(secMs < 1050) secMs++;
-        }
-        else if(secStart < incStart){
-            nextSec -= SYSTEM_TICK_PERIOD_MS; 
-            if(secMs > 950) secMs--; 
-        }
-    }
-
-    secStartL = secStart;
 }
 
-// if(status & SYNCSEC){                                   // sec sync correction
-//     if(secStart>incStart && secStart-incStart>secMs/2)
-//         incStart += secMs;
-
-//     tester = 0;
-//
-//     if(secStart > incStart)
-//             { nextSec+=6; tester=1; }
-//     else if(secStart < incStart)
-//             { nextSec-=6; tester=2; }
-//
-//     dt = secStart - secStartL;
-//
-//     if(dt>950 && dt<1050){
-//         if(dt > secMs)
-//             secMs++;
-//         else if(dt < secMs)
-//             secMs--;
-//     }
-// }
-
-// if(status & SYNCSEC){                                   // sec sync correction
-//     if(secStart-secStartL < 1500)
-//         secMs = secStart - secStartL;
-// }
-
 void Dcf::bitPulse(MicroBitEvent e)
 {
     if((status & (SYNC59 | SYNCDAR)) == SYNC59){            // SYNC59 done, data not ready
@@ -199,7 +155,7 @@
 //
 uint8_t Dcf::getData()
 {
-    dt = uBit->systemTime() - secStart;                   // pulse lenth
+    dt = timer.read_ms();                                   // bit length
 
     if(dt>80 && dt<140)                                     // zero
         bit = 0;