Duncan Wood / MSF_Time
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MSF_Time.cpp Source File

MSF_Time.cpp

00001 /*This library will decode an MSF signal on a digital input pin and turn it
00002 into a timestamp.
00003 Copyright (C) 2017 Duncan Wood
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00020 
00021 
00022 
00023 
00024 #ifndef MSF_Time_h
00025 #define MSF_Time_h
00026 
00027 #include "mbed.h"
00028 #include "MSF_Time.h"
00029 
00030 MSF_Time::MSF_Time(PinName InputPin, int polarity, int OffsetTuning)
00031     : Time_Data(InputPin), Polarity(polarity), OffsetTuning(OffsetTuning),
00032       MyInput(InputPin)
00033 {
00034     DataValid=false;
00035     Time_Data_Count=0;
00036     Time_Data_Duration=0x0000;
00037     Time_Data.fall(this, &MSF_Time::Falling);
00038     Time_Data.rise(this, &MSF_Time::Rising);
00039     Received_timestamp=0;  //set time to zero until we can set it properly
00040     MyData.BCDMonth=0;
00041     MyData.BCDTime=0;
00042     MyData.BCDYear=0;
00043     MyData.SyncByte=0;
00044     MyData.DayOfWeek=0;
00045     MyData.BST=0;
00046     MyData.DUT=0;
00047 
00048 }
00049 
00050 void MSF_Time::Rising()
00051 {
00052     if (Polarity==0) {
00053         LogicOne();
00054     } else {
00055         LogicZero();
00056     }
00057 
00058 
00059 }
00060 void MSF_Time::LogicOne()  //When there is no carrier (pulse every second)
00061 {
00062     Time_Data_timer.reset();
00063     Time_Data_timer.start();
00064 }
00065 void MSF_Time::LogicZero()  // When carrier is present (most of the time)
00066 {
00067     Time_Data_timer.stop();
00068     Time_Data_Duration=Time_Data_timer.read_us();
00069     // Test for the 500ms minute sync pulse
00070     if (Time_Data_Duration > 450000 && Time_Data_Duration < 550000 ) { // +/-50ms for now
00071         Received_Time.tm_sec=0;  //set time to zero until we can set it properly
00072         Time_Data_Count=0;
00073         MyData.BCDMonth=0;
00074         MyData.BCDTime=0;
00075         MyData.BCDYear=0;
00076         MyData.SyncByte=0;
00077         MyData.DayOfWeek=0;
00078         Time_Data_Sync=true;
00079         Time_Data_Ticker.attach(this, &MSF_Time::Time_Data_Strobe,0.05); // start a timer to read data
00080     }
00081 }
00082 void MSF_Time::Falling()
00083 {
00084     if (Polarity==0) {
00085         LogicZero();
00086     } else {
00087         LogicOne();
00088     }
00089 
00090 }
00091 
00092 void MSF_Time::IncrementSeconds()
00093 {
00094     // called 50ms ish before the second.  Add delay of 50ms ish.
00095     offset.attach_us(this, &MSF_Time::IncrementSecondsNow,OffsetTuning);
00096 }
00097 void MSF_Time::IncrementSecondsNow()
00098 {
00099     Received_timestamp++;
00100     if (DV) { //this is the signal to set time now at 00 seconds
00101         DV=false;
00102         Received_Time.tm_sec=0;
00103         Received_timestamp=mktime(&Received_Time);
00104         if (Received_timestamp != -1 ) {//0x80000001
00105             DataValid=true;
00106         }
00107     }
00108 }
00109 
00110 
00111 void MSF_Time::Time_Data_Strobe()
00112 {
00113     Time_Data_Count++;
00114     switch(Time_Data_Count) {
00115         case 1:
00116             break;
00117         case 9: //zero seconds
00118             IncrementSeconds();
00119             break;
00120             //case 13://01A
00121             //case 15://01B DUT1+
00122             //break;
00123         case 29:// Incerment seconds
00124             IncrementSeconds();
00125             break;
00126             //case 33://02A
00127             //case 35://02B DUT1+
00128             //break;
00129         case 49:
00130             IncrementSeconds();
00131             break;
00132             //case 53://03A
00133             //case 55://03B DUT1+
00134             //break;
00135         case 69:
00136             IncrementSeconds();
00137             break;
00138             //case 73://04A
00139             //case 75://04B DUT1+
00140         case 89:
00141             IncrementSeconds();
00142             break;
00143             //case 93://05A
00144             //case 95://05B DUT1+
00145         case 109:
00146             IncrementSeconds();
00147             break;
00148             //case 113://06A
00149             //case 115://06B DUT1+
00150         case 129:
00151             IncrementSeconds();
00152             break;
00153             //case 133://07A
00154             //case 135://07B DUT1+
00155         case 149:
00156             IncrementSeconds();
00157             break;
00158             //case 153://08A
00159             //case 155://08B DUT1+
00160         case 169:
00161             IncrementSeconds();
00162             break;
00163             //case 173://09A
00164             //case 175://09B DUT1-
00165         case 189:
00166             IncrementSeconds();
00167             break;
00168             //case 193://10A
00169             //case 195://10B DUT1-
00170         case 209:
00171             IncrementSeconds();
00172             break;
00173             //case 213://11A
00174             //case 215://11B DUT1-
00175         case 229:
00176             IncrementSeconds();
00177             break;
00178             //case 233://12A
00179             //case 235://12B DUT1-
00180         case 249:
00181             IncrementSeconds();
00182             break;
00183             //case 253://13A
00184             //case 255://13B DUT1-
00185         case 269:
00186             IncrementSeconds();
00187             break;
00188             //case 273://14A
00189             //case 275://14B DUT1-
00190         case 289:
00191             IncrementSeconds();
00192             break;
00193             //case 293://15A
00194             //case 295://15B DUT1-
00195         case 309:
00196             IncrementSeconds();
00197             break;
00198         case 313://16A
00199             MyData.BCDYear+= MyInput.read()^Polarity;
00200             //leap second
00201             break;
00202             //case 315://16B DUT1-
00203         case 329:
00204             IncrementSeconds();
00205             break;
00206         case 333://17A Year 80
00207             MyData.BCDYear=MyData.BCDYear << 1;
00208             MyData.BCDYear+= MyInput.read()^Polarity;
00209 
00210             break;
00211             //case 335://17B
00212         case 349:
00213             IncrementSeconds();
00214             break;
00215         case 353://18A Year 40
00216             MyData.BCDYear=MyData.BCDYear << 1;
00217             MyData.BCDYear+= MyInput.read()^Polarity;
00218             break;
00219             //case 355://18B
00220         case 369:
00221             IncrementSeconds();
00222             break;
00223         case 373://19A Year 20
00224             MyData.BCDYear=MyData.BCDYear << 1;
00225             MyData.BCDYear+= MyInput.read()^Polarity;
00226             break;
00227             //case 375://19B
00228         case 389:
00229             IncrementSeconds();
00230             break;
00231         case 393://20A Year 10
00232             MyData.BCDYear=MyData.BCDYear << 1;
00233             MyData.BCDYear+= MyInput.read()^Polarity;
00234             break;
00235             //case 395://20B
00236         case 409:
00237             IncrementSeconds();
00238             break;
00239         case 413://21A Year 8
00240             MyData.BCDYear=MyData.BCDYear << 1;
00241             MyData.BCDYear+= MyInput.read()^Polarity;
00242             break;
00243             //case 415://21B
00244         case 429:
00245             IncrementSeconds();
00246             break;
00247         case 433://22A Year 4
00248             MyData.BCDYear=MyData.BCDYear << 1;
00249             MyData.BCDYear+= MyInput.read()^Polarity;
00250             break;
00251             //case 435://22B
00252         case 449:
00253             IncrementSeconds();
00254             break;
00255         case 453://23A Year 2
00256             MyData.BCDYear=MyData.BCDYear << 1;
00257             MyData.BCDYear+= MyInput.read()^Polarity;
00258             break;
00259             //case 455://23B
00260         case 469:
00261             IncrementSeconds();
00262             break;
00263         case 473://24A Year 1
00264             MyData.BCDYear=MyData.BCDYear << 1;
00265             MyData.BCDYear+= MyInput.read()^Polarity;
00266             MyData.BCDMonth+= MyInput.read()^Polarity;; //leap second minus
00267 
00268             break;
00269             //case 475://24B
00270 
00271         case 489:
00272             IncrementSeconds();
00273             break;
00274         case 493://25A Month 10
00275             MyData.BCDMonth=MyData.BCDMonth << 1;
00276             MyData.BCDMonth+= MyInput.read()^Polarity;
00277 
00278             MyData.BCDYear=MyData.BCDYear << 1;
00279             MyData.BCDYear+= MyInput.read()^Polarity; //leap second
00280             break;
00281 
00282             //case 495://25B
00283 
00284         case 509:
00285             IncrementSeconds();
00286             break;
00287         case 513://26A Month 8
00288             MyData.BCDMonth=MyData.BCDMonth << 1;
00289             MyData.BCDMonth+= MyInput.read()^Polarity;
00290             break;
00291             //case 515://26B
00292         case 529:
00293             IncrementSeconds();
00294             break;
00295         case 533://27A Month 4
00296             MyData.BCDMonth=MyData.BCDMonth << 1;
00297             MyData.BCDMonth+= MyInput.read()^Polarity;
00298             break;
00299             //case 535://27B
00300         case 549:
00301             IncrementSeconds();
00302             break;
00303         case 553://28A Month 2
00304             MyData.BCDMonth=MyData.BCDMonth << 1;
00305             MyData.BCDMonth+= MyInput.read()^Polarity;
00306             break;
00307             //case 555://28B
00308         case 569:
00309             IncrementSeconds();
00310             break;
00311         case 573://29A Month 1
00312             MyData.BCDMonth=MyData.BCDMonth << 1;
00313             MyData.BCDMonth+= MyInput.read()^Polarity;
00314             break;
00315             //case 575://29B
00316         case 589:
00317             IncrementSeconds();
00318             break;
00319         case 593://30A Day of Month 20
00320             MyData.BCDMonth=MyData.BCDMonth << 1;
00321             MyData.BCDMonth+= MyInput.read()^Polarity;
00322             break;
00323             //case 595://30B
00324         case 609:
00325             IncrementSeconds();
00326             break;
00327         case 613://31A Day of Month 10
00328             MyData.BCDMonth=MyData.BCDMonth << 1;
00329             MyData.BCDMonth+= MyInput.read()^Polarity;
00330             break;
00331             //case 615://31B
00332         case 629:
00333             IncrementSeconds();
00334             break;
00335         case 633://32A Day of Month 8
00336             MyData.BCDMonth=MyData.BCDMonth << 1;
00337             MyData.BCDMonth+= MyInput.read()^Polarity;
00338             break;
00339             //case 635://32B
00340         case 649:
00341             IncrementSeconds();
00342             break;
00343         case 653://33A Day of Month 4
00344             MyData.BCDMonth=MyData.BCDMonth << 1;
00345             MyData.BCDMonth+= MyInput.read()^Polarity;
00346             break;
00347             //case 655://33B
00348         case 669:
00349             IncrementSeconds();
00350             break;
00351         case 673://34A Day of Month 2
00352             MyData.BCDMonth=MyData.BCDMonth << 1;
00353             MyData.BCDMonth+= MyInput.read()^Polarity;
00354             break;
00355             //case 675://34B
00356         case 689:
00357             IncrementSeconds();
00358             break;
00359         case 693://35A Day of Month 1
00360             MyData.BCDMonth=MyData.BCDMonth << 1;
00361             MyData.BCDMonth+= MyInput.read()^Polarity;
00362             MyData.DayOfWeek+= MyInput.read()^Polarity;
00363 
00364             break;
00365             //case 695://35B
00366 
00367         case 709:
00368             IncrementSeconds();
00369             break;
00370         case 713://36A Day of Week 4
00371             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00372             MyData.DayOfWeek+= MyInput.read()^Polarity;
00373 
00374             MyData.BCDMonth=MyData.BCDMonth << 1;
00375             MyData.BCDMonth+= MyInput.read()^Polarity;
00376             break;
00377             // case 715://36B
00378 
00379         case 729:
00380             IncrementSeconds();
00381             break;
00382         case 733://37A Day of Week 2
00383             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00384             MyData.DayOfWeek+= MyInput.read()^Polarity;
00385             break;
00386             //case 735://37B
00387         case 749:
00388             IncrementSeconds();
00389             break;
00390         case 753://38A Day of Week 1
00391             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00392             MyData.DayOfWeek+= MyInput.read()^Polarity;
00393             MyData.BCDTime+= MyInput.read()^Polarity; //leap second
00394 
00395             break;
00396             //case 755://38B
00397 
00398         case 769:
00399             IncrementSeconds();
00400             break;
00401         case 773://39A Hour 20
00402             MyData.BCDTime=MyData.BCDTime << 1;
00403             MyData.BCDTime+= MyInput.read()^Polarity;
00404 
00405             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00406             MyData.DayOfWeek+= MyInput.read()^Polarity;  //leap second
00407             break;
00408 
00409             //case 775://39B
00410 
00411         case 789:
00412             IncrementSeconds();
00413             break;
00414         case 793://40A Hour 10
00415             MyData.BCDTime=MyData.BCDTime << 1;
00416             MyData.BCDTime+= MyInput.read()^Polarity;
00417             break;
00418             //case 795://40B
00419         case 809:
00420             IncrementSeconds();
00421             break;
00422         case 813://41A Hour 8
00423             MyData.BCDTime=MyData.BCDTime << 1;
00424             MyData.BCDTime+= MyInput.read()^Polarity;
00425             break;
00426             //case 815://41B
00427         case 829:
00428             IncrementSeconds();
00429             break;
00430         case 833://42A Hour 4
00431             MyData.BCDTime=MyData.BCDTime << 1;
00432             MyData.BCDTime+= MyInput.read()^Polarity;
00433             break;
00434             //case 835://42B
00435         case 849:
00436             IncrementSeconds();
00437             break;
00438         case 853://43A Hour 2
00439             MyData.BCDTime=MyData.BCDTime << 1;
00440             MyData.BCDTime+= MyInput.read()^Polarity;
00441             break;
00442             //case 855://43B
00443         case 869:
00444             IncrementSeconds();
00445             break;
00446         case 873://44A Hour 1
00447             MyData.BCDTime=MyData.BCDTime << 1;
00448             MyData.BCDTime+= MyInput.read()^Polarity;
00449             break;
00450             //case 875://44B
00451         case 889:
00452             IncrementSeconds();
00453             break;
00454         case 893://45A Minute 40
00455             MyData.BCDTime=MyData.BCDTime << 1;
00456             MyData.BCDTime+= MyInput.read()^Polarity;
00457             break;
00458             //case 895://45B
00459         case 909:
00460             IncrementSeconds();
00461             break;
00462         case 913://46A Minute 20
00463             MyData.BCDTime=MyData.BCDTime << 1;
00464             MyData.BCDTime+= MyInput.read()^Polarity;
00465             break;
00466             //case 915://46B
00467         case 929:
00468             IncrementSeconds();
00469             break;
00470         case 933://47A Minute 10
00471             MyData.BCDTime=MyData.BCDTime << 1;
00472             MyData.BCDTime+= MyInput.read()^Polarity;
00473             break;
00474             //case 935://47B
00475         case 949:
00476             IncrementSeconds();
00477             break;
00478         case 953://48A Minute 8
00479             MyData.BCDTime=MyData.BCDTime << 1;
00480             MyData.BCDTime+= MyInput.read()^Polarity;
00481             break;
00482             //case 955://48B
00483         case 969:
00484             IncrementSeconds();
00485             break;
00486         case 973://49A Minute 4
00487             MyData.BCDTime=MyData.BCDTime << 1;
00488             MyData.BCDTime+= MyInput.read()^Polarity;
00489             break;
00490             //case 975://49B
00491         case 989:
00492             IncrementSeconds();
00493             break;
00494         case 993://50A Minute 2
00495             MyData.BCDTime=MyData.BCDTime << 1;
00496             MyData.BCDTime+= MyInput.read()^Polarity;
00497             break;
00498             //case 995://50B
00499 
00500         case 1009:
00501             IncrementSeconds();
00502             break;
00503         case 1013://51A Minute 1
00504             MyData.BCDTime=MyData.BCDTime << 1;
00505             MyData.BCDTime+= MyInput.read()^Polarity;
00506             MyData.SyncByte+= MyInput.read()^Polarity;  // Or is it a leap second
00507 
00508             break;
00509             //case 1015://51B
00510 
00511         case 1029:
00512             IncrementSeconds();
00513             break;
00514         case 1033://52A  set to 0
00515             MyData.SyncByte=MyData.SyncByte <<1;
00516             MyData.SyncByte+= MyInput.read()^Polarity;
00517 
00518             MyData.BCDTime=MyData.BCDTime << 1;
00519             MyData.BCDTime+= MyInput.read()^Polarity; //leap second
00520             break;
00521             //case 1035://52B
00522         case 1049:
00523             IncrementSeconds();
00524             break;
00525         case 1053://53A  set to 1
00526             MyData.SyncByte=MyData.SyncByte <<1;
00527             MyData.SyncByte+= MyInput.read()^Polarity;
00528 
00529             break;
00530         case 1055://53B  Change of summertime soon
00531             // Fortunately leap seconds are never added in spring or autumn
00532             MyData.BCDYear=MyData.BCDYear << 1;
00533             MyData.BCDYear+= MyInput.read()^Polarity;
00534             break;
00535         case 1069:
00536             IncrementSeconds();
00537             break;
00538 
00539 
00540         case 1073://54A  set to 1
00541             MyData.SyncByte=MyData.SyncByte <<1;
00542             MyData.SyncByte+= MyInput.read()^Polarity;
00543 
00544             break;
00545         case 1075://54B  Year Parity
00546             MyData.BCDYear=MyData.BCDYear << 1;
00547             MyData.BCDYear+= MyInput.read()^Polarity;
00548             MyData.BCDMonth=MyData.BCDMonth << 1;
00549             MyData.BCDMonth+= MyInput.read()^Polarity;
00550             break;
00551         case 1089:
00552             IncrementSeconds();
00553             break;
00554 
00555         case 1093://55A  set to 1
00556             MyData.SyncByte=MyData.SyncByte <<1;
00557             MyData.SyncByte+= MyInput.read()^Polarity;
00558 
00559             break;
00560         case 1095://55B  Month Parity
00561             MyData.BCDMonth=MyData.BCDMonth << 1;
00562             MyData.BCDMonth+= MyInput.read()^Polarity;
00563             MyData.BCDYear=MyData.BCDYear << 1;
00564             MyData.BCDYear+= MyInput.read()^Polarity;
00565             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00566             MyData.DayOfWeek+= MyInput.read()^Polarity;
00567             break;
00568         case 1109:
00569             IncrementSeconds();
00570             break;
00571         case 1113://56A  set to 1
00572             MyData.SyncByte=MyData.SyncByte <<1;
00573             MyData.SyncByte+= MyInput.read()^Polarity;
00574 
00575             break;
00576         case 1115://56B  day of Week Parity
00577             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00578             MyData.DayOfWeek+= MyInput.read()^Polarity;
00579             MyData.BCDMonth=MyData.BCDMonth << 1;
00580             MyData.BCDMonth+= MyInput.read()^Polarity;
00581             MyData.BCDTime=MyData.BCDTime << 1;
00582             MyData.BCDTime+= MyInput.read()^Polarity;
00583             break;
00584         case 1129:
00585             IncrementSeconds();
00586             break;
00587         case 1133://57A  set to 1
00588             MyData.SyncByte=MyData.SyncByte <<1;
00589             MyData.SyncByte+= MyInput.read()^Polarity;
00590 
00591             break;
00592         case 1135://57B  Time - hour minute parity
00593             MyData.BCDTime=MyData.BCDTime << 1;
00594             MyData.BCDTime+= MyInput.read()^Polarity;
00595             MyData.DayOfWeek=MyData.DayOfWeek <<1;
00596             MyData.DayOfWeek+= MyInput.read()^Polarity;
00597             break;
00598         case 1149:
00599             IncrementSeconds();
00600             break;
00601         case 1153://58A  set to 1
00602             MyData.SyncByte=MyData.SyncByte <<1;
00603             MyData.SyncByte+= MyInput.read()^Polarity;
00604 
00605 
00606             break;
00607         case 1155://58B  British Summertime
00608             MyData.BCDTime=MyData.BCDTime << 1;
00609             MyData.BCDTime+= MyInput.read()^Polarity;
00610             MyData.BST=MyInput.read()^Polarity;
00611 
00612             break;
00613         case 1169:
00614             IncrementSeconds();
00615             ProcessData();// if success count will be stopped but increment will still happen
00616             break;
00617         case 1173://59A  set to 0
00618             MyData.SyncByte=MyData.SyncByte <<1;
00619             MyData.SyncByte+= MyInput.read()^Polarity;
00620             break;
00621             // case 1175://59B
00622         case 1189:
00623             IncrementSeconds();
00624             ProcessData();
00625             break;
00626         case 1193://60A
00627             MyData.SyncByte=MyData.SyncByte <<1;
00628             MyData.SyncByte+= MyInput.read()^Polarity; //
00629             break;
00630             //   case 1195://60B
00631         case 1209:
00632             IncrementSeconds();
00633             ProcessData();
00634             // End stop
00635             // On a leap second we should count extra but not dealing with it
00636             // so for one minute time will be out by a second.
00637             Time_Data_Ticker.detach();
00638             Time_Data_Count=0; // Should stop this being called more than once
00639             DataValid=false;  //no data received
00640 
00641     }
00642 }
00643 
00644 int MSF_Time::ParityCheck(unsigned int CheckMe)   //0=even 1= odd naturally
00645 {
00646 // My parity is going to check 16 bit feel free to add more
00647 // Stolen shamelessly from internet
00648 //x ^= x >> 16;
00649 //x ^= x >> 8;
00650 //x ^= x >> 4;
00651 //x ^= x >> 2;
00652 //x ^= x >> 1;
00653 //return (~x) & 1;
00654     CheckMe^=CheckMe>>8;
00655     CheckMe^=CheckMe>>4;
00656     CheckMe^=CheckMe>>2;
00657     CheckMe^=CheckMe>>1;
00658     CheckMe&=1;// 1=odd 0=even
00659 
00660     return CheckMe;
00661 }
00662 
00663 void MSF_Time::ProcessData()
00664 {
00665     DV=false;
00666     int shift=0; // by how much to shift just to leave data
00667 
00668  
00669     // Find sync
00670     // sync data is 01111110
00671     if ((MyData.SyncByte&0x0FF) == 0x07E) { // sync byte
00672 
00673         /* There are 3 processdata calls.  The ticker will be either
00674         1155 or 1173 or 1193.  If it is on time or late, extra data will
00675         have been collected.  We shall get rid.*/
00676     } else {
00677         if (Time_Data_Count==1193) {
00678             //pc.printf("last chance of sync failed - data not valid");
00679             DataValid=false;
00680         }
00681         return;
00682     }
00683 
00684     if (Time_Data_Count==1169) { //leap second early
00685         shift=2;
00686 
00687     }
00688     if (Time_Data_Count==1189) {
00689         shift=1;
00690 
00691     }
00692     if (Time_Data_Count==1209) {
00693         shift=0;
00694     }
00695     Time_Data_Ticker.detach();
00696     Time_Data_Count=0; // Should stop this being called more than once
00697     MyData.BCDYear>>=shift;
00698     MyData.BCDMonth>>=shift;
00699     MyData.DayOfWeek>>=shift;
00700     MyData.BCDTime>>=shift;
00701     MyData.BCDYear&=0x7F9 ; //8 bits +2 rubbish + parity
00702     MyData.BCDMonth&=0x3FF9;       // 11 bits +2 rubbish + parity
00703     MyData.DayOfWeek&=0x039 ;   //3 bits +2 rubbish  + parity
00704     MyData.BCDTime&=0xFFF9; // 13bits +2 rubbish + parity
00705 
00706     if (ParityCheck(MyData.BCDYear) &&
00707             ParityCheck(MyData.BCDMonth) &&
00708             ParityCheck(MyData.DayOfWeek) &&
00709             ParityCheck(MyData.BCDTime) ) {
00710         // Parity ok - remove parity bits
00711         MyData.BCDYear>>=3;
00712         MyData.BCDMonth>>=3;
00713         MyData.DayOfWeek>>=3;
00714         MyData.BCDTime>>=3;
00715         DV=true;
00716     } else {
00717         DataValid=false; //sync but parity fail
00718         return;
00719     }
00720 
00721     //Convert BCD to binary
00722     // pc.printf("Year Month DOW Time\n\r");
00723 //pc.printf("%x %x %x %x\n\r",MyData.BCDYear,MyData.BCDMonth,MyData.DayOfWeek,MyData.BCDTime);
00724     if (DV) {
00725         Received_Time.tm_year=100+(MyData.BCDYear & 0x0F)+(10*((MyData.BCDYear>>4) & 0x01)) ; //years _since_ 1900
00726         Received_Time.tm_mon=((MyData.BCDMonth>>6) & 0x0F)+(10*((MyData.BCDMonth>>10) & 0x01))-1;
00727         Received_Time.tm_mday=(MyData.BCDMonth & 0x0F)+(10*((MyData.BCDMonth>>4) & 0x03)) ;
00728         Received_Time.tm_hour=((MyData.BCDTime>>7)& 0x0F)+(10*((MyData.BCDTime>>11) & 0x03));
00729         Received_Time.tm_min=(MyData.BCDTime&0x0F)+(10*((MyData.BCDTime>>4) & 0x07));
00730         Received_Time.tm_wday = (MyData.DayOfWeek&0x07);
00731         Received_Time.tm_sec=0;
00732     }
00733 }
00734 bool MSF_Time::Valid()
00735 {
00736     //if (DataValid) pc.printf("Data Valid\n\r");
00737 
00738     return DataValid;
00739 }
00740 time_t MSF_Time::Read()
00741 {
00742     // pc.printf("Received ts %s\n\r",ctime(&Received_timestamp));
00743     return Received_timestamp;
00744 }
00745 #endif
00746