Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_pulse_counter.c
1 #include <bc_pulse_counter.h>
2 #include <bc_system.h>
3 
4 typedef struct
5 {
7  unsigned int count;
9  bc_tick_t update_interval;
10  void (*event_handler)(bc_module_sensor_channel_t, bc_pulse_counter_event_t, void *);
11  void *event_param;
12  bc_pulse_counter_event_t pending_event;
13  bc_scheduler_task_id_t task_id;
14 
16 
17 static bc_pulse_counter_t _bc_module_pulse_counter[2];
18 
19 static void _bc_pulse_counter_channel_task_update(void *param);
20 static void _bc_pulse_counter_channel_exti(bc_exti_line_t line, void *param);
21 
23 {
24  static const bc_exti_line_t bc_pulse_counter_exti_line[2] =
25  {
28  };
29 
30  memset(&_bc_module_pulse_counter[channel], 0, sizeof(_bc_module_pulse_counter[channel]));
31 
35 
36  _bc_module_pulse_counter[channel].channel = channel;
37  _bc_module_pulse_counter[channel].edge = edge;
38  _bc_module_pulse_counter[channel].update_interval = BC_TICK_INFINITY;
39  _bc_module_pulse_counter[channel].task_id = bc_scheduler_register(_bc_pulse_counter_channel_task_update, &_bc_module_pulse_counter[channel], BC_TICK_INFINITY);
40 
41  bc_exti_register(bc_pulse_counter_exti_line[channel], (bc_exti_edge_t) edge, _bc_pulse_counter_channel_exti, &_bc_module_pulse_counter[channel].channel);
42 }
43 
45 {
46  _bc_module_pulse_counter[channel].event_handler = event_handler;
47  _bc_module_pulse_counter[channel].event_param = event_param;
48 }
49 
51 {
52  _bc_module_pulse_counter[channel].update_interval = interval;
53 
54  if (_bc_module_pulse_counter[channel].update_interval == BC_TICK_INFINITY)
55  {
56  bc_scheduler_plan_absolute(_bc_module_pulse_counter[channel].task_id, BC_TICK_INFINITY);
57  }
58  else
59  {
60  bc_scheduler_plan_relative(_bc_module_pulse_counter[channel].task_id, _bc_module_pulse_counter[channel].update_interval);
61  }
62 }
63 
64 void bc_pulse_counter_set(bc_module_sensor_channel_t channel, unsigned int count)
65 {
66  _bc_module_pulse_counter[channel].count = count;
67 }
68 
70 {
71  return _bc_module_pulse_counter[channel].count;
72 }
73 
75 {
76  _bc_module_pulse_counter[channel].count = 0;
77 }
78 
79 static void _bc_pulse_counter_channel_task_update(void *param)
80 {
81  bc_pulse_counter_t *self = param;
82 
83  if (self->event_handler != NULL)
84  {
85  if (self->pending_event == BC_PULSE_COUNTER_EVENT_OVERFLOW)
86  {
87  self->event_handler(self->channel, BC_PULSE_COUNTER_EVENT_OVERFLOW, self->event_param);
88  self->pending_event = BC_PULSE_COUNTER_EVENT_UPDATE;
89  }
90  else
91  {
92  self->event_handler(self->channel, BC_PULSE_COUNTER_EVENT_UPDATE, self->event_param);
93  }
94  }
95 
96  bc_scheduler_plan_current_relative(self->update_interval);
97 }
98 
99 static void _bc_pulse_counter_channel_exti(bc_exti_line_t line, void *param)
100 {
101  (void) line;
103 
104  _bc_module_pulse_counter[channel].count++;
105  if (_bc_module_pulse_counter[channel].count == 0)
106  {
107  _bc_module_pulse_counter[channel].pending_event = BC_PULSE_COUNTER_EVENT_OVERFLOW;
108  bc_scheduler_plan_now(_bc_module_pulse_counter[channel].task_id);
109  }
110 }
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
bool bc_module_sensor_set_pull(bc_module_sensor_channel_t channel, bc_module_sensor_pull_t pull)
Set pull of Sensor Module channel.
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_pulse_counter_set_update_interval(bc_module_sensor_channel_t channel, bc_tick_t interval)
Set update interval.
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_pulse_counter_init(bc_module_sensor_channel_t channel, bc_pulse_counter_edge_t edge)
Initialize pulse counter.
void bc_scheduler_plan_now(bc_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
Definition: bc_scheduler.c:119
EXTI line PA5.
Definition: bc_exti.h:39
void bc_scheduler_plan_current_relative(bc_tick_t tick)
Schedule current task to tick relative from current spin.
Definition: bc_scheduler.c:149
bc_exti_edge_t
Interrupt edge sensitivity.
Definition: bc_exti.h:195
void bc_pulse_counter_set(bc_module_sensor_channel_t channel, unsigned int count)
Set count.
size_t bc_scheduler_task_id_t
Task ID assigned by scheduler.
Definition: bc_scheduler.h:18
void bc_exti_register(bc_exti_line_t line, bc_exti_edge_t edge, void(*callback)(bc_exti_line_t, void *), void *param)
Enable EXTI line interrupt and register callback function.
Definition: bc_exti.c:17
unsigned int bc_pulse_counter_get(bc_module_sensor_channel_t channel)
Get count.
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
Channel operates as input.
void bc_module_sensor_set_mode(bc_module_sensor_channel_t channel, bc_module_sensor_mode_t mode)
Set output mode of Sensor Module channel.
bc_exti_line_t
EXTI lines.
Definition: bc_exti.h:21
bc_pulse_counter_event_t
Pulse counter event.
EXTI line PA4.
Definition: bc_exti.h:36
Channel has internal pull-up.
#define BC_TICK_INFINITY
Maximum timestamp value.
Definition: bc_tick.h:12
void bc_pulse_counter_reset(bc_module_sensor_channel_t channel)
Set count to zero.
bc_module_sensor_channel_t
Sensor Module channels.
bool bc_module_sensor_init(void)
Initialize Sensor Module.
void bc_pulse_counter_set_event_handler(bc_module_sensor_channel_t channel, void(*event_handler)(bc_module_sensor_channel_t, bc_pulse_counter_event_t, void *), void *event_param)
Set callback function.
bc_pulse_counter_edge_t
Pulse counter active edges.