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 /* osimage version information is linked in */
240 extern struct version_information version_information
;
241 /* bootrom version information is pointed to from _bootphase1_version_pointer */
242 extern char _bootphase1_version_pointer
, _flash_start
, _flash_end
;
243 void SendVersion(void)
245 char temp
[48]; /* Limited data payload in USB packets */
246 DbpString("Prox/RFID mark3 RFID instrument");
248 /* Try to find the bootrom version information. Expect to find a pointer at
249 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
250 * pointer, then use it.
252 void *bootrom_version
= *(void**)&_bootphase1_version_pointer
;
253 if( bootrom_version
< (void*)&_flash_start
|| bootrom_version
>= (void*)&_flash_end
) {
254 DbpString("bootrom version information appears invalid");
256 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
260 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
263 FpgaGatherVersion(temp
, sizeof(temp
));
267 // samy's sniff and repeat routine
270 DbpString("Stand-alone mode! No PC necessary.");
272 // 3 possible options? no just 2 for now
275 int high
[OPTS
], low
[OPTS
];
277 // Oooh pretty -- notify user we're in elite samy mode now
279 LED(LED_ORANGE
, 200);
281 LED(LED_ORANGE
, 200);
283 LED(LED_ORANGE
, 200);
285 LED(LED_ORANGE
, 200);
291 // Turn on selected LED
292 LED(selected
+ 1, 0);
299 // Was our button held down or pressed?
300 int button_pressed
= BUTTON_HELD(1000);
303 // Button was held for a second, begin recording
304 if (button_pressed
> 0)
307 LED(selected
+ 1, 0);
311 DbpString("Starting recording");
313 // wait for button to be released
314 while(BUTTON_PRESS())
317 /* need this delay to prevent catching some weird data */
320 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
321 DbpString("Recorded");
322 DbpIntegers(selected
, high
[selected
], low
[selected
]);
325 LED(selected
+ 1, 0);
326 // Finished recording
328 // If we were previously playing, set playing off
329 // so next button push begins playing what we recorded
333 // Change where to record (or begin playing)
334 else if (button_pressed
)
336 // Next option if we were previously playing
338 selected
= (selected
+ 1) % OPTS
;
342 LED(selected
+ 1, 0);
344 // Begin transmitting
348 DbpString("Playing");
349 // wait for button to be released
350 while(BUTTON_PRESS())
352 DbpIntegers(selected
, high
[selected
], low
[selected
]);
353 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
354 DbpString("Done playing");
355 if (BUTTON_HELD(1000) > 0)
357 DbpString("Exiting");
362 /* We pressed a button so ignore it here with a delay */
365 // when done, we're done playing, move to next option
366 selected
= (selected
+ 1) % OPTS
;
369 LED(selected
+ 1, 0);
372 while(BUTTON_PRESS())
381 Listen and detect an external reader. Determine the best location
385 Inside the ListenReaderField() function, there is two mode.
386 By default, when you call the function, you will enter mode 1.
387 If you press the PM3 button one time, you will enter mode 2.
388 If you press the PM3 button a second time, you will exit the function.
390 DESCRIPTION OF MODE 1:
391 This mode just listens for an external reader field and lights up green
392 for HF and/or red for LF. This is the original mode of the detectreader
395 DESCRIPTION OF MODE 2:
396 This mode will visually represent, using the LEDs, the actual strength of the
397 current compared to the maximum current detected. Basically, once you know
398 what kind of external reader is present, it will help you spot the best location to place
399 your antenna. You will probably not get some good results if there is a LF and a HF reader
400 at the same place! :-)
404 static const char LIGHT_SCHEME
[] = {
405 0x0, /* ---- | No field detected */
406 0x1, /* X--- | 14% of maximum current detected */
407 0x2, /* -X-- | 29% of maximum current detected */
408 0x4, /* --X- | 43% of maximum current detected */
409 0x8, /* ---X | 57% of maximum current detected */
410 0xC, /* --XX | 71% of maximum current detected */
411 0xE, /* -XXX | 86% of maximum current detected */
412 0xF, /* XXXX | 100% of maximum current detected */
414 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
416 void ListenReaderField(int limit
)
418 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
419 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
420 int mode
=1, display_val
, display_max
, i
;
427 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
429 if(limit
!= HF_ONLY
) {
430 DbpString("LF 125/134 Baseline:");
431 DbpIntegers(lf_av
,0,0);
435 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
437 if (limit
!= LF_ONLY
) {
438 DbpString("HF 13.56 Baseline:");
439 DbpIntegers(hf_av
,0,0);
444 if (BUTTON_PRESS()) {
449 DbpString("Signal Strength Mode");
453 DbpString("Stopped");
461 if (limit
!= HF_ONLY
) {
463 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
468 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
469 // see if there's a significant change
470 if(abs(lf_av
- lf_av_new
) > 10) {
471 DbpString("LF 125/134 Field Change:");
472 DbpIntegers(lf_av
,lf_av_new
,lf_count
);
480 if (limit
!= LF_ONLY
) {
482 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
487 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
488 // see if there's a significant change
489 if(abs(hf_av
- hf_av_new
) > 10) {
490 DbpString("HF 13.56 Field Change:");
491 DbpIntegers(hf_av
,hf_av_new
,hf_count
);
500 if (limit
== LF_ONLY
) {
502 display_max
= lf_max
;
503 } else if (limit
== HF_ONLY
) {
505 display_max
= hf_max
;
506 } else { /* Pick one at random */
507 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
509 display_max
= hf_max
;
512 display_max
= lf_max
;
515 for (i
=0; i
<LIGHT_LEN
; i
++) {
516 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
517 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
518 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
519 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
520 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
528 void UsbPacketReceived(BYTE
*packet
, int len
)
530 UsbCommand
*c
= (UsbCommand
*)packet
;
533 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
534 AcquireRawAdcSamples125k(c
->ext1
);
537 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
538 ModThenAcquireRawAdcSamples125k(c
->ext1
,c
->ext2
,c
->ext3
,c
->d
.asBytes
);
541 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
542 AcquireRawAdcSamplesIso15693();
549 case CMD_READER_ISO_15693
:
550 ReaderIso15693(c
->ext1
);
553 case CMD_SIMTAG_ISO_15693
:
554 SimTagIso15693(c
->ext1
);
557 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
558 AcquireRawAdcSamplesIso14443(c
->ext1
);
561 case CMD_READ_SRI512_TAG
:
562 ReadSRI512Iso14443(c
->ext1
);
565 case CMD_READER_ISO_14443a
:
566 ReaderIso14443a(c
->ext1
);
569 case CMD_SNOOP_ISO_14443
:
573 case CMD_SNOOP_ISO_14443a
:
577 case CMD_SIMULATE_TAG_HF_LISTEN
:
578 SimulateTagHfListen();
581 case CMD_SIMULATE_TAG_ISO_14443
:
582 SimulateIso14443Tag();
585 case CMD_SIMULATE_TAG_ISO_14443a
:
586 SimulateIso14443aTag(c
->ext1
, c
->ext2
); // ## Simulate iso14443a tag - pass tag type & UID
589 case CMD_MEASURE_ANTENNA_TUNING
:
590 MeasureAntennaTuning();
593 case CMD_LISTEN_READER_FIELD
:
594 ListenReaderField(c
->ext1
);
597 case CMD_HID_DEMOD_FSK
:
598 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
601 case CMD_HID_SIM_TAG
:
602 CmdHIDsimTAG(c
->ext1
, c
->ext2
, 1); // Simulate HID tag by ID
605 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
606 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
608 LED_D_OFF(); // LED D indicates field ON or OFF
611 case CMD_READ_TI_TYPE
:
615 case CMD_WRITE_TI_TYPE
:
616 WriteTItag(c
->ext1
,c
->ext2
,c
->ext3
);
619 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
621 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
622 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
624 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
627 memcpy(n
.d
.asDwords
, BigBuf
+c
->ext1
, 12*sizeof(DWORD
));
628 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
631 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
632 BYTE
*b
= (BYTE
*)BigBuf
;
633 memcpy(b
+c
->ext1
, c
->d
.asBytes
, 48);
636 case CMD_SIMULATE_TAG_125K
:
638 SimulateTagLowFrequency(c
->ext1
, 1);
644 case CMD_SET_LF_DIVISOR
:
645 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->ext1
);
650 case CMD_LF_SIMULATE_BIDIR
:
651 SimulateTagLowFrequencyBidir(c
->ext1
, c
->ext2
);
661 case CMD_SETUP_WRITE
:
662 case CMD_FINISH_WRITE
:
663 case CMD_HARDWARE_RESET
:
664 USB_D_PLUS_PULLUP_OFF();
667 RSTC_CONTROL
= RST_CONTROL_KEY
| RST_CONTROL_PROCESSOR_RESET
;
669 // We're going to reset, and the bootrom will take control.
674 DbpString("unknown command");
681 memset(BigBuf
,0,sizeof(BigBuf
));
691 // The FPGA gets its clock from us from PCK0 output, so set that up.
692 PIO_PERIPHERAL_B_SEL
= (1 << GPIO_PCK0
);
693 PIO_DISABLE
= (1 << GPIO_PCK0
);
694 PMC_SYS_CLK_ENABLE
= PMC_SYS_CLK_PROGRAMMABLE_CLK_0
;
695 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
696 PMC_PROGRAMMABLE_CLK_0
= PMC_CLK_SELECTION_PLL_CLOCK
|
697 PMC_CLK_PRESCALE_DIV_4
;
698 PIO_OUTPUT_ENABLE
= (1 << GPIO_PCK0
);
701 SPI_CONTROL
= SPI_CONTROL_RESET
;
703 SSC_CONTROL
= SSC_CONTROL_RESET
;
705 // Load the FPGA image, which we have stored in our flash.
712 // test text on different colored backgrounds
713 LCDString(" The quick brown fox ", &FONT6x8
,1,1+8*0,WHITE
,BLACK
);
714 LCDString(" jumped over the ", &FONT6x8
,1,1+8*1,BLACK
,WHITE
);
715 LCDString(" lazy dog. ", &FONT6x8
,1,1+8*2,YELLOW
,RED
);
716 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8
,1,1+8*3,RED
,GREEN
);
717 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
718 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
719 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8
,1,1+8*6,BLACK
,CYAN
);
720 LCDString(" _+{}|:\\\"<>? ",&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
723 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
724 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
725 LCDFill(0, 1+8*10, 132, 8, RED
);
726 LCDFill(0, 1+8*11, 132, 8, GREEN
);
727 LCDFill(0, 1+8*12, 132, 8, BLUE
);
728 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
729 LCDFill(0, 1+8*14, 132, 8, CYAN
);
730 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
738 if (BUTTON_HELD(1000) > 0)