Firmware SDK
twr_switch.c
1 #include <twr_switch.h>
2 #include <twr_timer.h>
3 
4 #define _TWR_SWITCH_SCAN_INTERVAL 50
5 #define _TWR_SWITCH_DEBOUNCE_TIME 20
6 #define _TWR_SWITCH_PULL_ADVANCE_TIME_US 50
7 
8 static void _twr_switch_task(void *param);
9 
10 static const twr_gpio_pull_t _twr_switch_pull_lut[5] = {
16 };
17 
19 {
20  memset(self, 0, sizeof(&self));
21  self->_channel = channel;
22  self->_type = type;
23  self->_pull = pull;
24  self->_scan_interval = _TWR_SWITCH_SCAN_INTERVAL;
25  self->_debounce_time = _TWR_SWITCH_DEBOUNCE_TIME;
26  self->_pull_advance_time = _TWR_SWITCH_PULL_ADVANCE_TIME_US;
27 
28  twr_gpio_init(channel);
29 
31 
32  self->_task_id = twr_scheduler_register(_twr_switch_task, self, 0);
33 
34  if ((self->_pull == TWR_SWITCH_PULL_UP_DYNAMIC) || (self->_pull == TWR_SWITCH_PULL_DOWN_DYNAMIC))
35  {
36  if (self->_pull_advance_time > 1000)
37  {
38  self->_task_state = TWR_SWITCH_TASK_STATE_SET_PULL;
39  }
40 
41  twr_gpio_set_pull(self->_channel, TWR_GPIO_PULL_NONE);
42 
44  }
45  else
46  {
47  twr_gpio_set_pull(self->_channel, _twr_switch_pull_lut[self->_pull]);
48  }
49 }
50 
52 {
53  return self->_pin_state != 0 ? TWR_SWITCH_OPEN : TWR_SWITCH_CLOSE;
54 }
55 
56 void twr_switch_set_event_handler(twr_switch_t *self, void (*event_handler)(twr_switch_t *, twr_switch_event_t, void*), void *event_param)
57 {
58  self->_event_handler = event_handler;
59  self->_event_param = event_param;
60 }
61 
63 {
64  self->_scan_interval = scan_interval;
65 }
66 
68 {
69  self->_debounce_time = debounce_time;
70 }
71 
72 void twr_switch_set_pull_advance_time(twr_switch_t *self, uint16_t pull_advance_time_us)
73 {
74  self->_pull_advance_time = pull_advance_time_us;
75 }
76 
77 static void _twr_switch_task(void *param)
78 {
79  twr_switch_t *self = (twr_switch_t *) param;
80 
81  switch (self->_task_state)
82  {
83  case TWR_SWITCH_TASK_STATE_MEASURE:
84  {
85  bool dynamic = (self->_pull == TWR_SWITCH_PULL_UP_DYNAMIC) || (self->_pull == TWR_SWITCH_PULL_DOWN_DYNAMIC);
86 
87  if (dynamic)
88  {
89  if (self->_pull_advance_time < 1000)
90  {
91  twr_gpio_set_pull(self->_channel, _twr_switch_pull_lut[self->_pull]);
92 
94 
95  twr_timer_delay(self->_pull_advance_time);
96 
98  }
99  }
100 
101  int pin_state = twr_gpio_get_input(self->_channel);
102 
103  if (dynamic)
104  {
105  twr_gpio_set_pull(self->_channel, TWR_GPIO_PULL_NONE);
106 
107  if (self->_pull_advance_time > 1000)
108  {
109  self->_task_state = TWR_SWITCH_TASK_STATE_SET_PULL;
110  }
111  }
112 
113  if (self->_type == TWR_SWITCH_TYPE_NC)
114  {
115  pin_state = pin_state == 0 ? 1 : 0;
116  }
117 
119 
120  if (self->_pin_state != pin_state)
121  {
122  if (self->_tick_debounce == TWR_TICK_INFINITY)
123  {
124  self->_tick_debounce = tick_now + self->_debounce_time;
125 
126  twr_scheduler_plan_current_relative(self->_debounce_time);
127 
128  return;
129  }
130 
131  if (tick_now >= self->_tick_debounce)
132  {
133  self->_pin_state = pin_state;
134 
135  if (self->_event_handler != NULL)
136  {
137  if (self->_pin_state != 0)
138  {
139  self->_event_handler(self, TWR_SWITCH_EVENT_CLOSED, self->_event_param);
140  }
141  else
142  {
143  self->_event_handler(self, TWR_SWITCH_EVENT_OPENED, self->_event_param);
144  }
145  }
146  }
147  }
148  else
149  {
150  self->_tick_debounce = TWR_TICK_INFINITY;
151  }
152 
153  twr_scheduler_plan_current_relative(self->_scan_interval);
154 
155  return;
156 
157  }
158  case TWR_SWITCH_TASK_STATE_SET_PULL:
159  {
160  twr_gpio_set_pull(self->_channel, _twr_switch_pull_lut[self->_pull]);
161 
162  twr_scheduler_plan_current_relative(self->_pull_advance_time / 1000);
163 
164  self->_task_state = TWR_SWITCH_TASK_STATE_MEASURE;
165 
166  return;
167  }
168  default:
169  {
170  return;
171  }
172  }
173 }
void twr_gpio_set_pull(twr_gpio_channel_t channel, twr_gpio_pull_t pull)
Set pull-up/pull-down configuration for GPIO channel.
Definition: twr_gpio.c:340
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
Definition: twr_gpio.c:325
twr_gpio_channel_t
GPIO channels.
Definition: twr_gpio.h:13
twr_gpio_pull_t
GPIO pull-up/pull-down setting.
Definition: twr_gpio.h:88
int twr_gpio_get_input(twr_gpio_channel_t channel)
Get input state for GPIO channel.
Definition: twr_gpio.c:465
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
Definition: twr_gpio.c:367
@ TWR_GPIO_MODE_INPUT
GPIO channel operates as input.
Definition: twr_gpio.h:105
@ TWR_GPIO_PULL_NONE
GPIO channel has no pull-up/pull-down.
Definition: twr_gpio.h:90
@ TWR_GPIO_PULL_DOWN
GPIO channel has pull-down.
Definition: twr_gpio.h:96
@ TWR_GPIO_PULL_UP
GPIO channel has pull-up.
Definition: twr_gpio.h:93
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
twr_tick_t twr_scheduler_get_spin_tick(void)
Get current tick of spin in which task has been run.
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
Definition: twr_scheduler.c:53
bool twr_switch_get_state(twr_switch_t *self)
Get state.
Definition: twr_switch.c:51
void twr_switch_init(twr_switch_t *self, twr_gpio_channel_t channel, twr_switch_type_t type, twr_switch_pull_t pull)
Initialize button.
Definition: twr_switch.c:18
void twr_switch_set_pull_advance_time(twr_switch_t *self, uint16_t pull_advance_time_us)
Set pull advance time (work only with dynamic pull up/down), default 50us, for time bigger than 1000u...
Definition: twr_switch.c:72
void twr_switch_set_debounce_time(twr_switch_t *self, twr_tick_t debounce_time)
Set debounce time (minimum sampling interval during which input cannot change to toggle its state),...
Definition: twr_switch.c:67
twr_switch_event_t
Callback events.
Definition: twr_switch.h:18
struct twr_switch_t twr_switch_t
State.
Definition: twr_switch.h:62
twr_switch_pull_t
Pull.
Definition: twr_switch.h:42
void twr_switch_set_scan_interval(twr_switch_t *self, twr_tick_t scan_interval)
Set scan interval (period of button input sampling), default 50ms.
Definition: twr_switch.c:62
void twr_switch_set_event_handler(twr_switch_t *self, void(*event_handler)(twr_switch_t *, twr_switch_event_t, void *), void *event_param)
Set callback function.
Definition: twr_switch.c:56
twr_switch_type_t
Type.
Definition: twr_switch.h:30
@ TWR_SWITCH_EVENT_OPENED
Event Opened.
Definition: twr_switch.h:20
@ TWR_SWITCH_EVENT_CLOSED
Event Closed.
Definition: twr_switch.h:23
@ TWR_SWITCH_PULL_NONE
Pull None.
Definition: twr_switch.h:44
@ TWR_SWITCH_PULL_DOWN
Pull Down.
Definition: twr_switch.h:53
@ TWR_SWITCH_PULL_UP
Pull Up.
Definition: twr_switch.h:47
@ TWR_SWITCH_PULL_DOWN_DYNAMIC
Pull Down dynamic (Turns pull only for measurement)
Definition: twr_switch.h:56
@ TWR_SWITCH_PULL_UP_DYNAMIC
Pull Up dynamic (Turns pull only for measurement)
Definition: twr_switch.h:50
@ TWR_SWITCH_TYPE_NC
Type Normally Closed.
Definition: twr_switch.h:35
#define TWR_TICK_INFINITY
Maximum timestamp value.
Definition: twr_tick.h:12
uint64_t twr_tick_t
Timestamp data type.
Definition: twr_tick.h:16
void twr_timer_init(void)
Initialize timer.
Definition: twr_timer.c:23
void twr_timer_delay(uint16_t microseconds)
Relative delay.
Definition: twr_timer.c:59
void twr_timer_stop(void)
Stop timer.
Definition: twr_timer.c:42
void twr_timer_start(void)
Start timer.
Definition: twr_timer.c:28