From 56f2abd6c81baff3fcf5c03cea932bf970a1a7d2 Mon Sep 17 00:00:00 2001 From: Steve Perkson Date: Fri, 20 Aug 2021 12:38:16 +0300 Subject: [PATCH 1/5] add different virbrations support --- src/components/motor/MotorController.cpp | 47 ++++++++++++++++++++++-- src/components/motor/MotorController.h | 35 ++++++++++++++++-- src/displayapp/screens/Notifications.cpp | 2 +- src/systemtask/SystemTask.cpp | 2 +- 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index b25e6bc829..cc5a4f4b55 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -8,15 +8,25 @@ APP_TIMER_DEF(longVibTimer); using namespace Pinetime::Controllers; +constexpr MotorController::Tune MotorController::tunes[]; + + MotorController::MotorController(Controllers::Settings& settingsController) : settingsController {settingsController} { } + + +uint8_t MotorController::step = 0; +MotorController::TuneType MotorController::runningTune = MotorController::TuneType::STOP; + + + void MotorController::Init() { nrf_gpio_cfg_output(pinMotor); nrf_gpio_pin_set(pinMotor); app_timer_init(); - app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, StopMotor); + app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, Vibrate); app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, Ring); } @@ -26,14 +36,27 @@ void MotorController::Ring(void* p_context) { } void MotorController::RunForDuration(uint8_t motorDuration) { + nrf_gpio_pin_set(pinMotor); if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { return; } - + step = 0; + runningTune = TuneType::STOP; nrf_gpio_pin_clear(pinMotor); app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); + } +void MotorController::VibrateTune(TuneType tune) { + nrf_gpio_pin_set(pinMotor); + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) + return; + step = 0; + runningTune = tune; + Vibrate(nullptr); +} + + void MotorController::StartRinging() { if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { return; @@ -47,6 +70,22 @@ void MotorController::StopRinging() { nrf_gpio_pin_set(pinMotor); } -void MotorController::StopMotor(void* p_context) { - nrf_gpio_pin_set(pinMotor); + +void MotorController::Vibrate(void* p_context) { + + if (step >= tunes[runningTune].length || step >= 8) { //end of tune turn off vibration + nrf_gpio_pin_set(pinMotor); + return; + } + + if (((1 << step) & tunes[runningTune].tune) > 0) { + nrf_gpio_pin_clear(pinMotor); + } else { + nrf_gpio_pin_set(pinMotor); + } + + ++step; + /* Start timer for the next cycle */ + app_timer_start(shortVibTimer, APP_TIMER_TICKS(tunes[runningTune].tempo), NULL); } + diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index d2c9fe5f2c..8d909b99f1 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -7,19 +7,48 @@ namespace Pinetime { namespace Controllers { static constexpr uint8_t pinMotor = 16; - + + class MotorController { + + public: + enum TuneType : uint8_t { + NOTIFICATION, + SHORT, + RING, + STOP + }; + MotorController(Controllers::Settings& settingsController); void Init(); void RunForDuration(uint8_t motorDuration); void StartRinging(); static void StopRinging(); + void VibrateTune(TuneType tune); private: - static void Ring(void* p_context); + + private: + struct Tune { + uint8_t tune; + uint8_t length; + uint8_t tempo; + }; Controllers::Settings& settingsController; - static void StopMotor(void* p_context); + static TuneType runningTune; + static uint8_t step; + + static constexpr Tune tunes[] = { + [TuneType::NOTIFICATION] = {.tune = 0x29, .length = 6, .tempo = 50}, + [TuneType::SHORT] = {.tune = 0x01, .length = 2, .tempo = 35}, + [TuneType::RING] = {.tune = 0x0f, .length = 8, .tempo = 50}, + [TuneType::STOP] = {.tune = 0x00, .length = 0, .tempo = 0}, + }; + + static void Vibrate(void* p_context); + static void Ring(void* p_context); + }; } } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index c061c1469d..f36586d3c6 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -40,7 +40,7 @@ Notifications::Notifications(DisplayApp* app, if (notification.category == Controllers::NotificationManager::Categories::IncomingCall) { motorController.StartRinging(); } else { - motorController.RunForDuration(35); + motorController.VibrateTune(Controllers::MotorController::TuneType::NOTIFICATION); timeoutLine = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 3553f449fd..471e2e2188 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -325,7 +325,7 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnChargingEvent: - motorController.RunForDuration(15); + motorController.VibrateTune(motorController.TuneType::SHORT); // Battery level is updated on every message - there's no need to do anything break; From d7a4007630f08949a0bea8f9941dfdd1f05698a6 Mon Sep 17 00:00:00 2001 From: Steve Perkson Date: Fri, 20 Aug 2021 13:12:11 +0300 Subject: [PATCH 2/5] using new vibrationtunes types --- src/components/motor/MotorController.cpp | 2 +- src/displayapp/screens/settings/QuickSettings.cpp | 2 +- src/systemtask/SystemTask.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index cc5a4f4b55..4635b13809 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -32,7 +32,7 @@ void MotorController::Init() { void MotorController::Ring(void* p_context) { auto* motorController = static_cast(p_context); - motorController->RunForDuration(50); + motorController->VibrateTune(TuneType::RING); } void MotorController::RunForDuration(uint8_t motorDuration) { diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 54e2f3e22e..802c98f1c3 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -143,7 +143,7 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); - motorController.RunForDuration(35); + motorController.VibrateTune(Controllers::MotorController::TuneType::NOTIFICATION); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); } else { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 471e2e2188..f2137f9c87 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -272,7 +272,7 @@ void SystemTask::Work() { if (isSleeping && !isWakingUp) { GoToRunning(); } - motorController.RunForDuration(35); + motorController.VibrateTune(Controllers::MotorController::TuneType::SHORT); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TimerDone); break; case Messages::BleConnected: From 2cd39228b6502184d06888a1d1bf97c20004ffd7 Mon Sep 17 00:00:00 2001 From: Steve Perkson Date: Fri, 20 Aug 2021 14:48:25 +0300 Subject: [PATCH 3/5] cleanups and suggestions --- src/components/motor/MotorController.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index 8d909b99f1..a28b03d587 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -14,10 +14,10 @@ namespace Pinetime { public: enum TuneType : uint8_t { + STOP, NOTIFICATION, SHORT, - RING, - STOP + RING }; MotorController(Controllers::Settings& settingsController); @@ -27,8 +27,6 @@ namespace Pinetime { static void StopRinging(); void VibrateTune(TuneType tune); - private: - private: struct Tune { uint8_t tune; @@ -40,10 +38,10 @@ namespace Pinetime { static uint8_t step; static constexpr Tune tunes[] = { - [TuneType::NOTIFICATION] = {.tune = 0x29, .length = 6, .tempo = 50}, - [TuneType::SHORT] = {.tune = 0x01, .length = 2, .tempo = 35}, - [TuneType::RING] = {.tune = 0x0f, .length = 8, .tempo = 50}, - [TuneType::STOP] = {.tune = 0x00, .length = 0, .tempo = 0}, + [TuneType::STOP] = {.tune = 0b00000000, .length = 0, .tempo = 0}, + [TuneType::NOTIFICATION] = {.tune = 0b00101001, .length = 6, .tempo = 50}, + [TuneType::SHORT] = {.tune = 0b00000001, .length = 2, .tempo = 35}, + [TuneType::RING] = {.tune = 0b00001111, .length = 8, .tempo = 50}, }; static void Vibrate(void* p_context); From fcb57fe22260d4be0b997e962c9f86f95d4dc1fd Mon Sep 17 00:00:00 2001 From: Steve Perkson Date: Fri, 20 Aug 2021 16:07:08 +0300 Subject: [PATCH 4/5] remove STOP state, Schedule next vibration timer tick is more readable, moved some variables from static scope to instance scope --- src/components/motor/MotorController.cpp | 64 +++++++++++++----------- src/components/motor/MotorController.h | 12 ++--- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 4635b13809..b66d2e1478 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -14,13 +14,6 @@ constexpr MotorController::Tune MotorController::tunes[]; MotorController::MotorController(Controllers::Settings& settingsController) : settingsController {settingsController} { } - - -uint8_t MotorController::step = 0; -MotorController::TuneType MotorController::runningTune = MotorController::TuneType::STOP; - - - void MotorController::Init() { nrf_gpio_cfg_output(pinMotor); nrf_gpio_pin_set(pinMotor); @@ -36,24 +29,41 @@ void MotorController::Ring(void* p_context) { } void MotorController::RunForDuration(uint8_t motorDuration) { - nrf_gpio_pin_set(pinMotor); if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { return; } + StopTune(); + ScheduleVibrateTimer(motorDuration, true); +} + + +void MotorController::StopTune() { + step = 255; +} + +void MotorController::ScheduleTune(TuneType tune) { step = 0; - runningTune = TuneType::STOP; - nrf_gpio_pin_clear(pinMotor); - app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); + runningTune = tune; +} +/** +* schedule next vibrate timer tick with or without vibration +*/ + +void MotorController::ScheduleVibrateTimer(uint8_t motorDuration, bool vibrate) { + if (vibrate) { + nrf_gpio_pin_clear(pinMotor); + } else { + nrf_gpio_pin_clear(pinMotor); + } + app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), this); } void MotorController::VibrateTune(TuneType tune) { - nrf_gpio_pin_set(pinMotor); if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) return; - step = 0; - runningTune = tune; - Vibrate(nullptr); + ScheduleTune(tune); + Vibrate(this); } @@ -72,20 +82,16 @@ void MotorController::StopRinging() { void MotorController::Vibrate(void* p_context) { + auto* motorC = static_cast(p_context); + auto* runningTune = &tunes[motorC->runningTune]; - if (step >= tunes[runningTune].length || step >= 8) { //end of tune turn off vibration - nrf_gpio_pin_set(pinMotor); - return; - } - - if (((1 << step) & tunes[runningTune].tune) > 0) { - nrf_gpio_pin_clear(pinMotor); - } else { - nrf_gpio_pin_set(pinMotor); - } + nrf_gpio_pin_set(pinMotor); //turn off vibration - ++step; - /* Start timer for the next cycle */ - app_timer_start(shortVibTimer, APP_TIMER_TICKS(tunes[runningTune].tempo), NULL); -} + //scedule next tune tick + if (motorC->step < 8 && motorC->step < runningTune->length) { + bool vibrate = ((1 << motorC->step) & runningTune->tune) > 0; + motorC->step++; + motorC->ScheduleVibrateTimer(runningTune->tempo, vibrate); + } +} diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index a28b03d587..3d3dba0916 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -14,7 +14,6 @@ namespace Pinetime { public: enum TuneType : uint8_t { - STOP, NOTIFICATION, SHORT, RING @@ -34,19 +33,20 @@ namespace Pinetime { uint8_t tempo; }; Controllers::Settings& settingsController; - static TuneType runningTune; - static uint8_t step; + TuneType runningTune = TuneType::SHORT; + uint8_t step = 255; static constexpr Tune tunes[] = { - [TuneType::STOP] = {.tune = 0b00000000, .length = 0, .tempo = 0}, [TuneType::NOTIFICATION] = {.tune = 0b00101001, .length = 6, .tempo = 50}, [TuneType::SHORT] = {.tune = 0b00000001, .length = 2, .tempo = 35}, [TuneType::RING] = {.tune = 0b00001111, .length = 8, .tempo = 50}, }; - + static void Vibrate(void* p_context); static void Ring(void* p_context); - + void ScheduleVibrateTimer(uint8_t motorDuration, bool vibrate); + void StopTune(); + void ScheduleTune(TuneType tune); }; } } From 3247001b3d509a250daba2e1c059fd0239ceb32d Mon Sep 17 00:00:00 2001 From: Steve Perkson Date: Fri, 20 Aug 2021 16:18:47 +0300 Subject: [PATCH 5/5] vibrate silence bug --- src/components/motor/MotorController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index b66d2e1478..40c9b642bc 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -54,7 +54,7 @@ void MotorController::ScheduleVibrateTimer(uint8_t motorDuration, bool vibrate) if (vibrate) { nrf_gpio_pin_clear(pinMotor); } else { - nrf_gpio_pin_clear(pinMotor); + nrf_gpio_pin_set(pinMotor); } app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), this); }