Contiki 3.x
button-sensor.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
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  *
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 /**
32  * \addtogroup cc2538dk-button-sensor
33  * @{
34  *
35  * \file
36  * Driver for the SmartRF06EB buttons
37  */
38 #include "contiki.h"
39 #include "dev/nvic.h"
40 #include "dev/ioc.h"
41 #include "dev/gpio.h"
42 #include "dev/button-sensor.h"
43 #include "sys/timer.h"
44 
45 #include <stdint.h>
46 #include <string.h>
47 
48 #define BUTTON_SELECT_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_SELECT_PORT)
49 #define BUTTON_SELECT_PIN_MASK GPIO_PIN_MASK(BUTTON_SELECT_PIN)
50 
51 #define BUTTON_LEFT_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_LEFT_PORT)
52 #define BUTTON_LEFT_PIN_MASK GPIO_PIN_MASK(BUTTON_LEFT_PIN)
53 
54 #define BUTTON_RIGHT_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_RIGHT_PORT)
55 #define BUTTON_RIGHT_PIN_MASK GPIO_PIN_MASK(BUTTON_RIGHT_PIN)
56 
57 #define BUTTON_UP_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_UP_PORT)
58 #define BUTTON_UP_PIN_MASK GPIO_PIN_MASK(BUTTON_UP_PIN)
59 
60 #define BUTTON_DOWN_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_DOWN_PORT)
61 #define BUTTON_DOWN_PIN_MASK GPIO_PIN_MASK(BUTTON_DOWN_PIN)
62 /*---------------------------------------------------------------------------*/
63 static struct timer debouncetimer;
64 /*---------------------------------------------------------------------------*/
65 /**
66  * \brief Common initialiser for all buttons
67  * \param port_base GPIO port's register offset
68  * \param pin_mask Pin mask corresponding to the button's pin
69  */
70 static void
71 config(uint32_t port_base, uint32_t pin_mask)
72 {
73  /* Software controlled */
74  GPIO_SOFTWARE_CONTROL(port_base, pin_mask);
75 
76  /* Set pin to input */
77  GPIO_SET_INPUT(port_base, pin_mask);
78 
79  /* Enable edge detection */
80  GPIO_DETECT_EDGE(port_base, pin_mask);
81 
82  /* Single edge */
83  GPIO_TRIGGER_SINGLE_EDGE(port_base, pin_mask);
84 
85  /* Trigger interrupt on Falling edge */
86  GPIO_DETECT_RISING(port_base, pin_mask);
87 
88  GPIO_ENABLE_INTERRUPT(port_base, pin_mask);
89 }
90 /*---------------------------------------------------------------------------*/
91 /**
92  * \brief Callback registered with the GPIO module. Gets fired with a button
93  * port/pin generates an interrupt
94  * \param port The port number that generated the interrupt
95  * \param pin The pin number that generated the interrupt. This is the pin
96  * absolute number (i.e. 0, 1, ..., 7), not a mask
97  */
98 static void
99 btn_callback(uint8_t port, uint8_t pin)
100 {
101  if(!timer_expired(&debouncetimer)) {
102  return;
103  }
104 
105  timer_set(&debouncetimer, CLOCK_SECOND / 8);
106 
107  if((port == BUTTON_SELECT_PORT) && (pin == BUTTON_SELECT_PIN)) {
108  sensors_changed(&button_select_sensor);
109  } else if((port == BUTTON_LEFT_PORT) && (pin == BUTTON_LEFT_PIN)) {
110  sensors_changed(&button_left_sensor);
111  } else if((port == BUTTON_RIGHT_PORT) && (pin == BUTTON_RIGHT_PIN)) {
112  sensors_changed(&button_right_sensor);
113  } else if((port == BUTTON_UP_PORT) && (pin == BUTTON_UP_PIN)) {
114  sensors_changed(&button_up_sensor);
115  } else if((port == BUTTON_DOWN_PORT) && (pin == BUTTON_DOWN_PIN)) {
116  sensors_changed(&button_down_sensor);
117  }
118 }
119 /*---------------------------------------------------------------------------*/
120 /**
121  * \brief Init function for the select button.
122  *
123  * Parameters are ignored. They have been included because the prototype is
124  * dictated by the core sensor api. The return value is also not required by
125  * the API but otherwise ignored.
126  *
127  * \param type ignored
128  * \param value ignored
129  * \return ignored
130  */
131 static int
132 config_select(int type, int value)
133 {
134  config(BUTTON_SELECT_PORT_BASE, BUTTON_SELECT_PIN_MASK);
135 
136  ioc_set_over(BUTTON_SELECT_PORT, BUTTON_SELECT_PIN, IOC_OVERRIDE_PUE);
137 
138  nvic_interrupt_enable(BUTTON_SELECT_VECTOR);
139 
141  return 1;
142 }
143 /*---------------------------------------------------------------------------*/
144 /**
145  * \brief Init function for the left button.
146  *
147  * Parameters are ignored. They have been included because the prototype is
148  * dictated by the core sensor api. The return value is also not required by
149  * the API but otherwise ignored.
150  *
151  * \param type ignored
152  * \param value ignored
153  * \return ignored
154  */
155 static int
156 config_left(int type, int value)
157 {
158  config(BUTTON_LEFT_PORT_BASE, BUTTON_LEFT_PIN_MASK);
159 
161 
162  nvic_interrupt_enable(BUTTON_LEFT_VECTOR);
163 
165  return 1;
166 }
167 /*---------------------------------------------------------------------------*/
168 /**
169  * \brief Init function for the right button.
170  *
171  * Parameters are ignored. They have been included because the prototype is
172  * dictated by the core sensor api. The return value is also not required by
173  * the API but otherwise ignored.
174  *
175  * \param type ignored
176  * \param value ignored
177  * \return ignored
178  */
179 static int
180 config_right(int type, int value)
181 {
182  config(BUTTON_RIGHT_PORT_BASE, BUTTON_RIGHT_PIN_MASK);
183 
184  ioc_set_over(BUTTON_RIGHT_PORT, BUTTON_RIGHT_PIN, IOC_OVERRIDE_PUE);
185 
186  nvic_interrupt_enable(BUTTON_RIGHT_VECTOR);
187 
189  return 1;
190 }
191 /*---------------------------------------------------------------------------*/
192 /**
193  * \brief Init function for the up button.
194  *
195  * Parameters are ignored. They have been included because the prototype is
196  * dictated by the core sensor api. The return value is also not required by
197  * the API but otherwise ignored.
198  *
199  * \param type ignored
200  * \param value ignored
201  * \return ignored
202  */
203 static int
204 config_up(int type, int value)
205 {
206  config(BUTTON_UP_PORT_BASE, BUTTON_UP_PIN_MASK);
207 
209 
210  nvic_interrupt_enable(BUTTON_UP_VECTOR);
211 
213  return 1;
214 }
215 /*---------------------------------------------------------------------------*/
216 /**
217  * \brief Init function for the down button.
218  *
219  * Parameters are ignored. They have been included because the prototype is
220  * dictated by the core sensor api. The return value is also not required by
221  * the API but otherwise ignored.
222  *
223  * \param type ignored
224  * \param value ignored
225  * \return ignored
226  */
227 static int
228 config_down(int type, int value)
229 {
230  config(BUTTON_DOWN_PORT_BASE, BUTTON_DOWN_PIN_MASK);
231 
233 
234  nvic_interrupt_enable(BUTTON_DOWN_VECTOR);
235 
237  return 1;
238 }
239 /*---------------------------------------------------------------------------*/
240 void
242 {
243  timer_set(&debouncetimer, 0);
244 }
245 /*---------------------------------------------------------------------------*/
246 SENSORS_SENSOR(button_select_sensor, BUTTON_SENSOR, NULL, config_select, NULL);
247 SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, NULL, config_left, NULL);
248 SENSORS_SENSOR(button_right_sensor, BUTTON_SENSOR, NULL, config_right, NULL);
249 SENSORS_SENSOR(button_up_sensor, BUTTON_SENSOR, NULL, config_up, NULL);
250 SENSORS_SENSOR(button_down_sensor, BUTTON_SENSOR, NULL, config_down, NULL);
251 
252 /** @} */
#define GPIO_TRIGGER_SINGLE_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on single edge (controlled by G...
Definition: gpio.h:178
#define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Enable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:202
static int config_down(int type, int value)
Init function for the down button.
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
Definition: gpio.h:93
#define BUTTON_RIGHT_PORT
BUTTON_RIGHT -> PC5.
Definition: board.h:152
static void btn_callback(uint8_t port, uint8_t pin)
Callback registered with the GPIO module.
Definition: button-sensor.c:99
static int config_up(int type, int value)
Init function for the up button.
#define IOC_OVERRIDE_PUE
Pull Up Enable.
Definition: ioc.h:223
const struct sensors_sensor button_left_sensor
Exports a global symbol to be used by the sensor API.
#define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to detect edge.
Definition: gpio.h:155
Timer library header file.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
#define BUTTON_LEFT_PORT
BUTTON_LEFT -> PC4.
Definition: board.h:147
Header file for the ARM Nested Vectored Interrupt Controller.
#define BUTTON_UP_PORT
BUTTON_UP -> PC6.
Definition: board.h:157
A timer.
Definition: timer.h:86
#define BUTTON_SELECT_PORT
BUTTON_SELECT -> PA3.
Definition: board.h:142
static int config_select(int type, int value)
Init function for the select button.
static int config_right(int type, int value)
Init function for the right button.
#define BUTTON_DOWN_PORT
BUTTON_DOWN -> PC7.
Definition: board.h:162
#define NULL
The null pointer.
Header file with declarations for the I/O Control module.
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE. ...
Definition: gpio.h:259
static void config(uint32_t port_base, uint32_t pin_mask)
Common initialiser for all buttons.
Definition: button-sensor.c:71
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
#define GPIO_DETECT_RISING(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on rising edge.
Definition: gpio.h:186
const struct sensors_sensor button_select_sensor
Exports a global symbol to be used by the sensor API.
void nvic_interrupt_enable(uint32_t intr)
Enables interrupt intr.
Definition: nvic.c:64
static int config_left(int type, int value)
Init function for the left button.
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
Definition: ioc.c:54
static int value(int type, nrf_drv_gpiote_pin_t pin)
Return current state of a button.
void gpio_register_callback(gpio_callback_t f, uint8_t port, uint8_t pin)
Register GPIO callback.
Definition: gpio.c:56
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:122
void button_sensor_init()
Common initialiser for all SmartRF Buttons.