Subversion Repositories DashDisplay

Rev

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