📄 clk_rawdcf.c
字号:
}}/* * raw dcf input routine - needs to fix up 50 baud * characters for 1/0 decision */static u_longcvt_rawdcf( unsigned char *buffer, int size, struct format *param, clocktime_t *clock_time, void *local ){ last_tcode_t *t = (last_tcode_t *)local; unsigned char *s = (unsigned char *)buffer; unsigned char *e = s + size; unsigned char *b = dcfparameter.onebits; unsigned char *c = dcfparameter.zerobits; u_long rtc = CVT_NONE; unsigned int i, lowmax, highmax, cutoff, span;#define BITS 9 unsigned char histbuf[BITS]; /* * the input buffer contains characters with runs of consecutive * bits set. These set bits are an indication of the DCF77 pulse * length. We assume that we receive the pulse at 50 Baud. Thus * a 100ms pulse would generate a 4 bit train (20ms per bit and * start bit) * a 200ms pulse would create all zeroes (and probably a frame error) */ for (i = 0; i < BITS; i++) { histbuf[i] = 0; } cutoff = 0; lowmax = 0; while (s < e) { unsigned int ch = *s ^ 0xFF; /* * these lines are left as an excercise to the reader 8-) */ if (!((ch+1) & ch) || !*s) { for (i = 0; ch; i++) { ch >>= 1; } *s = i; histbuf[i]++; cutoff += i; lowmax++; } else { parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: character check for 0x%x@%d FAILED\n", *s, (int)(s - (unsigned char *)buffer))); *s = (unsigned char)~0; rtc = CVT_FAIL|CVT_BADFMT; } s++; } if (lowmax) { cutoff /= lowmax; } else { cutoff = 4; /* doesn't really matter - it'll fail anyway, but gives error output */ } parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: average bit count: %d\n", cutoff)); lowmax = 0; highmax = 0; parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: histogram:")); for (i = 0; i <= cutoff; i++) { lowmax+=histbuf[i] * i; highmax += histbuf[i]; parseprintf(DD_RAWDCF,(" %d", histbuf[i])); } parseprintf(DD_RAWDCF, (" <M>")); lowmax += highmax / 2; if (highmax) { lowmax /= highmax; } else { lowmax = 0; } highmax = 0; cutoff = 0; for (; i < BITS; i++) { highmax+=histbuf[i] * i; cutoff +=histbuf[i]; parseprintf(DD_RAWDCF,(" %d", histbuf[i])); } parseprintf(DD_RAWDCF,("\n")); if (cutoff) { highmax /= cutoff; } else { highmax = BITS-1; } span = cutoff = lowmax; for (i = lowmax; i <= highmax; i++) { if (histbuf[cutoff] > histbuf[i]) { cutoff = i; span = i; } else if (histbuf[cutoff] == histbuf[i]) { span = i; } } cutoff = (cutoff + span) / 2; parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: lower maximum %d, higher maximum %d, cutoff %d\n", lowmax, highmax, cutoff)); s = (unsigned char *)buffer; while (s < e) { if (*s == (unsigned char)~0) { *s = '?'; } else { *s = (*s >= cutoff) ? *b : *c; } s++; if (*b) b++; if (*c) c++; } if (rtc == CVT_NONE) { rtc = convert_rawdcf(buffer, size, &dcfparameter, clock_time); if (rtc == CVT_OK) { time_t newtime; newtime = parse_to_unixtime(clock_time, &rtc); if ((rtc == CVT_OK) && t) { if ((newtime - t->tcode) == 60) /* guard against multi bit errors */ { clock_time->utctime = newtime; } else { rtc = CVT_FAIL|CVT_BADTIME; } t->tcode = newtime; } } } return rtc;}/* * pps_rawdcf * * currently a very stupid version - should be extended to decode * also ones and zeros (which is easy) *//*ARGSUSED*/static u_longpps_rawdcf( parse_t *parseio, int status, timestamp_t *ptime ){ if (!status) /* negative edge for simpler wiring (Rx->DCD) */ { parseio->parse_dtime.parse_ptime = *ptime; parseio->parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS; } return CVT_NONE;}static u_longsnt_rawdcf( parse_t *parseio, timestamp_t *ptime ){ if ((parseio->parse_dtime.parse_status & CVT_MASK) == CVT_OK) { parseio->parse_dtime.parse_stime = *ptime;#ifdef PARSEKERNEL parseio->parse_dtime.parse_time.tv.tv_sec++;#else parseio->parse_dtime.parse_time.fp.l_ui++;#endif parseprintf(DD_RAWDCF,("parse: snt_rawdcf: time stamp synthesized offset %d seconds\n", parseio->parse_index - 1)); return updatetimeinfo(parseio, parseio->parse_lstate); } return CVT_NONE;}/* * inp_rawdcf * * grab DCF77 data from input stream */static u_longinp_rawdcf( parse_t *parseio, unsigned int ch, timestamp_t *tstamp ){ static struct timeval timeout = { 1, 500000 }; /* 1.5 secongs denote second #60 */ parseprintf(DD_PARSE, ("inp_rawdcf(0x%lx, 0x%x, ...)\n", (long)parseio, ch)); parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */ if (parse_timedout(parseio, tstamp, &timeout)) { parseprintf(DD_PARSE, ("inp_rawdcf: time out seen\n")); (void) parse_end(parseio); (void) parse_addchar(parseio, ch); return PARSE_INP_TIME; } else { unsigned int rtc; rtc = parse_addchar(parseio, ch); if (rtc == PARSE_INP_SKIP) { if (snt_rawdcf(parseio, tstamp) == CVT_OK) return PARSE_INP_SYNTH; } return rtc; }}#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RAWDCF) */int clk_rawdcf_bs;#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RAWDCF) *//* * History: * * clk_rawdcf.c,v * Revision 4.15 2005/08/06 19:17:06 kardel * clean log output * * Revision 4.14 2005/08/06 17:39:40 kardel * cleanup size handling wrt/ to buffer boundaries * * Revision 4.13 2005/04/16 17:32:10 kardel * update copyright * * Revision 4.12 2004/11/14 15:29:41 kardel * support PPSAPI, upgrade Copyright to Berkeley style * * Revision 4.9 1999/12/06 13:42:23 kardel * transfer correctly converted time codes always into tcode * * Revision 4.8 1999/11/28 09:13:50 kardel * RECON_4_0_98F * * Revision 4.7 1999/04/01 20:07:20 kardel * added checking for minutie increment of timestamps in clk_rawdcf.c * * Revision 4.6 1998/06/14 21:09:37 kardel * Sun acc cleanup * * Revision 4.5 1998/06/13 12:04:16 kardel * fix SYSV clock name clash * * Revision 4.4 1998/06/12 15:22:28 kardel * fix prototypes * * Revision 4.3 1998/06/06 18:33:36 kardel * simplified condidional compile expression * * Revision 4.2 1998/05/24 11:04:18 kardel * triggering PPS on negative edge for simpler wiring (Rx->DCD) * * Revision 4.1 1998/05/24 09:39:53 kardel * implementation of the new IO handling model * * Revision 4.0 1998/04/10 19:45:30 kardel * Start 4.0 release version numbering * * from V3 3.24 log info deleted 1998/04/11 kardel * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -