diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 77bbbbc4d..a137a8fe6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -17,6 +17,7 @@ // The large multi-purpose buffer, typically used to hold A/D samples, // maybe pre-processed in some way. DWORD BigBuf[16000]; +int usbattached = 0; //============================================================================= // 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) { + /* this holds up stuff unless we're connected to usb */ + if (!usbattached) + return; + UsbCommand c; c.cmd = CMD_DEBUG_PRINT_STRING; c.ext1 = strlen(str); @@ -79,6 +84,10 @@ void DbpString(char *str) void DbpIntegers(int x1, int x2, int x3) { + /* this holds up stuff unless we're connected to usb */ + if (!usbattached) + return; + UsbCommand c; c.cmd = CMD_DEBUG_PRINT_INTEGERS; c.ext1 = x1; @@ -320,7 +329,7 @@ void MeasureAntennaTuning(void) UsbSendPacket((BYTE *)&c, sizeof(c)); } -void SimulateTagLowFrequency(int period) +void SimulateTagLowFrequency(int period, int ledcontrol) { int i; BYTE *tab = (BYTE *)BigBuf; @@ -345,13 +354,16 @@ void SimulateTagLowFrequency(int period) WDT_HIT(); } - LED_D_ON(); - if(tab[i]) { + if (ledcontrol) + LED_D_ON(); + + if(tab[i]) OPEN_COIL(); - } else { + else SHORT_COIL(); - } - LED_D_OFF(); + + if (ledcontrol) + LED_D_OFF(); while(PIO_PIN_DATA_STATUS & (1<= m) { break; } @@ -607,6 +626,13 @@ static void CmdHIDdemodFSK(void) if (found && (hi|lo)) { DbpString("TAG ID"); DbpIntegers(hi, lo, (lo>>1)&0xffff); + /* if we're only looking for one tag */ + if (findone) + { + *high = hi; + *low = lo; + return; + } hi=0; lo=0; found=0; @@ -633,6 +659,13 @@ static void CmdHIDdemodFSK(void) if (found && (hi|lo)) { DbpString("TAG ID"); DbpIntegers(hi, lo, (lo>>1)&0xffff); + /* if we're only looking for one tag */ + if (findone) + { + *high = hi; + *low = lo; + return; + } hi=0; lo=0; found=0; @@ -759,11 +792,11 @@ void UsbPacketReceived(BYTE *packet, int len) break; case CMD_HID_DEMOD_FSK: - CmdHIDdemodFSK(); // Demodulate HID tag + CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag break; 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; case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control @@ -792,7 +825,7 @@ void UsbPacketReceived(BYTE *packet, int len) } case CMD_SIMULATE_TAG_125K: LED_A_ON(); - SimulateTagLowFrequency(c->ext1); + SimulateTagLowFrequency(c->ext1, 1); LED_A_OFF(); break; #ifdef WITH_LCD @@ -887,54 +920,109 @@ void AppMain(void) #endif for(;;) { - UsbPoll(FALSE); + usbattached = UsbPoll(FALSE); 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 - 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; + // 3 possible options? no just 2 for now +#define OPTS 2 - WORD start = (WORD)PWM_CH_COUNTER(0); - - for(;;) { - WORD now = (WORD)PWM_CH_COUNTER(0); - if(now == (WORD)(start + ticks)) { - return; - } + int high[OPTS], low[OPTS]; + + // Oooh pretty -- notify user we're in elite samy mode now + LED(LED_RED, 200); + LED(LED_ORANGE, 200); + 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(); + + // 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 void ListenReaderField(int limit) diff --git a/armsrc/apps.h b/armsrc/apps.h index f2be79044..7e40fdd0a 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -9,10 +9,9 @@ /// appmain.c void AppMain(void); +void SamyRun(void); void DbpIntegers(int a, int b, int c); void DbpString(char *str); -void SpinDelay(int ms); -void SpinDelayUs(int us); void ToSendStuffBit(int b); void ToSendReset(void); 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 /// 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); void *memcpy(void *dest, const void *src, int len); void *memset(void *dest, int c, 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 diff --git a/armsrc/util.c b/armsrc/util.c index b3f0e76e4..5af09f886 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -51,3 +51,189 @@ int strlen(char *str) } 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(); + } +}