1 /*This file is prepared for Doxygen automatic documentation generation.*/
\r
2 /*! \file *********************************************************************
\r
4 * \brief AT32UC3B EVK1101 board LEDs support package.
\r
6 * This file contains definitions and services related to the LED features of
\r
9 * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
\r
10 * - Supported devices: All AVR32 AT32UC3B devices can be used.
\r
13 * \author Atmel Corporation: http://www.atmel.com \n
\r
14 * Support and FAQ: http://support.atmel.no/
\r
16 ******************************************************************************/
\r
18 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
\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
23 * 1. Redistributions of source code must retain the above copyright notice,
\r
24 * this list of conditions and the following disclaimer.
\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
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
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
46 #include <avr32/io.h>
\r
47 #include "preprocessor.h"
\r
48 #include "compiler.h"
\r
49 #include "evk1101.h"
\r
53 //! Structure describing LED hardware connections.
\r
54 typedef const struct
\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
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
69 //! Hardware descriptors of all LEDs.
\r
70 static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] =
\r
72 #define INSERT_LED_DESCRIPTOR(LED_NO, unused) \
\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
77 MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~)
\r
78 #undef INSERT_LED_DESCRIPTOR
\r
82 //! Saved state of all LEDs.
\r
83 static volatile U32 LED_State = (1 << LED_COUNT) - 1;
\r
86 U32 LED_Read_Display(void)
\r
92 void LED_Display(U32 leds)
\r
94 tLED_DESCRIPTOR *led_descriptor;
\r
95 volatile avr32_gpio_port_t *led_gpio_port;
\r
97 leds &= (1 << LED_COUNT) - 1;
\r
99 for (led_descriptor = &LED_DESCRIPTOR[0];
\r
100 led_descriptor < LED_DESCRIPTOR + LED_COUNT;
\r
103 led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
\r
106 led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
\r
110 led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
\r
112 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
113 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
119 U32 LED_Read_Display_Mask(U32 mask)
\r
121 return Rd_bits(LED_State, mask);
\r
125 void LED_Display_Mask(U32 mask, U32 leds)
\r
127 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
128 volatile avr32_gpio_port_t *led_gpio_port;
\r
131 mask &= (1 << LED_COUNT) - 1;
\r
132 Wr_bits(LED_State, mask, leds);
\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
141 led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK;
\r
145 led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK;
\r
147 led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
\r
148 led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
\r
150 mask >>= led_shift;
\r
155 Bool LED_Test(U32 leds)
\r
157 return Tst_bits(LED_State, leds);
\r
161 void LED_Off(U32 leds)
\r
163 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
164 volatile avr32_gpio_port_t *led_gpio_port;
\r
167 leds &= (1 << LED_COUNT) - 1;
\r
168 Clr_bits(LED_State, leds);
\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
182 void LED_On(U32 leds)
\r
184 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
185 volatile avr32_gpio_port_t *led_gpio_port;
\r
188 leds &= (1 << LED_COUNT) - 1;
\r
189 Set_bits(LED_State, leds);
\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
203 void LED_Toggle(U32 leds)
\r
205 tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
\r
206 volatile avr32_gpio_port_t *led_gpio_port;
\r
209 leds &= (1 << LED_COUNT) - 1;
\r
210 Tgl_bits(LED_State, leds);
\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
224 U32 LED_Read_Display_Field(U32 field)
\r
226 return Rd_bitfield(LED_State, field);
\r
230 void LED_Display_Field(U32 field, U32 leds)
\r
232 LED_Display_Mask(field, leds << ctz(field));
\r
236 U8 LED_Get_Intensity(U32 led)
\r
238 tLED_DESCRIPTOR *led_descriptor;
\r
240 // Check that the argument value is valid.
\r
242 led_descriptor = &LED_DESCRIPTOR[led];
\r
243 if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0;
\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
251 void LED_Set_Intensity(U32 leds, U8 intensity)
\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
258 // For each specified LED...
\r
259 for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift)
\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
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
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
281 while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL)));
\r
282 led_pwm_channel->cupd = intensity;
\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
289 led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK;
\r
293 led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK;
\r
295 if (led_descriptor->PWM.FUNCTION & 0x2)
\r
297 led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK;
\r
301 led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK;
\r
303 led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK;
\r