Subversion Repositories DashDisplay

Rev

Rev 70 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
66 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
 
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)
24
{
25
  HAL_FLASHEx_DATAEEPROM_Unlock();
26
  HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, (uint32_t)Address, data.u32);
27
  HAL_FLASHEx_DATAEEPROM_Lock();
28
}
29
 
30
static void
31
EraseNVRAM(nvram_info_t *Address)
32
{
33
  HAL_FLASHEx_DATAEEPROM_Unlock();
34
  HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, (uint32_t)Address);
35
  HAL_FLASHEx_DATAEEPROM_Lock();
36
}
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
    {
79 mjames 48
      // erase previous data, delete any entries that have a matching tag
66 mjames 49
      WriteNVRAM(&NVRAM_Base[ptr], MARKED_ERASED);
79 mjames 50
      // record the next location to the marked erased location
51
      // so that future writes occur further along in the Flash
52
      if (base == 0)
53
        base = ptr;
66 mjames 54
    }
55
  }
79 mjames 56
 
66 mjames 57
  // search forward for next erased or empty element, use it
58
  for (int offset = 1; offset < NVRAM_WORDS + 1; offset++)
59
  {
60
    int index = (base + offset) % NVRAM_WORDS;
61
    if (NVRAM_Base[index].u32 == MARKED_ERASED.u32 || NVRAM_Base[index].u32 == HARDWARE_ERASED.u32)
62
    {
63
      if (NVRAM_Base[index].u32 != HARDWARE_ERASED.u32)
64
        EraseNVRAM(&NVRAM_Base[index]);
65
      WriteNVRAM(&NVRAM_Base[index], data);
66
      // now check to see if it actually went
67
      if (NVRAM_Base[index].u32 != data.u32)
68
      {
69
        WriteNVRAM(&NVRAM_Base[index], MARKED_UNUSABLE); // mark as neither unused or used
70
        continue;
71
      }
72
      return;
73
    }
74
  }
75
}
76
 
77
nvram_info_t *find_nvram_data(uint8_t searchTag)
78
{
79
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
80
  {
81
    if (NVRAM_Base[ptr].data.tag == searchTag)
82
      return &NVRAM_Base[ptr];
83
  }
84
  return NULL;
85
}
70 mjames 86
 
87
void erase_nvram()
88
{
89
  /* search blank */
90
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
91
  {
92
    EraseNVRAM(&NVRAM_Base[ptr]);
93
  }
94
}