Subversion Repositories DashDisplay

Rev

Rev 66 | Rev 79 | 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
  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. }
  83.  
  84. void erase_nvram()
  85. {
  86.   /* search blank */
  87.   for (int ptr = 0; ptr < NVRAM_WORDS; ptr++)
  88.   {
  89.     EraseNVRAM(&NVRAM_Base[ptr]);
  90.   }
  91. }