Contiki 2.6

button-sensor.c

00001 /*
00002  * Copyright (c) 2005, Swedish Institute of Computer Science
00003  * 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  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  */
00031 
00032 /*
00033  * Portions of this file build on button-sensor.c in platforms sky and esb
00034  * This file contains ISRs: Keep it in the HOME bank.
00035  */
00036 
00037 #include "dev/models.h"
00038 #include "lib/sensors.h"
00039 #include "dev/hwconf.h"
00040 #include "dev/sensinode-sensors.h"
00041 
00042 #if BUTTON_SENSOR_ON
00043 static uint8_t p0ien;
00044 static uint8_t p2ien;
00045 static __data struct timer debouncetimer[2];
00046 
00047 #ifdef MODEL_N740
00048 HWCONF_PIN(BUTTON_1, 1, 0)
00049 HWCONF_PORT_1_IRQ(BUTTON_1, 0)
00050 HWCONF_PIN(BUTTON_2, 0, 4)
00051 HWCONF_PORT_0_IRQ(BUTTON_2, 4)
00052 #endif /* MODEL_N740 */
00053 
00054 #ifdef MODEL_N711
00055 HWCONF_PIN(BUTTON_1, 0, 6)
00056 HWCONF_PORT_0_IRQ(BUTTON_1, 6)
00057 HWCONF_PIN(BUTTON_2, 0, 7)
00058 HWCONF_PORT_0_IRQ(BUTTON_2, 7)
00059 #endif /* MODEL_N711 */
00060 
00061 /*---------------------------------------------------------------------------*/
00062 static
00063 int value_b1(int type)
00064 {
00065   return BUTTON_1_READ() || !timer_expired(&debouncetimer[0]);
00066 }
00067 /*---------------------------------------------------------------------------*/
00068 static
00069 int status_b1(int type)
00070 {
00071   switch (type) {
00072   case SENSORS_ACTIVE:
00073   case SENSORS_READY:
00074     return BUTTON_1_IRQ_ENABLED();
00075     }
00076   return 0;
00077 }
00078 /*---------------------------------------------------------------------------*/
00079 static
00080 int configure_b1(int type, int value)
00081 {
00082   switch(type) {
00083   case SENSORS_HW_INIT:
00084     /* Generates INT when pressed */
00085     BUTTON_1_IRQ_EDGE_SELECTD();
00086     BUTTON_1_SELECT();
00087     BUTTON_1_MAKE_INPUT();
00088     return 1;
00089   case SENSORS_ACTIVE:
00090     if(value) {
00091       if(!BUTTON_1_IRQ_ENABLED()) {
00092         timer_set(&debouncetimer[0], 0);
00093         BUTTON_1_IRQ_FLAG_OFF();
00094         BUTTON_1_ENABLE_IRQ();
00095 }
00096     } else {
00097       BUTTON_1_DISABLE_IRQ();
00098     }
00099     return 1;
00100   }
00101   return 0;
00102 }
00103 /*---------------------------------------------------------------------------*/
00104 static
00105 int value_b2(int type)
00106 {
00107   return BUTTON_2_READ() || !timer_expired(&debouncetimer[1]);
00108 }
00109 /*---------------------------------------------------------------------------*/
00110 static
00111 int status_b2(int type)
00112 {
00113   switch (type) {
00114   case SENSORS_ACTIVE:
00115   case SENSORS_READY:
00116     return BUTTON_2_IRQ_ENABLED();
00117   }
00118   return 0;
00119 }
00120 /*---------------------------------------------------------------------------*/
00121 static
00122 int configure_b2(int type, int value)
00123 {
00124   switch(type) {
00125   case SENSORS_HW_INIT:
00126     /* Generates INT when released */
00127     /* BUTTON_2_IRQ_EDGE_SELECTD(); */
00128     BUTTON_2_SELECT();
00129     BUTTON_2_MAKE_INPUT();
00130     return 1;
00131   case SENSORS_ACTIVE:
00132     if(value) {
00133       if(!BUTTON_2_IRQ_ENABLED()) {
00134         timer_set(&debouncetimer[1], 0);
00135         BUTTON_2_IRQ_FLAG_OFF();
00136         BUTTON_2_ENABLE_IRQ();
00137       }
00138     } else {
00139       BUTTON_2_DISABLE_IRQ();
00140     }
00141     return 1;
00142   }
00143   return 0;
00144 }
00145 /*---------------------------------------------------------------------------*/
00146 void
00147 port_0_ISR(void) __interrupt (P0INT_VECTOR)
00148 {
00149   EA = 0;
00150   ENERGEST_ON(ENERGEST_TYPE_IRQ);
00151 
00152   /* This ISR is for the entire port. Check if the interrupt was caused by our
00153    * button's pin. */
00154   /* Check B1 for N711 */
00155 #ifdef MODEL_N711
00156   if(BUTTON_1_CHECK_IRQ()) {
00157     if(timer_expired(&debouncetimer[0])) {
00158       timer_set(&debouncetimer[0], CLOCK_SECOND / 4);
00159       sensors_changed(&button_1_sensor);
00160     }
00161   }
00162 #endif /* MODEL_N711 */
00163   if(BUTTON_2_CHECK_IRQ()) {
00164     if(timer_expired(&debouncetimer[1])) {
00165       timer_set(&debouncetimer[1], CLOCK_SECOND / 4);
00166       sensors_changed(&button_2_sensor);
00167     }
00168   }
00169   P0IFG = 0;
00170   IRCON_P0IF = 0;
00171   ENERGEST_OFF(ENERGEST_TYPE_IRQ);
00172   EA = 1;
00173 }
00174 /*---------------------------------------------------------------------------*/
00175 /* We only need this ISR for N740 */
00176 #ifdef MODEL_N740
00177 void
00178 port_1_ISR(void) __interrupt (P1INT_VECTOR)
00179 {
00180   EA = 0;
00181   ENERGEST_ON(ENERGEST_TYPE_IRQ);
00182 
00183   /* This ISR is for the entire port. Check if the interrupt was caused by our
00184    * button's pin. This can only be B1 for N740 */
00185   if(BUTTON_1_CHECK_IRQ()) {
00186     if(timer_expired(&debouncetimer[0])) {
00187       timer_set(&debouncetimer[0], CLOCK_SECOND / 4);
00188       sensors_changed(&button_1_sensor);
00189     }
00190   }
00191   P1IFG = 0;
00192   IRCON2_P1IF = 0;
00193   ENERGEST_OFF(ENERGEST_TYPE_IRQ);
00194   EA = 1;
00195 }
00196 #endif /* MODEL_N740 */
00197 
00198 SENSORS_SENSOR(button_1_sensor, BUTTON_1_SENSOR, value_b1, configure_b1, status_b1);
00199 SENSORS_SENSOR(button_2_sensor, BUTTON_2_SENSOR, value_b2, configure_b2, status_b2);
00200 #endif /* BUTTON_SENSOR_ON */