Source

rfid / avrfid2.c

#include <avr/io.h>

/* Use r16 and r17 to track the state of the pins */
volatile  register  uint8_t r16 __asm__("r16"); 
volatile  register  uint8_t r17 __asm__("r17"); 


static inline void
delay(
	const uint8_t n
)
{
	switch (n)
	{
	case 8: asm("nop");
	case 7: asm("nop");
	case 6: asm("nop");
	case 5: asm("nop");
	case 4: asm("nop");
	case 3: asm("nop");
	case 2: asm("nop");
	case 1: asm("nop");
	case 0: break;
	}
}


static inline void
toggle(	
	const uint8_t n
)
{
	delay(n-2);
	asm(
		"eor r16, r17\n"
		"out 0x17, r16\n"
	);
}


static void
baseband_0(void
	//uint8_t startloop
)
{
	//if (startloop)
		toggle(2);
	//else
		//toggle(4);

	toggle(4); // 8
	toggle(4); // 12
	toggle(4); // 16
	toggle(4); // 20
	toggle(4); // 24
	toggle(4); // 28
	toggle(4); // 32
	toggle(4); // 36
	toggle(4); // 40
	toggle(4); // 44
	toggle(4); // 48
	toggle(4); // 52
}


static void
baseband_1(void
	//uint8_t startloop
)
{
	//if (startloop)
		toggle(3);
	//else
		//toggle(5);

	toggle(5); // 10
	toggle(5); // 15
	toggle(5); // 20
	toggle(5); // 25
	toggle(5); // 30
	toggle(5); // 35
	toggle(5); // 40
	toggle(5); // 45
	toggle(5); // 50
}


static inline void
header(void)
{
	baseband_0();
	baseband_0();
	baseband_0();
	baseband_0();
	baseband_1();
	baseband_1();
	baseband_1();
	baseband_1();
}


static void
manchester_bit(
	const uint8_t x
)
{
	if (x)
	{
		baseband_1();
		baseband_0();
	} else {
		baseband_0();
		baseband_1();
	}
}

static inline void
__attribute__((__always_inline__))
manchester(
	const uint32_t x,
	const uint8_t bits
)
{
	switch(bits)
	{
	case 20: manchester_bit(x >> 20);
	case 19: manchester_bit(x >> 19);
	case 18: manchester_bit(x >> 18);
	case 17: manchester_bit(x >> 17);
	case 16: manchester_bit(x >> 16);
	case 15: manchester_bit(x >> 15);
	case 14: manchester_bit(x >> 14);
	case 13: manchester_bit(x >> 13);
	case 12: manchester_bit(x >> 12);
	case 11: manchester_bit(x >> 11);
	case 10: manchester_bit(x >> 10);
	case  9: manchester_bit(x >>  9);
	case  8: manchester_bit(x >>  8);
	case  7: manchester_bit(x >>  7);
	case  6: manchester_bit(x >>  6);
	case  5: manchester_bit(x >>  5);
	case  4: manchester_bit(x >>  4);
	case  3: manchester_bit(x >>  3);
	case  2: manchester_bit(x >>  2);
	case  1: manchester_bit(x >>  1);
	case  0: break;
	}
}


#define HID_MFG_CODE        0x01002  // Do not modify
#define HID_SITE_CODE       42
#define HID_UNIQUE_ID       23946     // May be written on the back of the card

int
main(void)
{
	r16 = 0;
	r17 = 3;

	while (1)
	{
		header();
		manchester(HID_MFG_CODE, 20);
		manchester(HID_SITE_CODE, 8);
		manchester(HID_UNIQUE_ID, 16);
		manchester(0, 1);
	}
}