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