1 /* ----------------------------------------------------------------------------
\r
2 * ATMEL Microcontroller Software Support
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2008, Atmel Corporation
\r
6 * All rights reserved.
\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
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\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
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
30 //------------------------------------------------------------------------------
\r
32 //------------------------------------------------------------------------------
\r
36 #include <utility/assert.h>
\r
38 //------------------------------------------------------------------------------
\r
39 // Exported functions
\r
40 //------------------------------------------------------------------------------
\r
42 //------------------------------------------------------------------------------
\r
43 /// Enables the LCD controller, after waiting for the specified number of
\r
45 /// \param frames Number of frames before the LCD is enabled.
\r
46 //------------------------------------------------------------------------------
\r
47 void LCD_Enable(unsigned int frames)
\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
54 //------------------------------------------------------------------------------
\r
55 /// Disables the LCD controller, after waiting for the specified number of
\r
57 /// \param frames Number of frames before the LCD is shut down.
\r
58 //------------------------------------------------------------------------------
\r
59 void LCD_Disable(unsigned int frames)
\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
66 //------------------------------------------------------------------------------
\r
67 /// Enables the DMA of the LCD controller.
\r
68 //------------------------------------------------------------------------------
\r
69 void LCD_EnableDma()
\r
71 AT91C_BASE_LCDC->LCDC_DMACON = AT91C_LCDC_DMAEN;
\r
74 //------------------------------------------------------------------------------
\r
75 /// Disables the DMA of the LCD controller.
\r
76 //------------------------------------------------------------------------------
\r
77 void LCD_DisableDma()
\r
79 AT91C_BASE_LCDC->LCDC_DMACON = 0;
\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
90 AT91C_BASE_LCDC->LCDC_LCDCON1 = ((masterClock / (2 * pixelClock)) - 1) << 12;
\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
101 ASSERT((displayType & ~AT91C_LCDC_DISTYPE) == 0,
\r
102 "LCD_SetDisplayType: Wrong display type value.\n\r");
\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
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
116 unsigned int value;
\r
118 ASSERT((scanMode & ~AT91C_LCDC_SCANMOD) == 0,
\r
119 "LCD_SetScanMode: Wrong scan mode value.\n\r");
\r
121 value = AT91C_BASE_LCDC->LCDC_LCDCON2;
\r
122 value &= ~AT91C_LCDC_SCANMOD;
\r
124 AT91C_BASE_LCDC->LCDC_LCDCON2 = value;
\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
133 unsigned int value;
\r
135 ASSERT((bitsPerPixel & ~AT91C_LCDC_PIXELSIZE) == 0,
\r
136 "LCD_SetScanMode: Wrong bitsPerPixel value.\n\r");
\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
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
154 unsigned int lcdvsync,
\r
155 unsigned int lcdhsync,
\r
156 unsigned int lcddotclk,
\r
157 unsigned int lcdden)
\r
159 unsigned int value;
\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
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
178 //------------------------------------------------------------------------------
\r
179 /// Sets the LCD clock mode, i.e. always active or active only during display
\r
181 /// \param clockMode Clock mode to use.
\r
182 //------------------------------------------------------------------------------
\r
183 void LCD_SetClockMode(unsigned int clockMode)
\r
185 unsigned int value;
\r
187 ASSERT((clockMode & ~AT91C_LCDC_CLKMOD) == 0,
\r
188 "LCD_SetScanMode: Wrong scan mode value.\n\r");
\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
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
202 unsigned int value;
\r
204 ASSERT((format & ~AT91C_LCDC_MEMOR) == 0,
\r
205 "LCD_SetMemoryFormat: Wrong memory format value.\n\r");
\r
207 value = AT91C_BASE_LCDC->LCDC_LCDCON2;
\r
208 value &= ~AT91C_LCDC_MEMOR;
\r
210 AT91C_BASE_LCDC->LCDC_LCDCON2 = value;
\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
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
225 AT91C_BASE_LCDC->LCDC_LCDFRCFG = ((width - 1) << 21) | (height - 1);
\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
241 unsigned int vhdly)
\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
252 AT91C_BASE_LCDC->LCDC_TIM1 = vfp
\r
255 | ((vhdly-1) << 24);
\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
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
277 AT91C_BASE_LCDC->LCDC_TIM2 = (hbp-1) | ((hpw-1) << 8) | ((hfp-1) << 24);
\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
287 AT91C_BASE_LCDC->LCDC_BA1 = (unsigned int) address;
\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
296 ASSERT((frameSize & 0xFF800000) == 0,
\r
297 "LCD_SetFrameSize: Wrong frameSize value.\n\r");
\r
299 AT91C_BASE_LCDC->LCDC_FRMCFG = frameSize | (AT91C_BASE_LCDC->LCDC_FRMCFG & 0xFF000000);
\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
308 ASSERT(((burstLength-1) & 0xFFFFFF80) == 0,
\r
309 "LCD_SetBurstLength: Wrong burstLength value.\n\r");
\r
311 AT91C_BASE_LCDC->LCDC_FRMCFG &= 0x00FFFFFF;
\r
312 AT91C_BASE_LCDC->LCDC_FRMCFG |= ((burstLength-1) << 24);
\r
314 AT91C_BASE_LCDC->LCDC_FIFO = 2048 - (2 * burstLength + 3);
\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
323 ASSERT((prescaler & ~AT91C_LCDC_PS) == 0,
\r
324 "LCD_SetContrastPrescaler: Wrong prescaler value\n\r");
\r
326 AT91C_BASE_LCDC->LCDC_CTRSTCON &= ~AT91C_LCDC_PS;
\r
327 AT91C_BASE_LCDC->LCDC_CTRSTCON |= prescaler;
\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
336 ASSERT((polarity & ~AT91C_LCDC_POL) == 0,
\r
337 "LCD_SetContrastPolarity: Wrong polarity value\n\r");
\r
339 AT91C_BASE_LCDC->LCDC_CTRSTCON &= ~AT91C_LCDC_POL;
\r
340 AT91C_BASE_LCDC->LCDC_CTRSTCON |= polarity;
\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
349 ASSERT((value & ~AT91C_LCDC_CVAL) == 0,
\r
350 "LCD_SetContrastValue: Wrong value.\n\r");
\r
352 AT91C_BASE_LCDC->LCDC_CTRSTVAL = value;
\r
355 //------------------------------------------------------------------------------
\r
356 /// Enables the contrast PWM generator.
\r
357 //------------------------------------------------------------------------------
\r
358 void LCD_EnableContrast()
\r
360 AT91C_BASE_LCDC->LCDC_CTRSTCON |= AT91C_LCDC_ENA_PWMGEMENABLED;
\r