示例#1
0
int
main(int argc, char **argv)
{
	int i, p, act;
	struct hardware hw;

	if (set_mode(0, NULL, NULL)) {
		cleanup();
		return 0;
	}

	(void)read_hardware_parameters("hardware.txt", &hw);
	/* get our own copy, error handling in set_mode() */

	printf("%i\n", (int)(hw.freq * hw.min_len / 100));
	for (i = act = 0;; i++) {
		p = get_pulse();
		if (p & GETBIT_IO) {
			printf("IO error!\n");
			break;
		}
		act += p;
		printf("%c", p == 1 ? '+' : ' ');
		if (i == (int)(hw.freq * hw.min_len / 100)) {
			printf(" %lu\n", act*hw.freq/hw.min_len);
			i = act = 0;
		}
		(void)usleep(1000000.0 / hw.freq);
	}
	cleanup();
	return 0;
}
示例#2
0
int main(int argc, char **argv)
{
	struct tap tapin, tapout;
	FILE *infile;
	long pulse;
	
	getopts(argc, argv);
	
	if (optind == argc) {
		infile = stdin;
	} else if (optind == argc - 1) {
		if (!strcmp(argv[optind], "-")) {
			infile = stdin;
		} else {
			infile = fopen(argv[optind], "rb");
			if (!infile) {
				perror(argv[optind]);
				return 1;
			}
		}
	} else {
		fprintf(stderr, "%s: too many arguments\n", argv0);
		usage();
		return 1;
	}
	if (tap_read_header(&tapin, infile)) {
		fprintf(stderr, "%s: error reading TAP file\n", argv0);
		return 1;
	}
	if (outversion < 0) tapout.version = tapin.version;
	else tapout.version = outversion;
	if (tap_write_header(&tapout, stdout)) {
		fprintf(stderr, "%s: error writing TAP file\n", argv0);
		return 1;
	}
	
	while ((pulse = get_pulse(&tapin)) >= 0) {
		if (tapin.version == 0 &&
		    pulse == V0_LONG_PULSE) {
			pulse = LONG_PULSE;
		}
		pulse /= speed;
		put_pulse(pulse, &tapout);
	}
	tap_close(&tapout);
	return 0;
}
示例#3
0
/*
 * The bits are decoded from the signal using an exponential low-pass filter in
 * conjunction with a Schmitt trigger. The idea and the initial implementation
 * for this come from Udo Klein, with permission.
 * http://blog.blinkenlight.net/experiments/dcf77/binary-clock/#comment-5916
 */
struct GB_result
get_bit_live(void)
{
	char outch;
	bool newminute = false;
	unsigned stv = 1;
	int p;
	struct timespec slp;
#if !defined(MACOS)
	struct timespec tp0, tp1;
#endif
	unsigned sec2;
	long long a, y = 1000000000;
	long long twait;
	static int init_bit = 2;
	bool is_eom = gb_res.marker == emark_minute ||
	    gb_res.marker == emark_late;

	bit.freq_reset = false;
	bit.bitlen_reset = false;

	set_new_state();

	/*
	 * One period is either 1000 ms or 2000 ms long (normal or padding for
	 * last). The active part is either 100 ms ('0') or 200 ms ('1') long.
	 * The maximum allowed values as percentage of the second length are
	 * specified as half the value and the whole value of the lengths of
	 * bit 0 and bit 20 respectively.
	 *
	 *  ~A > 3/2 * realfreq: end-of-minute
	 *  ~A > 5/2 * realfreq: timeout
	 */

	if (init_bit == 2) {
		bit.realfreq = hw.freq * 1000000;
		bit.bit0 = bit.realfreq / 10;
		bit.bit20 = bit.realfreq / 5;
	}
	sec2 = 1000000000 / (hw.freq * hw.freq);
	/*
	 * Set up filter, reach 50% after realfreq/20 samples (i.e. 50 ms)
	 */
	a = 1000000000 - (long long)(1000000000 * exp2(-2e7 / bit.realfreq));
	bit.tlow = -1;
	bit.tlast0 = -1;

	for (bit.t = 0; bit.t != 0xFFFFFFFF; bit.t++) {
#if !defined(MACOS)
		(void)clock_gettime(CLOCK_MONOTONIC, &tp0);
#endif
		p = get_pulse();
		if (p == 2) {
			gb_res.bad_io = true;
			outch = '*';
			goto report;
		}
		if (bit.signal != NULL) {
			if ((bit.t & 7) == 0)
				bit.signal[bit.t / 8] = 0;
				/* clear data from previous second */
			bit.signal[bit.t / 8] |= p << (unsigned char)(bit.t & 7);
		}

		if (y >= 0 && y < a / 2)
			bit.tlast0 = (int)bit.t;
		y += a * (p * 1000000000 - y) / 1000000000;

		/*
		 * Prevent algorithm collapse during thunderstorms
		 * or scheduler abuse
		 */
		if (bit.realfreq <= hw.freq * 500000 ||
		    bit.realfreq >= hw.freq * 1500000)
			reset_frequency();

		if (bit.t > bit.realfreq * 2500000) {
			bit.realfreq += ((long long)
			    (bit.t * 2500000 - bit.realfreq) / 20);
			a = 1000000000 - (long long)(1000000000 *
			     exp2(-2e7 / bit.realfreq));
			if (bit.tlow * 100 / bit.t < 1) {
				gb_res.hwstat = ehw_receive;
				outch = 'r';
			} else if (bit.tlow * 100 / bit.t >= 99) {
				gb_res.hwstat = ehw_transmit;
				outch = 'x';
			} else {
				gb_res.hwstat = ehw_random;
				outch = '#';
			}
			goto report; /* timeout */
		}

		/*
		 * Schmitt trigger, maximize value to introduce
		 * hysteresis and to avoid infinite memory.
		 */
		if (y < 500000000 && stv == 1) {
			/* end of high part of second */
			y = 0;
			stv = 0;
			bit.tlow = (int)bit.t;
		}
		if (y > 500000000 && stv == 0) {
			/* end of low part of second */
			y = 1000000000;
			stv = 1;

			newminute = bit.t * 2000000 > bit.realfreq * 3;
			if (init_bit == 2)
				init_bit--;
			else {
				if (newminute)
					bit.realfreq += ((long long)(bit.t *
					    500000 - bit.realfreq) / 20);
				else
					bit.realfreq += ((long long)(bit.t *
					    1000000 - bit.realfreq) / 20);
				a = 1000000000 - (long long)(1000000000 *
				    exp2(-2e7 / bit.realfreq));
			}

			if (newminute) {
				/*
				 * Reset the frequency and the EOM flag if two
				 * consecutive EOM markers come in, which means
				 * something is wrong.
				 */
				if (is_eom) {
					if (gb_res.marker == emark_minute)
						gb_res.marker = emark_none;
					else if (gb_res.marker == emark_late)
						gb_res.marker = emark_toolong;
					reset_frequency();
				} else {
					if (gb_res.marker == emark_none)
						gb_res.marker = emark_minute;
					else if (gb_res.marker == emark_toolong)
						gb_res.marker = emark_late;
				}
			}
			break; /* start of new second */
		}
		twait = (long long)(sec2 * bit.realfreq / 1000000);
#if !defined(MACOS)
		(void)clock_gettime(CLOCK_MONOTONIC, &tp1);
		twait = twait - (tp1.tv_sec - tp0.tv_sec) * 1000000000 -
		   (tp1.tv_nsec - tp0.tv_nsec);
#endif
		slp.tv_sec = twait / 1000000000;
		slp.tv_nsec = twait % 1000000000;
		while (twait > 0 && nanosleep(&slp, &slp))
			;
	}

	if (2 * bit.realfreq * bit.tlow * (1 + (newminute ? 1 : 0)) <
	    (bit.bit0 + bit.bit20) * bit.t) {
		/* zero bit, ~100 ms active signal */
		gb_res.bitval = ebv_0;
		outch = '0';
		buffer[bitpos] = 0;
	} else if (bit.realfreq * bit.tlow * (1 + (newminute ? 1 : 0)) <
	    (bit.bit0 + bit.bit20) * bit.t) {
		/* one bit, ~200 ms active signal */
		gb_res.bitval = ebv_1;
		outch = '1';
		buffer[bitpos] = 1;
	} else {
		/* bad radio signal, retain old value */
		gb_res.bitval = ebv_none;
		outch = '_';
		/* force bit 20 to be 1 to recover from too low b20 value */
		if (bitpos == 20) {
			gb_res.bitval = ebv_1;
			outch = '1';
			buffer[20] = 1;
		}
	}
	if (init_bit == 1)
		init_bit--;
	else if (gb_res.hwstat == ehw_ok && gb_res.marker == emark_none) {
		if (bitpos == 0 && gb_res.bitval == ebv_0)
			bit.bit0 += ((long long)
			    (bit.tlow * 1000000 - bit.bit0) / 2);
		if (bitpos == 20 && gb_res.bitval == ebv_1)
			bit.bit20 += ((long long)
			    (bit.tlow * 1000000 - bit.bit20) / 2);
		/* During a thunderstorm the value of bit20 might underflow */
		if (bit.bit20 < bit.bit0)
			reset_bitlen();
	}
report:
	acc_minlen += 1000000 * bit.t / (bit.realfreq / 1000);
	if (logfile != NULL) {
		fprintf(logfile, "%c", outch);
		if (gb_res.marker == emark_minute ||
		    gb_res.marker == emark_late)
			fprintf(logfile, "a%uc%6.4f\n", acc_minlen,
			    (double)((bit.t * 1e6) / bit.realfreq));
	}
	if (gb_res.marker == emark_minute || gb_res.marker == emark_late)
		cutoff = bit.t * 1000000 / (bit.realfreq / 10000);
	return gb_res;
}
示例#4
0
int
main(int argc, char *argv[])
{
	struct sigaction sigact;
	struct hardware hw;
	int ch, min, res;
	bool raw = false, verbose = true;

	while ((ch = getopt(argc, argv, "qr")) != -1) {
		switch (ch) {
		case 'q' :
			verbose = false;
			break;
		case 'r' :
			raw = true;
			break;
		default:
			printf("usage: %s [-qr]\n", argv[0]);
			return EX_USAGE;
		}
	}

	res = read_config_file(ETCDIR"/config.txt");
	if (res != 0) {
		cleanup();
		return res;
	}
	res = set_mode_live();
	if (res != 0) {
		cleanup();
		return res;
	}
	hw = get_hardware_parameters();

	sigact.sa_handler = do_cleanup;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, (struct sigaction *)NULL);

	min = -1;

	for (;;) {
		struct bitinfo bi;
		struct GB_result bit;

		if (raw) {
			struct timespec slp;
			slp.tv_sec = 1.0 / hw.freq;
			slp.tv_nsec = 1e9 / hw.freq;
			printf("%i", get_pulse());
			fflush(stdout);
			while (nanosleep(&slp, &slp))
				;
			continue;
		}

		bit = get_bit_live();
		bi = get_bitinfo();
		if (verbose) {
			if (bi.freq_reset)
				printf("!");
			/* display first bi->t pulses */
			for (unsigned long long i = 0; i < bi.t / 8; i++)
				for (unsigned j = 0; j < 8; j++)
					printf("%c",
					    (bi.signal[i] & (1 << j)) > 0 ?
					    '+' : '-');
			/*
			 * display pulses in the last partially filled item
			 * bi.t is 0-based, hence the <= comparison
			 */
			for (unsigned j = 0; j <= (bi.t & 7); j++)
				printf("%c",
				    (bi.signal[bi.t / 8] & (1 << j)) > 0 ?
				    '+' : '-');
			printf("\n");
		}
		if (bit.marker == emark_toolong || bit.marker == emark_late)
			min++;
		printf("%i %i %u %llu %llu %llu %i:%i\n",
		    bi.tlow, bi.tlast0, bi.t, bi.bit0, bi.bit20, bi.realfreq,
		    min, get_bitpos());
		if (bit.marker == emark_minute)
			min++;
		bit = next_bit();
	}
	/* NOTREACHED */
}