implemented continuous vibration pattern for incoming calls

This commit is contained in:
Florian Kraupa 2021-05-12 20:23:04 +02:00
parent d7fa000b85
commit d13dd6dee3
7 changed files with 78 additions and 24 deletions

View file

@ -3,7 +3,8 @@
#include "systemtask/SystemTask.h" #include "systemtask/SystemTask.h"
#include "app_timer.h" #include "app_timer.h"
APP_TIMER_DEF(vibTimer); APP_TIMER_DEF(shortVibTimer);
APP_TIMER_DEF(longVibTimer);
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
@ -14,19 +15,42 @@ void MotorController::Init() {
nrf_gpio_cfg_output(pinMotor); nrf_gpio_cfg_output(pinMotor);
nrf_gpio_pin_set(pinMotor); nrf_gpio_pin_set(pinMotor);
app_timer_init(); app_timer_init();
app_timer_create(&vibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate);
app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate);
app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, vibrate);
isBusy = false;
} }
void MotorController::SetDuration(uint8_t motorDuration) { void MotorController::RunForDuration(uint8_t motorDuration) {
if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy)
return; return;
nrf_gpio_pin_clear(pinMotor); nrf_gpio_pin_clear(pinMotor);
/* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/
app_timer_start(vibTimer, APP_TIMER_TICKS(motorDuration), NULL); app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), NULL);
}
void MotorController::startRunning(uint8_t motorDuration) {
if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy )
return;
//prevent other vibrations while running
isBusy = true;
nrf_gpio_pin_clear(pinMotor);
app_timer_start(longVibTimer, APP_TIMER_TICKS(motorDuration), NULL);
}
void MotorController::stopRunning() {
app_timer_stop(longVibTimer);
nrf_gpio_pin_set(pinMotor);
isBusy = false;
} }
void MotorController::vibrate(void* p_context) { void MotorController::vibrate(void* p_context) {
if (nrf_gpio_pin_out_read(pinMotor) == 0) {
nrf_gpio_pin_set(pinMotor); nrf_gpio_pin_set(pinMotor);
} else {
nrf_gpio_pin_clear(pinMotor);
}
} }

View file

@ -12,11 +12,14 @@ namespace Pinetime {
public: public:
MotorController(Controllers::Settings& settingsController); MotorController(Controllers::Settings& settingsController);
void Init(); void Init();
void SetDuration(uint8_t motorDuration); void RunForDuration(uint8_t motorDuration);
void startRunning(uint8_t motorDuration);
void stopRunning();
private: private:
Controllers::Settings& settingsController; Controllers::Settings& settingsController;
static void vibrate(void* p_context); static void vibrate(void* p_context);
bool isBusy;
}; };
} }
} }

View file

@ -256,12 +256,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
case Apps::Notifications: case Apps::Notifications:
currentScreen = std::make_unique<Screens::Notifications>( currentScreen = std::make_unique<Screens::Notifications>(
this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal); this, notificationManager, systemTask.nimble().alertService(), motorController, Screens::Notifications::Modes::Normal);
ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
break; break;
case Apps::NotificationsPreview: case Apps::NotificationsPreview:
currentScreen = std::make_unique<Screens::Notifications>( currentScreen = std::make_unique<Screens::Notifications>(
this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview); this, notificationManager, systemTask.nimble().alertService(), motorController, Screens::Notifications::Modes::Preview);
ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
break; break;

View file

@ -11,8 +11,13 @@ extern lv_font_t jetbrains_mono_bold_20;
Notifications::Notifications(DisplayApp* app, Notifications::Notifications(DisplayApp* app,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::AlertNotificationService& alertNotificationService,
Controllers::MotorController& motorController,
Modes mode) Modes mode)
: Screen(app), notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, mode {mode} { : Screen(app),
notificationManager {notificationManager},
alertNotificationService {alertNotificationService},
motorController{motorController},
mode {mode} {
notificationManager.ClearNewNotificationFlag(); notificationManager.ClearNewNotificationFlag();
auto notification = notificationManager.GetLastNotification(); auto notification = notificationManager.GetLastNotification();
if (notification.valid) { if (notification.valid) {
@ -23,7 +28,8 @@ Notifications::Notifications(DisplayApp* app,
notification.category, notification.category,
notificationManager.NbNotifications(), notificationManager.NbNotifications(),
mode, mode,
alertNotificationService); alertNotificationService,
motorController);
validDisplay = true; validDisplay = true;
} else { } else {
currentItem = std::make_unique<NotificationItem>("Notification", currentItem = std::make_unique<NotificationItem>("Notification",
@ -32,11 +38,14 @@ Notifications::Notifications(DisplayApp* app,
notification.category, notification.category,
notificationManager.NbNotifications(), notificationManager.NbNotifications(),
Modes::Preview, Modes::Preview,
alertNotificationService); alertNotificationService,
motorController);
} }
if (mode == Modes::Preview) { if (mode == Modes::Preview) {
timeoutLine = lv_line_create(lv_scr_act(), nullptr); timeoutLine = lv_line_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
@ -63,7 +72,10 @@ bool Notifications::Refresh() {
timeoutLinePoints[1].x = pos; timeoutLinePoints[1].x = pos;
lv_line_set_points(timeoutLine, timeoutLinePoints, 2); lv_line_set_points(timeoutLine, timeoutLinePoints, 2);
} }
//make sure we stop any vibrations before exiting
if (!running) {
motorController.stopRunning();
}
return running; return running;
} }
@ -92,7 +104,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
previousNotification.category, previousNotification.category,
notificationManager.NbNotifications(), notificationManager.NbNotifications(),
mode, mode,
alertNotificationService); alertNotificationService,
motorController);
} }
return true; return true;
case Pinetime::Applications::TouchEvents::SwipeUp: { case Pinetime::Applications::TouchEvents::SwipeUp: {
@ -117,7 +130,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
nextNotification.category, nextNotification.category,
notificationManager.NbNotifications(), notificationManager.NbNotifications(),
mode, mode,
alertNotificationService); alertNotificationService,
motorController);
} }
return true; return true;
case Pinetime::Applications::TouchEvents::LongTap: { case Pinetime::Applications::TouchEvents::LongTap: {
@ -152,8 +166,9 @@ Notifications::NotificationItem::NotificationItem(const char* title,
Controllers::NotificationManager::Categories category, Controllers::NotificationManager::Categories category,
uint8_t notifNb, uint8_t notifNb,
Modes mode, Modes mode,
Pinetime::Controllers::AlertNotificationService& alertNotificationService) Pinetime::Controllers::AlertNotificationService& alertNotificationService,
: notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { Controllers::MotorController& motorController)
: notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService}, motorController{motorController} {
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL);
@ -236,9 +251,11 @@ Notifications::NotificationItem::NotificationItem(const char* title,
label_mute = lv_label_create(bt_mute, nullptr); label_mute = lv_label_create(bt_mute, nullptr);
lv_label_set_text(label_mute, Symbols::volumMute); lv_label_set_text(label_mute, Symbols::volumMute);
lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
} break; } break;
} }
lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr); lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_size(backgroundLabel, 240, 240);
@ -249,21 +266,21 @@ Notifications::NotificationItem::NotificationItem(const char* title,
void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) { void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) {
if (event != LV_EVENT_CLICKED) if (event != LV_EVENT_CLICKED)
return; return;
motorController.stopRunning();
alertNotificationService.AcceptIncomingCall(); alertNotificationService.AcceptIncomingCall();
} }
void Notifications::NotificationItem::OnMuteIncomingCall(lv_event_t event) { void Notifications::NotificationItem::OnMuteIncomingCall(lv_event_t event) {
if (event != LV_EVENT_CLICKED) if (event != LV_EVENT_CLICKED)
return; return;
motorController.stopRunning();
alertNotificationService.MuteIncomingCall(); alertNotificationService.MuteIncomingCall();
} }
void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) {
if (event != LV_EVENT_CLICKED) if (event != LV_EVENT_CLICKED)
return; return;
motorController.stopRunning();
alertNotificationService.RejectIncomingCall(); alertNotificationService.RejectIncomingCall();
} }

View file

@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include "Screen.h" #include "Screen.h"
#include "components/ble/NotificationManager.h" #include "components/ble/NotificationManager.h"
#include "components/motor/MotorController.h"
namespace Pinetime { namespace Pinetime {
namespace Controllers { namespace Controllers {
@ -19,6 +20,7 @@ namespace Pinetime {
explicit Notifications(DisplayApp* app, explicit Notifications(DisplayApp* app,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::AlertNotificationService& alertNotificationService,
Controllers::MotorController& motorController,
Modes mode); Modes mode);
~Notifications() override; ~Notifications() override;
@ -33,7 +35,8 @@ namespace Pinetime {
Controllers::NotificationManager::Categories, Controllers::NotificationManager::Categories,
uint8_t notifNb, uint8_t notifNb,
Modes mode, Modes mode,
Pinetime::Controllers::AlertNotificationService& alertNotificationService); Pinetime::Controllers::AlertNotificationService& alertNotificationService,
Controllers::MotorController& motorController);
~NotificationItem(); ~NotificationItem();
bool Refresh() { bool Refresh() {
return false; return false;
@ -60,6 +63,7 @@ namespace Pinetime {
lv_obj_t* bottomPlaceholder; lv_obj_t* bottomPlaceholder;
Modes mode; Modes mode;
Pinetime::Controllers::AlertNotificationService& alertNotificationService; Pinetime::Controllers::AlertNotificationService& alertNotificationService;
Controllers::MotorController& motorController;
}; };
private: private:
@ -72,6 +76,8 @@ namespace Pinetime {
Modes mode = Modes::Normal; Modes mode = Modes::Normal;
std::unique_ptr<NotificationItem> currentItem; std::unique_ptr<NotificationItem> currentItem;
Controllers::NotificationManager::Notification::Id currentId; Controllers::NotificationManager::Notification::Id currentId;
Controllers::MotorController& motorController;
bool validDisplay = false; bool validDisplay = false;
lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}}; lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}};

View file

@ -140,7 +140,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) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) {
settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON);
motorController.SetDuration(35); motorController.RunForDuration(35);
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn);
} else { } else {
settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF);

View file

@ -225,7 +225,11 @@ void SystemTask::Work() {
case Messages::OnNewNotification: case Messages::OnNewNotification:
if (isSleeping && !isWakingUp) if (isSleeping && !isWakingUp)
GoToRunning(); GoToRunning();
motorController.SetDuration(35); if (notificationManager.GetLastNotification().category == Controllers::NotificationManager::Categories::IncomingCall) {
motorController.startRunning(50);
} else {
motorController.RunForDuration(35);
}
displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification); displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification);
break; break;
case Messages::BleConnected: case Messages::BleConnected: