2 #include <twr_module_battery.h>
5 #include <twr_scheduler.h>
8 #define _TWR_MODULE_BATTERY_CELL_VOLTAGE 1.5f
10 #define _TWR_MODULE_BATTERY_STANDATD_DEFAULT_LEVEL_LOW (1.2 * 4)
11 #define _TWR_MODULE_BATTERY_DEFAULT_DEFAULT_LEVEL_CRITICAL (1.0 * 4)
13 #define _TWR_MODULE_BATTERY_MINI_DEFAULT_LEVEL_LOW (1.2 * 2)
14 #define _TWR_MODULE_BATTERY_MINI_DEFAULT_LEVEL_CRITICAL (1.0 * 2)
16 #define _TWR_MODULE_BATTERY_MINI_VOLTAGE_ON_BATTERY_TO_PERCENTAGE(__VOLTAGE__) ((100. * ((__VOLTAGE__) - _TWR_MODULE_BATTERY_MINI_DEFAULT_LEVEL_CRITICAL)) / ((_TWR_MODULE_BATTERY_CELL_VOLTAGE * 2) - _TWR_MODULE_BATTERY_MINI_DEFAULT_LEVEL_CRITICAL))
17 #define _TWR_MODULE_BATTERY_STANDARD_VOLTAGE_ON_BATTERY_TO_PERCENTAGE(__VOLTAGE__) ((100. * ((__VOLTAGE__) - _TWR_MODULE_BATTERY_DEFAULT_DEFAULT_LEVEL_CRITICAL)) / ((_TWR_MODULE_BATTERY_CELL_VOLTAGE * 4) - _TWR_MODULE_BATTERY_DEFAULT_DEFAULT_LEVEL_CRITICAL))
19 #define _TWR_MODULE_BATTERY_MINI_CALIBRATION(__VOLTAGE__) ((__VOLTAGE__) * 1.095f + 0.0069f)
20 #define _TWR_MODULE_BATTERY_STANDARD_CALIBRATION(__VOLTAGE__) ((__VOLTAGE__) * 1.1068f + 0.0212f)
22 #define _TWR_MODULE_BATTERY_MINI_RESULT_TO_VOLTAGE(__RESULT__) ((__RESULT__) * (1 / (5.0 / (5.0 + 10.0))))
23 #define _TWR_MODULE_BATTERY_STANDARD_RESULT_TO_VOLTAGE(__RESULT__) ((__RESULT__) * (1 / 0.13))
27 TWR_MODULE_STATE_DETECT_PRESENT = 0,
28 TWR_MODULE_STATE_DETECT_FORMAT = 1,
29 TWR_MODULE_STATE_MEASURE = 2,
30 TWR_MODULE_STATE_READ = 3,
31 TWR_MODULE_STATE_UPDATE = 4
33 } _twr_module_battery_state_t;
43 bool measurement_active;
44 float level_low_threshold;
45 float level_critical_threshold;
50 _twr_module_battery_state_t state;
52 } _twr_module_battery;
54 static bool _twr_module_battery_present_test(
void);
55 static void _twr_module_battery_task(
void *param);
57 static void _twr_module_battery_measurement(
int state);
61 memset(&_twr_module_battery, 0,
sizeof(_twr_module_battery));
63 _twr_module_battery.voltage = NAN;
64 _twr_module_battery.adc_value = NAN;
76 _twr_module_battery.event_handler = event_handler;
77 _twr_module_battery.event_param = event_param;
82 _twr_module_battery.update_interval = interval;
86 if (!_twr_module_battery.measurement_active)
99 _twr_module_battery.level_low_threshold = level_low_threshold;
100 _twr_module_battery.level_critical_threshold = level_critical_threshold;
105 return _twr_module_battery.format;
110 if ((_twr_module_battery.measurement_active) ||
111 (_twr_module_battery.state == TWR_MODULE_STATE_DETECT_FORMAT) ||
112 (_twr_module_battery.state == TWR_MODULE_STATE_READ))
117 _twr_module_battery.measurement_active =
true;
126 *voltage = _twr_module_battery.voltage;
128 return !isnan(_twr_module_battery.voltage);
140 *percentage = _TWR_MODULE_BATTERY_MINI_VOLTAGE_ON_BATTERY_TO_PERCENTAGE(voltage);
144 *percentage = _TWR_MODULE_BATTERY_STANDARD_VOLTAGE_ON_BATTERY_TO_PERCENTAGE(voltage);
147 if (*percentage > 100)
151 else if (*percentage < 0)
164 if (_twr_module_battery.state != TWR_MODULE_STATE_DETECT_PRESENT)
169 return _twr_module_battery_present_test();
172 static bool _twr_module_battery_present_test(
void)
174 twr_system_pll_enable();
192 twr_system_pll_disable();
197 static void _twr_module_battery_task(
void *param)
203 switch (_twr_module_battery.state)
206 case TWR_MODULE_STATE_DETECT_PRESENT:
214 _twr_module_battery.next_update_start =
twr_tick_get() + _twr_module_battery.update_interval;
219 if (!_twr_module_battery_present_test())
225 _twr_module_battery.measurement_active =
false;
228 if (_twr_module_battery.event_handler != NULL)
236 _twr_module_battery_measurement(ENABLE);
244 _twr_module_battery.state = TWR_MODULE_STATE_DETECT_FORMAT;
248 case TWR_MODULE_STATE_DETECT_FORMAT:
250 float voltage = _TWR_MODULE_BATTERY_STANDARD_CALIBRATION(_TWR_MODULE_BATTERY_STANDARD_RESULT_TO_VOLTAGE(_twr_module_battery.adc_value));
252 if ((voltage > 3.8) && (voltage < 7.0))
255 _twr_module_battery.level_low_threshold = _TWR_MODULE_BATTERY_STANDATD_DEFAULT_LEVEL_LOW;
256 _twr_module_battery.level_critical_threshold = _TWR_MODULE_BATTERY_DEFAULT_DEFAULT_LEVEL_CRITICAL;
257 _twr_module_battery.valid_min = 3.8;
258 _twr_module_battery.valid_max = 7.0;
263 _twr_module_battery.level_low_threshold = _TWR_MODULE_BATTERY_MINI_DEFAULT_LEVEL_LOW;
264 _twr_module_battery.level_critical_threshold = _TWR_MODULE_BATTERY_MINI_DEFAULT_LEVEL_CRITICAL;
265 _twr_module_battery.valid_min = 1.8;
266 _twr_module_battery.valid_max = 3.8;
269 _twr_module_battery.state = TWR_MODULE_STATE_MEASURE;
271 if (_twr_module_battery.measurement_active)
282 case TWR_MODULE_STATE_MEASURE:
284 _twr_module_battery.measurement_active =
true;
292 _twr_module_battery.next_update_start =
twr_tick_get() + _twr_module_battery.update_interval;
295 _twr_module_battery_measurement(ENABLE);
301 _twr_module_battery.state = TWR_MODULE_STATE_READ;
305 case TWR_MODULE_STATE_READ:
309 _twr_module_battery.voltage = _TWR_MODULE_BATTERY_MINI_CALIBRATION(_TWR_MODULE_BATTERY_MINI_RESULT_TO_VOLTAGE(_twr_module_battery.adc_value));
313 _twr_module_battery.voltage = _TWR_MODULE_BATTERY_STANDARD_CALIBRATION(_TWR_MODULE_BATTERY_STANDARD_RESULT_TO_VOLTAGE(_twr_module_battery.adc_value));
316 _twr_module_battery.measurement_active =
false;
318 if ((_twr_module_battery.voltage < _twr_module_battery.valid_min) || (_twr_module_battery.voltage > _twr_module_battery.valid_max))
320 _twr_module_battery.voltage = NAN;
322 _twr_module_battery.state = TWR_MODULE_STATE_DETECT_PRESENT;
326 if (_twr_module_battery.event_handler != NULL)
334 _twr_module_battery.state = TWR_MODULE_STATE_UPDATE;
338 case TWR_MODULE_STATE_UPDATE:
340 if (_twr_module_battery.event_handler != NULL)
343 if (_twr_module_battery.voltage <= _twr_module_battery.level_critical_threshold)
347 else if (_twr_module_battery.voltage <= _twr_module_battery.level_low_threshold)
355 _twr_module_battery.state = TWR_MODULE_STATE_MEASURE;
378 _twr_module_battery.adc_value = NAN;
381 _twr_module_battery_measurement(DISABLE);
387 static void _twr_module_battery_measurement(
int state)
bool twr_adc_async_measure(twr_adc_channel_t channel)
Begins reading the ADC channel voltage in asynchronous mode.
void twr_adc_oversampling_set(twr_adc_channel_t channel, twr_adc_oversampling_t oversampling)
Set ADC oversampling for specific channel.
bool twr_adc_set_event_handler(twr_adc_channel_t channel, void(*event_handler)(twr_adc_channel_t, twr_adc_event_t, void *), void *event_param)
Set callback function.
bool twr_adc_async_get_voltage(twr_adc_channel_t channel, float *result)
Get asynchronous measurement result in volts.
twr_adc_event_t
ADC event.
twr_adc_channel_t
ADC channel.
void twr_adc_init()
Initialize ADC converter.
@ TWR_ADC_OVERSAMPLING_256
ADC 256x oversampling.
@ TWR_ADC_EVENT_DONE
ADC event.
@ TWR_ADC_CHANNEL_A0
ADC channel A0.
void twr_gpio_set_output(twr_gpio_channel_t channel, int state)
Set output state for GPIO channel.
void twr_gpio_set_pull(twr_gpio_channel_t channel, twr_gpio_pull_t pull)
Set pull-up/pull-down configuration for GPIO channel.
void twr_gpio_init(twr_gpio_channel_t channel)
Initialize GPIO channel.
int twr_gpio_get_input(twr_gpio_channel_t channel)
Get input state for GPIO channel.
void twr_gpio_set_mode(twr_gpio_channel_t channel, twr_gpio_mode_t mode)
Set mode of operation for GPIO channel.
@ TWR_GPIO_MODE_INPUT
GPIO channel operates as input.
@ TWR_GPIO_MODE_OUTPUT
GPIO channel operates as output.
@ TWR_GPIO_MODE_ANALOG
GPIO channel operates in analog mode.
@ TWR_GPIO_P1
GPIO channel P1, A1, RXD0.
@ TWR_GPIO_P0
GPIO channel P0, A0, TXD0.
@ TWR_GPIO_PULL_DOWN
GPIO channel has pull-down.
void twr_module_battery_set_event_handler(void(*event_handler)(twr_module_battery_event_t, void *), void *event_param)
Set callback function.
void twr_module_battery_init(void)
Initialize Battery Module.
bool twr_module_battery_is_present(void)
Get Battery Module is pressent, can use without twr_module_battery_init.
twr_module_battery_format_t twr_module_battery_get_format()
Get Battery Module format.
bool twr_module_battery_get_voltage(float *voltage)
Get Battery Module voltage.
twr_module_battery_event_t
Battery Module event.
void twr_module_battery_set_update_interval(twr_tick_t interval)
Set update interval.
twr_module_battery_format_t
Battery Module format.
void twr_module_battery_set_threshold_levels(float level_low_threshold, float level_critical_threshold)
Set voltage levels.
bool twr_module_battery_get_charge_level(int *percentage)
Get Battery Module charge in percents.
bool twr_module_battery_measure(void)
Start mesurement.
@ TWR_MODULE_BATTERY_EVENT_LEVEL_LOW
Event low level.
@ TWR_MODULE_BATTERY_EVENT_ERROR
Event error.
@ TWR_MODULE_BATTERY_EVENT_UPDATE
Event update.
@ TWR_MODULE_BATTERY_EVENT_LEVEL_CRITICAL
Event critical level.
@ TWR_MODULE_BATTERY_FORMAT_UNKNOWN
Format is unknown.
@ TWR_MODULE_BATTERY_FORMAT_STANDARD
Format is standard 4xAAA.
@ TWR_MODULE_BATTERY_FORMAT_MINI
Format is mini 2xAAA.
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.
size_t twr_scheduler_task_id_t
Task ID assigned by scheduler.
void twr_scheduler_plan_now(twr_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
void twr_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
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.
void twr_timer_init(void)
Initialize timer.
void twr_timer_delay(uint16_t microseconds)
Relative delay.
void twr_timer_stop(void)
Stop timer.
void twr_timer_start(void)
Start timer.