1 #include <twr_lis2dh12.h>
2 #include <twr_scheduler.h>
6 #define _TWR_LIS2DH12_DELAY_RUN 10
7 #define _TWR_LIS2DH12_DELAY_READ 10
8 #define _TWR_LIS2DH12_AUTOINCREMENT_ADR 0x80
10 static void _twr_lis2dh12_task_interval(
void *param);
11 static void _twr_lis2dh12_task_measure(
void *param);
13 static bool _twr_lis2dh12_continuous_conversion(
twr_lis2dh12_t *
self);
17 static const float _twr_lis2dh12_fs_lut[] =
25 static const float _twr_lis2dh12_ths_lut[] =
35 memset(
self, 0,
sizeof(*
self));
37 self->_i2c_channel = i2c_channel;
38 self->_i2c_address = i2c_address;
43 RCC->IOPENR |= RCC_IOPENR_GPIOBEN;
49 GPIOB->MODER &= ~GPIO_MODER_MODE6_Msk;
52 self->_task_id_measure =
twr_scheduler_register(_twr_lis2dh12_task_measure,
self, _TWR_LIS2DH12_DELAY_RUN);
59 self->_event_handler = event_handler;
60 self->_event_param = event_param;
65 self->_update_interval = interval;
81 if (self->_measurement_active)
86 self->_measurement_active =
true;
95 *result_raw =
self->_raw;
97 return self->_accelerometer_valid;
109 float sensitivity = _twr_lis2dh12_fs_lut[
self->_scale];
111 result_g->
x_axis = (result_raw.
x_axis >> 4) * sensitivity;
112 result_g->
y_axis = (result_raw.
y_axis >> 4) * sensitivity;
113 result_g->
z_axis = (result_raw.
z_axis >> 4) * sensitivity;
118 static void _twr_lis2dh12_task_interval(
void *param)
127 static void _twr_lis2dh12_task_measure(
void *param)
133 switch (self->_state)
135 case TWR_LIS2DH12_STATE_ERROR:
137 self->_accelerometer_valid =
false;
139 self->_measurement_active =
false;
141 if (self->_event_handler != NULL)
146 self->_state = TWR_LIS2DH12_STATE_INITIALIZE;
150 case TWR_LIS2DH12_STATE_INITIALIZE:
152 self->_state = TWR_LIS2DH12_STATE_ERROR;
161 if (who_am_i != 0x33)
166 uint8_t cfg_reg4 = 0x80 | ((uint8_t) self->_scale << 4) | (((uint8_t) self->_resolution & 0x01) << 3);
173 if (!_twr_lis2dh12_power_down(
self))
178 self->_state = TWR_LIS2DH12_STATE_MEASURE;
180 if (self->_measurement_active)
187 case TWR_LIS2DH12_STATE_MEASURE:
189 self->_state = TWR_LIS2DH12_STATE_ERROR;
191 if (!_twr_lis2dh12_continuous_conversion(
self))
196 self->_state = TWR_LIS2DH12_STATE_READ;
202 case TWR_LIS2DH12_STATE_READ:
204 self->_state = TWR_LIS2DH12_STATE_ERROR;
206 if (!_twr_lis2dh12_read_result(
self))
212 if(!self->_alarm_active)
214 if (!_twr_lis2dh12_power_down(
self))
220 self->_accelerometer_valid =
true;
222 self->_state = TWR_LIS2DH12_STATE_UPDATE;
226 case TWR_LIS2DH12_STATE_UPDATE:
228 self->_state = TWR_LIS2DH12_STATE_ERROR;
230 self->_measurement_active =
false;
232 if (self->_event_handler != NULL)
238 if(self->_alarm_active)
251 if (self->_event_handler != NULL)
258 self->_state = TWR_LIS2DH12_STATE_MEASURE;
264 self->_state = TWR_LIS2DH12_STATE_ERROR;
282 static bool _twr_lis2dh12_continuous_conversion(
twr_lis2dh12_t *
self)
285 uint8_t cfg_reg1 = 0x57 | ((
self->_resolution & 0x02) << 2);
302 transfer.
buffer = &
self->_raw;
313 self->_alarm_active =
true;
321 uint8_t int1_ths = (uint8_t)((alarm->
threshold) / _twr_lis2dh12_ths_lut[
self->_scale]);
334 uint8_t int1_duration = (uint8_t)(alarm->duration / 1);
341 uint8_t ctrl_reg3 = (1 << 6);
348 uint8_t ctrl_reg6 = (1 << 1);
355 uint8_t ctrl_reg5 = (0 << 3);
366 int_cfg1 |= (alarm->z_high) ? (1 << 5) : 0;
367 int_cfg1 |= (alarm->z_low) ? (1 << 4) : 0;
369 int_cfg1 |= (alarm->y_high) ? (1 << 3) : 0;
370 int_cfg1 |= (alarm->y_low) ? (1 << 2) : 0;
372 int_cfg1 |= (alarm->x_high) ? (1 << 1) : 0;
373 int_cfg1 |= (alarm->x_low) ? (1 << 0) : 0;
385 self->_alarm_active =
false;
402 self->_resolution = resolution;
404 self->_state = TWR_LIS2DH12_STATE_INITIALIZE;
413 self->_scale = scale;
415 self->_state = TWR_LIS2DH12_STATE_INITIALIZE;
428 self->_irq_flag =
true;
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.
void twr_exti_unregister(twr_exti_line_t line)
Disable EXTI line interrupt.
twr_exti_line_t
EXTI lines.
@ TWR_EXTI_LINE_PB6
EXTI line PB6.
@ TWR_EXTI_EDGE_FALLING
EXTI line is configured to falling edge sensitivity.
void twr_i2c_init(twr_i2c_channel_t channel, twr_i2c_speed_t speed)
Initialize I2C channel.
bool twr_i2c_memory_read(twr_i2c_channel_t channel, const twr_i2c_memory_transfer_t *transfer)
Memory read from I2C channel.
bool twr_i2c_memory_write_8b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t data)
Memory write 1 byte to I2C channel.
bool twr_i2c_memory_read_8b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t *data)
Memory read 1 byte from I2C channel.
twr_i2c_channel_t
I2C channels.
@ TWR_I2C_SPEED_400_KHZ
I2C communication speed is 400 kHz.
twr_lis2dh12_resolution_t
Resolution and mode.
void twr_lis2dh12_set_event_handler(twr_lis2dh12_t *self, void(*event_handler)(twr_lis2dh12_t *, twr_lis2dh12_event_t, void *), void *event_param)
Set callback function.
bool twr_lis2dh12_measure(twr_lis2dh12_t *self)
Start measurement manually.
bool twr_lis2dh12_set_resolution(twr_lis2dh12_t *self, twr_lis2dh12_resolution_t resolution)
Set resolution.
twr_lis2dh12_event_t
Callback events.
void twr_lis2dh12_set_update_interval(twr_lis2dh12_t *self, twr_tick_t interval)
Set measurement interval.
bool twr_lis2dh12_init(twr_lis2dh12_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize LIS2DH12.
struct twr_lis2dh12_t twr_lis2dh12_t
LIS2DH12 instance.
bool twr_lis2dh12_get_result_g(twr_lis2dh12_t *self, twr_lis2dh12_result_g_t *result_g)
Get measured acceleration in g.
bool twr_lis2dh12_get_result_raw(twr_lis2dh12_t *self, twr_lis2dh12_result_raw_t *result_raw)
Get measured acceleration as raw value.
bool twr_lis2dh12_set_scale(twr_lis2dh12_t *self, twr_lis2dh12_scale_t scale)
Set scale.
bool twr_lis2dh12_set_alarm(twr_lis2dh12_t *self, twr_lis2dh12_alarm_t *alarm)
Enable or disable accelerometer threshold alarm.
@ TWR_LIS2DH12_EVENT_ALARM
Alarm event.
@ TWR_LIS2DH12_EVENT_ERROR
Error event.
@ TWR_LIS2DH12_EVENT_UPDATE
Update event.
@ TWR_LIS2DH12_SCALE_4G
±4 g.
@ TWR_LIS2DH12_SCALE_16G
±16 g.
@ TWR_LIS2DH12_SCALE_8G
±8 g.
@ TWR_LIS2DH12_SCALE_2G
±2 g (Default)
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.
#define TWR_TICK_INFINITY
Maximum timestamp value.
uint64_t twr_tick_t
Timestamp data type.
I2C memory transfer parameters.
uint32_t memory_address
8-bit I2C memory address (it can be extended to 16-bit format if OR-ed with TWR_I2C_MEMORY_ADDRESS_16...
uint8_t device_address
7-bit I2C device address
size_t length
Length of buffer which is being written or read.
void * buffer
Pointer to buffer which is being written or read.
LIS2DH12 alarm set structure.
float threshold
Alarm threshold in g.
LIS2DH12 result in raw values.