Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_analog_sensor.c
1 #include <bc_analog_sensor.h>
2 
3 static void _bc_analog_sensor_task_interval(void *param);
4 
5 static void _bc_analog_sensor_task_measure(void *param);
6 
7 static void _bc_analog_sensor_adc_event_handler(bc_adc_channel_t channel, bc_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 = bc_scheduler_register(_bc_analog_sensor_task_interval, self, BC_TICK_INFINITY);
17  self->_task_id_measure = bc_scheduler_register(_bc_analog_sensor_task_measure, self, BC_TICK_INFINITY);
18 
19  bc_adc_init();
20 
21  bc_adc_set_event_handler(self->_adc_channel, _bc_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 bc_analog_sensor_set_event_handler(bc_analog_sensor_t *self, void (*event_handler)(bc_analog_sensor_t *, bc_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 == BC_TICK_INFINITY)
40  {
41  bc_scheduler_plan_absolute(self->_task_id_interval, BC_TICK_INFINITY);
42  }
43  else
44  {
45  bc_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  bc_scheduler_plan_now(self->_task_id_measure);
61 
62  return true;
63 }
64 
65 bool bc_analog_sensor_get_value(bc_analog_sensor_t *self, uint16_t *result)
66 {
67  if (self->_state != BC_ANALOG_SENSOR_STATE_UPDATE)
68  {
69  return false;
70  }
71 
72  *result = self->_value;
73 
74  return true;
75 }
76 
77 static void _bc_analog_sensor_task_interval(void *param)
78 {
79  bc_analog_sensor_t *self = param;
80 
82 
83  bc_scheduler_plan_current_relative(self->_update_interval);
84 }
85 
86 static void _bc_analog_sensor_task_measure(void *param)
87 {
88  bc_analog_sensor_t *self = param;
89 
90 start:
91 
92  switch (self->_state)
93  {
94  case BC_ANALOG_SENSOR_STATE_ERROR:
95  {
96  self->_measurement_active = false;
97 
98  if (self->_event_handler != NULL)
99  {
100  self->_event_handler(self, BC_ANALOG_SENSOR_EVENT_ERROR, self->_event_param);
101  }
102 
103  self->_state = BC_ANALOG_SENSOR_STATE_ENABLE;
104 
105  return;
106  }
107  case BC_ANALOG_SENSOR_STATE_ENABLE:
108  {
109  self->_state = BC_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  bc_scheduler_plan_current_from_now(self->_driver->get_settling_interval(self));
118 
119  return;
120  }
121  }
122 
123  goto start;
124  }
125  case BC_ANALOG_SENSOR_STATE_MEASURE:
126  {
127  if (!bc_adc_get_value(self->_adc_channel, &self->_value))
128  {
129  self->_state = BC_ANALOG_SENSOR_STATE_ERROR;
130 
131  goto start;
132  }
133 
134  self->_state = BC_ANALOG_SENSOR_STATE_DISABLE;
135 
136  goto start;
137  }
138  case BC_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 = BC_ANALOG_SENSOR_STATE_UPDATE;
146 
147  goto start;
148  }
149  case BC_ANALOG_SENSOR_STATE_UPDATE:
150  {
151  self->_measurement_active = false;
152 
153  if (self->_event_handler != NULL)
154  {
155  self->_event_handler(self, BC_ANALOG_SENSOR_EVENT_UPDATE, self->_event_param);
156  }
157 
158  self->_state = BC_ANALOG_SENSOR_STATE_ENABLE;
159 
160  return;
161  }
162  default:
163  {
164  self->_state = BC_ANALOG_SENSOR_STATE_ERROR;
165 
166  goto start;
167  }
168  }
169 }
170 
171 static void _bc_analog_sensor_adc_event_handler(bc_adc_channel_t channel, bc_adc_event_t event, void *param)
172 {
173  (void) channel;
174 
175  bc_analog_sensor_t *self = param;
176 
177  if (event == BC_ADC_EVENT_DONE)
178  {
179  self->_state = BC_ANALOG_SENSOR_STATE_DISABLE;
180  }
181  else
182  {
183  self->_state = BC_ANALOG_SENSOR_STATE_ERROR;
184  }
185 
186  bc_scheduler_plan_now(self->_task_id_measure);
187 }
Analog sensor driver interface.
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
void bc_scheduler_plan_absolute(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to absolute tick.
Definition: bc_scheduler.c:124
void bc_analog_sensor_set_event_handler(bc_analog_sensor_t *self, void(*event_handler)(bc_analog_sensor_t *, bc_analog_sensor_event_t, void *), void *event_param)
Set callback function.
bc_scheduler_task_id_t bc_scheduler_register(void(*task)(void *), void *param, bc_tick_t tick)
Register task in scheduler.
Definition: bc_scheduler.c:56
void bc_scheduler_plan_now(bc_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
Definition: bc_scheduler.c:119
void bc_analog_sensor_set_update_interval(bc_analog_sensor_t *self, bc_tick_t interval)
Set measurement interval.
void bc_scheduler_plan_current_relative(bc_tick_t tick)
Schedule current task to tick relative from current spin.
Definition: bc_scheduler.c:149
void bc_adc_init()
Initialize ADC converter.
Definition: bc_adc.c:64
struct bc_analog_sensor_t bc_analog_sensor_t
Analog sensor instance.
bc_analog_sensor_event_t
Callback events.
void bc_scheduler_plan_relative(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to tick relative from current spin.
Definition: bc_scheduler.c:129
void bc_scheduler_plan_current_from_now(bc_tick_t tick)
Schedule current task to tick relative from now.
Definition: bc_scheduler.c:154
#define BC_TICK_INFINITY
Maximum timestamp value.
Definition: bc_tick.h:12
bc_adc_event_t
ADC event.
Definition: bc_adc.h:88
bool bc_analog_sensor_measure(bc_analog_sensor_t *self)
Start measurement manually.
bool bc_adc_set_event_handler(bc_adc_channel_t channel, void(*event_handler)(bc_adc_channel_t, bc_adc_event_t, void *), void *event_param)
Set callback function.
Definition: bc_adc.c:216
void bc_analog_sensor_init(bc_analog_sensor_t *self, bc_adc_channel_t adc_channel, const bc_analog_sensor_driver_t *driver)
Initialize generic analog sensor.
bc_adc_channel_t
ADC channel.
Definition: bc_adc.h:13
ADC event.
Definition: bc_adc.h:91
bool bc_adc_get_value(bc_adc_channel_t channel, uint16_t *result)
Reads the ADC channel value.
Definition: bc_adc.c:176