Kaynağa Gözat

Added EEPROM emulation from STM32G0. Need to be adopted.

Vladimir N. Shilov 1 yıl önce
ebeveyn
işleme
ca25c0c128
2 değiştirilmiş dosya ile 125 ekleme ve 0 silme
  1. 95 0
      lib/eeprom/eeprom.c
  2. 30 0
      lib/eeprom/eeprom.h

+ 95 - 0
lib/eeprom/eeprom.c

@@ -0,0 +1,95 @@
+#include "ch.h"
+#include "hal.h"
+#include "eeprom.h"
+
+/* Defines */
+#define WRITE_KEY1  0x45670123
+#define WRITE_KEY2  0xCDEF89AB
+
+/* Functions */
+flash_result_t Flash_Write(uint64_t * data) {
+  nt64_t val;
+  flash_result_t res = Flash_Ok;
+  uint32_t address = FLASH_PAGE_START;
+
+  val.u64 = *data;
+
+  // search first free cell
+  while ((address < FLASH_PAGE_END) && ((*(__IO uint32_t*)address) != 0xffffffff)) {
+    address += 8;
+  }
+
+  /* Authorize the FLASH Registers access */
+  FLASH->KEYR = WRITE_KEY1;
+  FLASH->KEYR = WRITE_KEY2;
+
+  /* verify Flash is unlock */
+  if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U) {
+    res = Flash_Error;
+  } else {
+
+    if (address > FLASH_PAGE_END) {
+      // no space, format flash page
+      uint32_t tmp;
+
+      /* Get configuration register, then clear page number */
+      tmp = (FLASH->CR & ~FLASH_CR_PNB);
+
+      /* Set page number, Page Erase bit & Start bit */
+      FLASH->CR = (tmp | (FLASH_CR_STRT | (FLASH_PAGE_NMB <<  FLASH_CR_PNB_Pos) | FLASH_CR_PER));
+
+      /* Wait for end of page erase */
+      while ((FLASH->CR & FLASH_CR_STRT) != 0) { __NOP(); }
+
+      address = FLASH_PAGE_START;
+    }
+
+    // write data from address
+    /* Set PG bit */
+    FLASH->CR |= FLASH_CR_PG;
+
+    /* Program first word */
+    *(uint32_t *)address = val.u32[0];
+
+    /* Barrier to ensure programming is performed in 2 steps, in right order
+      (independently of compiler optimization behavior) */
+    __ISB();
+
+    /* Program second word */
+    *(uint32_t *)(address + 4U) = val.u32[1];
+
+    /* Set the LOCK Bit to lock the FLASH Registers access */
+    SET_BIT(FLASH->CR, FLASH_CR_LOCK);
+
+  }
+
+  return res;
+}
+
+/**
+ * @brief Read fom flash latest actual data.
+ * @param data 
+ * @return flash_result_t 
+ */
+flash_result_t Flash_Read(uint64_t * data) {
+  nt64_t val;
+  flash_result_t res = Flash_Ok;
+  uint32_t address = FLASH_PAGE_START;
+
+  while ((address < FLASH_PAGE_END) && ((*(__IO uint32_t*)address) != 0xffffffff)) {
+    val.u32[0] = (*(__IO uint32_t*)address);
+    address += 4;
+    val.u32[1] = (*(__IO uint32_t*)address);
+    address += 4;
+  }
+
+  *data = val.u64;
+
+  if (address == FLASH_PAGE_START) {
+    res = Flash_PG_Clear;
+  } else if (address > FLASH_PAGE_END) {
+    res = Flash_PG_End;
+  }
+
+  return res;
+}

+ 30 - 0
lib/eeprom/eeprom.h

@@ -0,0 +1,30 @@
+#pragma once
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+/* Type defs */
+typedef union {
+  uint64_t  u64;
+  int64_t   i64;
+  uint32_t  u32[2];
+  int32_t   i32[2];
+} nt64_t;
+
+typedef enum {
+  Flash_Ok = 0,
+  Flash_Error = 1,
+  Flash_PG_End = 2,
+  Flash_PG_Clear = 3
+} flash_result_t;
+
+/* Defines */
+#define FLASH_PAGE_START  0x0800F800
+#define FLASH_PAGE_END    0x0800FFF8
+#define FLASH_PAGE_NMB    31
+#define FLASH_PAGE_NUM    1
+
+/* Functions prototypes */
+flash_result_t Flash_Write(uint64_t * data);
+flash_result_t Flash_Read(uint64_t * data);
+
+#endif /* __EEPROM_H__ */