1 //----------------------------------------------------------------------------- 
   2 // The main application code. This is the first thing called after start.c 
   4 // Jonathan Westhues, Mar 2006 
   5 // Edits by Gerhard de Koning Gans, Sep 2007 (##) 
   6 //----------------------------------------------------------------------------- 
  17 #define va_list __builtin_va_list 
  18 #define va_start __builtin_va_start 
  19 #define va_arg __builtin_va_arg 
  20 #define va_end __builtin_va_end 
  21 int kvsprintf(char const *fmt
, void *arg
, int radix
, va_list ap
); 
  23 //============================================================================= 
  24 // A buffer where we can queue things up to be sent through the FPGA, for 
  25 // any purpose (fake tag, as reader, whatever). We go MSB first, since that 
  26 // is the order in which they go out on the wire. 
  27 //============================================================================= 
  32 struct common_area common_area 
__attribute__((section(".commonarea"))); 
  34 void BufferClear(void) 
  36         memset(BigBuf
,0,sizeof(BigBuf
)); 
  37         DbpString("Buffer cleared"); 
  40 void ToSendReset(void) 
  46 void ToSendStuffBit(int b
) 
  50                 ToSend
[ToSendMax
] = 0; 
  55                 ToSend
[ToSendMax
] |= (1 << (7 - ToSendBit
)); 
  60         if(ToSendBit 
>= sizeof(ToSend
)) { 
  62                 DbpString("ToSendStuffBit overflowed!"); 
  66 //============================================================================= 
  67 // Debug print functions, to go out over USB, to the usual PC-side client. 
  68 //============================================================================= 
  70 void DbpString(char *str
) 
  72         /* this holds up stuff unless we're connected to usb */ 
  77         c
.cmd 
= CMD_DEBUG_PRINT_STRING
; 
  78         c
.arg
[0] = strlen(str
); 
  79         memcpy(c
.d
.asBytes
, str
, c
.arg
[0]); 
  81         UsbSendPacket((BYTE 
*)&c
, sizeof(c
)); 
  82         // TODO fix USB so stupid things like this aren't req'd 
  87 void DbpIntegers(int x1
, int x2
, int x3
) 
  89         /* this holds up stuff unless we're connected to usb */ 
  94         c
.cmd 
= CMD_DEBUG_PRINT_INTEGERS
; 
  99         UsbSendPacket((BYTE 
*)&c
, sizeof(c
)); 
 105 void Dbprintf(const char *fmt
, ...) { 
 106 // should probably limit size here; oh well, let's just use a big buffer 
 107         char output_string
[128]; 
 111         kvsprintf(fmt
, output_string
, 10, ap
); 
 114         DbpString(output_string
); 
 117 //----------------------------------------------------------------------------- 
 118 // Read an ADC channel and block till it completes, then return the result 
 119 // in ADC units (0 to 1023). Also a routine to average 32 samples and 
 121 //----------------------------------------------------------------------------- 
 122 static int ReadAdc(int ch
) 
 126         AT91C_BASE_ADC
->ADC_CR 
= AT91C_ADC_SWRST
; 
 127         AT91C_BASE_ADC
->ADC_MR 
= 
 128                 ADC_MODE_PRESCALE(32) | 
 129                 ADC_MODE_STARTUP_TIME(16) | 
 130                 ADC_MODE_SAMPLE_HOLD_TIME(8); 
 131         AT91C_BASE_ADC
->ADC_CHER 
= ADC_CHANNEL(ch
); 
 133         AT91C_BASE_ADC
->ADC_CR 
= AT91C_ADC_START
; 
 134         while(!(AT91C_BASE_ADC
->ADC_SR 
& ADC_END_OF_CONVERSION(ch
))) 
 136         d 
= AT91C_BASE_ADC
->ADC_CDR
[ch
]; 
 141 static int AvgAdc(int ch
) 
 146         for(i 
= 0; i 
< 32; i
++) { 
 150         return (a 
+ 15) >> 5; 
 153 void MeasureAntennaTuning(void) 
 155         BYTE 
*dest 
= (BYTE 
*)BigBuf
; 
 156         int i
, ptr 
= 0, adcval 
= 0, peak 
= 0, peakv 
= 0, peakf 
= 0;; 
 157         int vLf125 
= 0, vLf134 
= 0, vHf 
= 0;    // in mV 
 161         DbpString("Measuring antenna characteristics, please wait."); 
 162         memset(BigBuf
,0,sizeof(BigBuf
)); 
 165  * Sweeps the useful LF range of the proxmark from 
 166  * 46.8kHz (divisor=255) to 600kHz (divisor=19) and 
 167  * read the voltage in the antenna, the result left 
 168  * in the buffer is a graph which should clearly show 
 169  * the resonating frequency of your LF antenna 
 170  * ( hopefully around 95 if it is tuned to 125kHz!) 
 172         FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER
); 
 173         for (i
=255; i
>19; i
--) { 
 174                 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, i
); 
 176                 // Vref = 3.3V, and a 10000:240 voltage divider on the input 
 177                 // can measure voltages up to 137500 mV 
 178                 adcval 
= ((137500 * AvgAdc(ADC_CHAN_LF
)) >> 10); 
 179                 if (i
==95)      vLf125 
= adcval
; // voltage at 125Khz 
 180                 if (i
==89)      vLf134 
= adcval
; // voltage at 134Khz 
 182                 dest
[i
] = adcval
>>8; // scale int to fit in byte for graphing purposes 
 191         // Let the FPGA drive the high-frequency antenna around 13.56 MHz. 
 192         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
); 
 194         // Vref = 3300mV, and an 10:1 voltage divider on the input 
 195         // can measure voltages up to 33000 mV 
 196         vHf 
= (33000 * AvgAdc(ADC_CHAN_HF
)) >> 10; 
 198         c
.cmd 
= CMD_MEASURED_ANTENNA_TUNING
; 
 199         c
.arg
[0] = (vLf125 
<< 0) | (vLf134 
<< 16); 
 201         c
.arg
[2] = peakf 
| (peakv 
<< 16); 
 202         UsbSendPacket((BYTE 
*)&c
, sizeof(c
)); 
 205 void SimulateTagHfListen(void) 
 207         BYTE 
*dest 
= (BYTE 
*)BigBuf
; 
 208         int n 
= sizeof(BigBuf
); 
 213         // We're using this mode just so that I can test it out; the simulated 
 214         // tag mode would work just as well and be simpler. 
 215         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR 
| FPGA_HF_READER_RX_XCORR_848_KHZ 
| FPGA_HF_READER_RX_XCORR_SNOOP
); 
 217         // We need to listen to the high-frequency, peak-detected path. 
 218         SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); 
 224                 if(AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_TXRDY
)) { 
 225                         AT91C_BASE_SSC
->SSC_THR 
= 0xff; 
 227                 if(AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_RXRDY
)) { 
 228                         BYTE r 
= (BYTE
)AT91C_BASE_SSC
->SSC_RHR
; 
 248         DbpString("simulate tag (now type bitsamples)"); 
 251 void ReadMem(int addr
) 
 253         const DWORD 
*data 
= ((DWORD 
*)addr
); 
 255         Dbprintf("Reading memory at address %x: %02x %02x %02x %02x %02x %02x %02x %02x", 
 256                 addr
, data
[0], data
[1], data
[2], data
[3], data
[4], data
[5], data
[6], data
[7]); 
 259 /* osimage version information is linked in */ 
 260 extern struct version_information version_information
; 
 261 /* bootrom version information is pointed to from _bootphase1_version_pointer */ 
 262 extern char *_bootphase1_version_pointer
, _flash_start
, _flash_end
; 
 263 void SendVersion(void) 
 265         char temp
[48]; /* Limited data payload in USB packets */ 
 266         DbpString("Prox/RFID mark3 RFID instrument"); 
 268         /* Try to find the bootrom version information. Expect to find a pointer at  
 269          * symbol _bootphase1_version_pointer, perform slight sanity checks on the 
 270          * pointer, then use it. 
 272         char *bootrom_version 
= *(char**)&_bootphase1_version_pointer
; 
 273         if( bootrom_version 
< &_flash_start 
|| bootrom_version 
>= &_flash_end 
) { 
 274                 DbpString("bootrom version information appears invalid"); 
 276                 FormatVersionInformation(temp
, sizeof(temp
), "bootrom: ", bootrom_version
); 
 280         FormatVersionInformation(temp
, sizeof(temp
), "os: ", &version_information
); 
 283         FpgaGatherVersion(temp
, sizeof(temp
)); 
 288 // samy's sniff and repeat routine 
 291         DbpString("Stand-alone mode! No PC necessary."); 
 293         // 3 possible options? no just 2 for now 
 296         int high
[OPTS
], low
[OPTS
]; 
 298         // Oooh pretty -- notify user we're in elite samy mode now 
 300         LED(LED_ORANGE
, 200); 
 302         LED(LED_ORANGE
, 200); 
 304         LED(LED_ORANGE
, 200); 
 306         LED(LED_ORANGE
, 200); 
 312         // Turn on selected LED 
 313         LED(selected 
+ 1, 0); 
 320                 // Was our button held down or pressed? 
 321                 int button_pressed 
= BUTTON_HELD(1000); 
 324                 // Button was held for a second, begin recording 
 325                 if (button_pressed 
> 0) 
 328                         LED(selected 
+ 1, 0); 
 332                         DbpString("Starting recording"); 
 334                         // wait for button to be released 
 335                         while(BUTTON_PRESS()) 
 338                         /* need this delay to prevent catching some weird data */ 
 341                         CmdHIDdemodFSK(1, &high
[selected
], &low
[selected
], 0); 
 342                         Dbprintf("Recorded %x %x %x", selected
, high
[selected
], low
[selected
]); 
 345                         LED(selected 
+ 1, 0); 
 346                         // Finished recording 
 348                         // If we were previously playing, set playing off 
 349                         // so next button push begins playing what we recorded 
 353                 // Change where to record (or begin playing) 
 354                 else if (button_pressed
) 
 356                         // Next option if we were previously playing 
 358                                 selected 
= (selected 
+ 1) % OPTS
; 
 362                         LED(selected 
+ 1, 0); 
 364                         // Begin transmitting 
 368                                 DbpString("Playing"); 
 369                                 // wait for button to be released 
 370                                 while(BUTTON_PRESS()) 
 372                                 Dbprintf("%x %x %x", selected
, high
[selected
], low
[selected
]); 
 373                                 CmdHIDsimTAG(high
[selected
], low
[selected
], 0); 
 374                                 DbpString("Done playing"); 
 375                                 if (BUTTON_HELD(1000) > 0) 
 377                                         DbpString("Exiting"); 
 382                                 /* We pressed a button so ignore it here with a delay */ 
 385                                 // when done, we're done playing, move to next option 
 386                                 selected 
= (selected 
+ 1) % OPTS
; 
 389                                 LED(selected 
+ 1, 0); 
 392                                 while(BUTTON_PRESS()) 
 401 Listen and detect an external reader. Determine the best location 
 405 Inside the ListenReaderField() function, there is two mode. 
 406 By default, when you call the function, you will enter mode 1. 
 407 If you press the PM3 button one time, you will enter mode 2. 
 408 If you press the PM3 button a second time, you will exit the function. 
 410 DESCRIPTION OF MODE 1: 
 411 This mode just listens for an external reader field and lights up green 
 412 for HF and/or red for LF. This is the original mode of the detectreader 
 415 DESCRIPTION OF MODE 2: 
 416 This mode will visually represent, using the LEDs, the actual strength of the 
 417 current compared to the maximum current detected. Basically, once you know 
 418 what kind of external reader is present, it will help you spot the best location to place 
 419 your antenna. You will probably not get some good results if there is a LF and a HF reader 
 420 at the same place! :-) 
 424 static const char LIGHT_SCHEME
[] = { 
 425                 0x0, /* ----     | No field detected */ 
 426                 0x1, /* X---     | 14% of maximum current detected */ 
 427                 0x2, /* -X--     | 29% of maximum current detected */ 
 428                 0x4, /* --X-     | 43% of maximum current detected */ 
 429                 0x8, /* ---X     | 57% of maximum current detected */ 
 430                 0xC, /* --XX     | 71% of maximum current detected */ 
 431                 0xE, /* -XXX     | 86% of maximum current detected */ 
 432                 0xF, /* XXXX     | 100% of maximum current detected */ 
 434 static const int LIGHT_LEN 
= sizeof(LIGHT_SCHEME
)/sizeof(LIGHT_SCHEME
[0]); 
 436 void ListenReaderField(int limit
) 
 438         int lf_av
, lf_av_new
, lf_baseline
= 0, lf_count
= 0, lf_max
; 
 439         int hf_av
, hf_av_new
,  hf_baseline
= 0, hf_count
= 0, hf_max
; 
 440         int mode
=1, display_val
, display_max
, i
; 
 447         lf_av
=lf_max
=ReadAdc(ADC_CHAN_LF
); 
 449         if(limit 
!= HF_ONLY
) { 
 450                 Dbprintf("LF 125/134 Baseline: %d", lf_av
); 
 454         hf_av
=hf_max
=ReadAdc(ADC_CHAN_HF
); 
 456         if (limit 
!= LF_ONLY
) { 
 457                 Dbprintf("HF 13.56 Baseline: %d", hf_av
); 
 462                 if (BUTTON_PRESS()) { 
 467                                         DbpString("Signal Strength Mode"); 
 471                                         DbpString("Stopped"); 
 479                 if (limit 
!= HF_ONLY
) { 
 481                                 if (abs(lf_av 
- lf_baseline
) > 10) LED_D_ON(); 
 486                         lf_av_new
= ReadAdc(ADC_CHAN_LF
); 
 487                         // see if there's a significant change 
 488                         if(abs(lf_av 
- lf_av_new
) > 10) { 
 489                                 Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av
, lf_av_new
, lf_count
); 
 497                 if (limit 
!= LF_ONLY
) { 
 499                                 if (abs(hf_av 
- hf_baseline
) > 10) LED_B_ON(); 
 504                         hf_av_new
= ReadAdc(ADC_CHAN_HF
); 
 505                         // see if there's a significant change 
 506                         if(abs(hf_av 
- hf_av_new
) > 10) { 
 507                                 Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av
, hf_av_new
, hf_count
); 
 516                         if (limit 
== LF_ONLY
) { 
 518                                 display_max 
= lf_max
; 
 519                         } else if (limit 
== HF_ONLY
) { 
 521                                 display_max 
= hf_max
; 
 522                         } else { /* Pick one at random */ 
 523                                 if( (hf_max 
- hf_baseline
) > (lf_max 
- lf_baseline
) ) { 
 525                                         display_max 
= hf_max
; 
 528                                         display_max 
= lf_max
; 
 531                         for (i
=0; i
<LIGHT_LEN
; i
++) { 
 532                                 if (display_val 
>= ((display_max
/LIGHT_LEN
)*i
) && display_val 
<= ((display_max
/LIGHT_LEN
)*(i
+1))) { 
 533                                         if (LIGHT_SCHEME
[i
] & 0x1) LED_C_ON(); else LED_C_OFF(); 
 534                                         if (LIGHT_SCHEME
[i
] & 0x2) LED_A_ON(); else LED_A_OFF(); 
 535                                         if (LIGHT_SCHEME
[i
] & 0x4) LED_B_ON(); else LED_B_OFF(); 
 536                                         if (LIGHT_SCHEME
[i
] & 0x8) LED_D_ON(); else LED_D_OFF(); 
 544 void UsbPacketReceived(BYTE 
*packet
, int len
) 
 546         UsbCommand 
*c 
= (UsbCommand 
*)packet
; 
 550                 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
: 
 551                         AcquireRawAdcSamples125k(c
->arg
[0]); 
 556                 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
: 
 557                         ModThenAcquireRawAdcSamples125k(c
->arg
[0],c
->arg
[1],c
->arg
[2],c
->d
.asBytes
); 
 562                 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693
: 
 563                         AcquireRawAdcSamplesIso15693(); 
 572                 case CMD_READER_ISO_15693
: 
 573                         ReaderIso15693(c
->arg
[0]); 
 577                 case CMD_READER_LEGIC_RF
: 
 582                 case CMD_SIMTAG_ISO_15693
: 
 583                         SimTagIso15693(c
->arg
[0]); 
 587 #ifdef WITH_ISO14443b 
 588                 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
: 
 589                         AcquireRawAdcSamplesIso14443(c
->arg
[0]); 
 593 #ifdef WITH_ISO14443b 
 594                 case CMD_READ_SRI512_TAG
: 
 595                         ReadSRI512Iso14443(c
->arg
[0]); 
 597                case CMD_READ_SRIX4K_TAG
: 
 598                        ReadSRIX4KIso14443(c
->arg
[0]); 
 602 #ifdef WITH_ISO14443a 
 603                 case CMD_READER_ISO_14443a
: 
 604                         ReaderIso14443a(c
->arg
[0]); 
 608 #ifdef WITH_ISO14443a 
 609                 case CMD_READER_MIFARE
: 
 610                         ReaderMifare(c
->arg
[0]); 
 614 #ifdef WITH_ISO14443b 
 615                 case CMD_SNOOP_ISO_14443
: 
 620 #ifdef WITH_ISO14443a 
 621                 case CMD_SNOOP_ISO_14443a
: 
 626                 case CMD_SIMULATE_TAG_HF_LISTEN
: 
 627                         SimulateTagHfListen(); 
 630 #ifdef WITH_ISO14443b 
 631                 case CMD_SIMULATE_TAG_ISO_14443
: 
 632                         SimulateIso14443Tag(); 
 636 #ifdef WITH_ISO14443a 
 637                 case CMD_SIMULATE_TAG_ISO_14443a
: 
 638                         SimulateIso14443aTag(c
->arg
[0], c
->arg
[1]);  // ## Simulate iso14443a tag - pass tag type & UID 
 642                 case CMD_MEASURE_ANTENNA_TUNING
: 
 643                         MeasureAntennaTuning(); 
 646                 case CMD_LISTEN_READER_FIELD
: 
 647                         ListenReaderField(c
->arg
[0]); 
 651                 case CMD_HID_DEMOD_FSK
: 
 652                         CmdHIDdemodFSK(0, 0, 0, 1);                             // Demodulate HID tag 
 657                 case CMD_HID_SIM_TAG
: 
 658                         CmdHIDsimTAG(c
->arg
[0], c
->arg
[1], 1);                                  // Simulate HID tag by ID 
 662                 case CMD_FPGA_MAJOR_MODE_OFF
:           // ## FPGA Control 
 663                         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
 665                         LED_D_OFF(); // LED D indicates field ON or OFF 
 669                 case CMD_READ_TI_TYPE
: 
 675                 case CMD_WRITE_TI_TYPE
: 
 676                         WriteTItag(c
->arg
[0],c
->arg
[1],c
->arg
[2]); 
 680                 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
: { 
 682                         if(c
->cmd 
== CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K
) { 
 683                                 n
.cmd 
= CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
; 
 685                                 n
.cmd 
= CMD_DOWNLOADED_RAW_BITS_TI_TYPE
; 
 687                         n
.arg
[0] = c
->arg
[0]; 
 688                         memcpy(n
.d
.asDwords
, BigBuf
+c
->arg
[0], 12*sizeof(DWORD
)); 
 689                         UsbSendPacket((BYTE 
*)&n
, sizeof(n
)); 
 693                 case CMD_DOWNLOADED_SIM_SAMPLES_125K
: { 
 694                         BYTE 
*b 
= (BYTE 
*)BigBuf
; 
 695                         memcpy(b
+c
->arg
[0], c
->d
.asBytes
, 48); 
 700                 case CMD_SIMULATE_TAG_125K
: 
 702                         SimulateTagLowFrequency(c
->arg
[0], 1); 
 711                 case CMD_SET_LF_DIVISOR
: 
 712                         FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, c
->arg
[0]); 
 715                 case CMD_SET_ADC_MUX
: 
 717                                 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD
); break; 
 718                                 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW
); break; 
 719                                 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); break; 
 720                                 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW
); break; 
 729                 case CMD_LF_SIMULATE_BIDIR
: 
 730                         SimulateTagLowFrequencyBidir(c
->arg
[0], c
->arg
[1]); 
 742                 case CMD_SETUP_WRITE
: 
 743                 case CMD_FINISH_WRITE
: 
 744                 case CMD_HARDWARE_RESET
: 
 745                         USB_D_PLUS_PULLUP_OFF(); 
 748                         AT91C_BASE_RSTC
->RSTC_RCR 
= RST_CONTROL_KEY 
| AT91C_RSTC_PROCRST
; 
 750                                 // We're going to reset, and the bootrom will take control. 
 754                 case CMD_START_FLASH
: 
 755                         if(common_area
.flags
.bootrom_present
) { 
 756                                 common_area
.command 
= COMMON_AREA_COMMAND_ENTER_FLASH_MODE
; 
 758                         USB_D_PLUS_PULLUP_OFF(); 
 759                         AT91C_BASE_RSTC
->RSTC_RCR 
= RST_CONTROL_KEY 
| AT91C_RSTC_PROCRST
; 
 763                 case CMD_DEVICE_INFO
: { 
 765                         c
.cmd 
= CMD_DEVICE_INFO
; 
 766                         c
.arg
[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT 
| DEVICE_INFO_FLAG_CURRENT_MODE_OS
; 
 767                         if(common_area
.flags
.bootrom_present
) c
.arg
[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT
; 
 768                         UsbSendPacket((BYTE
*)&c
, sizeof(c
)); 
 772                         DbpString("unknown command"); 
 777 void  __attribute__((noreturn
)) AppMain(void) 
 781         if(common_area
.magic 
!= COMMON_AREA_MAGIC 
|| common_area
.version 
!= 1) { 
 782                 /* Initialize common area */ 
 783                 memset(&common_area
, 0, sizeof(common_area
)); 
 784                 common_area
.magic 
= COMMON_AREA_MAGIC
; 
 785                 common_area
.version 
= 1; 
 787         common_area
.flags
.osimage_present 
= 1; 
 796         // The FPGA gets its clock from us from PCK0 output, so set that up. 
 797         AT91C_BASE_PIOA
->PIO_BSR 
= GPIO_PCK0
; 
 798         AT91C_BASE_PIOA
->PIO_PDR 
= GPIO_PCK0
; 
 799         AT91C_BASE_PMC
->PMC_SCER 
= AT91C_PMC_PCK0
; 
 800         // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz 
 801         AT91C_BASE_PMC
->PMC_PCKR
[0] = AT91C_PMC_CSS_PLL_CLK 
| 
 802                 AT91C_PMC_PRES_CLK_4
; 
 803         AT91C_BASE_PIOA
->PIO_OER 
= GPIO_PCK0
; 
 806         AT91C_BASE_SPI
->SPI_CR 
= AT91C_SPI_SWRST
; 
 808         AT91C_BASE_SSC
->SSC_CR 
= AT91C_SSC_SWRST
; 
 810         // Load the FPGA image, which we have stored in our flash. 
 817         // test text on different colored backgrounds 
 818         LCDString(" The quick brown fox  ",     (char *)&FONT6x8
,1,1+8*0,WHITE  
,BLACK 
); 
 819         LCDString("  jumped over the     ",     (char *)&FONT6x8
,1,1+8*1,BLACK  
,WHITE 
); 
 820         LCDString("     lazy dog.        ",     (char *)&FONT6x8
,1,1+8*2,YELLOW 
,RED   
); 
 821         LCDString(" AaBbCcDdEeFfGgHhIiJj ",     (char *)&FONT6x8
,1,1+8*3,RED    
,GREEN 
); 
 822         LCDString(" KkLlMmNnOoPpQqRrSsTt ",     (char *)&FONT6x8
,1,1+8*4,MAGENTA
,BLUE  
); 
 823         LCDString("UuVvWwXxYyZz0123456789",     (char *)&FONT6x8
,1,1+8*5,BLUE   
,YELLOW
); 
 824         LCDString("`-=[]_;',./~!@#$%^&*()",     (char *)&FONT6x8
,1,1+8*6,BLACK  
,CYAN  
); 
 825         LCDString("     _+{}|:\\\"<>?     ",(char *)&FONT6x8
,1,1+8*7,BLUE  
,MAGENTA
); 
 828         LCDFill(0, 1+8* 8, 132, 8, BLACK
); 
 829         LCDFill(0, 1+8* 9, 132, 8, WHITE
); 
 830         LCDFill(0, 1+8*10, 132, 8, RED
); 
 831         LCDFill(0, 1+8*11, 132, 8, GREEN
); 
 832         LCDFill(0, 1+8*12, 132, 8, BLUE
); 
 833         LCDFill(0, 1+8*13, 132, 8, YELLOW
); 
 834         LCDFill(0, 1+8*14, 132, 8, CYAN
); 
 835         LCDFill(0, 1+8*15, 132, 8, MAGENTA
); 
 844                 if (BUTTON_HELD(1000) > 0)