Big refactoring and cleanup by removing sensors initialization code from the gfx_task.c file and moving it to the watch_peripherals.c source file. This is way more logical IMO. This change also allows to enable or disable the wrist tilt wakeup with a function call
This commit is contained in:
parent
b8a11a8a79
commit
92d3279eb9
@ -5,6 +5,10 @@
|
||||
#include "wm_adc.h"
|
||||
#include "wm_timer.h"
|
||||
#include "wm_pwm.h"
|
||||
#include "i2c.h"
|
||||
#include "BMP280.h"
|
||||
#include "FreeRTOS.h" // <---- Only needed for the pdMS_TO_TICKS macro, to be removed
|
||||
#include "bma456w.h"
|
||||
|
||||
#define INTERRUPT_POLICY (0)
|
||||
#define POLL_POLICY (1)
|
||||
@ -21,6 +25,23 @@ static uint8_t _vibration_motor_timer_id = WM_TIMER_ID_INVALID;
|
||||
static battery_controller_status_e _battery_fsm = BATTERY_CONTROLLER_STATUS_DISCHARGING;
|
||||
static BatteryControllerStatusChangeCb_t _BatteryControllerStatusChangeCb = NULL;
|
||||
|
||||
/* BMA456 strcture */
|
||||
struct
|
||||
{
|
||||
uint8_t dev_addr;
|
||||
struct bma4_dev bma;
|
||||
struct bma4_accel_config accel_conf;
|
||||
struct bma456w_wrist_wear_wakeup_params setting;
|
||||
struct bma4_int_pin_config pin_config;
|
||||
bool wrist_wakeup_enable;
|
||||
bool step_counter_enable;
|
||||
} _bma456 =
|
||||
{
|
||||
.dev_addr = BMA4_I2C_ADDR_SECONDARY,
|
||||
.wrist_wakeup_enable = false,
|
||||
};
|
||||
|
||||
|
||||
static void vibration_motor_timer_irq_cb(void *p)
|
||||
{
|
||||
(void)p;
|
||||
@ -29,7 +50,7 @@ static void vibration_motor_timer_irq_cb(void *p)
|
||||
tls_gpio_write(VIBRATION_MOTOR_ENABLE, 0);
|
||||
}
|
||||
|
||||
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == POLL_POLICY
|
||||
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == POLL_POLICY && HARDWARE_PLATFORM == SMART_WATCH_PCB
|
||||
static uint8_t _battery_status_timer_id = WM_TIMER_ID_INVALID;
|
||||
|
||||
static void battery_status_timer_irq_cb(void *p)
|
||||
@ -58,7 +79,7 @@ static void battery_status_timer_irq_cb(void *p)
|
||||
if(_BatteryControllerStatusChangeCb) _BatteryControllerStatusChangeCb(old_battery_status, _battery_fsm);
|
||||
}
|
||||
}
|
||||
#elif BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == INTERRUPT_POLICY
|
||||
#elif BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == INTERRUPT_POLICY && HARDWARE_PLATFORM == SMART_WATCH_PCB
|
||||
static void battery_controller_irq_cb(void *p)
|
||||
{
|
||||
enum tls_io_name gpio_pin = (enum tls_io_name)p;
|
||||
@ -122,7 +143,7 @@ static void watch_peripherals_io_init(void)
|
||||
tls_gpio_cfg(BATTERY_CONTROLLER_CHARGED_STATUS, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
|
||||
tls_gpio_cfg(BATTERY_CONTROLLER_CHARGING_STATUS, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
|
||||
|
||||
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == INTERRUPT_POLICY
|
||||
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == INTERRUPT_POLICY && HARDWARE_PLATFORM == SMART_WATCH_PCB
|
||||
tls_gpio_isr_register(BATTERY_CONTROLLER_CHARGED_STATUS, &(battery_controller_irq_cb), (int*) BATTERY_CONTROLLER_CHARGED_STATUS);
|
||||
tls_gpio_irq_enable(BATTERY_CONTROLLER_CHARGED_STATUS, WM_GPIO_IRQ_TRIG_DOUBLE_EDGE); // Enabled when level is changing edge
|
||||
|
||||
@ -171,7 +192,7 @@ void watch_peripherals_init(int8_t adcOffset)
|
||||
if(WM_TIMER_ID_INVALID == _vibration_motor_timer_id)
|
||||
APP_LOG_ERROR("Failed to create vibration motor timer");
|
||||
}
|
||||
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == POLL_POLICY
|
||||
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == POLL_POLICY && HARDWARE_PLATFORM == SMART_WATCH_PCB
|
||||
if(WM_TIMER_ID_INVALID == _battery_status_timer_id)
|
||||
{
|
||||
struct tls_timer_cfg battery_status_timer_cfg =
|
||||
@ -190,6 +211,9 @@ void watch_peripherals_init(int8_t adcOffset)
|
||||
tls_timer_start(_battery_status_timer_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Let's init the I2C interface */
|
||||
i2c_init(I2C_SDA, I2C_SCL, I2C_CLOCK_SPEED);
|
||||
}
|
||||
|
||||
void watch_peripherals_register_battery_controller_status_change_cb(BatteryControllerStatusChangeCb_t BatteryControllerStatusChangeCb)
|
||||
@ -264,3 +288,309 @@ void watch_peripherals_set_orientation(LCDOrientation_e orientation)
|
||||
extern LCDConfig_t LCDConfig;
|
||||
lcd_orientation(&LCDConfig, orientation);
|
||||
}
|
||||
|
||||
bool watch_peripherals_magnetometer_init(void)
|
||||
{
|
||||
/* Init the magnetometer */
|
||||
if(!QMC5883L_init())
|
||||
{
|
||||
APP_LOG_ERROR("Failed to init QMC5883L");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
APP_LOG_INFO("Inited QMC5883L");
|
||||
|
||||
/* Needed but UGLY */
|
||||
tls_os_time_delay(2);
|
||||
|
||||
if(!QMC5883L_set_power_mode(QMC5883L_Mode_Control_Continuous))
|
||||
{
|
||||
APP_LOG_ERROR("Failed to set QMC5883L mode");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
APP_LOG_INFO("QMC5883L Mode set");
|
||||
|
||||
/* Needed but UGLY */
|
||||
tls_os_time_delay(2);
|
||||
|
||||
if(!QMC5883L_configure_1(ODR_10HZ, FS_2G, OSR_512))
|
||||
{
|
||||
APP_LOG_ERROR("Failed to configure 1 QMC5883L");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
APP_LOG_INFO("QMC5883L configured");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void watch_peripherals_magnetometer_calibration_data_set(
|
||||
int16_t x_min, int16_t x_max,
|
||||
int16_t y_min, int16_t y_max,
|
||||
int16_t z_min, int16_t z_max, float temperature_offset
|
||||
)
|
||||
{
|
||||
QMC5883L_set_calibration_data(x_min, x_max, y_min, y_max, z_min, z_max, temperature_offset);
|
||||
}
|
||||
|
||||
uint16_t watch_peripherals_magnetometer_azimuth_read(bool *is_data_available)
|
||||
{
|
||||
bool data_ready = QMC5883L_is_data_available();
|
||||
|
||||
if(is_data_available) *is_data_available = data_ready;
|
||||
|
||||
if(!data_ready) return 0;
|
||||
|
||||
QMC5883L_MData_calibrated_t MData = QMC5883L_get_MFields_calibrated();
|
||||
return QMC5883L_get_azimuth(MData);
|
||||
}
|
||||
|
||||
QMC5883L_MData_t watch_peripherals_magnetometer_raw_data_read(void)
|
||||
{
|
||||
return QMC5883L_get_MFields_raw();
|
||||
}
|
||||
|
||||
bool watch_peripherals_magnetometer_power_mode_set(QMC5883L_Mode_Control_e mode_control)
|
||||
{
|
||||
return QMC5883L_set_power_mode(mode_control);
|
||||
}
|
||||
|
||||
bool watch_peripherals_pressure_sensor_init(void)
|
||||
{
|
||||
/* Init the BMP280 */
|
||||
if(!BMP280_init())
|
||||
{
|
||||
APP_LOG_ERROR("Failed to init BMP280");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
APP_LOG_INFO("Inited BMP280");
|
||||
|
||||
if(!BMP280_configure(BMP280_Forced, BMP280_Oversampling_x16, BMP280_Oversampling_x16, BMP280_Filter_x16, BMP280_Standby_4000MS))
|
||||
{
|
||||
APP_LOG_ERROR("Failed to configure BMP280");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
APP_LOG_INFO("BMP280 configured");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float watch_peripherals_pressure_sensor_get_pressure(float * const temperature)
|
||||
{
|
||||
BMP280_trigger_measurement();
|
||||
|
||||
while(BMP280_is_measuring());
|
||||
|
||||
return BMP280_get_pressure(temperature);
|
||||
}
|
||||
|
||||
static BMA4_INTF_RET_TYPE _bma4_i2c_read(uint8_t reg_addr, uint8_t *read_data, uint32_t len, void *intf_ptr)
|
||||
{
|
||||
uint8_t dev_address = *(uint8_t*)intf_ptr;
|
||||
|
||||
return !i2c_read(dev_address, reg_addr, read_data, len);
|
||||
}
|
||||
|
||||
static BMA4_INTF_RET_TYPE _bma4_i2c_write(uint8_t reg_addr, const uint8_t *read_data, uint32_t len, void *intf_ptr)
|
||||
{
|
||||
uint8_t dev_address = *(uint8_t*)intf_ptr;
|
||||
|
||||
return !i2c_write(dev_address, reg_addr, read_data, len);
|
||||
}
|
||||
|
||||
// TODO: Rework the delay_us function to rather use a timer and have real µs resolution and not ms ...
|
||||
static void _bma4_delay_us(uint32_t period, void *intf_ptr)
|
||||
{
|
||||
(void) intf_ptr;
|
||||
|
||||
if(period < 1000)
|
||||
tls_os_time_delay(1);
|
||||
else
|
||||
tls_os_time_delay(pdMS_TO_TICKS(period / 1000));
|
||||
}
|
||||
|
||||
bool watch_peripherals_accelerometer_init(void)
|
||||
{
|
||||
/* Init the BMA456 */
|
||||
_bma456.bma.intf = BMA4_I2C_INTF;
|
||||
_bma456.bma.intf_ptr = &_bma456.dev_addr;
|
||||
_bma456.bma.bus_read = &(_bma4_i2c_read);
|
||||
_bma456.bma.bus_write = &(_bma4_i2c_write);
|
||||
_bma456.bma.variant = BMA45X_VARIANT;
|
||||
_bma456.bma.delay_us = &(_bma4_delay_us);
|
||||
_bma456.bma.read_write_len = 46;
|
||||
_bma456.bma.perf_mode_status = BMA4_DISABLE;
|
||||
|
||||
if(bma456w_init(&_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 init");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("Failed to init BMA456");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bma4_soft_reset(&_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 soft reset");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("Failed to soft reset BMA456");
|
||||
return false;
|
||||
}
|
||||
tls_os_time_delay(2);
|
||||
|
||||
if(bma456w_write_config_file(&_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 config ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 config failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
_bma456.accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
|
||||
_bma456.accel_conf.range = BMA4_ACCEL_RANGE_2G;
|
||||
_bma456.accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
|
||||
_bma456.accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
|
||||
|
||||
if(bma4_set_accel_config(&_bma456.accel_conf, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 accel conf ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 accel conf failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bma4_set_accel_enable(1, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 accel en ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 accel en failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool watch_peripherals_accelerometer_wrist_wakeup_enable(bool enable)
|
||||
{
|
||||
if(_bma456.wrist_wakeup_enable == enable) return true;
|
||||
|
||||
_bma456.wrist_wakeup_enable = enable;
|
||||
|
||||
if(bma456w_feature_enable(BMA456W_WRIST_WEAR_WAKEUP, enable, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 feature enable ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 feature enable failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bma456w_get_wrist_wear_wakeup_param_config(&_bma456.setting, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 get wrist param ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 get wrist param failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
APP_LOG_DEBUG("%d %d %d %d %d %d %d %d",
|
||||
_bma456.setting.min_angle_focus,
|
||||
_bma456.setting.min_angle_non_focus,
|
||||
_bma456.setting.angle_landscape_right,
|
||||
_bma456.setting.angle_landscape_left,
|
||||
_bma456.setting.angle_portrait_up,
|
||||
_bma456.setting.angle_portrait_down,
|
||||
_bma456.setting.min_dur_moved,
|
||||
_bma456.setting.min_dur_quite);
|
||||
|
||||
if(bma4_get_int_pin_config(&_bma456.pin_config, BMA4_INTR1_MAP, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 get pin conf ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 get pin conf failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bma456w_map_interrupt(BMA4_INTR1_MAP, BMA456W_WRIST_WEAR_WAKEUP_INT, enable, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 map int ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 map int failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
_bma456.pin_config.edge_ctrl = BMA4_EDGE_TRIGGER;
|
||||
_bma456.pin_config.output_en = BMA4_OUTPUT_ENABLE;
|
||||
_bma456.pin_config.lvl = BMA4_ACTIVE_LOW;
|
||||
_bma456.pin_config.od = BMA4_PUSH_PULL;
|
||||
_bma456.pin_config.input_en = BMA4_INPUT_DISABLE;
|
||||
|
||||
if(bma4_set_int_pin_config(&_bma456.pin_config, BMA4_INTR1_MAP, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 set pin conf ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 set pin conf failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool watch_peripherals_accelerometer_wrist_wakeup_interrupt(void)
|
||||
{
|
||||
uint16_t bma456_int_status;
|
||||
uint8_t rslt = bma456w_read_int_status(&bma456_int_status, &_bma456.bma);
|
||||
if(rslt != BMA4_OK)
|
||||
{
|
||||
APP_LOG_ERROR("Failed to read int status");
|
||||
return false;
|
||||
}
|
||||
|
||||
if((BMA4_OK == rslt) && (bma456_int_status & BMA456W_WRIST_WEAR_WAKEUP_INT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool watch_peripherals_accelerometer_step_counter_enable(bool enable)
|
||||
{
|
||||
if(_bma456.step_counter_enable == enable) return true;
|
||||
|
||||
_bma456.step_counter_enable = enable;
|
||||
|
||||
if(bma456w_feature_enable(BMA456W_STEP_CNTR, BMA4_ENABLE, &_bma456.bma) == BMA4_OK)
|
||||
APP_LOG_INFO("BMA456 step cnter feature enable ok");
|
||||
else
|
||||
{
|
||||
APP_LOG_ERROR("BMA456 step cnter feature enable failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool watch_peripherals_accelerometer_step_count_read(uint32_t *step_count)
|
||||
{
|
||||
if(!step_count) return false;
|
||||
|
||||
if(bma456w_step_counter_output(step_count, &_bma456.bma) != BMA4_OK)
|
||||
{
|
||||
APP_LOG_ERROR("Failed to read step counts");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool watch_peripherals_accelerometer_step_count_reset(void)
|
||||
{
|
||||
if(bma456w_reset_step_counter(&_bma456.bma) != BMA4_OK)
|
||||
{
|
||||
APP_LOG_ERROR("Failed to reset step counts");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define WATCH_PERIPHERALS_H
|
||||
#include "lcd.h"
|
||||
#include "wm_type_def.h"
|
||||
#include "QMC5883L.h"
|
||||
|
||||
typedef enum battery_unit
|
||||
{
|
||||
@ -32,8 +33,8 @@ typedef void (*BatteryControllerStatusChangeCb_t)(battery_controller_status_e ol
|
||||
const char *battery_controller_status_2_str(battery_controller_status_e status);
|
||||
|
||||
/**
|
||||
* @brief Inits the watch peripherals driver.
|
||||
* This must be called before using the API.
|
||||
* @brief Inits the watch peripherals drivers and sets battery sensing ADC offset.
|
||||
* This must be called before using the watch peripherals API.
|
||||
*
|
||||
* @param adcOffset an offset in mV to apply to the battery voltage reading.
|
||||
*/
|
||||
@ -100,4 +101,34 @@ void watch_peripherals_set_brightness(uint8_t brightness);
|
||||
*/
|
||||
void watch_peripherals_set_orientation(LCDOrientation_e orientation);
|
||||
|
||||
bool watch_peripherals_magnetometer_init(void);
|
||||
|
||||
void watch_peripherals_magnetometer_calibration_data_set(
|
||||
int16_t x_min, int16_t x_max,
|
||||
int16_t y_min, int16_t y_max,
|
||||
int16_t z_min, int16_t z_max, float temperature_offset
|
||||
);
|
||||
|
||||
uint16_t watch_peripherals_magnetometer_azimuth_read(bool *is_data_available);
|
||||
|
||||
QMC5883L_MData_t watch_peripherals_magnetometer_raw_data_read(void);
|
||||
|
||||
bool watch_peripherals_magnetometer_power_mode_set(QMC5883L_Mode_Control_e mode_control);
|
||||
|
||||
bool watch_peripherals_pressure_sensor_init(void);
|
||||
|
||||
float watch_peripherals_pressure_sensor_get_pressure(float * const temperature);
|
||||
|
||||
bool watch_peripherals_accelerometer_init(void);
|
||||
|
||||
bool watch_peripherals_accelerometer_wrist_wakeup_enable(bool enable);
|
||||
|
||||
bool watch_peripherals_accelerometer_wrist_wakeup_interrupt(void);
|
||||
|
||||
bool watch_peripherals_accelerometer_step_counter_enable(bool enable);
|
||||
|
||||
bool watch_peripherals_accelerometer_step_count_read(uint32_t *step_count);
|
||||
|
||||
bool watch_peripherals_accelerometer_step_count_reset(void);
|
||||
|
||||
#endif //WATCH_PERIPHERALS_H
|
Loading…
Reference in New Issue
Block a user