diff options
| author | Michele Bini <michele.bini@gmail.com> | 2022-04-20 17:45:20 (GMT) |
|---|---|---|
| committer | Michele Bini <michele.bini@gmail.com> | 2022-04-20 17:45:20 (GMT) |
| commit | 822ec38fde294dfc2a19fd83fe463fc0d7b3ee2d (patch) | |
| tree | 43e006a2890832c3778a4dbcc0920483ce63ed17 | |
| parent | be01602fcb6dc9cd91df702658c0b52da74023a9 (diff) | |
| parent | aca605d4fb4040cc80c1acf101023aa86e7694ba (diff) | |
Merge branch 'alarm-reliability-and-switch-to-freertos-timers' into rev22-develop
| -rwxr-xr-x | cmake-nRF5x/CMake_nRF5x.cmake | 2 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/components/alarm/AlarmController.cpp | 46 | ||||
| -rw-r--r-- | src/components/alarm/AlarmController.h | 10 | ||||
| -rw-r--r-- | src/components/datetime/DateTimeController.cpp | 33 | ||||
| -rw-r--r-- | src/components/motor/MotorController.cpp | 23 | ||||
| -rw-r--r-- | src/components/motor/MotorController.h | 8 | ||||
| -rw-r--r-- | src/components/timer/TimerController.cpp | 37 | ||||
| -rw-r--r-- | src/components/timer/TimerController.h | 18 | ||||
| -rw-r--r-- | src/sdk_config.h | 2 | ||||
| -rw-r--r-- | src/systemtask/Messages.h | 65 | ||||
| -rw-r--r-- | src/systemtask/SystemTask.cpp | 19 |
12 files changed, 153 insertions, 111 deletions
diff --git a/cmake-nRF5x/CMake_nRF5x.cmake b/cmake-nRF5x/CMake_nRF5x.cmake index c7d0a68..9bf63f2 100755 --- a/cmake-nRF5x/CMake_nRF5x.cmake +++ b/cmake-nRF5x/CMake_nRF5x.cmake @@ -106,7 +106,6 @@ macro(nRF5x_setup) ${NRF5_SDK_PATH}/external/freertos/source/stream_buffer.c ${NRF5_SDK_PATH}/external/freertos/source/tasks.c ${NRF5_SDK_PATH}/external/freertos/source/timers.c - ${NRF5_SDK_PATH}/components/libraries/timer/app_timer_freertos.c ) # freertos include @@ -335,7 +334,6 @@ endmacro(nRF5x_addAppFIFO) # adds app-level Timer libraries macro(nRF5x_addAppTimer) list(APPEND SDK_SOURCE_FILES - "${NRF5_SDK_PATH}/components/libraries/timer/app_timer.c" ) endmacro(nRF5x_addAppTimer) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b233f92..c94442d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,7 +53,6 @@ set(SDK_SOURCE_FILES ${NRF5_SDK_PATH}/external/freertos/source/stream_buffer.c ${NRF5_SDK_PATH}/external/freertos/source/tasks.c ${NRF5_SDK_PATH}/external/freertos/source/timers.c - ${NRF5_SDK_PATH}/components/libraries/timer/app_timer_freertos.c # Libs "${NRF5_SDK_PATH}/components/libraries/atomic/nrf_atomic.c" diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 11d96e7..7cecc9c 100644 --- a/src/components/alarm/AlarmController.cpp +++ b/src/components/alarm/AlarmController.cpp @@ -27,20 +27,16 @@ using namespace std::chrono_literals; AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} { } -APP_TIMER_DEF(alarmAppTimer); - namespace { - void SetOffAlarm(void* p_context) { - auto* controller = static_cast<Pinetime::Controllers::AlarmController*>(p_context); - if (controller != nullptr) { - controller->SetOffAlarmNow(); - } + void SetOffAlarm(TimerHandle_t xTimer) { + auto controller = static_cast<Pinetime::Controllers::AlarmController*>(pvTimerGetTimerID(xTimer)); + controller->SetOffAlarmNow(); } } void AlarmController::Init(System::SystemTask* systemTask) { - app_timer_create(&alarmAppTimer, APP_TIMER_MODE_SINGLE_SHOT, SetOffAlarm); this->systemTask = systemTask; + alarmAppTimer = xTimerCreate("alarmAppTm", 1, pdFALSE, this, SetOffAlarm); } void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) { @@ -48,9 +44,28 @@ void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) { minutes = alarmMin; } +void AlarmController::OnAdjustTime() { + + if (state != AlarmState::Set) { + return; + } + + xTimerStop(alarmAppTimer, 0); + auto now = dateTimeController.CurrentDateTime(); + + if (now > alarmTime) { + xTimerChangePeriod(alarmAppTimer, 1, 0); + } else { + auto mSecToAlarm = std::chrono::duration_cast<std::chrono::milliseconds>(alarmTime - now).count(); + xTimerChangePeriod(alarmAppTimer, APP_TIMER_TICKS(mSecToAlarm), 0); + } + + xTimerStart(alarmAppTimer, 0); +} + void AlarmController::ScheduleAlarm() { - // Determine the next time the alarm needs to go off and set the app_timer - app_timer_stop(alarmAppTimer); + // Determine the next time the alarm needs to go off and set the timer + xTimerStop(alarmAppTimer, 0); auto now = dateTimeController.CurrentDateTime(); alarmTime = now; @@ -82,7 +97,8 @@ void AlarmController::ScheduleAlarm() { // now can convert back to a time_point alarmTime = std::chrono::system_clock::from_time_t(std::mktime(tmAlarmTime)); auto mSecToAlarm = std::chrono::duration_cast<std::chrono::milliseconds>(alarmTime - now).count(); - app_timer_start(alarmAppTimer, APP_TIMER_TICKS(mSecToAlarm), this); + xTimerChangePeriod(alarmAppTimer, APP_TIMER_TICKS(mSecToAlarm), 0); + xTimerStart(alarmAppTimer, 0); state = AlarmState::Set; } @@ -92,7 +108,7 @@ uint32_t AlarmController::SecondsToAlarm() { } void AlarmController::DisableAlarm() { - app_timer_stop(alarmAppTimer); + xTimerStop(alarmAppTimer, 0); state = AlarmState::Not_Set; } @@ -103,6 +119,12 @@ void AlarmController::SetOffAlarmNow() { void AlarmController::StopAlerting() { systemTask->PushMessage(System::Messages::StopRinging); +} + +void AlarmController::OnStopRinging() { + if (state != AlarmState::Alerting) { + return; + } // Alarm state is off unless this is a recurring alarm if (recurrence == RecurType::None) { diff --git a/src/components/alarm/AlarmController.h b/src/components/alarm/AlarmController.h index f39fbde..6ad220f 100644 --- a/src/components/alarm/AlarmController.h +++ b/src/components/alarm/AlarmController.h @@ -17,6 +17,8 @@ */ #pragma once +#include <FreeRTOS.h> +#include <timers.h> #include <cstdint> #include "components/datetime/DateTimeController.h" @@ -29,9 +31,9 @@ namespace Pinetime { public: AlarmController(Controllers::DateTime& dateTimeController); - void Init(System::SystemTask* systemTask); void SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin); void ScheduleAlarm(); + void OnAdjustTime(); void DisableAlarm(); void SetOffAlarmNow(); uint32_t SecondsToAlarm(); @@ -54,9 +56,15 @@ namespace Pinetime { recurrence = recurType; } + protected: + friend class Pinetime::System::SystemTask; + void Init(System::SystemTask* systemTask); + void OnStopRinging(); + private: Controllers::DateTime& dateTimeController; System::SystemTask* systemTask = nullptr; + TimerHandle_t alarmAppTimer; uint8_t hours = 7; uint8_t minutes = 0; std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> alarmTime; diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 3bfbdc7..2656764 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -30,6 +30,7 @@ void DateTime::SetTime( /* .tm_year = */ year - 1900, }; tm.tm_isdst = -1; // Use DST value from local time zone + auto previousDateTime = currentDateTime; currentDateTime = std::chrono::system_clock::from_time_t(std::mktime(&tm)); NRF_LOG_INFO("%d %d %d ", day, month, year); @@ -40,7 +41,17 @@ void DateTime::SetTime( NRF_LOG_INFO("* %d %d %d ", this->hour, this->minute, this->second); NRF_LOG_INFO("* %d %d %d ", this->day, this->month, this->year); - systemTask->PushMessage(System::Messages::OnNewTime); + decltype(currentDateTime - previousDateTime) timeDifference; + + if (currentDateTime > previousDateTime) { + timeDifference = currentDateTime - previousDateTime; + } else { + timeDifference = previousDateTime - currentDateTime; + } + + using namespace std::chrono_literals; + + systemTask->PushMessage(timeDifference < 3h ? System::Messages::OnAdjustTime : System::Messages::OnNewTime); } void DateTime::UpdateTime(uint32_t systickCounter) { @@ -129,16 +140,16 @@ std::string DateTime::FormattedTime() { // Return time as a string in 12- or 24-hour format char buff[9]; if (settingsController.GetClockType() == ClockType::H12) { - uint8_t hour12; - const char* amPmStr; - if (hour < 12) { - hour12 = (hour == 0) ? 12 : hour; - amPmStr = "AM"; - } else { - hour12 = (hour == 12) ? 12 : hour - 12; - amPmStr = "PM"; - } - sprintf(buff, "%i:%02i %s", hour12, minute, amPmStr); + uint8_t hour12; + const char* amPmStr; + if (hour < 12) { + hour12 = (hour == 0) ? 12 : hour; + amPmStr = "AM"; + } else { + hour12 = (hour == 12) ? 12 : hour - 12; + amPmStr = "PM"; + } + sprintf(buff, "%i:%02i %s", hour12, minute, amPmStr); } else { sprintf(buff, "%02i:%02i", hour, minute); } diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index c794a02..4c44fc4 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -12,32 +12,33 @@ using namespace Pinetime::Controllers; void MotorController::Init() { nrf_gpio_cfg_output(PinMap::Motor); nrf_gpio_pin_set(PinMap::Motor); - app_timer_init(); - app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, StopMotor); - app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, Ring); + shortVibTimer = xTimerCreate("shortVibTm", 1, pdFALSE, nullptr, StopMotor); + longVibTimer = xTimerCreate("longVibTm", 1, pdTRUE, this, Ring); } -void MotorController::Ring(void* p_context) { - auto* motorController = static_cast<MotorController*>(p_context); +void MotorController::Ring(TimerHandle_t xTimer) { + auto motorController = static_cast<MotorController*>(pvTimerGetTimerID(xTimer)); + xTimerChangePeriod(motorController->longVibTimer, APP_TIMER_TICKS(1000), 0); motorController->RunForDuration(50); } void MotorController::RunForDuration(uint8_t motorDuration) { - nrf_gpio_pin_clear(PinMap::Motor); - app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); + if (xTimerChangePeriod(shortVibTimer, APP_TIMER_TICKS(motorDuration), 0) == pdPASS && xTimerStart(shortVibTimer, 0) == pdPASS) { + nrf_gpio_pin_clear(PinMap::Motor); + } } void MotorController::StartRinging() { - Ring(this); - app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); + xTimerChangePeriod(longVibTimer, 1, 0); + xTimerStart(longVibTimer, 0); } void MotorController::StopRinging() { - app_timer_stop(longVibTimer); + xTimerStop(longVibTimer, 0); nrf_gpio_pin_set(PinMap::Motor); } -void MotorController::StopMotor(void* p_context) { +void MotorController::StopMotor(TimerHandle_t xTimer) { nrf_gpio_pin_set(PinMap::Motor); } diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index b5a592b..3c6cbd2 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -1,5 +1,7 @@ #pragma once +#include <FreeRTOS.h> +#include <timers.h> #include <cstdint> namespace Pinetime { @@ -15,8 +17,10 @@ namespace Pinetime { void StopRinging(); private: - static void Ring(void* p_context); - static void StopMotor(void* p_context); + static void Ring(TimerHandle_t xTimer); + static void StopMotor(TimerHandle_t xTimer); + TimerHandle_t shortVibTimer; + TimerHandle_t longVibTimer; }; } } diff --git a/src/components/timer/TimerController.cpp b/src/components/timer/TimerController.cpp index 79e44d6..31635a5 100644 --- a/src/components/timer/TimerController.cpp +++ b/src/components/timer/TimerController.cpp @@ -4,32 +4,29 @@ #include "components/timer/TimerController.h" #include "systemtask/SystemTask.h" -#include "app_timer.h" #include "task.h" using namespace Pinetime::Controllers; - -APP_TIMER_DEF(timerAppTimer); - namespace { - void TimerEnd(void* p_context) { - auto* controller = static_cast<Pinetime::Controllers::TimerController*> (p_context); - if(controller != nullptr) - controller->OnTimerEnd(); + void TimerEnd(TimerHandle_t xTimer) { + auto controller = static_cast<Pinetime::Controllers::TimerController*>(pvTimerGetTimerID(xTimer)); + controller->OnTimerEnd(); } } - -void TimerController::Init() { - app_timer_create(&timerAppTimer, APP_TIMER_MODE_SINGLE_SHOT, TimerEnd); +void TimerController::Init(System::SystemTask* systemTask) { + this->systemTask = systemTask; + timerAppTimer = xTimerCreate("timerAppTm", 1, pdFALSE, this, TimerEnd); } void TimerController::StartTimer(uint32_t duration) { - app_timer_stop(timerAppTimer); + xTimerStop(timerAppTimer, 0); auto currentTicks = xTaskGetTickCount(); - app_timer_start(timerAppTimer, APP_TIMER_TICKS(duration), this); - endTicks = currentTicks + APP_TIMER_TICKS(duration); + TickType_t durationTicks = APP_TIMER_TICKS(duration); + xTimerChangePeriod(timerAppTimer, durationTicks, 0); + xTimerStart(timerAppTimer, 0); + endTicks = currentTicks + durationTicks; timerRunning = true; } @@ -38,7 +35,7 @@ uint32_t TimerController::GetTimeRemaining() { return 0; } auto currentTicks = xTaskGetTickCount(); - + TickType_t deltaTicks = 0; if (currentTicks > endTicks) { deltaTicks = 0xffffffff - currentTicks; @@ -46,12 +43,12 @@ uint32_t TimerController::GetTimeRemaining() { } else { deltaTicks = endTicks - currentTicks; } - + return (static_cast<TickType_t>(deltaTicks) / static_cast<TickType_t>(configTICK_RATE_HZ)) * 1000; } void TimerController::StopTimer() { - app_timer_stop(timerAppTimer); + xTimerStop(timerAppTimer, 0); timerRunning = false; } @@ -60,10 +57,6 @@ bool TimerController::IsRunning() { } void TimerController::OnTimerEnd() { timerRunning = false; - if(systemTask != nullptr) + if (systemTask != nullptr) systemTask->PushMessage(System::Messages::OnTimerDone); } - -void TimerController::Register(Pinetime::System::SystemTask* systemTask) { - this->systemTask = systemTask; -} diff --git a/src/components/timer/TimerController.h b/src/components/timer/TimerController.h index fa7bc90..24d7150 100644 --- a/src/components/timer/TimerController.h +++ b/src/components/timer/TimerController.h @@ -1,5 +1,7 @@ #pragma once +#include <FreeRTOS.h> +#include <timers.h> #include <cstdint> #include "app_timer.h" #include "portmacro_cmsis.h" @@ -9,27 +11,27 @@ namespace Pinetime { class SystemTask; } namespace Controllers { - + class TimerController { public: TimerController() = default; - - void Init(); - + void StartTimer(uint32_t duration); - void StopTimer(); - + uint32_t GetTimeRemaining(); - + bool IsRunning(); void OnTimerEnd(); - void Register(System::SystemTask* systemTask); + protected: + friend class Pinetime::System::SystemTask; + void Init(System::SystemTask* systemTask); private: System::SystemTask* systemTask = nullptr; + TimerHandle_t timerAppTimer; TickType_t endTicks; bool timerRunning = false; }; diff --git a/src/sdk_config.h b/src/sdk_config.h index 7634dca..fa9d630 100644 --- a/src/sdk_config.h +++ b/src/sdk_config.h @@ -6781,7 +6781,7 @@ // <e> APP_TIMER_ENABLED - app_timer - Application timer functionality //========================================================== #ifndef APP_TIMER_ENABLED - #define APP_TIMER_ENABLED 1 + #define APP_TIMER_ENABLED 0 #endif // <o> APP_TIMER_CONFIG_RTC_FREQUENCY - Configure RTC prescaler. diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 2e3456a..3648142 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -2,36 +2,37 @@ namespace Pinetime { namespace System { - enum class Messages { - GoToSleep, - GoToRunning, - TouchWakeUp, - OnNewTime, - OnNewNotification, - OnTimerDone, - OnNewCall, - BleConnected, - UpdateTimeOut, - BleFirmwareUpdateStarted, - BleFirmwareUpdateFinished, - OnTouchEvent, - HandleButtonEvent, - HandleButtonTimerEvent, - OnDisplayTaskSleeping, - EnableSleeping, - DisableSleeping, - OnNewDay, - OnNewHour, - OnNewHalfHour, - OnChargingEvent, - OnPairing, - SetOffAlarm, - StopRinging, - MeasureBatteryTimerExpired, - BatteryPercentageUpdated, - StartFileTransfer, - StopFileTransfer, - BleRadioEnableToggle - }; - } + enum class Messages { + GoToSleep, + GoToRunning, + TouchWakeUp, + OnNewTime, + OnAdjustTime, + OnNewNotification, + OnTimerDone, + OnNewCall, + BleConnected, + UpdateTimeOut, + BleFirmwareUpdateStarted, + BleFirmwareUpdateFinished, + OnTouchEvent, + HandleButtonEvent, + HandleButtonTimerEvent, + OnDisplayTaskSleeping, + EnableSleeping, + DisableSleeping, + OnNewDay, + OnNewHour, + OnNewHalfHour, + OnChargingEvent, + OnPairing, + SetOffAlarm, + StopRinging, + MeasureBatteryTimerExpired, + BatteryPercentageUpdated, + StartFileTransfer, + StopFileTransfer, + BleRadioEnableToggle + }; + } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 38c728f..760f216 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -127,8 +127,6 @@ void SystemTask::Work() { NRF_LOG_INFO("Last reset reason : %s", Pinetime::Drivers::Watchdog::ResetReasonToString(watchdog.ResetReason())); APP_GPIOTE_INIT(2); - app_timer_init(); - spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); @@ -152,8 +150,7 @@ void SystemTask::Work() { batteryController.Register(this); motorController.Init(); motionSensor.SoftReset(); - timerController.Register(this); - timerController.Init(); + timerController.Init(this); alarmController.Init(this); // Reset the TWI device because the motion sensor chip most probably crashed it... @@ -287,9 +284,12 @@ void SystemTask::Work() { heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); break; case Messages::OnNewTime: + case Messages::OnAdjustTime: ReloadIdleTimer(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime); - if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) { + if (message == Messages::OnAdjustTime) { + alarmController.OnAdjustTime(); + } else { alarmController.ScheduleAlarm(); } break; @@ -319,6 +319,7 @@ void SystemTask::Work() { break; case Messages::StopRinging: motorController.StopRinging(); + alarmController.OnStopRinging(); break; case Messages::BleConnected: ReloadIdleTimer(); @@ -402,7 +403,8 @@ void SystemTask::Work() { break; case Messages::OnNewHour: using Pinetime::Controllers::AlarmController; - if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && alarmController.State() != AlarmController::AlarmState::Alerting) { + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && + alarmController.State() != AlarmController::AlarmState::Alerting) { if (isSleeping && !isWakingUp) { GoToRunning(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::Clock); @@ -412,7 +414,8 @@ void SystemTask::Work() { break; case Messages::OnNewHalfHour: using Pinetime::Controllers::AlarmController; - if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && alarmController.State() != AlarmController::AlarmState::Alerting) { + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && + alarmController.State() != AlarmController::AlarmState::Alerting) { if (isSleeping && !isWakingUp) { GoToRunning(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::Clock); @@ -442,7 +445,7 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::ShowPairingKey); break; case Messages::BleRadioEnableToggle: - if(settingsController.GetBleRadioEnabled()) { + if (settingsController.GetBleRadioEnabled()) { nimbleController.EnableRadio(); } else { nimbleController.DisableRadio(); |
