1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

mulle: Initialize NVRAM storage at boot, update boot counter

The boot counter is incremented on each boot. Still missing is an
interface for reading the boot counter from an application.
This commit is contained in:
Joakim Gebart 2015-01-28 13:51:45 +01:00 committed by Joakim Nohlgård
parent 2b29abed8e
commit 22af0cca80
4 changed files with 146 additions and 2 deletions

View File

@ -6,6 +6,9 @@ endif
# The RTT clock drives the core clock in the default configuration
FEATURES_REQUIRED += periph_rtt
# The RTT clock drives the core clock in the default configuration
FEATURES_REQUIRED += periph_rtt
# The Mulle uses NVRAM to store persistent variables, such as boot count.
#~ USEMODULE += nvram_spi
# Uncomment above when #2353 is merged.
USEMODULE += nvram_spi
FEATURES_REQUIRED += periph_spi

View File

@ -26,6 +26,16 @@
#include "periph/gpio.h"
#include "periph/uart.h"
#include "periph/rtt.h"
#include "periph/spi.h"
#include "nvram-spi.h"
static nvram_t mulle_nvram_dev;
nvram_t *mulle_nvram = &mulle_nvram_dev;
static nvram_spi_params_t nvram_spi_params = {
.spi = MULLE_NVRAM_SPI_DEV,
.cs = MULLE_NVRAM_SPI_CS,
.address_count = MULLE_NVRAM_SPI_ADDRESS_COUNT,
};
/**
* @brief Initialize the boards on-board LEDs
@ -50,9 +60,12 @@ static inline void set_safe_clock_dividers(void);
/** @brief Set the FLL source clock to RTC32k */
static inline void set_fll_source(void);
static void increase_boot_count(void);
static int mulle_nvram_init(void);
void board_init(void)
{
int status;
/* initialize the boards LEDs, this is done first for debugging purposes */
leds_init();
@ -60,6 +73,12 @@ void board_init(void)
power_pins_init();
/* Turn on Vperiph for peripherals */
/*
* By turning on Vperiph first, and before waiting for the clocks to
* stabilize, we will have used enough time to have let the FRAM start up
* properly when we want to access it later without having to add any extra
* delays.
*/
gpio_set(MULLE_POWER_VPERIPH);
/* Turn on AVDD for reading voltages */
@ -98,6 +117,17 @@ void board_init(void)
/* initialize the CPU */
cpu_init();
LED_YELLOW_ON;
/* Initialize NVRAM */
status = mulle_nvram_init();
if (status == 0) {
/* Increment boot counter */
increase_boot_count();
}
LED_GREEN_ON;
}
/**
@ -168,3 +198,57 @@ static inline void set_fll_source(void)
#error Unknown K60 CPU revision
#endif
}
static int mulle_nvram_init(void)
{
union {
uint32_t u32;
uint8_t u8[sizeof(uint32_t)];
} rec;
rec.u32 = 0;
if (spi_init_master(MULLE_NVRAM_SPI_DEV, SPI_CONF_FIRST_RISING, SPI_SPEED_5MHZ) != 0) {
return -1;
}
if (nvram_spi_init(mulle_nvram, &nvram_spi_params, MULLE_NVRAM_CAPACITY) != 0) {
return -2;
}
if (mulle_nvram->read(mulle_nvram, &rec.u8[0], MULLE_NVRAM_MAGIC, sizeof(rec.u32)) != sizeof(rec.u32)) {
return -3;
}
if (rec.u32 != MULLE_NVRAM_MAGIC_EXPECTED) {
int i;
union {
uint64_t u64;
uint8_t u8[sizeof(uint64_t)];
} zero;
zero.u64 = 0;
for (i = 0; i < MULLE_NVRAM_CAPACITY; i += sizeof(zero)) {
if (mulle_nvram->write(mulle_nvram, &zero.u8[0], i, sizeof(zero.u64)) != sizeof(zero.u64)) {
return -4;
}
}
rec.u32 = MULLE_NVRAM_MAGIC_EXPECTED;
if (mulle_nvram->write(mulle_nvram, &rec.u8[0], MULLE_NVRAM_MAGIC, sizeof(rec.u32)) != sizeof(rec.u32)) {
return -5;
}
}
return 0;
}
static void increase_boot_count(void)
{
union {
uint32_t u32;
uint8_t u8[sizeof(uint32_t)];
} rec;
rec.u32 = 0;
if (mulle_nvram->read(mulle_nvram, &rec.u8[0], MULLE_NVRAM_BOOT_COUNT, sizeof(rec.u32)) != sizeof(rec.u32)) {
return;
}
++rec.u32;
mulle_nvram->write(mulle_nvram, &rec.u8[0], MULLE_NVRAM_BOOT_COUNT, sizeof(rec.u32));
}

View File

@ -23,6 +23,7 @@
#include "cpu.h"
#include "periph_conf.h"
#include "mulle-nvram.h"
/* Use the on board RTC 32kHz clock for LPTMR clocking. */
#undef LPTIMER_CLKSRC
@ -120,6 +121,17 @@ void board_init(void);
#define MULLE_POWER_VSEC GPIO_5 /**< VSEC enable pin */
/** @} */
/**
* @name Mulle NVRAM hardware configuration
*/
/** @{ */
/** FRAM SPI bus, SPI_2 in RIOT is mapped to hardware bus SPI0, see periph_conf.h */
#define MULLE_NVRAM_SPI_DEV SPI_2
#define MULLE_NVRAM_SPI_CS GPIO_16 /**< FRAM CS pin */
#define MULLE_NVRAM_CAPACITY 512 /**< FRAM size, in bytes */
#define MULLE_NVRAM_SPI_ADDRESS_COUNT 1 /**< FRAM addressing size, in bytes */
/** @} */
/**
* @name K60 clock dividers
*/

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
#ifndef MULLE_NVRAM_H_
#define MULLE_NVRAM_H_
#include "nvram.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup board_mulle
* @{
*
* @file
* @brief NVRAM offsets for the Eistec Mulle IoT board
*
* @author Joakim Gebart <joakim.gebart@eistec.se>
*/
typedef enum mulle_nvram_address {
/** @brief NVRAM magic number, used to identify an initialized FRAM device. */
MULLE_NVRAM_MAGIC = 0x0000,
/** @brief Reboot counter */
MULLE_NVRAM_BOOT_COUNT = 0x0004,
} mulle_nvram_address_t;
#define MULLE_NVRAM_MAGIC_EXPECTED (0x4c4c554dul) /* == "MULL" in ASCII */
extern nvram_t *mulle_nvram;
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* MULLE_NVRAM_H_ */