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.

This commit is contained in:
anschrammh 2025-04-29 07:21:51 +02:00
parent f0a6562c99
commit cdc8ab151b
2 changed files with 148 additions and 17 deletions

View File

@ -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;

View File

@ -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