]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/appmain.c
The older gnuarm in the windows toolchain seems to need the glue_7t section
[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
9bea179a 239// samy's sniff and repeat routine
240void SamyRun()
959baa89 241{
9bea179a 242 DbpString("Stand-alone mode! No PC necessary.");
959baa89 243
9bea179a 244 // 3 possible options? no just 2 for now
245#define OPTS 2
959baa89 246
9bea179a 247 int high[OPTS], low[OPTS];
c701d2c2 248
9bea179a 249 // Oooh pretty -- notify user we're in elite samy mode now
250 LED(LED_RED, 200);
251 LED(LED_ORANGE, 200);
252 LED(LED_GREEN, 200);
253 LED(LED_ORANGE, 200);
254 LED(LED_RED, 200);
255 LED(LED_ORANGE, 200);
256 LED(LED_GREEN, 200);
257 LED(LED_ORANGE, 200);
258 LED(LED_RED, 200);
959baa89 259
9bea179a 260 int selected = 0;
261 int playing = 0;
959baa89 262
9bea179a 263 // Turn on selected LED
264 LED(selected + 1, 0);
959baa89 265
9bea179a 266 for (;;)
267 {
50722269 268 UsbPoll(FALSE);
9bea179a 269 WDT_HIT();
959baa89 270
9bea179a 271 // Was our button held down or pressed?
272 int button_pressed = BUTTON_HELD(1000);
273 SpinDelay(300);
959baa89 274
9bea179a 275 // Button was held for a second, begin recording
276 if (button_pressed > 0)
277 {
278 LEDsoff();
279 LED(selected + 1, 0);
280 LED(LED_RED2, 0);
959baa89 281
9bea179a 282 // record
283 DbpString("Starting recording");
959baa89 284
9bea179a 285 // wait for button to be released
286 while(BUTTON_PRESS())
287 WDT_HIT();
959baa89 288
9bea179a 289 /* need this delay to prevent catching some weird data */
290 SpinDelay(500);
959baa89 291
9bea179a 292 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
293 DbpString("Recorded");
294 DbpIntegers(selected, high[selected], low[selected]);
959baa89 295
9bea179a 296 LEDsoff();
297 LED(selected + 1, 0);
298 // Finished recording
959baa89 299
9bea179a 300 // If we were previously playing, set playing off
301 // so next button push begins playing what we recorded
302 playing = 0;
959baa89 303 }
959baa89 304
9bea179a 305 // Change where to record (or begin playing)
306 else if (button_pressed)
307 {
308 // Next option if we were previously playing
309 if (playing)
310 selected = (selected + 1) % OPTS;
311 playing = !playing;
959baa89 312
9bea179a 313 LEDsoff();
314 LED(selected + 1, 0);
315
316 // Begin transmitting
317 if (playing)
959baa89 318 {
9bea179a 319 LED(LED_GREEN, 0);
320 DbpString("Playing");
321 // wait for button to be released
322 while(BUTTON_PRESS())
323 WDT_HIT();
324 DbpIntegers(selected, high[selected], low[selected]);
325 CmdHIDsimTAG(high[selected], low[selected], 0);
326 DbpString("Done playing");
327 if (BUTTON_HELD(1000) > 0)
955fc5e2 328 {
9bea179a 329 DbpString("Exiting");
330 LEDsoff();
331 return;
955fc5e2 332 }
9bea179a 333
334 /* We pressed a button so ignore it here with a delay */
335 SpinDelay(300);
336
337 // when done, we're done playing, move to next option
338 selected = (selected + 1) % OPTS;
339 playing = !playing;
340 LEDsoff();
341 LED(selected + 1, 0);
959baa89 342 }
9bea179a 343 else
344 while(BUTTON_PRESS())
345 WDT_HIT();
959baa89 346 }
959baa89 347 }
348}
349
9bea179a 350
351/*
352OBJECTIVE
353Listen and detect an external reader. Determine the best location
354for the antenna.
355
356INSTRUCTIONS:
357Inside the ListenReaderField() function, there is two mode.
358By default, when you call the function, you will enter mode 1.
359If you press the PM3 button one time, you will enter mode 2.
360If you press the PM3 button a second time, you will exit the function.
361
362DESCRIPTION OF MODE 1:
363This mode just listens for an external reader field and lights up green
364for HF and/or red for LF. This is the original mode of the detectreader
365function.
366
367DESCRIPTION OF MODE 2:
368This mode will visually represent, using the LEDs, the actual strength of the
369current compared to the maximum current detected. Basically, once you know
370what kind of external reader is present, it will help you spot the best location to place
371your antenna. You will probably not get some good results if there is a LF and a HF reader
372at the same place! :-)
373
374LIGHT SCHEME USED:
9bea179a 375*/
bea2a866 376static const char LIGHT_SCHEME[] = {
377 0x0, /* ---- | No field detected */
378 0x1, /* X--- | 14% of maximum current detected */
379 0x2, /* -X-- | 29% of maximum current detected */
380 0x4, /* --X- | 43% of maximum current detected */
381 0x8, /* ---X | 57% of maximum current detected */
382 0xC, /* --XX | 71% of maximum current detected */
383 0xE, /* -XXX | 86% of maximum current detected */
384 0xF, /* XXXX | 100% of maximum current detected */
385};
386static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
387
9bea179a 388void ListenReaderField(int limit)
959baa89 389{
bea2a866 390 int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0, lf_max;
9bea179a 391 int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max;
bea2a866 392 int mode=1, display_val, display_max, i;
959baa89 393
9bea179a 394#define LF_ONLY 1
395#define HF_ONLY 2
959baa89 396
bea2a866 397 LEDsoff();
959baa89 398
bea2a866 399 lf_av=lf_max=ReadAdc(ADC_CHAN_LF);
959baa89 400
bea2a866 401 if(limit != HF_ONLY) {
9bea179a 402 DbpString("LF 125/134 Baseline:");
403 DbpIntegers(lf_av,0,0);
404 lf_baseline= lf_av;
bea2a866 405 }
959baa89 406
9bea179a 407 hf_av=hf_max=ReadAdc(ADC_CHAN_HF);
959baa89 408
bea2a866 409 if (limit != LF_ONLY) {
9bea179a 410 DbpString("HF 13.56 Baseline:");
411 DbpIntegers(hf_av,0,0);
412 hf_baseline= hf_av;
bea2a866 413 }
959baa89 414
bea2a866 415 for(;;) {
9bea179a 416 if (BUTTON_PRESS()) {
417 SpinDelay(500);
418 switch (mode) {
419 case 1:
420 mode=2;
421 DbpString("Signal Strength Mode");
959baa89 422 break;
9bea179a 423 case 2:
424 default:
425 DbpString("Stopped");
bea2a866 426 LEDsoff();
9bea179a 427 return;
428 break;
429 }
430 }
431 WDT_HIT();
432
bea2a866 433 if (limit != HF_ONLY) {
434 if(mode==1) {
435 if (abs(lf_av - lf_baseline) > 10) LED_D_ON();
436 else LED_D_OFF();
437 }
438
9bea179a 439 ++lf_count;
440 lf_av_new= ReadAdc(ADC_CHAN_LF);
441 // see if there's a significant change
bea2a866 442 if(abs(lf_av - lf_av_new) > 10) {
9bea179a 443 DbpString("LF 125/134 Field Change:");
444 DbpIntegers(lf_av,lf_av_new,lf_count);
445 lf_av= lf_av_new;
bea2a866 446 if (lf_av > lf_max)
447 lf_max = lf_av;
9bea179a 448 lf_count= 0;
9bea179a 449 }
bea2a866 450 }
9bea179a 451
bea2a866 452 if (limit != LF_ONLY) {
453 if (mode == 1){
454 if (abs(hf_av - hf_baseline) > 10) LED_B_ON();
455 else LED_B_OFF();
9bea179a 456 }
bea2a866 457
9bea179a 458 ++hf_count;
459 hf_av_new= ReadAdc(ADC_CHAN_HF);
460 // see if there's a significant change
bea2a866 461 if(abs(hf_av - hf_av_new) > 10) {
9bea179a 462 DbpString("HF 13.56 Field Change:");
463 DbpIntegers(hf_av,hf_av_new,hf_count);
464 hf_av= hf_av_new;
465 if (hf_av > hf_max)
466 hf_max = hf_av;
467 hf_count= 0;
bea2a866 468 }
469 }
470
471 if(mode == 2) {
472 if (limit == LF_ONLY) {
473 display_val = lf_av;
474 display_max = lf_max;
475 } else if (limit == HF_ONLY) {
476 display_val = hf_av;
477 display_max = hf_max;
478 } else { /* Pick one at random */
479 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {
480 display_val = hf_av;
481 display_max = hf_max;
482 } else {
483 display_val = lf_av;
484 display_max = lf_max;
485 }
486 }
487 for (i=0; i<LIGHT_LEN; i++) {
488 if (display_val >= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) {
489 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();
490 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();
491 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();
492 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();
493 break;
959baa89 494 }
495 }
496 }
bea2a866 497 }
959baa89 498}
499
500void UsbPacketReceived(BYTE *packet, int len)
501{
502 UsbCommand *c = (UsbCommand *)packet;
503
504 switch(c->cmd) {
505 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
506 AcquireRawAdcSamples125k(c->ext1);
507 break;
508
509 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
510 ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
511 break;
512
513 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
514 AcquireRawAdcSamplesIso15693();
515 break;
f23e056d 516
517 case CMD_BUFF_CLEAR:
518 BufferClear();
519 break;
959baa89 520
521 case CMD_READER_ISO_15693:
522 ReaderIso15693(c->ext1);
523 break;
524
525 case CMD_SIMTAG_ISO_15693:
526 SimTagIso15693(c->ext1);
527 break;
528
529 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
530 AcquireRawAdcSamplesIso14443(c->ext1);
531 break;
fb25b483 532
533 case CMD_READ_SRI512_TAG:
534 ReadSRI512Iso14443(c->ext1);
535 break;
959baa89 536
537 case CMD_READER_ISO_14443a:
538 ReaderIso14443a(c->ext1);
539 break;
540
541 case CMD_SNOOP_ISO_14443:
542 SnoopIso14443();
543 break;
544
545 case CMD_SNOOP_ISO_14443a:
546 SnoopIso14443a();
547 break;
548
549 case CMD_SIMULATE_TAG_HF_LISTEN:
550 SimulateTagHfListen();
551 break;
552
553 case CMD_SIMULATE_TAG_ISO_14443:
554 SimulateIso14443Tag();
555 break;
556
557 case CMD_SIMULATE_TAG_ISO_14443a:
558 SimulateIso14443aTag(c->ext1, c->ext2); // ## Simulate iso14443a tag - pass tag type & UID
559 break;
560
561 case CMD_MEASURE_ANTENNA_TUNING:
562 MeasureAntennaTuning();
563 break;
564
7f348042 565 case CMD_LISTEN_READER_FIELD:
566 ListenReaderField(c->ext1);
567 break;
568
959baa89 569 case CMD_HID_DEMOD_FSK:
955fc5e2 570 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
959baa89 571 break;
572
573 case CMD_HID_SIM_TAG:
955fc5e2 574 CmdHIDsimTAG(c->ext1, c->ext2, 1); // Simulate HID tag by ID
959baa89 575 break;
576
577 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
578 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
579 SpinDelay(200);
580 LED_D_OFF(); // LED D indicates field ON or OFF
581 break;
582
9bea179a 583 case CMD_READ_TI_TYPE:
584 ReadTItag();
585 break;
586
587 case CMD_WRITE_TI_TYPE:
588 WriteTItag(c->ext1,c->ext2,c->ext3);
589 break;
590
7381e8f2 591 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {
959baa89 592 UsbCommand n;
593 if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
594 n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
595 } else {
596 n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
597 }
598 n.ext1 = c->ext1;
599 memcpy(n.d.asDwords, BigBuf+c->ext1, 12*sizeof(DWORD));
600 UsbSendPacket((BYTE *)&n, sizeof(n));
601 break;
602 }
603 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
604 BYTE *b = (BYTE *)BigBuf;
605 memcpy(b+c->ext1, c->d.asBytes, 48);
606 break;
607 }
608 case CMD_SIMULATE_TAG_125K:
609 LED_A_ON();
955fc5e2 610 SimulateTagLowFrequency(c->ext1, 1);
959baa89 611 LED_A_OFF();
612 break;
1dff8c42 613 case CMD_READ_MEM:
614 ReadMem(c->ext1);
615 break;
959baa89 616 case CMD_SET_LF_DIVISOR:
617 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
618 break;
619#ifdef WITH_LCD
7381e8f2 620 case CMD_LCD_RESET:
621 LCDReset();
622 break;
959baa89 623 case CMD_LCD:
624 LCDSend(c->ext1);
625 break;
626#endif
9bea179a 627 case CMD_SETUP_WRITE:
959baa89 628 case CMD_FINISH_WRITE:
629 case CMD_HARDWARE_RESET:
630 USB_D_PLUS_PULLUP_OFF();
631 SpinDelay(1000);
632 SpinDelay(1000);
633 RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;
634 for(;;) {
635 // We're going to reset, and the bootrom will take control.
636 }
637 break;
638
959baa89 639 default:
640 DbpString("unknown command");
641 break;
642 }
643}
644
645void AppMain(void)
646{
647 memset(BigBuf,0,sizeof(BigBuf));
648 SpinDelay(100);
649
693f7cf7 650 LED_D_OFF();
651 LED_C_OFF();
652 LED_B_OFF();
653 LED_A_OFF();
959baa89 654
655 UsbStart();
656
657 // The FPGA gets its clock from us from PCK0 output, so set that up.
658 PIO_PERIPHERAL_B_SEL = (1 << GPIO_PCK0);
659 PIO_DISABLE = (1 << GPIO_PCK0);
660 PMC_SYS_CLK_ENABLE = PMC_SYS_CLK_PROGRAMMABLE_CLK_0;
661 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
662 PMC_PROGRAMMABLE_CLK_0 = PMC_CLK_SELECTION_PLL_CLOCK |
663 PMC_CLK_PRESCALE_DIV_4;
664 PIO_OUTPUT_ENABLE = (1 << GPIO_PCK0);
665
666 // Reset SPI
667 SPI_CONTROL = SPI_CONTROL_RESET;
668 // Reset SSC
669 SSC_CONTROL = SSC_CONTROL_RESET;
670
671 // Load the FPGA image, which we have stored in our flash.
672 FpgaDownloadAndGo();
673
674#ifdef WITH_LCD
675
676 LCDInit();
677
678 // test text on different colored backgrounds
693f7cf7 679 LCDString(" The quick brown fox ", &FONT6x8,1,1+8*0,WHITE ,BLACK );
680 LCDString(" jumped over the ", &FONT6x8,1,1+8*1,BLACK ,WHITE );
681 LCDString(" lazy dog. ", &FONT6x8,1,1+8*2,YELLOW ,RED );
682 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8,1,1+8*3,RED ,GREEN );
683 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8,1,1+8*4,MAGENTA,BLUE );
684 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8,1,1+8*5,BLUE ,YELLOW);
685 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8,1,1+8*6,BLACK ,CYAN );
686 LCDString(" _+{}|:\\\"<>? ",&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
959baa89 687
688 // color bands
689 LCDFill(0, 1+8* 8, 132, 8, BLACK);
690 LCDFill(0, 1+8* 9, 132, 8, WHITE);
691 LCDFill(0, 1+8*10, 132, 8, RED);
692 LCDFill(0, 1+8*11, 132, 8, GREEN);
693 LCDFill(0, 1+8*12, 132, 8, BLUE);
694 LCDFill(0, 1+8*13, 132, 8, YELLOW);
695 LCDFill(0, 1+8*14, 132, 8, CYAN);
696 LCDFill(0, 1+8*15, 132, 8, MAGENTA);
697
698#endif
699
700 for(;;) {
50722269 701 UsbPoll(FALSE);
959baa89 702 WDT_HIT();
959baa89 703
955fc5e2 704 if (BUTTON_HELD(1000) > 0)
705 SamyRun();
959baa89 706 }
707}
Impressum, Datenschutz