Firmware SDK
twr_pulse_counter.c
1 #include <twr_pulse_counter.h>
2 #include <twr_system.h>
3 
4 typedef struct
5 {
7  unsigned int count;
9  twr_tick_t update_interval;
10  void (*event_handler)(twr_module_sensor_channel_t, twr_pulse_counter_event_t, void *);
11  void *event_param;
12  bool pending_event_flag;
13  twr_pulse_counter_event_t pending_event;
15 
17 
18 static twr_pulse_counter_t _twr_module_pulse_counter[3];
19 
20 static void _twr_pulse_counter_channel_task_update(void *param);
21 static void _twr_pulse_counter_channel_exti(twr_exti_line_t line, void *param);
22 
24 {
25  static const twr_exti_line_t twr_pulse_counter_exti_line[3] =
26  {
30  };
31 
32  memset(&_twr_module_pulse_counter[channel], 0, sizeof(_twr_module_pulse_counter[channel]));
33 
37 
38  _twr_module_pulse_counter[channel].channel = channel;
39  _twr_module_pulse_counter[channel].edge = edge;
40  _twr_module_pulse_counter[channel].update_interval = TWR_TICK_INFINITY;
41  _twr_module_pulse_counter[channel].task_id = twr_scheduler_register(_twr_pulse_counter_channel_task_update, &_twr_module_pulse_counter[channel], TWR_TICK_INFINITY);
42 
43  twr_exti_register(twr_pulse_counter_exti_line[channel], (twr_exti_edge_t) edge, _twr_pulse_counter_channel_exti, &_twr_module_pulse_counter[channel].channel);
44 }
45 
47 {
48  _twr_module_pulse_counter[channel].event_handler = event_handler;
49  _twr_module_pulse_counter[channel].event_param = event_param;
50 }
51 
53 {
54  _twr_module_pulse_counter[channel].update_interval = interval;
55 
56  if (_twr_module_pulse_counter[channel].update_interval == TWR_TICK_INFINITY)
57  {
58  twr_scheduler_plan_absolute(_twr_module_pulse_counter[channel].task_id, TWR_TICK_INFINITY);
59  }
60  else
61  {
62  twr_scheduler_plan_relative(_twr_module_pulse_counter[channel].task_id, _twr_module_pulse_counter[channel].update_interval);
63  }
64 }
65 
66 void twr_pulse_counter_set(twr_module_sensor_channel_t channel, unsigned int count)
67 {
68  _twr_module_pulse_counter[channel].count = count;
69 }
70 
72 {
73  return _twr_module_pulse_counter[channel].count;
74 }
75 
77 {
78  _twr_module_pulse_counter[channel].count = 0;
79 }
80 
81 static void _twr_pulse_counter_channel_task_update(void *param)
82 {
83  twr_pulse_counter_t *self = param;
84 
85  if (self->pending_event_flag)
86  {
87  self->pending_event_flag = false;
88 
89  if (self->event_handler != NULL)
90  {
91  if (self->pending_event == TWR_PULSE_COUNTER_EVENT_OVERFLOW)
92  {
93  self->event_handler(self->channel, TWR_PULSE_COUNTER_EVENT_OVERFLOW, self->event_param);
94 
95  self->pending_event_flag = true;
96  self->pending_event = TWR_PULSE_COUNTER_EVENT_UPDATE;
97  }
98  else if (self->pending_event == TWR_PULSE_COUNTER_EVENT_UPDATE)
99  {
100  self->event_handler(self->channel, TWR_PULSE_COUNTER_EVENT_UPDATE, self->event_param);
101  }
102  }
103  }
104 
105  twr_scheduler_plan_current_relative(self->update_interval);
106 }
107 
108 static void _twr_pulse_counter_channel_exti(twr_exti_line_t line, void *param)
109 {
110  (void) line;
112 
113  _twr_module_pulse_counter[channel].count++;
114 
115  _twr_module_pulse_counter[channel].pending_event_flag = true;
116  _twr_module_pulse_counter[channel].pending_event = TWR_PULSE_COUNTER_EVENT_UPDATE;
117 
118  if (_twr_module_pulse_counter[channel].count == 0)
119  {
120  _twr_module_pulse_counter[channel].pending_event = TWR_PULSE_COUNTER_EVENT_OVERFLOW;
121  }
122 
123  twr_scheduler_plan_now(_twr_module_pulse_counter[channel].task_id);
124 }
Channel operates as input.
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_pulse_counter_edge_t
Pulse counter active edges.
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
twr_exti_edge_t
Interrupt edge sensitivity.
Definition: twr_exti.h:195
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_module_sensor_init(void)
Initialize Sensor Module.
twr_pulse_counter_event_t
Pulse counter event.
twr_exti_line_t
EXTI lines.
Definition: twr_exti.h:21
void twr_pulse_counter_set_update_interval(twr_module_sensor_channel_t channel, twr_tick_t interval)
Set update interval.
void twr_module_sensor_set_mode(twr_module_sensor_channel_t channel, twr_module_sensor_mode_t mode)
Set output mode of Sensor Module channel.
bool twr_module_sensor_set_pull(twr_module_sensor_channel_t channel, twr_module_sensor_pull_t pull)
Set pull of Sensor Module channel.
void twr_pulse_counter_reset(twr_module_sensor_channel_t channel)
Set count to zero.
twr_module_sensor_channel_t
Sensor Module channels.
EXTI line PA4.
Definition: twr_exti.h:36
void twr_pulse_counter_init(twr_module_sensor_channel_t channel, twr_pulse_counter_edge_t edge)
Initialize pulse counter.
size_t twr_scheduler_task_id_t
Task ID assigned by scheduler.
Definition: twr_scheduler.h:22
EXTI line PA6.
Definition: twr_exti.h:42
void twr_pulse_counter_set_event_handler(twr_module_sensor_channel_t channel, void(*event_handler)(twr_module_sensor_channel_t, twr_pulse_counter_event_t, void *), void *event_param)
Set callback function.
uint64_t twr_tick_t
Timestamp data type.
Definition: twr_tick.h:16
EXTI line PA5.
Definition: twr_exti.h:39
void twr_exti_register(twr_exti_line_t line, twr_exti_edge_t edge, void(*callback)(twr_exti_line_t, void *), void *param)
Enable EXTI line interrupt and register callback function.
Definition: twr_exti.c:17
unsigned int twr_pulse_counter_get(twr_module_sensor_channel_t channel)
Get count.
#define TWR_TICK_INFINITY
Maximum timestamp value.
Definition: twr_tick.h:12
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.
Channel has internal pull-up.
void twr_pulse_counter_set(twr_module_sensor_channel_t channel, unsigned int count)
Set count.