1 /** 2 * @file hal_lcd.c 3 * 4 * Copyright 2008 Texas Instruments, Inc. 5 ***************************************************************************/ 6 7 #include "hal_lcd.h" 8 9 #include <msp430x54x.h> 10 11 #include "hal_compat.h" 12 #include "hal_lcd_fonts.h" 13 #include "hal_board.h" 14 15 static unsigned char LcdInitMacro[]={ 16 0x74,0x00,0x00,0x76,0x00,0x01, // R00 start oscillation 17 0x74,0x00,0x01,0x76,0x00,0x0D, // R01 driver output control 18 0x74,0x00,0x02,0x76,0x00,0x4C, // R02 LCD - driving waveform control 19 0x74,0x00,0x03,0x76,0x12,0x14, // R03 Power control 20 0x74,0x00,0x04,0x76,0x04,0x66, // R04 Contrast control 21 0x74,0x00,0x05,0x76,0x00,0x10, // R05 Entry mode 22 0x74,0x00,0x06,0x76,0x00,0x00, // R06 RAM data write mask 23 0x74,0x00,0x07,0x76,0x00,0x15, // R07 Display control 24 0x74,0x00,0x08,0x76,0x00,0x03, // R08 Cursor Control 25 0x74,0x00,0x09,0x76,0x00,0x00, // R09 RAM data write mask 26 0x74,0x00,0x0A,0x76,0x00,0x15, // R0A 27 0x74,0x00,0x0B,0x76,0x00,0x03, // R0B Horizontal Cursor Position 28 0x74,0x00,0x0C,0x76,0x00,0x03, // R0C Vertical Cursor Position 29 0x74,0x00,0x0D,0x76,0x00,0x00, // R0D 30 0x74,0x00,0x0E,0x76,0x00,0x15, // R0E 31 0x74,0x00,0x0F,0x76,0x00,0x03, // R0F 32 0x74,0x00,0x10,0x76,0x00,0x15, // R0E 33 0x74,0x00,0x11,0x76,0x00,0x03, // R0F 34 }; 35 36 static unsigned char Read_Block_Address_Macro[]= {0x74,0x00,0x12,0x77,0x00,0x00}; 37 static unsigned char Draw_Block_Value_Macro[]={0x74,0x00,0x12,0x76,0xFF,0xFF}; 38 static unsigned char Draw_Block_Address_Macro[]={0x74,0x00,0x11,0x76,0x00,0x00}; 39 40 static unsigned int LcdAddress = 0, LcdTableAddress = 0; 41 static unsigned char backlight = 8; 42 static int LCD_MEM[110*17]; 43 44 /************************************************************************ 45 * @brief Sends 3+3 bytes of data to the LCD using the format specified 46 * by the LCD Guide. 47 * 48 * @param Data[] Data array for transmission 49 * 50 * @return none 51 *************************************************************************/ 52 void halLcdSendCommand(unsigned char Data[]) 53 { 54 unsigned char i; 55 56 LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer 57 for ( i = 0; i < 6; i++ ) 58 { 59 while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG 60 UCB2TXBUF = Data[i]; // Load data 61 62 while (UCB2STAT & UCBUSY); 63 64 if (i == 2) //Pull CS up after 3 bytes 65 { 66 LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer 67 LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer 68 } 69 } 70 LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer 71 } 72 73 /************************************************************************ 74 * @brief Initializes the USCI module, LCD device for communication. 75 * 76 * - Sets up the SPI2C Communication Module 77 * - Performs Hitachi LCD Initialization Procedure 78 * 79 * @param none 80 * 81 * @return none 82 *************************************************************************/ 83 void halLcdInit(void) 84 { 85 volatile unsigned int i=0; 86 87 LCD_CS_RST_OUT |= LCD_CS_PIN | LCD_RESET_PIN ; 88 LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ; 89 90 LCD_COMM_SEL |= LCD_BACKLIGHT_PIN; 91 92 LCD_CS_RST_OUT &= ~LCD_RESET_PIN; // Reset LCD 93 __delay_cycles(0x47FF); //Reset Pulse 94 LCD_CS_RST_OUT |= LCD_RESET_PIN; 95 96 // UCLK,MOSI setup, SOMI cleared 97 P9SEL |= BIT1 + BIT3; 98 P9SEL &= ~BIT2; 99 P9DIR |= BIT1 + BIT3; 100 P9DIR &= ~BIT2; 101 102 /* Initialize USCI state machine */ 103 UCB2CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master 104 UCB2CTL1 |= UCSSEL_2; // SMCLK 105 UCB2BR0 = 3; 106 UCB2BR1 = 0; 107 UCB2CTL1 &= ~UCSWRST; 108 UCB2IFG &= ~UCRXIFG; 109 110 // LCD Initialization Routine Using Predefined Macros 111 while (i < 8*6) 112 { 113 halLcdSendCommand(&LcdInitMacro[i]); 114 i += 6; 115 } 116 halLcdActive(); 117 } 118 119 /************************************************************************ 120 * @brief Shuts down the LCD display and hdisables the USCI communication. 121 * 122 * @param none 123 * 124 * @return none 125 *************************************************************************/ 126 void halLcdShutDown(void) 127 { 128 halLcdStandby(); 129 130 LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ; 131 LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN ); 132 LCD_CS_RST_OUT &= ~LCD_RESET_PIN; 133 134 P9SEL &= ~(BIT1 + BIT3 + BIT2); 135 P9DIR |= BIT1 + BIT3 + BIT2; 136 P9OUT &= ~(BIT1 + BIT3 + BIT2); 137 138 UCB2CTL0 = UCSWRST; 139 } 140 141 /************************************************************************ 142 * @brief Initializes the LCD backlight PWM signal. 143 * 144 * @param none 145 * 146 * @return none 147 * 148 *************************************************************************/ 149 void halLcdBackLightInit(void) 150 { 151 LCD_COMM_DIR |= LCD_BACKLIGHT_PIN; 152 LCD_COMM_OUT |= LCD_BACKLIGHT_PIN; 153 154 LCD_COMM_SEL |= LCD_BACKLIGHT_PIN; 155 TA0CCTL3 = OUTMOD_7; 156 TA0CCR3 = TA0CCR0 >> 1 ; 157 backlight = 8; 158 159 TA0CCR0 = 400; 160 TA0CTL = TASSEL_2+MC_1; 161 } 162 163 /************************************************************************ 164 * @brief Get function for the backlight PWM's duty cycle. 165 * 166 * @param none 167 * 168 * @return backlight One of the the 17 possible settings - valued 0 to 16. 169 * 170 *************************************************************************/ 171 unsigned int halLcdGetBackLight(void) 172 { 173 return backlight; 174 } 175 176 /************************************************************************ 177 * @brief Set function for the backlight PWM's duty cycle 178 * 179 * @param BackLightLevel The target backlight duty cycle - valued 0 to 16. 180 * 181 * @return none 182 *************************************************************************/ 183 void halLcdSetBackLight(unsigned char BackLightLevel) 184 { 185 unsigned int dutyCycle = 0, i, dummy; 186 187 if (BackLightLevel > 0) 188 { 189 TA0CCTL3 = OUTMOD_7; 190 dummy = (TA0CCR0 >> 4); 191 192 for (i = 0; i < BackLightLevel; i++) 193 dutyCycle += dummy; 194 195 TA0CCR3 = dutyCycle; 196 197 // If the backlight was previously turned off, turn it on. 198 if (!backlight) 199 TA0CTL |= MC0; 200 } 201 else 202 { 203 TA0CCTL3 = 0; 204 TA0CTL &= ~MC0; 205 } 206 backlight = BackLightLevel; 207 } 208 209 /************************************************************************ 210 * @brief Turns off the backlight. 211 * 212 * Clears the respective GPIO and timer settings. 213 * 214 * @param none 215 * 216 * @return none 217 *************************************************************************/ 218 void halLcdShutDownBackLight(void) 219 { 220 LCD_COMM_DIR |= LCD_BACKLIGHT_PIN; 221 LCD_COMM_OUT &= ~(LCD_BACKLIGHT_PIN); 222 LCD_COMM_SEL &= ~LCD_BACKLIGHT_PIN; 223 224 TA0CCTL3 = 0; 225 TA0CTL = 0; 226 227 backlight = 0; 228 } 229 230 /************************************************************************ 231 * @brief Set function for the contrast level of the LCD. 232 * 233 * @param ContrastLevel The target contrast level 234 * 235 * @return none 236 *************************************************************************/ 237 void halLcdSetContrast(unsigned char ContrastLevel) 238 { 239 if (ContrastLevel > 127) ContrastLevel = 127; 240 if (ContrastLevel < 70) ContrastLevel = 70; 241 LcdInitMacro[ 0x04 * 6 + 5 ] = ContrastLevel; 242 halLcdSendCommand(&LcdInitMacro[ 0x04 * 6 ]); 243 } 244 245 /************************************************************************ 246 * @brief Get function for the contrast level of the LCD. 247 * 248 * @param none 249 * 250 * @return ContrastLevel The LCD constrast level 251 *************************************************************************/ 252 unsigned char halLcdGetContrast(void) 253 { 254 return LcdInitMacro[ 0x04 * 6 + 5 ] ; 255 } 256 257 /************************************************************************ 258 * @brief Turns the LCD cursor on at the current text position. 259 * 260 * @param none 261 * 262 * @return none 263 *************************************************************************/ 264 void halLcdCursor(void) 265 { 266 LcdInitMacro[ 8 * 6 + 5 ] ^= BIT2; 267 halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]); 268 269 LcdInitMacro[ 0x0B * 6 + 5 ] = ((LcdAddress & 0x1F) << 3) ; 270 LcdInitMacro[ 0x0B * 6 + 4 ] = ( (LcdAddress & 0x1F) << 3 ) + 3; 271 LcdInitMacro[ 0x0C * 6 + 5 ] = (LcdAddress >> 5); 272 LcdInitMacro[ 0x0C * 6 + 4 ] = (LcdAddress >> 5) + 7; 273 halLcdSendCommand(&LcdInitMacro[ 0x0B * 6 ]); 274 halLcdSendCommand(&LcdInitMacro[ 0x0C * 6 ]); 275 276 halLcdSetAddress(LcdAddress); 277 } 278 279 /************************************************************************ 280 * @brief Turns off the LCD cursor. 281 * 282 * @param none 283 * 284 * @return none 285 *************************************************************************/ 286 void halLcdCursorOff(void) 287 { 288 LcdInitMacro[ 8 * 6 + 5 ] &= ~BIT2; 289 halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]); 290 } 291 292 /************************************************************************ 293 * @brief Inverts the grayscale values of the LCD display (Black <> white). 294 * 295 * @param none 296 * 297 * @return none 298 *************************************************************************/ 299 void halLcdReverse(void) 300 { 301 LcdInitMacro[ 7 * 6 + 5 ] ^= BIT1; 302 halLcdSendCommand(&LcdInitMacro[ 7 * 6 ]); 303 } 304 305 /************************************************************************ 306 * @brief Sets the LCD in standby mode to reduce power consumption. 307 * 308 * @param none 309 * 310 * @return none 311 *************************************************************************/ 312 void halLcdStandby(void) 313 { 314 LcdInitMacro[ 3 * 6 + 5 ] &= (~BIT3) & (~BIT2); 315 LcdInitMacro[ 3 * 6 + 5 ] |= BIT0; 316 halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]); 317 } 318 319 /************************************************************************ 320 * @brief Puts the LCD into active mode. 321 * 322 * @param none 323 * 324 * @return none 325 *************************************************************************/ 326 void halLcdActive(void) 327 { 328 halLcdSendCommand(LcdInitMacro); 329 LcdInitMacro[ 3 * 6 + 5 ] |= BIT3 ; 330 LcdInitMacro[ 3 * 6 + 5 ] &= ~BIT0; 331 halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]); 332 } 333 334 /************************************************************************ 335 * @brief Sets the pointer location in the LCD. 336 * 337 * - LcdAddress = Address 338 * - LcdTableAddress = Correct Address Row + Column 339 * = (Address / 0x20)* 17 + Column 340 * 341 * @param Address The target pointer location in the LCD. 342 * 343 * @return none 344 *************************************************************************/ 345 void halLcdSetAddress(int Address) 346 { 347 int temp; 348 349 Draw_Block_Address_Macro[4] = Address >> 8; 350 Draw_Block_Address_Macro[5] = Address & 0xFF; 351 halLcdSendCommand(Draw_Block_Address_Macro); 352 LcdAddress = Address; 353 temp = Address >> 5; // Divided by 0x20 354 temp = temp + (temp << 4); 355 //Multiplied by (1+16) and added by the offset 356 LcdTableAddress = temp + (Address & 0x1F); 357 } 358 359 /************************************************************************ 360 * @brief Draws a block at the specified LCD address. 361 * 362 * A block is the smallest addressable memory on the LCD and is 363 * equivalent to 8 pixels, each of which is represented by 2 bits 364 * that represent a grayscale value between 00b and 11b. 365 * 366 * @param Address The address at which to draw the block. 367 * 368 * @param Value The value of the block 369 * 370 * @return none 371 *************************************************************************/ 372 void halLcdDrawBlock(unsigned int Address, unsigned int Value) 373 { 374 halLcdSetAddress(Address); 375 halLcdDrawCurrentBlock(Value); 376 } 377 378 /************************************************************************ 379 * @brief Writes Value to LCD CGram and MSP430 internal LCD table. 380 * 381 * Also updates the LcdAddress and LcdTableAddress to the correct values. 382 * 383 * @param Value The value of the block to be written to the LCD. 384 * 385 * @return none 386 *************************************************************************/ 387 void halLcdDrawCurrentBlock(unsigned int Value) 388 { 389 int temp; 390 391 Draw_Block_Value_Macro[4] = Value >> 8; 392 Draw_Block_Value_Macro[5] = Value & 0xFF; 393 LCD_MEM[ LcdTableAddress ] = Value; 394 395 halLcdSendCommand(Draw_Block_Value_Macro); 396 397 LcdAddress++; 398 temp = LcdAddress >> 5; // Divided by 0x20 399 temp = temp + (temp << 4); 400 // Multiplied by (1+16) and added by the offset 401 LcdTableAddress = temp + (LcdAddress & 0x1F); 402 403 // If LcdAddress gets off the right edge, move to next line 404 if ((LcdAddress & 0x1F) > 0x11) 405 halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 ); 406 if (LcdAddress == LCD_Size) 407 halLcdSetAddress( 0 ); 408 } 409 410 411 /************************************************************************ 412 * @brief Returns the LCD CGRAM value at location Address. 413 * 414 * @param Address The address of the block to be read from the LCD. 415 * 416 * @return Value The value held at the specified address. 417 *************************************************************************/ 418 int halLcdReadBlock(unsigned int Address) 419 { 420 int i = 0, Value = 0, ReadData[7]; 421 422 halLcdSetAddress( Address ); 423 halLcdSendCommand(Read_Block_Address_Macro); 424 425 LCD_COMM_OUT &= ~LCD_CS_PIN; // start transfer CS=0 426 UCB2TXBUF = 0x77; // Transmit first character 0x75 427 428 while (!(UCB2IFG & UCTXIFG)); 429 while (UCB2STAT & UCBUSY); 430 431 //Read 5 dummies values and 2 valid address data 432 P9SEL &= ~BIT1; //Change SPI2C Dir 433 P9SEL |= BIT2; 434 435 for (i = 0; i < 7; i ++ ) 436 { 437 P4OUT |= BIT2; 438 P4OUT &= ~BIT2; 439 UCA0IFG &= ~UCRXIFG; 440 UCA0TXBUF = 1; // load dummy byte 1 for clk 441 while (!(UCA0IFG & UCRXIFG)); 442 ReadData[i] = UCA0RXBUF; 443 } 444 LCD_COMM_OUT |= LCD_CS_PIN; // Stop Transfer CS = 1 445 446 P9SEL |= BIT1; //Change SPI2C Dir 447 P9SEL &= ~BIT2; 448 449 Value = (ReadData[5] << 8) + ReadData[6]; 450 return Value; 451 } 452 453 /************************************************************************ 454 * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD 455 * 456 * @param x x-coordinate for grayscale value 457 * 458 * @param y y-coordinate for grayscale value 459 * 460 * @param GrayScale The intended grayscale value of the pixel - one of 461 * four possible settings. 462 * 463 * @return none 464 *************************************************************************/ 465 void halLcdPixel( int x, int y, unsigned char GrayScale) 466 { 467 int Address, Value; 468 unsigned char offset; 469 //Each line increments by 0x20 470 if ( (x>=0 ) && (x<LCD_COL) && (y>=0) && (y<LCD_ROW)) 471 { 472 Address = (y << 5) + (x >> 3) ; //Narrow down to 8 possible pixels 473 offset = x & 0x07; //3 LSBs = pos. within the 8 columns 474 475 Value = LCD_MEM[(y << 4)+ y + (x>>3)]; //y * 17 --> row. x>>3 --> column 476 switch(GrayScale) 477 { 478 case PIXEL_OFF: 479 Value &= ~ ( 3 << (offset * 2 )); //Both corresponding bits are off 480 break; 481 case PIXEL_LIGHT: 482 Value &= ~ ( 1 << ((offset * 2) + 1)); 483 Value |= 1<< ( offset * 2 ); //Lower bit is on 484 485 break; 486 case PIXEL_DARK: 487 Value &= ~ ( 1 << (offset * 2) ); //Lower bit is on 488 Value |= ( 1 << ( (offset * 2) + 1)); 489 490 break; 491 case PIXEL_ON: 492 Value |= ( 3 << (offset * 2 )); //Both on 493 break; 494 } 495 halLcdDrawBlock( Address, Value ); 496 } 497 } 498 499 /************************************************************************ 500 * @brief Clears entire LCD CGRAM as well as LCD_MEM. 501 * 502 * @param none 503 * 504 * @return none 505 *************************************************************************/ 506 void halLcdClearScreen(void) 507 { 508 int i; 509 510 halLcdSetAddress(0); 511 512 // Clear the entire LCD CGRAM 513 for ( i = 0; i < LCD_Size; i++) 514 halLcdDrawCurrentBlock(0x00); 515 516 halLcdSetAddress(0); // Reset LCD address 517 } 518 519 /************************************************************************ 520 * @brief Loads an image of size = rows * columns, starting at the 521 * coordinate (x,y). 522 * 523 * @param Image[] The image to be loaded 524 * 525 * @param Rows The number of rows in the image. Size = Rows * Columns. 526 * 527 * @param Columns The number of columns in the image. Size = Rows * Columns. 528 * 529 * @param x x-coordinate of the image's starting location 530 * 531 * @param y y-coordinate of the image's starting location 532 * 533 * @return none 534 *************************************************************************/ 535 void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y) 536 { 537 int i,j, CurrentLocation, index=0 ; 538 539 CurrentLocation = (y << 5) + (x >> 3); 540 halLcdSetAddress( CurrentLocation ); 541 for (i=0; i < Rows; i++) 542 { 543 for (j=0; j < Columns; j++) 544 halLcdDrawCurrentBlock(Image[index++]); 545 CurrentLocation += 0x20; 546 halLcdSetAddress(CurrentLocation ); 547 } 548 } 549 550 /************************************************************************ 551 * @brief Clears an image of size rows x columns starting at (x, y). 552 * 553 * @param Columns The size, in columns, of the image to be cleared. 554 * 555 * @param Rows The size, in rows, of the image to be cleared. 556 * 557 * @param x x-coordinate of the image to be cleared 558 * 559 * @param y y-coordinate of the image to be cleared 560 * 561 * @return none 562 *************************************************************************/ 563 void halLcdClearImage(int Columns, int Rows, int x, int y) 564 { 565 int i,j, Current_Location; 566 Current_Location = (y << 5) + (x >> 3); 567 halLcdSetAddress( Current_Location ); 568 for (i=0; i < Rows; i++) 569 { 570 for (j=0; j < Columns; j++) 571 halLcdDrawCurrentBlock(0); 572 Current_Location += 0x20; 573 halLcdSetAddress(Current_Location ); 574 } 575 } 576 577 /************************************************************************ 578 * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD 579 * are also updated. 580 * 581 * @param Value The value to be written to the current LCD pointer 582 * 583 * @return none 584 *************************************************************************/ 585 void halLcdDrawTextBlock(unsigned int Value) 586 { 587 int temp; 588 589 Draw_Block_Value_Macro[4] = Value >> 8; 590 Draw_Block_Value_Macro[5] = Value & 0xFF; 591 LCD_MEM[ LcdTableAddress ] = Value; 592 593 halLcdSendCommand(Draw_Block_Value_Macro); 594 595 LcdAddress++; 596 temp = LcdAddress >> 5; // Divided by 0x20 597 temp = temp + (temp << 4); 598 //Multiplied by (1+16) and added by the offset 599 LcdTableAddress = temp + (LcdAddress & 0x1F); 600 601 // If LcdAddress gets off the right edge, move to next line 602 if ((LcdAddress & 0x1F) > 0x10) 603 halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 ); 604 605 if (LcdAddress >= LCD_Size) 606 halLcdSetAddress( 0 ); 607 } 608 609 /************************************************************************ 610 * @brief Displays the string to the LCD starting at current location. 611 * 612 * Writes all the data to LCD_MEM first, then updates all corresponding 613 * LCD CGRAM locations at once, in a continuous fashion. 614 * 615 * @param String[] The string to be displayed on LCD. 616 * 617 * @param TextStyle Value that specifies whether the string is to be 618 * inverted or overwritten. 619 * - Invert = 0x01 620 * - Overwrite = 0x04 621 * 622 * @return none 623 *************************************************************************/ 624 void halLcdPrint( char String[], unsigned char TextStyle) 625 { 626 int Address; 627 int LCD_MEM_Add; 628 int ActualAddress; 629 int i, j, Counter=0, BlockValue; 630 int temp; 631 char LookUpChar; 632 633 ActualAddress = LcdAddress; 634 Counter = LcdAddress & 0x1F; 635 i=0; 636 637 while (String[i]!=0) // Stop on null character 638 { 639 LookUpChar = fonts_lookup[(uint8_t)String[i]]; 640 641 for (j=0;j < FONT_HEIGHT ;j++) 642 { 643 Address = ActualAddress + j*0x20; 644 temp = Address >> 5; 645 temp += (temp <<4); 646 647 LCD_MEM_Add = temp + (Address & 0x1F); 648 649 BlockValue = LCD_MEM[ LCD_MEM_Add ]; 650 651 #if 0 652 // work around a mspgcc bug - fixed in LTS but not in 11.10 yet 653 if (TextStyle & INVERT_TEXT) 654 if (TextStyle & OVERWRITE_TEXT) 655 BlockValue = 0xFFFF - fonts[LookUpChar*13+j]; 656 else 657 BlockValue |= 0xFFFF - fonts[LookUpChar*13+j]; 658 659 else 660 if (TextStyle & OVERWRITE_TEXT) 661 BlockValue = fonts[LookUpChar*(FONT_HEIGHT+1) +j]; 662 else 663 BlockValue |= fonts[LookUpChar*(FONT_HEIGHT+1) +j]; 664 #else 665 int offset = j; 666 int counter; 667 for (counter = 0 ; counter < LookUpChar ; counter++){ 668 offset = offset + FONT_HEIGHT + 1; 669 } 670 BlockValue |= fonts[offset]; 671 #endif 672 halLcdDrawBlock( Address, BlockValue); 673 } 674 675 Counter++; 676 if (Counter == 17) 677 { 678 Counter = 0; 679 ActualAddress += 0x20*FONT_HEIGHT - 16; 680 if (ActualAddress > LCD_Last_Pixel-0x20*FONT_HEIGHT ) 681 ActualAddress = 0; 682 } 683 else 684 ActualAddress++; 685 i++; 686 } 687 halLcdSetAddress(ActualAddress); 688 689 } 690 691 692 /************************************************************************ 693 * @brief Displays the string to the LCD starting at (x,y) location. 694 * 695 * Writes all the data to LCD_MEM first, then updates all corresponding 696 * LCD CGRAM locations at once, in a continuous fashion. 697 * 698 * @param String[] String to be displayed on LCD 699 * 700 * @param x x-coordinate of the write location on the LCD 701 * 702 * @param y y-coordinate of the write location on the LCD 703 * 704 * @param TextStyle Value that specifies whether the string is to be 705 * inverted or overwritten. 706 * - Invert = 0x01 707 * - Overwrite = 0x04 708 *************************************************************************/ 709 void halLcdPrintXY( char String[], int x, int y, unsigned char TextStyle) 710 { 711 //Each line increments by 0x20 712 halLcdSetAddress( (y << 5) + (x >> 3)) ; //Narrow down to 8 possible pixels 713 halLcdPrint(String, TextStyle); 714 } 715 716 /************************************************************************ 717 * @brief Displays a string on the LCD on the specified line. 718 * 719 * @param String[] The string to be displayed on LCD. 720 * 721 * @param Line The line on the LCD on which to print the string. 722 * 723 * @param TextStyle Value that specifies whether the string is to be 724 * inverted or overwritten. 725 * - Invert = 0x01 726 * - Overwrite = 0x04 727 * 728 * @return none 729 *************************************************************************/ 730 void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle) 731 { 732 int temp; 733 temp = Line * FONT_HEIGHT ; 734 halLcdSetAddress( temp << 5 ) ; // 0x20 = 2^5 735 halLcdPrint(String, TextStyle); 736 } 737 738 /************************************************************************ 739 * @brief Prints a string beginning on a given line and column. 740 * 741 * @param String[] The string to be displayed on LCD. 742 * 743 * @param Line The line on which to print the string of text 744 * 745 * @param Col The column on which to print the string of text 746 * 747 * @param TextStyle Value that specifies whether the string is to be 748 * inverted or overwritten. 749 * - Invert = 0x01 750 * - Overwrite = 0x04 751 * 752 * @return none 753 *************************************************************************/ 754 void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col, 755 unsigned char TextStyle) 756 { 757 int temp; 758 759 temp = Line * FONT_HEIGHT; 760 temp <<= 5; 761 temp += Col; 762 763 halLcdSetAddress( temp ) ; // 0x20 = 2^5 764 halLcdPrint(String, TextStyle); 765 } 766 767 768 /************************************************************************ 769 * @brief Draws a horizontral line from (x1,y) to (x2,y) of GrayScale level 770 * 771 * @param x1 x-coordinate of the first point 772 * 773 * @param x2 x-coordinate of the second point 774 * 775 * @param y y-coordinate of both points 776 * 777 * @param GrayScale Grayscale level of the horizontal line 778 * 779 * @return none 780 *************************************************************************/ 781 void halLcdHLine( int x1, int x2, int y, unsigned char GrayScale) 782 { 783 int x_dir, x; 784 if ( x1 < x2 ) 785 x_dir = 1; 786 else 787 x_dir = -1; 788 x = x1; 789 while (x != x2) 790 { 791 halLcdPixel( x,y, GrayScale); 792 x += x_dir; 793 } 794 } 795 796 /************************************************************************ 797 * @brief Draws a vertical line from (x,y1) to (x,y2) of GrayScale level 798 * 799 * @param x x-coordinate of both points 800 * 801 * @param y1 y-coordinate of the first point 802 * 803 * @param y2 y-coordinate of the second point 804 * 805 * @param GrayScale GrayScale level of the vertical line 806 * 807 * @return none 808 *************************************************************************/ 809 void halLcdVLine( int x, int y1, int y2, unsigned char GrayScale) 810 { 811 int y_dir, y; 812 if ( y1 < y2 ) 813 y_dir = 1; 814 else 815 y_dir = -1; 816 y = y1; 817 while (y != y2) 818 { 819 halLcdPixel( x,y, GrayScale); 820 y += y_dir; 821 } 822 } 823 824 /************************************************************************ 825 * @brief Draws a line from (x1,y1) to (x2,y2) of GrayScale level. 826 * 827 * Uses Bresenham's line algorithm. 828 * 829 * @param x1 x-coordinate of the first point 830 * 831 * @param y1 y-coordinate of the first point 832 * 833 * @param x2 x-coordinate of the second point 834 * 835 * @param y2 y-coordinate of the second point 836 * 837 * @param GrayScale Grayscale level of the line 838 * 839 * @return none 840 *************************************************************************/ 841 void halLcdLine( int x1, int y1, int x2, int y2, unsigned char GrayScale) 842 { 843 int x, y, deltay, deltax, d; 844 int x_dir, y_dir; 845 846 if ( x1 == x2 ) 847 halLcdVLine( x1, y1, y2, GrayScale ); 848 else 849 { 850 if ( y1 == y2 ) 851 halLcdHLine( x1, x2, y1, GrayScale ); 852 else // a diagonal line 853 { 854 if (x1 > x2) 855 x_dir = -1; 856 else x_dir = 1; 857 if (y1 > y2) 858 y_dir = -1; 859 else y_dir = 1; 860 861 x = x1; 862 y = y1; 863 deltay = ABS(y2 - y1); 864 deltax = ABS(x2 - x1); 865 866 if (deltax >= deltay) 867 { 868 d = (deltay << 1) - deltax; 869 while (x != x2) 870 { 871 halLcdPixel(x, y, GrayScale); 872 if ( d < 0 ) 873 d += (deltay << 1); 874 else 875 { 876 d += ((deltay - deltax) << 1); 877 y += y_dir; 878 } 879 x += x_dir; 880 } 881 } 882 else 883 { 884 d = (deltax << 1) - deltay; 885 while (y != y2) 886 { 887 halLcdPixel(x, y, GrayScale); 888 if ( d < 0 ) 889 d += (deltax << 1); 890 else 891 { 892 d += ((deltax - deltay) << 1); 893 x += x_dir; 894 } 895 y += y_dir; 896 } 897 } 898 } 899 } 900 } 901 902 903 /************************************************************************ 904 * @brief Draw a circle of Radius with center at (x,y) of GrayScale level. 905 * 906 * Uses Bresenham's circle algorithm 907 * 908 * @param x x-coordinate of the circle's center point 909 * 910 * @param y y-coordinate of the circle's center point 911 * 912 * @param Radius Radius of the circle 913 * 914 * @param GrayScale Grayscale level of the circle 915 *************************************************************************/ 916 void halLcdCircle(int x, int y, int Radius, int GrayScale) 917 { 918 int xx, yy, ddF_x, ddF_y, f; 919 920 ddF_x = 0; 921 ddF_y = -(2 * Radius); 922 f = 1 - Radius; 923 924 xx = 0; 925 yy = Radius; 926 halLcdPixel(x + xx, y + yy, GrayScale); 927 halLcdPixel(x + xx, y - yy, GrayScale); 928 halLcdPixel(x - xx, y + yy, GrayScale); 929 halLcdPixel(x - xx, y - yy, GrayScale); 930 halLcdPixel(x + yy, y + xx, GrayScale); 931 halLcdPixel(x + yy, y - xx, GrayScale); 932 halLcdPixel(x - yy, y + xx, GrayScale); 933 halLcdPixel(x - yy, y - xx, GrayScale); 934 while (xx < yy) 935 { 936 if (f >= 0) 937 { 938 yy--; 939 ddF_y += 2; 940 f += ddF_y; 941 } 942 xx++; 943 ddF_x += 2; 944 f += ddF_x + 1; 945 halLcdPixel(x + xx, y + yy, GrayScale); 946 halLcdPixel(x + xx, y - yy, GrayScale); 947 halLcdPixel(x - xx, y + yy, GrayScale); 948 halLcdPixel(x - xx, y - yy, GrayScale); 949 halLcdPixel(x + yy, y + xx, GrayScale); 950 halLcdPixel(x + yy, y - xx, GrayScale); 951 halLcdPixel(x - yy, y + xx, GrayScale); 952 halLcdPixel(x - yy, y - xx, GrayScale); 953 } 954 } 955 956 /************************************************************************ 957 * @brief Scrolls a single row of pixels one column to the left. 958 * 959 * The column that is scrolled out of the left side of the LCD will be 960 * displayed the right side of the LCD. 961 * 962 * @param y The row of pixels to scroll. y = 0 is at the top-left 963 * corner of the LCD. 964 * 965 * @return none 966 *************************************************************************/ 967 void halLcdScrollRow(int y) 968 { 969 int i, Address, LcdTableAddressTemp; 970 unsigned int temp; 971 972 Address = y << 5; 973 974 halLcdSetAddress( Address ); 975 976 //Multiplied by (1+16) and added by the offset 977 LcdTableAddressTemp = y + (y << 4); 978 temp = ((LCD_MEM[LcdTableAddressTemp] & 0x0003) <<14); 979 980 for (i = 0; i < 0x10; i++) 981 halLcdDrawCurrentBlock( ( (LCD_MEM[LcdTableAddressTemp+i] & 0xFFFC ) >> 2 ) \ 982 + ((LCD_MEM[LcdTableAddressTemp+i+1] & 0x0003) << 14 )); 983 984 halLcdDrawCurrentBlock( (( LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC ) >> 2) + temp); 985 } 986 987 /************************************************************************ 988 * @brief Scrolls multiple rows of pixels, yStart to yEnd, 989 * one column to the left. 990 * 991 * The column that is scrolled out of the left side of the LCD will be 992 * displayed the right side of the LCD. y = 0 is at the top-left of the 993 * LCD screen. 994 * 995 * @param yStart The beginning row to be scrolled 996 * 997 * @param yEnd The last row to be scrolled 998 * 999 * @return none 1000 *************************************************************************/ 1001 void halLcdHScroll(int yStart, int yEnd) 1002 { 1003 int i ; 1004 1005 for (i = yStart; i < yEnd+1; i++) 1006 halLcdScrollRow(i); 1007 } 1008 1009 /************************************************************************ 1010 * @brief Scrolls a line of text one column to the left. 1011 * 1012 * @param Line The line of text to be scrolled. 1013 * 1014 * @return none 1015 *************************************************************************/ 1016 void halLcdScrollLine(int Line) 1017 { 1018 int i, Row ; 1019 1020 Row = Line * FONT_HEIGHT; 1021 1022 for (i = Row; i < Row + FONT_HEIGHT ; i++) 1023 halLcdScrollRow(i); 1024 } 1025