From d8d7d76b17e188420f66705f0b319f6e80a328f2 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Sat, 9 May 2020 14:17:42 +0100 Subject: [PATCH] boards: Add pseudo-NVRAM support Currently the pseudo-NVRAM is used only to measure the time spent in the bootloader (which keeps the watch time stable when we reset the device). At this stage the legacy mechanisms to pass messages via the SRAM have not been modified. --- src/boards.c | 2 ++ src/pnvram.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/pnvram.h diff --git a/src/boards.c b/src/boards.c index 0e00b96..4a129ce 100644 --- a/src/boards.c +++ b/src/boards.c @@ -28,6 +28,7 @@ #include "nrf_wdt.h" #include "app_scheduler.h" #include "app_timer.h" +#include "pnvram.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION @@ -151,6 +152,7 @@ static uint32_t _long_press_count = 0; void SysTick_Handler(void) { _systick_count++; + pnvram_add_ms(pnvram, 1); #if LEDS_NUMBER > 0 led_tick(); #endif diff --git a/src/pnvram.h b/src/pnvram.h new file mode 100644 index 0000000..034bbb0 --- /dev/null +++ b/src/pnvram.h @@ -0,0 +1,54 @@ +/* + * SPDX-License-Identifier: LGPL-3.0-or-later + * Copyright (C) 2020 Daniel Thompson + */ + +#ifndef NPVRAM_H_ +#define NPVRAM_H_ + +#include +#include +#include + +/*! \brief Pseudo Non-Voltatile RAM + * + * This is a data structure that can be placed in the first available + * RAM location. It survives reset but not power down. It can be used + * to share information between the bootloader and the main + * application. + */ +struct pnvram { + uint32_t header; //!< Validation word - 0x1abe11ed + uint32_t offset; //!< Number of seconds since the epoch + uint32_t uptime; //!< Device uptime in milliseconds + uint32_t reserved[4]; + uint32_t footer; //!< Validation word - 0x10adab1e +}; + +#define PNVRAM_HEADER 0x1abe11ed +#define PNVRAM_FOOTER 0x10adab1e + +#ifdef NRF52832_XXAA +static volatile struct pnvram * const pnvram = (void *) 0x200039c0; +#endif + +static inline void pnvram_init(struct pnvram *p) +{ + memset(p, 1, sizeof(*p)); + + p->header = PNVRAM_HEADER; + p->footer = PNVRAM_FOOTER; +} + +static inline bool pnvram_is_valid(volatile struct pnvram * const p) +{ + return p->header == PNVRAM_HEADER && p->footer == PNVRAM_FOOTER; +} + +static inline void pnvram_add_ms(volatile struct pnvram * const p, uint32_t ms) +{ + if (pnvram_is_valid(p)) + p->uptime += ms; +} + +#endif /* NPVRAM_H_ */