diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 4e392416..2bbd2a03 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -5,14 +5,58 @@ using namespace Pinetime::Controllers; +namespace { + TimerHandle_t vibTimer; + + void PatternStep(TimerHandle_t xTimer) { + /* Vibration pattern format: + * { + * durationOfVibration, + * durationOfPause, + * durationOfVibration, + * durationOfPause, + * ..., + * durationOfVibration, + * zeroTerminator + * } + * + * Patterns can be any length + * The pattern must end with a duration of vibration and a terminator. + */ + + static constexpr uint8_t vibrationPattern[] = {10, 100, 50, 200, 10, 0}; + + static size_t patternPosition = 0; + if (vibrationPattern[patternPosition] != 0 && xTimerChangePeriod(vibTimer, vibrationPattern[patternPosition] << 1, 0) == pdPASS && + xTimerStart(vibTimer, 0) == pdPASS) { + if (patternPosition % 2 == 0) { + nrf_gpio_pin_clear(Pinetime::PinMap::Motor); + } else { + nrf_gpio_pin_set(Pinetime::PinMap::Motor); + } + patternPosition++; + } else { + patternPosition = 0; + nrf_gpio_pin_set(Pinetime::PinMap::Motor); + auto* motorController = static_cast(pvTimerGetTimerID(xTimer)); + motorController->PatternFinished(); + } + } +} + void MotorController::Init() { nrf_gpio_cfg_output(PinMap::Motor); nrf_gpio_pin_set(PinMap::Motor); + vibTimer = xTimerCreate("vibration", 1, pdFALSE, this, PatternStep); shortVib = xTimerCreate("shortVib", 1, pdFALSE, nullptr, StopMotor); longVib = xTimerCreate("longVib", pdMS_TO_TICKS(1000), pdTRUE, this, Ring); } +void MotorController::PatternFinished() { + patternPlaying = false; +} + void MotorController::Ring(TimerHandle_t xTimer) { auto* motorController = static_cast(pvTimerGetTimerID(xTimer)); motorController->RunForDuration(50); @@ -24,6 +68,15 @@ void MotorController::RunForDuration(uint8_t motorDuration) { } } +bool MotorController::StartPattern() { + if (!patternPlaying) { + patternPlaying = true; + PatternStep(vibTimer); + return true; + } + return false; +} + void MotorController::StartRinging() { RunForDuration(50); xTimerStart(longVib, 0); diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index 6dea6d1f..2f6ca59b 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -15,10 +15,13 @@ namespace Pinetime { void RunForDuration(uint8_t motorDuration); void StartRinging(); void StopRinging(); + void PatternFinished(); + bool StartPattern(); private: static void Ring(TimerHandle_t xTimer); static void StopMotor(TimerHandle_t xTimer); + bool patternPlaying; TimerHandle_t shortVib; TimerHandle_t longVib; }; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index a547cfbc..1ae59f05 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -389,7 +389,18 @@ void DisplayApp::Refresh() { break; case Messages::Chime: LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None); - motorController.RunForDuration(35); + time_var = dateTimeController.Minutes(); + if (time_var == 30){ + NRF_LOG_INFO("Short: %d", time_var); + motorController.StartPattern(); + } + else + { + NRF_LOG_INFO("Long: %d", time_var); + motorController.RunForDuration(200); + } + + break; case Messages::OnChargingEvent: RestoreBrightness(); diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index f537651d..2c8a3b64 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -128,6 +128,7 @@ namespace Pinetime { Utility::StaticStack returnAppStack; Utility::StaticStack appStackDirections; + int time_var; bool isDimmed = false; }; } diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index 16f25df0..f560fef7 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -2,6 +2,7 @@ #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" #include "displayapp/InfiniTimeTheme.h" +#include using namespace Pinetime::Applications::Screens; @@ -58,8 +59,17 @@ FlashLight::~FlashLight() { } void FlashLight::SetColors() { - lv_color_t bgColor = isOn ? LV_COLOR_WHITE : LV_COLOR_BLACK; - lv_color_t fgColor = isOn ? Colors::lightGray : LV_COLOR_WHITE; + lv_color_t bgColor = LV_COLOR_BLACK; + if(State_l == 0){ + bgColor = LV_COLOR_BLACK; + } else if (State_l == 1){ + bgColor = LV_COLOR_WHITE; + } + else { + bgColor = lv_color_hex(0xff0000); + } + + lv_color_t fgColor = State_l ? Colors::lightGray : LV_COLOR_WHITE; lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, bgColor); lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, fgColor); @@ -86,9 +96,11 @@ void FlashLight::SetIndicators() { } void FlashLight::Toggle() { - isOn = !isOn; + State_l++; + if(State_l > 2) + State_l = 0; SetColors(); - if (isOn) { + if (State_l) { brightnessController.Set(brightnessLevel); } else { brightnessController.Set(Controllers::BrightnessController::Levels::Low); @@ -99,7 +111,7 @@ bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { using namespace Pinetime::Controllers; auto SetState = [this]() { - if (isOn) { + if (State_l) { brightnessController.Set(brightnessLevel); } SetIndicators(); @@ -127,4 +139,4 @@ bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } return false; -} +} \ No newline at end of file diff --git a/src/displayapp/screens/FlashLight.h b/src/displayapp/screens/FlashLight.h index 2b710ed5..4f5d4ac3 100644 --- a/src/displayapp/screens/FlashLight.h +++ b/src/displayapp/screens/FlashLight.h @@ -26,12 +26,13 @@ namespace Pinetime { Pinetime::System::SystemTask& systemTask; Controllers::BrightnessController& brightnessController; + Controllers::BrightnessController::Levels brightnessLevel = Controllers::BrightnessController::Levels::High; lv_obj_t* flashLight; lv_obj_t* backgroundAction; lv_obj_t* indicators[3]; - bool isOn = false; + int State_l = 0; }; } }