Contiki-NG
ipso-button.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Yanzi Networks AB.
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 copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * \addtogroup ipso-objects
33 * @{
34 */
35
36/**
37 * \file
38 * Implementation of OMA LWM2M / IPSO button as a digital input
39 * NOTE: only works with a Contiki Button Sensor (not for Standalone)
40 * \author
41 * Joakim Eriksson <joakime@sics.se>
42 * Niclas Finne <nfi@sics.se>
43 */
44
45#include "contiki.h"
46#include "lwm2m-object.h"
47#include "lwm2m-engine.h"
48
49#define DEBUG 0
50#if DEBUG
51#include <stdio.h>
52#define PRINTF(...) printf(__VA_ARGS__)
53#else
54#define PRINTF(...)
55#endif
56
57#define IPSO_INPUT_STATE 5500
58#define IPSO_INPUT_COUNTER 5501
59#define IPSO_INPUT_DEBOUNCE 5503
60#define IPSO_INPUT_EDGE_SEL 5504
61#define IPSO_INPUT_CTR_RESET 5505
62#define IPSO_INPUT_SENSOR_TYPE 5751
63
64#if PLATFORM_HAS_BUTTON
65#if PLATFORM_SUPPORTS_BUTTON_HAL
66#include "dev/button-hal.h"
67#else
68#include "dev/button-sensor.h"
69#define IPSO_BUTTON_SENSOR button_sensor
70static struct etimer timer;
71#endif
72
73PROCESS(ipso_button_process, "ipso-button");
74#endif /* PLATFORM_HAS_BUTTON */
75
76
77static lwm2m_status_t lwm2m_callback(lwm2m_object_instance_t *object,
78 lwm2m_context_t *ctx);
79
80static int input_state = 0;
81static int32_t counter = 0;
82static int32_t edge_selection = 3; /* both */
83static int32_t debounce_time = 10;
84
85static const lwm2m_resource_id_t resources[] = {
86 RO(IPSO_INPUT_STATE), RO(IPSO_INPUT_COUNTER),
87 RW(IPSO_INPUT_DEBOUNCE), RW(IPSO_INPUT_EDGE_SEL), EX(IPSO_INPUT_CTR_RESET),
88 RO(IPSO_INPUT_SENSOR_TYPE)
89};
90
91/* Only support for one button for now */
92static lwm2m_object_instance_t reg_object = {
93 .object_id = 3200,
94 .instance_id = 0,
95 .resource_ids = resources,
96 .resource_count = sizeof(resources) / sizeof(lwm2m_resource_id_t),
97 .callback = lwm2m_callback,
98};
99
100/*---------------------------------------------------------------------------*/
101static int
102read_state(void)
103{
104 PRINTF("Read button state: %d\n", input_state);
105 return input_state;
106}
107/*---------------------------------------------------------------------------*/
108/*---------------------------------------------------------------------------*/
109static lwm2m_status_t
110lwm2m_callback(lwm2m_object_instance_t *object,
111 lwm2m_context_t *ctx)
112{
113 if(ctx->operation == LWM2M_OP_READ) {
114 switch(ctx->resource_id) {
115 case IPSO_INPUT_STATE:
116 lwm2m_object_write_int(ctx, read_state());
117 break;
118 case IPSO_INPUT_COUNTER:
119 lwm2m_object_write_int(ctx, counter);
120 break;
121 case IPSO_INPUT_DEBOUNCE:
122 lwm2m_object_write_int(ctx, debounce_time);
123 break;
124 case IPSO_INPUT_EDGE_SEL:
125 lwm2m_object_write_int(ctx, edge_selection);
126 break;
127 case IPSO_INPUT_SENSOR_TYPE:
128 lwm2m_object_write_string(ctx, "button", strlen("button"));
129 break;
130 default:
131 return LWM2M_STATUS_ERROR;
132 }
133 } else if(ctx->operation == LWM2M_OP_EXECUTE) {
134 if(ctx->resource_id == IPSO_INPUT_CTR_RESET) {
135 counter = 0;
136 } else {
137 return LWM2M_STATUS_ERROR;
138 }
139 }
140 return LWM2M_STATUS_OK;
141}
142/*---------------------------------------------------------------------------*/
143void
144ipso_button_init(void)
145{
146 /* register this device and its handlers - the handlers automatically
147 sends in the object to handle */
148 lwm2m_engine_add_object(&reg_object);
149
150#if PLATFORM_HAS_BUTTON
151 process_start(&ipso_button_process, NULL);
152#endif /* PLATFORM_HAS_BUTTON */
153}
154/*---------------------------------------------------------------------------*/
155#if PLATFORM_HAS_BUTTON
156PROCESS_THREAD(ipso_button_process, ev, data)
157{
159
160#if !PLATFORM_SUPPORTS_BUTTON_HAL
161 SENSORS_ACTIVATE(IPSO_BUTTON_SENSOR);
162#endif
163
164 while(1) {
166
167#if PLATFORM_SUPPORTS_BUTTON_HAL
168 if(ev == button_hal_press_event) {
169 input_state = 1;
170 counter++;
171 if((edge_selection & 2) != 0) {
172 lwm2m_notify_object_observers(&reg_object, IPSO_INPUT_STATE);
173 }
174 lwm2m_notify_object_observers(&reg_object, IPSO_INPUT_COUNTER);
175 } else if(ev == button_hal_release_event) {
176 input_state = 0;
177 if((edge_selection & 1) != 0) {
178 lwm2m_notify_object_observers(&reg_object, IPSO_INPUT_STATE);
179 }
180 }
181#else /* PLATFORM_SUPPORTS_BUTTON_HAL */
182 if(ev == sensors_event && data == &IPSO_BUTTON_SENSOR) {
183 if(!input_state) {
184 int32_t time;
185 input_state = 1;
186 counter++;
187 if((edge_selection & 2) != 0) {
188 lwm2m_notify_object_observers(&reg_object, IPSO_INPUT_STATE);
189 }
190 lwm2m_notify_object_observers(&reg_object, IPSO_INPUT_COUNTER);
191
192 time = (debounce_time * CLOCK_SECOND / 1000);
193 if(time < 1) {
194 time = 1;
195 }
196 etimer_set(&timer, (clock_time_t)time);
197 }
198 } else if(ev == PROCESS_EVENT_TIMER && data == &timer) {
199 if(!input_state) {
200 /* Button is not in pressed state */
201 } else if(IPSO_BUTTON_SENSOR.value(0) != 0) {
202 /* Button is still pressed */
204 } else {
205 input_state = 0;
206 if((edge_selection & 1) != 0) {
207 lwm2m_notify_object_observers(&reg_object, IPSO_INPUT_STATE);
208 }
209 }
210 }
211#endif /* PLATFORM_SUPPORTS_BUTTON_HAL */
212 }
213
214 PROCESS_END();
215}
216#endif /* PLATFORM_HAS_BUTTON */
217/*---------------------------------------------------------------------------*/
218/** @} */
Header file for the button HAL.
process_event_t button_hal_press_event
A broadcast event generated when a button gets pressed.
Definition: button-hal.c:53
process_event_t button_hal_release_event
A broadcast event generated when a button gets released.
Definition: button-hal.c:54
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1154
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
void etimer_reset(struct etimer *et)
Reset an event timer with the same interval as was previously set.
Definition: etimer.c:192
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition: etimer.c:177
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
Header file for the Contiki OMA LWM2M engine.
Header file for the LWM2M object API.
A timer.
Definition: etimer.h:76
A timer.
Definition: timer.h:82