1 //-----------------------------------------------------------------------------
2 // The main application code. This is the first thing called after start.c
4 // Jonathan Westhues, Mar 2006
5 // Edits by Gerhard de Koning Gans, Sep 2007 (##)
6 //-----------------------------------------------------------------------------
17 //=============================================================================
18 // A buffer where we can queue things up to be sent through the FPGA, for
19 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
20 // is the order in which they go out on the wire.
21 //=============================================================================
27 void BufferClear(void)
29 memset(BigBuf
,0,sizeof(BigBuf
));
30 DbpString("Buffer cleared");
33 void ToSendReset(void)
39 void ToSendStuffBit(int b
)
43 ToSend
[ToSendMax
] = 0;
48 ToSend
[ToSendMax
] |= (1 << (7 - ToSendBit
));
53 if(ToSendBit
>= sizeof(ToSend
)) {
55 DbpString("ToSendStuffBit overflowed!");
59 //=============================================================================
60 // Debug print functions, to go out over USB, to the usual PC-side client.
61 //=============================================================================
63 void DbpString(char *str
)
65 /* this holds up stuff unless we're connected to usb */
70 c
.cmd
= CMD_DEBUG_PRINT_STRING
;
72 memcpy(c
.d
.asBytes
, str
, c
.ext1
);
74 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
75 // TODO fix USB so stupid things like this aren't req'd
79 void DbpIntegers(int x1
, int x2
, int x3
)
81 /* this holds up stuff unless we're connected to usb */
86 c
.cmd
= CMD_DEBUG_PRINT_INTEGERS
;
91 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
96 //-----------------------------------------------------------------------------
97 // Read an ADC channel and block till it completes, then return the result
98 // in ADC units (0 to 1023). Also a routine to average 32 samples and
100 //-----------------------------------------------------------------------------
101 static int ReadAdc(int ch
)
105 ADC_CONTROL
= ADC_CONTROL_RESET
;
106 ADC_MODE
= ADC_MODE_PRESCALE(32) | ADC_MODE_STARTUP_TIME(16) |
107 ADC_MODE_SAMPLE_HOLD_TIME(8);
108 ADC_CHANNEL_ENABLE
= ADC_CHANNEL(ch
);
110 ADC_CONTROL
= ADC_CONTROL_START
;
111 while(!(ADC_STATUS
& ADC_END_OF_CONVERSION(ch
)))
113 d
= ADC_CHANNEL_DATA(ch
);
118 static int AvgAdc(int ch
)
123 for(i
= 0; i
< 32; i
++) {
127 return (a
+ 15) >> 5;
130 void MeasureAntennaTuning(void)
132 BYTE
*dest
= (BYTE
*)BigBuf
;
133 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
134 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
138 DbpString("Measuring antenna characteristics, please wait.");
139 memset(BigBuf
,0,sizeof(BigBuf
));
142 * Sweeps the useful LF range of the proxmark from
143 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
144 * read the voltage in the antenna, the result left
145 * in the buffer is a graph which should clearly show
146 * the resonating frequency of your LF antenna
147 * ( hopefully around 95 if it is tuned to 125kHz!)
149 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
150 for (i
=255; i
>19; i
--) {
151 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
153 // Vref = 3.3V, and a 10000:240 voltage divider on the input
154 // can measure voltages up to 137500 mV
155 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
156 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
157 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
159 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
168 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
169 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
171 // Vref = 3300mV, and an 10:1 voltage divider on the input
172 // can measure voltages up to 33000 mV
173 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
175 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
176 c
.ext1
= (vLf125
<< 0) | (vLf134
<< 16);
178 c
.ext3
= peakf
| (peakv
<< 16);
179 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
182 void SimulateTagHfListen(void)
184 BYTE
*dest
= (BYTE
*)BigBuf
;
185 int n
= sizeof(BigBuf
);
190 // We're using this mode just so that I can test it out; the simulated
191 // tag mode would work just as well and be simpler.
192 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
194 // We need to listen to the high-frequency, peak-detected path.
195 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
201 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
202 SSC_TRANSMIT_HOLDING
= 0xff;
204 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
205 BYTE r
= (BYTE
)SSC_RECEIVE_HOLDING
;
225 DbpString("simulate tag (now type bitsamples)");
228 void ReadMem(int addr
)
230 const DWORD
*data
= ((DWORD
*)addr
);
233 DbpString("Reading memory at address");
234 DbpIntegers(0, 0, addr
);
235 for (i
= 0; i
< 8; i
+= 2)
236 DbpIntegers(0, data
[i
], data
[i
+1]);
239 // samy's sniff and repeat routine
242 DbpString("Stand-alone mode! No PC necessary.");
244 // 3 possible options? no just 2 for now
247 int high
[OPTS
], low
[OPTS
];
249 // Oooh pretty -- notify user we're in elite samy mode now
251 LED(LED_ORANGE
, 200);
253 LED(LED_ORANGE
, 200);
255 LED(LED_ORANGE
, 200);
257 LED(LED_ORANGE
, 200);
263 // Turn on selected LED
264 LED(selected
+ 1, 0);
271 // Was our button held down or pressed?
272 int button_pressed
= BUTTON_HELD(1000);
275 // Button was held for a second, begin recording
276 if (button_pressed
> 0)
279 LED(selected
+ 1, 0);
283 DbpString("Starting recording");
285 // wait for button to be released
286 while(BUTTON_PRESS())
289 /* need this delay to prevent catching some weird data */
292 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
293 DbpString("Recorded");
294 DbpIntegers(selected
, high
[selected
], low
[selected
]);
297 LED(selected
+ 1, 0);
298 // Finished recording
300 // If we were previously playing, set playing off
301 // so next button push begins playing what we recorded
305 // Change where to record (or begin playing)
306 else if (button_pressed
)
308 // Next option if we were previously playing
310 selected
= (selected
+ 1) % OPTS
;
314 LED(selected
+ 1, 0);
316 // Begin transmitting
320 DbpString("Playing");
321 // wait for button to be released
322 while(BUTTON_PRESS())
324 DbpIntegers(selected
, high
[selected
], low
[selected
]);
325 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
326 DbpString("Done playing");
327 if (BUTTON_HELD(1000) > 0)
329 DbpString("Exiting");
334 /* We pressed a button so ignore it here with a delay */
337 // when done, we're done playing, move to next option
338 selected
= (selected
+ 1) % OPTS
;
341 LED(selected
+ 1, 0);
344 while(BUTTON_PRESS())
353 Listen and detect an external reader. Determine the best location
357 Inside the ListenReaderField() function, there is two mode.
358 By default, when you call the function, you will enter mode 1.
359 If you press the PM3 button one time, you will enter mode 2.
360 If you press the PM3 button a second time, you will exit the function.
362 DESCRIPTION OF MODE 1:
363 This mode just listens for an external reader field and lights up green
364 for HF and/or red for LF. This is the original mode of the detectreader
367 DESCRIPTION OF MODE 2:
368 This mode will visually represent, using the LEDs, the actual strength of the
369 current compared to the maximum current detected. Basically, once you know
370 what kind of external reader is present, it will help you spot the best location to place
371 your antenna. You will probably not get some good results if there is a LF and a HF reader
372 at the same place! :-)
376 Light scheme | Descriptiong
377 ----------------------------------------------------
378 ---- | No field detected
379 X--- | 14% of maximum current detected
380 -X-- | 29% of maximum current detected
381 --X- | 43% of maximum current detected
382 ---X | 57% of maximum current detected
383 --XX | 71% of maximum current detected
384 -XXX | 86% of maximum current detected
385 XXXX | 100% of maximum current detected
388 Add the LF part for MODE 2
391 void ListenReaderField(int limit
)
393 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0;
394 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
405 lf_av
= ReadAdc(ADC_CHAN_LF
);
409 DbpString("LF 125/134 Baseline:");
410 DbpIntegers(lf_av
,0,0);
414 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
416 if (limit
!= LF_ONLY
)
418 DbpString("HF 13.56 Baseline:");
419 DbpIntegers(hf_av
,0,0);
425 if (BUTTON_PRESS()) {
430 DbpString("Signal Strength Mode");
434 DbpString("Stopped");
445 if (limit
!= HF_ONLY
)
447 if (abs(lf_av
- lf_baseline
) > 10)
452 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
453 // see if there's a significant change
454 if(abs(lf_av
- lf_av_new
) > 10)
456 DbpString("LF 125/134 Field Change:");
457 DbpIntegers(lf_av
,lf_av_new
,lf_count
);
463 if (limit
!= LF_ONLY
)
465 if (abs(hf_av
- hf_baseline
) > 10) {
469 if ( hf_av
>(hf_max
/7)*6) {
470 LED_A_ON(); LED_B_ON(); LED_C_ON(); LED_D_ON();
472 if ( (hf_av
>(hf_max
/7)*5) && (hf_av
<=(hf_max
/7)*6) ) {
473 LED_A_ON(); LED_B_ON(); LED_C_OFF(); LED_D_ON();
475 if ( (hf_av
>(hf_max
/7)*4) && (hf_av
<=(hf_max
/7)*5) ) {
476 LED_A_OFF(); LED_B_ON(); LED_C_OFF(); LED_D_ON();
478 if ( (hf_av
>(hf_max
/7)*3) && (hf_av
<=(hf_max
/7)*4) ) {
479 LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); LED_D_ON();
481 if ( (hf_av
>(hf_max
/7)*2) && (hf_av
<=(hf_max
/7)*3) ) {
482 LED_A_OFF(); LED_B_ON(); LED_C_OFF(); LED_D_OFF();
484 if ( (hf_av
>(hf_max
/7)*1) && (hf_av
<=(hf_max
/7)*2) ) {
485 LED_A_ON(); LED_B_OFF(); LED_C_OFF(); LED_D_OFF();
487 if ( (hf_av
>(hf_max
/7)*0) && (hf_av
<=(hf_max
/7)*1) ) {
488 LED_A_OFF(); LED_B_OFF(); LED_C_ON(); LED_D_OFF();
496 LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); LED_D_OFF();
501 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
502 // see if there's a significant change
503 if(abs(hf_av
- hf_av_new
) > 10)
505 DbpString("HF 13.56 Field Change:");
506 DbpIntegers(hf_av
,hf_av_new
,hf_count
);
516 void UsbPacketReceived(BYTE
*packet
, int len
)
518 UsbCommand
*c
= (UsbCommand
*)packet
;
521 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
522 AcquireRawAdcSamples125k(c
->ext1
);
525 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
526 ModThenAcquireRawAdcSamples125k(c
->ext1
,c
->ext2
,c
->ext3
,c
->d
.asBytes
);
529 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
530 AcquireRawAdcSamplesIso15693();
537 case CMD_READER_ISO_15693
:
538 ReaderIso15693(c
->ext1
);
541 case CMD_SIMTAG_ISO_15693
:
542 SimTagIso15693(c
->ext1
);
545 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
546 AcquireRawAdcSamplesIso14443(c
->ext1
);
549 case CMD_READ_SRI512_TAG
:
550 ReadSRI512Iso14443(c
->ext1
);
553 case CMD_READER_ISO_14443a
:
554 ReaderIso14443a(c
->ext1
);
557 case CMD_SNOOP_ISO_14443
:
561 case CMD_SNOOP_ISO_14443a
:
565 case CMD_SIMULATE_TAG_HF_LISTEN
:
566 SimulateTagHfListen();
569 case CMD_SIMULATE_TAG_ISO_14443
:
570 SimulateIso14443Tag();
573 case CMD_SIMULATE_TAG_ISO_14443a
:
574 SimulateIso14443aTag(c
->ext1
, c
->ext2
); // ## Simulate iso14443a tag - pass tag type & UID
577 case CMD_MEASURE_ANTENNA_TUNING
:
578 MeasureAntennaTuning();
581 case CMD_LISTEN_READER_FIELD
:
582 ListenReaderField(c
->ext1
);
585 case CMD_HID_DEMOD_FSK
:
586 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
589 case CMD_HID_SIM_TAG
:
590 CmdHIDsimTAG(c
->ext1
, c
->ext2
, 1); // Simulate HID tag by ID
593 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
594 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
596 LED_D_OFF(); // LED D indicates field ON or OFF
599 case CMD_READ_TI_TYPE
:
603 case CMD_WRITE_TI_TYPE
:
604 WriteTItag(c
->ext1
,c
->ext2
,c
->ext3
);
607 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
609 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
610 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
612 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
615 memcpy(n
.d
.asDwords
, BigBuf
+c
->ext1
, 12*sizeof(DWORD
));
616 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
619 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
620 BYTE
*b
= (BYTE
*)BigBuf
;
621 memcpy(b
+c
->ext1
, c
->d
.asBytes
, 48);
624 case CMD_SIMULATE_TAG_125K
:
626 SimulateTagLowFrequency(c
->ext1
, 1);
632 case CMD_SET_LF_DIVISOR
:
633 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->ext1
);
643 case CMD_SETUP_WRITE
:
644 case CMD_FINISH_WRITE
:
645 case CMD_HARDWARE_RESET
:
646 USB_D_PLUS_PULLUP_OFF();
649 RSTC_CONTROL
= RST_CONTROL_KEY
| RST_CONTROL_PROCESSOR_RESET
;
651 // We're going to reset, and the bootrom will take control.
656 DbpString("unknown command");
663 memset(BigBuf
,0,sizeof(BigBuf
));
673 // The FPGA gets its clock from us from PCK0 output, so set that up.
674 PIO_PERIPHERAL_B_SEL
= (1 << GPIO_PCK0
);
675 PIO_DISABLE
= (1 << GPIO_PCK0
);
676 PMC_SYS_CLK_ENABLE
= PMC_SYS_CLK_PROGRAMMABLE_CLK_0
;
677 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
678 PMC_PROGRAMMABLE_CLK_0
= PMC_CLK_SELECTION_PLL_CLOCK
|
679 PMC_CLK_PRESCALE_DIV_4
;
680 PIO_OUTPUT_ENABLE
= (1 << GPIO_PCK0
);
683 SPI_CONTROL
= SPI_CONTROL_RESET
;
685 SSC_CONTROL
= SSC_CONTROL_RESET
;
687 // Load the FPGA image, which we have stored in our flash.
694 // test text on different colored backgrounds
695 LCDString(" The quick brown fox ", &FONT6x8
,1,1+8*0,WHITE
,BLACK
);
696 LCDString(" jumped over the ", &FONT6x8
,1,1+8*1,BLACK
,WHITE
);
697 LCDString(" lazy dog. ", &FONT6x8
,1,1+8*2,YELLOW
,RED
);
698 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8
,1,1+8*3,RED
,GREEN
);
699 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
700 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
701 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8
,1,1+8*6,BLACK
,CYAN
);
702 LCDString(" _+{}|:\\\"<>? ",&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
705 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
706 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
707 LCDFill(0, 1+8*10, 132, 8, RED
);
708 LCDFill(0, 1+8*11, 132, 8, GREEN
);
709 LCDFill(0, 1+8*12, 132, 8, BLUE
);
710 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
711 LCDFill(0, 1+8*14, 132, 8, CYAN
);
712 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
720 if (BUTTON_HELD(1000) > 0)