- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# led.c

Go to the documentation of this file.

    00001 /*This file is prepared for Doxygen automatic documentation generation.*/
    00018 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
    00019  *
    00020  * Redistribution and use in source and binary forms, with or without
    00021  * modification, are permitted provided that the following conditions are met:
    00022  *
    00023  * 1. Redistributions of source code must retain the above copyright notice, this
    00024  * list of conditions and the following disclaimer.
    00025  *
    00026  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00027  * this list of conditions and the following disclaimer in the documentation
    00028  * and/or other materials provided with the distribution.
    00029  *
    00030  * 3. The name of Atmel may not be used to endorse or promote products derived
    00031  * from this software without specific prior written permission.
    00032  *
    00033  * 4. This software may only be redistributed and used in connection with an Atmel
    00034  * AVR product.
    00035  *
    00036  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
    00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00038  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
    00039  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
    00040  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00041  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00042  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00044  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    00045  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
    00046  *
    00047  */
    00048
    00049 #include <avr32/io.h>
    00050 #include "preprocessor.h"
    00051 #include "compiler.h"
    00052 #include "uc3l_ek.h"
    00053 #include "led.h"
    00054
    00055
    00057 typedef const struct
    00058 {
    00059   struct
    00060   {
    00061     U32 PORT;
    00062     U32 PIN_MASK;
    00063   } GPIO;
    00064   struct
    00065   {
    00066     S32 CHANNEL;
    00067     S32 FUNCTION;
    00068   } PWM;
    00069 } tLED_DESCRIPTOR;
    00070
    00071
    00073 static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] =
    00074 {
    00075 #define INSERT_LED_DESCRIPTOR(LED_NO, unused)                 \
    00076   {                                                           \
    00077     {LED##LED_NO##_GPIO / 32, 1 << (LED##LED_NO##_GPIO % 32)},\
    00078     {LED##LED_NO##_PWM,       LED##LED_NO##_PWM_FUNCTION    } \
    00079   },
    00080   MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~)
    00081 #undef INSERT_LED_DESCRIPTOR
    00082 };
    00083
    00084
    00086 static volatile U32 LED_State = (1 << LED_COUNT) - 1;
    00087
    00088
    00089 U32 LED_Read_Display(void)
    00090 {
    00091   return LED_State;
    00092 }
    00093
    00094
    00095 void LED_Display(U32 leds)
    00096 {
    00097   // Use the LED descriptors to get the connections of a given LED to the MCU.
    00098   tLED_DESCRIPTOR *led_descriptor;
    00099   volatile avr32_gpio_port_t *led_gpio_port;
    00100
    00101   // Make sure only existing LEDs are specified.
    00102   leds &= (1 << LED_COUNT) - 1;
    00103
    00104   // Update the saved state of all LEDs with the requested changes.
    00105   LED_State = leds;
    00106
    00107   // For all LEDs...
    00108   for (led_descriptor = &LED_DESCRIPTOR[0];
    00109        led_descriptor < LED_DESCRIPTOR + LED_COUNT;
    00110        led_descriptor++)
    00111   {
    00112     // Set the LED to the requested state.
    00113     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    00114     if (leds & 1)
    00115     {
    00116       led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;
    00117     }
    00118     else
    00119     {
    00120       led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;
    00121     }
    00122     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    00123     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    00124     leds >>= 1;
    00125   }
    00126 }
    00127
    00128
    00129 U32 LED_Read_Display_Mask(U32 mask)
    00130 {
    00131   return Rd_bits(LED_State, mask);
    00132 }
    00133
    00134
    00135 void LED_Display_Mask(U32 mask, U32 leds)
    00136 {
    00137   // Use the LED descriptors to get the connections of a given LED to the MCU.
    00138   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
    00139   volatile avr32_gpio_port_t *led_gpio_port;
    00140   U8 led_shift;
    00141
    00142   // Make sure only existing LEDs are specified.
    00143   mask &= (1 << LED_COUNT) - 1;
    00144
    00145   // Update the saved state of all LEDs with the requested changes.
    00146   Wr_bits(LED_State, mask, leds);
    00147
    00148   // While there are specified LEDs left to manage...
    00149   while (mask)
    00150   {
    00151     // Select the next specified LED and set it to the requested state.
    00152     led_shift = 1 + ctz(mask);
    00153     led_descriptor += led_shift;
    00154     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    00155     leds >>= led_shift - 1;
    00156     if (leds & 1)
    00157     {
    00158       led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;
    00159     }
    00160     else
    00161     {
    00162       led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;
    00163     }
    00164     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    00165     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    00166     leds >>= 1;
    00167     mask >>= led_shift;
    00168   }
    00169 }
    00170
    00171
    00172 Bool LED_Test(U32 leds)
    00173 {
    00174   return Tst_bits(LED_State, leds);
    00175 }
    00176
    00177
    00178 void LED_Off(U32 leds)
    00179 {
    00180   // Use the LED descriptors to get the connections of a given LED to the MCU.
    00181   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
    00182   volatile avr32_gpio_port_t *led_gpio_port;
    00183   U8 led_shift;
    00184
    00185   // Make sure only existing LEDs are specified.
    00186   leds &= (1 << LED_COUNT) - 1;
    00187
    00188   // Update the saved state of all LEDs with the requested changes.
    00189   Clr_bits(LED_State, leds);
    00190
    00191   // While there are specified LEDs left to manage...
    00192   while (leds)
    00193   {
    00194     // Select the next specified LED and turn it off.
    00195     led_shift = 1 + ctz(leds);
    00196     led_descriptor += led_shift;
    00197     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    00198     led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;
    00199     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    00200     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    00201     leds >>= led_shift;
    00202   }
    00203 }
    00204
    00205
    00206 void LED_On(U32 leds)
    00207 {
    00208   // Use the LED descriptors to get the connections of a given LED to the MCU.
    00209   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
    00210   volatile avr32_gpio_port_t *led_gpio_port;
    00211   U8 led_shift;
    00212
    00213   // Make sure only existing LEDs are specified.
    00214   leds &= (1 << LED_COUNT) - 1;
    00215
    00216   // Update the saved state of all LEDs with the requested changes.
    00217   Set_bits(LED_State, leds);
    00218
    00219   // While there are specified LEDs left to manage...
    00220   while (leds)
    00221   {
    00222     // Select the next specified LED and turn it on.
    00223     led_shift = 1 + ctz(leds);
    00224     led_descriptor += led_shift;
    00225     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    00226     led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;
    00227     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    00228     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    00229     leds >>= led_shift;
    00230   }
    00231 }
    00232
    00233
    00234 void LED_Toggle(U32 leds)
    00235 {
    00236   // Use the LED descriptors to get the connections of a given LED to the MCU.
    00237   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
    00238   volatile avr32_gpio_port_t *led_gpio_port;
    00239   U8 led_shift;
    00240
    00241   // Make sure only existing LEDs are specified.
    00242   leds &= (1 << LED_COUNT) - 1;
    00243
    00244   // Update the saved state of all LEDs with the requested changes.
    00245   Tgl_bits(LED_State, leds);
    00246
    00247   // While there are specified LEDs left to manage...
    00248   while (leds)
    00249   {
    00250     // Select the next specified LED and toggle it.
    00251     led_shift = 1 + ctz(leds);
    00252     led_descriptor += led_shift;
    00253     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    00254     led_gpio_port->ovrt  = led_descriptor->GPIO.PIN_MASK;
    00255     led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    00256     led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    00257     leds >>= led_shift;
    00258   }
    00259 }
    00260
    00261
    00262 U32 LED_Read_Display_Field(U32 field)
    00263 {
    00264   return Rd_bitfield(LED_State, field);
    00265 }
    00266
    00267
    00268 void LED_Display_Field(U32 field, U32 leds)
    00269 {
    00270   // Move the bit-field to the appropriate position for the bit-mask.
    00271   LED_Display_Mask(field, leds << ctz(field));
    00272 }
    00273
    00274
    00275 U8 LED_Get_Intensity(U32 led)
    00276 {
    00277 #if 0 // TODO
    00278   tLED_DESCRIPTOR *led_descriptor;
    00279
    00280   // Check that the argument value is valid.
    00281   led = ctz(led);
    00282   led_descriptor = &LED_DESCRIPTOR[led];
    00283   if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0;
    00284
    00285   // Return the duty cycle value if the LED PWM channel is enabled, else 0.
    00286   return (AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)) ?
    00287            AVR32_PWM.channel[led_descriptor->PWM.CHANNEL].cdty : 0;
    00288 #else
    00289   return 0;
    00290 #endif
    00291 }
    00292
    00293
    00294 void LED_Set_Intensity(U32 leds, U8 intensity)
    00295 {
    00296 #if 0 // TODO
    00297   tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
    00298   volatile avr32_pwm_channel_t *led_pwm_channel;
    00299   volatile avr32_gpio_port_t *led_gpio_port;
    00300   U8 led_shift;
    00301
    00302   // For each specified LED...
    00303   for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift)
    00304   {
    00305     // Select the next specified LED and check that it has a PWM channel.
    00306     led_shift = 1 + ctz(leds);
    00307     led_descriptor += led_shift;
    00308     if (led_descriptor->PWM.CHANNEL < 0) continue;
    00309
    00310     // Initialize or update the LED PWM channel.
    00311     led_pwm_channel = &AVR32_PWM.channel[led_descriptor->PWM.CHANNEL];
    00312     if (!(AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)))
    00313     {
    00314       led_pwm_channel->cmr = (AVR32_PWM_CPRE_MCK << AVR32_PWM_CPRE_OFFSET) &
    00315                              ~(AVR32_PWM_CALG_MASK |
    00316                                AVR32_PWM_CPOL_MASK |
    00317                                AVR32_PWM_CPD_MASK);
    00318       led_pwm_channel->cprd = 0x000000FF;
    00319       led_pwm_channel->cdty = intensity;
    00320       AVR32_PWM.ena = 1 << led_descriptor->PWM.CHANNEL;
    00321     }
    00322     else
    00323     {
    00324       AVR32_PWM.isr;
    00325       while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL)));
    00326       led_pwm_channel->cupd = intensity;
    00327     }
    00328
    00329     // Switch the LED pin to its PWM function.
    00330     led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    00331     if (led_descriptor->PWM.FUNCTION & 0x1)
    00332     {
    00333       led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK;
    00334     }
    00335     else
    00336     {
    00337       led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK;
    00338     }
    00339     if (led_descriptor->PWM.FUNCTION & 0x2)
    00340     {
    00341       led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK;
    00342     }
    00343     else
    00344     {
    00345       led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK;
    00346     }
    00347     led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK;
    00348   }
    00349 #else
    00350   return;
    00351 #endif
    00352 }