]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/AVR32_UC3/BOARDS/EVK1101/led.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / AVR32_UC3 / BOARDS / EVK1101 / led.c
1 /*This file is prepared for Doxygen automatic documentation generation.*/\r
2 /*! \file *********************************************************************\r
3  *\r
4  * \brief AT32UC3B EVK1101 board LEDs support package.\r
5  *\r
6  * This file contains definitions and services related to the LED features of\r
7  * the EVK1101 board.\r
8  *\r
9  * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32\r
10  * - Supported devices:  All AVR32 AT32UC3B devices can be used.\r
11  * - AppNote:\r
12  *\r
13  * \author               Atmel Corporation: http://www.atmel.com \n\r
14  *                       Support and FAQ: http://support.atmel.no/\r
15  *\r
16  ******************************************************************************/\r
17 \r
18 /* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
19  *\r
20  * Redistribution and use in source and binary forms, with or without\r
21  * modification, are permitted provided that the following conditions are met:\r
22  *\r
23  * 1. Redistributions of source code must retain the above copyright notice,\r
24  * this list of conditions and the following disclaimer.\r
25  *\r
26  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
27  * this list of conditions and the following disclaimer in the documentation\r
28  * and/or other materials provided with the distribution.\r
29  *\r
30  * 3. The name of ATMEL may not be used to endorse or promote products derived\r
31  * from this software without specific prior written permission.\r
32  *\r
33  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
34  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
35  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
36  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
37  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
38  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
39  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
40  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
41  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
42  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
43  */\r
44 \r
45 \r
46 #include <avr32/io.h>\r
47 #include "preprocessor.h"\r
48 #include "compiler.h"\r
49 #include "evk1101.h"\r
50 #include "led.h"\r
51 \r
52 \r
53 //! Structure describing LED hardware connections.\r
54 typedef const struct\r
55 {\r
56   struct\r
57   {\r
58     U32 PORT;     //!< LED GPIO port.\r
59     U32 PIN_MASK; //!< Bit-mask of LED pin in GPIO port.\r
60   } GPIO; //!< LED GPIO descriptor.\r
61   struct\r
62   {\r
63     S32 CHANNEL;  //!< LED PWM channel (< 0 if N/A).\r
64     S32 FUNCTION; //!< LED pin PWM function (< 0 if N/A).\r
65   } PWM;  //!< LED PWM descriptor.\r
66 } tLED_DESCRIPTOR;\r
67 \r
68 \r
69 //! Hardware descriptors of all LEDs.\r
70 static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] =\r
71 {\r
72 #define INSERT_LED_DESCRIPTOR(LED_NO, unused)                 \\r
73   {                                                           \\r
74     {LED##LED_NO##_GPIO / 32, 1 << (LED##LED_NO##_GPIO % 32)},\\r
75     {LED##LED_NO##_PWM,       LED##LED_NO##_PWM_FUNCTION    } \\r
76   },\r
77   MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~)\r
78 #undef INSERT_LED_DESCRIPTOR\r
79 };\r
80 \r
81 \r
82 //! Saved state of all LEDs.\r
83 static volatile U32 LED_State = (1 << LED_COUNT) - 1;\r
84 \r
85 \r
86 U32 LED_Read_Display(void)\r
87 {\r
88   return LED_State;\r
89 }\r
90 \r
91 \r
92 void LED_Display(U32 leds)\r
93 {\r
94   tLED_DESCRIPTOR *led_descriptor;\r
95   volatile avr32_gpio_port_t *led_gpio_port;\r
96 \r
97   leds &= (1 << LED_COUNT) - 1;\r
98   LED_State = leds;\r
99   for (led_descriptor = &LED_DESCRIPTOR[0];\r
100        led_descriptor < LED_DESCRIPTOR + LED_COUNT;\r
101        led_descriptor++)\r
102   {\r
103     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];\r
104     if (leds & 1)\r
105     {\r
106       led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;\r
107     }\r
108     else\r
109     {\r
110       led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;\r
111     }\r
112     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;\r
113     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;\r
114     leds >>= 1;\r
115   }\r
116 }\r
117 \r
118 \r
119 U32 LED_Read_Display_Mask(U32 mask)\r
120 {\r
121   return Rd_bits(LED_State, mask);\r
122 }\r
123 \r
124 \r
125 void LED_Display_Mask(U32 mask, U32 leds)\r
126 {\r
127   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;\r
128   volatile avr32_gpio_port_t *led_gpio_port;\r
129   U8 led_shift;\r
130 \r
131   mask &= (1 << LED_COUNT) - 1;\r
132   Wr_bits(LED_State, mask, leds);\r
133   while (mask)\r
134   {\r
135     led_shift = 1 + ctz(mask);\r
136     led_descriptor += led_shift;\r
137     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];\r
138     leds >>= led_shift - 1;\r
139     if (leds & 1)\r
140     {\r
141       led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;\r
142     }\r
143     else\r
144     {\r
145       led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;\r
146     }\r
147     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;\r
148     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;\r
149     leds >>= 1;\r
150     mask >>= led_shift;\r
151   }\r
152 }\r
153 \r
154 \r
155 Bool LED_Test(U32 leds)\r
156 {\r
157   return Tst_bits(LED_State, leds);\r
158 }\r
159 \r
160 \r
161 void LED_Off(U32 leds)\r
162 {\r
163   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;\r
164   volatile avr32_gpio_port_t *led_gpio_port;\r
165   U8 led_shift;\r
166 \r
167   leds &= (1 << LED_COUNT) - 1;\r
168   Clr_bits(LED_State, leds);\r
169   while (leds)\r
170   {\r
171     led_shift = 1 + ctz(leds);\r
172     led_descriptor += led_shift;\r
173     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];\r
174     led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;\r
175     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;\r
176     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;\r
177     leds >>= led_shift;\r
178   }\r
179 }\r
180 \r
181 \r
182 void LED_On(U32 leds)\r
183 {\r
184   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;\r
185   volatile avr32_gpio_port_t *led_gpio_port;\r
186   U8 led_shift;\r
187 \r
188   leds &= (1 << LED_COUNT) - 1;\r
189   Set_bits(LED_State, leds);\r
190   while (leds)\r
191   {\r
192     led_shift = 1 + ctz(leds);\r
193     led_descriptor += led_shift;\r
194     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];\r
195     led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;\r
196     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;\r
197     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;\r
198     leds >>= led_shift;\r
199   }\r
200 }\r
201 \r
202 \r
203 void LED_Toggle(U32 leds)\r
204 {\r
205   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;\r
206   volatile avr32_gpio_port_t *led_gpio_port;\r
207   U8 led_shift;\r
208 \r
209   leds &= (1 << LED_COUNT) - 1;\r
210   Tgl_bits(LED_State, leds);\r
211   while (leds)\r
212   {\r
213     led_shift = 1 + ctz(leds);\r
214     led_descriptor += led_shift;\r
215     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];\r
216     led_gpio_port->ovrt  = led_descriptor->GPIO.PIN_MASK;\r
217     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;\r
218     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;\r
219     leds >>= led_shift;\r
220   }\r
221 }\r
222 \r
223 \r
224 U32 LED_Read_Display_Field(U32 field)\r
225 {\r
226   return Rd_bitfield(LED_State, field);\r
227 }\r
228 \r
229 \r
230 void LED_Display_Field(U32 field, U32 leds)\r
231 {\r
232   LED_Display_Mask(field, leds << ctz(field));\r
233 }\r
234 \r
235 \r
236 U8 LED_Get_Intensity(U32 led)\r
237 {\r
238   tLED_DESCRIPTOR *led_descriptor;\r
239 \r
240   // Check that the argument value is valid.\r
241   led = ctz(led);\r
242   led_descriptor = &LED_DESCRIPTOR[led];\r
243   if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0;\r
244 \r
245   // Return the duty cycle value if the LED PWM channel is enabled, else 0.\r
246   return (AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)) ?\r
247            AVR32_PWM.channel[led_descriptor->PWM.CHANNEL].cdty : 0;\r
248 }\r
249 \r
250 \r
251 void LED_Set_Intensity(U32 leds, U8 intensity)\r
252 {\r
253   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;\r
254   volatile avr32_pwm_channel_t *led_pwm_channel;\r
255   volatile avr32_gpio_port_t *led_gpio_port;\r
256   U8 led_shift;\r
257 \r
258   // For each specified LED...\r
259   for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift)\r
260   {\r
261     // Select the next specified LED and check that it has a PWM channel.\r
262     led_shift = 1 + ctz(leds);\r
263     led_descriptor += led_shift;\r
264     if (led_descriptor->PWM.CHANNEL < 0) continue;\r
265 \r
266     // Initialize or update the LED PWM channel.\r
267     led_pwm_channel = &AVR32_PWM.channel[led_descriptor->PWM.CHANNEL];\r
268     if (!(AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)))\r
269     {\r
270       led_pwm_channel->cmr = (AVR32_PWM_CPRE_MCK << AVR32_PWM_CPRE_OFFSET) &\r
271                              ~(AVR32_PWM_CALG_MASK |\r
272                                AVR32_PWM_CPOL_MASK |\r
273                                AVR32_PWM_CPD_MASK);\r
274       led_pwm_channel->cprd = 0x000000FF;\r
275       led_pwm_channel->cdty = intensity;\r
276       AVR32_PWM.ena = 1 << led_descriptor->PWM.CHANNEL;\r
277     }\r
278     else\r
279     {\r
280       AVR32_PWM.isr;\r
281       while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL)));\r
282       led_pwm_channel->cupd = intensity;\r
283     }\r
284 \r
285     // Switch the LED pin to its PWM function.\r
286     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];\r
287     if (led_descriptor->PWM.FUNCTION & 0x1)\r
288     {\r
289       led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK;\r
290     }\r
291     else\r
292     {\r
293       led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK;\r
294     }\r
295     if (led_descriptor->PWM.FUNCTION & 0x2)\r
296     {\r
297       led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK;\r
298     }\r
299     else\r
300     {\r
301       led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK;\r
302     }\r
303     led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK;\r
304   }\r
305 }\r