eeprom.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "ch.h"
  2. #include "hal.h"
  3. #include "eeprom.h"
  4. /* Defines */
  5. #define WRITE_KEY1 0x45670123
  6. #define WRITE_KEY2 0xCDEF89AB
  7. /* Functions */
  8. flash_result_t Flash_Write(uint64_t * data) {
  9. nt64_t val;
  10. flash_result_t res = Flash_Ok;
  11. uint32_t address = FLASH_PAGE_START;
  12. val.u64 = *data;
  13. // search first free cell
  14. while ((address < FLASH_PAGE_END) && ((*(__IO uint32_t*)address) != 0xffffffff)) {
  15. address += 8;
  16. }
  17. /* Authorize the FLASH Registers access */
  18. FLASH->KEYR = WRITE_KEY1;
  19. FLASH->KEYR = WRITE_KEY2;
  20. /* verify Flash is unlock */
  21. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U) {
  22. res = Flash_Error;
  23. } else {
  24. if (address > FLASH_PAGE_END) {
  25. // no space, format flash page
  26. uint32_t tmp;
  27. /* Get configuration register, then clear page number */
  28. tmp = (FLASH->CR & ~FLASH_CR_PNB);
  29. /* Set page number, Page Erase bit & Start bit */
  30. FLASH->CR = (tmp | (FLASH_CR_STRT | (FLASH_PAGE_NMB << FLASH_CR_PNB_Pos) | FLASH_CR_PER));
  31. /* Wait for end of page erase */
  32. while ((FLASH->CR & FLASH_CR_STRT) != 0) { __NOP(); }
  33. address = FLASH_PAGE_START;
  34. }
  35. // write data from address
  36. /* Set PG bit */
  37. FLASH->CR |= FLASH_CR_PG;
  38. /* Program first word */
  39. *(uint32_t *)address = val.u32[0];
  40. /* Barrier to ensure programming is performed in 2 steps, in right order
  41. (independently of compiler optimization behavior) */
  42. __ISB();
  43. /* Program second word */
  44. *(uint32_t *)(address + 4U) = val.u32[1];
  45. /* Set the LOCK Bit to lock the FLASH Registers access */
  46. SET_BIT(FLASH->CR, FLASH_CR_LOCK);
  47. }
  48. return res;
  49. }
  50. /**
  51. * @brief Read fom flash latest actual data.
  52. * @param data
  53. * @return flash_result_t
  54. */
  55. flash_result_t Flash_Read(uint64_t * data) {
  56. nt64_t val;
  57. flash_result_t res = Flash_Ok;
  58. uint32_t address = FLASH_PAGE_START;
  59. while ((address < FLASH_PAGE_END) && ((*(__IO uint32_t*)address) != 0xffffffff)) {
  60. val.u32[0] = (*(__IO uint32_t*)address);
  61. address += 4;
  62. val.u32[1] = (*(__IO uint32_t*)address);
  63. address += 4;
  64. }
  65. *data = val.u64;
  66. if (address == FLASH_PAGE_START) {
  67. res = Flash_PG_Clear;
  68. } else if (address > FLASH_PAGE_END) {
  69. res = Flash_PG_End;
  70. }
  71. return res;
  72. }