Added stand-alone mode (no PC) with HID reading and cloning, moved helper functions to util.c

This commit is contained in:
skamkar 2009-07-13 04:54:37 +00:00
commit 955fc5e2f8
3 changed files with 345 additions and 57 deletions

View file

@ -17,6 +17,7 @@
// The large multi-purpose buffer, typically used to hold A/D samples, // The large multi-purpose buffer, typically used to hold A/D samples,
// maybe pre-processed in some way. // maybe pre-processed in some way.
DWORD BigBuf[16000]; DWORD BigBuf[16000];
int usbattached = 0;
//============================================================================= //=============================================================================
// A buffer where we can queue things up to be sent through the FPGA, for // A buffer where we can queue things up to be sent through the FPGA, for
@ -67,6 +68,10 @@ void ToSendStuffBit(int b)
void DbpString(char *str) void DbpString(char *str)
{ {
/* this holds up stuff unless we're connected to usb */
if (!usbattached)
return;
UsbCommand c; UsbCommand c;
c.cmd = CMD_DEBUG_PRINT_STRING; c.cmd = CMD_DEBUG_PRINT_STRING;
c.ext1 = strlen(str); c.ext1 = strlen(str);
@ -79,6 +84,10 @@ void DbpString(char *str)
void DbpIntegers(int x1, int x2, int x3) void DbpIntegers(int x1, int x2, int x3)
{ {
/* this holds up stuff unless we're connected to usb */
if (!usbattached)
return;
UsbCommand c; UsbCommand c;
c.cmd = CMD_DEBUG_PRINT_INTEGERS; c.cmd = CMD_DEBUG_PRINT_INTEGERS;
c.ext1 = x1; c.ext1 = x1;
@ -320,7 +329,7 @@ void MeasureAntennaTuning(void)
UsbSendPacket((BYTE *)&c, sizeof(c)); UsbSendPacket((BYTE *)&c, sizeof(c));
} }
void SimulateTagLowFrequency(int period) void SimulateTagLowFrequency(int period, int ledcontrol)
{ {
int i; int i;
BYTE *tab = (BYTE *)BigBuf; BYTE *tab = (BYTE *)BigBuf;
@ -345,13 +354,16 @@ void SimulateTagLowFrequency(int period)
WDT_HIT(); WDT_HIT();
} }
LED_D_ON(); if (ledcontrol)
if(tab[i]) { LED_D_ON();
if(tab[i])
OPEN_COIL(); OPEN_COIL();
} else { else
SHORT_COIL(); SHORT_COIL();
}
LED_D_OFF(); if (ledcontrol)
LED_D_OFF();
while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) { while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) {
if(BUTTON_PRESS()) { if(BUTTON_PRESS()) {
@ -415,7 +427,7 @@ static void fc(int c, int *n) {
// prepare a waveform pattern in the buffer based on the ID given then // prepare a waveform pattern in the buffer based on the ID given then
// simulate a HID tag until the button is pressed // simulate a HID tag until the button is pressed
static void CmdHIDsimTAG(int hi, int lo) static void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
{ {
int n=0, i=0; int n=0, i=0;
/* /*
@ -461,13 +473,16 @@ static void CmdHIDsimTAG(int hi, int lo)
} }
} }
LED_A_ON(); if (ledcontrol)
SimulateTagLowFrequency(n); LED_A_ON();
LED_A_OFF(); SimulateTagLowFrequency(n, ledcontrol);
if (ledcontrol)
LED_A_OFF();
} }
// loop to capture raw HID waveform then FSK demodulate the TAG ID from it // loop to capture raw HID waveform then FSK demodulate the TAG ID from it
static void CmdHIDdemodFSK(void) static void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{ {
BYTE *dest = (BYTE *)BigBuf; BYTE *dest = (BYTE *)BigBuf;
int m=0, n=0, i=0, idx=0, found=0, lastval=0; int m=0, n=0, i=0, idx=0, found=0, lastval=0;
@ -487,10 +502,12 @@ static void CmdHIDdemodFSK(void)
for(;;) { for(;;) {
WDT_HIT(); WDT_HIT();
LED_A_ON(); if (ledcontrol)
LED_A_ON();
if(BUTTON_PRESS()) { if(BUTTON_PRESS()) {
DbpString("Stopped"); DbpString("Stopped");
LED_A_OFF(); if (ledcontrol)
LED_A_OFF();
return; return;
} }
@ -500,7 +517,8 @@ static void CmdHIDdemodFSK(void)
for(;;) { for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) { if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43; SSC_TRANSMIT_HOLDING = 0x43;
LED_D_ON(); if (ledcontrol)
LED_D_ON();
} }
if(SSC_STATUS & (SSC_STATUS_RX_READY)) { if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
dest[i] = (BYTE)SSC_RECEIVE_HOLDING; dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
@ -508,7 +526,8 @@ static void CmdHIDdemodFSK(void)
// threshold essentially we capture zero crossings for later analysis // threshold essentially we capture zero crossings for later analysis
if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
i++; i++;
LED_D_OFF(); if (ledcontrol)
LED_D_OFF();
if(i >= m) { if(i >= m) {
break; break;
} }
@ -607,6 +626,13 @@ static void CmdHIDdemodFSK(void)
if (found && (hi|lo)) { if (found && (hi|lo)) {
DbpString("TAG ID"); DbpString("TAG ID");
DbpIntegers(hi, lo, (lo>>1)&0xffff); DbpIntegers(hi, lo, (lo>>1)&0xffff);
/* if we're only looking for one tag */
if (findone)
{
*high = hi;
*low = lo;
return;
}
hi=0; hi=0;
lo=0; lo=0;
found=0; found=0;
@ -633,6 +659,13 @@ static void CmdHIDdemodFSK(void)
if (found && (hi|lo)) { if (found && (hi|lo)) {
DbpString("TAG ID"); DbpString("TAG ID");
DbpIntegers(hi, lo, (lo>>1)&0xffff); DbpIntegers(hi, lo, (lo>>1)&0xffff);
/* if we're only looking for one tag */
if (findone)
{
*high = hi;
*low = lo;
return;
}
hi=0; hi=0;
lo=0; lo=0;
found=0; found=0;
@ -759,11 +792,11 @@ void UsbPacketReceived(BYTE *packet, int len)
break; break;
case CMD_HID_DEMOD_FSK: case CMD_HID_DEMOD_FSK:
CmdHIDdemodFSK(); // Demodulate HID tag CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
break; break;
case CMD_HID_SIM_TAG: case CMD_HID_SIM_TAG:
CmdHIDsimTAG(c->ext1, c->ext2); // Simulate HID tag by ID CmdHIDsimTAG(c->ext1, c->ext2, 1); // Simulate HID tag by ID
break; break;
case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
@ -792,7 +825,7 @@ void UsbPacketReceived(BYTE *packet, int len)
} }
case CMD_SIMULATE_TAG_125K: case CMD_SIMULATE_TAG_125K:
LED_A_ON(); LED_A_ON();
SimulateTagLowFrequency(c->ext1); SimulateTagLowFrequency(c->ext1, 1);
LED_A_OFF(); LED_A_OFF();
break; break;
#ifdef WITH_LCD #ifdef WITH_LCD
@ -887,54 +920,109 @@ void AppMain(void)
#endif #endif
for(;;) { for(;;) {
UsbPoll(FALSE); usbattached = UsbPoll(FALSE);
WDT_HIT(); WDT_HIT();
if (BUTTON_HELD(1000) > 0)
SamyRun();
} }
} }
void SpinDelayUs(int us)
// samy's sniff and repeat routine
void SamyRun()
{ {
int ticks = (48*us) >> 10; DbpString("Stand-alone mode! No PC necessary.");
// Borrow a PWM unit for my real-time clock // 3 possible options? no just 2 for now
PWM_ENABLE = PWM_CHANNEL(0); #define OPTS 2
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0); int high[OPTS], low[OPTS];
for(;;) { // Oooh pretty -- notify user we're in elite samy mode now
WORD now = (WORD)PWM_CH_COUNTER(0); LED(LED_RED, 200);
if(now == (WORD)(start + ticks)) { LED(LED_ORANGE, 200);
return; LED(LED_GREEN, 200);
} LED(LED_ORANGE, 200);
LED(LED_RED, 200);
LED(LED_ORANGE, 200);
LED(LED_GREEN, 200);
LED(LED_ORANGE, 200);
LED(LED_RED, 200);
int selected = 0;
int playing = 0;
// Turn on selected LED
LED(selected + 1, 0);
for (;;)
{
usbattached = UsbPoll(FALSE);
WDT_HIT(); WDT_HIT();
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
SpinDelay(300);
// Button was held for a second, begin recording
if (button_pressed > 0)
{
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// record
DbpString("Starting recording");
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
DbpString("Recorded");
DbpIntegers(selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
}
// Change where to record (or begin playing)
else if (button_pressed)
{
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
// Begin transmitting
if (playing)
{
LED(LED_GREEN, 0);
DbpString("Playing");
DbpIntegers(selected, high[selected], low[selected]);
CmdHIDsimTAG(high[selected], low[selected], 0);
DbpString("Done playing");
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
}
} }
} }
void SpinDelay(int ms)
{
int ticks = (48000*ms) >> 10;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
for(;;) {
WORD now = (WORD)PWM_CH_COUNTER(0);
if(now == (WORD)(start + ticks)) {
return;
}
WDT_HIT();
}
}
// listen for external reader // listen for external reader
void ListenReaderField(int limit) void ListenReaderField(int limit)

View file

@ -9,10 +9,9 @@
/// appmain.c /// appmain.c
void AppMain(void); void AppMain(void);
void SamyRun(void);
void DbpIntegers(int a, int b, int c); void DbpIntegers(int a, int b, int c);
void DbpString(char *str); void DbpString(char *str);
void SpinDelay(int ms);
void SpinDelayUs(int us);
void ToSendStuffBit(int b); void ToSendStuffBit(int b);
void ToSendReset(void); void ToSendReset(void);
void ListenReaderField(int limit); void ListenReaderField(int limit);
@ -78,9 +77,24 @@ void ReaderIso15693(DWORD parameter); // Simulate an ISO15693 reader - greg
void SimTagIso15693(DWORD parameter); // simulate an ISO15693 tag - greg void SimTagIso15693(DWORD parameter); // simulate an ISO15693 tag - greg
/// util.h /// util.h
#define LED_RED 1
#define LED_ORANGE 2
#define LED_GREEN 4
#define LED_RED2 8
#define BUTTON_HOLD 1
#define BUTTON_NO_CLICK 0
#define BUTTON_SINGLE_CLICK -1
#define BUTTON_DOUBLE_CLICK -2
#define BUTTON_ERROR -99
int strlen(char *str); int strlen(char *str);
void *memcpy(void *dest, const void *src, int len); void *memcpy(void *dest, const void *src, int len);
void *memset(void *dest, int c, int len); void *memset(void *dest, int c, int len);
int memcmp(const void *av, const void *bv, int len); int memcmp(const void *av, const void *bv, int len);
void SpinDelay(int ms);
void SpinDelayUs(int us);
void LED(int led, int ms);
void LEDsoff();
int BUTTON_CLICKED(int ms);
int BUTTON_HELD(int ms);
#endif #endif

View file

@ -51,3 +51,189 @@ int strlen(char *str)
} }
return l; return l;
} }
void LEDsoff()
{
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
LED_D_OFF();
}
// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
void LED(int led, int ms)
{
if (led & LED_RED)
LED_C_ON();
if (led & LED_ORANGE)
LED_A_ON();
if (led & LED_GREEN)
LED_B_ON();
if (led & LED_RED2)
LED_D_ON();
if (!ms)
return;
SpinDelay(ms);
if (led & LED_RED)
LED_C_OFF();
if (led & LED_ORANGE)
LED_A_OFF();
if (led & LED_GREEN)
LED_B_OFF();
if (led & LED_RED2)
LED_D_OFF();
}
// Determine if a button is double clicked, single clicked,
// not clicked, or held down (for ms || 1sec)
// In general, don't use this function unless you expect a
// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
int BUTTON_CLICKED(int ms)
{
// Up to 500ms in between clicks to mean a double click
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
// If we're not even pressed, forget about it!
if (!BUTTON_PRESS())
return BUTTON_NO_CLICK;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
int letoff = 0;
for(;;)
{
WORD now = (WORD)PWM_CH_COUNTER(0);
// We haven't let off the button yet
if (!letoff)
{
// We just let it off!
if (!BUTTON_PRESS())
{
letoff = 1;
// reset our timer for 500ms
start = (WORD)PWM_CH_COUNTER(0);
ticks = (48000 * (500)) >> 10;
}
// Still haven't let it off
else
// Have we held down a full second?
if (now == (WORD)(start + ticks))
return BUTTON_HOLD;
}
// We already let off, did we click again?
else
// Sweet, double click!
if (BUTTON_PRESS())
return BUTTON_DOUBLE_CLICK;
// Have we ran out of time to double click?
else
if (now == (WORD)(start + ticks))
// At least we did a single click
return BUTTON_SINGLE_CLICK;
WDT_HIT();
}
// We should never get here
return BUTTON_ERROR;
}
// Determine if a button is held down
int BUTTON_HELD(int ms)
{
// If button is held for one second
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
// If we're not even pressed, forget about it!
if (!BUTTON_PRESS())
return BUTTON_NO_CLICK;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
for(;;)
{
WORD now = (WORD)PWM_CH_COUNTER(0);
// As soon as our button let go, we didn't hold long enough
if (!BUTTON_PRESS())
return BUTTON_SINGLE_CLICK;
// Have we waited the full second?
else
if (now == (WORD)(start + ticks))
return BUTTON_HOLD;
WDT_HIT();
}
// We should never get here
return BUTTON_ERROR;
}
void SpinDelayUs(int us)
{
int ticks = (48*us) >> 10;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
for(;;) {
WORD now = (WORD)PWM_CH_COUNTER(0);
if(now == (WORD)(start + ticks)) {
return;
}
WDT_HIT();
}
}
void SpinDelay(int ms)
{
int ticks = (48000*ms) >> 10;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
for(;;)
{
WORD now = (WORD)PWM_CH_COUNTER(0);
if (now == (WORD)(start + ticks))
return;
WDT_HIT();
}
}