Contiki 3.x
button-sensor.c
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  */
31 
32 /*
33  * Portions of this file build on button-sensor.c in platforms sky and esb
34  * This file contains ISRs: Keep it in the HOME bank.
35  */
36 
37 #include "dev/models.h"
38 #include "lib/sensors.h"
39 #include "dev/hwconf.h"
40 #include "dev/sensinode-sensors.h"
41 
42 #if BUTTON_SENSOR_ON
43 static uint8_t p0ien;
44 static uint8_t p2ien;
45 static CC_AT_DATA struct timer debouncetimer[2];
46 
47 #ifdef MODEL_N740
48 HWCONF_PIN(BUTTON_1, 1, 0)
49 HWCONF_PORT_1_IRQ(BUTTON_1, 0)
50 HWCONF_PIN(BUTTON_2, 0, 4)
51 HWCONF_PORT_0_IRQ(BUTTON_2, 4)
52 #endif /* MODEL_N740 */
53 
54 #ifdef MODEL_N711
55 HWCONF_PIN(BUTTON_1, 0, 6)
56 HWCONF_PORT_0_IRQ(BUTTON_1, 6)
57 HWCONF_PIN(BUTTON_2, 0, 7)
58 HWCONF_PORT_0_IRQ(BUTTON_2, 7)
59 #endif /* MODEL_N711 */
60 
61 /*---------------------------------------------------------------------------*/
62 static int
63 value_b1(int type)
64 {
65  return BUTTON_1_READ() || !timer_expired(&debouncetimer[0]);
66 }
67 /*---------------------------------------------------------------------------*/
68 static int
69 status_b1(int type)
70 {
71  switch(type) {
72  case SENSORS_ACTIVE:
73  case SENSORS_READY:
74  return BUTTON_1_IRQ_ENABLED();
75  }
76  return 0;
77 }
78 /*---------------------------------------------------------------------------*/
79 static int
80 configure_b1(int type, int value)
81 {
82  switch(type) {
83  case SENSORS_HW_INIT:
84  /* Generates INT when pressed */
85  BUTTON_1_IRQ_EDGE_SELECTD();
86  BUTTON_1_SELECT();
87  BUTTON_1_MAKE_INPUT();
88  return 1;
89  case SENSORS_ACTIVE:
90  if(value) {
91  if(!BUTTON_1_IRQ_ENABLED()) {
92  timer_set(&debouncetimer[0], 0);
93  BUTTON_1_IRQ_FLAG_OFF();
94  BUTTON_1_ENABLE_IRQ();
95  }
96  } else {
97  BUTTON_1_DISABLE_IRQ();
98  }
99  return 1;
100  }
101  return 0;
102 }
103 /*---------------------------------------------------------------------------*/
104 static int
105 value_b2(int type)
106 {
107  return BUTTON_2_READ() || !timer_expired(&debouncetimer[1]);
108 }
109 /*---------------------------------------------------------------------------*/
110 static int
111 status_b2(int type)
112 {
113  switch(type) {
114  case SENSORS_ACTIVE:
115  case SENSORS_READY:
116  return BUTTON_2_IRQ_ENABLED();
117  }
118  return 0;
119 }
120 /*---------------------------------------------------------------------------*/
121 static int
122 configure_b2(int type, int value)
123 {
124  switch(type) {
125  case SENSORS_HW_INIT:
126  /* Generates INT when released */
127  /* BUTTON_2_IRQ_EDGE_SELECTD(); */
128  BUTTON_2_SELECT();
129  BUTTON_2_MAKE_INPUT();
130  return 1;
131  case SENSORS_ACTIVE:
132  if(value) {
133  if(!BUTTON_2_IRQ_ENABLED()) {
134  timer_set(&debouncetimer[1], 0);
135  BUTTON_2_IRQ_FLAG_OFF();
136  BUTTON_2_ENABLE_IRQ();
137  }
138  } else {
139  BUTTON_2_DISABLE_IRQ();
140  }
141  return 1;
142  }
143  return 0;
144 }
145 /*---------------------------------------------------------------------------*/
146 #pragma save
147 #if CC_CONF_OPTIMIZE_STACK_SIZE
148 #pragma exclude bits
149 #endif
150 void
151 port_0_ISR(void) __interrupt (P0INT_VECTOR)
152 {
153  EA = 0;
154  ENERGEST_ON(ENERGEST_TYPE_IRQ);
155 
156  /* This ISR is for the entire port. Check if the interrupt was caused by our
157  * button's pin. */
158  /* Check B1 for N711 */
159 #ifdef MODEL_N711
160  if(BUTTON_1_CHECK_IRQ()) {
161  if(timer_expired(&debouncetimer[0])) {
162  timer_set(&debouncetimer[0], CLOCK_SECOND / 4);
163  sensors_changed(&button_1_sensor);
164  }
165  }
166 #endif /* MODEL_N711 */
167  if(BUTTON_2_CHECK_IRQ()) {
168  if(timer_expired(&debouncetimer[1])) {
169  timer_set(&debouncetimer[1], CLOCK_SECOND / 4);
170  sensors_changed(&button_2_sensor);
171  }
172  }
173  P0IFG = 0;
174  IRCON_P0IF = 0;
175  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
176  EA = 1;
177 }
178 /*---------------------------------------------------------------------------*/
179 /* We only need this ISR for N740 */
180 #ifdef MODEL_N740
181 void
182 port_1_ISR(void) __interrupt (P1INT_VECTOR)
183 {
184  EA = 0;
185  ENERGEST_ON(ENERGEST_TYPE_IRQ);
186 
187  /* This ISR is for the entire port. Check if the interrupt was caused by our
188  * button's pin. This can only be B1 for N740 */
189  if(BUTTON_1_CHECK_IRQ()) {
190  if(timer_expired(&debouncetimer[0])) {
191  timer_set(&debouncetimer[0], CLOCK_SECOND / 4);
192  sensors_changed(&button_1_sensor);
193  }
194  }
195  P1IFG = 0;
196  IRCON2_P1IF = 0;
197  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
198  EA = 1;
199 }
200 #endif /* MODEL_N740 */
201 #pragma restore
202 
203 SENSORS_SENSOR(button_1_sensor, BUTTON_1_SENSOR, value_b1, configure_b1, status_b1);
204 SENSORS_SENSOR(button_2_sensor, BUTTON_2_SENSOR, value_b2, configure_b2, status_b2);
205 #endif /* BUTTON_SENSOR_ON */
A timer.
Definition: timer.h:86
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
Defines for the sensors on the various Sensinode models.
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:121
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82