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