Contiki-NG
button-sensor.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Nordic Semiconductor
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  */
30 /*---------------------------------------------------------------------------*/
31 /**
32  * \addtogroup nrf52dk-devices Device drivers
33  * @{
34  *
35  * \addtogroup nrf52dk-devices-button Buttons driver
36  * @{
37  *
38  * \file
39  * Driver for nRF52 DK buttons.
40  * \author
41  * Wojciech Bober <wojciech.bober@nordicsemi.no>
42  */
43 /*---------------------------------------------------------------------------*/
44 #include <stdint.h>
45 #include "nordic_common.h"
46 #include "nrf_drv_gpiote.h"
47 #include "nrf_assert.h"
48 #include "boards.h"
49 #include "contiki.h"
50 #include "lib/sensors.h"
51 #include "button-sensor.h"
52 
53 /*---------------------------------------------------------------------------*/
54 #define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) /**< Delay before button state is assumed to be stable */
55 
56 /*---------------------------------------------------------------------------*/
57 struct btn_timer
58 {
59  struct timer debounce;
60  clock_time_t start;
61  clock_time_t duration;
62 };
63 
64 static struct btn_timer btn_timer[BUTTONS_NUMBER];
65 static int btn_state = 0;
66 
67 /*---------------------------------------------------------------------------*/
68 /**
69  * \brief Button toggle handler
70  * \param pin GPIO pin which has been triggered
71  * \param action toggle direction
72  *
73  */
74 static void
75 gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
76 {
77  int id = pin - BUTTON_START;
78 
79  if(!timer_expired(&(btn_timer[id].debounce))) {
80  return;
81  }
82 
83  /* Set timer to ignore consecutive changes for
84  * DEBOUNCE_DURATION.
85  */
86  timer_set(&(btn_timer[id].debounce), DEBOUNCE_DURATION);
87 
88  /*
89  * Start measuring duration on falling edge, stop on rising edge.
90  */
91  if(nrf_drv_gpiote_in_is_set(pin) == 0) {
92  btn_timer[id].start = clock_time();
93  btn_timer[id].duration = 0;
94  } else {
95  btn_timer[id].duration = clock_time() - btn_timer[id].start;
96  }
97  sensors_changed(&buttons[id]);
98 }
99 /*---------------------------------------------------------------------------*/
100 /**
101  * \brief Configuration function for the button sensor for all buttons.
102  *
103  * \param type if \a SENSORS_HW_INIT is passed the function will initialize
104  * given button
105  * if \a SENSORS_ACTIVE is passed then \p c parameter defines
106  * whether button should be set active or inactive
107  * \param c 0 to disable the button, non-zero: enable
108  * \param pin GPIOE pin number
109  */
110 static int
111 config(int type, int c, nrf_drv_gpiote_pin_t pin)
112 {
113  int id = pin - BUTTON_START;
114 
115  switch(type) {
116  case SENSORS_HW_INIT: {
117  nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
118  config.pull = NRF_GPIO_PIN_PULLUP;
119  nrf_drv_gpiote_in_init(pin, &config, gpiote_event_handler);
120  timer_set(&(btn_timer[id].debounce), DEBOUNCE_DURATION);
121  return 1;
122  }
123  case SENSORS_ACTIVE: {
124  if(c) {
125  nrf_drv_gpiote_in_event_enable(pin, true);
126  btn_state |= (1 << id);
127  } else {
128  nrf_drv_gpiote_in_event_disable(pin);
129  btn_state &= ~(1 << id);
130  }
131  return 1;
132  }
133  default:
134  return 0;
135  }
136 }
137 /*---------------------------------------------------------------------------*/
138 /**
139  * \brief Configuration function for button 1
140  *
141  * \param type passed to config() as-is
142  * \param value passed to config() as-is
143  * \return same as config() return value
144  */
145 static int
146 config_button_1(int type, int value)
147 {
148  return config(type, value, BSP_BUTTON_0);
149 }
150 /*---------------------------------------------------------------------------*/
151 /**
152  * \brief Configuration function for button 2
153  *
154  * \param type passed to config() as-is
155  * \param value passed to config() as-is
156  * \return same as config() return value
157  */
158 static int
159 config_button_2(int type, int value)
160 {
161  return config(type, value, BSP_BUTTON_1);
162 }
163 /*---------------------------------------------------------------------------*/
164 /**
165  * \brief Configuration function for button 3
166  *
167  * \param type passed to config() as-is
168  * \param value passed to config() as-is
169  * \return same as config() return value
170  */
171 static int
172 config_button_3(int type, int value)
173 {
174  return config(type, value, BSP_BUTTON_2);
175 }
176 /*---------------------------------------------------------------------------*/
177 /**
178  * \brief Configuration function for button 4
179  *
180  * \param type passed to config() as-is
181  * \param value passed to config() as-is
182  * \return same as config() return value
183  */
184 static int
185 config_button_4(int type, int value)
186 {
187  return config(type, value, BSP_BUTTON_3);
188 }
189 /*---------------------------------------------------------------------------*/
190 /**
191  * \brief Return current state of a button
192  * \param type pass \ref BUTTON_SENSOR_VALUE_STATE to get current button state
193  * or \ref BUTTON_SENSOR_VALUE_DURATION to get active state duration
194  * \param pin GPIOE pin number
195  *
196  * \retval BUTTON_SENSOR_VALUE_PRESSED
197  * \retval BUTTON_SENSOR_VALUE_RELEASED when \a type is \ref BUTTON_SENSOR_VALUE_STATE
198  * \retval duration Active state duration in clock ticks
199  */
200 static int
201 value(int type, nrf_drv_gpiote_pin_t pin)
202 {
203 
204  if(type == BUTTON_SENSOR_VALUE_STATE) {
205  return nrf_drv_gpiote_in_is_set(pin) == 0 ?
206  BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED;
207  } else if(type == BUTTON_SENSOR_VALUE_DURATION) {
208  return btn_timer[pin - BUTTON_START].duration;
209  }
210 
211  return 0;
212 }
213 /*---------------------------------------------------------------------------*/
214 /**
215  * \brief Return current state of a button 1
216  * \param type passed to value() as-is
217  * \return same as value returned by value()
218  */
219 static int
220 value_button_1(int type)
221 {
222  return value(type, BSP_BUTTON_0);
223 }
224 /*---------------------------------------------------------------------------*/
225 /**
226  * \brief Return current state of a button 2
227  * \param type passed to value() as-is
228  * \return same as value returned by value()
229  */
230 static int
231 value_button_2(int type)
232 {
233  return value(type, BSP_BUTTON_1);
234 }
235 /*---------------------------------------------------------------------------*/
236 /**
237  * \brief Return current state of a button 3
238  * \param type passed to value() as-is
239  * \return same as value returned by value()
240  */
241 static int
242 value_button_3(int type)
243 {
244  return value(type, BSP_BUTTON_2);
245 }
246 /*---------------------------------------------------------------------------*/
247 /**
248  * \brief Return current state of a button 4
249  * \param type passed to value() as-is
250  * \return same as value returned by value()
251  */
252 static int
253 value_button_4(int type)
254 {
255  return value(type, BSP_BUTTON_3);
256 }
257 /*---------------------------------------------------------------------------*/
258 /**
259  * \brief Get status of a given button
260  * \param type \a SENSORS_ACTIVE or \a SENSORS_READY
261  * \param pin GPIOE pin number
262  * \return 1 if the button's port interrupt is enabled
263  */
264 static int
265 status(int type, nrf_drv_gpiote_pin_t pin)
266 {
267  switch(type) {
268  case SENSORS_ACTIVE:
269  case SENSORS_READY:
270  return (btn_state & (1 << (pin - BUTTON_START)));
271  default:
272  break;
273  }
274  return 0;
275 }
276 /*---------------------------------------------------------------------------*/
277 /**
278  * \brief Status function for button 1
279  * \param type passed to state() as-is
280  * \return value returned by state()
281  */
282 static int
284 {
285  return status(type, BSP_BUTTON_0);
286 }
287 /*---------------------------------------------------------------------------*/
288 /**
289  * \brief Status function for button 2
290  * \param type passed to state() as-is
291  * \return value returned by state()
292  */
293 static int
295 {
296  return status(type, BSP_BUTTON_1);
297 }
298 /*---------------------------------------------------------------------------*/
299 /**
300  * \brief Status function for button 3
301  * \param type passed to state() as-is
302  * \return value returned by state()
303  */
304 static int
306 {
307  return status(type, BSP_BUTTON_2);
308 }
309 /*---------------------------------------------------------------------------*/
310 /**
311  * \brief Status function for button 3
312  * \param type passed to state() as-is
313  * \return value returned by state()
314  */
315 static int
317 {
318  return status(type, BSP_BUTTON_3);
319 }
320 /*---------------------------------------------------------------------------*/
321 const struct sensors_sensor buttons[BUTTONS_NUMBER] = {
325  {BUTTON_SENSOR, value_button_4, config_button_4, status_button_4}, };
326 /*---------------------------------------------------------------------------*/
327 /**
328  * @}
329  * @}
330  */
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
static int value(int type, nrf_drv_gpiote_pin_t pin)
Return current state of a button.
static int config_button_1(int type, int value)
Configuration function for button 1.
static int config_button_4(int type, int value)
Configuration function for button 4.
static int config_button_2(int type, int value)
Configuration function for button 2.
static int status_button_1(int type)
Status function for button 1.
A timer.
Definition: timer.h:82
static int value_button_3(int type)
Return current state of a button 3.
static int status_button_4(int type)
Status function for button 3.
static int status_button_2(int type)
Status function for button 2.
static void start(void)
Start measurement.
static int value_button_4(int type)
Return current state of a button 4.
#define DEBOUNCE_DURATION
Delay before button state is assumed to be stable.
Definition: button-sensor.c:54
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:123
clock_time_t clock_time(void)
Get the current clock time.
Definition: clock.c:118
static int status(int type, nrf_drv_gpiote_pin_t pin)
Get status of a given button.
static int config(int type, int c, nrf_drv_gpiote_pin_t pin)
Configuration function for the button sensor for all buttons.
static int config_button_3(int type, int value)
Configuration function for button 3.
#define BUTTON_SENSOR_VALUE_DURATION
Can be passed to value() function to get low state duration.
Definition: button-sensor.h:55
static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
Button toggle handler.
Definition: button-sensor.c:75
#define BUTTON_SENSOR_VALUE_STATE
Can be passed to value() function to get current button state.
Definition: button-sensor.h:52
static int value_button_1(int type)
Return current state of a button 1.
static int status_button_3(int type)
Status function for button 3.
static int value_button_2(int type)
Return current state of a button 2.