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 /*
00035  * $Log$
00036  *
00037  * Revision 0.2  2009/04/13 ulrichprinz
00038  * First checkin, led driver with extra functionality and variable io-access
00039  * (currently SAM7X256 is tested only)
00040  *
00041  */
00042 
00043 #include <compiler.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <memdebug.h>
00047 #include <sys/heap.h>
00048 
00049 #include <io.h>
00050 
00051 #include <cfg/arch.h>
00052 #include <dev/board.h>
00053 #include <dev/gpio.h>
00054 
00055 #include <sys/thread.h>
00056 #include <sys/timer.h>
00057 #include <sys/event.h>
00058 #include <dev/pca9555.h>
00059 #include <dev/led.h>
00060 
00061 typedef struct
00062 {
00063     void       *next;       
00064     uint8_t     interval;   
00065     uint8_t     duration;   
00066     int         bank;       
00067     int         pin;        
00068     uint8_t     state;      
00069     uint8_t     fx;         
00070 } LEDEventT;
00071 
00072 LEDEventT *first_led = NULL;
00073 
00074 HANDLE led_evt = NULL;
00075 HANDLE led_tmr = NULL;
00076 
00081 /****************************************************************************/
00082 void InitLED(LEDEventT *led)
00083 /****************************************************************************/
00084 {
00085     if( led->bank < IOXP_PORT0) {
00086         GpioPinConfigSet( led->bank, led->pin, GPIO_CFG_OUTPUT);
00087         GpioPinSetHigh( led->bank, led->pin);
00088     }
00089     else {
00090         IOExpPinConfigSet(led->bank, led->pin, GPIO_CFG_OUTPUT);
00091         IOExpSetBitHigh( led->bank, led->pin);
00092     }
00093 }
00094 
00099 /****************************************************************************/
00100 void TimerCallback(HANDLE timer, void *arg)
00101 /****************************************************************************/
00102 {
00103     NutEventPostAsync(arg);
00104 }
00105 
00111 /****************************************************************************/
00112 THREAD( sys_led, arg)
00113 /****************************************************************************/
00114 {
00115     LEDEventT *led;
00116     NutThreadSetPriority(16);
00117     for(;;) {
00118         if (NutEventWait(arg, NUT_WAIT_INFINITE)==0) {
00119             led = first_led;
00120             while( led) 
00121             {
00122                 if( led->fx >= LED_ONESHOT) 
00123                 {
00124                     if( led->duration) 
00125                         led->duration--;
00126                     else {
00127                         led->duration = led->interval;
00128                         if( led->fx==LED_ONESHOT) led->fx = LED_OFF;
00129                         NutSetLed( (HANDLE*)led, led->interval, led->fx);
00130                     }
00131                 }
00132                 led = led->next;
00133             }
00134         }
00135     }
00136 }
00137 
00152 /****************************************************************************/
00153 void NutSetLed( HANDLE ledh, uint8_t tim, uint8_t fxin)
00154 /****************************************************************************/
00155 {
00156     LEDEventT *led = (LEDEventT *)ledh;
00157 
00158     if( ledh == NULL) return;
00159 
00160     led->duration = tim;
00161     led->fx = fxin;
00162     
00163     switch( fxin) {
00164         case LED_ONESHOT:
00165             led->interval = 0;
00166         case LED_ON:
00167             led->state = 0;
00168             break;
00169         case LED_BLINK:
00170             led->interval = tim;
00171         case LED_FLIP:
00172             led->state ^= 1;
00173             break;
00174         case LED_OFF:
00175         default:
00176             led->state = 1;
00177             break;
00178     }
00179 
00180     if( led->bank < IOXP_PORT0)
00181         GpioPinSet( led->bank, led->pin, led->state);
00182     else
00183         IOExpSetBit( led->bank, led->pin, led->state);
00184 
00185     if( led_tmr == NULL) {
00186         NutThreadCreate("sys_led", sys_led, &led_evt, 512);
00187         led_tmr = NutTimerStart(10, TimerCallback, &led_evt, 0);
00188     }
00189 }
00190 
00198 /****************************************************************************/
00199 int NutRegisterLed( HANDLE * ledh, int bank, int pin)
00200 /****************************************************************************/
00201 {
00202     LEDEventT *led;
00203 
00204     /* Check memory constraints and assign memory to new led struct */
00205     led = malloc(sizeof( LEDEventT));
00206     *ledh = (void*)led;
00207     
00208     if( led == NULL) {
00209         return -1;
00210     }
00211 
00212     /* Preset new led struct */
00213     memset( led, 0, sizeof( LEDEventT));
00214     led->bank = bank;
00215     led->pin = pin;
00216 
00217     /* Assign the led to the led chain */
00218     if( first_led == NULL) {
00219         /* it is the first led */
00220         first_led = led;
00221     }
00222     else {
00223         led->next = first_led;
00224         first_led = led;
00225     }
00226 
00227     InitLED( led);
00228     return 0;
00229 }
00230 

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