]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/appmain.c
Add version command
[proxmark3-svn] / armsrc / appmain.c
CommitLineData
959baa89 1//-----------------------------------------------------------------------------
2// The main application code. This is the first thing called after start.c
3// executes.
4// Jonathan Westhues, Mar 2006
5// Edits by Gerhard de Koning Gans, Sep 2007 (##)
6//-----------------------------------------------------------------------------
7
959baa89 8#include <proxmark3.h>
7f348042 9#include <stdlib.h>
959baa89 10#include "apps.h"
11#ifdef WITH_LCD
12#include "fonts.h"
13#include "LCD.h"
14#endif
15
959baa89 16
17//=============================================================================
18// A buffer where we can queue things up to be sent through the FPGA, for
19// any purpose (fake tag, as reader, whatever). We go MSB first, since that
20// is the order in which they go out on the wire.
21//=============================================================================
22
23BYTE ToSend[256];
24int ToSendMax;
25static int ToSendBit;
26
f23e056d 27void BufferClear(void)
28{
29 memset(BigBuf,0,sizeof(BigBuf));
30 DbpString("Buffer cleared");
31}
32
959baa89 33void ToSendReset(void)
34{
35 ToSendMax = -1;
36 ToSendBit = 8;
37}
38
39void ToSendStuffBit(int b)
40{
41 if(ToSendBit >= 8) {
42 ToSendMax++;
43 ToSend[ToSendMax] = 0;
44 ToSendBit = 0;
45 }
46
47 if(b) {
48 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
49 }
50
51 ToSendBit++;
52
53 if(ToSendBit >= sizeof(ToSend)) {
54 ToSendBit = 0;
55 DbpString("ToSendStuffBit overflowed!");
56 }
57}
58
59//=============================================================================
60// Debug print functions, to go out over USB, to the usual PC-side client.
61//=============================================================================
62
63void DbpString(char *str)
64{
955fc5e2 65 /* this holds up stuff unless we're connected to usb */
50722269 66 if (!UsbConnected())
67 return;
c701d2c2 68
959baa89 69 UsbCommand c;
70 c.cmd = CMD_DEBUG_PRINT_STRING;
71 c.ext1 = strlen(str);
72 memcpy(c.d.asBytes, str, c.ext1);
73
74 UsbSendPacket((BYTE *)&c, sizeof(c));
75 // TODO fix USB so stupid things like this aren't req'd
76 SpinDelay(50);
77}
78
79void DbpIntegers(int x1, int x2, int x3)
80{
955fc5e2 81 /* this holds up stuff unless we're connected to usb */
50722269 82 if (!UsbConnected())
83 return;
955fc5e2 84
959baa89 85 UsbCommand c;
86 c.cmd = CMD_DEBUG_PRINT_INTEGERS;
87 c.ext1 = x1;
88 c.ext2 = x2;
89 c.ext3 = x3;
90
91 UsbSendPacket((BYTE *)&c, sizeof(c));
92 // XXX
93 SpinDelay(50);
94}
95
959baa89 96//-----------------------------------------------------------------------------
97// Read an ADC channel and block till it completes, then return the result
98// in ADC units (0 to 1023). Also a routine to average 32 samples and
99// return that.
100//-----------------------------------------------------------------------------
101static int ReadAdc(int ch)
102{
103 DWORD d;
104
105 ADC_CONTROL = ADC_CONTROL_RESET;
106 ADC_MODE = ADC_MODE_PRESCALE(32) | ADC_MODE_STARTUP_TIME(16) |
107 ADC_MODE_SAMPLE_HOLD_TIME(8);
108 ADC_CHANNEL_ENABLE = ADC_CHANNEL(ch);
109
110 ADC_CONTROL = ADC_CONTROL_START;
111 while(!(ADC_STATUS & ADC_END_OF_CONVERSION(ch)))
112 ;
113 d = ADC_CHANNEL_DATA(ch);
114
115 return d;
116}
117
118static int AvgAdc(int ch)
119{
120 int i;
121 int a = 0;
122
123 for(i = 0; i < 32; i++) {
124 a += ReadAdc(ch);
125 }
126
127 return (a + 15) >> 5;
128}
30f2a7d3 129
e7aee94e 130void MeasureAntennaTuning(void)
959baa89 131{
132 BYTE *dest = (BYTE *)BigBuf;
e7aee94e 133 int i, ptr = 0, adcval = 0, peak = 0, peakv = 0, peakf = 0;;
134 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
135
136 UsbCommand c;
959baa89 137
e7aee94e 138 DbpString("Measuring antenna characteristics, please wait.");
959baa89 139 memset(BigBuf,0,sizeof(BigBuf));
140
e7aee94e 141/*
142 * Sweeps the useful LF range of the proxmark from
143 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
144 * read the voltage in the antenna, the result left
145 * in the buffer is a graph which should clearly show
146 * the resonating frequency of your LF antenna
147 * ( hopefully around 95 if it is tuned to 125kHz!)
148 */
959baa89 149 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
150 for (i=255; i>19; i--) {
151 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
152 SpinDelay(20);
e7aee94e 153 // Vref = 3.3V, and a 10000:240 voltage divider on the input
154 // can measure voltages up to 137500 mV
155 adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);
156 if (i==95) vLf125 = adcval; // voltage at 125Khz
157 if (i==89) vLf134 = adcval; // voltage at 134Khz
158
159 dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
38b65694 160 if(dest[i] > peak) {
e7aee94e 161 peakv = adcval;
162 peak = dest[i];
163 peakf = i;
164 ptr = i;
38b65694 165 }
e7aee94e 166 }
959baa89 167
168 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
169 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
170 SpinDelay(20);
959baa89 171 // Vref = 3300mV, and an 10:1 voltage divider on the input
172 // can measure voltages up to 33000 mV
e7aee94e 173 vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
959baa89 174
175 c.cmd = CMD_MEASURED_ANTENNA_TUNING;
176 c.ext1 = (vLf125 << 0) | (vLf134 << 16);
177 c.ext2 = vHf;
c701d2c2 178 c.ext3 = peakf | (peakv << 16);
959baa89 179 UsbSendPacket((BYTE *)&c, sizeof(c));
180}
181
9bea179a 182void SimulateTagHfListen(void)
959baa89 183{
9bea179a 184 BYTE *dest = (BYTE *)BigBuf;
185 int n = sizeof(BigBuf);
186 BYTE v = 0;
959baa89 187 int i;
9bea179a 188 int p = 0;
959baa89 189
9bea179a 190 // We're using this mode just so that I can test it out; the simulated
191 // tag mode would work just as well and be simpler.
192 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
959baa89 193
9bea179a 194 // We need to listen to the high-frequency, peak-detected path.
195 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
959baa89 196
9bea179a 197 FpgaSetupSsc();
959baa89 198
199 i = 0;
200 for(;;) {
9bea179a 201 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
202 SSC_TRANSMIT_HOLDING = 0xff;
959baa89 203 }
9bea179a 204 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
205 BYTE r = (BYTE)SSC_RECEIVE_HOLDING;
959baa89 206
9bea179a 207 v <<= 1;
208 if(r & 1) {
209 v |= 1;
210 }
211 p++;
c701d2c2 212
9bea179a 213 if(p >= 8) {
214 dest[i] = v;
215 v = 0;
216 p = 0;
217 i++;
959baa89 218
9bea179a 219 if(i >= n) {
220 break;
221 }
959baa89 222 }
959baa89 223 }
959baa89 224 }
9bea179a 225 DbpString("simulate tag (now type bitsamples)");
959baa89 226}
227
9bea179a 228void ReadMem(int addr)
229{
230 const DWORD *data = ((DWORD *)addr);
231 int i;
959baa89 232
9bea179a 233 DbpString("Reading memory at address");
234 DbpIntegers(0, 0, addr);
235 for (i = 0; i < 8; i+= 2)
236 DbpIntegers(0, data[i], data[i+1]);
959baa89 237}
238
ba8a80b3 239void SendVersion(void)
240{
241 char temp[48]; /* Limited data payload in USB packets */
242 DbpString("Prox/RFID mark3 RFID instrument");
243 FpgaGatherVersion(temp, sizeof(temp));
244 DbpString(temp);
245}
246
9bea179a 247// samy's sniff and repeat routine
248void SamyRun()
959baa89 249{
9bea179a 250 DbpString("Stand-alone mode! No PC necessary.");
959baa89 251
9bea179a 252 // 3 possible options? no just 2 for now
253#define OPTS 2
959baa89 254
9bea179a 255 int high[OPTS], low[OPTS];
c701d2c2 256
9bea179a 257 // Oooh pretty -- notify user we're in elite samy mode now
258 LED(LED_RED, 200);
259 LED(LED_ORANGE, 200);
260 LED(LED_GREEN, 200);
261 LED(LED_ORANGE, 200);
262 LED(LED_RED, 200);
263 LED(LED_ORANGE, 200);
264 LED(LED_GREEN, 200);
265 LED(LED_ORANGE, 200);
266 LED(LED_RED, 200);
959baa89 267
9bea179a 268 int selected = 0;
269 int playing = 0;
959baa89 270
9bea179a 271 // Turn on selected LED
272 LED(selected + 1, 0);
959baa89 273
9bea179a 274 for (;;)
275 {
50722269 276 UsbPoll(FALSE);
9bea179a 277 WDT_HIT();
959baa89 278
9bea179a 279 // Was our button held down or pressed?
280 int button_pressed = BUTTON_HELD(1000);
281 SpinDelay(300);
959baa89 282
9bea179a 283 // Button was held for a second, begin recording
284 if (button_pressed > 0)
285 {
286 LEDsoff();
287 LED(selected + 1, 0);
288 LED(LED_RED2, 0);
959baa89 289
9bea179a 290 // record
291 DbpString("Starting recording");
959baa89 292
9bea179a 293 // wait for button to be released
294 while(BUTTON_PRESS())
295 WDT_HIT();
959baa89 296
9bea179a 297 /* need this delay to prevent catching some weird data */
298 SpinDelay(500);
959baa89 299
9bea179a 300 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
301 DbpString("Recorded");
302 DbpIntegers(selected, high[selected], low[selected]);
959baa89 303
9bea179a 304 LEDsoff();
305 LED(selected + 1, 0);
306 // Finished recording
959baa89 307
9bea179a 308 // If we were previously playing, set playing off
309 // so next button push begins playing what we recorded
310 playing = 0;
959baa89 311 }
959baa89 312
9bea179a 313 // Change where to record (or begin playing)
314 else if (button_pressed)
315 {
316 // Next option if we were previously playing
317 if (playing)
318 selected = (selected + 1) % OPTS;
319 playing = !playing;
959baa89 320
9bea179a 321 LEDsoff();
322 LED(selected + 1, 0);
323
324 // Begin transmitting
325 if (playing)
959baa89 326 {
9bea179a 327 LED(LED_GREEN, 0);
328 DbpString("Playing");
329 // wait for button to be released
330 while(BUTTON_PRESS())
331 WDT_HIT();
332 DbpIntegers(selected, high[selected], low[selected]);
333 CmdHIDsimTAG(high[selected], low[selected], 0);
334 DbpString("Done playing");
335 if (BUTTON_HELD(1000) > 0)
955fc5e2 336 {
9bea179a 337 DbpString("Exiting");
338 LEDsoff();
339 return;
955fc5e2 340 }
9bea179a 341
342 /* We pressed a button so ignore it here with a delay */
343 SpinDelay(300);
344
345 // when done, we're done playing, move to next option
346 selected = (selected + 1) % OPTS;
347 playing = !playing;
348 LEDsoff();
349 LED(selected + 1, 0);
959baa89 350 }
9bea179a 351 else
352 while(BUTTON_PRESS())
353 WDT_HIT();
959baa89 354 }
959baa89 355 }
356}
357
9bea179a 358
359/*
360OBJECTIVE
361Listen and detect an external reader. Determine the best location
362for the antenna.
363
364INSTRUCTIONS:
365Inside the ListenReaderField() function, there is two mode.
366By default, when you call the function, you will enter mode 1.
367If you press the PM3 button one time, you will enter mode 2.
368If you press the PM3 button a second time, you will exit the function.
369
370DESCRIPTION OF MODE 1:
371This mode just listens for an external reader field and lights up green
372for HF and/or red for LF. This is the original mode of the detectreader
373function.
374
375DESCRIPTION OF MODE 2:
376This mode will visually represent, using the LEDs, the actual strength of the
377current compared to the maximum current detected. Basically, once you know
378what kind of external reader is present, it will help you spot the best location to place
379your antenna. You will probably not get some good results if there is a LF and a HF reader
380at the same place! :-)
381
382LIGHT SCHEME USED:
9bea179a 383*/
bea2a866 384static const char LIGHT_SCHEME[] = {
385 0x0, /* ---- | No field detected */
386 0x1, /* X--- | 14% of maximum current detected */
387 0x2, /* -X-- | 29% of maximum current detected */
388 0x4, /* --X- | 43% of maximum current detected */
389 0x8, /* ---X | 57% of maximum current detected */
390 0xC, /* --XX | 71% of maximum current detected */
391 0xE, /* -XXX | 86% of maximum current detected */
392 0xF, /* XXXX | 100% of maximum current detected */
393};
394static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
395
9bea179a 396void ListenReaderField(int limit)
959baa89 397{
bea2a866 398 int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0, lf_max;
9bea179a 399 int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max;
bea2a866 400 int mode=1, display_val, display_max, i;
959baa89 401
9bea179a 402#define LF_ONLY 1
403#define HF_ONLY 2
959baa89 404
bea2a866 405 LEDsoff();
959baa89 406
bea2a866 407 lf_av=lf_max=ReadAdc(ADC_CHAN_LF);
959baa89 408
bea2a866 409 if(limit != HF_ONLY) {
9bea179a 410 DbpString("LF 125/134 Baseline:");
411 DbpIntegers(lf_av,0,0);
412 lf_baseline= lf_av;
bea2a866 413 }
959baa89 414
9bea179a 415 hf_av=hf_max=ReadAdc(ADC_CHAN_HF);
959baa89 416
bea2a866 417 if (limit != LF_ONLY) {
9bea179a 418 DbpString("HF 13.56 Baseline:");
419 DbpIntegers(hf_av,0,0);
420 hf_baseline= hf_av;
bea2a866 421 }
959baa89 422
bea2a866 423 for(;;) {
9bea179a 424 if (BUTTON_PRESS()) {
425 SpinDelay(500);
426 switch (mode) {
427 case 1:
428 mode=2;
429 DbpString("Signal Strength Mode");
959baa89 430 break;
9bea179a 431 case 2:
432 default:
433 DbpString("Stopped");
bea2a866 434 LEDsoff();
9bea179a 435 return;
436 break;
437 }
438 }
439 WDT_HIT();
440
bea2a866 441 if (limit != HF_ONLY) {
442 if(mode==1) {
443 if (abs(lf_av - lf_baseline) > 10) LED_D_ON();
444 else LED_D_OFF();
445 }
446
9bea179a 447 ++lf_count;
448 lf_av_new= ReadAdc(ADC_CHAN_LF);
449 // see if there's a significant change
bea2a866 450 if(abs(lf_av - lf_av_new) > 10) {
9bea179a 451 DbpString("LF 125/134 Field Change:");
452 DbpIntegers(lf_av,lf_av_new,lf_count);
453 lf_av= lf_av_new;
bea2a866 454 if (lf_av > lf_max)
455 lf_max = lf_av;
9bea179a 456 lf_count= 0;
9bea179a 457 }
bea2a866 458 }
9bea179a 459
bea2a866 460 if (limit != LF_ONLY) {
461 if (mode == 1){
462 if (abs(hf_av - hf_baseline) > 10) LED_B_ON();
463 else LED_B_OFF();
9bea179a 464 }
bea2a866 465
9bea179a 466 ++hf_count;
467 hf_av_new= ReadAdc(ADC_CHAN_HF);
468 // see if there's a significant change
bea2a866 469 if(abs(hf_av - hf_av_new) > 10) {
9bea179a 470 DbpString("HF 13.56 Field Change:");
471 DbpIntegers(hf_av,hf_av_new,hf_count);
472 hf_av= hf_av_new;
473 if (hf_av > hf_max)
474 hf_max = hf_av;
475 hf_count= 0;
bea2a866 476 }
477 }
478
479 if(mode == 2) {
480 if (limit == LF_ONLY) {
481 display_val = lf_av;
482 display_max = lf_max;
483 } else if (limit == HF_ONLY) {
484 display_val = hf_av;
485 display_max = hf_max;
486 } else { /* Pick one at random */
487 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {
488 display_val = hf_av;
489 display_max = hf_max;
490 } else {
491 display_val = lf_av;
492 display_max = lf_max;
493 }
494 }
495 for (i=0; i<LIGHT_LEN; i++) {
496 if (display_val >= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) {
497 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();
498 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();
499 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();
500 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();
501 break;
959baa89 502 }
503 }
504 }
bea2a866 505 }
959baa89 506}
507
508void UsbPacketReceived(BYTE *packet, int len)
509{
510 UsbCommand *c = (UsbCommand *)packet;
511
512 switch(c->cmd) {
513 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
514 AcquireRawAdcSamples125k(c->ext1);
515 break;
516
517 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
518 ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
519 break;
520
521 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
522 AcquireRawAdcSamplesIso15693();
523 break;
f23e056d 524
525 case CMD_BUFF_CLEAR:
526 BufferClear();
527 break;
959baa89 528
529 case CMD_READER_ISO_15693:
530 ReaderIso15693(c->ext1);
531 break;
532
533 case CMD_SIMTAG_ISO_15693:
534 SimTagIso15693(c->ext1);
535 break;
536
537 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
538 AcquireRawAdcSamplesIso14443(c->ext1);
539 break;
fb25b483 540
541 case CMD_READ_SRI512_TAG:
542 ReadSRI512Iso14443(c->ext1);
543 break;
959baa89 544
545 case CMD_READER_ISO_14443a:
546 ReaderIso14443a(c->ext1);
547 break;
548
549 case CMD_SNOOP_ISO_14443:
550 SnoopIso14443();
551 break;
552
553 case CMD_SNOOP_ISO_14443a:
554 SnoopIso14443a();
555 break;
556
557 case CMD_SIMULATE_TAG_HF_LISTEN:
558 SimulateTagHfListen();
559 break;
560
561 case CMD_SIMULATE_TAG_ISO_14443:
562 SimulateIso14443Tag();
563 break;
564
565 case CMD_SIMULATE_TAG_ISO_14443a:
566 SimulateIso14443aTag(c->ext1, c->ext2); // ## Simulate iso14443a tag - pass tag type & UID
567 break;
568
569 case CMD_MEASURE_ANTENNA_TUNING:
570 MeasureAntennaTuning();
571 break;
572
7f348042 573 case CMD_LISTEN_READER_FIELD:
574 ListenReaderField(c->ext1);
575 break;
576
959baa89 577 case CMD_HID_DEMOD_FSK:
955fc5e2 578 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
959baa89 579 break;
580
581 case CMD_HID_SIM_TAG:
955fc5e2 582 CmdHIDsimTAG(c->ext1, c->ext2, 1); // Simulate HID tag by ID
959baa89 583 break;
584
585 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
586 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
587 SpinDelay(200);
588 LED_D_OFF(); // LED D indicates field ON or OFF
589 break;
590
9bea179a 591 case CMD_READ_TI_TYPE:
592 ReadTItag();
593 break;
594
595 case CMD_WRITE_TI_TYPE:
596 WriteTItag(c->ext1,c->ext2,c->ext3);
597 break;
598
7381e8f2 599 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {
959baa89 600 UsbCommand n;
601 if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
602 n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
603 } else {
604 n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
605 }
606 n.ext1 = c->ext1;
607 memcpy(n.d.asDwords, BigBuf+c->ext1, 12*sizeof(DWORD));
608 UsbSendPacket((BYTE *)&n, sizeof(n));
609 break;
610 }
611 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
612 BYTE *b = (BYTE *)BigBuf;
613 memcpy(b+c->ext1, c->d.asBytes, 48);
614 break;
615 }
616 case CMD_SIMULATE_TAG_125K:
617 LED_A_ON();
955fc5e2 618 SimulateTagLowFrequency(c->ext1, 1);
959baa89 619 LED_A_OFF();
620 break;
1dff8c42 621 case CMD_READ_MEM:
622 ReadMem(c->ext1);
623 break;
959baa89 624 case CMD_SET_LF_DIVISOR:
625 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
626 break;
ba8a80b3 627 case CMD_VERSION:
628 SendVersion();
629 break;
959baa89 630#ifdef WITH_LCD
7381e8f2 631 case CMD_LCD_RESET:
632 LCDReset();
633 break;
959baa89 634 case CMD_LCD:
635 LCDSend(c->ext1);
636 break;
637#endif
9bea179a 638 case CMD_SETUP_WRITE:
959baa89 639 case CMD_FINISH_WRITE:
640 case CMD_HARDWARE_RESET:
641 USB_D_PLUS_PULLUP_OFF();
642 SpinDelay(1000);
643 SpinDelay(1000);
644 RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;
645 for(;;) {
646 // We're going to reset, and the bootrom will take control.
647 }
648 break;
649
959baa89 650 default:
651 DbpString("unknown command");
652 break;
653 }
654}
655
656void AppMain(void)
657{
658 memset(BigBuf,0,sizeof(BigBuf));
659 SpinDelay(100);
660
693f7cf7 661 LED_D_OFF();
662 LED_C_OFF();
663 LED_B_OFF();
664 LED_A_OFF();
959baa89 665
666 UsbStart();
667
668 // The FPGA gets its clock from us from PCK0 output, so set that up.
669 PIO_PERIPHERAL_B_SEL = (1 << GPIO_PCK0);
670 PIO_DISABLE = (1 << GPIO_PCK0);
671 PMC_SYS_CLK_ENABLE = PMC_SYS_CLK_PROGRAMMABLE_CLK_0;
672 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
673 PMC_PROGRAMMABLE_CLK_0 = PMC_CLK_SELECTION_PLL_CLOCK |
674 PMC_CLK_PRESCALE_DIV_4;
675 PIO_OUTPUT_ENABLE = (1 << GPIO_PCK0);
676
677 // Reset SPI
678 SPI_CONTROL = SPI_CONTROL_RESET;
679 // Reset SSC
680 SSC_CONTROL = SSC_CONTROL_RESET;
681
682 // Load the FPGA image, which we have stored in our flash.
683 FpgaDownloadAndGo();
684
685#ifdef WITH_LCD
686
687 LCDInit();
688
689 // test text on different colored backgrounds
693f7cf7 690 LCDString(" The quick brown fox ", &FONT6x8,1,1+8*0,WHITE ,BLACK );
691 LCDString(" jumped over the ", &FONT6x8,1,1+8*1,BLACK ,WHITE );
692 LCDString(" lazy dog. ", &FONT6x8,1,1+8*2,YELLOW ,RED );
693 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8,1,1+8*3,RED ,GREEN );
694 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8,1,1+8*4,MAGENTA,BLUE );
695 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8,1,1+8*5,BLUE ,YELLOW);
696 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8,1,1+8*6,BLACK ,CYAN );
697 LCDString(" _+{}|:\\\"<>? ",&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
959baa89 698
699 // color bands
700 LCDFill(0, 1+8* 8, 132, 8, BLACK);
701 LCDFill(0, 1+8* 9, 132, 8, WHITE);
702 LCDFill(0, 1+8*10, 132, 8, RED);
703 LCDFill(0, 1+8*11, 132, 8, GREEN);
704 LCDFill(0, 1+8*12, 132, 8, BLUE);
705 LCDFill(0, 1+8*13, 132, 8, YELLOW);
706 LCDFill(0, 1+8*14, 132, 8, CYAN);
707 LCDFill(0, 1+8*15, 132, 8, MAGENTA);
708
709#endif
710
711 for(;;) {
50722269 712 UsbPoll(FALSE);
959baa89 713 WDT_HIT();
959baa89 714
955fc5e2 715 if (BUTTON_HELD(1000) > 0)
716 SamyRun();
959baa89 717 }
718}
Impressum, Datenschutz