]> git.sur5r.net Git - freertos/blob
878af9b0990008d4ae93bd7162ca291e8b214fca
[freertos] /
1 /**********************************************************************\r
2 * $Id$          lpc18xx_lcd.c           2011-06-02\r
3 *//**\r
4 * @file         lpc18xx_lcd.c\r
5 * @brief        Contains all function support for LCD Driver\r
6 * @version      1.0\r
7 * @date         02. June. 2011\r
8 * @author       NXP MCU SW Application Team\r
9 *\r
10 * Copyright(C) 2011, NXP Semiconductor\r
11 * All rights reserved.\r
12 *\r
13 ***********************************************************************\r
14 * Software that is described herein is for illustrative purposes only\r
15 * which provides customers with programming information regarding the\r
16 * products. This software is supplied "AS IS" without any warranties.\r
17 * NXP Semiconductors assumes no responsibility or liability for the\r
18 * use of the software, conveys no license or title under any patent,\r
19 * copyright, or mask work right to the product. NXP Semiconductors\r
20 * reserves the right to make changes in the software without\r
21 * notification. NXP Semiconductors also make no representation or\r
22 * warranty that such application will be suitable for the specified\r
23 * use without further testing or modification.\r
24 **********************************************************************/\r
25 \r
26 /* Peripheral group ----------------------------------------------------------- */\r
27 /** @addtogroup LCD\r
28  * @{\r
29  */\r
30 \r
31 /* Includes ------------------------------------------------------------------- */\r
32 #include "LPC18xx.h"\r
33 #include "lpc18xx_lcd.h"\r
34 \r
35 /* If this source file built with example, the LPC18xx FW library configuration\r
36  * file in each example directory ("lpc18xx_libcfg.h") must be included,\r
37  * otherwise the default FW library configuration file must be included instead\r
38  */\r
39 #ifdef __BUILD_WITH_EXAMPLE__\r
40 #include "lpc18xx_libcfg.h"\r
41 #else\r
42 #include "lpc18xx_libcfg_default.h"\r
43 #endif /* __BUILD_WITH_EXAMPLE__ */\r
44 \r
45 #ifdef _LCD\r
46 \r
47 LCD_CURSOR_SIZE_OPT LCD_Cursor_Size = LCD_CURSOR_64x64;\r
48 \r
49 /* Private Functions ---------------------------------------------------------- */\r
50 \r
51 /*********************************************************************//**\r
52  * @brief               Init the LPC18xx LCD Controller\r
53  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
54  * @param[in]   LCD_ConfigStruct point to LCD_CFG_Type that describe the LCD Panel\r
55  * @return              None\r
56  **********************************************************************/\r
57 void LCD_Init(LPC_LCD_Type *LCDx, LCD_CFG_Type *LCD_ConfigStruct){\r
58         uint32_t i, regValue, *pPal;\r
59         uint32_t pcd;\r
60         /* disable the display */\r
61         LCDx->CTRL &= ~CLCDC_LCDCTRL_ENABLE;\r
62 \r
63         /* Setting LCD_TIMH register */\r
64         regValue= ( ((((LCD_ConfigStruct->screen_width/16)-1)&0x3F) << 2)\r
65         |         (( (LCD_ConfigStruct->HSync_pulse_width-1)    &0xFF) << 8)\r
66         |         (( (LCD_ConfigStruct->horizontal_porch.front-1)    &0xFF) << 16)\r
67         |         (( (LCD_ConfigStruct->horizontal_porch.back-1)    &0xFF) << 24) );\r
68 \r
69         LCDx->TIMH = regValue;\r
70 \r
71         /* Setting LCD_TIMV register */\r
72         regValue =((((LCD_ConfigStruct->screen_height-1) &0x3FF) << 0)\r
73         |        (((LCD_ConfigStruct->VSync_pulse_width-1) &0x03F) << 10)\r
74         |        (((LCD_ConfigStruct->vertical_porch.front-1) &0x0FF) << 16)\r
75         |        (((LCD_ConfigStruct->vertical_porch.back-1) &0x0FF) << 24) );\r
76 \r
77         LCDx->TIMV = regValue;\r
78 \r
79         /* Generate the clock and signal polarity control word */\r
80         regValue = 0;\r
81         regValue = (((LCD_ConfigStruct->ac_bias_frequency-1) & 0x1F) << 6);\r
82 \r
83         regValue |= (LCD_ConfigStruct->OE_pol & 1)<< 14;\r
84 \r
85         regValue |= (LCD_ConfigStruct->panel_clk_edge & 1)<< 13;\r
86 \r
87         regValue |= (LCD_ConfigStruct->HSync_pol & 1)<< 12;\r
88 \r
89         regValue |= (LCD_ConfigStruct->VSync_pol & 1)<< 11;\r
90 \r
91         /* Compute clocks per line based on panel type */\r
92 \r
93         switch(LCD_ConfigStruct->lcd_panel_type)\r
94         {\r
95           case LCD_MONO_4:\r
96                 regValue |= ((((LCD_ConfigStruct->screen_width / 4)-1) & 0x3FF) << 16);\r
97                 break;\r
98           case LCD_MONO_8:\r
99                 regValue |= ((((LCD_ConfigStruct->screen_width / 8)-1) & 0x3FF) << 16);\r
100                 break;\r
101           case LCD_CSTN:\r
102                 regValue |= (((((LCD_ConfigStruct->screen_width * 3)/8)-1) & 0x3FF) << 16);\r
103                 break;\r
104           case LCD_TFT:\r
105           default:\r
106                 regValue |= 1<<26 | (((LCD_ConfigStruct->screen_width-1) & 0x3FF) << 16);\r
107         }\r
108 \r
109         /* panel clock divisor */\r
110         pcd = LCD_ConfigStruct->pcd;   // TODO: should be calculated from LCDDCLK\r
111         pcd &= 0x3FF;\r
112         regValue |=  ((pcd>>5)<<27) | ((pcd)&0x1F);\r
113 \r
114         LCDx->POL = regValue;\r
115 \r
116         /* configure line end control */\r
117         CHECK_PARAM(LCD_ConfigStruct->line_end_delay<=(1<<7));\r
118         if(LCD_ConfigStruct->line_end_delay)\r
119                 LCDx->LE  = (LCD_ConfigStruct->line_end_delay-1) | 1<<16;\r
120         else\r
121                 LCDx->LE = 0;\r
122 \r
123         /* disable interrupts */\r
124         LCDx->INTMSK = 0;\r
125 \r
126         /* set bits per pixel */\r
127         regValue = LCD_ConfigStruct->bits_per_pixel << 1;\r
128 \r
129         /* set color format BGR or RGB */\r
130         regValue |= LCD_ConfigStruct->color_format << 8;\r
131 \r
132         regValue |= LCD_ConfigStruct->lcd_panel_type << 4;\r
133 \r
134         if(LCD_ConfigStruct->dual_panel == 1)\r
135         {\r
136                 regValue |= 1 << 7;\r
137         }\r
138         LCDx->CTRL = regValue;\r
139         /* clear palette */\r
140         pPal = (uint32_t*) (&(LCDx->PAL));\r
141 \r
142         for(i = 0; i < 128; i++)\r
143         {\r
144                 *pPal = 0;\r
145                 pPal++;\r
146         }\r
147 }\r
148 \r
149 \r
150 /*********************************************************************//**\r
151  * @brief               Deinit LCD controller\r
152  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
153  * @return              None\r
154  **********************************************************************/\r
155 void LCD_DeInit(LPC_LCD_Type *LCDx);\r
156 \r
157 \r
158 /*********************************************************************//**\r
159  * @brief               Power the LCD Panel\r
160  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
161  * @param[in]   OnOff   Turn on/off LCD\r
162  *                                      - TRUE  :Turn on\r
163  *                                      - FALSE :Turn off\r
164  * @return              None\r
165  **********************************************************************/\r
166 void LCD_Power(LPC_LCD_Type *LCDx, FunctionalState OnOff){\r
167 int i;\r
168         if(OnOff){\r
169                 LPC_LCD->CTRL |= CLCDC_LCDCTRL_PWR;\r
170                 for(i=0;i<100000;i++);\r
171                 LPC_LCD->CTRL |= CLCDC_LCDCTRL_ENABLE;\r
172         }else{\r
173                 LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_PWR;\r
174                 for(i=0;i<100000;i++);\r
175                 LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_ENABLE;\r
176         }\r
177 }\r
178 \r
179 \r
180 /*********************************************************************//**\r
181  * @brief               Enable/Disable the LCD Controller\r
182  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
183  * @param[in]   EnDis   Enable/disable status\r
184  *                                      - TRUE  :Enable\r
185  *                                      - FALSE :Disable\r
186  * @return              None\r
187  **********************************************************************/\r
188 void LCD_Enable(LPC_LCD_Type *LCDx, FunctionalState EnDis){\r
189         if (EnDis)\r
190         {\r
191           LCDx->CTRL |= CLCDC_LCDCTRL_ENABLE;\r
192         }\r
193         else\r
194         {\r
195           LCDx->CTRL &= ~CLCDC_LCDCTRL_ENABLE;\r
196         }\r
197 }\r
198 \r
199 \r
200 /*********************************************************************//**\r
201  * @brief               Set LCD Frame Buffer for Single Panel or Upper Panel Frame\r
202  *                              Buffer for Dual Panel\r
203  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
204  * @param[in]   buffer address of buffer\r
205  * @return              None\r
206  **********************************************************************/\r
207 void LCD_SetFrameBuffer(LPC_LCD_Type *LCDx, void* buffer){\r
208         LCDx->UPBASE = (uint32_t)buffer;\r
209 }\r
210 \r
211 \r
212 /*********************************************************************//**\r
213  * @brief               Set LCD Lower Panel Frame Buffer for Dual Panel\r
214  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
215  * @param[in]   buffer address of buffer\r
216  * @return              None\r
217  **********************************************************************/\r
218 void LCD_SetLPFrameBuffer(LPC_LCD_Type *LCDx, void* buffer){\r
219         LCDx->LPBASE = (uint32_t)buffer;\r
220 }\r
221 \r
222 \r
223 /*********************************************************************//**\r
224  * @brief               Configure Cursor\r
225  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
226  * @param[in]   cursor_size specify size of cursor\r
227  *                                      - LCD_CURSOR_32x32      :cursor size is 32x32 pixels\r
228  *                                      - LCD_CURSOR_64x64      :cursor size is 64x64 pixels\r
229  * @param[in]   sync cursor sync mode\r
230  *                                      - TRUE  :cursor sync to the frame sync pulse\r
231  *                                      - FALSE :cursor async mode\r
232  * @return              None\r
233  **********************************************************************/\r
234 void LCD_Cursor_Config(LPC_LCD_Type *LCDx, LCD_CURSOR_SIZE_OPT cursor_size, Bool sync){\r
235         LCD_Cursor_Size = cursor_size;\r
236         LCDx->CRSR_CFG = ((sync?1:0)<<1) | cursor_size;\r
237 }\r
238 \r
239 \r
240 /*********************************************************************//**\r
241  * @brief               Write Cursor Image into Internal Cursor Image Buffer\r
242  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
243  * @param[in]   cursor_num specify number of cursor is going to be written\r
244  *                              this param must < 4\r
245  * @param[in]   Image point to Cursor Image Buffer\r
246  * @return              None\r
247  **********************************************************************/\r
248 void LCD_Cursor_WriteImage(LPC_LCD_Type *LCDx, uint8_t cursor_num, void* Image){\r
249         int i,j;\r
250         uint8_t *fifoptr, *crsr_ptr = (uint8_t *)Image;\r
251 \r
252         CHECK_PARAM(cursor_num<4);\r
253         /* Check if Cursor Size was configured as 32x32 or 64x64*/\r
254         if(LCD_Cursor_Size == LCD_CURSOR_32x32){\r
255                 i = cursor_num * 256;\r
256                 j = i + 256;\r
257         }else{\r
258                 i = 0;\r
259                 j = 1024;\r
260         }\r
261         fifoptr = (uint8_t*)&(LCDx->CRSR_IMG[0]);\r
262         /* Copy Cursor Image content to FIFO */\r
263         for(; i < j; i++)\r
264         {\r
265           fifoptr[i] = *(uint8_t *)crsr_ptr;\r
266           crsr_ptr++;\r
267         }\r
268 }\r
269 \r
270 \r
271 /*********************************************************************//**\r
272  * @brief               Get Internal Cursor Image Buffer Address\r
273  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
274  * @param[in]   cursor_num specify number of cursor is going to be written\r
275  *                              this param must < 4\r
276  * @return              Cursor Image Buffer Address\r
277  **********************************************************************/\r
278 void* LCD_Cursor_GetImageBufferAddress(LPC_LCD_Type *LCDx, uint8_t cursor_num){\r
279         CHECK_PARAM(cursor_num<4);\r
280         return (void*)&(LCDx->CRSR_IMG[cursor_num*64]);\r
281 }\r
282 \r
283 \r
284 /*********************************************************************//**\r
285  * @brief               Enable Cursor\r
286  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
287  * @param[in]   cursor_num specify number of cursor is going to be written\r
288  *                              this param must < 4\r
289  * @param[in]   OnOff Turn on/off LCD\r
290  *                                      - TRUE  :Enable\r
291  *                                      - FALSE :Disable\r
292  * @return              None\r
293  **********************************************************************/\r
294 void LCD_Cursor_Enable(LPC_LCD_Type *LCDx, uint8_t cursor_num, FunctionalState OnOff){\r
295         CHECK_PARAM(cursor_num<4);\r
296         if (OnOff)\r
297         {\r
298           LCDx->CRSR_CTRL = (cursor_num<<4) | 1;\r
299         }\r
300         else\r
301         {\r
302           LCDx->CRSR_CTRL = (cursor_num<<4);\r
303         }\r
304 }\r
305 \r
306 \r
307 /*********************************************************************//**\r
308  * @brief               Load LCD Palette\r
309  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
310  * @param[in]   palette point to palette address\r
311  * @return              None\r
312  **********************************************************************/\r
313 void LCD_LoadPalette(LPC_LCD_Type *LCDx, void* palette){\r
314         LCD_PALETTE_ENTRY_Type pal_entry, *ptr_pal_entry;\r
315         uint8_t i, *pal_ptr;\r
316         /* This function supports loading of the color palette from\r
317         the C file generated by the bmp2c utility. It expects the\r
318         palette to be passed as an array of 32-bit BGR entries having\r
319         the following format:\r
320         2:0 - Not used\r
321         7:3 - Blue\r
322         10:8 - Not used\r
323         15:11 - Green\r
324         18:16 - Not used\r
325         23:19 - Red\r
326         31:24 - Not used\r
327         arg = pointer to input palette table address */\r
328         ptr_pal_entry = &pal_entry;\r
329         pal_ptr = (uint8_t *) palette;\r
330 \r
331         /* 256 entry in the palette table */\r
332         for(i = 0; i < 256/2; i++)\r
333         {\r
334         pal_entry.Bl = (*pal_ptr++) >> 3;  /* blue first */\r
335         pal_entry.Gl = (*pal_ptr++) >> 3;  /* get green */\r
336         pal_entry.Rl = (*pal_ptr++) >> 3;  /* get red */\r
337         pal_ptr++;      /* skip over the unused byte */\r
338         /* do the most significant halfword of the palette */\r
339         pal_entry.Bu = (*pal_ptr++) >> 3;  /* blue first */\r
340         pal_entry.Gu = (*pal_ptr++) >> 3;  /* get green */\r
341         pal_entry.Ru = (*pal_ptr++) >> 3;  /* get red */\r
342         pal_ptr++;      /* skip over the unused byte */\r
343 \r
344         LCDx->PAL[i] = *(uint32_t *)ptr_pal_entry;\r
345         }\r
346 }\r
347 \r
348 \r
349 /*********************************************************************//**\r
350  * @brief               Load Cursor Palette\r
351  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
352  * @param[in]   palette_color cursor palette 0 value\r
353  * @return              None\r
354  **********************************************************************/\r
355 void LCD_Cursor_LoadPalette0(LPC_LCD_Type *LCDx, uint32_t palette_color){\r
356         /* 7:0 - Red\r
357         15:8 - Green\r
358         23:16 - Blue\r
359         31:24 - Not used*/\r
360         LCDx->CRSR_PAL0 = (uint32_t)palette_color;\r
361 }\r
362 \r
363 \r
364 /*********************************************************************//**\r
365  * @brief               Load Cursor Palette\r
366  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
367  * @param[in]   palette_color cursor palette 1 value\r
368  * @return              None\r
369  **********************************************************************/\r
370 void LCD_Cursor_LoadPalette1(LPC_LCD_Type *LCDx, uint32_t palette_color){\r
371         /* 7:0 - Red\r
372         15:8 - Green\r
373         23:16 - Blue\r
374         31:24 - Not used*/\r
375         LCDx->CRSR_PAL1 = (uint32_t)palette_color;\r
376 }\r
377 \r
378 \r
379 /*********************************************************************//**\r
380  * @brief               Set Interrupt\r
381  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
382  * @param[in]   Int LCD Interrupt Source, should be:\r
383  *                                      - LCD_INT_FUF   :FIFO underflow\r
384  *                                      - LCD_INT_LNBU  :LCD next base address update bit\r
385  *                                      - LCD_INT_VCOMP :Vertical compare bit\r
386  *                                      - LCD_INT_BER   :AHB master error interrupt bit\r
387  * @return              None\r
388  **********************************************************************/\r
389 void LCD_SetInterrupt(LPC_LCD_Type *LCDx, LCD_INT_SRC Int){\r
390         LCDx->INTMSK |= Int;\r
391 }\r
392 \r
393 \r
394 /*********************************************************************//**\r
395  * @brief               Clear Interrupt\r
396  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
397  * @param[in]   Int LCD Interrupt Source, should be:\r
398  *                                      - LCD_INT_FUF   :FIFO underflow\r
399  *                                      - LCD_INT_LNBU  :LCD next base address update bit\r
400  *                                      - LCD_INT_VCOMP :Vertical compare bit\r
401  *                                      - LCD_INT_BER   :AHB master error interrupt bit\r
402  * @return              None\r
403  **********************************************************************/\r
404 void LCD_ClrInterrupt(LPC_LCD_Type *LCDx, LCD_INT_SRC Int){\r
405         LCDx->INTCLR |= Int;\r
406 }\r
407 \r
408 \r
409 /*********************************************************************//**\r
410  * @brief               Get LCD Interrupt Status\r
411  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
412  * @return              None\r
413  **********************************************************************/\r
414 LCD_INT_SRC LCD_GetInterrupt(LPC_LCD_Type *LCDx){\r
415         return (LCD_INT_SRC)LCDx->INTRAW;\r
416 }\r
417 \r
418 \r
419 /*********************************************************************//**\r
420  * @brief               Enable Cursor Interrupt\r
421  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
422  * @return              None\r
423  **********************************************************************/\r
424 void LCD_Cursor_SetInterrupt(LPC_LCD_Type *LCDx){\r
425         LCDx->CRSR_INTMSK |= 1;\r
426 }\r
427 \r
428 \r
429 /*********************************************************************//**\r
430  * @brief               Clear Cursor Interrupt\r
431  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
432  * @return              None\r
433  **********************************************************************/\r
434 void LCD_Cursor_ClrInterrupt(LPC_LCD_Type *LCDx){\r
435         LCDx->CRSR_INTCLR |= 1;\r
436 }\r
437 \r
438 \r
439 /*********************************************************************//**\r
440  * @brief               Set Cursor Position\r
441  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
442  * @param[in]   x horizontal position\r
443  * @param[in]   y vertical position\r
444  * @return              None\r
445  **********************************************************************/\r
446 void LCD_Cursor_SetPos(LPC_LCD_Type *LCDx, uint16_t x, uint16_t y){\r
447         LCDx->CRSR_XY = (x & 0x3FF) | ((y & 0x3FF) << 16);\r
448 }\r
449 \r
450 \r
451 /*********************************************************************//**\r
452  * @brief               Set Cursor Clipping Position\r
453  * @param[in]   LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD\r
454  * @param[in]   x horizontal position, should be in range: 0..63\r
455  * @param[in]   y vertical position, should be in range: 0..63\r
456  * @return              None\r
457  **********************************************************************/\r
458 void LCD_Cursor_SetClip(LPC_LCD_Type *LCDx, uint16_t x, uint16_t y){\r
459         LCDx->CRSR_CLIP = (x & 0x3F) | ((y & 0x3F) << 8);\r
460 }\r
461 #endif /* _LCD */\r
462 \r
463 /**\r
464  * @}\r
465  */\r
466 \r
467 /* --------------------------------- End Of File ------------------------------ */\r