ref: e5b73212f6addcfdb5e306df63d7135e543c4f8d
src/heartratetask/HeartRateTask.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
#include "heartratetask/HeartRateTask.h" #include <drivers/Hrs3300.h> #include <components/heartrate/HeartRateController.h> #include <nrf_log.h> using namespace Pinetime::Applications; HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) : heartRateSensor {heartRateSensor}, controller {controller} { } void HeartRateTask::Start() { messageQueue = xQueueCreate(10, 1); controller.SetHeartRateTask(this); if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle)) { APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } } void HeartRateTask::Process(void* instance) { auto* app = static_cast<HeartRateTask*>(instance); app->Work(); } void HeartRateTask::Work() { int lastBpm = 0; while (true) { Messages msg; uint32_t delay; if (state == States::Running) { if (measurementStarted) { delay = ppg.deltaTms; } else { delay = 100; } } else { delay = portMAX_DELAY; } if (xQueueReceive(messageQueue, &msg, delay)) { switch (msg) { case Messages::GoToSleep: StopMeasurement(); state = States::Idle; break; case Messages::WakeUp: state = States::Running; if (measurementStarted) { lastBpm = 0; StartMeasurement(); } break; case Messages::StartMeasurement: if (measurementStarted) { break; } lastBpm = 0; StartMeasurement(); measurementStarted = true; break; case Messages::StopMeasurement: if (!measurementStarted) { break; } StopMeasurement(); measurementStarted = false; break; } } if (measurementStarted) { int8_t ambient = ppg.Preprocess(heartRateSensor.ReadHrs(), heartRateSensor.ReadAls()); int bpm = ppg.HeartRate(); // If ambient light detected or a reset requested (bpm < 0) if (ambient > 0) { // Reset all DAQ buffers ppg.Reset(true); // Force state to NotEnoughData (below) lastBpm = 0; bpm = 0; } else if (bpm < 0) { // Reset all DAQ buffers except HRS buffer ppg.Reset(false); // Set HR to zero and update bpm = 0; controller.Update(Controllers::HeartRateController::States::Running, bpm); } if (lastBpm == 0 && bpm == 0) { controller.Update(Controllers::HeartRateController::States::NotEnoughData, bpm); } if (bpm != 0) { lastBpm = bpm; controller.Update(Controllers::HeartRateController::States::Running, lastBpm); } } } } void HeartRateTask::PushMessage(HeartRateTask::Messages msg) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(messageQueue, &msg, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { /* Actual macro used here is port specific. */ // TODO : should I do something here? } } void HeartRateTask::StartMeasurement() { heartRateSensor.Enable(); ppg.Reset(true); vTaskDelay(100); } void HeartRateTask::StopMeasurement() { heartRateSensor.Disable(); ppg.Reset(true); vTaskDelay(100); } |