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  * This file is part of the Contiki operating system.
32  *
33  */
34 /*---------------------------------------------------------------------------*/
35 /**
36  * \addtogroup openmote-button-sensor
37  * @{
38  *
39  * \file
40  * Driver for for the OpenMote-CC2538 user button
41  */
42 /*---------------------------------------------------------------------------*/
43 #include "contiki.h"
44 #include "dev/nvic.h"
45 #include "dev/ioc.h"
46 #include "dev/gpio.h"
47 #include "dev/button-sensor.h"
48 #include "sys/timer.h"
49 #include "sys/ctimer.h"
50 #include "sys/process.h"
51 
52 #include <stdint.h>
53 #include <string.h>
54 /*---------------------------------------------------------------------------*/
55 #define BUTTON_USER_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_USER_PORT)
56 #define BUTTON_USER_PIN_MASK GPIO_PIN_MASK(BUTTON_USER_PIN)
57 /*---------------------------------------------------------------------------*/
58 #define DEBOUNCE_DURATION (CLOCK_SECOND >> 4)
59 
60 static struct timer debouncetimer;
61 /*---------------------------------------------------------------------------*/
62 static clock_time_t press_duration = 0;
63 static struct ctimer press_counter;
64 static uint8_t press_event_counter;
65 
66 process_event_t button_press_duration_exceeded;
67 /*---------------------------------------------------------------------------*/
68 static void
69 duration_exceeded_callback(void *data)
70 {
71  press_event_counter++;
72  process_post(PROCESS_BROADCAST, button_press_duration_exceeded,
73  &press_event_counter);
74  ctimer_set(&press_counter, press_duration, duration_exceeded_callback,
75  NULL);
76 }
77 /*---------------------------------------------------------------------------*/
78 /**
79  * \brief Retrieves the value of the button pin
80  * \param type Returns the pin level or the counter of press duration events.
81  * type == BUTTON_SENSOR_VALUE_TYPE_LEVEL or
82  * type == BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION
83  * respectively
84  */
85 static int
86 value(int type)
87 {
88  switch(type) {
89  case BUTTON_SENSOR_VALUE_TYPE_LEVEL:
90  return GPIO_READ_PIN(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
91  case BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION:
92  return press_event_counter;
93  }
94 
95  return 0;
96 }
97 /*---------------------------------------------------------------------------*/
98 /**
99  * \brief Callback registered with the GPIO module. Gets fired with a button
100  * port/pin generates an interrupt
101  * \param port The port number that generated the interrupt
102  * \param pin The pin number that generated the interrupt. This is the pin
103  * absolute number (i.e. 0, 1, ..., 7), not a mask
104  */
105 static void
106 btn_callback(uint8_t port, uint8_t pin)
107 {
108  if(!timer_expired(&debouncetimer)) {
109  return;
110  }
111 
112  timer_set(&debouncetimer, DEBOUNCE_DURATION);
113 
114  if(press_duration) {
115  press_event_counter = 0;
116  if(value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) {
117  ctimer_set(&press_counter, press_duration, duration_exceeded_callback,
118  NULL);
119  } else {
120  ctimer_stop(&press_counter);
121  }
122  }
123 
124  sensors_changed(&button_sensor);
125 }
126 /*---------------------------------------------------------------------------*/
127 /**
128  * \brief Init function for the User button.
129  * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1
130  * or 0 respectively)
131  *
132  * \param value Depends on the value of the type argument
133  * \return Depends on the value of the type argument
134  */
135 static int
136 config_user(int type, int value)
137 {
138  switch(type) {
139  case SENSORS_HW_INIT:
140  button_press_duration_exceeded = process_alloc_event();
141 
142  /* Software controlled */
143  GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
144 
145  /* Set pin to input */
146  GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
147 
148  /* Enable edge detection */
149  GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
150 
151  /* Both Edges */
152  GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
153 
155 
157  break;
158  case SENSORS_ACTIVE:
159  if(value) {
160  GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
161  nvic_interrupt_enable(BUTTON_USER_VECTOR);
162  } else {
163  GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
164  nvic_interrupt_disable(BUTTON_USER_VECTOR);
165  }
166  return value;
167  case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL:
168  press_duration = (clock_time_t)value;
169  break;
170  default:
171  break;
172  }
173 
174  return 1;
175 }
176 /*---------------------------------------------------------------------------*/
177 SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, config_user, NULL);
178 /*---------------------------------------------------------------------------*/
179 /** @} */
#define DEBOUNCE_DURATION
Delay before button state is assumed to be stable.
Definition: button-sensor.c:54
#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
#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 IOC_OVERRIDE_PUE
Pull Up Enable.
Definition: ioc.h:223
#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
Header file for the ARM Nested Vectored Interrupt Controller.
A timer.
Definition: timer.h:86
static int config_user(int type, int value)
Init function for the User button.
static void btn_callback(uint8_t port, uint8_t pin)
Callback registered with the GPIO module.
#define GPIO_READ_PIN(PORT_BASE, PIN_MASK)
Read pins with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:148
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
process_event_t process_alloc_event(void)
Allocate a global event number.
Definition: process.c:93
const struct sensors_sensor button_sensor
Copyright (c) 2014, Analog Devices, Inc.
Definition: button-sensor.c:44
Header file for the callback timer
#define NULL
The null pointer.
Header file with declarations for the I/O Control module.
static int value(int type)
Retrieves the value of the button pin.
Definition: button-sensor.c:86
#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
#define BUTTON_USER_PORT
BUTTON_USER -> PC3.
Definition: board.h:126
#define GPIO_TRIGGER_BOTH_EDGES(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on both edges.
Definition: gpio.h:170
Header file for the Contiki process interface.
void nvic_interrupt_enable(uint32_t intr)
Enables interrupt intr.
Definition: nvic.c:64
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
void nvic_interrupt_disable(uint32_t intr)
Disables interrupt intr.
Definition: nvic.c:71
#define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Disable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:210
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition: ctimer.c:149
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
Definition: ioc.c:54
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