Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/components/motion/MotionController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ namespace {
void MotionController::AdvanceDay() {
--nbSteps; // Higher index = further in the past
SetSteps(Days::Today, 0);
carrySteps = 0;
if (service != nullptr) {
service->OnNewStepCountValue(NbSteps(Days::Today));
}
}

void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) {
// Offset the sensor value by whatever we are carrying forward
nbSteps += carrySteps;
uint32_t oldSteps = NbSteps(Days::Today);
if (oldSteps != nbSteps && service != nullptr) {
service->OnNewStepCountValue(nbSteps);
Expand Down Expand Up @@ -160,3 +163,9 @@ void MotionController::Init(Pinetime::Drivers::Bma421::DeviceTypes types) {
break;
}
}

void MotionController::Restore(uint32_t carrySteps, uint32_t carryTripSteps) {
this->carrySteps = carrySteps;
SetSteps(Days::Today, carrySteps);
currentTripSteps = carryTripSteps;
}
3 changes: 3 additions & 0 deletions src/components/motion/MotionController.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ namespace Pinetime {

void Init(Pinetime::Drivers::Bma421::DeviceTypes types);

void Restore(uint32_t carrySteps, uint32_t carryTripSteps);

void SetService(Pinetime::Controllers::MotionService* service) {
this->service = service;
}
Expand All @@ -76,6 +78,7 @@ namespace Pinetime {

private:
Utility::CircularBuffer<uint32_t, stepHistorySize> nbSteps = {0};
uint32_t carrySteps = 0;
uint32_t currentTripSteps = 0;

void SetSteps(Days day, uint32_t steps) {
Expand Down
36 changes: 36 additions & 0 deletions src/components/persistence/RebootPersist.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <cstdint>

namespace Pinetime {
namespace Components {
class RebootPersist {
public:
[[nodiscard]] bool IsValid() const volatile {
return canary == magic;
}

void SetValid() volatile {
canary = magic;
}

// layout of time point is implementation defined
// instead store milliseconds since epoch
uint64_t timeMillis;
uint32_t steps;
uint32_t tripSteps;

private:
// The canary determines whether memory has been kept or not after a reset,
// since the NRF52832 doesn't guarantee RAM retention
// See https://docs.nordicsemi.com/bundle/ps_nrf52832/page/power.html#d935e523
// If the magic value is still in the canary when booting,
// we assume that memory is intact from the previous boot

// Increment magic upon changing members of this class
// Otherwise garbage values will be loaded after DFU
static constexpr uint32_t magic = 0xDEAD0001;
uint32_t canary;
};
}
}
17 changes: 8 additions & 9 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "components/datetime/DateTimeController.h"
#include "components/heartrate/HeartRateController.h"
#include "components/stopwatch/StopWatchController.h"
#include "components/persistence/RebootPersist.h"
#include "components/fs/FS.h"
#include "drivers/Spi.h"
#include "drivers/SpiMaster.h"
Expand Down Expand Up @@ -161,14 +162,10 @@ void vApplicationStackOverflowHook(TaskHandle_t /*xTask*/, char* /*pcTaskName*/)
stackOverflowCount++;
}
}
/* Variable Declarations for variables in noinit SRAM
Increment NoInit_MagicValue upon adding variables to this area
*/
// Variable Declarations for variables in noinit SRAM
extern uint32_t __start_noinit_data;
extern uint32_t __stop_noinit_data;
static constexpr uint32_t NoInit_MagicValue = 0xDEAD0000;
uint32_t NoInit_MagicWord __attribute__((section(".noinit")));
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> NoInit_BackUpTime __attribute__((section(".noinit")));
volatile Pinetime::Components::RebootPersist NoInit_Persistence __attribute__((section(".noinit")));

void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
if (pin == Pinetime::PinMap::Cst816sIrq) {
Expand Down Expand Up @@ -352,12 +349,14 @@ int main() {
// retrieve version stored by bootloader
Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]);

if (NoInit_MagicWord == NoInit_MagicValue) {
dateTimeController.SetCurrentTime(NoInit_BackUpTime);
if (NoInit_Persistence.IsValid()) {
dateTimeController.SetCurrentTime(
std::chrono::time_point<std::chrono::system_clock>(std::chrono::milliseconds(NoInit_Persistence.timeMillis)));
motionController.Restore(NoInit_Persistence.steps, NoInit_Persistence.tripSteps);
} else {
// Clear Memory to known state
memset(&__start_noinit_data, 0, (uintptr_t) &__stop_noinit_data - (uintptr_t) &__start_noinit_data);
NoInit_MagicWord = NoInit_MagicValue;
NoInit_Persistence.SetValid();
}

systemTask.Start();
Expand Down
6 changes: 5 additions & 1 deletion src/systemtask/SystemTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,11 @@ void SystemTask::Work() {
}
}
monitor.Process();
NoInit_BackUpTime = dateTimeController.CurrentDateTime();

NoInit_Persistence.steps = motionController.NbSteps();
NoInit_Persistence.tripSteps = motionController.GetTripSteps();
NoInit_Persistence.timeMillis =
std::chrono::duration_cast<std::chrono::milliseconds>(dateTimeController.CurrentDateTime().time_since_epoch()).count();
if (nrf_gpio_pin_read(PinMap::Button) == 0) {
watchdog.Reload();
}
Expand Down
3 changes: 2 additions & 1 deletion src/systemtask/SystemTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "components/stopwatch/StopWatchController.h"
#include "components/alarm/AlarmController.h"
#include "components/fs/FS.h"
#include "components/persistence/RebootPersist.h"
#include "touchhandler/TouchHandler.h"
#include "buttonhandler/ButtonHandler.h"
#include "buttonhandler/ButtonActions.h"
Expand All @@ -32,7 +33,7 @@
#include "drivers/Watchdog.h"
#include "systemtask/Messages.h"

extern std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> NoInit_BackUpTime;
extern volatile Pinetime::Components::RebootPersist NoInit_Persistence;

namespace Pinetime {
namespace Drivers {
Expand Down
Loading