Firmware SDK
twr_analog_sensor.c
1 #include <twr_analog_sensor.h>
2 
3 static void _twr_analog_sensor_task_interval(void *param);
4 
5 static void _twr_analog_sensor_task_measure(void *param);
6 
7 static void _twr_analog_sensor_adc_event_handler(twr_adc_channel_t channel, twr_adc_event_t event, void *param);
8 
10 {
11  memset(self, 0, sizeof(*self));
12 
13  self->_adc_channel = adc_channel;
14  self->_driver = driver;
15 
16  self->_task_id_interval = twr_scheduler_register(_twr_analog_sensor_task_interval, self, TWR_TICK_INFINITY);
17  self->_task_id_measure = twr_scheduler_register(_twr_analog_sensor_task_measure, self, TWR_TICK_INFINITY);
18 
19  twr_adc_init();
20 
21  twr_adc_set_event_handler(self->_adc_channel, _twr_analog_sensor_adc_event_handler, self);
22 
23  if (self->_driver != NULL && self->_driver->init != NULL)
24  {
25  self->_driver->init(self);
26  }
27 }
28 
29 void twr_analog_sensor_set_event_handler(twr_analog_sensor_t *self, void (*event_handler)(twr_analog_sensor_t *, twr_analog_sensor_event_t, void *), void *event_param)
30 {
31  self->_event_handler = event_handler;
32  self->_event_param = event_param;
33 }
34 
36 {
37  self->_update_interval = interval;
38 
39  if (self->_update_interval == TWR_TICK_INFINITY)
40  {
41  twr_scheduler_plan_absolute(self->_task_id_interval, TWR_TICK_INFINITY);
42  }
43  else
44  {
45  twr_scheduler_plan_relative(self->_task_id_interval, self->_update_interval);
46 
48  }
49 }
50 
52 {
53  if (self->_measurement_active)
54  {
55  return false;
56  }
57 
58  self->_measurement_active = true;
59 
60  twr_scheduler_plan_now(self->_task_id_measure);
61 
62  return true;
63 }
64 
65 bool twr_analog_sensor_get_value(twr_analog_sensor_t *self, uint16_t *result)
66 {
67  if (self->_state != TWR_ANALOG_SENSOR_STATE_UPDATE)
68  {
69  return false;
70  }
71 
72  *result = self->_value;
73 
74  return true;
75 }
76 
77 static void _twr_analog_sensor_task_interval(void *param)
78 {
79  twr_analog_sensor_t *self = param;
80 
82 
83  twr_scheduler_plan_current_relative(self->_update_interval);
84 }
85 
86 static void _twr_analog_sensor_task_measure(void *param)
87 {
88  twr_analog_sensor_t *self = param;
89 
90 start:
91 
92  switch (self->_state)
93  {
94  case TWR_ANALOG_SENSOR_STATE_ERROR:
95  {
96  self->_measurement_active = false;
97 
98  if (self->_event_handler != NULL)
99  {
100  self->_event_handler(self, TWR_ANALOG_SENSOR_EVENT_ERROR, self->_event_param);
101  }
102 
103  self->_state = TWR_ANALOG_SENSOR_STATE_ENABLE;
104 
105  return;
106  }
107  case TWR_ANALOG_SENSOR_STATE_ENABLE:
108  {
109  self->_state = TWR_ANALOG_SENSOR_STATE_MEASURE;
110 
111  if (self->_driver != NULL && self->_driver->enable != NULL)
112  {
113  self->_driver->enable(self);
114 
115  if (self->_driver->get_settling_interval != NULL)
116  {
117  twr_scheduler_plan_current_from_now(self->_driver->get_settling_interval(self));
118 
119  return;
120  }
121  }
122 
123  goto start;
124  }
125  case TWR_ANALOG_SENSOR_STATE_MEASURE:
126  {
127  if (!twr_adc_get_value(self->_adc_channel, &self->_value))
128  {
129  self->_state = TWR_ANALOG_SENSOR_STATE_ERROR;
130 
131  goto start;
132  }
133 
134  self->_state = TWR_ANALOG_SENSOR_STATE_DISABLE;
135 
136  goto start;
137  }
138  case TWR_ANALOG_SENSOR_STATE_DISABLE:
139  {
140  if (self->_driver != NULL && self->_driver->disable != NULL)
141  {
142  self->_driver->disable(self);
143  }
144 
145  self->_state = TWR_ANALOG_SENSOR_STATE_UPDATE;
146 
147  goto start;
148  }
149  case TWR_ANALOG_SENSOR_STATE_UPDATE:
150  {
151  self->_measurement_active = false;
152 
153  if (self->_event_handler != NULL)
154  {
155  self->_event_handler(self, TWR_ANALOG_SENSOR_EVENT_UPDATE, self->_event_param);
156  }
157 
158  self->_state = TWR_ANALOG_SENSOR_STATE_ENABLE;
159 
160  return;
161  }
162  default:
163  {
164  self->_state = TWR_ANALOG_SENSOR_STATE_ERROR;
165 
166  goto start;
167  }
168  }
169 }
170 
171 static void _twr_analog_sensor_adc_event_handler(twr_adc_channel_t channel, twr_adc_event_t event, void *param)
172 {
173  (void) channel;
174 
175  twr_analog_sensor_t *self = param;
176 
177  if (event == TWR_ADC_EVENT_DONE)
178  {
179  self->_state = TWR_ANALOG_SENSOR_STATE_DISABLE;
180  }
181  else
182  {
183  self->_state = TWR_ANALOG_SENSOR_STATE_ERROR;
184  }
185 
186  twr_scheduler_plan_now(self->_task_id_measure);
187 }
bool twr_adc_set_event_handler(twr_adc_channel_t channel, void(*event_handler)(twr_adc_channel_t, twr_adc_event_t, void *), void *event_param)
Set callback function.
Definition: twr_adc.c:218
twr_adc_event_t
ADC event.
Definition: twr_adc.h:92
twr_adc_channel_t
ADC channel.
Definition: twr_adc.h:14
bool twr_adc_get_value(twr_adc_channel_t channel, uint16_t *result)
Reads the ADC channel value.
Definition: twr_adc.c:178
void twr_adc_init()
Initialize ADC converter.
Definition: twr_adc.c:66
@ TWR_ADC_EVENT_DONE
ADC event.
Definition: twr_adc.h:94
void twr_analog_sensor_init(twr_analog_sensor_t *self, twr_adc_channel_t adc_channel, const twr_analog_sensor_driver_t *driver)
Initialize generic analog sensor.
bool twr_analog_sensor_measure(twr_analog_sensor_t *self)
Start measurement manually.
twr_analog_sensor_event_t
Callback events.
struct twr_analog_sensor_t twr_analog_sensor_t
Analog sensor instance.
void twr_analog_sensor_set_update_interval(twr_analog_sensor_t *self, twr_tick_t interval)
Set measurement interval.
void twr_analog_sensor_set_event_handler(twr_analog_sensor_t *self, void(*event_handler)(twr_analog_sensor_t *, twr_analog_sensor_event_t, void *), void *event_param)
Set callback function.
@ TWR_ANALOG_SENSOR_EVENT_ERROR
Error event.
@ TWR_ANALOG_SENSOR_EVENT_UPDATE
Update event.
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
void twr_scheduler_plan_absolute(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to absolute tick.
void twr_scheduler_plan_now(twr_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
void twr_scheduler_plan_relative(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to tick relative from current spin.
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
#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
Analog sensor driver interface.