Subversion Repositories DashDisplay

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 mjames 1
/*
2
 * nvram.c
3
 *
4
 *  Created on: 4 Jun 2017
5
 *      Author: Mike
6
 */
7
 
8
/* Includes ------------------------------------------------------------------*/
9
#include "stm32l1xx_hal.h"
10
 
11
#include "nvram.h"
12
 
65 mjames 13
// NVRAM hardware erases to all 0x
14
nvram_info_t const HARDWARE_ERASED = {.u32 = 0UL};
15
// Marked as erased change to all 1
16
nvram_info_t const MARKED_ERASED = {.u32 = ~0UL};
17
// marked as unusable  change pattern to something in between
18
nvram_info_t const MARKED_UNUSABLE = {.u32 = 0x55555555UL};
19
 
20
nvram_info_t NVRAM_Base[NVRAM_WORDS] __attribute__((section(".NVRAM_Data"))); // set by linker
21
 
22
static void
23
WriteNVRAM(nvram_info_t *Address, nvram_info_t data)
30 mjames 24
{
65 mjames 25
  HAL_FLASHEx_DATAEEPROM_Unlock();
26
  HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, (uint32_t)Address, data.u32);
27
  HAL_FLASHEx_DATAEEPROM_Lock();
56 mjames 28
}
30 mjames 29
 
65 mjames 30
static void
31
EraseNVRAM(nvram_info_t *Address)
56 mjames 32
{
65 mjames 33
  HAL_FLASHEx_DATAEEPROM_Unlock();
34
  HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, (uint32_t)Address);
35
  HAL_FLASHEx_DATAEEPROM_Lock();
30 mjames 36
}
65 mjames 37
 
38
void write_nvram_data(nvram_info_t data)
39
{
40
  int base = 0;
41
 
42
  /* search blank */
43
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
44
  {
45
    // erase the entry just found
46
    if (NVRAM_Base[ptr].data.tag == data.data.tag)
47
    {
48
      // erase previous data
49
      WriteNVRAM(&NVRAM_Base[ptr], MARKED_ERASED);
50
      base = ptr;
51
      break;
52
    }
53
  }
54
  // search forward for next erased or empty element, use it
55
  for (int offset = 1; offset < NVRAM_WORDS + 1; offset++)
56
  {
57
    int index = (base + offset) % NVRAM_WORDS;
58
    if (NVRAM_Base[index].u32 == MARKED_ERASED.u32 || NVRAM_Base[index].u32 == HARDWARE_ERASED.u32)
59
    {
60
      if (NVRAM_Base[index].u32 != HARDWARE_ERASED.u32)
61
        EraseNVRAM(&NVRAM_Base[index]);
62
      WriteNVRAM(&NVRAM_Base[index], data);
63
      // now check to see if it actually went
64
      if (NVRAM_Base[index].u32 != data.u32)
65
      {
66
        WriteNVRAM(&NVRAM_Base[index], MARKED_UNUSABLE); // mark as neither unused or used
67
        continue;
68
      }
69
      return;
70
    }
71
  }
72
}
73
 
74
nvram_info_t *find_nvram_data(uint8_t searchTag)
75
{
76
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
77
  {
78
    if (NVRAM_Base[ptr].data.tag == searchTag)
79
      return &NVRAM_Base[ptr];
80
  }
81
  return NULL;
82
}