From cdc8ab151b8de482bcfef623793e54877cf9a0e5 Mon Sep 17 00:00:00 2001 From: anschrammh Date: Tue, 29 Apr 2025 07:21:51 +0200 Subject: [PATCH] Added header comments in both files, added a function to check the wakeup source against the RTC alarm interrupt as well as to read the acceleremoter's axes and temperature plus other minor improvements and changes. --- .../watch_peripherals/watch_peripherals.c | 100 +++++++++++++++--- .../watch_peripherals/watch_peripherals.h | 65 +++++++++++- 2 files changed, 148 insertions(+), 17 deletions(-) diff --git a/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.c b/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.c index be4559a..9afb3c3 100644 --- a/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.c +++ b/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.c @@ -1,3 +1,14 @@ +/** + * @file watch_peripherals.c + * @author Anatole SCHRAMM-HENRY + * @brief Defines various functions to interract with some of the watch's + * peripherals like : reading the battery voltage, using the vibration motor etc. + * @version 0.1 + * @date 2025-04-29 + * + * @copyright MIT + */ + #include "watch_peripherals.h" #include "app_config.h" #include "app_log.h" @@ -13,6 +24,7 @@ #include "CST816D.h" #include "app_utils.h" #include "watch_settings.h" +#include "FreeRTOS.h" #define INTERRUPT_POLICY (0) #define POLL_POLICY (1) @@ -46,8 +58,10 @@ static battery_controller_status_e _battery_fsm = BATTERY_CONTROLLER_STATUS_DISC static BatteryControllerStatusChangeCb_t _BatteryControllerStatusChangeCb = NULL; /* Wakeup source boolean */ -static bool _wakeup_is_io = false; -static bool _wakeup_is_timer = false; +static struct +{ + bool is_io:1, is_timer:1, is_rtc_alarm:1; +} _wakeup_src = {false, false, false}; /* BMA456 structure */ static struct @@ -187,17 +201,25 @@ typedef enum wakeup_source { WAKEUP_SOURCE_IO = 0, WAKEUP_SOURCE_TIMER, + WAKEUP_SOURCE_RTC_ALARM, } wakeup_source_e; static void pmu_wakeup_source_irq_cb(void *arg) { wakeup_source_e wakeup_source = (wakeup_source_e)arg; - if(wakeup_source == WAKEUP_SOURCE_IO) - _wakeup_is_io = true; - - if(wakeup_source == WAKEUP_SOURCE_TIMER) - _wakeup_is_timer = true; + switch(wakeup_source) + { + case WAKEUP_SOURCE_IO: + _wakeup_src.is_io = true; + break; + case WAKEUP_SOURCE_TIMER: + _wakeup_src.is_timer = true; + break; + case WAKEUP_SOURCE_RTC_ALARM: + _wakeup_src.is_rtc_alarm = true; + break; + } } static void watch_peripherals_io_init(void) @@ -226,6 +248,7 @@ static void watch_peripherals_io_init(void) /* We register the IRQs needed to determine the watch wake up source/reason */ tls_pmu_gpio_isr_register(&(pmu_wakeup_source_irq_cb), (void *)WAKEUP_SOURCE_IO); tls_pmu_timer0_isr_register(&(pmu_wakeup_source_irq_cb), (void *)WAKEUP_SOURCE_TIMER); + tls_rtc_isr_register(&(pmu_wakeup_source_irq_cb), (void *)WAKEUP_SOURCE_RTC_ALARM); } #ifndef CASE_RETURN_STR @@ -464,9 +487,9 @@ void watch_peripherals_set_orientation(LCDOrientation_e orientation) bool watch_peripherals_wakeup_source_is_user(void) { - if(_wakeup_is_io) + if(_wakeup_src.is_io) { - _wakeup_is_io = false; + _wakeup_src.is_io = false; return true; } return false; @@ -474,9 +497,19 @@ bool watch_peripherals_wakeup_source_is_user(void) bool watch_peripherals_wakeup_source_is_timer(void) { - if(_wakeup_is_timer) + if(_wakeup_src.is_timer) { - _wakeup_is_timer = false; + _wakeup_src.is_timer = false; + return true; + } + return false; +} + +bool watch_peripherals_wakeup_source_is_rtc_alarm(void) +{ + if(_wakeup_src.is_rtc_alarm) + { + _wakeup_src.is_rtc_alarm = false; return true; } return false; @@ -539,9 +572,12 @@ uint16_t watch_peripherals_magnetometer_azimuth_read(bool *is_data_available) return QMC5883L_get_azimuth(MData); } -QMC5883L_MData_t watch_peripherals_magnetometer_raw_data_read(void) +watch_peripherals_axes_t watch_peripherals_magnetometer_raw_data_read(void) { - return QMC5883L_get_MFields_raw(); + QMC5883L_MData_t MData = QMC5883L_get_MFields_raw(); + + watch_peripherals_axes_t axes = {.mag.x = MData.MFieldX, .mag.y = MData.MFieldY, .mag.z = MData.MFieldZ}; + return axes; } float watch_peripherals_magnetometer_temperature_read() @@ -591,7 +627,8 @@ bool watch_peripherals_pressure_sensor_select_profile(watch_peripherals_pressure float watch_peripherals_pressure_sensor_get_pressure(float * const temperature) { BMP280_trigger_measurement(); - + /* Not great but needed to avoid an I2C wait ack err */ + tls_os_time_delay(pdMS_TO_TICKS(2)); while(BMP280_is_measuring()); return BMP280_get_pressure(temperature); @@ -786,6 +823,41 @@ bool watch_peripherals_accelerometer_step_count_reset(void) return true; } +bool watch_peripherals_accelerometer_temperature_read(float *temperature) +{ + if(!temperature) return false; + + int32_t raw_temperature; + if(bma4_get_temperature(&raw_temperature, BMA4_DEG, &_bma456.bma) != BMA4_OK) + { + APP_LOG_ERROR("Failed to read temperature"); + return false; + } + + *temperature = raw_temperature / 1000.0F; + + return true; +} + +bool watch_peripherals_accelerometer_accel_read(watch_peripherals_axes_t *axes) +{ + if(!axes) + return false; + + struct bma4_accel acceleration = { .x = -1, .y = -1, .z = -1}; + if(bma4_read_accel_xyz(&acceleration, &_bma456.bma) != BMA4_OK) + { + APP_LOG_ERROR("Failed to read the acceleration"); + return false; + } + + axes->accel.x = acceleration.x; + axes->accel.y = acceleration.y; + axes->accel.z = acceleration.z; + + return true; +} + void watch_peripherals_watch_sleep(void) { extern LCDConfig_t LCDConfig; diff --git a/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.h b/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.h index af0df7b..3dc043a 100644 --- a/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.h +++ b/src/W800_SDK_v1.00.10/app/app_drivers/watch_peripherals/watch_peripherals.h @@ -1,7 +1,14 @@ /** - * Declares various functions to interract with some of the watch's - * peripherals like : reading the battery voltage, using the vibration motor etc. + * @file watch_peripherals.h + * @author Anatole SCHRAMM-HENRY + * @brief Declares various functions to interract with some of the watch's + * peripherals like : reading the battery voltage, using the vibration motor etc. + * @version 0.1 + * @date 2025-04-29 + * + * @copyright MIT */ + #ifndef WATCH_PERIPHERALS_H #define WATCH_PERIPHERALS_H @@ -25,6 +32,23 @@ typedef enum battery_controller_status BATTERY_CONTROLLER_STATUS_ERROR } battery_controller_status_e; +typedef union watch_peripherals_axes +{ + struct + { + int16_t x; + int16_t y; + int16_t z; + } accel; + + struct + { + int16_t x; + int16_t y; + int16_t z; + } mag; +} watch_peripherals_axes_t; + typedef void (*BatteryControllerStatusChangeCb_t)(battery_controller_status_e old, battery_controller_status_e new); /** @@ -142,6 +166,7 @@ void watch_peripherals_set_orientation(LCDOrientation_e orientation); /** * @brief Check if the watch woke up because of the user(trigger on the wakeup pin : wrist tilt or touch screen). + * Calling this function clears the wakeup source flag. * * @return true if the source of the wakeup is the user * @return false otherwise @@ -150,12 +175,22 @@ bool watch_peripherals_wakeup_source_is_user(void); /** * @brief Check if the watch woke up because of a timed event (timer 0 of the PMU module). + * Calling this function clears the wakeup source flag. * * @return true if the source of the wake up is the timer 0 * @return false otherwise */ bool watch_peripherals_wakeup_source_is_timer(void); +/** + * @brief Check if the watch woke up because of a RTC alarm event. + * Calling this function clears the wakeup source flag. + * + * @return true if the source of the wake up is the RTC alarm + * @return false otherwise + */ +bool watch_peripherals_wakeup_source_is_rtc_alarm(void); + bool watch_peripherals_magnetometer_init(void); void watch_peripherals_magnetometer_calibration_data_set( @@ -166,7 +201,7 @@ void watch_peripherals_magnetometer_calibration_data_set( uint16_t watch_peripherals_magnetometer_azimuth_read(bool *is_data_available); -QMC5883L_MData_t watch_peripherals_magnetometer_raw_data_read(void); +watch_peripherals_axes_t watch_peripherals_magnetometer_raw_data_read(void); float watch_peripherals_magnetometer_temperature_read(); @@ -182,6 +217,12 @@ typedef enum watch_peripherals_pressure_sensor_profile bool watch_peripherals_pressure_sensor_select_profile(watch_peripherals_pressure_sensor_profile_e profile); +/** + * @brief Returns the measured pressure by the sensor in Pa and temperature in °C. + * + * @param temperature the address of a float which will contain the measured temperature in °C. If not needed, can be NULL. + * @return float the value of the pressure in Pa + */ float watch_peripherals_pressure_sensor_get_pressure(float * const temperature); bool watch_peripherals_accelerometer_init(void); @@ -196,6 +237,24 @@ bool watch_peripherals_accelerometer_step_count_read(uint32_t *step_count); bool watch_peripherals_accelerometer_step_count_reset(void); +/** + * @brief Reads the accelerometer's temperature in °C. + * + * @param temperature the address of a float which will contain the measured temperature in °C. + * @return true if the temperature could be retrieved + * @return false otherwise + */ +bool watch_peripherals_accelerometer_temperature_read(float *temperature); + +/** + * @brief Reads the accelerometer's acceleration on the X,Y and Z axes. + * + * @param axes the address of an union of type @ref watch_peripherals_axes_t used to store the values. + * @return true if the acceleration could be retrieved + * @return false otherwise + */ +bool watch_peripherals_accelerometer_accel_read(watch_peripherals_axes_t *axes); + void watch_peripherals_watch_sleep(void); #endif //WATCH_PERIPHERALS_H \ No newline at end of file