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 *************************************************************************/
halLcdSendCommand(unsigned char Data[])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 *************************************************************************/
halLcdInit(void)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 *************************************************************************/
halLcdShutDown(void)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 *************************************************************************/
halLcdBackLightInit(void)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 *************************************************************************/
halLcdGetBackLight(void)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 *************************************************************************/
halLcdSetBackLight(unsigned char BackLightLevel)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 *************************************************************************/
halLcdShutDownBackLight(void)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 *************************************************************************/
halLcdSetContrast(unsigned char ContrastLevel)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 *************************************************************************/
halLcdGetContrast(void)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 *************************************************************************/
halLcdCursor(void)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 *************************************************************************/
halLcdCursorOff(void)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 *************************************************************************/
halLcdReverse(void)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 *************************************************************************/
halLcdStandby(void)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 *************************************************************************/
halLcdActive(void)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 *************************************************************************/
halLcdSetAddress(int Address)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 *************************************************************************/
halLcdDrawBlock(unsigned int Address,unsigned int Value)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 *************************************************************************/
halLcdDrawCurrentBlock(unsigned int Value)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 *************************************************************************/
halLcdReadBlock(unsigned int Address)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 *************************************************************************/
halLcdPixel(int x,int y,unsigned char GrayScale)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 *************************************************************************/
halLcdClearScreen(void)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 *************************************************************************/
halLcdImage(const unsigned int Image[],int Columns,int Rows,int x,int y)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 *************************************************************************/
halLcdClearImage(int Columns,int Rows,int x,int y)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 *************************************************************************/
halLcdDrawTextBlock(unsigned int Value)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 *************************************************************************/
halLcdPrint(char String[],unsigned char TextStyle)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 *************************************************************************/
halLcdPrintXY(char String[],int x,int y,unsigned char TextStyle)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 *************************************************************************/
halLcdPrintLine(char String[],unsigned char Line,unsigned char TextStyle)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 *************************************************************************/
halLcdPrintLineCol(char String[],unsigned char Line,unsigned char Col,unsigned char TextStyle)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 *************************************************************************/
halLcdHLine(int x1,int x2,int y,unsigned char GrayScale)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 *************************************************************************/
halLcdVLine(int x,int y1,int y2,unsigned char GrayScale)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 *************************************************************************/
halLcdLine(int x1,int y1,int x2,int y2,unsigned char GrayScale)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 *************************************************************************/
halLcdCircle(int x,int y,int Radius,int GrayScale)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 *************************************************************************/
halLcdScrollRow(int y)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 *************************************************************************/
halLcdHScroll(int yStart,int yEnd)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 *************************************************************************/
halLcdScrollLine(int Line)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