diff --git a/docker/Dockerfile b/docker/Dockerfile index 7f0fb4b0..894e534b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -21,6 +21,7 @@ RUN apt-get update -qq \ && rm -rf /var/cache/apt/* /var/lib/apt/lists/*; RUN pip3 install adafruit-nrfutil +RUN pip3 install -Iv cryptography==3.3 # build.sh knows how to compile COPY build.sh /opt/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 863d3179..78f7cebb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,10 +36,12 @@ set(SDK_SOURCE_FILES # Base SDK "${NRF5_SDK_PATH}/components/boards/boards.c" "${NRF5_SDK_PATH}/integration/nrfx/legacy/nrf_drv_clock.c" + "${NRF5_SDK_PATH}/integration/nrfx/legacy/nrf_drv_clock.h" "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_clock.c" "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_gpiote.c" "${NRF5_SDK_PATH}/modules/nrfx/soc/nrfx_atomic.c" "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_saadc.c" + "${NRF5_SDK_PATH}/components/libraries/timer/app_timer.h" # FreeRTOS ${NRF5_SDK_PATH}/external/freertos/source/croutine.c @@ -468,6 +470,7 @@ list(APPEND SOURCE_FILES components/ble/ServiceDiscovery.cpp components/ble/HeartRateService.cpp components/firmwarevalidator/FirmwareValidator.cpp + components/motor/MotorController.cpp drivers/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c @@ -577,6 +580,7 @@ set(INCLUDE_FILES components/heartrate/Biquad.h components/heartrate/Ptagc.h components/heartrate/HeartRateController.h + components/motor/MotorController.h ) include_directories( diff --git a/src/components/ble/NotificationManager.cpp b/src/components/ble/NotificationManager.cpp index dabcb4ba..36abf026 100644 --- a/src/components/ble/NotificationManager.cpp +++ b/src/components/ble/NotificationManager.cpp @@ -71,6 +71,14 @@ bool NotificationManager::AreNewNotificationsAvailable() { return newNotification; } +bool NotificationManager::IsVibrationEnabled() { + return vibrationEnabled; +} + +void NotificationManager::ToggleVibrations() { + vibrationEnabled = !vibrationEnabled; +} + bool NotificationManager::ClearNewNotificationFlag() { return newNotification.exchange(false); } diff --git a/src/components/ble/NotificationManager.h b/src/components/ble/NotificationManager.h index 036d2ed9..075a9a45 100644 --- a/src/components/ble/NotificationManager.h +++ b/src/components/ble/NotificationManager.h @@ -28,6 +28,8 @@ namespace Pinetime { Notification GetPrevious(Notification::Id id); bool ClearNewNotificationFlag(); bool AreNewNotificationsAvailable(); + bool IsVibrationEnabled(); + void ToggleVibrations(); static constexpr size_t MaximumMessageSize() { return MessageSize; }; size_t NbNotifications() const; @@ -40,6 +42,7 @@ namespace Pinetime { uint8_t writeIndex = 0; bool empty = true; std::atomic newNotification{false}; + bool vibrationEnabled = true; }; } } \ No newline at end of file diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp new file mode 100644 index 00000000..7f53fbf7 --- /dev/null +++ b/src/components/motor/MotorController.cpp @@ -0,0 +1,25 @@ +#include "MotorController.h" +#include +#include "systemtask/SystemTask.h" +#include "app_timer.h" + +APP_TIMER_DEF(vibTimer); + +using namespace Pinetime::Controllers; + +void MotorController::Init() { + nrf_gpio_cfg_output(pinMotor); + nrf_gpio_pin_set(pinMotor); + app_timer_init(); + app_timer_create(&vibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); +} + +void MotorController::SetDuration(uint8_t motorDuration) { + nrf_gpio_pin_clear(pinMotor); + /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ + app_timer_start(vibTimer, APP_TIMER_TICKS(motorDuration), NULL); +} + +void MotorController::vibrate(void * p_context) { + nrf_gpio_pin_set(pinMotor); +} \ No newline at end of file diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h new file mode 100644 index 00000000..bdc20c0c --- /dev/null +++ b/src/components/motor/MotorController.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include "app_timer.h" + +namespace Pinetime { + namespace Controllers { + static constexpr uint8_t pinMotor = 16; + + class MotorController { + public: + void Init(); + void SetDuration(uint8_t motorDuration); + + private: + static void vibrate(void * p_context); + }; + } +} diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 7ca91cfb..c09562f3 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -41,7 +41,6 @@ Notifications::Notifications(DisplayApp *app, style_line.line.width = 3; style_line.line.rounded = 0; - timeoutLine = lv_line_create(lv_scr_act(), nullptr); lv_line_set_style(timeoutLine, LV_LINE_STYLE_MAIN, &style_line); lv_line_set_points(timeoutLine, timeoutLinePoints, 2); @@ -119,6 +118,10 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { alertNotificationService)); } return true; + case Pinetime::Applications::TouchEvents::LongTap: { + notificationManager.ToggleVibrations(); + return true; + } default: return false; } @@ -135,7 +138,7 @@ namespace { auto* item = static_cast(obj->user_data); item->OnAcceptIncomingCall(event); } - + static void MuteIncomingCallEventHandler(lv_obj_t *obj, lv_event_t event) { auto* item = static_cast(obj->user_data); item->OnMuteIncomingCall(event); @@ -247,7 +250,7 @@ Notifications::NotificationItem::NotificationItem(const char *title, lv_obj_align(bt_reject, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, -20); label_reject = lv_label_create(bt_reject, nullptr); lv_label_set_text(label_reject, Symbols::phoneSlash); - + bt_mute = lv_btn_create(container1, nullptr); bt_mute->user_data = this; lv_obj_set_event_cb(bt_mute, MuteIncomingCallEventHandler); diff --git a/src/main.cpp b/src/main.cpp index 4aaf23c0..8644ed48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,6 +30,7 @@ #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" +#include "components/motor/MotorController.h" #include "components/datetime/DateTimeController.h" #include "displayapp/DisplayApp.h" #include "displayapp/LittleVgl.h" @@ -98,6 +99,8 @@ void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; std::unique_ptr systemTask; +Pinetime::Controllers::MotorController motorController; + void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if(pin == pinTouchIrq) { systemTask->OnTouchEvent(); @@ -239,7 +242,7 @@ int main(void) { debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback); systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, spiNorFlash, twiMaster, touchPanel, lvgl, batteryController, bleController, - dateTimeController, heartRateSensor)); + dateTimeController, motorController, heartRateSensor)); systemTask->Start(); nimble_port_init(); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index f998ac82..6e6360a4 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -40,13 +40,14 @@ SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Controllers::Battery &batteryController, Controllers::Ble &bleController, Controllers::DateTime &dateTimeController, + Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor) : spi{spi}, lcd{lcd}, spiNorFlash{spiNorFlash}, twiMaster{twiMaster}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, heartRateController{*this}, bleController{bleController}, dateTimeController{dateTimeController}, watchdog{}, watchdogView{watchdog}, - heartRateSensor{heartRateSensor}, + motorController{motorController}, heartRateSensor{heartRateSensor}, nimbleController(*this, bleController,dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { systemTasksMsgQueue = xQueueCreate(10, 1); } @@ -78,15 +79,17 @@ void SystemTask::Work() { twiMaster.Init(); touchPanel.Init(); batteryController.Init(); + motorController.Init(); + displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, - dateTimeController, watchdogView, *this, notificationManager, heartRateController)); + dateTimeController, watchdogView, *this, notificationManager, + heartRateController)); displayApp->Start(); batteryController.Update(); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); - heartRateSensor.Init(); heartRateSensor.Disable(); heartRateApp.reset(new Pinetime::Applications::HeartRateTask(heartRateSensor, heartRateController)); @@ -158,6 +161,7 @@ void SystemTask::Work() { break; case Messages::OnNewNotification: if(isSleeping && !isWakingUp) GoToRunning(); + if(notificationManager.IsVibrationEnabled()) motorController.SetDuration(35); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification); break; case Messages::BleConnected: diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index ed3574c0..c650d085 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -12,6 +12,7 @@ #include "components/battery/BatteryController.h" #include "components/ble/NimbleController.h" #include "components/ble/NotificationManager.h" +#include "components/motor/MotorController.h" #include "displayapp/DisplayApp.h" #include "drivers/Watchdog.h" @@ -37,6 +38,7 @@ namespace Pinetime { Components::LittleVgl &lvgl, Controllers::Battery &batteryController, Controllers::Ble &bleController, Controllers::DateTime &dateTimeController, + Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor); @@ -73,6 +75,7 @@ namespace Pinetime { Pinetime::Drivers::Watchdog watchdog; Pinetime::Drivers::WatchdogView watchdogView; Pinetime::Controllers::NotificationManager notificationManager; + Pinetime::Controllers::MotorController& motorController; Pinetime::Drivers::Hrs3300& heartRateSensor; Pinetime::Controllers::NimbleController nimbleController;