Source

rfid / hid-rfid-reader.c

/**
 * \file HID ProxPro Wiegand reader.
 *
 */

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>
#include <util/delay.h>
#include "usb_serial.h"
#include "bits.h"


// Send a string to the USB serial port.  The string must be in
// flash memory, using PSTR
//
void send_str(const char *s)
{
	char c;
	while (1) {
		c = pgm_read_byte(s++);
		if (!c) break;
		usb_serial_putchar(c);
	}
}


static char
hexdigit(
	uint8_t x
)
{
	x &= 0xF;
	if (x < 0xA)
		return x + '0';
	else
		return x + 'A' - 0xA;
}



int main(void)
{
	// set for 16 MHz clock
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
	CPU_PRESCALE(0);

	// Disable the ADC
	ADMUX = 0;

	// initialize the USB, and then wait for the host
	// to set configuration.  If the Teensy is powered
	// without a PC connected to the USB port, this 
	// will wait forever.
	usb_init();
	while (!usb_configured())
		continue;

	_delay_ms(500);

	// wait for the user to run their terminal emulator program
	// which sets DTR to indicate it is ready to receive.
	while (!(usb_serial_get_control() & USB_SERIAL_DTR))
		continue;

	// discard anything that was received prior.  Sometimes the
	// operating system or other software will send a modem
	// "AT command", which can still be buffered.
	usb_serial_flush_input();

	// configure D7 as a output clock
	// it is just toggled every time through the loop,
	// not quite a real clock
	ddr(0xD7, 1);
	

	out(0xB0, 1);
	ddr(0xB0, 0); // pull up
	out(0xB1, 1);
	ddr(0xB1, 0); // pull up

	ddr(0xD6, 1); // LED

	uint8_t bits = 0;
	uint8_t old = 0;
	uint16_t counter = 0;
	const uint16_t limit = 65500;

	while (1)
	{
		// hack to generate a recovery clock
		out(0xD7, !in(0xD7));

		uint8_t d = ~PINB & 0x3;
		if (d == 0)
		{
			old = d;
			if (counter++ != limit)
				continue;
			if (bits == 0)
				continue;
			bits = 0;
			counter = 0;
			send_str(PSTR("\r\n"));
			continue;
		}

		// Wait for a level change
		if (d == old)
			continue;

		old = d;
		counter = 0;

		if (d == 3)
		{
			bits = 0;
			send_str(PSTR("!!!\r\n"));
			continue;
		}


		if (d == 1)
			usb_serial_putchar('0');
		else
			usb_serial_putchar('1');
		bits++;
	}
}