#include "dcf77dec.h"
#include <avr/pgmspace.h>
#include <string.h>
DCF77Dec dcf77dec;
void DateTime::operator++() {
asm("rcall incMinute"::"z"(this):"r24","r25");
}
byte DateTime::operator=(const DateTime&o) {
byte r;
asm("rcall copyDate$mov %0,r24":"=r"(r):"x"(this),"z"(&o):"r24","r25");
return r;
}
unsigned DateTime::operator=(const DCF77Data&o) {
unsigned Err;
asm("rcall checkConvert$movw %A0,r22":"=r"(Err):"x"(this),"z"(&o):"r18","r19","r22","r23","r24","r25");
return Err;
}
#define setBit(ptr,bit) ({void*X=(ptr);byte B=(bit);asm("mov r24,%1$rcall setBit"::"x"(X),"r"(B):"r24","r25");})
void DCF77Dec::ProcessVal(byte twobits) {
// Datenbit abspeichern, noch nicht auswerten
byte b = recvbit;
if (!(twobits&1)) setBit(&data,b);
asm(
" cpi %0,41 \n" // hier (bei 41) hängen bleiben
" breq 2f \n"
" inc %0 \n"
" sbrc %0,6 \n" // 64->40
" ldi %0,40 \n"
" cpi %0,39 \n" // 39->42
" brne 1f \n"
" ldi %0,42 \n"
"1: cpi %0,22 \n" // 22->24
" brne 1f \n"
" ldi %0,24 \n"
"1: cpi %0,15 \n" // 15->16
" brne 2f \n"
" inc %0 \n"
"2: \n"
:"+d"(b));
recvbit = b;
// Zeit aktualisieren (das passiert in Zehntelsekunde 5 also 0,5 s zu früh)
// TODO: Irgendwie muss eine Resynchronisation mit einer Minutenmarke auch nachträglich möglich sein!
if (Grade) {
byte sec=60;
if (Grade>3 && data.inf&0x08 && !data.min) ++sec; // (positive) Schaltsekunde erwarten
if (++Second>=sec) {
if (twobits!=3 && Grade>3) --Grade; // Minutenmarke muss kommen, sonst abwerten
Second=0;
}else{
if (twobits==3 && Grade>3) --Grade; // Minutenmarke darf nicht kommen, sonst abwerten
}
}else if (twobits==3) Grade=1;
// Minutenanfang setzen NUR wenn noch keine Minute erfolgreich empfangen wurde
// Sonst fehlende Trägerabsenkung ignorieren
if (Second) return;
if (Grade>1) ++dt;
DateTime dtl;
unsigned Err = dtl=data; // 12 verschiedene Fehlerbits
Info = data.inf&15;
if (Err) /*uprintf(FP("Err=%X"),Err)*/;
else{
byte Mod = dt = dtl;
if (Mod) {
// uprintf(FP("Mod=%X"),Mod);
if (Grade>1) Err|=1<<11; // Das ist auch ein Fehler!
}
}
if (Err && Grade>3) --Grade; // Herabstufen (TODO: Parallele Quarzuhr)
if (!Err && Grade<99) ++Grade;
memset(&recvbit,0,9);
}
void DateTime::print() const{
uprintf(F("%.2s, %02u.%02u.%u %02u:%02u"),
F("SoMoDiMiDoFrSa") + 2*WDay,
byte(Date+1),
byte(Month+1),
Year+2000,
Hour&0x1F,
Minute);
}
Vorgefundene Kodierung: UTF-8 | 0
|