Subversion Repositories DashDisplay

Rev

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

  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.     {
  48.       // erase previous data, delete any entries that have a matching tag
  49.       WriteNVRAM(&NVRAM_Base[ptr], MARKED_ERASED);
  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;
  54.     }
  55.   }
  56.  
  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. }
  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. }