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 //-----------------------------------------------------------------------------
16 //=============================================================================
17 // A buffer where we can queue things up to be sent through the FPGA, for
18 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
19 // is the order in which they go out on the wire.
20 //=============================================================================
25 struct common_area common_area
__attribute__((section(".commonarea")));
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 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_SWRST
;
106 AT91C_BASE_ADC
->ADC_MR
=
107 ADC_MODE_PRESCALE(32) |
108 ADC_MODE_STARTUP_TIME(16) |
109 ADC_MODE_SAMPLE_HOLD_TIME(8);
110 AT91C_BASE_ADC
->ADC_CHER
= ADC_CHANNEL(ch
);
112 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_START
;
113 while(!(AT91C_BASE_ADC
->ADC_SR
& ADC_END_OF_CONVERSION(ch
)))
115 d
= AT91C_BASE_ADC
->ADC_CDR
[ch
];
120 static int AvgAdc(int ch
)
125 for(i
= 0; i
< 32; i
++) {
129 return (a
+ 15) >> 5;
132 void MeasureAntennaTuning(void)
134 BYTE
*dest
= (BYTE
*)BigBuf
;
135 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
136 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
140 DbpString("Measuring antenna characteristics, please wait.");
141 memset(BigBuf
,0,sizeof(BigBuf
));
144 * Sweeps the useful LF range of the proxmark from
145 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
146 * read the voltage in the antenna, the result left
147 * in the buffer is a graph which should clearly show
148 * the resonating frequency of your LF antenna
149 * ( hopefully around 95 if it is tuned to 125kHz!)
151 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
152 for (i
=255; i
>19; i
--) {
153 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
155 // Vref = 3.3V, and a 10000:240 voltage divider on the input
156 // can measure voltages up to 137500 mV
157 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
158 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
159 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
161 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
170 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
171 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
173 // Vref = 3300mV, and an 10:1 voltage divider on the input
174 // can measure voltages up to 33000 mV
175 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
177 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
178 c
.ext1
= (vLf125
<< 0) | (vLf134
<< 16);
180 c
.ext3
= peakf
| (peakv
<< 16);
181 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
184 void SimulateTagHfListen(void)
186 BYTE
*dest
= (BYTE
*)BigBuf
;
187 int n
= sizeof(BigBuf
);
192 // We're using this mode just so that I can test it out; the simulated
193 // tag mode would work just as well and be simpler.
194 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
196 // We need to listen to the high-frequency, peak-detected path.
197 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
203 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
204 AT91C_BASE_SSC
->SSC_THR
= 0xff;
206 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
207 BYTE r
= (BYTE
)AT91C_BASE_SSC
->SSC_RHR
;
227 DbpString("simulate tag (now type bitsamples)");
230 void ReadMem(int addr
)
232 const DWORD
*data
= ((DWORD
*)addr
);
235 DbpString("Reading memory at address");
236 DbpIntegers(0, 0, addr
);
237 for (i
= 0; i
< 8; i
+= 2)
238 DbpIntegers(0, data
[i
], data
[i
+1]);
241 /* osimage version information is linked in */
242 extern struct version_information version_information
;
243 /* bootrom version information is pointed to from _bootphase1_version_pointer */
244 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
;
245 void SendVersion(void)
247 char temp
[48]; /* Limited data payload in USB packets */
248 DbpString("Prox/RFID mark3 RFID instrument");
250 /* Try to find the bootrom version information. Expect to find a pointer at
251 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
252 * pointer, then use it.
254 char *bootrom_version
= *(char**)&_bootphase1_version_pointer
;
255 if( bootrom_version
< &_flash_start
|| bootrom_version
>= &_flash_end
) {
256 DbpString("bootrom version information appears invalid");
258 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
262 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
265 FpgaGatherVersion(temp
, sizeof(temp
));
269 // samy's sniff and repeat routine
272 DbpString("Stand-alone mode! No PC necessary.");
274 // 3 possible options? no just 2 for now
277 int high
[OPTS
], low
[OPTS
];
279 // Oooh pretty -- notify user we're in elite samy mode now
281 LED(LED_ORANGE
, 200);
283 LED(LED_ORANGE
, 200);
285 LED(LED_ORANGE
, 200);
287 LED(LED_ORANGE
, 200);
293 // Turn on selected LED
294 LED(selected
+ 1, 0);
301 // Was our button held down or pressed?
302 int button_pressed
= BUTTON_HELD(1000);
305 // Button was held for a second, begin recording
306 if (button_pressed
> 0)
309 LED(selected
+ 1, 0);
313 DbpString("Starting recording");
315 // wait for button to be released
316 while(BUTTON_PRESS())
319 /* need this delay to prevent catching some weird data */
322 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
323 DbpString("Recorded");
324 DbpIntegers(selected
, high
[selected
], low
[selected
]);
327 LED(selected
+ 1, 0);
328 // Finished recording
330 // If we were previously playing, set playing off
331 // so next button push begins playing what we recorded
335 // Change where to record (or begin playing)
336 else if (button_pressed
)
338 // Next option if we were previously playing
340 selected
= (selected
+ 1) % OPTS
;
344 LED(selected
+ 1, 0);
346 // Begin transmitting
350 DbpString("Playing");
351 // wait for button to be released
352 while(BUTTON_PRESS())
354 DbpIntegers(selected
, high
[selected
], low
[selected
]);
355 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
356 DbpString("Done playing");
357 if (BUTTON_HELD(1000) > 0)
359 DbpString("Exiting");
364 /* We pressed a button so ignore it here with a delay */
367 // when done, we're done playing, move to next option
368 selected
= (selected
+ 1) % OPTS
;
371 LED(selected
+ 1, 0);
374 while(BUTTON_PRESS())
383 Listen and detect an external reader. Determine the best location
387 Inside the ListenReaderField() function, there is two mode.
388 By default, when you call the function, you will enter mode 1.
389 If you press the PM3 button one time, you will enter mode 2.
390 If you press the PM3 button a second time, you will exit the function.
392 DESCRIPTION OF MODE 1:
393 This mode just listens for an external reader field and lights up green
394 for HF and/or red for LF. This is the original mode of the detectreader
397 DESCRIPTION OF MODE 2:
398 This mode will visually represent, using the LEDs, the actual strength of the
399 current compared to the maximum current detected. Basically, once you know
400 what kind of external reader is present, it will help you spot the best location to place
401 your antenna. You will probably not get some good results if there is a LF and a HF reader
402 at the same place! :-)
406 static const char LIGHT_SCHEME
[] = {
407 0x0, /* ---- | No field detected */
408 0x1, /* X--- | 14% of maximum current detected */
409 0x2, /* -X-- | 29% of maximum current detected */
410 0x4, /* --X- | 43% of maximum current detected */
411 0x8, /* ---X | 57% of maximum current detected */
412 0xC, /* --XX | 71% of maximum current detected */
413 0xE, /* -XXX | 86% of maximum current detected */
414 0xF, /* XXXX | 100% of maximum current detected */
416 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
418 void ListenReaderField(int limit
)
420 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
421 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
422 int mode
=1, display_val
, display_max
, i
;
429 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
431 if(limit
!= HF_ONLY
) {
432 DbpString("LF 125/134 Baseline:");
433 DbpIntegers(lf_av
,0,0);
437 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
439 if (limit
!= LF_ONLY
) {
440 DbpString("HF 13.56 Baseline:");
441 DbpIntegers(hf_av
,0,0);
446 if (BUTTON_PRESS()) {
451 DbpString("Signal Strength Mode");
455 DbpString("Stopped");
463 if (limit
!= HF_ONLY
) {
465 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
470 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
471 // see if there's a significant change
472 if(abs(lf_av
- lf_av_new
) > 10) {
473 DbpString("LF 125/134 Field Change:");
474 DbpIntegers(lf_av
,lf_av_new
,lf_count
);
482 if (limit
!= LF_ONLY
) {
484 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
489 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
490 // see if there's a significant change
491 if(abs(hf_av
- hf_av_new
) > 10) {
492 DbpString("HF 13.56 Field Change:");
493 DbpIntegers(hf_av
,hf_av_new
,hf_count
);
502 if (limit
== LF_ONLY
) {
504 display_max
= lf_max
;
505 } else if (limit
== HF_ONLY
) {
507 display_max
= hf_max
;
508 } else { /* Pick one at random */
509 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
511 display_max
= hf_max
;
514 display_max
= lf_max
;
517 for (i
=0; i
<LIGHT_LEN
; i
++) {
518 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
519 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
520 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
521 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
522 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
530 void UsbPacketReceived(BYTE
*packet
, int len
)
532 UsbCommand
*c
= (UsbCommand
*)packet
;
535 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
536 AcquireRawAdcSamples125k(c
->ext1
);
539 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
540 ModThenAcquireRawAdcSamples125k(c
->ext1
,c
->ext2
,c
->ext3
,c
->d
.asBytes
);
543 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
544 AcquireRawAdcSamplesIso15693();
551 case CMD_READER_ISO_15693
:
552 ReaderIso15693(c
->ext1
);
555 case CMD_SIMTAG_ISO_15693
:
556 SimTagIso15693(c
->ext1
);
559 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
560 AcquireRawAdcSamplesIso14443(c
->ext1
);
563 case CMD_READ_SRI512_TAG
:
564 ReadSRI512Iso14443(c
->ext1
);
567 case CMD_READER_ISO_14443a
:
568 ReaderIso14443a(c
->ext1
);
571 case CMD_SNOOP_ISO_14443
:
575 case CMD_SNOOP_ISO_14443a
:
579 case CMD_SIMULATE_TAG_HF_LISTEN
:
580 SimulateTagHfListen();
583 case CMD_SIMULATE_TAG_ISO_14443
:
584 SimulateIso14443Tag();
587 case CMD_SIMULATE_TAG_ISO_14443a
:
588 SimulateIso14443aTag(c
->ext1
, c
->ext2
); // ## Simulate iso14443a tag - pass tag type & UID
591 case CMD_MEASURE_ANTENNA_TUNING
:
592 MeasureAntennaTuning();
595 case CMD_LISTEN_READER_FIELD
:
596 ListenReaderField(c
->ext1
);
599 case CMD_HID_DEMOD_FSK
:
600 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
603 case CMD_HID_SIM_TAG
:
604 CmdHIDsimTAG(c
->ext1
, c
->ext2
, 1); // Simulate HID tag by ID
607 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
608 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
610 LED_D_OFF(); // LED D indicates field ON or OFF
613 case CMD_READ_TI_TYPE
:
617 case CMD_WRITE_TI_TYPE
:
618 WriteTItag(c
->ext1
,c
->ext2
,c
->ext3
);
621 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
623 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
624 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
626 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
629 memcpy(n
.d
.asDwords
, BigBuf
+c
->ext1
, 12*sizeof(DWORD
));
630 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
633 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
634 BYTE
*b
= (BYTE
*)BigBuf
;
635 memcpy(b
+c
->ext1
, c
->d
.asBytes
, 48);
638 case CMD_SIMULATE_TAG_125K
:
640 SimulateTagLowFrequency(c
->ext1
, 1);
646 case CMD_SET_LF_DIVISOR
:
647 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->ext1
);
649 case CMD_SET_ADC_MUX
:
651 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break;
652 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break;
653 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break;
654 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break;
660 case CMD_LF_SIMULATE_BIDIR
:
661 SimulateTagLowFrequencyBidir(c
->ext1
, c
->ext2
);
671 case CMD_SETUP_WRITE
:
672 case CMD_FINISH_WRITE
:
673 case CMD_HARDWARE_RESET
:
674 USB_D_PLUS_PULLUP_OFF();
677 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
679 // We're going to reset, and the bootrom will take control.
682 case CMD_START_FLASH
:
683 if(common_area
.flags
.bootrom_present
) {
684 common_area
.command
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
;
686 USB_D_PLUS_PULLUP_OFF();
687 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
691 case CMD_DEVICE_INFO
: {
693 c
.cmd
= CMD_DEVICE_INFO
;
694 c
.ext1
= DEVICE_INFO_FLAG_OSIMAGE_PRESENT
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
;
695 if(common_area
.flags
.bootrom_present
) c
.ext1
|= DEVICE_INFO_FLAG_BOOTROM_PRESENT
;
696 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
700 DbpString("unknown command");
705 void __attribute__((noreturn
)) AppMain(void)
709 if(common_area
.magic
!= COMMON_AREA_MAGIC
|| common_area
.version
!= 1) {
710 /* Initialize common area */
711 memset(&common_area
, 0, sizeof(common_area
));
712 common_area
.magic
= COMMON_AREA_MAGIC
;
713 common_area
.version
= 1;
715 common_area
.flags
.osimage_present
= 1;
724 // The FPGA gets its clock from us from PCK0 output, so set that up.
725 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_PCK0
;
726 AT91C_BASE_PIOA
->PIO_PDR
= GPIO_PCK0
;
727 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_PCK0
;
728 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
729 AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK
|
730 AT91C_PMC_PRES_CLK_4
;
731 AT91C_BASE_PIOA
->PIO_OER
= GPIO_PCK0
;
734 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
736 AT91C_BASE_SSC
->SSC_CR
= AT91C_SSC_SWRST
;
738 // Load the FPGA image, which we have stored in our flash.
745 // test text on different colored backgrounds
746 LCDString(" The quick brown fox ", (char *)&FONT6x8
,1,1+8*0,WHITE
,BLACK
);
747 LCDString(" jumped over the ", (char *)&FONT6x8
,1,1+8*1,BLACK
,WHITE
);
748 LCDString(" lazy dog. ", (char *)&FONT6x8
,1,1+8*2,YELLOW
,RED
);
749 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8
,1,1+8*3,RED
,GREEN
);
750 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
751 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
752 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8
,1,1+8*6,BLACK
,CYAN
);
753 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
756 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
757 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
758 LCDFill(0, 1+8*10, 132, 8, RED
);
759 LCDFill(0, 1+8*11, 132, 8, GREEN
);
760 LCDFill(0, 1+8*12, 132, 8, BLUE
);
761 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
762 LCDFill(0, 1+8*14, 132, 8, CYAN
);
763 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
771 if (BUTTON_HELD(1000) > 0)