]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/appmain.c
This version code now reads a TI tag properly.
[proxmark3-svn] / armsrc / appmain.c
index 27a7551d55d06b680b35999321f6b072b3d1a55a..a5c082e59e9325cd0ff138d55454063ce3388128 100644 (file)
@@ -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;
@@ -94,10 +103,10 @@ void AcquireRawAdcSamples125k(BOOL at134khz)
 {
        if(at134khz) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        } else {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        }
 
        // Connect the A/D to the peak-detected low-frequency path.
@@ -144,17 +153,17 @@ void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYT
        BOOL at134khz;
 
        // see if 'h' was specified
-       if(command[strlen(command) - 1] == 'h')
+       if(command[strlen((char *) command) - 1] == 'h')
                at134khz= TRUE;
        else
                at134khz= FALSE;
-       
+
        if(at134khz) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        } else {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        }
 
        // Give it a bit of time for the resonant antenna to settle.
@@ -171,10 +180,10 @@ void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYT
                SpinDelayUs(delay_off);
                if(at134khz) {
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
                } else {
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
                }
                LED_D_ON();
                if(*(command++) == '0')
@@ -187,16 +196,88 @@ void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYT
        SpinDelayUs(delay_off);
        if(at134khz) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        } else {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        }
 
        // now do the read
        DoAcquisition125k(at134khz);
 }
 
+void AcquireTiType(void)
+{
+       int i;
+       int n = 5000;
+
+       // clear buffer
+       memset(BigBuf,0,sizeof(BigBuf));
+
+       // Set up the synchronous serial port
+  PIO_DISABLE = (1<<GPIO_SSC_DIN);
+  PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN);
+
+       // steal this pin from the SSP and use it to control the modulation
+  PIO_ENABLE = (1<<GPIO_SSC_DOUT);
+       PIO_OUTPUT_ENABLE       = (1<<GPIO_SSC_DOUT);
+
+  SSC_CONTROL = SSC_CONTROL_RESET;
+  SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
+
+  // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
+  // 48/2 = 24 MHz clock must be divided by 12
+  SSC_CLOCK_DIVISOR = 12;
+
+  SSC_RECEIVE_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(0);
+       SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(32) | SSC_FRAME_MODE_MSB_FIRST;
+       SSC_TRANSMIT_CLOCK_MODE = 0;
+       SSC_TRANSMIT_FRAME_MODE = 0;
+
+       LED_D_ON();
+
+       // modulate antenna
+       PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
+
+       // Charge TI tag for 50ms.
+       SpinDelay(50);
+
+       // stop modulating antenna and listen
+       PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
+
+       LED_D_OFF();
+
+       i = 0;
+       for(;;) {
+                       if(SSC_STATUS & SSC_STATUS_RX_READY) {
+                                       BigBuf[i] = SSC_RECEIVE_HOLDING;        // store 32 bit values in buffer
+                                       i++; if(i >= n) return;
+                       }
+                       WDT_HIT();
+       }
+
+       // return stolen pin ro SSP
+       PIO_DISABLE = (1<<GPIO_SSC_DOUT);
+       PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN) | (1<<GPIO_SSC_DOUT);
+}
+
+void AcquireRawBitsTI(void)
+{
+       LED_D_ON();
+       // TI tags charge at 134.2Khz
+       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
+       // Place FPGA in passthrough mode, in this mode the CROSS_LO line
+       // connects to SSP_DIN and the SSP_DOUT logic level controls
+       // whether we're modulating the antenna (high)
+       // or listening to the antenna (low)
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
+
+       // get TI tag data into the buffer
+       AcquireTiType();
+
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+}
+
 //-----------------------------------------------------------------------------
 // Read an ADC channel and block till it completes, then return the result
 // in ADC units (0 to 1023). Also a routine to average 32 samples and
@@ -231,73 +312,59 @@ static int AvgAdc(int ch)
        return (a + 15) >> 5;
 }
 
-/*
- * Sweeps the useful LF range of the proxmark from
- * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
- * reads the voltage in the antenna: the result is a graph
- * which should clearly show the resonating frequency of your
- * LF antenna ( hopefully around 90 if it is tuned to 125kHz!)
- */
-void SweepLFrange()
+void MeasureAntennaTuning(void)
 {
        BYTE *dest = (BYTE *)BigBuf;
-       int i;
+       int i, ptr = 0, adcval = 0, peak = 0, peakv = 0, peakf = 0;;
+       int vLf125 = 0, vLf134 = 0, vHf = 0;    // in mV
 
-       // clear buffer
+       UsbCommand c;
+
+       DbpString("Measuring antenna characteristics, please wait.");
        memset(BigBuf,0,sizeof(BigBuf));
 
+/*
+ * Sweeps the useful LF range of the proxmark from
+ * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
+ * read the voltage in the antenna, the result left
+ * in the buffer is a graph which should clearly show
+ * the resonating frequency of your LF antenna
+ * ( hopefully around 95 if it is tuned to 125kHz!)
+ */
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        for (i=255; i>19; i--) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
                SpinDelay(20);
-               dest[i] = (137500 * AvgAdc(ADC_CHAN_LF)) >> 18;
+               // Vref = 3.3V, and a 10000:240 voltage divider on the input
+               // can measure voltages up to 137500 mV
+               adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);
+               if (i==95)      vLf125 = adcval; // voltage at 125Khz
+               if (i==89)      vLf134 = adcval; // voltage at 134Khz
+
+               dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
+               if(dest[i] > peak) {
+                       peakv = adcval;
+                       peak = dest[i];
+                       peakf = i;
+                       ptr = i;
+               }
        }
-}
-
-void MeasureAntennaTuning(void)
-{
-// Impedances are Zc = 1/(j*omega*C), in ohms
-#define LF_TUNING_CAP_Z        1273    //  1 nF @ 125   kHz
-#define HF_TUNING_CAP_Z        235             // 50 pF @ 13.56 MHz
-
-       int vLf125, vLf134, vHf;        // in mV
-
-       UsbCommand c;
-
-       // Let the FPGA drive the low-frequency antenna around 125 kHz.
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
-       SpinDelay(20);
-       vLf125 = AvgAdc(ADC_CHAN_LF);
-       // Vref = 3.3V, and a 10000:240 voltage divider on the input
-       // can measure voltages up to 137500 mV
-       vLf125 = (137500 * vLf125) >> 10;
-
-       // Let the FPGA drive the low-frequency antenna around 134 kHz.
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
-       SpinDelay(20);
-       vLf134 = AvgAdc(ADC_CHAN_LF);
-       // Vref = 3.3V, and a 10000:240 voltage divider on the input
-       // can measure voltages up to 137500 mV
-       vLf134 = (137500 * vLf134) >> 10;
 
        // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        SpinDelay(20);
-       vHf = AvgAdc(ADC_CHAN_HF);
        // Vref = 3300mV, and an 10:1 voltage divider on the input
        // can measure voltages up to 33000 mV
-       vHf = (33000 * vHf) >> 10;
+       vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
 
        c.cmd = CMD_MEASURED_ANTENNA_TUNING;
        c.ext1 = (vLf125 << 0) | (vLf134 << 16);
        c.ext2 = vHf;
-       c.ext3 = (LF_TUNING_CAP_Z << 0) | (HF_TUNING_CAP_Z << 16);
+       c.ext3 = peakf | (peakv << 16);
        UsbSendPacket((BYTE *)&c, sizeof(c));
 }
 
-void SimulateTagLowFrequency(int period)
+void SimulateTagLowFrequency(int period, int ledcontrol)
 {
        int i;
        BYTE *tab = (BYTE *)BigBuf;
@@ -316,21 +383,26 @@ void SimulateTagLowFrequency(int period)
        for(;;) {
                while(!(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK))) {
                        if(BUTTON_PRESS()) {
+                               DbpString("Stopped");
                                return;
                        }
                        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<<GPIO_SSC_CLK)) {
                        if(BUTTON_PRESS()) {
+                               DbpString("Stopped");
                                return;
                        }
                        WDT_HIT();
@@ -390,7 +462,7 @@ static void fc(int c, int *n) {
 
 // prepare a waveform pattern in the buffer based on the ID given then
 // 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;
        /*
@@ -436,20 +508,23 @@ static void CmdHIDsimTAG(int hi, int lo)
                }
        }
 
-       LED_A_ON();
-       SimulateTagLowFrequency(n);
-       LED_A_OFF();
+       if (ledcontrol)
+               LED_A_ON();
+       SimulateTagLowFrequency(n, ledcontrol);
+
+       if (ledcontrol)
+               LED_A_OFF();
 }
 
 // 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;
        int m=0, n=0, i=0, idx=0, found=0, lastval=0;
        DWORD hi=0, lo=0;
 
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 
        // Connect the A/D to the peak-detected low-frequency path.
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -462,9 +537,12 @@ static void CmdHIDdemodFSK(void)
 
        for(;;) {
                WDT_HIT();
-               LED_A_ON();
+               if (ledcontrol)
+                       LED_A_ON();
                if(BUTTON_PRESS()) {
-                       LED_A_OFF();
+                       DbpString("Stopped");
+                       if (ledcontrol)
+                               LED_A_OFF();
                        return;
                }
 
@@ -474,7 +552,8 @@ static void CmdHIDdemodFSK(void)
                for(;;) {
                        if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
                                SSC_TRANSMIT_HOLDING = 0x43;
-                               LED_D_ON();
+                               if (ledcontrol)
+                                       LED_D_ON();
                        }
                        if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
                                dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
@@ -482,7 +561,8 @@ static void CmdHIDdemodFSK(void)
                                // threshold essentially we capture zero crossings for later analysis
                                if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
                                i++;
-                               LED_D_OFF();
+                               if (ledcontrol)
+                                       LED_D_OFF();
                                if(i >= m) {
                                        break;
                                }
@@ -581,6 +661,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;
@@ -607,6 +694,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;
@@ -676,6 +770,10 @@ void UsbPacketReceived(BYTE *packet, int len)
                        ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
                        break;
 
+               case CMD_ACQUIRE_RAW_BITS_TI_TYPE:
+                       AcquireRawBitsTI();
+                       break;
+
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
                        AcquireRawAdcSamplesIso15693();
                        break;
@@ -733,11 +831,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
@@ -766,7 +864,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
@@ -774,10 +872,9 @@ void UsbPacketReceived(BYTE *packet, int len)
                        LCDReset();
                        break;
 #endif
-               case CMD_SWEEP_LF:
-                       SweepLFrange();
+               case CMD_READ_MEM:
+                       ReadMem(c->ext1);
                        break;
-
                case CMD_SET_LF_DIVISOR:
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
                        break;
@@ -805,15 +902,26 @@ void UsbPacketReceived(BYTE *packet, int len)
        }
 }
 
+void ReadMem(int addr)
+{
+       const DWORD *data = ((DWORD *)addr);
+       int i;
+
+       DbpString("Reading memory at address");
+       DbpIntegers(0, 0, addr);
+       for (i = 0; i < 8; i+= 2)
+               DbpIntegers(0, data[i], data[i+1]);
+}
+
 void AppMain(void)
 {
        memset(BigBuf,0,sizeof(BigBuf));
        SpinDelay(100);
 
-    LED_D_OFF();
-    LED_C_OFF();
-    LED_B_OFF();
-    LED_A_OFF();
+       LED_D_OFF();
+       LED_C_OFF();
+       LED_B_OFF();
+       LED_A_OFF();
 
        UsbStart();
 
@@ -839,14 +947,14 @@ void AppMain(void)
        LCDInit();
 
        // test text on different colored backgrounds
-    LCDString(" The quick brown fox  ",        &FONT6x8,1,1+8*0,WHITE  ,BLACK );
-    LCDString("  jumped over the     ",        &FONT6x8,1,1+8*1,BLACK  ,WHITE );
-    LCDString("     lazy dog.        ",        &FONT6x8,1,1+8*2,YELLOW ,RED   );
-    LCDString(" AaBbCcDdEeFfGgHhIiJj ",        &FONT6x8,1,1+8*3,RED    ,GREEN );
-    LCDString(" KkLlMmNnOoPpQqRrSsTt ",        &FONT6x8,1,1+8*4,MAGENTA,BLUE  );
-    LCDString("UuVvWwXxYyZz0123456789",        &FONT6x8,1,1+8*5,BLUE   ,YELLOW);
-    LCDString("`-=[]_;',./~!@#$%^&*()",        &FONT6x8,1,1+8*6,BLACK  ,CYAN  );
-    LCDString("     _+{}|:\\\"<>?     ",&FONT6x8,1,1+8*7,BLUE  ,MAGENTA);
+       LCDString(" The quick brown fox  ",     &FONT6x8,1,1+8*0,WHITE  ,BLACK );
+       LCDString("  jumped over the     ",     &FONT6x8,1,1+8*1,BLACK  ,WHITE );
+       LCDString("     lazy dog.        ",     &FONT6x8,1,1+8*2,YELLOW ,RED   );
+       LCDString(" AaBbCcDdEeFfGgHhIiJj ",     &FONT6x8,1,1+8*3,RED    ,GREEN );
+       LCDString(" KkLlMmNnOoPpQqRrSsTt ",     &FONT6x8,1,1+8*4,MAGENTA,BLUE  );
+       LCDString("UuVvWwXxYyZz0123456789",     &FONT6x8,1,1+8*5,BLUE   ,YELLOW);
+       LCDString("`-=[]_;',./~!@#$%^&*()",     &FONT6x8,1,1+8*6,BLACK  ,CYAN  );
+       LCDString("     _+{}|:\\\"<>?     ",&FONT6x8,1,1+8*7,BLUE  ,MAGENTA);
 
        // color bands
        LCDFill(0, 1+8* 8, 132, 8, BLACK);
@@ -861,60 +969,132 @@ 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);
+       int high[OPTS], low[OPTS];
 
-       for(;;) {
-               WORD now = (WORD)PWM_CH_COUNTER(0);
-               if(now == (WORD)(start + ticks)) {
-                       return;
-               }
+       // 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();
-       }
-}
 
-void SpinDelay(int ms)
-{
-       int ticks = (48000*ms) >> 10;
+               // Was our button held down or pressed?
+               int button_pressed = BUTTON_HELD(1000);
+               SpinDelay(300);
 
-       // 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;
+               // Button was held for a second, begin recording
+               if (button_pressed > 0)
+               {
+                       LEDsoff();
+                       LED(selected + 1, 0);
+                       LED(LED_RED2, 0);
 
-       WORD start = (WORD)PWM_CH_COUNTER(0);
+                       // record
+                       DbpString("Starting recording");
 
-       for(;;) {
-               WORD now = (WORD)PWM_CH_COUNTER(0);
-               if(now == (WORD)(start + ticks)) {
-                       return;
+                       // wait for button to be released
+                       while(BUTTON_PRESS())
+                               WDT_HIT();
+
+                       /* 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");
+                               // wait for button to be released
+                               while(BUTTON_PRESS())
+                                       WDT_HIT();
+                               DbpIntegers(selected, high[selected], low[selected]);
+                               CmdHIDsimTAG(high[selected], low[selected], 0);
+                               DbpString("Done playing");
+                               if (BUTTON_HELD(1000) > 0)
+                                       {
+                                       DbpString("Exiting");
+                                       LEDsoff();
+                                       return;
+                                       }
+
+                               /* 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);
+                       }
+                       else
+                               while(BUTTON_PRESS())
+                                       WDT_HIT();
                }
-               WDT_HIT();
        }
 }
 
-// listen for external reader 
+
+// listen for external reader
 void ListenReaderField(int limit)
 {
-       int lf_av, lf_av_new, lf_baseline= -1, lf_count= 0;
-       int hf_av, hf_av_new,  hf_baseline= -1, hf_count= 0;
+       int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0;
+       int hf_av, hf_av_new,  hf_baseline= 0, hf_count= 0;
 
 #define LF_ONLY                1
 #define HF_ONLY                2
@@ -926,7 +1106,7 @@ void ListenReaderField(int limit)
 
        lf_av= ReadAdc(ADC_CHAN_LF);
 
-       if(limit != HF_ONLY && lf_baseline ==  -1) 
+       if(limit != HF_ONLY)
                {
                DbpString("LF 125/134 Baseline:");
                DbpIntegers(lf_av,0,0);
@@ -936,17 +1116,18 @@ void ListenReaderField(int limit)
        hf_av= ReadAdc(ADC_CHAN_HF);
 
 
-       if (limit != LF_ONLY && hf_baseline == -1) 
+       if (limit != LF_ONLY)
                {
                DbpString("HF 13.56 Baseline:");
                DbpIntegers(hf_av,0,0);
                hf_baseline= hf_av;
                }
 
-       for(;;) 
+       for(;;)
                {
-               if(BUTTON_PRESS()) 
+               if(BUTTON_PRESS())
                        {
+                       DbpString("Stopped");
                        LED_B_OFF();
                        LED_D_OFF();
                        return;
@@ -954,7 +1135,7 @@ void ListenReaderField(int limit)
                WDT_HIT();
 
 
-               if (limit != HF_ONLY) 
+               if (limit != HF_ONLY)
                        {
                        if (abs(lf_av - lf_baseline) > 10)
                                LED_D_ON();
@@ -963,7 +1144,7 @@ void ListenReaderField(int limit)
                        ++lf_count;
                        lf_av_new= ReadAdc(ADC_CHAN_LF);
                        // see if there's a significant change
-                       if(abs(lf_av - lf_av_new) > 10) 
+                       if(abs(lf_av - lf_av_new) > 10)
                                {
                                DbpString("LF 125/134 Field Change:");
                                DbpIntegers(lf_av,lf_av_new,lf_count);
@@ -972,7 +1153,7 @@ void ListenReaderField(int limit)
                                }
                        }
 
-               if (limit != LF_ONLY) 
+               if (limit != LF_ONLY)
                        {
                        if (abs(hf_av - hf_baseline) > 10)
                                LED_B_ON();
@@ -981,7 +1162,7 @@ void ListenReaderField(int limit)
                        ++hf_count;
                        hf_av_new= ReadAdc(ADC_CHAN_HF);
                        // see if there's a significant change
-                       if(abs(hf_av - hf_av_new) > 10) 
+                       if(abs(hf_av - hf_av_new) > 10)
                                {
                                DbpString("HF 13.56 Field Change:");
                                DbpIntegers(hf_av,hf_av_new,hf_count);
Impressum, Datenschutz