led.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 by Rittal GmbH & Co. KG,
00003  * Ulrich Prinz <prinz.u@rittal.de> All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY EMBEDDED IT AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EMBEDDED IT
00022  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 
00056 #include <cfg/os.h>
00057 
00058 #include <compiler.h>
00059 #include <dev/board.h>
00060 #include <dev/gpio.h>
00061 
00062 #include <stdlib.h>
00063 #include <string.h>
00064 #include <sys/heap.h>
00065 #include <sys/event.h>
00066 #include <sys/timer.h>
00067 #include <sys/atom.h>
00068 
00069 #include <sys/nutdebug.h>
00070 
00071 #include <cfg/pca9555.h>
00072 #ifdef LED_SUPPORT_IOEXP
00073 #include <dev/pca9555.h>
00074 #endif
00075 #include "dev/led.h"
00076 
00081 
00082 /* define inverted LED states as LEDs are driven by low side switching */
00083 #define LED_IS_ON  0
00084 #define LED_IS_OFF 1
00085 
00086 typedef struct
00087 {
00088     void         *next;     
00089     uint32_t     timOn;     
00090     uint32_t     timOff;    
00091     uint32_t     tim;       
00092     int          bank;      
00093     int          pin;       
00094     int          state;     
00095     uint_fast8_t fx;        
00096 } LEDEventT;
00097 
00098 /* Pointer to first led registered */
00099 LEDEventT *first_led = NULL;
00100 
00101 /* Timer- and Timer-Event-Handler */
00102 HANDLE led_tmr = NULL;
00103 HANDLE led_evt = NULL;
00104 
00110 int InitLED(LEDEventT *led)
00111 {
00112 #ifdef LED_SUPPORT_IOEXP
00113     if( led->bank >= IOXP_PORT0) {
00114         IOExpPinConfigSet(led->bank, led->pin, GPIO_CFG_OUTPUT);
00115         IOExpSetBitHigh( led->bank, led->pin);
00116         return 0;
00117     }
00118     else
00119 #else
00120     {
00121         GpioPinConfigSet( led->bank, led->pin, GPIO_CFG_OUTPUT);
00122         GpioPinSetHigh( led->bank, led->pin);
00123         return 0;
00124     }
00125 #endif
00126     return -1;
00127 }
00128 
00139 static void LedTimerCb(HANDLE timer, void *arg)
00140 {
00141     NutEventPostAsync( arg);
00142 }
00143 
00157 /****************************************************************************/
00158 THREAD( sys_led, arg)
00159 /****************************************************************************/
00160 {
00161     LEDEventT *led;
00162     uint32_t now, last, dur;
00163 
00164     NUTASSERT( arg != NULL);
00165 
00166     last = NutGetMillis();
00167     NutThreadSetPriority(16);
00168     for(;;) {
00169         if (NutEventWait(arg, NUT_WAIT_INFINITE)==0) {
00170             now = NutGetMillis();
00171             dur = now-last;
00172             last = now;
00173             led = first_led;
00174 
00175             while( led)
00176             {
00177                 switch( led->fx) {
00178                     case LED_ON:
00179                         if( led->timOn > 0) {
00180                             if( led->tim >= dur) led->tim -= dur;
00181                             else
00182                                 NutSetLed( led, LED_OFF, 0, 0);
00183                         }
00184                         break;
00185                     case LED_OFF:
00186                         if( led->timOff > 0) {
00187                             if( led->tim >= dur) led->tim -= dur;
00188                             else
00189                                 NutSetLed( led, LED_ON, 0, 0);
00190                         }
00191                         break;
00192                     case LED_BLINK:
00193                         if( led->tim >= dur) led->tim -= dur;
00194                         else {
00195                             NutSetLed( led, LED_FLIP, 0, 0);
00196                             led->fx = LED_BLINK;
00197                             if( led->state)
00198                                 led->tim = led->timOff;
00199                             else
00200                                 led->tim = led->timOn;
00201                         }
00202                         break;
00203                 }
00204 
00205                 led = led->next;
00206             }
00207         }
00208     }
00209 }
00210 
00221 void NutSetLed( HANDLE ledh, uint_fast8_t fxin, uint32_t timOn, uint32_t timOff)
00222 {
00223     LEDEventT *led = (LEDEventT *)ledh;
00224 
00225     NUTASSERT( ledh != NULL);
00226 
00227     led->fx = fxin;
00228 
00229     switch( fxin) {
00230         case LED_BLINK:
00231             led->state ^= 1;
00232             led->timOn = timOn;
00233             led->timOff = timOff;
00234             if( led->state)
00235                 led->tim = timOff;
00236             else
00237                 led->tim = timOn;
00238             break;
00239         case LED_FLIP:
00240             led->state ^= 1;
00241             break;
00242         case LED_ON:
00243             led->state = LED_IS_ON;
00244             led->timOn = led->tim = timOn;
00245             break;
00246         case LED_OFF:
00247         default:
00248             led->state = LED_IS_OFF;
00249             led->timOff = led->tim = timOff;
00250             break;
00251     }
00252 
00253 #ifdef LED_SUPPORT_IOEXP
00254     if( led->bank < IOXP_PORT0)
00255         GpioPinSet( led->bank, led->pin, led->state);
00256     else
00257         IOExpSetBit( led->bank, led->pin, led->state);
00258 #else
00259         GpioPinSet( led->bank, led->pin, led->state);
00260 #endif
00261 
00262 }
00263 
00279 int NutRegisterLed( HANDLE * ledh, int bank, int pin)
00280 {
00281     LEDEventT *led;
00282 
00283     /* Check memory constraints and assign memory to new led struct */
00284     led = malloc(sizeof( LEDEventT));
00285     *ledh = (void*)led;
00286 
00287     if( led == NULL) {
00288         return -1;
00289     }
00290 
00291     /* Preset new led struct */
00292     memset( led, 0, sizeof( LEDEventT));
00293     led->bank = bank;
00294     led->pin = pin;
00295     led->state = LED_IS_OFF;
00296 
00297     /* Assign the led to the chain */
00298     NutEnterCritical();
00299     if( first_led == NULL) {
00300         /* it is the first led */
00301         first_led = led;
00302     }
00303     else {
00304         /* if not first, put it into the chain at first position */
00305         led->next = first_led;
00306         first_led = led;
00307     }
00308     NutExitCritical();
00309 
00310     /* Start timer for LED effects, but only one timer for all */
00311     if( led_tmr == NULL) {
00312         NutThreadCreate("sys_led", sys_led, &led_evt, 192);
00313         led_tmr = NutTimerStart(10, LedTimerCb, &led_evt, 0);
00314     }
00315 
00316     return InitLED( led);
00317 }
00318 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/