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