Library to decode MSF time signal.

Committer:
dswood
Date:
Fri Jan 07 12:12:25 2022 +0000
Revision:
0:340305453f64
A simple library to decode MSF time signal. Probably useful for DSF

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dswood 0:340305453f64 1 /*This library will decode an MSF signal on a digital input pin and turn it
dswood 0:340305453f64 2 into a timestamp.
dswood 0:340305453f64 3 Copyright (C) 2017 Duncan Wood
dswood 0:340305453f64 4
dswood 0:340305453f64 5 This library is free software; you can redistribute it and/or
dswood 0:340305453f64 6 modify it under the terms of the GNU Lesser General Public
dswood 0:340305453f64 7 License as published by the Free Software Foundation; either
dswood 0:340305453f64 8 version 2.1 of the License, or (at your option) any later version.
dswood 0:340305453f64 9
dswood 0:340305453f64 10 This library is distributed in the hope that it will be useful,
dswood 0:340305453f64 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
dswood 0:340305453f64 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dswood 0:340305453f64 13 Lesser General Public License for more details.
dswood 0:340305453f64 14
dswood 0:340305453f64 15 You should have received a copy of the GNU Lesser General Public
dswood 0:340305453f64 16 License along with this library; if not, write to the Free Software
dswood 0:340305453f64 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
dswood 0:340305453f64 18 */
dswood 0:340305453f64 19
dswood 0:340305453f64 20
dswood 0:340305453f64 21
dswood 0:340305453f64 22
dswood 0:340305453f64 23
dswood 0:340305453f64 24 #ifndef MSF_Time_h
dswood 0:340305453f64 25 #define MSF_Time_h
dswood 0:340305453f64 26
dswood 0:340305453f64 27 #include "mbed.h"
dswood 0:340305453f64 28 #include "MSF_Time.h"
dswood 0:340305453f64 29
dswood 0:340305453f64 30 MSF_Time::MSF_Time(PinName InputPin, int polarity, int OffsetTuning)
dswood 0:340305453f64 31 : Time_Data(InputPin), Polarity(polarity), OffsetTuning(OffsetTuning),
dswood 0:340305453f64 32 MyInput(InputPin)
dswood 0:340305453f64 33 {
dswood 0:340305453f64 34 DataValid=false;
dswood 0:340305453f64 35 Time_Data_Count=0;
dswood 0:340305453f64 36 Time_Data_Duration=0x0000;
dswood 0:340305453f64 37 Time_Data.fall(this, &MSF_Time::Falling);
dswood 0:340305453f64 38 Time_Data.rise(this, &MSF_Time::Rising);
dswood 0:340305453f64 39 Received_timestamp=0; //set time to zero until we can set it properly
dswood 0:340305453f64 40 MyData.BCDMonth=0;
dswood 0:340305453f64 41 MyData.BCDTime=0;
dswood 0:340305453f64 42 MyData.BCDYear=0;
dswood 0:340305453f64 43 MyData.SyncByte=0;
dswood 0:340305453f64 44 MyData.DayOfWeek=0;
dswood 0:340305453f64 45 MyData.BST=0;
dswood 0:340305453f64 46 MyData.DUT=0;
dswood 0:340305453f64 47
dswood 0:340305453f64 48 }
dswood 0:340305453f64 49
dswood 0:340305453f64 50 void MSF_Time::Rising()
dswood 0:340305453f64 51 {
dswood 0:340305453f64 52 if (Polarity==0) {
dswood 0:340305453f64 53 LogicOne();
dswood 0:340305453f64 54 } else {
dswood 0:340305453f64 55 LogicZero();
dswood 0:340305453f64 56 }
dswood 0:340305453f64 57
dswood 0:340305453f64 58
dswood 0:340305453f64 59 }
dswood 0:340305453f64 60 void MSF_Time::LogicOne() //When there is no carrier (pulse every second)
dswood 0:340305453f64 61 {
dswood 0:340305453f64 62 Time_Data_timer.reset();
dswood 0:340305453f64 63 Time_Data_timer.start();
dswood 0:340305453f64 64 }
dswood 0:340305453f64 65 void MSF_Time::LogicZero() // When carrier is present (most of the time)
dswood 0:340305453f64 66 {
dswood 0:340305453f64 67 Time_Data_timer.stop();
dswood 0:340305453f64 68 Time_Data_Duration=Time_Data_timer.read_us();
dswood 0:340305453f64 69 // Test for the 500ms minute sync pulse
dswood 0:340305453f64 70 if (Time_Data_Duration > 450000 && Time_Data_Duration < 550000 ) { // +/-50ms for now
dswood 0:340305453f64 71 Received_Time.tm_sec=0; //set time to zero until we can set it properly
dswood 0:340305453f64 72 Time_Data_Count=0;
dswood 0:340305453f64 73 MyData.BCDMonth=0;
dswood 0:340305453f64 74 MyData.BCDTime=0;
dswood 0:340305453f64 75 MyData.BCDYear=0;
dswood 0:340305453f64 76 MyData.SyncByte=0;
dswood 0:340305453f64 77 MyData.DayOfWeek=0;
dswood 0:340305453f64 78 Time_Data_Sync=true;
dswood 0:340305453f64 79 Time_Data_Ticker.attach(this, &MSF_Time::Time_Data_Strobe,0.05); // start a timer to read data
dswood 0:340305453f64 80 }
dswood 0:340305453f64 81 }
dswood 0:340305453f64 82 void MSF_Time::Falling()
dswood 0:340305453f64 83 {
dswood 0:340305453f64 84 if (Polarity==0) {
dswood 0:340305453f64 85 LogicZero();
dswood 0:340305453f64 86 } else {
dswood 0:340305453f64 87 LogicOne();
dswood 0:340305453f64 88 }
dswood 0:340305453f64 89
dswood 0:340305453f64 90 }
dswood 0:340305453f64 91
dswood 0:340305453f64 92 void MSF_Time::IncrementSeconds()
dswood 0:340305453f64 93 {
dswood 0:340305453f64 94 // called 50ms ish before the second. Add delay of 50ms ish.
dswood 0:340305453f64 95 offset.attach_us(this, &MSF_Time::IncrementSecondsNow,OffsetTuning);
dswood 0:340305453f64 96 }
dswood 0:340305453f64 97 void MSF_Time::IncrementSecondsNow()
dswood 0:340305453f64 98 {
dswood 0:340305453f64 99 Received_timestamp++;
dswood 0:340305453f64 100 if (DV) { //this is the signal to set time now at 00 seconds
dswood 0:340305453f64 101 DV=false;
dswood 0:340305453f64 102 Received_Time.tm_sec=0;
dswood 0:340305453f64 103 Received_timestamp=mktime(&Received_Time);
dswood 0:340305453f64 104 if (Received_timestamp != -1 ) {//0x80000001
dswood 0:340305453f64 105 DataValid=true;
dswood 0:340305453f64 106 }
dswood 0:340305453f64 107 }
dswood 0:340305453f64 108 }
dswood 0:340305453f64 109
dswood 0:340305453f64 110
dswood 0:340305453f64 111 void MSF_Time::Time_Data_Strobe()
dswood 0:340305453f64 112 {
dswood 0:340305453f64 113 Time_Data_Count++;
dswood 0:340305453f64 114 switch(Time_Data_Count) {
dswood 0:340305453f64 115 case 1:
dswood 0:340305453f64 116 break;
dswood 0:340305453f64 117 case 9: //zero seconds
dswood 0:340305453f64 118 IncrementSeconds();
dswood 0:340305453f64 119 break;
dswood 0:340305453f64 120 //case 13://01A
dswood 0:340305453f64 121 //case 15://01B DUT1+
dswood 0:340305453f64 122 //break;
dswood 0:340305453f64 123 case 29:// Incerment seconds
dswood 0:340305453f64 124 IncrementSeconds();
dswood 0:340305453f64 125 break;
dswood 0:340305453f64 126 //case 33://02A
dswood 0:340305453f64 127 //case 35://02B DUT1+
dswood 0:340305453f64 128 //break;
dswood 0:340305453f64 129 case 49:
dswood 0:340305453f64 130 IncrementSeconds();
dswood 0:340305453f64 131 break;
dswood 0:340305453f64 132 //case 53://03A
dswood 0:340305453f64 133 //case 55://03B DUT1+
dswood 0:340305453f64 134 //break;
dswood 0:340305453f64 135 case 69:
dswood 0:340305453f64 136 IncrementSeconds();
dswood 0:340305453f64 137 break;
dswood 0:340305453f64 138 //case 73://04A
dswood 0:340305453f64 139 //case 75://04B DUT1+
dswood 0:340305453f64 140 case 89:
dswood 0:340305453f64 141 IncrementSeconds();
dswood 0:340305453f64 142 break;
dswood 0:340305453f64 143 //case 93://05A
dswood 0:340305453f64 144 //case 95://05B DUT1+
dswood 0:340305453f64 145 case 109:
dswood 0:340305453f64 146 IncrementSeconds();
dswood 0:340305453f64 147 break;
dswood 0:340305453f64 148 //case 113://06A
dswood 0:340305453f64 149 //case 115://06B DUT1+
dswood 0:340305453f64 150 case 129:
dswood 0:340305453f64 151 IncrementSeconds();
dswood 0:340305453f64 152 break;
dswood 0:340305453f64 153 //case 133://07A
dswood 0:340305453f64 154 //case 135://07B DUT1+
dswood 0:340305453f64 155 case 149:
dswood 0:340305453f64 156 IncrementSeconds();
dswood 0:340305453f64 157 break;
dswood 0:340305453f64 158 //case 153://08A
dswood 0:340305453f64 159 //case 155://08B DUT1+
dswood 0:340305453f64 160 case 169:
dswood 0:340305453f64 161 IncrementSeconds();
dswood 0:340305453f64 162 break;
dswood 0:340305453f64 163 //case 173://09A
dswood 0:340305453f64 164 //case 175://09B DUT1-
dswood 0:340305453f64 165 case 189:
dswood 0:340305453f64 166 IncrementSeconds();
dswood 0:340305453f64 167 break;
dswood 0:340305453f64 168 //case 193://10A
dswood 0:340305453f64 169 //case 195://10B DUT1-
dswood 0:340305453f64 170 case 209:
dswood 0:340305453f64 171 IncrementSeconds();
dswood 0:340305453f64 172 break;
dswood 0:340305453f64 173 //case 213://11A
dswood 0:340305453f64 174 //case 215://11B DUT1-
dswood 0:340305453f64 175 case 229:
dswood 0:340305453f64 176 IncrementSeconds();
dswood 0:340305453f64 177 break;
dswood 0:340305453f64 178 //case 233://12A
dswood 0:340305453f64 179 //case 235://12B DUT1-
dswood 0:340305453f64 180 case 249:
dswood 0:340305453f64 181 IncrementSeconds();
dswood 0:340305453f64 182 break;
dswood 0:340305453f64 183 //case 253://13A
dswood 0:340305453f64 184 //case 255://13B DUT1-
dswood 0:340305453f64 185 case 269:
dswood 0:340305453f64 186 IncrementSeconds();
dswood 0:340305453f64 187 break;
dswood 0:340305453f64 188 //case 273://14A
dswood 0:340305453f64 189 //case 275://14B DUT1-
dswood 0:340305453f64 190 case 289:
dswood 0:340305453f64 191 IncrementSeconds();
dswood 0:340305453f64 192 break;
dswood 0:340305453f64 193 //case 293://15A
dswood 0:340305453f64 194 //case 295://15B DUT1-
dswood 0:340305453f64 195 case 309:
dswood 0:340305453f64 196 IncrementSeconds();
dswood 0:340305453f64 197 break;
dswood 0:340305453f64 198 case 313://16A
dswood 0:340305453f64 199 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 200 //leap second
dswood 0:340305453f64 201 break;
dswood 0:340305453f64 202 //case 315://16B DUT1-
dswood 0:340305453f64 203 case 329:
dswood 0:340305453f64 204 IncrementSeconds();
dswood 0:340305453f64 205 break;
dswood 0:340305453f64 206 case 333://17A Year 80
dswood 0:340305453f64 207 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 208 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 209
dswood 0:340305453f64 210 break;
dswood 0:340305453f64 211 //case 335://17B
dswood 0:340305453f64 212 case 349:
dswood 0:340305453f64 213 IncrementSeconds();
dswood 0:340305453f64 214 break;
dswood 0:340305453f64 215 case 353://18A Year 40
dswood 0:340305453f64 216 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 217 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 218 break;
dswood 0:340305453f64 219 //case 355://18B
dswood 0:340305453f64 220 case 369:
dswood 0:340305453f64 221 IncrementSeconds();
dswood 0:340305453f64 222 break;
dswood 0:340305453f64 223 case 373://19A Year 20
dswood 0:340305453f64 224 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 225 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 226 break;
dswood 0:340305453f64 227 //case 375://19B
dswood 0:340305453f64 228 case 389:
dswood 0:340305453f64 229 IncrementSeconds();
dswood 0:340305453f64 230 break;
dswood 0:340305453f64 231 case 393://20A Year 10
dswood 0:340305453f64 232 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 233 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 234 break;
dswood 0:340305453f64 235 //case 395://20B
dswood 0:340305453f64 236 case 409:
dswood 0:340305453f64 237 IncrementSeconds();
dswood 0:340305453f64 238 break;
dswood 0:340305453f64 239 case 413://21A Year 8
dswood 0:340305453f64 240 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 241 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 242 break;
dswood 0:340305453f64 243 //case 415://21B
dswood 0:340305453f64 244 case 429:
dswood 0:340305453f64 245 IncrementSeconds();
dswood 0:340305453f64 246 break;
dswood 0:340305453f64 247 case 433://22A Year 4
dswood 0:340305453f64 248 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 249 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 250 break;
dswood 0:340305453f64 251 //case 435://22B
dswood 0:340305453f64 252 case 449:
dswood 0:340305453f64 253 IncrementSeconds();
dswood 0:340305453f64 254 break;
dswood 0:340305453f64 255 case 453://23A Year 2
dswood 0:340305453f64 256 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 257 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 258 break;
dswood 0:340305453f64 259 //case 455://23B
dswood 0:340305453f64 260 case 469:
dswood 0:340305453f64 261 IncrementSeconds();
dswood 0:340305453f64 262 break;
dswood 0:340305453f64 263 case 473://24A Year 1
dswood 0:340305453f64 264 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 265 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 266 MyData.BCDMonth+= MyInput.read()^Polarity;; //leap second minus
dswood 0:340305453f64 267
dswood 0:340305453f64 268 break;
dswood 0:340305453f64 269 //case 475://24B
dswood 0:340305453f64 270
dswood 0:340305453f64 271 case 489:
dswood 0:340305453f64 272 IncrementSeconds();
dswood 0:340305453f64 273 break;
dswood 0:340305453f64 274 case 493://25A Month 10
dswood 0:340305453f64 275 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 276 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 277
dswood 0:340305453f64 278 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 279 MyData.BCDYear+= MyInput.read()^Polarity; //leap second
dswood 0:340305453f64 280 break;
dswood 0:340305453f64 281
dswood 0:340305453f64 282 //case 495://25B
dswood 0:340305453f64 283
dswood 0:340305453f64 284 case 509:
dswood 0:340305453f64 285 IncrementSeconds();
dswood 0:340305453f64 286 break;
dswood 0:340305453f64 287 case 513://26A Month 8
dswood 0:340305453f64 288 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 289 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 290 break;
dswood 0:340305453f64 291 //case 515://26B
dswood 0:340305453f64 292 case 529:
dswood 0:340305453f64 293 IncrementSeconds();
dswood 0:340305453f64 294 break;
dswood 0:340305453f64 295 case 533://27A Month 4
dswood 0:340305453f64 296 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 297 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 298 break;
dswood 0:340305453f64 299 //case 535://27B
dswood 0:340305453f64 300 case 549:
dswood 0:340305453f64 301 IncrementSeconds();
dswood 0:340305453f64 302 break;
dswood 0:340305453f64 303 case 553://28A Month 2
dswood 0:340305453f64 304 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 305 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 306 break;
dswood 0:340305453f64 307 //case 555://28B
dswood 0:340305453f64 308 case 569:
dswood 0:340305453f64 309 IncrementSeconds();
dswood 0:340305453f64 310 break;
dswood 0:340305453f64 311 case 573://29A Month 1
dswood 0:340305453f64 312 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 313 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 314 break;
dswood 0:340305453f64 315 //case 575://29B
dswood 0:340305453f64 316 case 589:
dswood 0:340305453f64 317 IncrementSeconds();
dswood 0:340305453f64 318 break;
dswood 0:340305453f64 319 case 593://30A Day of Month 20
dswood 0:340305453f64 320 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 321 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 322 break;
dswood 0:340305453f64 323 //case 595://30B
dswood 0:340305453f64 324 case 609:
dswood 0:340305453f64 325 IncrementSeconds();
dswood 0:340305453f64 326 break;
dswood 0:340305453f64 327 case 613://31A Day of Month 10
dswood 0:340305453f64 328 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 329 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 330 break;
dswood 0:340305453f64 331 //case 615://31B
dswood 0:340305453f64 332 case 629:
dswood 0:340305453f64 333 IncrementSeconds();
dswood 0:340305453f64 334 break;
dswood 0:340305453f64 335 case 633://32A Day of Month 8
dswood 0:340305453f64 336 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 337 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 338 break;
dswood 0:340305453f64 339 //case 635://32B
dswood 0:340305453f64 340 case 649:
dswood 0:340305453f64 341 IncrementSeconds();
dswood 0:340305453f64 342 break;
dswood 0:340305453f64 343 case 653://33A Day of Month 4
dswood 0:340305453f64 344 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 345 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 346 break;
dswood 0:340305453f64 347 //case 655://33B
dswood 0:340305453f64 348 case 669:
dswood 0:340305453f64 349 IncrementSeconds();
dswood 0:340305453f64 350 break;
dswood 0:340305453f64 351 case 673://34A Day of Month 2
dswood 0:340305453f64 352 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 353 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 354 break;
dswood 0:340305453f64 355 //case 675://34B
dswood 0:340305453f64 356 case 689:
dswood 0:340305453f64 357 IncrementSeconds();
dswood 0:340305453f64 358 break;
dswood 0:340305453f64 359 case 693://35A Day of Month 1
dswood 0:340305453f64 360 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 361 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 362 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 363
dswood 0:340305453f64 364 break;
dswood 0:340305453f64 365 //case 695://35B
dswood 0:340305453f64 366
dswood 0:340305453f64 367 case 709:
dswood 0:340305453f64 368 IncrementSeconds();
dswood 0:340305453f64 369 break;
dswood 0:340305453f64 370 case 713://36A Day of Week 4
dswood 0:340305453f64 371 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 372 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 373
dswood 0:340305453f64 374 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 375 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 376 break;
dswood 0:340305453f64 377 // case 715://36B
dswood 0:340305453f64 378
dswood 0:340305453f64 379 case 729:
dswood 0:340305453f64 380 IncrementSeconds();
dswood 0:340305453f64 381 break;
dswood 0:340305453f64 382 case 733://37A Day of Week 2
dswood 0:340305453f64 383 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 384 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 385 break;
dswood 0:340305453f64 386 //case 735://37B
dswood 0:340305453f64 387 case 749:
dswood 0:340305453f64 388 IncrementSeconds();
dswood 0:340305453f64 389 break;
dswood 0:340305453f64 390 case 753://38A Day of Week 1
dswood 0:340305453f64 391 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 392 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 393 MyData.BCDTime+= MyInput.read()^Polarity; //leap second
dswood 0:340305453f64 394
dswood 0:340305453f64 395 break;
dswood 0:340305453f64 396 //case 755://38B
dswood 0:340305453f64 397
dswood 0:340305453f64 398 case 769:
dswood 0:340305453f64 399 IncrementSeconds();
dswood 0:340305453f64 400 break;
dswood 0:340305453f64 401 case 773://39A Hour 20
dswood 0:340305453f64 402 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 403 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 404
dswood 0:340305453f64 405 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 406 MyData.DayOfWeek+= MyInput.read()^Polarity; //leap second
dswood 0:340305453f64 407 break;
dswood 0:340305453f64 408
dswood 0:340305453f64 409 //case 775://39B
dswood 0:340305453f64 410
dswood 0:340305453f64 411 case 789:
dswood 0:340305453f64 412 IncrementSeconds();
dswood 0:340305453f64 413 break;
dswood 0:340305453f64 414 case 793://40A Hour 10
dswood 0:340305453f64 415 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 416 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 417 break;
dswood 0:340305453f64 418 //case 795://40B
dswood 0:340305453f64 419 case 809:
dswood 0:340305453f64 420 IncrementSeconds();
dswood 0:340305453f64 421 break;
dswood 0:340305453f64 422 case 813://41A Hour 8
dswood 0:340305453f64 423 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 424 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 425 break;
dswood 0:340305453f64 426 //case 815://41B
dswood 0:340305453f64 427 case 829:
dswood 0:340305453f64 428 IncrementSeconds();
dswood 0:340305453f64 429 break;
dswood 0:340305453f64 430 case 833://42A Hour 4
dswood 0:340305453f64 431 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 432 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 433 break;
dswood 0:340305453f64 434 //case 835://42B
dswood 0:340305453f64 435 case 849:
dswood 0:340305453f64 436 IncrementSeconds();
dswood 0:340305453f64 437 break;
dswood 0:340305453f64 438 case 853://43A Hour 2
dswood 0:340305453f64 439 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 440 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 441 break;
dswood 0:340305453f64 442 //case 855://43B
dswood 0:340305453f64 443 case 869:
dswood 0:340305453f64 444 IncrementSeconds();
dswood 0:340305453f64 445 break;
dswood 0:340305453f64 446 case 873://44A Hour 1
dswood 0:340305453f64 447 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 448 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 449 break;
dswood 0:340305453f64 450 //case 875://44B
dswood 0:340305453f64 451 case 889:
dswood 0:340305453f64 452 IncrementSeconds();
dswood 0:340305453f64 453 break;
dswood 0:340305453f64 454 case 893://45A Minute 40
dswood 0:340305453f64 455 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 456 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 457 break;
dswood 0:340305453f64 458 //case 895://45B
dswood 0:340305453f64 459 case 909:
dswood 0:340305453f64 460 IncrementSeconds();
dswood 0:340305453f64 461 break;
dswood 0:340305453f64 462 case 913://46A Minute 20
dswood 0:340305453f64 463 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 464 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 465 break;
dswood 0:340305453f64 466 //case 915://46B
dswood 0:340305453f64 467 case 929:
dswood 0:340305453f64 468 IncrementSeconds();
dswood 0:340305453f64 469 break;
dswood 0:340305453f64 470 case 933://47A Minute 10
dswood 0:340305453f64 471 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 472 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 473 break;
dswood 0:340305453f64 474 //case 935://47B
dswood 0:340305453f64 475 case 949:
dswood 0:340305453f64 476 IncrementSeconds();
dswood 0:340305453f64 477 break;
dswood 0:340305453f64 478 case 953://48A Minute 8
dswood 0:340305453f64 479 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 480 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 481 break;
dswood 0:340305453f64 482 //case 955://48B
dswood 0:340305453f64 483 case 969:
dswood 0:340305453f64 484 IncrementSeconds();
dswood 0:340305453f64 485 break;
dswood 0:340305453f64 486 case 973://49A Minute 4
dswood 0:340305453f64 487 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 488 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 489 break;
dswood 0:340305453f64 490 //case 975://49B
dswood 0:340305453f64 491 case 989:
dswood 0:340305453f64 492 IncrementSeconds();
dswood 0:340305453f64 493 break;
dswood 0:340305453f64 494 case 993://50A Minute 2
dswood 0:340305453f64 495 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 496 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 497 break;
dswood 0:340305453f64 498 //case 995://50B
dswood 0:340305453f64 499
dswood 0:340305453f64 500 case 1009:
dswood 0:340305453f64 501 IncrementSeconds();
dswood 0:340305453f64 502 break;
dswood 0:340305453f64 503 case 1013://51A Minute 1
dswood 0:340305453f64 504 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 505 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 506 MyData.SyncByte+= MyInput.read()^Polarity; // Or is it a leap second
dswood 0:340305453f64 507
dswood 0:340305453f64 508 break;
dswood 0:340305453f64 509 //case 1015://51B
dswood 0:340305453f64 510
dswood 0:340305453f64 511 case 1029:
dswood 0:340305453f64 512 IncrementSeconds();
dswood 0:340305453f64 513 break;
dswood 0:340305453f64 514 case 1033://52A set to 0
dswood 0:340305453f64 515 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 516 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 517
dswood 0:340305453f64 518 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 519 MyData.BCDTime+= MyInput.read()^Polarity; //leap second
dswood 0:340305453f64 520 break;
dswood 0:340305453f64 521 //case 1035://52B
dswood 0:340305453f64 522 case 1049:
dswood 0:340305453f64 523 IncrementSeconds();
dswood 0:340305453f64 524 break;
dswood 0:340305453f64 525 case 1053://53A set to 1
dswood 0:340305453f64 526 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 527 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 528
dswood 0:340305453f64 529 break;
dswood 0:340305453f64 530 case 1055://53B Change of summertime soon
dswood 0:340305453f64 531 // Fortunately leap seconds are never added in spring or autumn
dswood 0:340305453f64 532 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 533 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 534 break;
dswood 0:340305453f64 535 case 1069:
dswood 0:340305453f64 536 IncrementSeconds();
dswood 0:340305453f64 537 break;
dswood 0:340305453f64 538
dswood 0:340305453f64 539
dswood 0:340305453f64 540 case 1073://54A set to 1
dswood 0:340305453f64 541 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 542 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 543
dswood 0:340305453f64 544 break;
dswood 0:340305453f64 545 case 1075://54B Year Parity
dswood 0:340305453f64 546 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 547 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 548 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 549 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 550 break;
dswood 0:340305453f64 551 case 1089:
dswood 0:340305453f64 552 IncrementSeconds();
dswood 0:340305453f64 553 break;
dswood 0:340305453f64 554
dswood 0:340305453f64 555 case 1093://55A set to 1
dswood 0:340305453f64 556 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 557 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 558
dswood 0:340305453f64 559 break;
dswood 0:340305453f64 560 case 1095://55B Month Parity
dswood 0:340305453f64 561 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 562 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 563 MyData.BCDYear=MyData.BCDYear << 1;
dswood 0:340305453f64 564 MyData.BCDYear+= MyInput.read()^Polarity;
dswood 0:340305453f64 565 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 566 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 567 break;
dswood 0:340305453f64 568 case 1109:
dswood 0:340305453f64 569 IncrementSeconds();
dswood 0:340305453f64 570 break;
dswood 0:340305453f64 571 case 1113://56A set to 1
dswood 0:340305453f64 572 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 573 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 574
dswood 0:340305453f64 575 break;
dswood 0:340305453f64 576 case 1115://56B day of Week Parity
dswood 0:340305453f64 577 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 578 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 579 MyData.BCDMonth=MyData.BCDMonth << 1;
dswood 0:340305453f64 580 MyData.BCDMonth+= MyInput.read()^Polarity;
dswood 0:340305453f64 581 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 582 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 583 break;
dswood 0:340305453f64 584 case 1129:
dswood 0:340305453f64 585 IncrementSeconds();
dswood 0:340305453f64 586 break;
dswood 0:340305453f64 587 case 1133://57A set to 1
dswood 0:340305453f64 588 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 589 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 590
dswood 0:340305453f64 591 break;
dswood 0:340305453f64 592 case 1135://57B Time - hour minute parity
dswood 0:340305453f64 593 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 594 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 595 MyData.DayOfWeek=MyData.DayOfWeek <<1;
dswood 0:340305453f64 596 MyData.DayOfWeek+= MyInput.read()^Polarity;
dswood 0:340305453f64 597 break;
dswood 0:340305453f64 598 case 1149:
dswood 0:340305453f64 599 IncrementSeconds();
dswood 0:340305453f64 600 break;
dswood 0:340305453f64 601 case 1153://58A set to 1
dswood 0:340305453f64 602 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 603 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 604
dswood 0:340305453f64 605
dswood 0:340305453f64 606 break;
dswood 0:340305453f64 607 case 1155://58B British Summertime
dswood 0:340305453f64 608 MyData.BCDTime=MyData.BCDTime << 1;
dswood 0:340305453f64 609 MyData.BCDTime+= MyInput.read()^Polarity;
dswood 0:340305453f64 610 MyData.BST=MyInput.read()^Polarity;
dswood 0:340305453f64 611
dswood 0:340305453f64 612 break;
dswood 0:340305453f64 613 case 1169:
dswood 0:340305453f64 614 IncrementSeconds();
dswood 0:340305453f64 615 ProcessData();// if success count will be stopped but increment will still happen
dswood 0:340305453f64 616 break;
dswood 0:340305453f64 617 case 1173://59A set to 0
dswood 0:340305453f64 618 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 619 MyData.SyncByte+= MyInput.read()^Polarity;
dswood 0:340305453f64 620 break;
dswood 0:340305453f64 621 // case 1175://59B
dswood 0:340305453f64 622 case 1189:
dswood 0:340305453f64 623 IncrementSeconds();
dswood 0:340305453f64 624 ProcessData();
dswood 0:340305453f64 625 break;
dswood 0:340305453f64 626 case 1193://60A
dswood 0:340305453f64 627 MyData.SyncByte=MyData.SyncByte <<1;
dswood 0:340305453f64 628 MyData.SyncByte+= MyInput.read()^Polarity; //
dswood 0:340305453f64 629 break;
dswood 0:340305453f64 630 // case 1195://60B
dswood 0:340305453f64 631 case 1209:
dswood 0:340305453f64 632 IncrementSeconds();
dswood 0:340305453f64 633 ProcessData();
dswood 0:340305453f64 634 // End stop
dswood 0:340305453f64 635 // On a leap second we should count extra but not dealing with it
dswood 0:340305453f64 636 // so for one minute time will be out by a second.
dswood 0:340305453f64 637 Time_Data_Ticker.detach();
dswood 0:340305453f64 638 Time_Data_Count=0; // Should stop this being called more than once
dswood 0:340305453f64 639 DataValid=false; //no data received
dswood 0:340305453f64 640
dswood 0:340305453f64 641 }
dswood 0:340305453f64 642 }
dswood 0:340305453f64 643
dswood 0:340305453f64 644 int MSF_Time::ParityCheck(unsigned int CheckMe) //0=even 1= odd naturally
dswood 0:340305453f64 645 {
dswood 0:340305453f64 646 // My parity is going to check 16 bit feel free to add more
dswood 0:340305453f64 647 // Stolen shamelessly from internet
dswood 0:340305453f64 648 //x ^= x >> 16;
dswood 0:340305453f64 649 //x ^= x >> 8;
dswood 0:340305453f64 650 //x ^= x >> 4;
dswood 0:340305453f64 651 //x ^= x >> 2;
dswood 0:340305453f64 652 //x ^= x >> 1;
dswood 0:340305453f64 653 //return (~x) & 1;
dswood 0:340305453f64 654 CheckMe^=CheckMe>>8;
dswood 0:340305453f64 655 CheckMe^=CheckMe>>4;
dswood 0:340305453f64 656 CheckMe^=CheckMe>>2;
dswood 0:340305453f64 657 CheckMe^=CheckMe>>1;
dswood 0:340305453f64 658 CheckMe&=1;// 1=odd 0=even
dswood 0:340305453f64 659
dswood 0:340305453f64 660 return CheckMe;
dswood 0:340305453f64 661 }
dswood 0:340305453f64 662
dswood 0:340305453f64 663 void MSF_Time::ProcessData()
dswood 0:340305453f64 664 {
dswood 0:340305453f64 665 DV=false;
dswood 0:340305453f64 666 int shift=0; // by how much to shift just to leave data
dswood 0:340305453f64 667
dswood 0:340305453f64 668
dswood 0:340305453f64 669 // Find sync
dswood 0:340305453f64 670 // sync data is 01111110
dswood 0:340305453f64 671 if ((MyData.SyncByte&0x0FF) == 0x07E) { // sync byte
dswood 0:340305453f64 672
dswood 0:340305453f64 673 /* There are 3 processdata calls. The ticker will be either
dswood 0:340305453f64 674 1155 or 1173 or 1193. If it is on time or late, extra data will
dswood 0:340305453f64 675 have been collected. We shall get rid.*/
dswood 0:340305453f64 676 } else {
dswood 0:340305453f64 677 if (Time_Data_Count==1193) {
dswood 0:340305453f64 678 //pc.printf("last chance of sync failed - data not valid");
dswood 0:340305453f64 679 DataValid=false;
dswood 0:340305453f64 680 }
dswood 0:340305453f64 681 return;
dswood 0:340305453f64 682 }
dswood 0:340305453f64 683
dswood 0:340305453f64 684 if (Time_Data_Count==1169) { //leap second early
dswood 0:340305453f64 685 shift=2;
dswood 0:340305453f64 686
dswood 0:340305453f64 687 }
dswood 0:340305453f64 688 if (Time_Data_Count==1189) {
dswood 0:340305453f64 689 shift=1;
dswood 0:340305453f64 690
dswood 0:340305453f64 691 }
dswood 0:340305453f64 692 if (Time_Data_Count==1209) {
dswood 0:340305453f64 693 shift=0;
dswood 0:340305453f64 694 }
dswood 0:340305453f64 695 Time_Data_Ticker.detach();
dswood 0:340305453f64 696 Time_Data_Count=0; // Should stop this being called more than once
dswood 0:340305453f64 697 MyData.BCDYear>>=shift;
dswood 0:340305453f64 698 MyData.BCDMonth>>=shift;
dswood 0:340305453f64 699 MyData.DayOfWeek>>=shift;
dswood 0:340305453f64 700 MyData.BCDTime>>=shift;
dswood 0:340305453f64 701 MyData.BCDYear&=0x7F9 ; //8 bits +2 rubbish + parity
dswood 0:340305453f64 702 MyData.BCDMonth&=0x3FF9; // 11 bits +2 rubbish + parity
dswood 0:340305453f64 703 MyData.DayOfWeek&=0x039 ; //3 bits +2 rubbish + parity
dswood 0:340305453f64 704 MyData.BCDTime&=0xFFF9; // 13bits +2 rubbish + parity
dswood 0:340305453f64 705
dswood 0:340305453f64 706 if (ParityCheck(MyData.BCDYear) &&
dswood 0:340305453f64 707 ParityCheck(MyData.BCDMonth) &&
dswood 0:340305453f64 708 ParityCheck(MyData.DayOfWeek) &&
dswood 0:340305453f64 709 ParityCheck(MyData.BCDTime) ) {
dswood 0:340305453f64 710 // Parity ok - remove parity bits
dswood 0:340305453f64 711 MyData.BCDYear>>=3;
dswood 0:340305453f64 712 MyData.BCDMonth>>=3;
dswood 0:340305453f64 713 MyData.DayOfWeek>>=3;
dswood 0:340305453f64 714 MyData.BCDTime>>=3;
dswood 0:340305453f64 715 DV=true;
dswood 0:340305453f64 716 } else {
dswood 0:340305453f64 717 DataValid=false; //sync but parity fail
dswood 0:340305453f64 718 return;
dswood 0:340305453f64 719 }
dswood 0:340305453f64 720
dswood 0:340305453f64 721 //Convert BCD to binary
dswood 0:340305453f64 722 // pc.printf("Year Month DOW Time\n\r");
dswood 0:340305453f64 723 //pc.printf("%x %x %x %x\n\r",MyData.BCDYear,MyData.BCDMonth,MyData.DayOfWeek,MyData.BCDTime);
dswood 0:340305453f64 724 if (DV) {
dswood 0:340305453f64 725 Received_Time.tm_year=100+(MyData.BCDYear & 0x0F)+(10*((MyData.BCDYear>>4) & 0x01)) ; //years _since_ 1900
dswood 0:340305453f64 726 Received_Time.tm_mon=((MyData.BCDMonth>>6) & 0x0F)+(10*((MyData.BCDMonth>>10) & 0x01))-1;
dswood 0:340305453f64 727 Received_Time.tm_mday=(MyData.BCDMonth & 0x0F)+(10*((MyData.BCDMonth>>4) & 0x03)) ;
dswood 0:340305453f64 728 Received_Time.tm_hour=((MyData.BCDTime>>7)& 0x0F)+(10*((MyData.BCDTime>>11) & 0x03));
dswood 0:340305453f64 729 Received_Time.tm_min=(MyData.BCDTime&0x0F)+(10*((MyData.BCDTime>>4) & 0x07));
dswood 0:340305453f64 730 Received_Time.tm_wday = (MyData.DayOfWeek&0x07);
dswood 0:340305453f64 731 Received_Time.tm_sec=0;
dswood 0:340305453f64 732 }
dswood 0:340305453f64 733 }
dswood 0:340305453f64 734 bool MSF_Time::Valid()
dswood 0:340305453f64 735 {
dswood 0:340305453f64 736 //if (DataValid) pc.printf("Data Valid\n\r");
dswood 0:340305453f64 737
dswood 0:340305453f64 738 return DataValid;
dswood 0:340305453f64 739 }
dswood 0:340305453f64 740 time_t MSF_Time::Read()
dswood 0:340305453f64 741 {
dswood 0:340305453f64 742 // pc.printf("Received ts %s\n\r",ctime(&Received_timestamp));
dswood 0:340305453f64 743 return Received_timestamp;
dswood 0:340305453f64 744 }
dswood 0:340305453f64 745 #endif
dswood 0:340305453f64 746