Source file: /~heha/basteln/PC/FunkUsb/dcf77franz9.zip/dcf77dec.cpp

#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);
}
Detected encoding: UTF-80