1 /*************************************************************************
2 *
3 * Used with ICCARM and AARM.
4 *
5 * (c) Copyright IAR Systems 2008
6 *
7 * File name : drv_glcd.c
8 * Description : Graphical LCD driver
9 *
10 * History :
11 * 1. Date : 6, March 2008
12 * Author : Stanimir Bonev
13 * Description : Create
14 *
15 *
16 * $Revision: 24636 $
17 *
18 * @Modify: NXP MCU Application Team - NguyenCao
19 * @Date: 04. March. 2011
20 **************************************************************************/
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <assert.h>
25 //#include "ConstGlbPtrs.h"
26 //#include "Ex_sdram.h"
27 #include "drv_glcd.h"
28 #include "lpc177x_8x_clkpwr.h"
29 #include "lpc177x_8x_pinsel.h"
30
31 //#include "Cursor.h"
32 //#include "logo.h"
33
34 //#define MHZ
35
36 #define C_GLCD_CLK_PER_LINE (C_GLCD_H_SIZE + C_GLCD_H_PULSE + C_GLCD_H_FRONT_PORCH + C_GLCD_H_BACK_PORCH)
37 #define C_GLCD_LINES_PER_FRAME (C_GLCD_V_SIZE + C_GLCD_V_PULSE + C_GLCD_V_FRONT_PORCH + C_GLCD_V_BACK_PORCH)
38 #define C_GLCD_PIX_CLK (C_GLCD_CLK_PER_LINE * C_GLCD_LINES_PER_FRAME)
39
40 //LPC_LCD_TypeDef * const g_pLCD = ((LPC_LCD_TypeDef*) LPC_LCD_BASE);
41 //LPC_SC_TypeDef * const g_pSC = ((LPC_SC_TypeDef*) LPC_SC_BASE);
42
43 #define SDRAM_BASE 0xA0000000 /* CS0 */
44 #define SDRAM_BASE_ADDR SDRAM_BASE
45
46 #define LCD_VRAM_BASE_ADDR ((unsigned long)SDRAM_BASE_ADDR + 0x00000000)
47 #define LCD_CURSOR_BASE_ADDR ((unsigned long)0x20088800)
48
49
50 static pFontType_t pCurrFont = NULL;
51 static LdcPixel_t TextColour;
52 static LdcPixel_t TextBackgndColour;
53
54 static unsigned long TextX_Pos = 0;
55 static unsigned long TextY_Pos = 0;
56
57 static unsigned long XL_Win = 0;
58 static unsigned long YU_Win = 0;
59 static unsigned long XR_Win = C_GLCD_H_SIZE-1;
60 static unsigned long YD_Win = C_GLCD_V_SIZE-1;
61
62 static unsigned long TabSize = TEXT_DEF_TAB_SIZE;
63
64 static unsigned long WindY_Size, WindX_Size;
65 static unsigned long CurrY_Size, CurrX_Size;
66 static unsigned long *pWind;
67 static unsigned long *pPix;
68
69 /*************************************************************************
70 * Function Name: GLCD_Cursor_Cnfg
71 * Parameters:
72 *
73 * Return: none
74 *
75 * Description: Configure the cursor
76 *
77 *************************************************************************/
GLCD_Cursor_Cfg(int Cfg)78 void GLCD_Cursor_Cfg(int Cfg)
79 {
80 LPC_LCD->CRSR_CFG = Cfg;
81 }
82 /*************************************************************************
83 * Function Name: GLCD_Cursor_En
84 * Parameters: cursor - Cursor Number
85 *
86 * Return: none
87 *
88 * Description: Enable Cursor
89 *
90 *************************************************************************/
GLCD_Cursor_En(int cursor)91 void GLCD_Cursor_En(int cursor)
92 {
93 LPC_LCD->CRSR_CTRL |= (cursor<<4);
94 LPC_LCD->CRSR_CTRL |= 1;
95 }
96
97 /*************************************************************************
98 * Function Name: GLCD_Cursor_Dis
99 * Parameters: None
100 *
101 * Return: none
102 *
103 * Description: Disable Cursor
104 *
105 *************************************************************************/
GLCD_Cursor_Dis(int cursor)106 void GLCD_Cursor_Dis(int cursor)
107 {
108 LPC_LCD->CRSR_CTRL &= (1<<0);
109 }
110
111 /*************************************************************************
112 * Function Name: GLCD_Move_Cursor
113 * Parameters: x - cursor x position
114 * y - cursor y position
115 *
116 * Return: none
117 *
118 * Description: Moves cursor on position (x,y). Negativ values are posible.
119 *
120 *************************************************************************/
GLCD_Move_Cursor(int x,int y)121 void GLCD_Move_Cursor(int x, int y)
122 {
123 LPC_LCD->CRSR_CLIP = 0;
124 LPC_LCD->CRSR_XY = 0;
125 if(0 <= x)
126 {//no clipping
127 LPC_LCD->CRSR_XY |= (x & 0x3FF);
128 }
129 else
130 {//clip x
131 LPC_LCD->CRSR_CLIP |= -x;
132 }
133
134 if(0 <= y)
135 {//no clipping
136
137 LPC_LCD->CRSR_XY |= (y << 16);
138 }
139 else
140 {//clip y
141 LPC_LCD->CRSR_CLIP |= (-y << 8);
142 }
143 }
144
145 /*************************************************************************
146 * Function Name: GLCD_Copy_Cursor
147 * Parameters: pCursor - pointer to cursor conts image
148 * cursor - cursor Number (0,1,2 or 3)
149 * for 64x64(size 256) pix cursor always use 0
150 * size - cursor size in words
151 * Return: none
152 *
153 * Description: Copy Cursor from const image to LCD RAM image
154 *
155 *************************************************************************/
GLCD_Copy_Cursor(const unsigned long * pCursor,int cursor,int size)156 void GLCD_Copy_Cursor (const unsigned long *pCursor, int cursor, int size)
157 {
158 unsigned long i ;
159 unsigned long * pDst = (unsigned long *)LCD_CURSOR_BASE_ADDR;
160
161 pDst += cursor*64;
162
163 for(i = 0; i < size ; i++)
164 // *pDst++ = *pCursor++;
165 {
166 *pDst = *pCursor;
167 pDst++;
168 pCursor++;
169 }
170 }
171 /*************************************************************************
172 * Function Name: GLCD_Init
173 * Parameters: const unsigned long *pPain, const unsigned long * pPallete
174 *
175 * Return: none
176 *
177 * Description: GLCD controller init
178 *
179 *************************************************************************/
GLCD_Init(void * VRAMBase)180 void GLCD_Init (void* VRAMBase)
181 {
182 // unsigned long i;
183 // Assign pins
184 LPC_IOCON->P2_9 = 0x06; // VD3, R0
185 LPC_IOCON->P2_6 = 0x07; // VD4, R1
186 LPC_IOCON->P2_7 = 0x07; // VD5, R2
187 LPC_IOCON->P4_28 = 0x05; // VD6, R3
188 LPC_IOCON->P4_29 = 0x05; // VD7, R4
189
190 LPC_IOCON->P1_20 = 0x07; // VD10, G0
191 LPC_IOCON->P1_21 = 0x07; // VD11, G1
192 LPC_IOCON->P1_22 = 0x07; // VD12, G2
193 LPC_IOCON->P1_23 = 0x07; // VD13, G3
194 LPC_IOCON->P1_24 = 0x07; // VD14, G4
195 LPC_IOCON->P1_25 = 0x07; // VD15, G5
196
197 LPC_IOCON->P2_13 = 0x07; // VD19, B0
198 LPC_IOCON->P1_26 = 0x07; // VD20, B1
199 LPC_IOCON->P1_27 = 0x07; // VD21, B2
200 LPC_IOCON->P1_28 = 0x07; // VD22, B3
201 LPC_IOCON->P1_29 = 0x07; // VD23, B4
202
203 LPC_IOCON->P2_2 = 0x07; // DCLK
204 LPC_IOCON->P2_0 = 0x07; // DSIP(power)
205 LPC_IOCON->P2_5 = 0x07; // HSYNC
206 LPC_IOCON->P2_3 = 0x07; // VSYNC
207 LPC_IOCON->P2_4 = 0x07; // DataEn
208
209 // LPC_IOCON->P5_4 = 0x00; // Backlight
210
211 // >>> debug >>>
212
213 // <<< debug <<<
214
215 /*Back light enable*/
216 // LPC_GPIO5->DIR = (1<<4);
217 // LPC_GPIO5->SET= (5<<4);
218
219 //Turn on LCD clock
220 CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);
221
222 // Disable cursor
223 LPC_LCD->CRSR_CTRL &=~(1<<0);
224
225 // disable GLCD controller
226 LPC_LCD->CTRL = 0;
227 // RGB888
228 LPC_LCD->CTRL &= ~(0x07 <<1);
229 LPC_LCD->CTRL |= (6<<1);
230
231 // TFT panel
232 LPC_LCD->CTRL |= (1<<5);
233 // single panel
234 LPC_LCD->CTRL &= ~(1<<7);
235 // notmal output
236 LPC_LCD->CTRL &= ~(1<<8);
237 // little endian byte order
238 LPC_LCD->CTRL &= ~(1<<9);
239 // little endian pix order
240 LPC_LCD->CTRL &= ~(1<<10);
241 // disable power
242 LPC_LCD->CTRL &= ~(1<<11);
243 // init pixel clock
244 // g_pSC->LCD_CFG = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / ((unsigned long)C_GLCD_PIX_CLK);
245 LPC_SC->LCD_CFG = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / ((unsigned long)C_GLCD_PIX_CLK);
246 // bypass inrenal clk divider
247 LPC_LCD->POL |=(1<<26);
248 // clock source for the LCD block is HCLK
249 LPC_LCD->POL &= ~(1<<5);
250 // LCDFP pin is active LOW and inactive HIGH
251 LPC_LCD->POL |= (1<<11);
252 // LCDLP pin is active LOW and inactive HIGH
253 LPC_LCD->POL |= (1<<12);
254 // data is driven out into the LCD on the falling edge
255 LPC_LCD->POL &= ~(1<<13);
256 // active high
257 LPC_LCD->POL &= ~(1<<14);
258 LPC_LCD->POL &= ~(0x3FF <<16);
259 LPC_LCD->POL |= (C_GLCD_H_SIZE-1)<<16;
260
261 // init Horizontal Timing
262 LPC_LCD->TIMH = 0; //reset TIMH before set value
263 LPC_LCD->TIMH |= (C_GLCD_H_BACK_PORCH - 1)<<24;
264 LPC_LCD->TIMH |= (C_GLCD_H_FRONT_PORCH - 1)<<16;
265 LPC_LCD->TIMH |= (C_GLCD_H_PULSE - 1)<<8;
266 LPC_LCD->TIMH |= ((C_GLCD_H_SIZE/16) - 1)<<2;
267
268 // init Vertical Timing
269 LPC_LCD->TIMV = 0; //reset TIMV value before setting
270 LPC_LCD->TIMV |= (C_GLCD_V_BACK_PORCH)<<24;
271 LPC_LCD->TIMV |= (C_GLCD_V_FRONT_PORCH)<<16;
272 LPC_LCD->TIMV |= (C_GLCD_V_PULSE - 1)<<10;
273 LPC_LCD->TIMV |= C_GLCD_V_SIZE - 1;
274 // Frame Base Address doubleword aligned
275 LPC_LCD->UPBASE = (unsigned long)VRAMBase & ~7UL ;
276 LPC_LCD->LPBASE = (unsigned long)VRAMBase & ~7UL ;
277 }
278
279 /*************************************************************************
280 * Function Name: GLCD_SetPallet
281 * Parameters: const unsigned long * pPallete
282 *
283 * Return: none
284 *
285 * Description: GLCD init colour pallete
286 *
287 *************************************************************************/
GLCD_SetPallet(const unsigned long * pPallete)288 void GLCD_SetPallet (const unsigned long * pPallete)
289 {
290 unsigned long i;
291 unsigned long * pDst = (unsigned long *)LPC_LCD->PAL;
292 // //assert(pPallete);
293 for (i = 0; i < 128; i++)
294 {
295 *pDst++ = *pPallete++;
296 }
297 }
298
299 /*************************************************************************
300 * Function Name: GLCD_Ctrl
301 * Parameters: Bool bEna
302 *
303 * Return: none
304 *
305 * Description: GLCD enable disabe sequence
306 *
307 *************************************************************************/
GLCD_Ctrl(Bool bEna)308 void GLCD_Ctrl (Bool bEna)
309 {
310 volatile unsigned long i;
311 if (bEna)
312 {
313 // LCD_CTRL_bit.LcdEn = 1;
314 LPC_LCD->CTRL |= (1<<0);
315 for(i = C_GLCD_PWR_ENA_DIS_DLY; i; i--);
316 // LCD_CTRL_bit.LcdPwr= 1; // enable power
317 LPC_LCD->CTRL |= (1<<11);
318 }
319 else
320 {
321 // LCD_CTRL_bit.LcdPwr= 0; // disable power
322 LPC_LCD->CTRL &= ~(1<<11);
323 for(i = C_GLCD_PWR_ENA_DIS_DLY; i; i--);
324 // LCD_CTRL_bit.LcdEn = 0;
325 LPC_LCD->CTRL &= ~(1<<0);
326 }
327 }
328
329 /*************************************************************************
330 * Function Name: GLCD_SetFont
331 * Parameters: pFontType_t pFont, LdcPixel_t Color
332 * LdcPixel_t BackgndColor
333 *
334 * Return: none
335 *
336 * Description: Set current font, font color and background color
337 *
338 *************************************************************************/
GLCD_SetFont(pFontType_t pFont,LdcPixel_t Color,LdcPixel_t BackgndColor)339 void GLCD_SetFont(pFontType_t pFont, LdcPixel_t Color, LdcPixel_t BackgndColor)
340 {
341 pCurrFont = pFont;
342 TextColour = Color;
343 TextBackgndColour = BackgndColor;
344 }
345
346 /*************************************************************************
347 * Function Name: GLCD_SetWindow
348 * Parameters: unsigned long X_Left, unsigned long Y_Up,
349 * unsigned long X_Right, unsigned long Y_Down
350 *
351 * Return: none
352 *
353 * Description: Set draw window XY coordinate in pixels
354 *
355 *************************************************************************/
GLCD_SetWindow(unsigned long X_Left,unsigned long Y_Up,unsigned long X_Right,unsigned long Y_Down)356 void GLCD_SetWindow(unsigned long X_Left, unsigned long Y_Up,
357 unsigned long X_Right, unsigned long Y_Down)
358 {
359 // //assert(X_Right < C_GLCD_H_SIZE);
360 // //assert(Y_Down < C_GLCD_V_SIZE);
361 // //assert(X_Left < X_Right);
362 //assert(Y_Up < Y_Down);
363 XL_Win = X_Left;
364 YU_Win = Y_Up;
365 XR_Win = X_Right;
366 YD_Win = Y_Down;
367 }
368
369 /*************************************************************************
370 * Function Name: GLCD_TextSetPos
371 * Parameters: unsigned long X_UpLeft, unsigned long Y_UpLeft,
372 * unsigned long X_DownLeft, unsigned long Y_DownLeft
373 *
374 * Return: none
375 *
376 * Description: Set text X,Y coordinate in characters
377 *
378 *************************************************************************/
GLCD_TextSetPos(unsigned long X,unsigned long Y)379 void GLCD_TextSetPos(unsigned long X, unsigned long Y)
380 {
381 TextX_Pos = X;
382 TextY_Pos = Y;
383 }
384
385 /*************************************************************************
386 * Function Name: GLCD_TextSetTabSize
387 * Parameters: unsigned long Size
388 *
389 * Return: none
390 *
391 * Description: Set text tab size in characters
392 *
393 *************************************************************************/
GLCD_TextSetTabSize(unsigned long Size)394 void GLCD_TextSetTabSize(unsigned long Size)
395 {
396 TabSize = Size;
397 }
398
399 /*************************************************************************
400 * Function Name: LCD_SET_WINDOW
401 * Parameters: int c
402 *
403 * Return: none
404 *
405 * Description: Put char function
406 *
407 *************************************************************************/
408 static
LCD_SET_WINDOW(unsigned long X_Left,unsigned long X_Right,unsigned long Y_Up,unsigned long Y_Down)409 void LCD_SET_WINDOW (unsigned long X_Left, unsigned long X_Right,
410 unsigned long Y_Up, unsigned long Y_Down)
411 {
412 pPix = pWind = ((unsigned long *)LCD_VRAM_BASE_ADDR) + X_Left + (Y_Up*C_GLCD_H_SIZE);
413 WindX_Size = X_Right - X_Left;
414 WindY_Size = Y_Down - Y_Up;
415 CurrX_Size = CurrY_Size = 0;
416 }
417
418 /*************************************************************************
419 * Function Name: LCD_SET_WINDOW
420 * Parameters: int c
421 *
422 * Return: none
423 *
424 * Description: Put char function
425 *
426 *************************************************************************/
427 static
LCD_WRITE_PIXEL(unsigned long Pixel)428 void LCD_WRITE_PIXEL (unsigned long Pixel)
429 {
430 *pPix++ = Pixel;
431 if (++CurrX_Size > WindX_Size)
432 {
433 CurrX_Size = 0;
434 if(++CurrY_Size > WindY_Size)
435 {
436 CurrY_Size = 0;
437 }
438 pPix = pWind + CurrY_Size * C_GLCD_H_SIZE;
439 }
440 }
441
442 /*************************************************************************
443 * Function Name: GLCD_TextCalcWindow
444 * Parameters: unsigned long * pXL, unsigned long * pXR,
445 * unsigned long * pYU, unsigned long * pYD,
446 * unsigned long * pH_Size, unsigned long * pV_Size
447 *
448 * Return: Bool
449 * FALSE - out of window coordinate aren't valid
450 * TRUE - the returned coordinate are valid
451 *
452 * Description: Calculate character window
453 *
454 *************************************************************************/
455 static
GLCD_TextCalcWindow(unsigned long * pXL,unsigned long * pXR,unsigned long * pYU,unsigned long * pYD,unsigned long * pH_Size,unsigned long * pV_Size)456 Bool GLCD_TextCalcWindow (unsigned long * pXL, unsigned long * pXR,
457 unsigned long * pYU, unsigned long * pYD,
458 unsigned long * pH_Size, unsigned long * pV_Size)
459 {
460 *pH_Size = pCurrFont->H_Size;
461 *pV_Size = pCurrFont->V_Size;
462 *pXL = XL_Win + (TextX_Pos*pCurrFont->H_Size);
463 if(*pXL > XR_Win)
464 {
465 return(FALSE);
466 }
467 *pYU = YU_Win + (TextY_Pos*pCurrFont->V_Size);
468 if(*pYU > YD_Win)
469 {
470 return(FALSE);
471 }
472
473 *pXR = XL_Win + ((TextX_Pos+1)*pCurrFont->H_Size) - 1;
474 if(*pXR > XR_Win)
475 {
476 *pH_Size -= *pXR - XR_Win;
477 *pXR = XR_Win;
478 }
479
480 *pYD = YU_Win + ((TextY_Pos+1)*pCurrFont->V_Size) - 1;
481 if(*pYD > YD_Win)
482 {
483 *pV_Size -= *pYD - YD_Win;
484 *pYD = YD_Win;
485 }
486
487 return(TRUE);
488 }
489
490 /*************************************************************************
491 * Function Name: putchar
492 * Parameters: int c
493 *
494 * Return: none
495 *
496 * Description: Put char function
497 *
498 *************************************************************************/
_putchar(int c)499 int _putchar (int c)
500 {
501 uint8_t *pSrc;
502 unsigned long H_Line;
503 unsigned long xl,xr,yu,yd,Temp,V_Size, H_Size, SrcInc = 1;
504 unsigned long WhiteSpaceNumb;
505 unsigned long i, j, k;
506 if(pCurrFont == NULL)
507 {
508 return(EOF);
509 }
510 H_Line = (pCurrFont->H_Size / 8) + ((pCurrFont->H_Size % 8)?1:0);
511 switch(c)
512 {
513 case '\n': // go to begin of next line (NewLine)
514 ++TextY_Pos;
515 break;
516 case '\r': // go to begin of this line (Carriage Return)
517 // clear from current position to end of line
518 while(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
519 {
520 LCD_SET_WINDOW(xl,xr,yu,yd);
521 for(i = 0; i < V_Size; ++i)
522 {
523 for(j = 0; j < H_Size; ++j)
524 {
525 LCD_WRITE_PIXEL(TextBackgndColour);
526 }
527 }
528 ++TextX_Pos;
529 }
530 TextX_Pos = 0;
531 break;
532 case '\b': // go back one position (BackSpace)
533 if(TextX_Pos)
534 {
535 --TextX_Pos;
536 // del current position
537 if(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
538 {
539 LCD_SET_WINDOW(xl,xr,yu,yd);
540 for(i = 0; i < V_Size; ++i)
541 {
542 for(j = 0; j < H_Size; ++j)
543 {
544 LCD_WRITE_PIXEL(TextBackgndColour);
545 }
546 }
547 }
548 }
549 break;
550 case '\t': // go to next Horizontal Tab stop
551 WhiteSpaceNumb = TabSize - (TextX_Pos%TabSize);
552 for(k = 0; k < WhiteSpaceNumb; ++k)
553 {
554 LCD_SET_WINDOW(xl,xr,yu,yd);
555 if(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
556 {
557 for(i = 0; i < V_Size; ++i)
558 {
559 for(j = 0; j < H_Size; ++j)
560 {
561 LCD_WRITE_PIXEL(TextBackgndColour);
562 }
563 }
564 ++TextX_Pos;
565 }
566 else
567 {
568 break;
569 }
570 }
571 break;
572 case '\f': // go to top of page (Form Feed)
573 // clear entire window
574 H_Size = XR_Win - XL_Win;
575 V_Size = YD_Win - YU_Win;
576 // set character window X left, Y right
577 LCD_SET_WINDOW(XL_Win,XR_Win,YU_Win,YD_Win);
578 // Fill window with background font color
579 for(i = 0; i <= V_Size; ++i)
580 {
581 for(j = 0; j <= H_Size; ++j)
582 {
583 LCD_WRITE_PIXEL(TextBackgndColour);
584 }
585 }
586
587 TextX_Pos = TextY_Pos = 0;
588 break;
589 case '\a': // signal an alert (BELl)
590 TEXT_BEL1_FUNC();
591 break;
592 default:
593 // Calculate the current character base address from stream
594 // and the character position
595 if((c < pCurrFont->CharacterOffset) &&
596 (c >= pCurrFont->CharactersNuber))
597 {
598 c = 0;
599 }
600 else
601 {
602 c -= pCurrFont->CharacterOffset;
603 }
604 pSrc = pCurrFont->pFontStream + (H_Line * pCurrFont->V_Size * c);
605 // Calculate character window and fit it in the text window
606 if(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
607 {
608 // set character window X left, Y right
609 LCD_SET_WINDOW(xl,xr,yu,yd);
610 // Send char data
611 for(i = 0; i < V_Size; ++i)
612 {
613 SrcInc = H_Line;
614 for(j = 0; j < H_Size; ++j)
615 {
616 Temp = (*pSrc & (1UL << (j&0x7)))?TextColour:TextBackgndColour;
617 LCD_WRITE_PIXEL(Temp);
618 if((j&0x7) == 7)
619 {
620 ++pSrc;
621 --SrcInc;
622 }
623 }
624 // next line of character
625 pSrc += SrcInc;
626 }
627 }
628 ++TextX_Pos;
629 }
630 return(c);
631 }
632
633 /*************************************************************************
634 * Function Name: GLCD_LoadPic
635 * Parameters: unsigned long X_Left, unsigned long Y_Up, Bmp_t * pBmp
636 *
637 * Return: none
638 *
639 * Description: Load picture in VRAM memory area
640 *
641 *************************************************************************/
GLCD_LoadPic(unsigned long X_Left,unsigned long Y_Up,Bmp_t * pBmp,unsigned long Mask)642 void GLCD_LoadPic (unsigned long X_Left, unsigned long Y_Up, Bmp_t * pBmp, unsigned long Mask)
643 {
644 unsigned long i, j;
645 unsigned long * pData = ((unsigned long *) LCD_VRAM_BASE_ADDR) + X_Left + (Y_Up * C_GLCD_H_SIZE);
646 unsigned long * pSrc = pBmp->pPicStream;
647 unsigned long X_LeftHold;
648 for(i = 0; i < pBmp->V_Size; i++)
649 {
650 if(Y_Up++ >= C_GLCD_V_SIZE)
651 {
652 break;
653 }
654 for(j = 0; j < pBmp->H_Size; j++)
655 {
656 if(X_LeftHold++ >= C_GLCD_H_SIZE)
657 {
658 pSrc += pBmp->H_Size - j;
659 break;
660 }
661 *(pData+j) = *pSrc++ ^ Mask;
662 }
663 X_LeftHold = X_Left;
664 pData += C_GLCD_H_SIZE;
665 }
666 }
667
668
669