1 #include <twr_mpl3115a2.h>
3 #define _TWR_MPL3115A2_DELAY_RUN 1500
4 #define _TWR_MPL3115A2_DELAY_INITIALIZATION 1500
5 #define _TWR_MPL3115A2_DELAY_MEASUREMENT 1500
7 static void _twr_mpl3115a2_task_interval(
void *param);
9 static void _twr_mpl3115a2_task_measure(
void *param);
13 memset(
self, 0,
sizeof(*
self));
15 self->_i2c_channel = i2c_channel;
16 self->_i2c_address = i2c_address;
19 self->_task_id_measure =
twr_scheduler_register(_twr_mpl3115a2_task_measure,
self, _TWR_MPL3115A2_DELAY_RUN);
21 self->_tick_ready =
twr_tick_get() + _TWR_MPL3115A2_DELAY_RUN;
37 self->_event_handler = event_handler;
38 self->_event_param = event_param;
43 self->_update_interval = interval;
59 if (self->_measurement_active)
64 self->_measurement_active =
true;
73 if (!self->_altitude_valid)
78 int32_t out_pa = (uint32_t) self->_reg_out_p_msb_altitude << 24 | (uint32_t)
self->_reg_out_p_csb_altitude << 16 | (uint32_t) (self->_reg_out_p_lsb_altitude & 0xf0) << 8;
80 *meter = ((float) out_pa) / 65536.f;
87 if (!self->_pressure_valid)
92 uint32_t out_p = (uint32_t) self->_reg_out_p_msb_pressure << 16 | (uint32_t)
self->_reg_out_p_csb_pressure << 8 | (uint32_t) self->_reg_out_p_lsb_pressure;
94 *pascal = ((
float) out_p) / 64.f;
99 static void _twr_mpl3115a2_task_interval(
void *param)
108 static void _twr_mpl3115a2_task_measure(
void *param)
114 switch (self->_state)
116 case TWR_MPL3115A2_STATE_ERROR:
118 self->_altitude_valid =
false;
119 self->_pressure_valid =
false;
121 self->_measurement_active =
false;
123 if (self->_event_handler != NULL)
128 self->_state = TWR_MPL3115A2_STATE_INITIALIZE;
132 case TWR_MPL3115A2_STATE_INITIALIZE:
136 self->_state = TWR_MPL3115A2_STATE_MEASURE_ALTITUDE;
138 self->_tick_ready =
twr_tick_get() + _TWR_MPL3115A2_DELAY_INITIALIZATION;
140 if (self->_measurement_active)
147 case TWR_MPL3115A2_STATE_MEASURE_ALTITUDE:
149 self->_state = TWR_MPL3115A2_STATE_ERROR;
166 self->_state = TWR_MPL3115A2_STATE_READ_ALTITUDE;
172 case TWR_MPL3115A2_STATE_READ_ALTITUDE:
174 self->_state = TWR_MPL3115A2_STATE_ERROR;
183 if ((reg_status & 0x04) == 0)
202 self->_reg_out_p_msb_altitude = buffer[0];
203 self->_reg_out_p_csb_altitude = buffer[1];
204 self->_reg_out_p_lsb_altitude = buffer[2];
205 self->_reg_out_t_msb_altitude = buffer[3];
206 self->_reg_out_t_lsb_altitude = buffer[4];
208 self->_altitude_valid =
true;
210 self->_state = TWR_MPL3115A2_STATE_MEASURE_PRESSURE;
214 case TWR_MPL3115A2_STATE_MEASURE_PRESSURE:
216 self->_state = TWR_MPL3115A2_STATE_ERROR;
233 self->_state = TWR_MPL3115A2_STATE_READ_PRESSURE;
239 case TWR_MPL3115A2_STATE_READ_PRESSURE:
241 self->_state = TWR_MPL3115A2_STATE_ERROR;
250 if ((reg_status & 0x04) == 0)
269 self->_reg_out_p_msb_pressure = buffer[0];
270 self->_reg_out_p_csb_pressure = buffer[1];
271 self->_reg_out_p_lsb_pressure = buffer[2];
272 self->_reg_out_t_msb_pressure = buffer[3];
273 self->_reg_out_t_lsb_pressure = buffer[4];
275 self->_pressure_valid =
true;
277 self->_state = TWR_MPL3115A2_STATE_UPDATE;
281 case TWR_MPL3115A2_STATE_UPDATE:
283 self->_measurement_active =
false;
285 if (self->_event_handler != NULL)
290 self->_state = TWR_MPL3115A2_STATE_MEASURE_ALTITUDE;
296 self->_state = TWR_MPL3115A2_STATE_ERROR;
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.
void twr_mpl3115a2_init(twr_mpl3115a2_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize MPL3115A2.
bool twr_mpl3115a2_get_pressure_pascal(twr_mpl3115a2_t *self, float *pascal)
Get measured pressured in Pascal.
bool twr_mpl3115a2_measure(twr_mpl3115a2_t *self)
Start measurement manually.
void twr_mpl3115a2_set_event_handler(twr_mpl3115a2_t *self, void(*event_handler)(twr_mpl3115a2_t *, twr_mpl3115a2_event_t, void *), void *event_param)
Set callback function.
struct twr_mpl3115a2_t twr_mpl3115a2_t
MPL3115A2 instance.
twr_mpl3115a2_event_t
Callback events.
void twr_mpl3115a2_set_update_interval(twr_mpl3115a2_t *self, twr_tick_t interval)
Set measurement interval.
void twr_mpl3115a2_deinit(twr_mpl3115a2_t *self)
Deinitialize MPL3115A2.
bool twr_mpl3115a2_get_altitude_meter(twr_mpl3115a2_t *self, float *meter)
Get measured altitude in meters.
@ TWR_MPL3115A2_EVENT_ERROR
Error event.
@ TWR_MPL3115A2_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_current_absolute(twr_tick_t tick)
Schedule current task to absolute tick.
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_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
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.
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
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.