]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/drivers/Atmel/at91lib/peripherals/lcd/lcd.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / Common / drivers / Atmel / at91lib / peripherals / lcd / lcd.c
1 /* ----------------------------------------------------------------------------\r
2  *         ATMEL Microcontroller Software Support \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2008, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 //------------------------------------------------------------------------------\r
31 //         Headers\r
32 //------------------------------------------------------------------------------\r
33 \r
34 #include "lcd.h"\r
35 #include <board.h>\r
36 #include <utility/assert.h>\r
37 \r
38 //------------------------------------------------------------------------------\r
39 //         Exported functions\r
40 //------------------------------------------------------------------------------\r
41 \r
42 //------------------------------------------------------------------------------\r
43 /// Enables the LCD controller, after waiting for the specified number of\r
44 /// frames.\r
45 /// \param frames  Number of frames before the LCD is enabled.\r
46 //------------------------------------------------------------------------------\r
47 void LCD_Enable(unsigned int frames)\r
48 {\r
49     ASSERT((frames & 0xFFFFFF80) == 0,\r
50            "LCD_Enable: Wrong frames value.\n\r");\r
51     AT91C_BASE_LCDC->LCDC_PWRCON = AT91C_LCDC_PWR | (frames << 1);\r
52 }\r
53 \r
54 //------------------------------------------------------------------------------\r
55 /// Disables the LCD controller, after waiting for the specified number of\r
56 /// frames.\r
57 /// \param frames  Number of frames before the LCD is shut down.\r
58 //------------------------------------------------------------------------------\r
59 void LCD_Disable(unsigned int frames)\r
60 {\r
61     ASSERT((frames & 0xFFFFFF80) == 0,\r
62            "LCD_Disable: Wrong frames value.\n\r");\r
63     AT91C_BASE_LCDC->LCDC_PWRCON = frames << 1;\r
64 }\r
65 \r
66 //------------------------------------------------------------------------------\r
67 /// Enables the DMA of the LCD controller.\r
68 //------------------------------------------------------------------------------\r
69 void LCD_EnableDma()\r
70 {\r
71     AT91C_BASE_LCDC->LCDC_DMACON = AT91C_LCDC_DMAEN;\r
72 }\r
73 \r
74 //------------------------------------------------------------------------------\r
75 /// Disables the DMA of the LCD controller.\r
76 //------------------------------------------------------------------------------\r
77 void LCD_DisableDma()\r
78 {\r
79     AT91C_BASE_LCDC->LCDC_DMACON = 0;\r
80 }\r
81 \r
82 //------------------------------------------------------------------------------\r
83 /// Configures the internal clock of the LCD controller given the master clock of\r
84 /// the system and the desired pixel clock in MHz.\r
85 /// \param masterClock  Master clock frequency.\r
86 /// \param pixelClock  Pixel clock frequency.\r
87 //------------------------------------------------------------------------------\r
88 void LCD_SetPixelClock(unsigned int masterClock, unsigned int pixelClock)\r
89 {\r
90     AT91C_BASE_LCDC->LCDC_LCDCON1 = ((masterClock / (2 * pixelClock)) - 1) << 12;\r
91 }\r
92 \r
93 //------------------------------------------------------------------------------\r
94 /// Sets the type of display used with the LCD controller.\r
95 /// \param displayType  Type of display used.\r
96 //------------------------------------------------------------------------------\r
97 void LCD_SetDisplayType(unsigned int displayType)\r
98 {\r
99     unsigned int value;\r
100 \r
101     ASSERT((displayType & ~AT91C_LCDC_DISTYPE) == 0,\r
102            "LCD_SetDisplayType: Wrong display type value.\n\r");\r
103 \r
104     value = AT91C_BASE_LCDC->LCDC_LCDCON2;\r
105     value &= ~AT91C_LCDC_DISTYPE;\r
106     value |= displayType;\r
107     AT91C_BASE_LCDC->LCDC_LCDCON2 = value;\r
108 }\r
109 \r
110 //------------------------------------------------------------------------------\r
111 /// Sets the scan mode used by the LCD (either single scan or double-scan).\r
112 /// \param scanMode  Scan mode to use.\r
113 //------------------------------------------------------------------------------\r
114 void LCD_SetScanMode(unsigned int scanMode)\r
115 {\r
116     unsigned int value;\r
117 \r
118     ASSERT((scanMode & ~AT91C_LCDC_SCANMOD) == 0,\r
119            "LCD_SetScanMode: Wrong scan mode value.\n\r");\r
120 \r
121     value = AT91C_BASE_LCDC->LCDC_LCDCON2;\r
122     value &= ~AT91C_LCDC_SCANMOD;\r
123     value |= scanMode;\r
124     AT91C_BASE_LCDC->LCDC_LCDCON2 = value;\r
125 }\r
126 \r
127 //------------------------------------------------------------------------------\r
128 /// Sets the number of bits per pixel used by the LCD display.\r
129 /// \param bitsPerPixel  Number of bits per pixel to use.\r
130 //------------------------------------------------------------------------------\r
131 void LCD_SetBitsPerPixel(unsigned int bitsPerPixel)\r
132 {\r
133     unsigned int value;\r
134 \r
135     ASSERT((bitsPerPixel & ~AT91C_LCDC_PIXELSIZE) == 0,\r
136            "LCD_SetScanMode: Wrong bitsPerPixel value.\n\r");\r
137 \r
138     value = AT91C_BASE_LCDC->LCDC_LCDCON2;\r
139     value &= ~AT91C_LCDC_PIXELSIZE;\r
140     value |= bitsPerPixel;\r
141     AT91C_BASE_LCDC->LCDC_LCDCON2 = value;\r
142 }\r
143 \r
144 //------------------------------------------------------------------------------\r
145 /// Sets the LCDD, LCDVSYNC, LCDHSYNC, LCDDOTCLK and LCDDEN signal polarities.\r
146 /// \param lcdd  LCDD signal polarity.\r
147 /// \param lcdvsync  LCDVSYNC signal polarity.\r
148 /// \param lcdhsync  LCDHSYNC signal polarity.\r
149 /// \param lcddotclk  LCDDOTCLK signal polarity.\r
150 /// \param lcdden  LCDDEN signal polarity.\r
151 //------------------------------------------------------------------------------\r
152 void LCD_SetPolarities(\r
153     unsigned int lcdd,\r
154     unsigned int lcdvsync,\r
155     unsigned int lcdhsync,\r
156     unsigned int lcddotclk,\r
157     unsigned int lcdden)\r
158 {\r
159     unsigned int value;\r
160 \r
161     ASSERT((lcdd & ~AT91C_LCDC_INVVD) == 0,\r
162            "LCD_SetPolarities: Wrong lcdd value.\n\r");\r
163     ASSERT((lcdvsync & ~AT91C_LCDC_INVFRAME) == 0,\r
164            "LCD_SetPolarities: Wrong lcdvsync value.\n\r");\r
165     ASSERT((lcdhsync & ~AT91C_LCDC_INVLINE) == 0,\r
166            "LCD_SetPolarities: Wrong lcdhsync value.\n\r");\r
167     ASSERT((lcddotclk & ~AT91C_LCDC_INVCLK) == 0,\r
168            "LCD_SetPolarities: Wrong lcddotclk value.\n\r");\r
169     ASSERT((lcdden & ~AT91C_LCDC_INVDVAL) == 0,\r
170            "LCD_SetPolarities: Wrong lcdden value.\n\r");\r
171 \r
172     value = AT91C_BASE_LCDC->LCDC_LCDCON2;\r
173     value &= 0xFFFFE0FF;\r
174     value |= lcdd | lcdvsync | lcdhsync | lcddotclk | lcdden;\r
175     AT91C_BASE_LCDC->LCDC_LCDCON2 = value;\r
176 }\r
177 \r
178 //------------------------------------------------------------------------------\r
179 /// Sets the LCD clock mode, i.e. always active or active only during display\r
180 /// period.\r
181 /// \param clockMode  Clock mode to use.\r
182 //------------------------------------------------------------------------------\r
183 void LCD_SetClockMode(unsigned int clockMode)\r
184 {\r
185     unsigned int value;\r
186 \r
187     ASSERT((clockMode & ~AT91C_LCDC_CLKMOD) == 0,\r
188            "LCD_SetScanMode: Wrong scan mode value.\n\r");\r
189 \r
190     value = AT91C_BASE_LCDC->LCDC_LCDCON2;\r
191     value &= ~AT91C_LCDC_CLKMOD;\r
192     value |= clockMode;\r
193     AT91C_BASE_LCDC->LCDC_LCDCON2 = value;\r
194 }\r
195 \r
196 //------------------------------------------------------------------------------\r
197 /// Sets the format of the frame buffer memory.\r
198 /// \param format  Memory ordering format.\r
199 //------------------------------------------------------------------------------\r
200 void LCD_SetMemoryFormat(unsigned int format)\r
201 {\r
202     unsigned int value;\r
203 \r
204     ASSERT((format & ~AT91C_LCDC_MEMOR) == 0,\r
205            "LCD_SetMemoryFormat: Wrong memory format value.\n\r");\r
206 \r
207     value = AT91C_BASE_LCDC->LCDC_LCDCON2;\r
208     value &= ~AT91C_LCDC_MEMOR;\r
209     value |= format;\r
210     AT91C_BASE_LCDC->LCDC_LCDCON2 = value;\r
211 }\r
212 \r
213 //------------------------------------------------------------------------------\r
214 /// Sets the size in pixel of the LCD display.\r
215 /// \param width  Width in pixel of the LCD display.\r
216 /// \param height  Height in pixel of the LCD display.\r
217 //------------------------------------------------------------------------------\r
218 void LCD_SetSize(unsigned int width, unsigned int height)\r
219 {\r
220     ASSERT(((width - 1) & 0xFFFFF800) == 0,\r
221            "LCD_SetSize: Wrong width value.\n\r");\r
222     ASSERT(((height - 1) & 0xFFFFF800) == 0,\r
223            "LCD_SetSize: Wrong height value.\n\r");\r
224 \r
225     AT91C_BASE_LCDC->LCDC_LCDFRCFG = ((width - 1) << 21) | (height - 1);\r
226 }\r
227 \r
228 //------------------------------------------------------------------------------\r
229 /// Sets the vertical timings of the LCD controller. Only meaningful when\r
230 /// using a TFT display.\r
231 /// \param vfp  Number of idle lines at the end of a frame.\r
232 /// \param vbp  Number of idle lines at the beginning of a frame.\r
233 /// \param vpw  Vertical synchronization pulse width in number of lines.\r
234 /// \param vhdly  Delay between LCDVSYNC edge and LCDHSYNC rising edge, in\r
235 ///               LCDDOTCLK cycles.\r
236 //------------------------------------------------------------------------------\r
237 void LCD_SetVerticalTimings(\r
238     unsigned int vfp,\r
239     unsigned int vbp,\r
240     unsigned int vpw,\r
241     unsigned int vhdly)\r
242 {\r
243     ASSERT((vfp & 0xFFFFFF00) == 0,\r
244            "LCD_SetVerticalTimings: Wrong vfp value.\n\r");\r
245     ASSERT((vbp & 0xFFFFFF00) == 0,\r
246            "LCD_SetVerticalTimings: Wrong vbp value.\n\r");\r
247     ASSERT(((vpw-1) & 0xFFFFFFC0) == 0,\r
248            "LCD_SetVerticalTimings: Wrong vpw value.\n\r");\r
249     ASSERT(((vhdly-1) & 0xFFFFFFF0) == 0,\r
250            "LCD_SetVerticalTimings: Wrong vhdly value.\n\r");\r
251 \r
252     AT91C_BASE_LCDC->LCDC_TIM1 = vfp\r
253                                  | (vbp << 8)\r
254                                  | ((vpw-1) << 16)\r
255                                  | ((vhdly-1) << 24);\r
256 }\r
257 \r
258 //------------------------------------------------------------------------------\r
259 /// Sets the horizontal timings of the LCD controller. Meaningful for both\r
260 /// STN and TFT displays.\r
261 /// \param hbp  Number of idle LCDDOTCLK cycles at the beginning of a line.\r
262 /// \param hpw  Width of the LCDHSYNC pulse, in LCDDOTCLK cycles.\r
263 /// \param hfp  Number of idel LCDDOTCLK cycles at the end of a line.\r
264 //------------------------------------------------------------------------------\r
265 void LCD_SetHorizontalTimings(\r
266     unsigned int hbp,\r
267     unsigned int hpw,\r
268     unsigned int hfp)\r
269 {\r
270     ASSERT(((hbp-1) & 0xFFFFFF00) == 0,\r
271            "LCD_SetHorizontalTimings: Wrong hbp value.\n\r");\r
272     ASSERT(((hpw-1) & 0xFFFFFFC0) == 0,\r
273            "LCD_SetHorizontalTimings: Wrong hpw value.\n\r");\r
274     ASSERT(((hfp-1) & 0xFFFFFF00) == 0,\r
275            "LCD_SetHorizontalTimings: Wrong hfp value.\n\r");\r
276 \r
277     AT91C_BASE_LCDC->LCDC_TIM2 = (hbp-1) | ((hpw-1) << 8) | ((hfp-1) << 24);\r
278 }\r
279 \r
280 //------------------------------------------------------------------------------\r
281 /// Sets the address of the frame buffer in the LCD controller DMA. When using\r
282 /// dual-scan mode, this is the upper frame buffer.\r
283 /// \param address  Frame buffer address.\r
284 //------------------------------------------------------------------------------\r
285 void LCD_SetFrameBufferAddress(void *address)\r
286 {\r
287     AT91C_BASE_LCDC->LCDC_BA1 = (unsigned int) address;\r
288 }\r
289 \r
290 //------------------------------------------------------------------------------\r
291 /// Sets the size in pixels of a frame (height * width * bpp).\r
292 /// \param frameSize  Size of frame in pixels.\r
293 //------------------------------------------------------------------------------\r
294 void LCD_SetFrameSize(unsigned int frameSize)\r
295 {\r
296     ASSERT((frameSize & 0xFF800000) == 0,\r
297            "LCD_SetFrameSize: Wrong frameSize value.\n\r");\r
298 \r
299     AT91C_BASE_LCDC->LCDC_FRMCFG = frameSize | (AT91C_BASE_LCDC->LCDC_FRMCFG & 0xFF000000);\r
300 }\r
301 \r
302 //------------------------------------------------------------------------------\r
303 /// Sets the DMA controller burst length.\r
304 /// \param burstLength  Desired burst length.\r
305 //------------------------------------------------------------------------------\r
306 void LCD_SetBurstLength(unsigned int burstLength)\r
307 {\r
308     ASSERT(((burstLength-1) & 0xFFFFFF80) == 0,\r
309            "LCD_SetBurstLength: Wrong burstLength value.\n\r");\r
310 \r
311     AT91C_BASE_LCDC->LCDC_FRMCFG &= 0x00FFFFFF;\r
312     AT91C_BASE_LCDC->LCDC_FRMCFG |= ((burstLength-1) << 24);\r
313 \r
314     AT91C_BASE_LCDC->LCDC_FIFO = 2048 - (2 * burstLength + 3);\r
315 }\r
316 \r
317 //------------------------------------------------------------------------------\r
318 /// Sets the prescaler value of the contrast control PWM.\r
319 /// \param prescaler  Desired prescaler value.\r
320 //------------------------------------------------------------------------------\r
321 void LCD_SetContrastPrescaler(unsigned int prescaler)\r
322 {\r
323     ASSERT((prescaler & ~AT91C_LCDC_PS) == 0,\r
324            "LCD_SetContrastPrescaler: Wrong prescaler value\n\r");\r
325 \r
326     AT91C_BASE_LCDC->LCDC_CTRSTCON &= ~AT91C_LCDC_PS;\r
327     AT91C_BASE_LCDC->LCDC_CTRSTCON |= prescaler;\r
328 }\r
329 \r
330 //------------------------------------------------------------------------------\r
331 /// Sets the polarity of the contrast PWM.\r
332 /// \param polarity  PWM polarity\r
333 //------------------------------------------------------------------------------\r
334 void LCD_SetContrastPolarity(unsigned int polarity)\r
335 {\r
336     ASSERT((polarity & ~AT91C_LCDC_POL) == 0,\r
337            "LCD_SetContrastPolarity: Wrong polarity value\n\r");\r
338 \r
339     AT91C_BASE_LCDC->LCDC_CTRSTCON &= ~AT91C_LCDC_POL;\r
340     AT91C_BASE_LCDC->LCDC_CTRSTCON |= polarity;\r
341 }\r
342 \r
343 //------------------------------------------------------------------------------\r
344 /// Sets the threshold value of the constrast PWM.\r
345 /// \param value  PWM threshold value.\r
346 //------------------------------------------------------------------------------\r
347 void LCD_SetContrastValue(unsigned int value)\r
348 {\r
349     ASSERT((value & ~AT91C_LCDC_CVAL) == 0,\r
350            "LCD_SetContrastValue: Wrong value.\n\r");\r
351 \r
352     AT91C_BASE_LCDC->LCDC_CTRSTVAL = value;\r
353 }\r
354 \r
355 //------------------------------------------------------------------------------\r
356 /// Enables the contrast PWM generator.\r
357 //------------------------------------------------------------------------------\r
358 void LCD_EnableContrast()\r
359 {\r
360     AT91C_BASE_LCDC->LCDC_CTRSTCON |= AT91C_LCDC_ENA_PWMGEMENABLED;\r
361 }\r
362 \r