Added a new function to the watch peripherals API to vibrate the watch with a custom pattern

This commit is contained in:
anschrammh 2023-05-30 19:09:26 +02:00
parent 5276ce1664
commit bc37beb5c0
2 changed files with 85 additions and 3 deletions

View File

@ -21,6 +21,19 @@ static int8_t _adc_offset = 0;
/* Vibration motor timer */
static uint8_t _vibration_motor_timer_id = WM_TIMER_ID_INVALID;
static uint8_t _vibration_strength = 0;
static struct vibration_pattern_conf
{
uint16_t vibration_pattern[VIBRATION_PATTERN_SLOTS];
uint8_t vibration_pattern_index;
bool vibration_pattern_mode;
} _vibration_pattern_conf =
{
.vibration_pattern = {0}, /* Used to store the pattern itself */
.vibration_pattern_index = 0, /* Used to iterate over the array */
.vibration_pattern_mode = false, /* Value used by the timer callback to know if we are in pattern mode */
};
/* Battery charge controller status */
static battery_controller_status_e _battery_fsm = BATTERY_CONTROLLER_STATUS_DISCHARGING;
@ -50,9 +63,40 @@ struct
static void vibration_motor_timer_irq_cb(void *p)
{
(void)p;
tls_pwm_stop(VIBRATION_MOTOR_PWM_CHANNEL);
tls_gpio_cfg(VIBRATION_MOTOR_ENABLE, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(VIBRATION_MOTOR_ENABLE, 0);
if(!_vibration_pattern_conf.vibration_pattern_mode)
{
tls_pwm_stop(VIBRATION_MOTOR_PWM_CHANNEL);
tls_gpio_cfg(VIBRATION_MOTOR_ENABLE, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(VIBRATION_MOTOR_ENABLE, 0);
}
else
{
/* Depending on the index, we may turn the vibration on or off */
if(++_vibration_pattern_conf.vibration_pattern_index % 2 != 0) /* Odd indexes */
{
tls_pwm_stop(VIBRATION_MOTOR_PWM_CHANNEL);
tls_gpio_cfg(VIBRATION_MOTOR_ENABLE, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(VIBRATION_MOTOR_ENABLE, 0);
}
else if(_vibration_pattern_conf.vibration_pattern[_vibration_pattern_conf.vibration_pattern_index]) /* We turn the vibration back on */
{
wm_pwm0_config(VIBRATION_MOTOR_ENABLE);
tls_pwm_init(VIBRATION_MOTOR_PWM_CHANNEL, 10000, 0, 0);
tls_pwm_duty_set(VIBRATION_MOTOR_PWM_CHANNEL, _vibration_strength);
}
/* If we are reaching the end of the pattern array, or the current pattern has a length of 0 (meaning the end), exit the function */
if(_vibration_pattern_conf.vibration_pattern_index >= VIBRATION_PATTERN_SLOTS - 1 || !_vibration_pattern_conf.vibration_pattern[_vibration_pattern_conf.vibration_pattern_index])
{
_vibration_pattern_conf.vibration_pattern_index = 0;
return;
}
/* We rearm the timer for the next call */
tls_timer_change(_vibration_motor_timer_id, _vibration_pattern_conf.vibration_pattern[_vibration_pattern_conf.vibration_pattern_index]);
tls_timer_start(_vibration_motor_timer_id);
}
}
#if BATTERY_CONTROLLER_STATUS_DETECTION_POLICY == POLL_POLICY && HARDWARE_PLATFORM == SMART_WATCH_PCB
@ -295,6 +339,10 @@ void watch_peripherals_vibrate(uint8_t strength, uint32_t durationMs)
{
/* No need to do anything if the duration is 0 or if the strength is 0 */
if(!strength || !durationMs) return;
/* We indicate that we are not working in vibration pattern mode */
_vibration_pattern_conf.vibration_pattern_mode = false;
/* We start the timer which will stop the vibration after durationMs time */
tls_timer_change(_vibration_motor_timer_id, durationMs);
wm_pwm0_config(VIBRATION_MOTOR_ENABLE);
@ -303,6 +351,29 @@ void watch_peripherals_vibrate(uint8_t strength, uint32_t durationMs)
tls_timer_start(_vibration_motor_timer_id);
}
void watch_peripherals_vibrate_with_pattern(uint8_t strength, uint16_t pattern[VIBRATION_PATTERN_SLOTS])
{
if(!pattern || !strength) return;
if(!pattern[0]) return;
/* We indicate that we are working in vibration pattern mode */
_vibration_pattern_conf.vibration_pattern_mode = true;
/* First we copy the provided pattern in our local array */
memcpy(_vibration_pattern_conf.vibration_pattern, pattern, sizeof _vibration_pattern_conf.vibration_pattern);
/* We reset the iterator index */
_vibration_pattern_conf.vibration_pattern_index = 0;
_vibration_strength = strength;
/* We start the timer and the vibration */
tls_timer_change(_vibration_motor_timer_id, _vibration_pattern_conf.vibration_pattern[_vibration_pattern_conf.vibration_pattern_index]);
wm_pwm0_config(VIBRATION_MOTOR_ENABLE);
tls_pwm_init(VIBRATION_MOTOR_PWM_CHANNEL, 10000, 0, 0);
tls_pwm_duty_set(VIBRATION_MOTOR_PWM_CHANNEL, strength);
tls_timer_start(_vibration_motor_timer_id);
}
void watch_peripherals_set_brightness(uint8_t brightness)
{
extern LCDConfig_t LCDConfig;

View File

@ -8,6 +8,8 @@
#include "wm_type_def.h"
#include "QMC5883L.h"
#define VIBRATION_PATTERN_SLOTS (8)
typedef enum battery_unit
{
battery_unit_mv = 0,
@ -83,6 +85,15 @@ battery_controller_status_e watch_peripherals_get_battery_controller_status(void
*/
void watch_peripherals_vibrate(uint8_t strength, uint32_t durationMs);
/**
* @brief Triggers the vibration motor to vibrate with the specified pattern.
*
* @param strength the vibration strength from 0 to 255 (the same is used for every vibrations)
* @param pattern the vibration pattern : a pointer to an array of size @ref VIBRATION_PATTERN_SLOTS.
* The first duration is the on duration, the second is the off duration and so on.
*/
void watch_peripherals_vibrate_with_pattern(uint8_t strength, uint16_t pattern[VIBRATION_PATTERN_SLOTS]);
/**
* @brief Sets the brightness of the LCD display
*