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 #define va_list __builtin_va_list
18 #define va_start __builtin_va_start
19 #define va_arg __builtin_va_arg
20 #define va_end __builtin_va_end
21 int kvsprintf(char const *fmt
, void *arg
, int radix
, va_list ap
);
23 //=============================================================================
24 // A buffer where we can queue things up to be sent through the FPGA, for
25 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
26 // is the order in which they go out on the wire.
27 //=============================================================================
32 struct common_area common_area
__attribute__((section(".commonarea")));
34 void BufferClear(void)
36 memset(BigBuf
,0,sizeof(BigBuf
));
37 DbpString("Buffer cleared");
40 void ToSendReset(void)
46 void ToSendStuffBit(int b
)
50 ToSend
[ToSendMax
] = 0;
55 ToSend
[ToSendMax
] |= (1 << (7 - ToSendBit
));
60 if(ToSendBit
>= sizeof(ToSend
)) {
62 DbpString("ToSendStuffBit overflowed!");
66 //=============================================================================
67 // Debug print functions, to go out over USB, to the usual PC-side client.
68 //=============================================================================
70 void DbpString(char *str
)
72 /* this holds up stuff unless we're connected to usb */
77 c
.cmd
= CMD_DEBUG_PRINT_STRING
;
78 c
.arg
[0] = strlen(str
);
79 memcpy(c
.d
.asBytes
, str
, c
.arg
[0]);
81 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
82 // TODO fix USB so stupid things like this aren't req'd
87 void DbpIntegers(int x1
, int x2
, int x3
)
89 /* this holds up stuff unless we're connected to usb */
94 c
.cmd
= CMD_DEBUG_PRINT_INTEGERS
;
99 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
105 void Dbprintf(const char *fmt
, ...) {
106 // should probably limit size here; oh well, let's just use a big buffer
107 char output_string
[128];
111 kvsprintf(fmt
, output_string
, 10, ap
);
114 DbpString(output_string
);
117 //-----------------------------------------------------------------------------
118 // Read an ADC channel and block till it completes, then return the result
119 // in ADC units (0 to 1023). Also a routine to average 32 samples and
121 //-----------------------------------------------------------------------------
122 static int ReadAdc(int ch
)
126 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_SWRST
;
127 AT91C_BASE_ADC
->ADC_MR
=
128 ADC_MODE_PRESCALE(32) |
129 ADC_MODE_STARTUP_TIME(16) |
130 ADC_MODE_SAMPLE_HOLD_TIME(8);
131 AT91C_BASE_ADC
->ADC_CHER
= ADC_CHANNEL(ch
);
133 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_START
;
134 while(!(AT91C_BASE_ADC
->ADC_SR
& ADC_END_OF_CONVERSION(ch
)))
136 d
= AT91C_BASE_ADC
->ADC_CDR
[ch
];
141 static int AvgAdc(int ch
)
146 for(i
= 0; i
< 32; i
++) {
150 return (a
+ 15) >> 5;
153 void MeasureAntennaTuning(void)
155 BYTE
*dest
= (BYTE
*)BigBuf
;
156 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
157 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
161 DbpString("Measuring antenna characteristics, please wait.");
162 memset(BigBuf
,0,sizeof(BigBuf
));
165 * Sweeps the useful LF range of the proxmark from
166 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
167 * read the voltage in the antenna, the result left
168 * in the buffer is a graph which should clearly show
169 * the resonating frequency of your LF antenna
170 * ( hopefully around 95 if it is tuned to 125kHz!)
172 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
173 for (i
=255; i
>19; i
--) {
174 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
176 // Vref = 3.3V, and a 10000:240 voltage divider on the input
177 // can measure voltages up to 137500 mV
178 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
179 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
180 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
182 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
191 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
192 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
194 // Vref = 3300mV, and an 10:1 voltage divider on the input
195 // can measure voltages up to 33000 mV
196 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
198 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
199 c
.arg
[0] = (vLf125
<< 0) | (vLf134
<< 16);
201 c
.arg
[2] = peakf
| (peakv
<< 16);
202 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
205 void SimulateTagHfListen(void)
207 BYTE
*dest
= (BYTE
*)BigBuf
;
208 int n
= sizeof(BigBuf
);
213 // We're using this mode just so that I can test it out; the simulated
214 // tag mode would work just as well and be simpler.
215 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
217 // We need to listen to the high-frequency, peak-detected path.
218 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
224 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
225 AT91C_BASE_SSC
->SSC_THR
= 0xff;
227 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
228 BYTE r
= (BYTE
)AT91C_BASE_SSC
->SSC_RHR
;
248 DbpString("simulate tag (now type bitsamples)");
251 void ReadMem(int addr
)
253 const DWORD
*data
= ((DWORD
*)addr
);
255 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
256 addr
, data
[0], data
[1], data
[2], data
[3], data
[4], data
[5], data
[6], data
[7]);
259 /* osimage version information is linked in */
260 extern struct version_information version_information
;
261 /* bootrom version information is pointed to from _bootphase1_version_pointer */
262 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
;
263 void SendVersion(void)
265 char temp
[48]; /* Limited data payload in USB packets */
266 DbpString("Prox/RFID mark3 RFID instrument");
268 /* Try to find the bootrom version information. Expect to find a pointer at
269 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
270 * pointer, then use it.
272 char *bootrom_version
= *(char**)&_bootphase1_version_pointer
;
273 if( bootrom_version
< &_flash_start
|| bootrom_version
>= &_flash_end
) {
274 DbpString("bootrom version information appears invalid");
276 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
280 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
283 FpgaGatherVersion(temp
, sizeof(temp
));
288 // samy's sniff and repeat routine
291 DbpString("Stand-alone mode! No PC necessary.");
293 // 3 possible options? no just 2 for now
296 int high
[OPTS
], low
[OPTS
];
298 // Oooh pretty -- notify user we're in elite samy mode now
300 LED(LED_ORANGE
, 200);
302 LED(LED_ORANGE
, 200);
304 LED(LED_ORANGE
, 200);
306 LED(LED_ORANGE
, 200);
312 // Turn on selected LED
313 LED(selected
+ 1, 0);
320 // Was our button held down or pressed?
321 int button_pressed
= BUTTON_HELD(1000);
324 // Button was held for a second, begin recording
325 if (button_pressed
> 0)
328 LED(selected
+ 1, 0);
332 DbpString("Starting recording");
334 // wait for button to be released
335 while(BUTTON_PRESS())
338 /* need this delay to prevent catching some weird data */
341 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
342 Dbprintf("Recorded %x %x %x", selected
, high
[selected
], low
[selected
]);
345 LED(selected
+ 1, 0);
346 // Finished recording
348 // If we were previously playing, set playing off
349 // so next button push begins playing what we recorded
353 // Change where to record (or begin playing)
354 else if (button_pressed
)
356 // Next option if we were previously playing
358 selected
= (selected
+ 1) % OPTS
;
362 LED(selected
+ 1, 0);
364 // Begin transmitting
368 DbpString("Playing");
369 // wait for button to be released
370 while(BUTTON_PRESS())
372 Dbprintf("%x %x %x", selected
, high
[selected
], low
[selected
]);
373 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
374 DbpString("Done playing");
375 if (BUTTON_HELD(1000) > 0)
377 DbpString("Exiting");
382 /* We pressed a button so ignore it here with a delay */
385 // when done, we're done playing, move to next option
386 selected
= (selected
+ 1) % OPTS
;
389 LED(selected
+ 1, 0);
392 while(BUTTON_PRESS())
401 Listen and detect an external reader. Determine the best location
405 Inside the ListenReaderField() function, there is two mode.
406 By default, when you call the function, you will enter mode 1.
407 If you press the PM3 button one time, you will enter mode 2.
408 If you press the PM3 button a second time, you will exit the function.
410 DESCRIPTION OF MODE 1:
411 This mode just listens for an external reader field and lights up green
412 for HF and/or red for LF. This is the original mode of the detectreader
415 DESCRIPTION OF MODE 2:
416 This mode will visually represent, using the LEDs, the actual strength of the
417 current compared to the maximum current detected. Basically, once you know
418 what kind of external reader is present, it will help you spot the best location to place
419 your antenna. You will probably not get some good results if there is a LF and a HF reader
420 at the same place! :-)
424 static const char LIGHT_SCHEME
[] = {
425 0x0, /* ---- | No field detected */
426 0x1, /* X--- | 14% of maximum current detected */
427 0x2, /* -X-- | 29% of maximum current detected */
428 0x4, /* --X- | 43% of maximum current detected */
429 0x8, /* ---X | 57% of maximum current detected */
430 0xC, /* --XX | 71% of maximum current detected */
431 0xE, /* -XXX | 86% of maximum current detected */
432 0xF, /* XXXX | 100% of maximum current detected */
434 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
436 void ListenReaderField(int limit
)
438 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
439 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
440 int mode
=1, display_val
, display_max
, i
;
447 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
449 if(limit
!= HF_ONLY
) {
450 Dbprintf("LF 125/134 Baseline: %d", lf_av
);
454 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
456 if (limit
!= LF_ONLY
) {
457 Dbprintf("HF 13.56 Baseline: %d", hf_av
);
462 if (BUTTON_PRESS()) {
467 DbpString("Signal Strength Mode");
471 DbpString("Stopped");
479 if (limit
!= HF_ONLY
) {
481 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
486 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
487 // see if there's a significant change
488 if(abs(lf_av
- lf_av_new
) > 10) {
489 Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av
, lf_av_new
, lf_count
);
497 if (limit
!= LF_ONLY
) {
499 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
504 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
505 // see if there's a significant change
506 if(abs(hf_av
- hf_av_new
) > 10) {
507 Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av
, hf_av_new
, hf_count
);
516 if (limit
== LF_ONLY
) {
518 display_max
= lf_max
;
519 } else if (limit
== HF_ONLY
) {
521 display_max
= hf_max
;
522 } else { /* Pick one at random */
523 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
525 display_max
= hf_max
;
528 display_max
= lf_max
;
531 for (i
=0; i
<LIGHT_LEN
; i
++) {
532 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
533 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
534 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
535 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
536 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
544 void UsbPacketReceived(BYTE
*packet
, int len
)
546 UsbCommand
*c
= (UsbCommand
*)packet
;
550 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
551 AcquireRawAdcSamples125k(c
->arg
[0]);
556 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
557 ModThenAcquireRawAdcSamples125k(c
->arg
[0],c
->arg
[1],c
->arg
[2],c
->d
.asBytes
);
562 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
563 AcquireRawAdcSamplesIso15693();
572 case CMD_READER_ISO_15693
:
573 ReaderIso15693(c
->arg
[0]);
577 case CMD_READER_LEGIC_RF
:
582 case CMD_SIMTAG_ISO_15693
:
583 SimTagIso15693(c
->arg
[0]);
587 #ifdef WITH_ISO14443b
588 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
589 AcquireRawAdcSamplesIso14443(c
->arg
[0]);
593 #ifdef WITH_ISO14443b
594 case CMD_READ_SRI512_TAG
:
595 ReadSRI512Iso14443(c
->arg
[0]);
597 case CMD_READ_SRIX4K_TAG
:
598 ReadSRIX4KIso14443(c
->arg
[0]);
602 #ifdef WITH_ISO14443a
603 case CMD_READER_ISO_14443a
:
604 ReaderIso14443a(c
->arg
[0]);
608 #ifdef WITH_ISO14443a
609 case CMD_READER_MIFARE
:
610 ReaderMifare(c
->arg
[0]);
614 #ifdef WITH_ISO14443b
615 case CMD_SNOOP_ISO_14443
:
620 #ifdef WITH_ISO14443a
621 case CMD_SNOOP_ISO_14443a
:
626 case CMD_SIMULATE_TAG_HF_LISTEN
:
627 SimulateTagHfListen();
630 #ifdef WITH_ISO14443b
631 case CMD_SIMULATE_TAG_ISO_14443
:
632 SimulateIso14443Tag();
636 #ifdef WITH_ISO14443a
637 case CMD_SIMULATE_TAG_ISO_14443a
:
638 SimulateIso14443aTag(c
->arg
[0], c
->arg
[1]); // ## Simulate iso14443a tag - pass tag type & UID
642 case CMD_MEASURE_ANTENNA_TUNING
:
643 MeasureAntennaTuning();
646 case CMD_LISTEN_READER_FIELD
:
647 ListenReaderField(c
->arg
[0]);
651 case CMD_HID_DEMOD_FSK
:
652 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
657 case CMD_HID_SIM_TAG
:
658 CmdHIDsimTAG(c
->arg
[0], c
->arg
[1], 1); // Simulate HID tag by ID
662 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
663 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
665 LED_D_OFF(); // LED D indicates field ON or OFF
669 case CMD_READ_TI_TYPE
:
675 case CMD_WRITE_TI_TYPE
:
676 WriteTItag(c
->arg
[0],c
->arg
[1],c
->arg
[2]);
680 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
682 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
683 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
685 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
687 n
.arg
[0] = c
->arg
[0];
688 memcpy(n
.d
.asDwords
, BigBuf
+c
->arg
[0], 12*sizeof(DWORD
));
689 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
693 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
694 BYTE
*b
= (BYTE
*)BigBuf
;
695 memcpy(b
+c
->arg
[0], c
->d
.asBytes
, 48);
700 case CMD_SIMULATE_TAG_125K
:
702 SimulateTagLowFrequency(c
->arg
[0], 1);
711 case CMD_SET_LF_DIVISOR
:
712 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->arg
[0]);
715 case CMD_SET_ADC_MUX
:
717 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break;
718 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break;
719 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break;
720 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break;
729 case CMD_LF_SIMULATE_BIDIR
:
730 SimulateTagLowFrequencyBidir(c
->arg
[0], c
->arg
[1]);
742 case CMD_SETUP_WRITE
:
743 case CMD_FINISH_WRITE
:
744 case CMD_HARDWARE_RESET
:
745 USB_D_PLUS_PULLUP_OFF();
748 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
750 // We're going to reset, and the bootrom will take control.
754 case CMD_START_FLASH
:
755 if(common_area
.flags
.bootrom_present
) {
756 common_area
.command
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
;
758 USB_D_PLUS_PULLUP_OFF();
759 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
763 case CMD_DEVICE_INFO
: {
765 c
.cmd
= CMD_DEVICE_INFO
;
766 c
.arg
[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
;
767 if(common_area
.flags
.bootrom_present
) c
.arg
[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT
;
768 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
772 DbpString("unknown command");
777 void __attribute__((noreturn
)) AppMain(void)
781 if(common_area
.magic
!= COMMON_AREA_MAGIC
|| common_area
.version
!= 1) {
782 /* Initialize common area */
783 memset(&common_area
, 0, sizeof(common_area
));
784 common_area
.magic
= COMMON_AREA_MAGIC
;
785 common_area
.version
= 1;
787 common_area
.flags
.osimage_present
= 1;
796 // The FPGA gets its clock from us from PCK0 output, so set that up.
797 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_PCK0
;
798 AT91C_BASE_PIOA
->PIO_PDR
= GPIO_PCK0
;
799 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_PCK0
;
800 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
801 AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK
|
802 AT91C_PMC_PRES_CLK_4
;
803 AT91C_BASE_PIOA
->PIO_OER
= GPIO_PCK0
;
806 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
808 AT91C_BASE_SSC
->SSC_CR
= AT91C_SSC_SWRST
;
810 // Load the FPGA image, which we have stored in our flash.
817 // test text on different colored backgrounds
818 LCDString(" The quick brown fox ", (char *)&FONT6x8
,1,1+8*0,WHITE
,BLACK
);
819 LCDString(" jumped over the ", (char *)&FONT6x8
,1,1+8*1,BLACK
,WHITE
);
820 LCDString(" lazy dog. ", (char *)&FONT6x8
,1,1+8*2,YELLOW
,RED
);
821 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8
,1,1+8*3,RED
,GREEN
);
822 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
823 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
824 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8
,1,1+8*6,BLACK
,CYAN
);
825 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
828 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
829 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
830 LCDFill(0, 1+8*10, 132, 8, RED
);
831 LCDFill(0, 1+8*11, 132, 8, GREEN
);
832 LCDFill(0, 1+8*12, 132, 8, BLUE
);
833 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
834 LCDFill(0, 1+8*14, 132, 8, CYAN
);
835 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
844 if (BUTTON_HELD(1000) > 0)