E:\Project\MainBrain32_MZ\Display.c
   1 /*********************************************************************
   2     FileName:           Display.c
   3     Dependencies:       See #includes
   4     Processor:          PIC32MZ
   5     Hardware:           MainBrain MZ
   6     Complier:           XC32 4.40
   7     Author:             Larry Knight 2023
   8 /*********************************************************************
   9  
  10     Software License Agreement:
  11  
  12     Licensed under the Apache License, Version 2.0 (the "License");
  13     you may not use this file except in compliance with the License.
  14     You may obtain a copy of the License at
  15 
  16     http://www.apache.org/licenses/LICENSE-2.0
  17 
  18     Unless required by applicable law or agreed to in writing, software
  19     distributed under the License is distributed on an "AS IS" BASIS,
  20     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21     See the License for the specific language governing permissions and
  22     limitations under the License.
  23  
  24     Description:
  25         System Clock = 200 - 250 MHz
  26 
  27     File Description:
  28 
  29     Change History:
  30  
  31 /***********************************************************************/
  32 
  33 #include <string.h>
  34 #include <xc.h>
  35 #include "MainBrain.h"
  36 
  37 uint8_t back_level;
  38 int CanvasColor;
  39 int TextColor;
  40 unsigned ascii_char;
  41 int color1;
  42 int color2;
  43 uint16_t hchar;
  44 uint16_t vchar;
  45 uint8_t Display_Read;
  46 uint8_t disData[10];
  47 unsigned row_start;
  48 unsigned row_end;
  49 unsigned col_start;
  50 unsigned col_end;
  51 int t;
  52 
  53 void Backlight_Control(uint8_t back_level)
  54 {   
  55     //PWM Setup for backlight control
  56     //sets frequency
  57     PR2 = 300;
  58 
  59     OC5CONbits.OCTSEL = 0;  //select TMR2
  60     OC5CONbits.OCM = 6;     //PWM mode, no fault pin
  61     OC5CONbits.ON = 1;
  62 
  63     //specifies duty cycle in percent
  64     if((back_level <= 10) | (back_level >= 0))
  65     {
  66         if(back_level == 0)
  67         {
  68             OC5RS = 300;
  69         }
  70         if(back_level == 1)
  71         {
  72             OC5RS = 270;
  73         }
  74         if(back_level == 2)
  75         {
  76             OC5RS = 243;
  77         }
  78         if(back_level == 3)
  79         {
  80             OC5RS = 216;
  81         }
  82         if(back_level == 4)
  83         {
  84             OC5RS = 189;
  85         }
  86         if(back_level == 5)
  87         {
  88             OC5RS = 162;
  89         }
  90         if(back_level == 6)
  91         {
  92             OC5RS = 135;
  93         }
  94         if(back_level == 7)
  95         {
  96             OC5RS = 108;
  97         }
  98         if(back_level == 8)
  99         {
 100             OC5RS = 81;
 101         }
 102         if(back_level == 9)
 103         {
 104             OC5RS = 54;
 105         }
 106         if(back_level == 10)
 107         {
 108             OC5RS = 27;
 109         }
 110 
 111     }
 112 
 113     T2CONbits.ON = 1;
 114 
 115     return;
 116 }
 117 
 118 void Display_init(void)
 119 {
 120     //RG12 and RG14 = data bits D17 and D16
 121     TRISGbits.TRISG12 = 0;
 122     TRISGbits.TRISG14 = 0;
 123     PORTGbits.RG12 = 0;
 124     PORTGbits.RG14 = 0;
 125 
 126     //Configure Pin for D/C
 127     TRISBbits.TRISB1 = 0;
 128     PORTBbits.RB1 = 1;        
 129 
 130     //Select Display (/CS) 
 131     TRISAbits.TRISA9 = 0;
 132     PORTAbits.RA9 = 0;
 133 
 134     //Software RESET
 135     //RB1 = D/C 1=Data, 0=Command
 136     PORTBbits.RB1 = 0;
 137     PMDOUT = 0x01;
 138     while(PMMODEbits.BUSY == 1);
 139 
 140     //Select Display (/CS)    
 141     PORTAbits.RA9 = 1;
 142     
 143     //>120mS Delay
 144     //to allow display to complete reset
 145     //set Timer 5 prescaler /256
 146     Delay32(7, 65535);
 147 
 148      //Select Display (/CS)    
 149     PORTAbits.RA9 = 0;
 150 
 151     //SLPOUT
 152     //RB1 = D/C 1=Data, 0=Command
 153     PORTBbits.RB1 = 0;
 154     PMDOUT = 0x011;
 155     while(PMMODEbits.BUSY == 1);
 156 
 157     //Set pixel format = 16-bit
 158     //05h = 16-bit
 159     //06h = 18-bit
 160     //07h = 24-bit
 161     //RB1 = D/C 1=Data, 0=Command
 162     PORTBbits.RB1 = 0;
 163     PMDOUT = 0x03a;
 164     while(PMMODEbits.BUSY == 1);
 165     //RB1 = D/C 1=Data, 0=Command
 166     PORTBbits.RB1 = 1;
 167     PMDOUT = 0x55;
 168     while(PMMODEbits.BUSY == 1);
 169 
 170     //Set Screen Rotation
 171     //RB1 = D/C 1=Data, 0=Command
 172     PORTBbits.RB1 = 0;
 173 
 174     //MADCTL - Memory Access Control
 175     PMDOUT = 0x36;
 176     while(PMMODEbits.BUSY == 1);
 177 
 178     //RB1 = D/C 1=Data, 0=Command
 179     PORTBbits.RB1 = 1;
 180     //D7 (MY) this flips the screen vertically (upside down)
 181     //D6 (MX) this flips the screen horizontally (mirror)
 182     //D5 (MV) rotates 90 degrees counter clockwise
 183     //D4 (ML) keep default
 184     //D3 (RGB) 1=BGR. 0=RGB
 185     //D2 (reserved)
 186     //D1 (SS)
 187     //D0 (GS)
 188     //0x28 = wide screen, connector on righthand side
 189     //0xe8 = wide screen, connector on Lefthand side
 190     PMDOUT = 0x28;
 191     while(PMMODEbits.BUSY == 1);
 192 
 193     //Select Display (/CS)    
 194     PORTAbits.RA9 = 1;
 195 }
 196 
 197 //00h - no operation
 198 void Display_NOP(void)
 199 {
 200     //Select Display (/CS)    
 201     PORTAbits.RA9 = 0;
 202 
 203     //RB1 = D/C 1=Data, 0=Command
 204     PORTBbits.RB1 = 0;
 205 
 206     //Command 00h = NOP
 207     PMDOUT = 0x00;
 208     while(PMMODEbits.BUSY == 1);
 209 
 210     //Select Display (/CS)    
 211     PORTAbits.RA9 = 1;
 212 
 213     return;
 214 }
 215 
 216 //01 - software reset
 217 void Display_SWRESET(void)
 218 {
 219     //Select Display (/CS)    
 220     PORTAbits.RA9 = 0;
 221 
 222     //RB1 = D/C 1=Data, 0=Command
 223     PORTBbits.RB1 = 0;
 224 
 225     //Command 01h = SWRESET
 226     PMDOUT = 0x01;
 227     while(PMMODEbits.BUSY == 1);
 228 
 229     //Select Display (/CS)    
 230     PORTAbits.RA9 = 1;
 231 
 232     return;
 233 }
 234 
 235 //04h - Read Display Identification Information
 236 uint8_t Display_RDDIDIF(void)
 237 {
 238     //Select Display (/CS)    
 239     PORTAbits.RA9 = 0;
 240 
 241     //RB1 = D/C 1=Data, 0=Command
 242     PORTBbits.RB1 = 0;
 243 
 244     //Command 04h = RDDPM
 245     PMDOUT = 0x04;
 246     while(PMMODEbits.BUSY == 1);
 247 
 248     //RB1 = D/C 1=Data, 0=Command
 249     PORTBbits.RB1 = 1;
 250 
 251     //Dummy Read
 252     disData[0] = PMRDIN;
 253     while(PMMODEbits.BUSY == 1);
 254 
 255     //Read Display Data
 256     disData[1] = PMRDIN;
 257     while(PMMODEbits.BUSY == 1);
 258 
 259     disData[2] = PMRDIN;
 260     while(PMMODEbits.BUSY == 1);
 261     
 262     //Read Display Data
 263     disData[3] = PMRDIN;
 264     while(PMMODEbits.BUSY == 1);
 265 
 266     disData[4] = PMRDIN;
 267     while(PMMODEbits.BUSY == 1);
 268 
 269     //Select Display (/CS)    
 270     PORTAbits.RA9 = 1;
 271 }
 272 
 273 //05 - Read Number of the Errors on DSI
 274 void Display_RDNUMED(void)
 275 {
 276     //Select Display (/CS)  
 277     PORTAbits.RA9 = 0;
 278 
 279     //RB1 = D/C 1=Data, 0=Command
 280     PORTBbits.RB1 = 0;
 281 
 282     //Command 05h = RDDPM
 283     PMDOUT = 0x05;
 284     while(PMMODEbits.BUSY == 1);
 285 
 286     //RB1 = D/C 1=Data, 0=Command
 287     PORTBbits.RB1 = 1;
 288 
 289     //Dummy Read for PMP
 290     disData[0] = PMRDIN;
 291     while(PMMODEbits.BUSY == 1);
 292 
 293     //Dummy read for display
 294     disData[1] = PMRDIN;
 295     while(PMMODEbits.BUSY == 1);
 296 
 297     //Read Display Data
 298     disData[2] = PMRDIN;
 299     while(PMMODEbits.BUSY == 1);
 300 
 301     //Select Display (/CS)    
 302     PORTAbits.RA9 = 1;
 303 }
 304 
 305 //09h - Read Display Status
 306 void Display_RDDST(void)
 307 {
 308     //Select Display (/CS)  
 309     PORTAbits.RA9 = 0;
 310 
 311     //RB1 = D/C 1=Data, 0=Command
 312     PORTBbits.RB1 = 0;
 313 
 314     //Command 09h = RDDPM
 315     PMDOUT = 0x09;
 316     while(PMMODEbits.BUSY == 1);
 317 
 318     //RB1 = D/C 1=Data, 0=Command
 319     PORTBbits.RB1 = 1;
 320 
 321     //Dummy Read for PMP
 322     disData[0] = PMRDIN;
 323     while(PMMODEbits.BUSY == 1);
 324 
 325     //Dummy read for display
 326     disData[1] = PMRDIN;
 327     while(PMMODEbits.BUSY == 1);
 328 
 329     //Dummy read for Display
 330     disData[2] = PMRDIN;
 331     while(PMMODEbits.BUSY == 1);
 332     
 333     //Read Display Data
 334     disData[3] = PMRDIN;
 335     while(PMMODEbits.BUSY == 1);
 336 
 337     disData[4] = PMRDIN;
 338     while(PMMODEbits.BUSY == 1);
 339 
 340     disData[5] = PMRDIN;
 341     while(PMMODEbits.BUSY == 1);
 342 
 343     //Select Display (/CS)    
 344     PORTAbits.RA9 = 1;
 345 }
 346 
 347 //0Ah - read power mode
 348 void Display_RDDPM(void)
 349 {
 350     //Select Display (/CS)    
 351     PORTAbits.RA9 = 0;
 352 
 353     //RB1 = D/C 1=Data, 0=Command
 354     PORTBbits.RB1 = 0;
 355 
 356     //Command 0ah = RDDPM
 357     PMDOUT = 0x0a;
 358     while(PMMODEbits.BUSY == 1);
 359 
 360     //RB1 = D/C 1=Data, 0=Command
 361     PORTBbits.RB1 = 1;
 362 
 363     //Dummy Read for PMP
 364     disData[0] = PMRDIN;
 365     while(PMMODEbits.BUSY == 1);
 366 
 367     //Dummy read for display
 368     disData[1] = PMRDIN;
 369     while(PMMODEbits.BUSY == 1);
 370 
 371     //Read the Data
 372     disData[2] = PMRDIN;
 373     while(PMMODEbits.BUSY == 1);
 374     
 375     //Select Display (/CS)    
 376     PORTAbits.RA9 = 1;
 377 }
 378 
 379 //0Bh - read display MADCTL
 380 uint8_t Display_RDDMADCTL(void)
 381 {
 382     //Select Display (/CS)    
 383     PORTAbits.RA9 = 0;
 384 
 385     //RB1 = D/C 1=Data, 0=Command
 386     PORTBbits.RB1 = 0;
 387 
 388     //Command 0bh = RDDPM
 389     PMDOUT = 0x0b;
 390     while(PMMODEbits.BUSY == 1);
 391 
 392     //RB1 = D/C 1=Data, 0=Command
 393     PORTBbits.RB1 = 1;
 394 
 395     //Dummy Read for PMP
 396     disData[0] = PMRDIN;
 397     while(PMMODEbits.BUSY == 1);
 398 
 399     //Dummy read for display
 400     disData[1] = PMRDIN;
 401     while(PMMODEbits.BUSY == 1);
 402 
 403     //Read the Data
 404     disData[2] = PMRDIN;
 405     while(PMMODEbits.BUSY == 1);
 406     
 407     //Select Display (/CS)    
 408     PORTAbits.RA9 = 1;
 409 }
 410 
 411 //0Ch - get pixel format
 412 void Display_RDDCOLMOD(void)
 413 {
 414     //Select Display (/CS)    
 415     PORTAbits.RA9 = 0;
 416 
 417     //RB1 = D/C 1=Data, 0=Command
 418     PORTBbits.RB1 = 0;
 419 
 420     //Command 0ch = RDDCOLMOD
 421     PMDOUT = 0x0c;
 422     while(PMMODEbits.BUSY == 1);
 423 
 424     //RB1 = D/C 1=Data, 0=Command
 425     PORTBbits.RB1 = 1;
 426 
 427     //Dummy Read for PMP
 428     disData[0] = PMRDIN;
 429     while(PMMODEbits.BUSY == 1);
 430 
 431     //Dummy read for display
 432     disData[1] = PMRDIN;
 433     while(PMMODEbits.BUSY == 1);
 434 
 435     //Read the Data
 436     disData[2] = PMRDIN;
 437     while(PMMODEbits.BUSY == 1);
 438     
 439     //Select Display (/CS)    
 440     PORTAbits.RA9 = 1;
 441 }
 442 
 443 //0Dh - get display mode
 444 void Display_RDDIM(void)
 445 {
 446     //Select Display (/CS)    
 447     PORTAbits.RA9 = 0;
 448 
 449     //RB1 = D/C 1=Data, 0=Command
 450     PORTBbits.RB1 = 0;
 451 
 452     //Command 0dh = RDDIM
 453     PMDOUT = 0x0d;
 454     while(PMMODEbits.BUSY == 1);
 455 
 456     //RB1 = D/C 1=Data, 0=Command
 457     PORTBbits.RB1 = 1;
 458 
 459     //Dummy Read for PMP
 460     disData[0] = PMRDIN;
 461     while(PMMODEbits.BUSY == 1);
 462 
 463     //Dummy read for display
 464     disData[1] = PMRDIN;
 465     while(PMMODEbits.BUSY == 1);
 466 
 467     //Read the Data
 468     disData[2] = PMRDIN;
 469     while(PMMODEbits.BUSY == 1);
 470     
 471     //Select Display (/CS)    
 472     PORTAbits.RA9 = 1;
 473 }
 474 
 475 //0Eh - get signal mode
 476 void Display_RDDSM(void)
 477 {
 478     //Select Display (/CS)    
 479     PORTAbits.RA9 = 0;
 480 
 481     //RB1 = D/C 1=Data, 0=Command
 482     PORTBbits.RB1 = 0;
 483 
 484     //Command 0eh = RDDSM
 485     PMDOUT = 0x0e;
 486     while(PMMODEbits.BUSY == 1);
 487 
 488     //RB1 = D/C 1=Data, 0=Command
 489     PORTBbits.RB1 = 1;
 490 
 491     //Dummy Read for PMP
 492     disData[0] = PMRDIN;
 493     while(PMMODEbits.BUSY == 1);
 494 
 495     //Dummy read for display
 496     disData[1] = PMRDIN;
 497     while(PMMODEbits.BUSY == 1);
 498 
 499     //Read the Data
 500     disData[2] = PMRDIN;
 501     while(PMMODEbits.BUSY == 1);
 502     
 503     //Select Display (/CS)    
 504     PORTAbits.RA9 = 1;
 505 }
 506 
 507 //0Fh - get diagnostic result
 508 void Display_RDDSDR(void)
 509 {
 510     //Select Display (/CS)    
 511     PORTAbits.RA9 = 0;
 512 
 513     //RB1 = D/C 1=Data, 0=Command
 514     PORTBbits.RB1 = 0;
 515 
 516     //Command 0fh = RDDSDR
 517     PMDOUT = 0x0f;
 518     while(PMMODEbits.BUSY == 1);
 519 
 520     //RB1 = D/C 1=Data, 0=Command
 521     PORTBbits.RB1 = 1;
 522 
 523     //Dummy Read for PMP
 524     disData[0] = PMRDIN;
 525     while(PMMODEbits.BUSY == 1);
 526 
 527     //Dummy read for display
 528     disData[1] = PMRDIN;
 529     while(PMMODEbits.BUSY == 1);
 530 
 531     //Read the Data
 532     disData[2] = PMRDIN;
 533     while(PMMODEbits.BUSY == 1);
 534     
 535     //Select Display (/CS)    
 536     PORTAbits.RA9 = 1;
 537 }
 538 
 539 //10h - enter sleep mode
 540 void Display_SLPIN(void)
 541 {
 542     //Select Display (/CS)    
 543     PORTAbits.RA9 = 0;
 544 
 545     //RB1 = D/C 1=Data, 0=Command
 546     PORTBbits.RB1 = 0;
 547 
 548     //Command 10h = SLPIN
 549     PMDOUT = 0x10;
 550     while(PMMODEbits.BUSY == 1);
 551 
 552     //Select Display (/CS)    
 553     PORTAbits.RA9 = 1;
 554 }
 555 
 556 //11h - exit sleep mode
 557 void Display_SLPOUT(void)
 558 {
 559     //Select Display (/CS)    
 560     PORTAbits.RA9 = 0;
 561 
 562     //RB1 = D/C 1=Data, 0=Command
 563     PORTBbits.RB1 = 0;
 564 
 565     //Command 11h = SLPOUT
 566     PMDOUT = 0x11;
 567     while(PMMODEbits.BUSY == 1);
 568 
 569     //Select Display (/CS)    
 570     PORTAbits.RA9 = 1;
 571 }
 572 
 573 //12h - enter partial mode
 574 void Display_PTLON(void)
 575 {
 576     //Select Display (/CS)    
 577     PORTAbits.RA9 = 0;
 578 
 579     //RB1 = D/C 1=Data, 0=Command
 580     PORTBbits.RB1 = 0;
 581 
 582     //Command 12h = PTLON
 583     PMDOUT = 0x12;
 584     while(PMMODEbits.BUSY == 1);
 585 
 586     //Select Display (/CS)    
 587     PORTAbits.RA9 = 1;
 588 }
 589 
 590 //13h - enter normal mode
 591 void Display_NORON(void)
 592 {
 593     //Select Display (/CS)    
 594     PORTAbits.RA9 = 0;
 595 
 596     //RB1 = D/C 1=Data, 0=Command
 597     PORTBbits.RB1 = 0;
 598 
 599     //Command 13h = NORON
 600     PMDOUT = 0x13;
 601     while(PMMODEbits.BUSY == 1);
 602 
 603     //Select Display (/CS)    
 604     PORTAbits.RA9 = 1;
 605 }
 606 
 607 //20h - exit inversion mode
 608 void Display_INVOFF(void)
 609 {
 610     //Select Display (/CS)    
 611     PORTAbits.RA9 = 0;
 612 
 613     //RB1 = D/C 1=Data, 0=Command
 614     PORTBbits.RB1 = 0;
 615 
 616     //Command 20h = INVOFF
 617     PMDOUT = 0x20;
 618     while(PMMODEbits.BUSY == 1);
 619 
 620     //Select Display (/CS)    
 621     PORTAbits.RA9 = 1;
 622 }
 623 
 624 //21h - enter inversion mode
 625 void Display_INVON(void)
 626 {
 627     //Select Display (/CS)    
 628     PORTAbits.RA9 = 0;
 629 
 630     //RB1 = D/C 1=Data, 0=Command
 631     PORTBbits.RB1 = 0;
 632 
 633     //Command 21h = INVON
 634     PMDOUT = 0x21;
 635     while(PMMODEbits.BUSY == 1);
 636 
 637      //Select Display (/CS)    
 638     PORTAbits.RA9 = 1;
 639 }
 640 
 641 //22h - All Pixels OFF
 642 void Display_ALLPOFF(void)
 643 {
 644     //Select Display (/CS)    
 645     PORTAbits.RA9 = 0;
 646 
 647     //RB1 = D/C 1=Data, 0=Command
 648     PORTBbits.RB1 = 0;
 649 
 650     //Command 22h = INVON
 651     PMDOUT = 0x22;
 652     while(PMMODEbits.BUSY == 1);
 653 
 654      //Select Display (/CS)    
 655     PORTAbits.RA9 = 1;
 656 }
 657 
 658 //23h - All Pixels ON
 659 void Display_ALLPON(void)
 660 {
 661     //Select Display (/CS)    
 662     PORTAbits.RA9 = 0;
 663 
 664     //RB1 = D/C 1=Data, 0=Command
 665     PORTBbits.RB1 = 0;
 666 
 667     //Command 23h = INVON
 668     PMDOUT = 0x23;
 669     while(PMMODEbits.BUSY == 1);
 670 
 671      //Select Display (/CS)    
 672     PORTAbits.RA9 = 1;
 673 
 674    return;
 675 }
 676 
 677 //28h - display off
 678 void Display_DISPOFF(void)
 679 {
 680     //Select Display (/CS)    
 681     PORTAbits.RA9 = 0;
 682 
 683     //RB1 = D/C 1=Data, 0=Command
 684     PORTBbits.RB1 = 0;
 685 
 686     //Command 28h = DSPOFF
 687     PMDOUT = 0x28;
 688     while(PMMODEbits.BUSY == 1);
 689 
 690     //Select Display (/CS)    
 691     PORTAbits.RA9 = 1;
 692 
 693     return;
 694 }
 695 
 696 //29h - display on
 697 void Display_DISPON(void)
 698 {
 699     //Select Display (/CS)    
 700     PORTAbits.RA9 = 0;
 701 
 702     //RB1 = D/C 1=Data, 0=Command
 703     PORTBbits.RB1 = 0;
 704 
 705     //Command 29h = DISPON
 706     PMDOUT = 0x29;
 707     while(PMMODEbits.BUSY == 1);
 708 
 709     //Select Display (/CS)    
 710     PORTAbits.RA9 = 1;
 711 
 712     return;
 713 }
 714 
 715 //2a - set column address
 716 void Display_CASET(uint16_t col_start, uint16_t col_end)
 717 {
 718     if(col_end == 0)
 719     {
 720         col_end = col_start + 15;
 721     }
 722 
 723     //Select Display (/CS)    
 724     PORTAbits.RA9 = 0;
 725 
 726     //RB1 = D/C 1=Data, 0=Command
 727     PORTBbits.RB1 = 0;
 728 
 729     PMDOUT = 0x02a;
 730     while(PMMODEbits.BUSY == 1);
 731     //RB1 = D/C 1=Data, 0=Command
 732     PORTBbits.RB1 = 1;
 733     //break in to bytes HI and LO
 734     //Column Start
 735     //HI
 736     if(col_start > 0xff)
 737     {
 738         PMDOUT = 1;       
 739     }
 740     else
 741     {
 742         PMDOUT = 0;               
 743     }
 744     while(PMMODEbits.BUSY == 1);
 745     //LO
 746     PMDOUT = col_start;
 747     while(PMMODEbits.BUSY == 1);
 748 
 749     //Column End
 750     //HI
 751     if(col_end > 0xff)
 752     {
 753         PMDOUT = 1;       
 754     }
 755     else
 756     {
 757         PMDOUT = 0;               
 758     }
 759     while(PMMODEbits.BUSY == 1);
 760     //LO
 761     PMDOUT = col_end;
 762     while(PMMODEbits.BUSY == 1);
 763 
 764     //Select Display (/CS)    
 765     PORTAbits.RA9 = 1;
 766 
 767     return;
 768 }
 769 
 770 //2Bh - set row address
 771 void Display_RASET(unsigned row_start, unsigned row_end)
 772 {
 773     if(row_end == 0)
 774     {
 775         row_end = row_start + 21;
 776     }
 777 
 778     //Select Display (/CS)    
 779     PORTAbits.RA9 = 0;
 780 
 781     //RB1 = D/C 1=Data, 0=Command
 782     PORTBbits.RB1 = 0;
 783 
 784     PMDOUT = 0x02b;
 785     while(PMMODEbits.BUSY == 1);
 786     //RB1 = D/C 1=Data, 0=Command
 787     PORTBbits.RB1 = 1;
 788     //break in to bytes HI and LO
 789     //Row Start
 790     //HI
 791     if(row_start > 0xff)
 792     {
 793         PMDOUT = 1;       
 794     }
 795     else
 796     {
 797         PMDOUT = 0;               
 798     }
 799     while(PMMODEbits.BUSY == 1);
 800     //LO
 801     PMDOUT = row_start;
 802     while(PMMODEbits.BUSY == 1);
 803 
 804     //Row End
 805     //HI
 806     if(row_end > 0xff)
 807     {
 808         PMDOUT = 1;       
 809     }
 810     else
 811     {
 812         PMDOUT = 0;               
 813     }
 814     while(PMMODEbits.BUSY == 1);
 815     //LO
 816     PMDOUT = row_end;
 817     while(PMMODEbits.BUSY == 1);
 818 
 819     //Select Display (/CS)    
 820     PORTAbits.RA9 = 1;
 821 
 822     return;
 823 }
 824 
 825 //2Ch - memory write
 826 void Display_RAMWR(void)
 827 {
 828     //Select Display (/CS)    
 829     PORTAbits.RA9 = 0;
 830 
 831     //RB1 = D/C 1=Data, 0=Command
 832     PORTBbits.RB1 = 0;
 833 
 834     //Command 2Ch = RAMWR
 835     PMDOUT = 0x2C;
 836     while(PMMODEbits.BUSY == 1);
 837 
 838     //RB1 = D/C 1=Data, 0=Command
 839     PORTBbits.RB1 = 1;
 840 
 841     //pixel data is then written here
 842     //until another command is given
 843 
 844     //Select Display (/CS)    
 845     //PORTAbits.RA9 = 1;
 846 
 847     return;
 848 }
 849 
 850 //2Eh - memory read
 851 void Display_RAMRD(void)
 852 {
 853     //Select Display (/CS)    
 854     PORTAbits.RA9 = 0;
 855 
 856     //RB1 = D/C 1=Data, 0=Command
 857     PORTBbits.RB1 = 0;
 858 
 859     //Command 2eh = RDDSM
 860     PMDOUT = 0x2e;
 861     while(PMMODEbits.BUSY == 1);
 862 
 863     //RB1 = D/C 1=Data, 0=Command
 864     PORTBbits.RB1 = 1;
 865 
 866     //pixel data is then read here
 867     //until another command is given
 868     
 869     //Select Display (/CS)    
 870     //PORTAbits.RA9 = 1;
 871 
 872     return;
 873 }
 874 
 875 //30h - Set_partial_area
 876 void Display_PLTAR(unsigned SR_HI, unsigned SR_LO, unsigned ER_HI, unsigned ER_LO)
 877 {
 878     //Select Display (/CS)    
 879     PORTAbits.RA9 = 0;
 880 
 881     //RB1 = D/C 1=Data, 0=Command
 882     PORTBbits.RB1 = 0;
 883 
 884     //Command 30h
 885     PMDOUT = 0x30;
 886     while(PMMODEbits.BUSY == 1);
 887 
 888     //RB1 = D/C 1=Data, 0=Command
 889     PORTBbits.RB1 = 1;
 890 
 891     //Upper byte start row
 892     PMDOUT = SR_HI;
 893     while(PMMODEbits.BUSY == 1);
 894 
 895     //Lower byte start row
 896     PMDOUT = SR_LO;
 897     while(PMMODEbits.BUSY == 1);
 898 
 899     //Upper byte end row
 900     PMDOUT = ER_HI;
 901     while(PMMODEbits.BUSY == 1);
 902 
 903     //Upper byte end row
 904     PMDOUT = ER_LO;
 905     while(PMMODEbits.BUSY == 1);
 906 
 907     //Select Display (/CS)    
 908     PORTAbits.RA9 = 1;
 909 }
 910 
 911 //draws a rectangular block of colored pixels
 912 void Display_Rect(unsigned col_start, unsigned col_end, unsigned row_start, unsigned row_end, unsigned rect_color)
 913 {
 914     unsigned a = col_start;
 915     unsigned b = row_start;
 916     unsigned c = col_end;
 917     unsigned d = row_end;
 918 
 919     Display_CASET(col_start, col_end - 1);    
 920     Display_RASET(row_start, row_end - 1);
 921 
 922     Display_RAMWR();
 923 
 924     
 925     //Select Display (/CS)    
 926     PORTAbits.RA9 = 0;
 927 
 928     for(int i=0;i<(col_end - col_start) * (row_end - row_start); i++)
 929     {
 930         PMDOUT = rect_color;
 931         while(PMMODEbits.BUSY == 1);
 932         for(int i=0;i<5;i++);   
 933     }    
 934 
 935     //Select Display (/CS)    
 936     PORTAbits.RA9 = 1;
 937 
 938     col_start = a;
 939     row_start = b;
 940     col_end = c;
 941     row_end = d;
 942 }
 943 
 944 void Display_CLRSCN(int CanvasColor)
 945 {
 946     Display_CASET(0, 479);
 947     Display_RASET(0, 319);
 948     Display_RAMWR();
 949 
 950     for(int i=0;i<=153600;i++)
 951     {
 952         PMDOUT = CanvasColor;
 953         while(PMMODEbits.BUSY == 1);            
 954     }
 955 }
 956 
 957 //Writes a character to the screen
 958 void WriteChar(unsigned col_start, unsigned row_start, unsigned ascii_char, int TextColor, int CanvasColor)
 959 {
 960     //Makes sure no out of bounds
 961     if(ascii_char > 0x7e || ascii_char < 0x20)
 962     {
 963         ascii_char = 0x2a; // '*'
 964     }
 965 
 966     int x;
 967     int text_char = ascii_char - 32;
 968     int off_set = lut[text_char];
 969     int read = courier_new_10pt_bold[off_set];//courier_new_16pt_bold[off_set];
 970     int a = 0b10000000;
 971     int pixel = 0;
 972     int s = 0;
 973     int i;
 974 
 975     col_end = col_start + 15;
 976     row_end = row_start + 26;
 977     Display_CASET(col_start, col_end);
 978     Display_RASET(row_start, row_end);
 979 
 980     Display_RAMWR();
 981 
 982     for(s=0;s<=52;s++)
 983     {
 984         for(i=0;i<=7;i++)
 985         {
 986             x = read & a;
 987             if(x > 0)
 988             {
 989                 pixel = TextColor;
 990             }
 991             else
 992             {
 993                 pixel = CanvasColor;
 994             }
 995 
 996             //Select Display (/CS)    
 997             PORTAbits.RA9 = 0;
 998 
 999             PMDOUT = pixel;
1000             while(PMMODEbits.BUSY == 1);
1001 
1002             //Select Display (/CS)    
1003             PORTAbits.RA9 = 1;
1004 
1005             a = a / 2;
1006         }
1007         off_set++;
1008         read = courier_new_10pt_bold[off_set];
1009         a = 0b10000000;
1010     }
1011     //this keeps track of the horizontal position.
1012     hchar = hchar + 15;
1013 
1014     return;
1015 }
1016 
1017 //Writes a null terminated string from a previously defined array
1018 void WriteString(unsigned col_start, unsigned row_start, char array_name[], int TextColor, int CanvasColor)
1019 {
1020     int offset = 0;
1021 
1022     //must initialize test_char to something other than \0
1023     //so we might as well use the array data
1024     char test_char = array_name[offset];
1025 
1026     while(test_char != '\0')
1027     {
1028         test_char = array_name[offset];
1029 
1030         Display_CASET(col_start, col_start + 15);
1031 
1032         WriteChar(col_start, row_start, test_char, TextColor, CanvasColor);    
1033         offset++;       
1034         col_start = col_start + 15;
1035     }
1036     //cleans up the extra white space
1037     hchar = hchar - 15;
1038 }
1039 
1040 //Writes a character with 2 background colors for button text
1041 void WriteButtonChar(unsigned col_start, unsigned row_start, unsigned ascii_char, int TextColor, int color1, int color2)
1042 {
1043     //Makes sure no out of bounds
1044     if(ascii_char > 0x7F || ascii_char < 0)
1045     {
1046         ascii_char = 0x2a;
1047     }
1048 
1049     int x;
1050     int text_char = ascii_char - 32;
1051     int off_set = lut[text_char];
1052     int read = courier_new_10pt_bold[off_set];
1053     int a = 0b10000000;
1054     int pixel = 0;
1055     int s = 0;
1056     int i;
1057 
1058     col_end = col_start + 15;
1059     row_end = row_start + 21;
1060     Display_CASET(col_start, col_end);
1061     Display_RASET(row_start, row_end);
1062 
1063     Display_RAMWR();
1064 
1065     for(s=0;s<44;s++)
1066     {
1067         for(i=0;i<=7;i++)
1068         {
1069             x = read & a;
1070             if(x > 0)
1071             {
1072                 pixel = TextColor;
1073             }
1074             else
1075             {
1076                 if(s < 24)
1077                 {
1078                     pixel = color1;
1079                 }
1080                 else
1081                 {
1082                     pixel = color2;
1083                 }
1084             }
1085 
1086             //Select Display (/CS)    
1087             PORTAbits.RA9 = 0;
1088 
1089             PMDOUT = pixel;
1090             while(PMMODEbits.BUSY == 1);
1091 
1092             //Select Display (/CS)    
1093             PORTAbits.RA9 = 1;
1094 
1095             a = a / 2;
1096         }
1097         off_set++;
1098         read = courier_new_10pt_bold[off_set];
1099         a = 0b10000000;
1100     }
1101     //this keeps track of the horizontal position.
1102     hchar = hchar + 15;
1103     return;
1104 }
1105 
1106 //Writes a null terminated string from a previously defined array with button colors
1107 void WriteButtonString(unsigned col_start, unsigned row_start, char array_name[], int TextColor, int color1, int color2)
1108 {
1109     int offset = 0;
1110 
1111     //must initialize test_char to something other than \0
1112     //so we might as well use the array data
1113     char test_char = array_name[offset];
1114 
1115     while(test_char != '\0')
1116     {
1117         test_char = array_name[offset];
1118 
1119         Display_CASET(col_start, col_start + 15);
1120 
1121         WriteButtonChar(col_start, row_start, test_char, TextColor, color1, color2);   
1122         offset++;       
1123         col_start = col_start + 15;
1124     }
1125     //cleans up the extra white space
1126     hchar = hchar - 15;
1127 }
1128 
1129 void DrawButton(unsigned col_start, unsigned row_start, uint8_t length, uint8_t height, int color1, int color2, int border_color, char array_name[])
1130 {
1131     //Draw border
1132     //Display_Rect(20, 170, 50, 52, 0xad55);
1133     Display_Rect(col_start, col_start + length, row_start, row_start + 2, border_color);
1134     //Display_Rect(168, 170, 50, 100, 0xad55);
1135     Display_Rect((col_start + length) - 2, col_start + length, row_start, row_start + height, border_color);
1136     //Display_Rect(20, 170, 98, 100, 0xad55);
1137     Display_Rect(col_start, col_start + length, (row_start + height) - 2, row_start + height, border_color);
1138     //Display_Rect(20, 22, 50, 100, 0xad55);
1139     Display_Rect(col_start, col_start + 2, row_start, row_start + height, border_color);
1140 
1141     //Draw upper half
1142     //Display_Rect(colStart + 2, 168, 52, 75, 0xef7d);
1143     Display_Rect(col_start + 2, (col_start + length) - 2, row_start + 2, row_start + (height / 2), color1);
1144     //Draw lower half
1145     //Display_Rect(22, 168, 75, 98, 0xd6ba);
1146     Display_Rect(col_start + 2, (col_start + length) - 2, row_start + (height / 2), (row_start + height) - 2, color2);
1147 
1148     //Draw Button Text
1149     WriteButtonString(col_start + ((length - ((strlen(array_name) * 15))) / 2), row_start + 13, array_name, TextColor, color1, color2);//((length - strlen(array_name)) / 2)
1150 }
1151