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 //-----------------------------------------------------------------------------
18 //=============================================================================
19 // A buffer where we can queue things up to be sent through the FPGA, for
20 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
21 // is the order in which they go out on the wire.
22 //=============================================================================
28 void BufferClear(void)
30 memset(BigBuf
,0,sizeof(BigBuf
));
31 DbpString("Buffer cleared");
34 void ToSendReset(void)
40 void ToSendStuffBit(int b
)
44 ToSend
[ToSendMax
] = 0;
49 ToSend
[ToSendMax
] |= (1 << (7 - ToSendBit
));
54 if(ToSendBit
>= sizeof(ToSend
)) {
56 DbpString("ToSendStuffBit overflowed!");
60 //=============================================================================
61 // Debug print functions, to go out over USB, to the usual PC-side client.
62 //=============================================================================
64 void DbpString(char *str
)
66 /* this holds up stuff unless we're connected to usb */
71 c
.cmd
= CMD_DEBUG_PRINT_STRING
;
73 memcpy(c
.d
.asBytes
, str
, c
.ext1
);
75 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
76 // TODO fix USB so stupid things like this aren't req'd
80 void DbpIntegers(int x1
, int x2
, int x3
)
82 /* this holds up stuff unless we're connected to usb */
87 c
.cmd
= CMD_DEBUG_PRINT_INTEGERS
;
92 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
97 //-----------------------------------------------------------------------------
98 // Read an ADC channel and block till it completes, then return the result
99 // in ADC units (0 to 1023). Also a routine to average 32 samples and
101 //-----------------------------------------------------------------------------
102 static int ReadAdc(int ch
)
106 ADC_CONTROL
= ADC_CONTROL_RESET
;
107 ADC_MODE
= ADC_MODE_PRESCALE(32) | ADC_MODE_STARTUP_TIME(16) |
108 ADC_MODE_SAMPLE_HOLD_TIME(8);
109 ADC_CHANNEL_ENABLE
= ADC_CHANNEL(ch
);
111 ADC_CONTROL
= ADC_CONTROL_START
;
112 while(!(ADC_STATUS
& ADC_END_OF_CONVERSION(ch
)))
114 d
= ADC_CHANNEL_DATA(ch
);
119 static int AvgAdc(int ch
)
124 for(i
= 0; i
< 32; i
++) {
128 return (a
+ 15) >> 5;
131 void MeasureAntennaTuning(void)
133 BYTE
*dest
= (BYTE
*)BigBuf
;
134 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
135 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
139 DbpString("Measuring antenna characteristics, please wait.");
140 memset(BigBuf
,0,sizeof(BigBuf
));
143 * Sweeps the useful LF range of the proxmark from
144 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
145 * read the voltage in the antenna, the result left
146 * in the buffer is a graph which should clearly show
147 * the resonating frequency of your LF antenna
148 * ( hopefully around 95 if it is tuned to 125kHz!)
150 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
151 for (i
=255; i
>19; i
--) {
152 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
154 // Vref = 3.3V, and a 10000:240 voltage divider on the input
155 // can measure voltages up to 137500 mV
156 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
157 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
158 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
160 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
169 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
170 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
172 // Vref = 3300mV, and an 10:1 voltage divider on the input
173 // can measure voltages up to 33000 mV
174 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
176 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
177 c
.ext1
= (vLf125
<< 0) | (vLf134
<< 16);
179 c
.ext3
= peakf
| (peakv
<< 16);
180 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
183 void SimulateTagHfListen(void)
185 BYTE
*dest
= (BYTE
*)BigBuf
;
186 int n
= sizeof(BigBuf
);
191 // We're using this mode just so that I can test it out; the simulated
192 // tag mode would work just as well and be simpler.
193 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
195 // We need to listen to the high-frequency, peak-detected path.
196 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
202 if(SSC_STATUS
& (SSC_STATUS_TX_READY
)) {
203 SSC_TRANSMIT_HOLDING
= 0xff;
205 if(SSC_STATUS
& (SSC_STATUS_RX_READY
)) {
206 BYTE r
= (BYTE
)SSC_RECEIVE_HOLDING
;
226 DbpString("simulate tag (now type bitsamples)");
229 void ReadMem(int addr
)
231 const DWORD
*data
= ((DWORD
*)addr
);
234 DbpString("Reading memory at address");
235 DbpIntegers(0, 0, addr
);
236 for (i
= 0; i
< 8; i
+= 2)
237 DbpIntegers(0, data
[i
], data
[i
+1]);
240 // samy's sniff and repeat routine
243 DbpString("Stand-alone mode! No PC necessary.");
245 // 3 possible options? no just 2 for now
248 int high
[OPTS
], low
[OPTS
];
250 // Oooh pretty -- notify user we're in elite samy mode now
252 LED(LED_ORANGE
, 200);
254 LED(LED_ORANGE
, 200);
256 LED(LED_ORANGE
, 200);
258 LED(LED_ORANGE
, 200);
264 // Turn on selected LED
265 LED(selected
+ 1, 0);
269 usbattached
= UsbPoll(FALSE
);
272 // Was our button held down or pressed?
273 int button_pressed
= BUTTON_HELD(1000);
276 // Button was held for a second, begin recording
277 if (button_pressed
> 0)
280 LED(selected
+ 1, 0);
284 DbpString("Starting recording");
286 // wait for button to be released
287 while(BUTTON_PRESS())
290 /* need this delay to prevent catching some weird data */
293 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
294 DbpString("Recorded");
295 DbpIntegers(selected
, high
[selected
], low
[selected
]);
298 LED(selected
+ 1, 0);
299 // Finished recording
301 // If we were previously playing, set playing off
302 // so next button push begins playing what we recorded
306 // Change where to record (or begin playing)
307 else if (button_pressed
)
309 // Next option if we were previously playing
311 selected
= (selected
+ 1) % OPTS
;
315 LED(selected
+ 1, 0);
317 // Begin transmitting
321 DbpString("Playing");
322 // wait for button to be released
323 while(BUTTON_PRESS())
325 DbpIntegers(selected
, high
[selected
], low
[selected
]);
326 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
327 DbpString("Done playing");
328 if (BUTTON_HELD(1000) > 0)
330 DbpString("Exiting");
335 /* We pressed a button so ignore it here with a delay */
338 // when done, we're done playing, move to next option
339 selected
= (selected
+ 1) % OPTS
;
342 LED(selected
+ 1, 0);
345 while(BUTTON_PRESS())
354 Listen and detect an external reader. Determine the best location
358 Inside the ListenReaderField() function, there is two mode.
359 By default, when you call the function, you will enter mode 1.
360 If you press the PM3 button one time, you will enter mode 2.
361 If you press the PM3 button a second time, you will exit the function.
363 DESCRIPTION OF MODE 1:
364 This mode just listens for an external reader field and lights up green
365 for HF and/or red for LF. This is the original mode of the detectreader
368 DESCRIPTION OF MODE 2:
369 This mode will visually represent, using the LEDs, the actual strength of the
370 current compared to the maximum current detected. Basically, once you know
371 what kind of external reader is present, it will help you spot the best location to place
372 your antenna. You will probably not get some good results if there is a LF and a HF reader
373 at the same place! :-)
377 Light scheme | Descriptiong
378 ----------------------------------------------------
379 ---- | No field detected
380 X--- | 14% of maximum current detected
381 -X-- | 29% of maximum current detected
382 --X- | 43% of maximum current detected
383 ---X | 57% of maximum current detected
384 --XX | 71% of maximum current detected
385 -XXX | 86% of maximum current detected
386 XXXX | 100% of maximum current detected
389 Add the LF part for MODE 2
392 void ListenReaderField(int limit
)
394 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0;
395 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
406 lf_av
= ReadAdc(ADC_CHAN_LF
);
410 DbpString("LF 125/134 Baseline:");
411 DbpIntegers(lf_av
,0,0);
415 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
417 if (limit
!= LF_ONLY
)
419 DbpString("HF 13.56 Baseline:");
420 DbpIntegers(hf_av
,0,0);
426 if (BUTTON_PRESS()) {
431 DbpString("Signal Strength Mode");
435 DbpString("Stopped");
446 if (limit
!= HF_ONLY
)
448 if (abs(lf_av
- lf_baseline
) > 10)
453 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
454 // see if there's a significant change
455 if(abs(lf_av
- lf_av_new
) > 10)
457 DbpString("LF 125/134 Field Change:");
458 DbpIntegers(lf_av
,lf_av_new
,lf_count
);
464 if (limit
!= LF_ONLY
)
466 if (abs(hf_av
- hf_baseline
) > 10) {
470 if ( hf_av
>(hf_max
/7)*6) {
471 LED_A_ON(); LED_B_ON(); LED_C_ON(); LED_D_ON();
473 if ( (hf_av
>(hf_max
/7)*5) && (hf_av
<=(hf_max
/7)*6) ) {
474 LED_A_ON(); LED_B_ON(); LED_C_OFF(); LED_D_ON();
476 if ( (hf_av
>(hf_max
/7)*4) && (hf_av
<=(hf_max
/7)*5) ) {
477 LED_A_OFF(); LED_B_ON(); LED_C_OFF(); LED_D_ON();
479 if ( (hf_av
>(hf_max
/7)*3) && (hf_av
<=(hf_max
/7)*4) ) {
480 LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); LED_D_ON();
482 if ( (hf_av
>(hf_max
/7)*2) && (hf_av
<=(hf_max
/7)*3) ) {
483 LED_A_OFF(); LED_B_ON(); LED_C_OFF(); LED_D_OFF();
485 if ( (hf_av
>(hf_max
/7)*1) && (hf_av
<=(hf_max
/7)*2) ) {
486 LED_A_ON(); LED_B_OFF(); LED_C_OFF(); LED_D_OFF();
488 if ( (hf_av
>(hf_max
/7)*0) && (hf_av
<=(hf_max
/7)*1) ) {
489 LED_A_OFF(); LED_B_OFF(); LED_C_ON(); LED_D_OFF();
497 LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); LED_D_OFF();
502 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
503 // see if there's a significant change
504 if(abs(hf_av
- hf_av_new
) > 10)
506 DbpString("HF 13.56 Field Change:");
507 DbpIntegers(hf_av
,hf_av_new
,hf_count
);
517 void UsbPacketReceived(BYTE
*packet
, int len
)
519 UsbCommand
*c
= (UsbCommand
*)packet
;
522 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
523 AcquireRawAdcSamples125k(c
->ext1
);
526 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
527 ModThenAcquireRawAdcSamples125k(c
->ext1
,c
->ext2
,c
->ext3
,c
->d
.asBytes
);
530 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
531 AcquireRawAdcSamplesIso15693();
538 case CMD_READER_ISO_15693
:
539 ReaderIso15693(c
->ext1
);
542 case CMD_SIMTAG_ISO_15693
:
543 SimTagIso15693(c
->ext1
);
546 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
547 AcquireRawAdcSamplesIso14443(c
->ext1
);
550 case CMD_READ_SRI512_TAG
:
551 ReadSRI512Iso14443(c
->ext1
);
554 case CMD_READER_ISO_14443a
:
555 ReaderIso14443a(c
->ext1
);
558 case CMD_SNOOP_ISO_14443
:
562 case CMD_SNOOP_ISO_14443a
:
566 case CMD_SIMULATE_TAG_HF_LISTEN
:
567 SimulateTagHfListen();
570 case CMD_SIMULATE_TAG_ISO_14443
:
571 SimulateIso14443Tag();
574 case CMD_SIMULATE_TAG_ISO_14443a
:
575 SimulateIso14443aTag(c
->ext1
, c
->ext2
); // ## Simulate iso14443a tag - pass tag type & UID
578 case CMD_MEASURE_ANTENNA_TUNING
:
579 MeasureAntennaTuning();
582 case CMD_LISTEN_READER_FIELD
:
583 ListenReaderField(c
->ext1
);
586 case CMD_HID_DEMOD_FSK
:
587 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
590 case CMD_HID_SIM_TAG
:
591 CmdHIDsimTAG(c
->ext1
, c
->ext2
, 1); // Simulate HID tag by ID
594 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
595 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
597 LED_D_OFF(); // LED D indicates field ON or OFF
600 case CMD_ACQUIRE_RAW_BITS_TI_TYPE
:
604 case CMD_READ_TI_TYPE
:
608 case CMD_WRITE_TI_TYPE
:
609 WriteTItag(c
->ext1
,c
->ext2
,c
->ext3
);
612 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
:
613 case CMD_DOWNLOAD_RAW_BITS_TI_TYPE
: {
615 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
616 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
618 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
621 memcpy(n
.d
.asDwords
, BigBuf
+c
->ext1
, 12*sizeof(DWORD
));
622 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
625 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
626 BYTE
*b
= (BYTE
*)BigBuf
;
627 memcpy(b
+c
->ext1
, c
->d
.asBytes
, 48);
630 case CMD_SIMULATE_TAG_125K
:
632 SimulateTagLowFrequency(c
->ext1
, 1);
643 case CMD_SET_LF_DIVISOR
:
644 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->ext1
);
651 case CMD_SETUP_WRITE
:
652 case CMD_FINISH_WRITE
:
653 case CMD_HARDWARE_RESET
:
654 USB_D_PLUS_PULLUP_OFF();
657 RSTC_CONTROL
= RST_CONTROL_KEY
| RST_CONTROL_PROCESSOR_RESET
;
659 // We're going to reset, and the bootrom will take control.
665 DbpString("unknown command");
672 memset(BigBuf
,0,sizeof(BigBuf
));
682 // The FPGA gets its clock from us from PCK0 output, so set that up.
683 PIO_PERIPHERAL_B_SEL
= (1 << GPIO_PCK0
);
684 PIO_DISABLE
= (1 << GPIO_PCK0
);
685 PMC_SYS_CLK_ENABLE
= PMC_SYS_CLK_PROGRAMMABLE_CLK_0
;
686 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
687 PMC_PROGRAMMABLE_CLK_0
= PMC_CLK_SELECTION_PLL_CLOCK
|
688 PMC_CLK_PRESCALE_DIV_4
;
689 PIO_OUTPUT_ENABLE
= (1 << GPIO_PCK0
);
692 SPI_CONTROL
= SPI_CONTROL_RESET
;
694 SSC_CONTROL
= SSC_CONTROL_RESET
;
696 // Load the FPGA image, which we have stored in our flash.
703 // test text on different colored backgrounds
704 LCDString(" The quick brown fox ", &FONT6x8
,1,1+8*0,WHITE
,BLACK
);
705 LCDString(" jumped over the ", &FONT6x8
,1,1+8*1,BLACK
,WHITE
);
706 LCDString(" lazy dog. ", &FONT6x8
,1,1+8*2,YELLOW
,RED
);
707 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8
,1,1+8*3,RED
,GREEN
);
708 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
709 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
710 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8
,1,1+8*6,BLACK
,CYAN
);
711 LCDString(" _+{}|:\\\"<>? ",&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
714 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
715 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
716 LCDFill(0, 1+8*10, 132, 8, RED
);
717 LCDFill(0, 1+8*11, 132, 8, GREEN
);
718 LCDFill(0, 1+8*12, 132, 8, BLUE
);
719 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
720 LCDFill(0, 1+8*14, 132, 8, CYAN
);
721 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
726 usbattached
= UsbPoll(FALSE
);
729 if (BUTTON_HELD(1000) > 0)