1 /* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
\r
3 /*This file is prepared for Doxygen automatic documentation generation.*/
\r
4 /*! \file *********************************************************************
\r
6 * \brief AT32UC3A EVK1100 board LEDs support package.
\r
8 * This file contains definitions and services related to the LED features of
\r
11 * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
\r
12 * - Supported devices: All AVR32 AT32UC3A devices can be used.
\r
15 * \author Atmel Corporation: http://www.atmel.com \n
\r
16 * Support and FAQ: http://support.atmel.no/
\r
18 ******************************************************************************/
\r
20 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
\r
22 * Redistribution and use in source and binary forms, with or without
\r
23 * modification, are permitted provided that the following conditions are met:
\r
25 * 1. Redistributions of source code must retain the above copyright notice, this
\r
26 * list of conditions and the following disclaimer.
\r
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
29 * this list of conditions and the following disclaimer in the documentation
\r
30 * and/or other materials provided with the distribution.
\r
32 * 3. The name of Atmel may not be used to endorse or promote products derived
\r
33 * from this software without specific prior written permission.
\r
35 * 4. This software may only be redistributed and used in connection with an Atmel
\r
38 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
\r
39 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
40 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
41 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
\r
42 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
\r
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
\r
51 #include <avr32/io.h>
\r
52 #include "preprocessor.h"
\r
53 #include "compiler.h"
\r
54 #include "evk1100.h"
\r
58 //! Structure describing LED hardware connections.
\r
59 typedef const struct
\r
63 U32 PORT; //!< LED GPIO port.
\r
64 U32 PIN_MASK; //!< Bit-mask of LED pin in GPIO port.
\r
65 } GPIO; //!< LED GPIO descriptor.
\r
68 S32 CHANNEL; //!< LED PWM channel (< 0 if N/A).
\r
69 S32 FUNCTION; //!< LED pin PWM function (< 0 if N/A).
\r
70 } PWM; //!< LED PWM descriptor.
\r
74 //! Hardware descriptors of all LEDs.
\r
75 static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] =
\r
77 #define INSERT_LED_DESCRIPTOR(LED_NO, unused) \
\r
79 {LED##LED_NO##_GPIO / 32, 1 << (LED##LED_NO##_GPIO % 32)},\
\r
80 {LED##LED_NO##_PWM, LED##LED_NO##_PWM_FUNCTION } \
\r
82 MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~)
\r
83 #undef INSERT_LED_DESCRIPTOR
\r
87 //! Saved state of all LEDs.
\r
88 static volatile U32 LED_State = (1 << LED_COUNT) - 1;
\r
91 U32 LED_Read_Display(void)
\r
97 void LED_Display(U32 leds)
\r
99 // Use the LED descriptors to get the connections of a given LED to the MCU.
\r
100 tLED_DESCRIPTOR *led_descriptor;
\r
101 volatile avr32_gpio_port_t *led_gpio_port;
\r
103 // Make sure only existing LEDs are specified.
\r
104 leds &= (1 << LED_COUNT) - 1;
\r
106 // Update the saved state of all LEDs with the requested changes.
\r
110 for (led_descriptor = &LED_DESCRIPTOR[0];
\r
111 led_descriptor < LED_DESCRIPTOR + LED_COUNT;
\r
114 // Set the LED to the requested state.
\r
115 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
118 led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
\r
122 led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
\r
124 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
125 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
131 U32 LED_Read_Display_Mask(U32 mask)
\r
133 return Rd_bits(LED_State, mask);
\r
137 void LED_Display_Mask(U32 mask, U32 leds)
\r
139 // Use the LED descriptors to get the connections of a given LED to the MCU.
\r
140 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
141 volatile avr32_gpio_port_t *led_gpio_port;
\r
144 // Make sure only existing LEDs are specified.
\r
145 mask &= (1 << LED_COUNT) - 1;
\r
147 // Update the saved state of all LEDs with the requested changes.
\r
148 Wr_bits(LED_State, mask, leds);
\r
150 // While there are specified LEDs left to manage...
\r
153 // Select the next specified LED and set it to the requested state.
\r
154 led_shift = 1 + ctz(mask);
\r
155 led_descriptor += led_shift;
\r
156 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
157 leds >>= led_shift - 1;
\r
160 led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
\r
164 led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
\r
166 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
167 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
169 mask >>= led_shift;
\r
174 Bool LED_Test(U32 leds)
\r
176 return Tst_bits(LED_State, leds);
\r
180 void LED_Off(U32 leds)
\r
182 // Use the LED descriptors to get the connections of a given LED to the MCU.
\r
183 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
184 volatile avr32_gpio_port_t *led_gpio_port;
\r
187 // Make sure only existing LEDs are specified.
\r
188 leds &= (1 << LED_COUNT) - 1;
\r
190 // Update the saved state of all LEDs with the requested changes.
\r
191 Clr_bits(LED_State, leds);
\r
193 // While there are specified LEDs left to manage...
\r
196 // Select the next specified LED and turn it off.
\r
197 led_shift = 1 + ctz(leds);
\r
198 led_descriptor += led_shift;
\r
199 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
200 led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
\r
201 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
202 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
203 leds >>= led_shift;
\r
208 void LED_On(U32 leds)
\r
210 // Use the LED descriptors to get the connections of a given LED to the MCU.
\r
211 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
212 volatile avr32_gpio_port_t *led_gpio_port;
\r
215 // Make sure only existing LEDs are specified.
\r
216 leds &= (1 << LED_COUNT) - 1;
\r
218 // Update the saved state of all LEDs with the requested changes.
\r
219 Set_bits(LED_State, leds);
\r
221 // While there are specified LEDs left to manage...
\r
224 // Select the next specified LED and turn it on.
\r
225 led_shift = 1 + ctz(leds);
\r
226 led_descriptor += led_shift;
\r
227 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
228 led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
\r
229 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
230 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
231 leds >>= led_shift;
\r
236 void LED_Toggle(U32 leds)
\r
238 // Use the LED descriptors to get the connections of a given LED to the MCU.
\r
239 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
240 volatile avr32_gpio_port_t *led_gpio_port;
\r
243 // Make sure only existing LEDs are specified.
\r
244 leds &= (1 << LED_COUNT) - 1;
\r
246 // Update the saved state of all LEDs with the requested changes.
\r
247 Tgl_bits(LED_State, leds);
\r
249 // While there are specified LEDs left to manage...
\r
252 // Select the next specified LED and toggle it.
\r
253 led_shift = 1 + ctz(leds);
\r
254 led_descriptor += led_shift;
\r
255 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
256 led_gpio_port->ovrt = led_descriptor->GPIO.PIN_MASK;
\r
257 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
258 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
259 leds >>= led_shift;
\r
264 U32 LED_Read_Display_Field(U32 field)
\r
266 return Rd_bitfield(LED_State, field);
\r
270 void LED_Display_Field(U32 field, U32 leds)
\r
272 // Move the bit-field to the appropriate position for the bit-mask.
\r
273 LED_Display_Mask(field, leds << ctz(field));
\r
277 U8 LED_Get_Intensity(U32 led)
\r
279 tLED_DESCRIPTOR *led_descriptor;
\r
281 // Check that the argument value is valid.
\r
283 led_descriptor = &LED_DESCRIPTOR[led];
\r
284 if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0;
\r
286 // Return the duty cycle value if the LED PWM channel is enabled, else 0.
\r
287 return (AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)) ?
\r
288 AVR32_PWM.channel[led_descriptor->PWM.CHANNEL].cdty : 0;
\r
292 void LED_Set_Intensity(U32 leds, U8 intensity)
\r
294 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
295 volatile avr32_pwm_channel_t *led_pwm_channel;
\r
296 volatile avr32_gpio_port_t *led_gpio_port;
\r
299 // For each specified LED...
\r
300 for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift)
\r
302 // Select the next specified LED and check that it has a PWM channel.
\r
303 led_shift = 1 + ctz(leds);
\r
304 led_descriptor += led_shift;
\r
305 if (led_descriptor->PWM.CHANNEL < 0) continue;
\r
307 // Initialize or update the LED PWM channel.
\r
308 led_pwm_channel = &AVR32_PWM.channel[led_descriptor->PWM.CHANNEL];
\r
309 if (!(AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)))
\r
311 led_pwm_channel->cmr = (AVR32_PWM_CPRE_MCK << AVR32_PWM_CPRE_OFFSET) &
\r
312 ~(AVR32_PWM_CALG_MASK |
\r
313 AVR32_PWM_CPOL_MASK |
\r
314 AVR32_PWM_CPD_MASK);
\r
315 led_pwm_channel->cprd = 0x000000FF;
\r
316 led_pwm_channel->cdty = intensity;
\r
317 AVR32_PWM.ena = 1 << led_descriptor->PWM.CHANNEL;
\r
322 while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL)));
\r
323 led_pwm_channel->cupd = intensity;
\r
326 // Switch the LED pin to its PWM function.
\r
327 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
328 if (led_descriptor->PWM.FUNCTION & 0x1)
\r
330 led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK;
\r
334 led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK;
\r
336 if (led_descriptor->PWM.FUNCTION & 0x2)
\r
338 led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK;
\r
342 led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK;
\r
344 led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK;
\r