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 //=============================================================================
26 struct common_area common_area
__attribute__((section(".commonarea")));
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
;
72 c
.arg
[0] = strlen(str
);
73 memcpy(c
.d
.asBytes
, str
, c
.arg
[0]);
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 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_SWRST
;
107 AT91C_BASE_ADC
->ADC_MR
=
108 ADC_MODE_PRESCALE(32) |
109 ADC_MODE_STARTUP_TIME(16) |
110 ADC_MODE_SAMPLE_HOLD_TIME(8);
111 AT91C_BASE_ADC
->ADC_CHER
= ADC_CHANNEL(ch
);
113 AT91C_BASE_ADC
->ADC_CR
= AT91C_ADC_START
;
114 while(!(AT91C_BASE_ADC
->ADC_SR
& ADC_END_OF_CONVERSION(ch
)))
116 d
= AT91C_BASE_ADC
->ADC_CDR
[ch
];
121 static int AvgAdc(int ch
)
126 for(i
= 0; i
< 32; i
++) {
130 return (a
+ 15) >> 5;
133 void MeasureAntennaTuning(void)
135 BYTE
*dest
= (BYTE
*)BigBuf
;
136 int i
, ptr
= 0, adcval
= 0, peak
= 0, peakv
= 0, peakf
= 0;;
137 int vLf125
= 0, vLf134
= 0, vHf
= 0; // in mV
141 DbpString("Measuring antenna characteristics, please wait.");
142 memset(BigBuf
,0,sizeof(BigBuf
));
145 * Sweeps the useful LF range of the proxmark from
146 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
147 * read the voltage in the antenna, the result left
148 * in the buffer is a graph which should clearly show
149 * the resonating frequency of your LF antenna
150 * ( hopefully around 95 if it is tuned to 125kHz!)
152 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
);
153 for (i
=255; i
>19; i
--) {
154 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
);
156 // Vref = 3.3V, and a 10000:240 voltage divider on the input
157 // can measure voltages up to 137500 mV
158 adcval
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10);
159 if (i
==95) vLf125
= adcval
; // voltage at 125Khz
160 if (i
==89) vLf134
= adcval
; // voltage at 134Khz
162 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes
171 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
172 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
174 // Vref = 3300mV, and an 10:1 voltage divider on the input
175 // can measure voltages up to 33000 mV
176 vHf
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10;
178 c
.cmd
= CMD_MEASURED_ANTENNA_TUNING
;
179 c
.arg
[0] = (vLf125
<< 0) | (vLf134
<< 16);
181 c
.arg
[2] = peakf
| (peakv
<< 16);
182 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
185 void SimulateTagHfListen(void)
187 BYTE
*dest
= (BYTE
*)BigBuf
;
188 int n
= sizeof(BigBuf
);
193 // We're using this mode just so that I can test it out; the simulated
194 // tag mode would work just as well and be simpler.
195 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_SNOOP
);
197 // We need to listen to the high-frequency, peak-detected path.
198 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
204 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
205 AT91C_BASE_SSC
->SSC_THR
= 0xff;
207 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
208 BYTE r
= (BYTE
)AT91C_BASE_SSC
->SSC_RHR
;
228 DbpString("simulate tag (now type bitsamples)");
231 void ReadMem(int addr
)
233 const DWORD
*data
= ((DWORD
*)addr
);
236 DbpString("Reading memory at address");
237 DbpIntegers(0, 0, addr
);
238 for (i
= 0; i
< 8; i
+= 2)
239 DbpIntegers(0, data
[i
], data
[i
+1]);
242 /* osimage version information is linked in */
243 extern struct version_information version_information
;
244 /* bootrom version information is pointed to from _bootphase1_version_pointer */
245 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
;
246 void SendVersion(void)
248 char temp
[48]; /* Limited data payload in USB packets */
249 DbpString("Prox/RFID mark3 RFID instrument");
251 /* Try to find the bootrom version information. Expect to find a pointer at
252 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
253 * pointer, then use it.
255 char *bootrom_version
= *(char**)&_bootphase1_version_pointer
;
256 if( bootrom_version
< &_flash_start
|| bootrom_version
>= &_flash_end
) {
257 DbpString("bootrom version information appears invalid");
259 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
);
263 FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
);
266 FpgaGatherVersion(temp
, sizeof(temp
));
271 // samy's sniff and repeat routine
274 DbpString("Stand-alone mode! No PC necessary.");
276 // 3 possible options? no just 2 for now
279 int high
[OPTS
], low
[OPTS
];
281 // Oooh pretty -- notify user we're in elite samy mode now
283 LED(LED_ORANGE
, 200);
285 LED(LED_ORANGE
, 200);
287 LED(LED_ORANGE
, 200);
289 LED(LED_ORANGE
, 200);
295 // Turn on selected LED
296 LED(selected
+ 1, 0);
303 // Was our button held down or pressed?
304 int button_pressed
= BUTTON_HELD(1000);
307 // Button was held for a second, begin recording
308 if (button_pressed
> 0)
311 LED(selected
+ 1, 0);
315 DbpString("Starting recording");
317 // wait for button to be released
318 while(BUTTON_PRESS())
321 /* need this delay to prevent catching some weird data */
324 CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0);
325 DbpString("Recorded");
326 DbpIntegers(selected
, high
[selected
], low
[selected
]);
329 LED(selected
+ 1, 0);
330 // Finished recording
332 // If we were previously playing, set playing off
333 // so next button push begins playing what we recorded
337 // Change where to record (or begin playing)
338 else if (button_pressed
)
340 // Next option if we were previously playing
342 selected
= (selected
+ 1) % OPTS
;
346 LED(selected
+ 1, 0);
348 // Begin transmitting
352 DbpString("Playing");
353 // wait for button to be released
354 while(BUTTON_PRESS())
356 DbpIntegers(selected
, high
[selected
], low
[selected
]);
357 CmdHIDsimTAG(high
[selected
], low
[selected
], 0);
358 DbpString("Done playing");
359 if (BUTTON_HELD(1000) > 0)
361 DbpString("Exiting");
366 /* We pressed a button so ignore it here with a delay */
369 // when done, we're done playing, move to next option
370 selected
= (selected
+ 1) % OPTS
;
373 LED(selected
+ 1, 0);
376 while(BUTTON_PRESS())
385 Listen and detect an external reader. Determine the best location
389 Inside the ListenReaderField() function, there is two mode.
390 By default, when you call the function, you will enter mode 1.
391 If you press the PM3 button one time, you will enter mode 2.
392 If you press the PM3 button a second time, you will exit the function.
394 DESCRIPTION OF MODE 1:
395 This mode just listens for an external reader field and lights up green
396 for HF and/or red for LF. This is the original mode of the detectreader
399 DESCRIPTION OF MODE 2:
400 This mode will visually represent, using the LEDs, the actual strength of the
401 current compared to the maximum current detected. Basically, once you know
402 what kind of external reader is present, it will help you spot the best location to place
403 your antenna. You will probably not get some good results if there is a LF and a HF reader
404 at the same place! :-)
408 static const char LIGHT_SCHEME
[] = {
409 0x0, /* ---- | No field detected */
410 0x1, /* X--- | 14% of maximum current detected */
411 0x2, /* -X-- | 29% of maximum current detected */
412 0x4, /* --X- | 43% of maximum current detected */
413 0x8, /* ---X | 57% of maximum current detected */
414 0xC, /* --XX | 71% of maximum current detected */
415 0xE, /* -XXX | 86% of maximum current detected */
416 0xF, /* XXXX | 100% of maximum current detected */
418 static const int LIGHT_LEN
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]);
420 void ListenReaderField(int limit
)
422 int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
;
423 int hf_av
, hf_av_new
, hf_baseline
= 0, hf_count
= 0, hf_max
;
424 int mode
=1, display_val
, display_max
, i
;
431 lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
);
433 if(limit
!= HF_ONLY
) {
434 DbpString("LF 125/134 Baseline:");
435 DbpIntegers(lf_av
,0,0);
439 hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
);
441 if (limit
!= LF_ONLY
) {
442 DbpString("HF 13.56 Baseline:");
443 DbpIntegers(hf_av
,0,0);
448 if (BUTTON_PRESS()) {
453 DbpString("Signal Strength Mode");
457 DbpString("Stopped");
465 if (limit
!= HF_ONLY
) {
467 if (abs(lf_av
- lf_baseline
) > 10) LED_D_ON();
472 lf_av_new
= ReadAdc(ADC_CHAN_LF
);
473 // see if there's a significant change
474 if(abs(lf_av
- lf_av_new
) > 10) {
475 DbpString("LF 125/134 Field Change:");
476 DbpIntegers(lf_av
,lf_av_new
,lf_count
);
484 if (limit
!= LF_ONLY
) {
486 if (abs(hf_av
- hf_baseline
) > 10) LED_B_ON();
491 hf_av_new
= ReadAdc(ADC_CHAN_HF
);
492 // see if there's a significant change
493 if(abs(hf_av
- hf_av_new
) > 10) {
494 DbpString("HF 13.56 Field Change:");
495 DbpIntegers(hf_av
,hf_av_new
,hf_count
);
504 if (limit
== LF_ONLY
) {
506 display_max
= lf_max
;
507 } else if (limit
== HF_ONLY
) {
509 display_max
= hf_max
;
510 } else { /* Pick one at random */
511 if( (hf_max
- hf_baseline
) > (lf_max
- lf_baseline
) ) {
513 display_max
= hf_max
;
516 display_max
= lf_max
;
519 for (i
=0; i
<LIGHT_LEN
; i
++) {
520 if (display_val
>= ((display_max
/LIGHT_LEN
)*i
) && display_val
<= ((display_max
/LIGHT_LEN
)*(i
+1))) {
521 if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF();
522 if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF();
523 if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF();
524 if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF();
532 void UsbPacketReceived(BYTE
*packet
, int len
)
534 UsbCommand
*c
= (UsbCommand
*)packet
;
538 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
:
539 AcquireRawAdcSamples125k(c
->arg
[0]);
544 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
:
545 ModThenAcquireRawAdcSamples125k(c
->arg
[0],c
->arg
[1],c
->arg
[2],c
->d
.asBytes
);
550 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
:
551 AcquireRawAdcSamplesIso15693();
560 case CMD_READER_ISO_15693
:
561 ReaderIso15693(c
->arg
[0]);
565 case CMD_READER_LEGIC_RF
:
570 case CMD_SIMTAG_ISO_15693
:
571 SimTagIso15693(c
->arg
[0]);
575 #ifdef WITH_ISO14443b
576 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
:
577 AcquireRawAdcSamplesIso14443(c
->arg
[0]);
581 #ifdef WITH_ISO14443b
582 case CMD_READ_SRI512_TAG
:
583 ReadSRI512Iso14443(c
->arg
[0]);
585 case CMD_READ_SRIX4K_TAG
:
586 ReadSRIX4KIso14443(c
->arg
[0]);
590 #ifdef WITH_ISO14443a
591 case CMD_READER_ISO_14443a
:
592 ReaderIso14443a(c
->arg
[0]);
596 #ifdef WITH_ISO14443b
597 case CMD_SNOOP_ISO_14443
:
602 #ifdef WITH_ISO14443a
603 case CMD_SNOOP_ISO_14443a
:
608 case CMD_SIMULATE_TAG_HF_LISTEN
:
609 SimulateTagHfListen();
612 #ifdef WITH_ISO14443b
613 case CMD_SIMULATE_TAG_ISO_14443
:
614 SimulateIso14443Tag();
618 #ifdef WITH_ISO14443a
619 case CMD_SIMULATE_TAG_ISO_14443a
:
620 SimulateIso14443aTag(c
->arg
[0], c
->arg
[1]); // ## Simulate iso14443a tag - pass tag type & UID
624 case CMD_MEASURE_ANTENNA_TUNING
:
625 MeasureAntennaTuning();
628 case CMD_LISTEN_READER_FIELD
:
629 ListenReaderField(c
->arg
[0]);
633 case CMD_HID_DEMOD_FSK
:
634 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
639 case CMD_HID_SIM_TAG
:
640 CmdHIDsimTAG(c
->arg
[0], c
->arg
[1], 1); // Simulate HID tag by ID
644 case CMD_FPGA_MAJOR_MODE_OFF
: // ## FPGA Control
645 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
647 LED_D_OFF(); // LED D indicates field ON or OFF
651 case CMD_READ_TI_TYPE
:
657 case CMD_WRITE_TI_TYPE
:
658 WriteTItag(c
->arg
[0],c
->arg
[1],c
->arg
[2]);
662 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: {
664 if(c
->cmd
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) {
665 n
.cmd
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
;
667 n
.cmd
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
;
669 n
.arg
[0] = c
->arg
[0];
670 memcpy(n
.d
.asDwords
, BigBuf
+c
->arg
[0], 12*sizeof(DWORD
));
671 UsbSendPacket((BYTE
*)&n
, sizeof(n
));
675 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: {
676 BYTE
*b
= (BYTE
*)BigBuf
;
677 memcpy(b
+c
->arg
[0], c
->d
.asBytes
, 48);
682 case CMD_SIMULATE_TAG_125K
:
684 SimulateTagLowFrequency(c
->arg
[0], 1);
693 case CMD_SET_LF_DIVISOR
:
694 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->arg
[0]);
697 case CMD_SET_ADC_MUX
:
699 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break;
700 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break;
701 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break;
702 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break;
711 case CMD_LF_SIMULATE_BIDIR
:
712 SimulateTagLowFrequencyBidir(c
->arg
[0], c
->arg
[1]);
724 case CMD_SETUP_WRITE
:
725 case CMD_FINISH_WRITE
:
726 case CMD_HARDWARE_RESET
:
727 USB_D_PLUS_PULLUP_OFF();
730 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
732 // We're going to reset, and the bootrom will take control.
736 case CMD_START_FLASH
:
737 if(common_area
.flags
.bootrom_present
) {
738 common_area
.command
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
;
740 USB_D_PLUS_PULLUP_OFF();
741 AT91C_BASE_RSTC
->RSTC_RCR
= RST_CONTROL_KEY
| AT91C_RSTC_PROCRST
;
745 case CMD_DEVICE_INFO
: {
747 c
.cmd
= CMD_DEVICE_INFO
;
748 c
.arg
[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
;
749 if(common_area
.flags
.bootrom_present
) c
.arg
[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT
;
750 UsbSendPacket((BYTE
*)&c
, sizeof(c
));
754 DbpString("unknown command");
759 void __attribute__((noreturn
)) AppMain(void)
763 if(common_area
.magic
!= COMMON_AREA_MAGIC
|| common_area
.version
!= 1) {
764 /* Initialize common area */
765 memset(&common_area
, 0, sizeof(common_area
));
766 common_area
.magic
= COMMON_AREA_MAGIC
;
767 common_area
.version
= 1;
769 common_area
.flags
.osimage_present
= 1;
778 // The FPGA gets its clock from us from PCK0 output, so set that up.
779 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_PCK0
;
780 AT91C_BASE_PIOA
->PIO_PDR
= GPIO_PCK0
;
781 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_PCK0
;
782 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
783 AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK
|
784 AT91C_PMC_PRES_CLK_4
;
785 AT91C_BASE_PIOA
->PIO_OER
= GPIO_PCK0
;
788 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
790 AT91C_BASE_SSC
->SSC_CR
= AT91C_SSC_SWRST
;
792 // Load the FPGA image, which we have stored in our flash.
799 // test text on different colored backgrounds
800 LCDString(" The quick brown fox ", (char *)&FONT6x8
,1,1+8*0,WHITE
,BLACK
);
801 LCDString(" jumped over the ", (char *)&FONT6x8
,1,1+8*1,BLACK
,WHITE
);
802 LCDString(" lazy dog. ", (char *)&FONT6x8
,1,1+8*2,YELLOW
,RED
);
803 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8
,1,1+8*3,RED
,GREEN
);
804 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE
);
805 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8
,1,1+8*5,BLUE
,YELLOW
);
806 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8
,1,1+8*6,BLACK
,CYAN
);
807 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8
,1,1+8*7,BLUE
,MAGENTA
);
810 LCDFill(0, 1+8* 8, 132, 8, BLACK
);
811 LCDFill(0, 1+8* 9, 132, 8, WHITE
);
812 LCDFill(0, 1+8*10, 132, 8, RED
);
813 LCDFill(0, 1+8*11, 132, 8, GREEN
);
814 LCDFill(0, 1+8*12, 132, 8, BLUE
);
815 LCDFill(0, 1+8*13, 132, 8, YELLOW
);
816 LCDFill(0, 1+8*14, 132, 8, CYAN
);
817 LCDFill(0, 1+8*15, 132, 8, MAGENTA
);
826 if (BUTTON_HELD(1000) > 0)