Merge pull request #3485 from gebart/pr/mulle-nvram

mulle: Initialize NVRAM storage at boot, update boot counter
cc430
Peter Kietzmann 8 years ago
commit fc539573a4

@ -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

@ -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));
}

@ -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
*/

@ -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_ */
Loading…
Cancel
Save