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