]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/appmain.c
usb communication (device side) refactoring
[proxmark3-svn] / armsrc / appmain.c
CommitLineData
15c4dc5a 1//-----------------------------------------------------------------------------
15c4dc5a 2// Jonathan Westhues, Mar 2006
3// Edits by Gerhard de Koning Gans, Sep 2007 (##)
bd20f8f4 4//
5// This code is licensed to you under the terms of the GNU GPL, version 2 or,
6// at your option, any later version. See the LICENSE.txt file for the text of
7// the license.
8//-----------------------------------------------------------------------------
9// The main application code. This is the first thing called after start.c
10// executes.
15c4dc5a 11//-----------------------------------------------------------------------------
12
b8e461ff 13#include <stdarg.h>
14
902cb3c0 15#include "usb_cdc.h"
e30c654b 16#include "proxmark3.h"
15c4dc5a 17#include "apps.h"
472345da 18#include "fpga.h"
f7e3ed82 19#include "util.h"
9ab7a6c7 20#include "printf.h"
21#include "string.h"
15c4dc5a 22#include "legicrf.h"
1b902aa0 23#include "legicrfsim.h"
b8e461ff 24#include "hitag2.h"
25#include "hitagS.h"
17505ce2 26#include "iclass.h"
5ea2a248 27#include "iso14443b.h"
d9de20fa 28#include "iso15693.h"
31abe49f 29#include "lfsampling.h"
3000dc4e 30#include "BigBuf.h"
0b4efbde 31#include "mifarecmd.h"
c89274cc 32#include "mifareutil.h"
a8561e35 33#include "mifaresim.h"
d10e08ae 34#include "pcf7931.h"
050aa18b 35#include "i2c.h"
fc52fbd4 36#include "hfsnoop.h"
37#include "fpgaloader.h"
15c4dc5a 38#ifdef WITH_LCD
1d04b933 39 #include "LCD.h"
15c4dc5a 40#endif
43591e64 41
a9104f7e 42static uint32_t hw_capabilities;
15c4dc5a 43
e46fe044 44// Craig Young - 14a stand-alone code
854fdf15 45#ifdef WITH_ISO14443a
1d04b933 46 #include "iso14443a.h"
e46fe044
CY
47#endif
48
15c4dc5a 49//=============================================================================
50// A buffer where we can queue things up to be sent through the FPGA, for
51// any purpose (fake tag, as reader, whatever). We go MSB first, since that
52// is the order in which they go out on the wire.
53//=============================================================================
54
1d04b933 55#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
6a1f2d82 56uint8_t ToSend[TOSEND_BUFFER_SIZE];
15c4dc5a 57int ToSendMax;
58static int ToSendBit;
59struct common_area common_area __attribute__((section(".commonarea")));
60
1d04b933 61void ToSendReset(void) {
15c4dc5a 62 ToSendMax = -1;
63 ToSendBit = 8;
64}
65
1d04b933 66void ToSendStuffBit(int b) {
67 if (ToSendBit >= 8) {
15c4dc5a 68 ToSendMax++;
69 ToSend[ToSendMax] = 0;
70 ToSendBit = 0;
71 }
72
1d04b933 73 if (b) {
15c4dc5a 74 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
75 }
76
77 ToSendBit++;
78
1d04b933 79 if (ToSendMax >= sizeof(ToSend)) {
15c4dc5a 80 ToSendBit = 0;
81 DbpString("ToSendStuffBit overflowed!");
82 }
83}
84
85//=============================================================================
86// Debug print functions, to go out over USB, to the usual PC-side client.
87//=============================================================================
88
1d04b933 89void DbpString(char *str) {
90 uint8_t len = strlen(str);
91 cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(uint8_t*)str,len);
15c4dc5a 92}
93
15c4dc5a 94void Dbprintf(const char *fmt, ...) {
95// should probably limit size here; oh well, let's just use a big buffer
96 char output_string[128];
97 va_list ap;
98
99 va_start(ap, fmt);
100 kvsprintf(fmt, output_string, 10, ap);
101 va_end(ap);
e30c654b 102
15c4dc5a 103 DbpString(output_string);
104}
105
9455b51c 106// prints HEX & ASCII
d19929cb 107void Dbhexdump(int len, uint8_t *d, bool bAsci) {
9455b51c 108 int l=0,i;
109 char ascii[9];
1d04b933 110
9455b51c 111 while (len>0) {
112 if (len>8) l=8;
113 else l=len;
1d04b933 114
9455b51c 115 memcpy(ascii,d,l);
d19929cb 116 ascii[l]=0;
1d04b933 117
9455b51c 118 // filter safe ascii
1d04b933 119 for (i = 0; i < l; i++)
120 if (ascii[i]<32 || ascii[i]>126) ascii[i] = '.';
121
d19929cb 122 if (bAsci) {
1d04b933 123 Dbprintf("%-8s %*D",ascii, l, d, " ");
d19929cb 124 } else {
1d04b933 125 Dbprintf("%*D", l, d, " ");
d19929cb 126 }
1d04b933 127
128 len -= 8;
129 d += 8;
9455b51c 130 }
131}
132
15c4dc5a 133//-----------------------------------------------------------------------------
134// Read an ADC channel and block till it completes, then return the result
135// in ADC units (0 to 1023). Also a routine to average 32 samples and
136// return that.
137//-----------------------------------------------------------------------------
1d04b933 138static int ReadAdc(int ch) {
139 // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
050aa18b 140 // AMPL_HI is a high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
1d04b933 141 // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged.
142 //
3b692427 143 // The maths are:
144 // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be
145 //
9b32625c 146 // v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%)
15c4dc5a 147
2d51da38
I
148 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
149 AT91C_BASE_ADC->ADC_MR =
1d04b933 150 ADC_MODE_PRESCALE(63) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
151 ADC_MODE_STARTUP_TIME(1) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
152 ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
3b692427 153
2d51da38
I
154 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
155 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
15c4dc5a 156
2d51da38 157 while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {};
1d04b933 158
050aa18b 159 return AT91C_BASE_ADC->ADC_CDR[ch] & 0x3ff;
15c4dc5a 160}
161
1d04b933 162int AvgAdc(int ch) { // was static - merlok{
15c4dc5a 163 int i;
164 int a = 0;
165
166 for(i = 0; i < 32; i++) {
167 a += ReadAdc(ch);
168 }
169
170 return (a + 15) >> 5;
171}
172
1d04b933 173static int AvgAdc_Voltage_HF(void) {
050aa18b 174 int AvgAdc_Voltage_Low, AvgAdc_Voltage_High;
1d04b933 175
050aa18b 176 AvgAdc_Voltage_Low= (MAX_ADC_HF_VOLTAGE_LOW * AvgAdc(ADC_CHAN_HF_LOW)) >> 10;
177 // if voltage range is about to be exceeded, use high voltage ADC channel if available (RDV40 only)
178 if (AvgAdc_Voltage_Low > MAX_ADC_HF_VOLTAGE_LOW - 300) {
179 AvgAdc_Voltage_High = (MAX_ADC_HF_VOLTAGE_HIGH * AvgAdc(ADC_CHAN_HF_HIGH)) >> 10;
180 if (AvgAdc_Voltage_High >= AvgAdc_Voltage_Low) {
181 return AvgAdc_Voltage_High;
182 }
183 }
184 return AvgAdc_Voltage_Low;
185}
186
1d04b933 187static int AvgAdc_Voltage_LF(void) {
050aa18b 188 return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10;
189}
190
1d04b933 191void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv, uint8_t LF_Results[]) {
9b32625c 192 int i, adcval = 0, peak = 0;
15c4dc5a 193
194/*
195 * Sweeps the useful LF range of the proxmark from
196 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
197 * read the voltage in the antenna, the result left
198 * in the buffer is a graph which should clearly show
199 * the resonating frequency of your LF antenna
200 * ( hopefully around 95 if it is tuned to 125kHz!)
201 */
fdcfbdcc
RAB
202
203 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
b014c96d 204 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
2d51da38 205 SpinDelay(50);
1d04b933 206
207 for (i = 255; i >= 19; i--) {
fdcfbdcc 208 WDT_HIT();
15c4dc5a 209 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
210 SpinDelay(20);
050aa18b 211 adcval = AvgAdc_Voltage_LF();
1d04b933 212 if (i == 95) *vLf125 = adcval; // voltage at 125Khz
213 if (i == 89) *vLf134 = adcval; // voltage at 134Khz
15c4dc5a 214
2d51da38 215 LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes
1d04b933 216 if (LF_Results[i] > peak) {
fdcfbdcc 217 *peakv = adcval;
2bdd68c3 218 peak = LF_Results[i];
fdcfbdcc 219 *peakf = i;
9f693930 220 //ptr = i;
15c4dc5a 221 }
222 }
223
1d04b933 224 for (i = 18; i >= 0; i--) LF_Results[i] = 0;
fdcfbdcc
RAB
225
226 return;
227}
228
1d04b933 229void MeasureAntennaTuningHfOnly(int *vHf) {
15c4dc5a 230 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
fdcfbdcc
RAB
231 LED_A_ON();
232 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
5ea2a248 233 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
15c4dc5a 234 SpinDelay(20);
050aa18b 235 *vHf = AvgAdc_Voltage_HF();
fdcfbdcc 236 LED_A_OFF();
fdcfbdcc
RAB
237 return;
238}
239
1d04b933 240void MeasureAntennaTuning(int mode) {
fdcfbdcc
RAB
241 uint8_t LF_Results[256] = {0};
242 int peakv = 0, peakf = 0;
243 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
244
245 LED_B_ON();
246
247 if (((mode & FLAG_TUNE_ALL) == FLAG_TUNE_ALL) && (FpgaGetCurrent() == FPGA_BITSTREAM_HF)) {
248 // Reverse "standard" order if HF already loaded, to avoid unnecessary swap.
249 MeasureAntennaTuningHfOnly(&vHf);
250 MeasureAntennaTuningLfOnly(&vLf125, &vLf134, &peakf, &peakv, LF_Results);
251 } else {
252 if (mode & FLAG_TUNE_LF) {
253 MeasureAntennaTuningLfOnly(&vLf125, &vLf134, &peakf, &peakv, LF_Results);
254 }
255 if (mode & FLAG_TUNE_HF) {
256 MeasureAntennaTuningHfOnly(&vHf);
257 }
258 }
15c4dc5a 259
d040cb90 260 cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125>>1 | (vLf134>>1<<16), vHf, peakf | (peakv>>1<<16), LF_Results, 256);
d19929cb 261 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2bdd68c3 262 LED_B_OFF();
263 return;
15c4dc5a 264}
265
1d04b933 266void MeasureAntennaTuningHf(void) {
267 int vHf = 0; // in mV
15c4dc5a 268
269 DbpString("Measuring HF antenna, press button to exit");
270
3b692427 271 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
272 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
5ea2a248 273 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
3b692427 274
15c4dc5a 275 for (;;) {
050aa18b 276 SpinDelay(500);
277 vHf = AvgAdc_Voltage_HF();
e30c654b 278
15c4dc5a 279 Dbprintf("%d mV",vHf);
280 if (BUTTON_PRESS()) break;
281 }
282 DbpString("cancelled");
3b692427 283
284 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
285
15c4dc5a 286}
287
288
1d04b933 289void ReadMem(int addr) {
f7e3ed82 290 const uint8_t *data = ((uint8_t *)addr);
15c4dc5a 291
292 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
293 addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
294}
295
296/* osimage version information is linked in */
297extern struct version_information version_information;
298/* bootrom version information is pointed to from _bootphase1_version_pointer */
0fa01ec7 299extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
472345da 300
050aa18b 301
1d04b933 302void set_hw_capabilities(void) {
a9104f7e 303 if (I2C_is_available()) {
304 hw_capabilities |= HAS_SMARTCARD_SLOT;
305 }
1d04b933 306
a9104f7e 307 if (false) { // TODO: implement a test
308 hw_capabilities |= HAS_EXTRA_FLASH_MEM;
309 }
1d04b933 310}
a9104f7e 311
312
1d04b933 313void SendVersion(void) {
a9104f7e 314 set_hw_capabilities();
1d04b933 315
8e074056 316 char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
317 char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
e30c654b 318
319 /* Try to find the bootrom version information. Expect to find a pointer at
15c4dc5a 320 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
321 * pointer, then use it.
322 */
323 char *bootrom_version = *(char**)&_bootphase1_version_pointer;
1d04b933 324 if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) {
8e074056 325 strcat(VersionString, "bootrom version information appears invalid\n");
15c4dc5a 326 } else {
327 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
8e074056 328 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
15c4dc5a 329 }
e30c654b 330
15c4dc5a 331 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
8e074056 332 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
e30c654b 333
472345da 334 for (int i = 0; i < fpga_bitstream_num; i++) {
335 strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
050aa18b 336 strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
472345da 337 }
1d04b933 338
050aa18b 339 // test availability of SmartCard slot
340 if (I2C_is_available()) {
341 strncat(VersionString, "SmartCard Slot: available\n", sizeof(VersionString) - strlen(VersionString) - 1);
342 } else {
343 strncat(VersionString, "SmartCard Slot: not available\n", sizeof(VersionString) - strlen(VersionString) - 1);
344 }
1d04b933 345
e6153040 346 // Send Chip ID and used flash memory
0fa01ec7 347 uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
348 uint32_t compressed_data_section_size = common_area.arg1;
a9104f7e 349 cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, hw_capabilities, VersionString, strlen(VersionString));
15c4dc5a 350}
351
bfb01844 352// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
353// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included.
1d04b933 354void printUSBSpeed(void) {
bfb01844 355 Dbprintf("USB Speed:");
67b7d6fa 356 Dbprintf(" Sending USB packets to client...");
bfb01844 357
1d04b933 358 #define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds
bfb01844 359 uint8_t *test_data = BigBuf_get_addr();
67b7d6fa 360 uint32_t end_time;
bfb01844 361
67b7d6fa 362 uint32_t start_time = end_time = GetTickCount();
363 uint32_t bytes_transferred = 0;
1d04b933 364
bfb01844 365 LED_B_ON();
67b7d6fa 366 while(end_time < start_time + USB_SPEED_TEST_MIN_TIME) {
367 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE);
368 end_time = GetTickCount();
369 bytes_transferred += USB_CMD_DATA_SIZE;
bfb01844 370 }
371 LED_B_OFF();
372
67b7d6fa 373 Dbprintf(" Time elapsed: %dms", end_time - start_time);
374 Dbprintf(" Bytes transferred: %d", bytes_transferred);
1d04b933 375 Dbprintf(" USB Transfer Speed PM3 -> Client = %d Bytes/s",
67b7d6fa 376 1000 * bytes_transferred / (end_time - start_time));
bfb01844 377
378}
1d04b933 379
c89274cc
CY
380/**
381 * Prints runtime information about the PM3.
382**/
1d04b933 383void SendStatus(void) {
c89274cc
CY
384 BigBuf_print_status();
385 Fpga_print_status();
43591e64 386#ifdef WITH_SMARTCARD
387 I2C_print_status();
388#endif
c89274cc 389 printConfig(); //LF Sampling config
67b7d6fa 390 printUSBSpeed();
c89274cc 391 Dbprintf("Various");
43591e64 392 Dbprintf(" MF_DBGLEVEL........%d", MF_DBGLEVEL);
393 Dbprintf(" ToSendMax..........%d", ToSendMax);
394 Dbprintf(" ToSendBit..........%d", ToSendBit);
bfb01844 395
396 cmd_send(CMD_ACK,1,0,0,0,0);
c89274cc 397}
15c4dc5a 398
a2937cea 399#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF_StandAlone)
15c4dc5a 400
15c4dc5a 401#define OPTS 2
402
1d04b933 403void StandAloneMode() {
86a83668 404 DbpString("Stand-alone mode! No PC necessary.");
15c4dc5a 405 // Oooh pretty -- notify user we're in elite samy mode now
1d04b933 406 LED(LED_RED, 200);
15c4dc5a 407 LED(LED_ORANGE, 200);
1d04b933 408 LED(LED_GREEN, 200);
15c4dc5a 409 LED(LED_ORANGE, 200);
1d04b933 410 LED(LED_RED, 200);
15c4dc5a 411 LED(LED_ORANGE, 200);
1d04b933 412 LED(LED_GREEN, 200);
15c4dc5a 413 LED(LED_ORANGE, 200);
1d04b933 414 LED(LED_RED, 200);
86a83668
MHS
415}
416
417#endif
418
419
420
421#ifdef WITH_ISO14443a_StandAlone
1d04b933 422void StandAloneMode14a() {
86a83668
MHS
423 StandAloneMode();
424 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
425
15c4dc5a 426 int selected = 0;
44964fd1 427 bool playing = false, GotoRecord = false, GotoClone = false;
428 bool cardRead[OPTS] = {false};
86a83668
MHS
429 uint8_t readUID[10] = {0};
430 uint32_t uid_1st[OPTS]={0};
431 uint32_t uid_2nd[OPTS]={0};
c89274cc
CY
432 uint32_t uid_tmp1 = 0;
433 uint32_t uid_tmp2 = 0;
434 iso14a_card_select_t hi14a_card[OPTS];
15c4dc5a 435
15c4dc5a 436 LED(selected + 1, 0);
437
1d04b933 438 for (;;) {
6e82300d 439 usb_poll();
86a83668 440 WDT_HIT();
15c4dc5a 441 SpinDelay(300);
442
1d04b933 443 if (GotoRecord || !cardRead[selected]) {
44964fd1 444 GotoRecord = false;
15c4dc5a 445 LEDsoff();
446 LED(selected + 1, 0);
447 LED(LED_RED2, 0);
448
449 // record
86a83668 450 Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
15c4dc5a 451 /* need this delay to prevent catching some weird data */
452 SpinDelay(500);
86a83668
MHS
453 /* Code for reading from 14a tag */
454 uint8_t uid[10] ={0};
455 uint32_t cuid;
456 iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
15c4dc5a 457
1d04b933 458 for ( ; ; ) {
86a83668 459 WDT_HIT();
c89274cc
CY
460 if (BUTTON_PRESS()) {
461 if (cardRead[selected]) {
462 Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
463 break;
1d04b933 464 } else if (cardRead[(selected+1)%OPTS]) {
c89274cc
CY
465 Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
466 selected = (selected+1)%OPTS;
44964fd1 467 break;
1d04b933 468 } else {
c89274cc
CY
469 Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
470 SpinDelay(300);
471 }
472 }
c04a4b60 473 if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0, true))
86a83668 474 continue;
1d04b933 475 else {
86a83668
MHS
476 Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
477 memcpy(readUID,uid,10*sizeof(uint8_t));
c89274cc 478 uint8_t *dst = (uint8_t *)&uid_tmp1;
86a83668 479 // Set UID byte order
1d04b933 480 for (int i = 0; i < 4; i++)
86a83668 481 dst[i] = uid[3-i];
c89274cc 482 dst = (uint8_t *)&uid_tmp2;
1d04b933 483 for (int i = 0; i < 4; i++)
86a83668 484 dst[i] = uid[7-i];
1d04b933 485 if (uid_1st[(selected+1) % OPTS] == uid_tmp1 && uid_2nd[(selected+1) % OPTS] == uid_tmp2) {
c89274cc 486 Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
1d04b933 487 } else {
c89274cc 488 if (uid_tmp2) {
1d04b933 489 Dbprintf("Bank[%d] received a 7-byte UID", selected);
c89274cc
CY
490 uid_1st[selected] = (uid_tmp1)>>8;
491 uid_2nd[selected] = (uid_tmp1<<24) + (uid_tmp2>>8);
1d04b933 492 } else {
493 Dbprintf("Bank[%d] received a 4-byte UID", selected);
c89274cc
CY
494 uid_1st[selected] = uid_tmp1;
495 uid_2nd[selected] = uid_tmp2;
496 }
497 break;
498 }
86a83668
MHS
499 }
500 }
1d04b933 501 Dbprintf("ATQA = %02X%02X", hi14a_card[selected].atqa[0], hi14a_card[selected].atqa[1]);
502 Dbprintf("SAK = %02X", hi14a_card[selected].sak);
86a83668
MHS
503 LEDsoff();
504 LED(LED_GREEN, 200);
505 LED(LED_ORANGE, 200);
506 LED(LED_GREEN, 200);
507 LED(LED_ORANGE, 200);
15c4dc5a 508
509 LEDsoff();
510 LED(selected + 1, 0);
15c4dc5a 511
c89274cc 512 // Next state is replay:
44964fd1 513 playing = true;
3fe4ff4f 514
44964fd1 515 cardRead[selected] = true;
1d04b933 516 } else if (GotoClone) { /* MF Classic UID clone */
44964fd1 517 GotoClone=false;
c89274cc
CY
518 LEDsoff();
519 LED(selected + 1, 0);
520 LED(LED_ORANGE, 250);
3fe4ff4f 521
3fe4ff4f 522
c89274cc
CY
523 // record
524 Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
3fe4ff4f 525
c89274cc 526 // wait for button to be released
1d04b933 527 while(BUTTON_PRESS()) {
c89274cc
CY
528 // Delay cloning until card is in place
529 WDT_HIT();
530 }
531 Dbprintf("Starting clone. [Bank: %u]", selected);
532 // need this delay to prevent catching some weird data
533 SpinDelay(500);
534 // Begin clone function here:
535 /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
536 UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
537 memcpy(c.d.asBytes, data, 16);
538 SendCommand(&c);
539
540 Block read is similar:
541 UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
542 We need to imitate that call with blockNo 0 to set a uid.
543
544 The get and set commands are handled in this file:
545 // Work with "magic Chinese" card
546 case CMD_MIFARE_CSETBLOCK:
547 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
548 break;
549 case CMD_MIFARE_CGETBLOCK:
550 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
551 break;
552
553 mfCSetUID provides example logic for UID set workflow:
554 -Read block0 from card in field with MifareCGetBlock()
555 -Configure new values without replacing reserved bytes
556 memcpy(block0, uid, 4); // Copy UID bytes from byte array
557 // Mifare UID BCC
558 block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
559 Bytes 5-7 are reserved SAK and ATQA for mifare classic
560 -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
561 */
562 uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
563 // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
564 MifareCGetBlock(0x3F, 1, 0, oldBlock0);
565 if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
566 Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
44964fd1 567 playing = true;
1d04b933 568 } else {
569 Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0], oldBlock0[1], oldBlock0[2], oldBlock0[3]);
570 memcpy(newBlock0, oldBlock0, 16);
c89274cc
CY
571 // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
572
1d04b933 573 newBlock0[0] = uid_1st[selected] >> 24;
574 newBlock0[1] = 0xFF & (uid_1st[selected] >> 16);
575 newBlock0[2] = 0xFF & (uid_1st[selected] >> 8);
c89274cc 576 newBlock0[3] = 0xFF & (uid_1st[selected]);
1d04b933 577 newBlock0[4] = newBlock0[0] ^ newBlock0[1] ^ newBlock0[2] ^ newBlock0[3];
c89274cc 578 // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
1d04b933 579 MifareCSetBlock(0, 0xFF, 0, newBlock0);
c89274cc 580 MifareCGetBlock(0x3F, 1, 0, testBlock0);
1d04b933 581 if (memcmp(testBlock0, newBlock0, 16) == 0) {
c89274cc 582 DbpString("Cloned successfull!");
44964fd1 583 cardRead[selected] = false; // Only if the card was cloned successfully should we clear it
584 playing = false;
585 GotoRecord = true;
c89274cc 586 selected = (selected+1) % OPTS;
1d04b933 587 } else {
c89274cc 588 Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
44964fd1 589 playing = true;
c89274cc
CY
590 }
591 }
592 LEDsoff();
593 LED(selected + 1, 0);
15c4dc5a 594
1d04b933 595 } else if (playing) {
596 // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
597 // Change where to record (or begin playing)
15c4dc5a 598 LEDsoff();
599 LED(selected + 1, 0);
600
601 // Begin transmitting
44964fd1 602 LED(LED_GREEN, 0);
603 DbpString("Playing");
604 for ( ; ; ) {
605 WDT_HIT();
606 int button_action = BUTTON_HELD(1000);
607 if (button_action == 0) { // No button action, proceed with sim
608 uint8_t data[512] = {0}; // in case there is a read command received we shouldn't break
1d04b933 609 Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected], uid_2nd[selected], selected);
44964fd1 610 if (hi14a_card[selected].sak == 8 && hi14a_card[selected].atqa[0] == 4 && hi14a_card[selected].atqa[1] == 0) {
611 DbpString("Mifare Classic");
1d04b933 612 SimulateIso14443aTag(1, uid_1st[selected], uid_2nd[selected], data); // Mifare Classic
613 } else if (hi14a_card[selected].sak == 0 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 0) {
44964fd1 614 DbpString("Mifare Ultralight");
1d04b933 615 SimulateIso14443aTag(2, uid_1st[selected], uid_2nd[selected], data); // Mifare Ultralight
616 } else if (hi14a_card[selected].sak == 20 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 3) {
44964fd1 617 DbpString("Mifare DESFire");
1d04b933 618 SimulateIso14443aTag(3, uid_1st[selected], uid_2nd[selected], data); // Mifare DESFire
619 } else {
44964fd1 620 Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
1d04b933 621 SimulateIso14443aTag(1, uid_1st[selected], uid_2nd[selected], data);
c89274cc 622 }
1d04b933 623 } else if (button_action == BUTTON_SINGLE_CLICK) {
44964fd1 624 selected = (selected + 1) % OPTS;
625 Dbprintf("Done playing. Switching to record mode on bank %d",selected);
626 GotoRecord = true;
627 break;
1d04b933 628 } else if (button_action == BUTTON_HOLD) {
44964fd1 629 Dbprintf("Playtime over. Begin cloning...");
630 GotoClone = true;
631 break;
632 }
633 WDT_HIT();
15c4dc5a 634 }
44964fd1 635
636 /* We pressed a button so ignore it here with a delay */
637 SpinDelay(300);
638 LEDsoff();
639 LED(selected + 1, 0);
15c4dc5a 640 }
641 }
642}
1d04b933 643
a2937cea 644#elif WITH_LF_StandAlone
1d04b933 645
86a83668 646// samy's sniff and repeat routine
1d04b933 647void SamyRun() {
86a83668
MHS
648 StandAloneMode();
649 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
e46fe044 650
53e2f2fa 651 int tops[OPTS], high[OPTS], low[OPTS];
15c4dc5a 652 int selected = 0;
653 int playing = 0;
3fe4ff4f 654 int cardRead = 0;
15c4dc5a 655
656 // Turn on selected LED
657 LED(selected + 1, 0);
658
1d04b933 659 for (;;) {
6e82300d 660 usb_poll();
86a83668 661 WDT_HIT();
15c4dc5a 662
663 // Was our button held down or pressed?
664 int button_pressed = BUTTON_HELD(1000);
665 SpinDelay(300);
666
667 // Button was held for a second, begin recording
1d04b933 668 if (button_pressed > 0 && cardRead == 0) {
15c4dc5a 669 LEDsoff();
670 LED(selected + 1, 0);
671 LED(LED_RED2, 0);
672
673 // record
674 DbpString("Starting recording");
675
676 // wait for button to be released
677 while(BUTTON_PRESS())
678 WDT_HIT();
679
680 /* need this delay to prevent catching some weird data */
681 SpinDelay(500);
682
53e2f2fa 683 CmdHIDdemodFSK(1, &tops[selected], &high[selected], &low[selected], 0);
684 if (tops[selected] > 0)
685 Dbprintf("Recorded %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
686 else
687 Dbprintf("Recorded %x %x%08x", selected, high[selected], low[selected]);
15c4dc5a 688
689 LEDsoff();
690 LED(selected + 1, 0);
691 // Finished recording
692
693 // If we were previously playing, set playing off
694 // so next button push begins playing what we recorded
695 playing = 0;
1d04b933 696
3fe4ff4f 697 cardRead = 1;
3fe4ff4f 698
1d04b933 699 } else if (button_pressed > 0 && cardRead == 1) {
700 LEDsoff();
701 LED(selected + 1, 0);
702 LED(LED_ORANGE, 0);
703
704 // record
705 if (tops[selected] > 0)
706 Dbprintf("Cloning %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
707 else
708 Dbprintf("Cloning %x %x%08x", selected, high[selected], low[selected]);
3fe4ff4f 709
1d04b933 710 // wait for button to be released
711 while(BUTTON_PRESS())
712 WDT_HIT();
3fe4ff4f 713
1d04b933 714 /* need this delay to prevent catching some weird data */
715 SpinDelay(500);
3fe4ff4f 716
1d04b933 717 CopyHIDtoT55x7(tops[selected] & 0x000FFFFF, high[selected], low[selected], (tops[selected] != 0 && ((high[selected]& 0xFFFFFFC0) != 0)), 0x1D);
718 if (tops[selected] > 0)
719 Dbprintf("Cloned %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
720 else
721 Dbprintf("Cloned %x %x%08x", selected, high[selected], low[selected]);
3fe4ff4f 722
1d04b933 723 LEDsoff();
724 LED(selected + 1, 0);
725 // Finished recording
3fe4ff4f 726
1d04b933 727 // If we were previously playing, set playing off
728 // so next button push begins playing what we recorded
729 playing = 0;
730
731 cardRead = 0;
732
733 } else if (button_pressed) {
15c4dc5a 734
1d04b933 735 // Change where to record (or begin playing)
15c4dc5a 736 // Next option if we were previously playing
737 if (playing)
738 selected = (selected + 1) % OPTS;
739 playing = !playing;
740
741 LEDsoff();
742 LED(selected + 1, 0);
743
744 // Begin transmitting
1d04b933 745 if (playing) {
15c4dc5a 746 LED(LED_GREEN, 0);
747 DbpString("Playing");
748 // wait for button to be released
749 while(BUTTON_PRESS())
750 WDT_HIT();
53e2f2fa 751 if (tops[selected] > 0)
752 Dbprintf("%x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
753 else
754 Dbprintf("%x %x%08x", selected, high[selected], low[selected]);
1d04b933 755
53e2f2fa 756 CmdHIDsimTAG(tops[selected], high[selected], low[selected], 0);
15c4dc5a 757 DbpString("Done playing");
1d04b933 758 if (BUTTON_HELD(1000) > 0) {
15c4dc5a 759 DbpString("Exiting");
760 LEDsoff();
761 return;
1d04b933 762 }
15c4dc5a 763
764 /* We pressed a button so ignore it here with a delay */
765 SpinDelay(300);
766
767 // when done, we're done playing, move to next option
768 selected = (selected + 1) % OPTS;
769 playing = !playing;
770 LEDsoff();
771 LED(selected + 1, 0);
1d04b933 772 } else
15c4dc5a 773 while(BUTTON_PRESS())
774 WDT_HIT();
775 }
776 }
777}
15c4dc5a 778
e46fe044 779#endif
1d04b933 780
15c4dc5a 781/*
782OBJECTIVE
783Listen and detect an external reader. Determine the best location
784for the antenna.
785
786INSTRUCTIONS:
787Inside the ListenReaderField() function, there is two mode.
788By default, when you call the function, you will enter mode 1.
789If you press the PM3 button one time, you will enter mode 2.
790If you press the PM3 button a second time, you will exit the function.
791
792DESCRIPTION OF MODE 1:
793This mode just listens for an external reader field and lights up green
794for HF and/or red for LF. This is the original mode of the detectreader
795function.
796
797DESCRIPTION OF MODE 2:
798This mode will visually represent, using the LEDs, the actual strength of the
799current compared to the maximum current detected. Basically, once you know
800what kind of external reader is present, it will help you spot the best location to place
801your antenna. You will probably not get some good results if there is a LF and a HF reader
802at the same place! :-)
803
804LIGHT SCHEME USED:
805*/
806static const char LIGHT_SCHEME[] = {
807 0x0, /* ---- | No field detected */
808 0x1, /* X--- | 14% of maximum current detected */
809 0x2, /* -X-- | 29% of maximum current detected */
810 0x4, /* --X- | 43% of maximum current detected */
811 0x8, /* ---X | 57% of maximum current detected */
812 0xC, /* --XX | 71% of maximum current detected */
813 0xE, /* -XXX | 86% of maximum current detected */
814 0xF, /* XXXX | 100% of maximum current detected */
815};
1d04b933 816
15c4dc5a 817static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
818
1d04b933 819void ListenReaderField(int limit) {
050aa18b 820 int lf_av, lf_av_new=0, lf_baseline= 0, lf_max;
821 int hf_av, hf_av_new=0, hf_baseline= 0, hf_max;
15c4dc5a 822 int mode=1, display_val, display_max, i;
823
050aa18b 824#define LF_ONLY 1
825#define HF_ONLY 2
826#define REPORT_CHANGE_PERCENT 5 // report new values only if they have changed at least by REPORT_CHANGE_PERCENT
827#define MIN_HF_FIELD 300 // in mode 1 signal HF field greater than MIN_HF_FIELD above baseline
828#define MIN_LF_FIELD 1200 // in mode 1 signal LF field greater than MIN_LF_FIELD above baseline
3b692427 829
830
831 // switch off FPGA - we don't want to measure our own signal
832 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
833 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
15c4dc5a 834
835 LEDsoff();
836
050aa18b 837 lf_av = lf_max = AvgAdc_Voltage_LF();
15c4dc5a 838
1d04b933 839 if (limit != HF_ONLY) {
050aa18b 840 Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av);
15c4dc5a 841 lf_baseline = lf_av;
842 }
843
050aa18b 844 hf_av = hf_max = AvgAdc_Voltage_HF();
1d04b933 845
15c4dc5a 846 if (limit != LF_ONLY) {
050aa18b 847 Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av);
15c4dc5a 848 hf_baseline = hf_av;
849 }
850
851 for(;;) {
050aa18b 852 SpinDelay(500);
15c4dc5a 853 if (BUTTON_PRESS()) {
15c4dc5a 854 switch (mode) {
855 case 1:
856 mode=2;
857 DbpString("Signal Strength Mode");
858 break;
859 case 2:
860 default:
861 DbpString("Stopped");
862 LEDsoff();
863 return;
864 break;
865 }
1d04b933 866 while (BUTTON_PRESS())
867 /* wait */;
15c4dc5a 868 }
869 WDT_HIT();
870
871 if (limit != HF_ONLY) {
3b692427 872 if(mode == 1) {
050aa18b 873 if (lf_av - lf_baseline > MIN_LF_FIELD)
3b692427 874 LED_D_ON();
875 else
876 LED_D_OFF();
15c4dc5a 877 }
e30c654b 878
050aa18b 879 lf_av_new = AvgAdc_Voltage_LF();
15c4dc5a 880 // see if there's a significant change
1d04b933 881 if (ABS((lf_av - lf_av_new) * 100 / (lf_av?lf_av:1)) > REPORT_CHANGE_PERCENT) {
050aa18b 882 Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new);
15c4dc5a 883 lf_av = lf_av_new;
884 if (lf_av > lf_max)
885 lf_max = lf_av;
15c4dc5a 886 }
887 }
888
889 if (limit != LF_ONLY) {
890 if (mode == 1){
050aa18b 891 if (hf_av - hf_baseline > MIN_HF_FIELD)
3b692427 892 LED_B_ON();
893 else
894 LED_B_OFF();
15c4dc5a 895 }
e30c654b 896
050aa18b 897 hf_av_new = AvgAdc_Voltage_HF();
1d04b933 898
15c4dc5a 899 // see if there's a significant change
1d04b933 900 if (ABS((hf_av - hf_av_new) * 100 / (hf_av?hf_av:1)) > REPORT_CHANGE_PERCENT) {
050aa18b 901 Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new);
15c4dc5a 902 hf_av = hf_av_new;
903 if (hf_av > hf_max)
904 hf_max = hf_av;
15c4dc5a 905 }
906 }
e30c654b 907
1d04b933 908 if (mode == 2) {
15c4dc5a 909 if (limit == LF_ONLY) {
910 display_val = lf_av;
911 display_max = lf_max;
912 } else if (limit == HF_ONLY) {
913 display_val = hf_av;
914 display_max = hf_max;
915 } else { /* Pick one at random */
916 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {
917 display_val = hf_av;
918 display_max = hf_max;
919 } else {
920 display_val = lf_av;
921 display_max = lf_max;
922 }
923 }
1d04b933 924 for (i = 0; i < LIGHT_LEN; i++) {
925 if (display_val >= (display_max / LIGHT_LEN * i) && display_val <= (display_max / LIGHT_LEN * (i+1))) {
15c4dc5a 926 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();
927 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();
928 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();
929 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();
930 break;
931 }
932 }
933 }
934 }
935}
936
1d04b933 937
867e10a5 938void UsbPacketReceived(UsbCommand *c) {
15c4dc5a 939
902cb3c0 940// Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
1d04b933 941
15c4dc5a 942 switch(c->cmd) {
943#ifdef WITH_LF
31abe49f 944 case CMD_SET_LF_SAMPLING_CONFIG:
70dbfc3f 945 setSamplingConfig(c->d.asBytes);
31abe49f 946 break;
15c4dc5a 947 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
b9957414 948 cmd_send(CMD_ACK,SampleLF(c->arg[0], c->arg[1]),0,0,0,0);
15c4dc5a 949 break;
15c4dc5a 950 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
951 ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
952 break;
b014c96d 953 case CMD_LF_SNOOP_RAW_ADC_SAMPLES:
31abe49f 954 cmd_send(CMD_ACK,SnoopLF(),0,0,0,0);
b014c96d 955 break;
7e67e42f 956 case CMD_HID_DEMOD_FSK:
be59094d 957 CmdHIDdemodFSK(c->arg[0], 0, 0, 0, 1);
7e67e42f 958 break;
959 case CMD_HID_SIM_TAG:
be59094d 960 CmdHIDsimTAG(c->arg[0], c->arg[1], c->arg[2], 1);
7e67e42f 961 break;
abd6112f 962 case CMD_FSK_SIM_TAG:
963 CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
964 break;
965 case CMD_ASK_SIM_TAG:
966 CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
967 break;
872e3d4d 968 case CMD_PSK_SIM_TAG:
969 CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
970 break;
971 case CMD_HID_CLONE_TAG:
5f84531b
SS
972 CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0], 0x1D);
973 break;
974 case CMD_PARADOX_CLONE_TAG:
975 // Paradox cards are the same as HID, with a different preamble, so we can reuse the same function
976 CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0], 0x0F);
7e67e42f 977 break;
a1f3bb12 978 case CMD_IO_DEMOD_FSK:
3fe4ff4f 979 CmdIOdemodFSK(c->arg[0], 0, 0, 1);
a1f3bb12 980 break;
3fe4ff4f 981 case CMD_IO_CLONE_TAG:
9f669cb2 982 CopyIOtoT55x7(c->arg[0], c->arg[1]);
a1f3bb12 983 break;
66707a3b 984 case CMD_EM410X_DEMOD:
985 CmdEM410xdemod(c->arg[0], 0, 0, 1);
986 break;
2d4eae76 987 case CMD_EM410X_WRITE_TAG:
988 WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
989 break;
7e67e42f 990 case CMD_READ_TI_TYPE:
991 ReadTItag();
992 break;
993 case CMD_WRITE_TI_TYPE:
994 WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
995 break;
996 case CMD_SIMULATE_TAG_125K:
31d1caa5 997 LED_A_ON();
7e67e42f 998 SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
31d1caa5 999 LED_A_OFF();
7e67e42f 1000 break;
1001 case CMD_LF_SIMULATE_BIDIR:
1002 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
1003 break;
3fe4ff4f 1004 case CMD_INDALA_CLONE_TAG:
1d04b933 1005 CopyIndala64toT55x7(c->arg[0], c->arg[1]);
2414f978 1006 break;
3fe4ff4f 1007 case CMD_INDALA_CLONE_TAG_L:
2414f978 1008 CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
1009 break;
1c611bbd 1010 case CMD_T55XX_READ_BLOCK:
8e99ec25 1011 T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]);
1c611bbd 1012 break;
1013 case CMD_T55XX_WRITE_BLOCK:
1014 T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
1015 break;
be2d41b7 1016 case CMD_T55XX_WAKEUP:
1017 T55xxWakeUp(c->arg[0]);
1c611bbd 1018 break;
66837a03 1019 case CMD_T55XX_RESET_READ:
1020 T55xxResetRead();
1021 break;
3fe4ff4f 1022 case CMD_PCF7931_READ:
1c611bbd 1023 ReadPCF7931();
1c611bbd 1024 break;
dc4300ba 1025 case CMD_PCF7931_WRITE:
d10e08ae 1026 WritePCF7931(c->d.asBytes[0],c->d.asBytes[1],c->d.asBytes[2],c->d.asBytes[3],c->d.asBytes[4],c->d.asBytes[5],c->d.asBytes[6], c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128, c->arg[0], c->arg[1], c->arg[2]);
dc4300ba 1027 break;
818e15b0
S
1028 case CMD_PCF7931_BRUTEFORCE:
1029 BruteForcePCF7931(c->arg[0], (c->arg[1] & 0xFF), c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128);
1030 break;
1c611bbd 1031 case CMD_EM4X_READ_WORD:
7666f460 1032 EM4xReadWord(c->arg[0], c->arg[1],c->arg[2]);
1c611bbd 1033 break;
1034 case CMD_EM4X_WRITE_WORD:
7666f460 1035 EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]);
1c611bbd 1036 break;
2de26056 1037 case CMD_EM4X_PROTECT:
1038 EM4xProtect(c->arg[0], c->arg[1], c->arg[2]);
1039 break;
dbf6e824
CY
1040 case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
1041 CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
7cfc777b 1042 break;
709665b5 1043 case CMD_VIKING_CLONE_TAG:
1044 CopyVikingtoT55xx(c->arg[0], c->arg[1], c->arg[2]);
1045 break;
e04475c4 1046 case CMD_COTAG:
1047 Cotag(c->arg[0]);
1048 break;
15c4dc5a 1049#endif
1050
d19929cb 1051#ifdef WITH_HITAG
1052 case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
1053 SnoopHitag(c->arg[0]);
1054 break;
1055 case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
1d04b933 1056 SimulateHitagTag((bool)c->arg[0], (uint8_t*)c->d.asBytes);
d19929cb 1057 break;
1058 case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
1059 ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
1060 break;
4e12287d 1061 case CMD_SIMULATE_HITAG_S:// Simulate Hitag s tag, args = memory content
1d04b933 1062 SimulateHitagSTag((bool)c->arg[0],(uint8_t*)c->d.asBytes);
4e12287d
RS
1063 break;
1064 case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file
1d04b933 1065 check_challenges_cmd((bool)c->arg[0], (uint8_t*)c->d.asBytes, (uint8_t)c->arg[1]);
4e12287d
RS
1066 break;
1067 case CMD_READ_HITAG_S://Reader for only Hitag S tags, args = key or challenge
7b6e3205 1068 ReadHitagSCmd((hitag_function)c->arg[0], (hitag_data*)c->d.asBytes, (uint8_t)c->arg[1], (uint8_t)c->arg[2], false);
1069 break;
1070 case CMD_READ_HITAG_S_BLK:
1071 ReadHitagSCmd((hitag_function)c->arg[0], (hitag_data*)c->d.asBytes, (uint8_t)c->arg[1], (uint8_t)c->arg[2], true);
4e12287d
RS
1072 break;
1073 case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
52244230
HJ
1074 if ((hitag_function)c->arg[0] < 10) {
1075 WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
1076 }
1077 else if ((hitag_function)c->arg[0] >= 10) {
1078 WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]);
1079 }
4e12287d 1080 break;
d19929cb 1081#endif
f168b263 1082
15c4dc5a 1083#ifdef WITH_ISO15693
1084 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
1085 AcquireRawAdcSamplesIso15693();
1086 break;
1d04b933 1087
d9de20fa 1088 case CMD_SNOOP_ISO_15693:
be09ea86 1089 SnoopIso15693(0, NULL);
9455b51c 1090 break;
1d04b933 1091
9455b51c 1092 case CMD_ISO_15693_COMMAND:
1093 DirectTag15693Command(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
1094 break;
1d04b933 1095
9455b51c 1096 case CMD_ISO_15693_FIND_AFI:
1097 BruteforceIso15693Afi(c->arg[0]);
1d04b933 1098 break;
1099
9455b51c 1100 case CMD_ISO_15693_DEBUG:
1101 SetDebugIso15693(c->arg[0]);
1102 break;
15c4dc5a 1103
15c4dc5a 1104 case CMD_READER_ISO_15693:
1105 ReaderIso15693(c->arg[0]);
1106 break;
096dee17 1107
7e67e42f 1108 case CMD_SIMTAG_ISO_15693:
3fe4ff4f 1109 SimTagIso15693(c->arg[0], c->d.asBytes);
7e67e42f 1110 break;
096dee17 1111
1112 case CMD_CSETUID_ISO_15693:
1113 SetTag15693Uid(c->d.asBytes);
1114 break;
15c4dc5a 1115#endif
1116
7e67e42f 1117#ifdef WITH_LEGICRF
1118 case CMD_SIMULATE_TAG_LEGIC_RF:
1b902aa0 1119 LegicRfSimulate(c->arg[0]);
7e67e42f 1120 break;
3612a8a8 1121
7e67e42f 1122 case CMD_WRITER_LEGIC_RF:
1123 LegicRfWriter(c->arg[1], c->arg[0]);
1124 break;
3612a8a8 1125
15c4dc5a 1126 case CMD_READER_LEGIC_RF:
1127 LegicRfReader(c->arg[0], c->arg[1]);
1128 break;
15c4dc5a 1129#endif
1130
1131#ifdef WITH_ISO14443b
15c4dc5a 1132 case CMD_READ_SRI512_TAG:
51d4f6f1 1133 ReadSTMemoryIso14443b(0x0F);
15c4dc5a 1134 break;
7e67e42f 1135 case CMD_READ_SRIX4K_TAG:
51d4f6f1 1136 ReadSTMemoryIso14443b(0x7F);
7e67e42f 1137 break;
132a0217 1138 case CMD_SNOOP_ISO_14443B:
51d4f6f1 1139 SnoopIso14443b();
7e67e42f 1140 break;
132a0217 1141 case CMD_SIMULATE_TAG_ISO_14443B:
51d4f6f1 1142 SimulateIso14443bTag();
7e67e42f 1143 break;
7cf3ef20 1144 case CMD_ISO_14443B_COMMAND:
1145 SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
1146 break;
15c4dc5a 1147#endif
1148
1149#ifdef WITH_ISO14443a
7e67e42f 1150 case CMD_SNOOP_ISO_14443a:
5cd9ec01 1151 SnoopIso14443a(c->arg[0]);
7e67e42f 1152 break;
15c4dc5a 1153 case CMD_READER_ISO_14443a:
902cb3c0 1154 ReaderIso14443a(c);
15c4dc5a 1155 break;
7e67e42f 1156 case CMD_SIMULATE_TAG_ISO_14443a:
28afbd2b 1157 SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID
7e67e42f 1158 break;
1d04b933 1159
5acd09bd 1160 case CMD_EPA_PACE_COLLECT_NONCE:
902cb3c0 1161 EPA_PACE_Collect_Nonce(c);
5acd09bd 1162 break;
3bb07d96
FM
1163 case CMD_EPA_PACE_REPLAY:
1164 EPA_PACE_Replay(c);
1165 break;
1d04b933 1166
15c4dc5a 1167 case CMD_READER_MIFARE:
f168b263 1168 ReaderMifare(c->arg[0]);
15c4dc5a 1169 break;
20f9a2a1
M
1170 case CMD_MIFARE_READBL:
1171 MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1172 break;
981bd429 1173 case CMD_MIFAREU_READBL:
f168b263 1174 MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
981bd429 1175 break;
8258f409 1176 case CMD_MIFAREUC_AUTH:
1177 MifareUC_Auth(c->arg[0],c->d.asBytes);
a631936e 1178 break;
981bd429 1179 case CMD_MIFAREU_READCARD:
75377d29 1180 MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
117d9ec2 1181 break;
1d04b933 1182 case CMD_MIFAREUC_SETPWD:
f168b263 1183 MifareUSetPwd(c->arg[0], c->d.asBytes);
1184 break;
20f9a2a1
M
1185 case CMD_MIFARE_READSC:
1186 MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1187 break;
1188 case CMD_MIFARE_WRITEBL:
1189 MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1190 break;
0b4efbde 1191 case CMD_MIFARE_PERSONALIZE_UID:
1192 MifarePersonalizeUID(c->arg[0], c->arg[1], c->d.asBytes);
1193 break;
4973f23d 1194 //case CMD_MIFAREU_WRITEBL_COMPAT:
1195 //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
1196 //break;
981bd429 1197 case CMD_MIFAREU_WRITEBL:
4973f23d 1198 MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
f168b263 1199 break;
c48c4d78 1200 case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES:
1201 MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1202 break;
20f9a2a1
M
1203 case CMD_MIFARE_NESTED:
1204 MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
f397b5cc
M
1205 break;
1206 case CMD_MIFARE_CHKKEYS:
1207 MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
20f9a2a1
M
1208 break;
1209 case CMD_SIMULATE_MIFARE_CARD:
a8561e35 1210 MifareSim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
20f9a2a1 1211 break;
1d04b933 1212
8556b852
M
1213 // emulator
1214 case CMD_MIFARE_SET_DBGMODE:
1215 MifareSetDbgLvl(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1216 break;
1217 case CMD_MIFARE_EML_MEMCLR:
1218 MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1219 break;
1220 case CMD_MIFARE_EML_MEMSET:
1221 MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1222 break;
1223 case CMD_MIFARE_EML_MEMGET:
1224 MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1225 break;
1226 case CMD_MIFARE_EML_CARDLOAD:
1227 MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
0675f200 1228 break;
1d04b933 1229
0675f200 1230 // Work with "magic Chinese" card
3a05a1e7
OM
1231 case CMD_MIFARE_CWIPE:
1232 MifareCWipe(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1233 break;
3fe4ff4f 1234 case CMD_MIFARE_CSETBLOCK:
0675f200 1235 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
545a1f38 1236 break;
3fe4ff4f 1237 case CMD_MIFARE_CGETBLOCK:
545a1f38 1238 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
8556b852 1239 break;
3fe4ff4f 1240 case CMD_MIFARE_CIDENT:
1241 MifareCIdent();
1242 break;
1d04b933 1243
b62a5a84
M
1244 // mifare sniffer
1245 case CMD_MIFARE_SNIFFER:
5cd9ec01 1246 SniffMifare(c->arg[0]);
b62a5a84 1247 break;
a631936e 1248
20f9a2a1
M
1249#endif
1250
7e67e42f 1251#ifdef WITH_ICLASS
cee5a30d 1252 // Makes use of ISO14443a FPGA Firmware
1253 case CMD_SNOOP_ICLASS:
be09ea86 1254 SnoopIClass(c->arg[0], c->d.asBytes);
cee5a30d 1255 break;
1e262141 1256 case CMD_SIMULATE_TAG_ICLASS:
ff7bb4ef 1257 SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1e262141 1258 break;
1259 case CMD_READER_ICLASS:
1260 ReaderIClass(c->arg[0]);
1261 break;
aa53efc3 1262 case CMD_ICLASS_EML_MEMSET:
e80aeb96
MHS
1263 emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
1264 break;
aa53efc3 1265 case CMD_ICLASS_WRITEBLOCK:
3ac22ee1 1266 iClass_WriteBlock(c->arg[0], c->d.asBytes);
1267 break;
aa53efc3 1268 case CMD_ICLASS_READBLOCK:
3ac22ee1 1269 iClass_ReadBlk(c->arg[0]);
aa53efc3 1270 break;
ece38ef3 1271 case CMD_ICLASS_CHECK:
1272 iClass_Check(c->d.asBytes);
1273 break;
1274 case CMD_ICLASS_READCHECK:
1275 iClass_Readcheck(c->arg[0], c->arg[1]);
aa53efc3 1276 break;
1277 case CMD_ICLASS_DUMP:
3ac22ee1 1278 iClass_Dump(c->arg[0], c->arg[1]);
aa53efc3 1279 break;
1280 case CMD_ICLASS_CLONE:
3ac22ee1 1281 iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes);
aa53efc3 1282 break;
cee5a30d 1283#endif
fc52fbd4 1284
0472d76d 1285#ifdef WITH_HFSNOOP
1286 case CMD_HF_SNIFFER:
1287 HfSnoop(c->arg[0], c->arg[1]);
1288 break;
fc52fbd4 1289 case CMD_HF_PLOT:
1290 HfPlot();
1291 break;
0472d76d 1292#endif
fc52fbd4 1293
43591e64 1294#ifdef WITH_SMARTCARD
1295 case CMD_SMART_ATR: {
1296 SmartCardAtr();
1297 break;
1298 }
1299 case CMD_SMART_SETCLOCK:{
1300 SmartCardSetClock(c->arg[0]);
1301 break;
1302 }
1303 case CMD_SMART_RAW: {
1304 SmartCardRaw(c->arg[0], c->arg[1], c->d.asBytes);
1305 break;
1306 }
1307 case CMD_SMART_UPLOAD: {
1308 // upload file from client
1309 uint8_t *mem = BigBuf_get_addr();
1310 memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1311 cmd_send(CMD_ACK,1,0,0,0,0);
1312 break;
1313 }
1314 case CMD_SMART_UPGRADE: {
1315 SmartCardUpgrade(c->arg[0]);
1316 break;
1317 }
1318#endif
cee5a30d 1319
7e67e42f 1320 case CMD_BUFF_CLEAR:
117d9ec2 1321 BigBuf_Clear();
15c4dc5a 1322 break;
15c4dc5a 1323
1324 case CMD_MEASURE_ANTENNA_TUNING:
fdcfbdcc 1325 MeasureAntennaTuning(c->arg[0]);
15c4dc5a 1326 break;
1327
1328 case CMD_MEASURE_ANTENNA_TUNING_HF:
1329 MeasureAntennaTuningHf();
1330 break;
1331
1332 case CMD_LISTEN_READER_FIELD:
1333 ListenReaderField(c->arg[0]);
1334 break;
1335
1d04b933 1336 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
15c4dc5a 1337 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1338 SpinDelay(200);
1339 LED_D_OFF(); // LED D indicates field ON or OFF
1340 break;
1341
1c611bbd 1342 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
1c611bbd 1343 LED_B_ON();
117d9ec2 1344 uint8_t *BigBuf = BigBuf_get_addr();
1c611bbd 1345 for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
1346 size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
3000dc4e 1347 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
1c611bbd 1348 }
1349 // Trigger a finish downloading signal with an ACK frame
3000dc4e 1350 cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
d3b1f4e4 1351 LED_B_OFF();
1c611bbd 1352 break;
15c4dc5a 1353
1354 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
8c8317a5 1355 // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before.
1d04b933 1356 // to be able to use this one for uploading data to device
1357 // arg1 = 0 upload for LF usage
8c8317a5 1358 // 1 upload for HF usage
1359 if (c->arg[1] == 0)
1360 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
1361 else
1362 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1363
117d9ec2 1364 uint8_t *b = BigBuf_get_addr();
3fe4ff4f 1365 memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1c611bbd 1366 cmd_send(CMD_ACK,0,0,0,0,0);
1367 break;
1d04b933 1368 }
15c4dc5a 1369 case CMD_READ_MEM:
1370 ReadMem(c->arg[0]);
1371 break;
1372
1373 case CMD_SET_LF_DIVISOR:
8c8317a5 1374 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 1375 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
1376 break;
1377
1378 case CMD_SET_ADC_MUX:
1379 switch(c->arg[0]) {
1380 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;
1381 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;
1382 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;
1383 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;
1384 }
1385 break;
1386
1387 case CMD_VERSION:
1388 SendVersion();
1389 break;
c89274cc 1390 case CMD_STATUS:
67b7d6fa 1391 SendStatus();
c89274cc
CY
1392 break;
1393 case CMD_PING:
1394 cmd_send(CMD_ACK,0,0,0,0,0);
1395 break;
15c4dc5a 1396#ifdef WITH_LCD
1397 case CMD_LCD_RESET:
1398 LCDReset();
1399 break;
1400 case CMD_LCD:
1401 LCDSend(c->arg[0]);
1402 break;
1403#endif
1404 case CMD_SETUP_WRITE:
1405 case CMD_FINISH_WRITE:
1c611bbd 1406 case CMD_HARDWARE_RESET:
1407 usb_disable();
15c4dc5a 1408 SpinDelay(1000);
1409 SpinDelay(1000);
1410 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1411 for(;;) {
1412 // We're going to reset, and the bootrom will take control.
1413 }
1c611bbd 1414 break;
15c4dc5a 1415
1c611bbd 1416 case CMD_START_FLASH:
15c4dc5a 1417 if(common_area.flags.bootrom_present) {
1418 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
1419 }
1c611bbd 1420 usb_disable();
15c4dc5a 1421 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1422 for(;;);
1c611bbd 1423 break;
e30c654b 1424
15c4dc5a 1425 case CMD_DEVICE_INFO: {
902cb3c0 1426 uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
1427 if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
1d04b933 1428 cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
1c611bbd 1429 break;
1430 }
1431 default:
15c4dc5a 1432 Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
1c611bbd 1433 break;
15c4dc5a 1434 }
1435}
1436
1d04b933 1437
1438void __attribute__((noreturn)) AppMain(void) {
1439
15c4dc5a 1440 SpinDelay(100);
9e8255d4 1441 clear_trace();
15c4dc5a 1442 if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
1443 /* Initialize common area */
1444 memset(&common_area, 0, sizeof(common_area));
1445 common_area.magic = COMMON_AREA_MAGIC;
1446 common_area.version = 1;
1447 }
1448 common_area.flags.osimage_present = 1;
1449
3d057cfb 1450 LEDsoff();
1d04b933 1451
3fe4ff4f 1452 // Init USB device
050aa18b 1453 usb_enable();
15c4dc5a 1454
1455 // The FPGA gets its clock from us from PCK0 output, so set that up.
1456 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
1457 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
1458 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;
1459 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
1460 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK |
0472d76d 1461 AT91C_PMC_PRES_CLK_4; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0
15c4dc5a 1462 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
1463
1464 // Reset SPI
1465 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
1466 // Reset SSC
1467 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
1468
1469 // Load the FPGA image, which we have stored in our flash.
7cc204bf 1470 // (the HF version by default)
1471 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1472
9ca155ba 1473 StartTickCount();
1d04b933 1474
15c4dc5a 1475#ifdef WITH_LCD
15c4dc5a 1476 LCDInit();
15c4dc5a 1477#endif
1478
867e10a5 1479 UsbCommand rx;
1480
15c4dc5a 1481 for(;;) {
867e10a5 1482 if (cmd_receive(&rx)) {
1483 UsbPacketReceived(&rx);
1484 }
1485
15c4dc5a 1486 WDT_HIT();
6b34699a 1487 if (usb_poll() && (rx_len = usb_read(rx, sizeof(rx)))) {
1488 UsbPacketReceived(rx, rx_len);
1489 } else {
1490#if defined(WITH_LF_StandAlone) && !defined(WITH_ISO14443a_StandAlone)
1491 if (BUTTON_HELD(1000) > 0)
1492 SamyRun();
e46fe044 1493#endif
6b34699a 1494#if defined(WITH_ISO14443a) && defined(WITH_ISO14443a_StandAlone)
1495 if (BUTTON_HELD(1000) > 0)
1496 StandAloneMode14a();
15c4dc5a 1497#endif
6b34699a 1498 }
15c4dc5a 1499 }
1500}
Impressum, Datenschutz