Subversion Repositories DashDisplay

Rev

Rev 79 | 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
80 mjames 18
nvram_info_t const MARKED_UNUSABLE = {.u32 = 0x555555FFUL};
66 mjames 19
 
20
nvram_info_t NVRAM_Base[NVRAM_WORDS] __attribute__((section(".NVRAM_Data"))); // set by linker
21
 
22
static void
80 mjames 23
WriteNVRAM(int offset, nvram_info_t data)
66 mjames 24
{
25
  HAL_FLASHEx_DATAEEPROM_Unlock();
80 mjames 26
  HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, (uint32_t)(&NVRAM_Base[offset]), data.u32);
66 mjames 27
  HAL_FLASHEx_DATAEEPROM_Lock();
28
}
29
 
30
static void
80 mjames 31
EraseNVRAM(int offset)
66 mjames 32
{
33
  HAL_FLASHEx_DATAEEPROM_Unlock();
80 mjames 34
  HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, (uint32_t)(&NVRAM_Base[offset]));
66 mjames 35
  HAL_FLASHEx_DATAEEPROM_Lock();
36
}
37
 
38
void write_nvram_data(nvram_info_t data)
39
{
80 mjames 40
#if defined SEMIHOSTING
41
  printf("write\n");
42
#endif
43
 
66 mjames 44
  int base = 0;
45
 
46
  /* search blank */
47
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
48
  {
49
    // erase the entry just found
50
    if (NVRAM_Base[ptr].data.tag == data.data.tag)
51
    {
79 mjames 52
      // erase previous data, delete any entries that have a matching tag
80 mjames 53
#if defined SEMIHOSTING
54
      printf("marked erased %d\n", ptr);
55
#endif
56
      WriteNVRAM(ptr, MARKED_ERASED);
57
 
58
      base = ptr;
66 mjames 59
    }
60
  }
80 mjames 61
 
66 mjames 62
  // search forward for next erased or empty element, use it
63
  for (int offset = 1; offset < NVRAM_WORDS + 1; offset++)
64
  {
65
    int index = (base + offset) % NVRAM_WORDS;
66
    if (NVRAM_Base[index].u32 == MARKED_ERASED.u32 || NVRAM_Base[index].u32 == HARDWARE_ERASED.u32)
67
    {
68
      if (NVRAM_Base[index].u32 != HARDWARE_ERASED.u32)
80 mjames 69
      {
70
   #if defined SEMIHOSTING
71
       printf("erase %d\n", index);
72
#endif
73
 
74
        EraseNVRAM(index);
75
      }
76
        #if defined SEMIHOSTING
77
printf("write %d=%d\n", index, data.data.pos);
78
#endif
79
      WriteNVRAM(index, data);
66 mjames 80
      // now check to see if it actually went
81
      if (NVRAM_Base[index].u32 != data.u32)
82
      {
80 mjames 83
          #if defined SEMIHOSTING
84
        printf("unusable %d\n", index);
85
#endif
86
        WriteNVRAM(index, MARKED_UNUSABLE); // mark as neither unused or used
66 mjames 87
        continue;
88
      }
89
      return;
90
    }
91
  }
92
}
93
 
94
nvram_info_t *find_nvram_data(uint8_t searchTag)
80 mjames 95
{  
96
  #if defined SEMIHOSTING
97
  printf("find\n");
98
#endif
66 mjames 99
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
100
  {
101
    if (NVRAM_Base[ptr].data.tag == searchTag)
80 mjames 102
    {
103
        #if defined SEMIHOSTING
104
      printf("found %d=%d\n", ptr, NVRAM_Base[ptr].data.pos);
105
#endif
66 mjames 106
      return &NVRAM_Base[ptr];
80 mjames 107
    }
66 mjames 108
  }
109
  return NULL;
110
}
70 mjames 111
 
112
void erase_nvram()
113
{
80 mjames 114
    #if defined SEMIHOSTING
115
  printf("erase all\n");
116
#endif
70 mjames 117
  for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
80 mjames 118
    EraseNVRAM(ptr);
70 mjames 119
}