diff --git a/Flash/FlashReadWrite_AssemblyAPI/Driver/__driver_Flash_API.h b/Flash/FlashReadWrite_AssemblyAPI/Driver/__driver_Flash_API.h
index 4f4aac677867a5cb23bc57ac98a52ac531f96f59..d0a6d58f57ab7ca0104a789f2cfe8c75eb49025c 100644
--- a/Flash/FlashReadWrite_AssemblyAPI/Driver/__driver_Flash_API.h
+++ b/Flash/FlashReadWrite_AssemblyAPI/Driver/__driver_Flash_API.h
@@ -67,11 +67,11 @@ unsigned int __FLASH_Read__(unsigned int address,unsigned int length,unsigned i
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
unsigned int __FLASH_UNLOCK_FUNCTION__(volatile unsigned int key,volatile unsigned int isopen);
-unsigned int __FLASH_Erase__(volatile unsigned key,volatile unsigned int WritrAddr,
+unsigned int __FLASH_Erase__(volatile unsigned key,volatile unsigned int WriteAddr,
volatile unsigned int DataLength);
-unsigned int __FLASH_Program__(volatile unsigned int key,volatile unsigned int WritrAddr,
+unsigned int __FLASH_Program__(volatile unsigned int key,volatile unsigned int WriteAddr,
volatile unsigned int DataLength,unsigned int WriteData[]);
-unsigned int __FLASH_Program_NBytes__(volatile unsigned int key,volatile unsigned int WritrAddr,
+unsigned int __FLASH_Program_NBytes__(volatile unsigned int key,volatile unsigned int WriteAddr,
volatile unsigned int DataLength,unsigned int WriteData[]);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/FlashEEPROMEmulation/.cproject b/FlashEEPROMEmulation/.cproject
new file mode 100644
index 0000000000000000000000000000000000000000..cb5b0cfff2336f82c8ad75a20cac2784f03a763f
--- /dev/null
+++ b/FlashEEPROMEmulation/.cproject
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FlashEEPROMEmulation/.project b/FlashEEPROMEmulation/.project
new file mode 100644
index 0000000000000000000000000000000000000000..c772c1359019cd1e7e192dfdd821f2d80033615a
--- /dev/null
+++ b/FlashEEPROMEmulation/.project
@@ -0,0 +1,83 @@
+
+
+ FlashEEPROMEmulation
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.autoBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.buildArguments
+ -k -j
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ gmake
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/A156_Project_Templete/Release}
+
+
+ org.eclipse.cdt.make.core.cleanBuildTarget
+ clean
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.fullBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.chipon32.chiponide.core.chiponnature
+
+
diff --git a/FlashEEPROMEmulation/.settings/com.chipon32.chiponide.core.prefs b/FlashEEPROMEmulation/.settings/com.chipon32.chiponide.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..10e05f664be06696112fde9a5538b29a71bb5ddd
--- /dev/null
+++ b/FlashEEPROMEmulation/.settings/com.chipon32.chiponide.core.prefs
@@ -0,0 +1,39 @@
+eclipse.preferences.version=1
+kf32target/ChipPower=3
+kf32target/IspMode=21436587
+kf32target/Protect=5A5AA5A5
+kf32target/chipName=KF32A136KQS
+kf32target/compilerType=ccr1_issue
+kf32target/debugMode=0
+kf32target/debugRunadd=0
+kf32target/debugSpeed=60
+kf32target/dflashuse=6384
+kf32target/diff0_address=0
+kf32target/diff0_enable=false
+kf32target/diff0_length=0
+kf32target/diff0_type=auto
+kf32target/diff1_address=0
+kf32target/diff1_enable=false
+kf32target/diff1_length=32768
+kf32target/diff1_type=range
+kf32target/diff2_address=32768
+kf32target/diff2_enable=false
+kf32target/diff2_length=32768
+kf32target/diff2_type=range
+kf32target/diff3_address=65536
+kf32target/diff3_enable=false
+kf32target/diff3_length=32768
+kf32target/diff3_type=range
+kf32target/diff4_address=98304
+kf32target/diff4_enable=false
+kf32target/diff4_length=32768
+kf32target/diff4_type=range
+kf32target/diff_download_config=false
+kf32target/dramuse=460
+kf32target/maintimeout=5
+kf32target/parsefilesizeandstack=0
+kf32target/rflashuse=10336
+kf32target/rramuse=6108
+kf32target/stepintimeout=5
+kf32target/stepouttimeout=5
+kf32target/steppasstimeout=5
diff --git a/FlashEEPROMEmulation/Driver/EmulatedEE.c b/FlashEEPROMEmulation/Driver/EmulatedEE.c
new file mode 100644
index 0000000000000000000000000000000000000000..e8b26bee626e35570a1786f2a787b3d61e5fd09c
--- /dev/null
+++ b/FlashEEPROMEmulation/Driver/EmulatedEE.c
@@ -0,0 +1,724 @@
+/******************************************************************************
+ * Shanghai ChipON Micro-Electronic Co.,Ltd
+ ******************************************************************************
+ * @File Name : EmulatedEE.c
+ * @Author : ChipON AE/FAE Group
+ * @Date : 2024-03-15
+ * @Version : V0.2.0
+ * @Description :
+ *****************************************************************************
+ * Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
+ * All rights reserved.
+ *
+ * This software is copyright protected and proprietary to
+ * Shanghai ChipON Micro-Electronic Co.,Ltd.
+ ******************************************************************************/
+
+/******************************************************************************
+ * QAC Warnings
+ ******************************************************************************/
+/**
+ * @page QAC Warnings
+ *
+ */
+/* PRQA S 0310 EOF #Casting to different object pointer type. */
+/* PRQA S 0306 EOF #Cast between a pointer to object and an integral type. */
+/******************************************************************************
+ * Include Files
+ ******************************************************************************/
+#include
+#include
+#include "EmulatedEE.h"
+#include "__driver_Flash_API.h"
+#if EE_USE_FLS_API
+#include "kf32a1x6_hli_fls.h"
+#endif
+
+#define EE_PAGE_NONE ((uint32_t)0x0FFFFU) /*!< no valid page found */
+#define EE_PAGE_ERASED ((uint32_t)0xFFFFFFFFU) /*!< page is in erased state */
+#define EE_PAGE_TRANSFER ((uint32_t)0xCCCCCCCCU) /*!< page is in transfer state */
+#define EE_PAGE_VALID ((uint32_t)0x00000000U) /*!< page is in valid state */
+
+void EmulatedEE_UpdatePageStatus(void);
+uint32_t EmulatedEE_CheckEEFormat(void);
+
+static uint32_t CurValidPage = EE_PAGE_NONE;
+static uint32_t CurValidPageInv = EE_PAGE_NONE;
+static uint32_t CurTansferPage = EE_PAGE_NONE;
+static uint32_t CurTansferPageInv = EE_PAGE_NONE;
+
+/**
+ * @brief:模拟EE擦除页
+ * @param[in] PageAddress
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_ErasePage(uint32_t PageAddress)
+{
+ uint32_t i = 0U;
+ uint32_t kvEraseAddress = 0U;
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+ /* PRQA S 2877 ++ #This loop will never be executed more than once. */
+ /* erase one or more sectors */
+ for (i = 0; i < EE_SECTOR_NUM; i++)
+ {
+ /* calculate the erase address */
+ kvEraseAddress = PageAddress + (i * EE_SECTOR_SIZE);
+#if EE_USE_FLS_API
+ kvFlashStatus = (uint32_t)HLI_Fls_EraseSector(kvEraseAddress, EE_SECTOR_SIZE);
+ (kvFlashStatus == HLI_FLS_STATUS_OK) ? (kvFlashStatus = CMD_SUCCESS) : (kvFlashStatus = CMD_ERROR);
+
+#else
+
+ /* erase sector */
+ kvFlashStatus = __FLASH_Erase__(Function_Parameter_Validate, kvEraseAddress, EE_SECTOR_SIZE);
+#endif
+
+ if (kvFlashStatus != CMD_SUCCESS)
+ {
+ break;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ return kvFlashStatus;
+ /* PRQA S 2877 -- #This loop will never be executed more than once. */
+}
+
+static inline uint32_t EmulatedEE_WriteFlashData(uint32_t WriteAddress, uint32_t Len, uint32_t *data)
+{
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+#if EE_USE_FLS_API
+ kvFlashStatus = (uint32_t)HLI_Fls_WriteMinimumWriteableBytes(WriteAddress, Len, (uint8_t *)data);
+ (kvFlashStatus == HLI_FLS_STATUS_OK) ? (kvFlashStatus = CMD_SUCCESS) : (kvFlashStatus = CMD_ERROR);
+#else
+ /* write */
+ kvFlashStatus = __FLASH_Program_NBytes__(Function_Parameter_Validate, WriteAddress, Len, data);
+#endif
+ return kvFlashStatus;
+}
+/**
+ * @brief: 模拟EE获取有效页
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_GetValidPage(void)
+{
+ if ((CurValidPage + CurValidPageInv) == 0xFFFFFFFFU)
+ {
+ return CurValidPage;
+ }
+ else
+ {
+ if (EmulatedEE_CheckEEFormat() == 0U)
+ {
+ EmulatedEE_UpdatePageStatus();
+ return CurValidPage;
+ }
+ else
+ {
+ return EE_PAGE_NONE;
+ }
+ }
+}
+
+/**
+ * @brief: 模拟EE获取可写Page
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_GetWriteablePage(void)
+{
+ if (((CurValidPage + CurValidPageInv) == 0xFFFFFFFFU) && ((CurTansferPage + CurTansferPageInv) == 0xFFFFFFFFU))
+ {
+ if (CurTansferPage != EE_PAGE_NONE)
+ {
+ return CurTansferPage;
+ }
+ else if (CurValidPage != EE_PAGE_NONE)
+ {
+ return CurValidPage;
+ }
+ else
+ {
+ return EE_PAGE_NONE;
+ }
+ }
+ else
+ {
+ if (EmulatedEE_CheckEEFormat() == 0U)
+ {
+ EmulatedEE_UpdatePageStatus();
+ return CurValidPage;
+ }
+ else
+ {
+ return EE_PAGE_NONE;
+ }
+ }
+}
+
+/**
+ * @brief: 模拟EE写Flash数据
+ * @param[in] Address
+ * @param[in] Data
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_DirectHwWrite(uint32_t Address, uint32_t Data)
+{
+ uint32_t kvValidPage = EE_PAGE_NONE;
+ uint32_t kvFindAddress = 0U;
+ uint32_t kvEndAddress = 0U;
+ uint32_t kvFlashStatus = 0U;
+
+ /* get the valid page */
+ kvValidPage = EmulatedEE_GetWriteablePage();
+
+ if (kvValidPage == EE_PAGE_NONE)
+ {
+ return 0xFFU;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* find address calculation */
+ kvFindAddress = EE_BASE_ADDRESS + (kvValidPage * EE_PAGE_SIZE) + 8U;
+
+ /* end address calculation */
+ kvEndAddress = EE_BASE_ADDRESS + (kvValidPage * EE_PAGE_SIZE) + EE_PAGE_SIZE;
+
+ while (kvFindAddress < kvEndAddress)
+ {
+ /* find addresses without Data */
+ if ((*(uint32_t *)kvFindAddress) == 0xFFFFFFFFU)
+ {
+ uint32_t kvTempData[2U] = {0U, 0U};
+ kvTempData[0U] = Data;
+ kvTempData[1U] = Address;
+
+ /* write Data to flash */
+ kvFlashStatus = EmulatedEE_WriteFlashData(kvFindAddress, 8U, (uint32_t *)&kvTempData);
+
+ return kvFlashStatus;
+ }
+ else
+ {
+ kvFindAddress += 8U;
+ }
+ }
+
+ return kvFlashStatus;
+}
+
+/**
+ * @brief: 模拟EE复制有效数据到下一页
+ * @param[in] ValidPage
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_CopyDataToNewPage(uint32_t ValidPage)
+{
+ uint32_t kvData = 0U;
+ uint32_t kvIdx = 0U;
+ uint32_t kvFullPageAddress = 0U;
+ uint32_t kvEmptyPageAddress = 0U;
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+ if (ValidPage != EE_PAGE_NONE)
+ {
+ kvEmptyPageAddress = (EE_BASE_ADDRESS + (EE_PAGE_SIZE * ((ValidPage + 1) % EE_PAGE_NUM)));
+
+ kvFullPageAddress = (EE_BASE_ADDRESS + (EE_PAGE_SIZE * ValidPage));
+ }
+ else
+ {
+ return 0xFFU;
+ }
+
+ uint32_t kvTempData[2U] = {0U, 0U};
+ kvTempData[0U] = EE_PAGE_TRANSFER;
+
+ /* change the status of the empty page to TRANSFER */
+
+ if ((kvFlashStatus = EmulatedEE_WriteFlashData(kvEmptyPageAddress, 8U, (uint32_t *)&kvTempData)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ EmulatedEE_UpdatePageStatus();
+
+ for (kvIdx = 0U; kvIdx < EE_PARA_MAX_NUMBER; kvIdx++)
+ {
+ /* find valid variables */
+ if (EmulatedEE_ReadData(kvIdx * 4U, &kvData) == 0U)
+ {
+
+ /* store variable to new page */
+ if ((kvFlashStatus = EmulatedEE_DirectHwWrite(kvIdx * 4U, kvData)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ /* erase old page */
+ if ((kvFlashStatus = EmulatedEE_ErasePage(kvFullPageAddress)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ kvTempData[0U] = EE_PAGE_VALID;
+
+ /* change the status of the empty page to VALID */
+
+ if ((kvFlashStatus = EmulatedEE_WriteFlashData(kvEmptyPageAddress, 8U, (uint32_t *)&kvTempData)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ EmulatedEE_UpdatePageStatus();
+
+ return kvFlashStatus;
+}
+
+/**
+ * @brief 模拟EE空间格式化
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_FormatSpace(void)
+{
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+ for (uint32_t i = 0U; i < EE_PAGE_NUM; i++)
+ {
+ uint32_t kvEraseAddress = (EE_BASE_ADDRESS + (EE_PAGE_SIZE * i));
+ /* erase page */
+ if ((kvFlashStatus = EmulatedEE_ErasePage(kvEraseAddress)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ {
+ uint32_t kvTempData[2U] = {0U, 0U};
+ kvTempData[0U] = EE_PAGE_VALID;
+ /* mark the status of page 0 as VALID */
+ kvFlashStatus = EmulatedEE_WriteFlashData(EE_BASE_ADDRESS, 8U, (uint32_t *)&kvTempData);
+ }
+
+ return kvFlashStatus;
+}
+
+/**
+ * @brief: 确认是否为模拟EE格式
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_CheckEEFormat(void)
+{
+ uint32_t kvPageStatus = EE_PAGE_ERASED;
+ uint32_t kvValidPage = EE_PAGE_NONE;
+ uint32_t kvTransferPage = EE_PAGE_NONE;
+
+ for (uint32_t i = 0U; i < EE_PAGE_NUM; i++)
+ {
+ kvPageStatus = (*(uint32_t *)(EE_BASE_ADDRESS + (EE_PAGE_SIZE * i)));
+
+ if ((kvPageStatus != EE_PAGE_ERASED) && (kvPageStatus != EE_PAGE_TRANSFER) && (kvPageStatus != EE_PAGE_VALID))
+ {
+ return 1U;
+ }
+ else if (kvPageStatus == EE_PAGE_VALID)
+ {
+ if (kvValidPage == EE_PAGE_NONE)
+ {
+ kvValidPage = i;
+ }
+ else
+ {
+ return 1U;
+ }
+ }
+ else if (kvPageStatus == EE_PAGE_TRANSFER)
+ {
+ if (kvTransferPage == EE_PAGE_NONE)
+ {
+ kvTransferPage = i;
+ }
+ else
+ {
+ return 1U;
+ }
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ if ((kvValidPage == EE_PAGE_NONE) && (kvTransferPage == EE_PAGE_NONE))
+ {
+ return 1U;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* the format is correct */
+ return 0U;
+}
+
+/**
+ * @brief: 模拟EE确认是否写满
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_CheckPageDateFull(void)
+{
+ uint32_t kvValidPage = 0U;
+ uint32_t kvEndAddress = 0U;
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+ /* get the valid page */
+ kvValidPage = EmulatedEE_GetValidPage();
+
+ if (kvValidPage == EE_PAGE_NONE)
+ {
+ return 0xFFU;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* end address calculation */
+ kvEndAddress = EE_BASE_ADDRESS + (kvValidPage * EE_PAGE_SIZE) + EE_PAGE_SIZE;
+
+ /* check if the page is full */
+ if ((*(uint32_t *)(kvEndAddress - 8U)) != 0xFFFFFFFFU)
+ {
+ /* when the page is full, transfer the kvData to erase page */
+ if ((kvFlashStatus = EmulatedEE_CopyDataToNewPage(kvValidPage)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* page full check ok */
+ return 0U;
+}
+
+/**
+ * @brief: 模拟EE初始化状态-只有Transfer页
+ * @param[in] TransferPage
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_InitStateOnlyTransfer(uint32_t TransferPage)
+{
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+ uint32_t kvTransferPageAddress = (EE_BASE_ADDRESS + (EE_PAGE_SIZE * TransferPage));
+
+ uint32_t kvTempData[2U] = {0U, 0U};
+ kvTempData[0U] = EE_PAGE_VALID;
+
+ kvFlashStatus = EmulatedEE_WriteFlashData(kvTransferPageAddress, 8, (uint32_t *)&kvTempData);
+
+ EmulatedEE_UpdatePageStatus();
+ return kvFlashStatus;
+}
+
+/**
+ * @brief: 模拟EE初始化状态- 同时存在Valid,Transfer页
+ * @param[in] ValidPage
+ * @param[in] TransferPage
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_InitStateValidTransfer(uint32_t ValidPage, uint32_t TransferPage)
+{
+ uint32_t kvErasePageAddress = EE_BASE_ADDRESS + (EE_PAGE_SIZE * TransferPage);
+
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+ /* erase the transfer state page */
+ if ((kvFlashStatus = EmulatedEE_ErasePage(kvErasePageAddress)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ EmulatedEE_UpdatePageStatus();
+
+ /* retransmit kvData */
+ return EmulatedEE_CopyDataToNewPage(ValidPage);
+}
+
+/**
+ * @brief: 模拟EE初始化ram
+ * @retval uint32_t
+ */
+void EmulatedEE_UpdatePageStatus(void)
+{
+ uint32_t kvPageStatus = EE_PAGE_ERASED;
+
+ for (uint32_t i = 0U; i < EE_PAGE_NUM; i++)
+ {
+ kvPageStatus = (*(uint32_t *)(EE_BASE_ADDRESS + (EE_PAGE_SIZE * i)));
+ if (kvPageStatus == EE_PAGE_VALID)
+ {
+ CurValidPage = i;
+ }
+ else if (kvPageStatus == EE_PAGE_TRANSFER)
+ {
+ CurTansferPage = i;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ CurValidPageInv = ~CurValidPage;
+ CurTansferPageInv = ~CurTansferPage;
+}
+
+/**
+ * @brief: 模拟EE初始化
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_Init(void)
+{
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+ uint32_t kvPageStatus = EE_PAGE_ERASED;
+ uint32_t kvValidPage = EE_PAGE_NONE;
+ uint32_t kvTransferPage = EE_PAGE_NONE;
+
+ /* format validity check */
+ if (EmulatedEE_CheckEEFormat() != 0U)
+ {
+ /* if the format is invalid, reformat */
+ if ((kvFlashStatus = EmulatedEE_FormatSpace()) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ EmulatedEE_UpdatePageStatus();
+
+ for (uint32_t i = 0U; i < EE_PAGE_NUM; i++)
+ {
+ kvPageStatus = (*(uint32_t *)(EE_BASE_ADDRESS + (EE_PAGE_SIZE * i)));
+ if (kvPageStatus == EE_PAGE_VALID)
+ {
+ kvValidPage = i;
+ }
+ else if (kvPageStatus == EE_PAGE_TRANSFER)
+ {
+ kvTransferPage = i;
+ }
+ else
+ {
+ uint32_t kvEraseAddress = (EE_BASE_ADDRESS + (EE_PAGE_SIZE * i));
+ if ((kvFlashStatus = EmulatedEE_ErasePage(kvEraseAddress)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ }
+
+ if ((kvValidPage == EE_PAGE_NONE) && (kvTransferPage != EE_PAGE_NONE))
+ {
+ if ((kvFlashStatus = EmulatedEE_InitStateOnlyTransfer(kvTransferPage)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ else if ((kvValidPage != EE_PAGE_NONE) && (kvTransferPage != EE_PAGE_NONE))
+ {
+ if ((kvFlashStatus = EmulatedEE_InitStateValidTransfer(kvValidPage, kvTransferPage)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* check if the page is full, when the page is full, transfer the kvData to erase page */
+ if ((kvFlashStatus = EmulatedEE_CheckPageDateFull()) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ return kvFlashStatus;
+}
+
+/**
+ * @brief: 模拟EE写数据
+ * @param[in] Address EE的虚拟地址
+ * @param[in] Data 4字节数据
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_WriteData(uint32_t Address, uint32_t Data)
+{
+ uint32_t kvFlashStatus = CMD_SUCCESS;
+
+ if (((Address & 0x3U) > 0U) || (Address > ((EE_PAGE_SIZE / 2U) - 5U)))
+ {
+ return PARAM_ERROR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* check if the page is full, when the page is full, transfer the kvData to erase page */
+ if ((kvFlashStatus = EmulatedEE_CheckPageDateFull()) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* write kvData to flash */
+ if ((kvFlashStatus = EmulatedEE_DirectHwWrite(Address, Data)) != CMD_SUCCESS)
+ {
+ return kvFlashStatus;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ return kvFlashStatus;
+}
+
+/**
+ * @brief 模拟EE读取数据
+ * @param[in] Address EE的虚拟地址
+ * @param[in] Data 4字节数据
+ * @retval uint32_t
+ */
+uint32_t EmulatedEE_ReadData(uint32_t Address, uint32_t *Data)
+{
+ uint32_t kvValidPage = EE_PAGE_NONE;
+ uint32_t kvDataAddress = 0U;
+ uint32_t kvFindAddress = 0U;
+ uint32_t kvStartAddress = 0U;
+
+ if (((Address & 0x3U) > 0U) && (Address > ((EE_PAGE_SIZE / 2U) - 5U)))
+ {
+ return PARAM_ERROR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* get the valid page */
+ kvValidPage = EmulatedEE_GetValidPage();
+
+ if (kvValidPage == EE_PAGE_NONE)
+ {
+ return EE_PAGE_NONE;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ /* start address calculation */
+ kvStartAddress = EE_BASE_ADDRESS + (kvValidPage * EE_PAGE_SIZE) + 8U;
+
+ /* find address calculation */
+ kvFindAddress = ((EE_BASE_ADDRESS + (kvValidPage * EE_PAGE_SIZE)) + EE_PAGE_SIZE) - 4U;
+
+ while (kvFindAddress > kvStartAddress)
+ {
+ /* read variable address */
+ kvDataAddress = (*(uint16_t *)kvFindAddress);
+
+ /* variable address matching */
+ if (Address == kvDataAddress)
+ {
+
+ /* read Data */
+ *Data = (*(uint32_t *)(kvFindAddress - 4U));
+
+ /* kvData successfully read */
+ return 0U;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ /* find address - 8 */
+ kvFindAddress -= 8U;
+ }
+
+ /* failed to read kvData */
+ return 1U;
+}
diff --git a/FlashEEPROMEmulation/Driver/EmulatedEE.h b/FlashEEPROMEmulation/Driver/EmulatedEE.h
new file mode 100644
index 0000000000000000000000000000000000000000..77314ac8dfef948678265fba35d747e7bbd94d37
--- /dev/null
+++ b/FlashEEPROMEmulation/Driver/EmulatedEE.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * Shanghai ChipON Micro-Electronic Co.,Ltd
+ ******************************************************************************
+ * @File Name : EmulatedEE.h
+ * @Author : ChipON AE/FAE Group
+ * @Date : 2024-03-15
+ * @Version : V0.2.0
+ * @Description :
+ *****************************************************************************
+ * Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
+ * All rights reserved.
+ *
+ * This software is copyright protected and proprietary to
+ * Shanghai ChipON Micro-Electronic Co.,Ltd.
+ ******************************************************************************/
+
+#ifndef EMULATED_EE_H
+#define EMULATED_EE_H
+
+#include "__Kungfu32_chipmodel_define.h"
+#include
+
+/* Flash sector number */
+/* KF32A136 */
+#if defined(KF32A136KQT) || defined(KF32A136KQS) || defined(KF32A136KNP)
+#define EE_FLASH_SECTOR_NUM (256U)
+#elif defined(KF32A136IQT) || defined(KF32A136IQS) || defined(KF32A136INP)
+#define EE_FLASH_SECTOR_NUM (128U)
+#elif defined(KF32A136GNP) || defined(KF32A136GQS)
+#define EE_FLASH_SECTOR_NUM (64U)
+#else
+#error "Please define the chip model"
+#endif
+
+/* User-modifiable parameters */
+#define EE_SECTOR_NUM ((uint32_t)1U) /*!< sector number, support multiple sectors to from 1 page */
+#define EE_PAGE_NUM \
+ ((uint32_t)2U) /*!< page number, Increase total read and write lifespan by increasing the number of flash pages */
+
+/* Non-user-modifiable parameters */
+#define EE_USE_FLS_API (false)
+
+#define EE_SECTOR_SIZE ((uint32_t)(1024U)) /*!< sector size */
+
+#define EE_PAGE_SIZE ((uint32_t)(EE_SECTOR_NUM * EE_SECTOR_SIZE)) /*!< page size */
+
+#define EE_BASE_ADDRESS \
+ ((uint32_t)((EE_FLASH_SECTOR_NUM * EE_SECTOR_SIZE) - (EE_PAGE_SIZE * EE_PAGE_NUM))) /*!< eeprom base address */
+
+#define EE_PARA_MAX_NUMBER \
+ ((uint32_t)((EE_PAGE_SIZE / 8U) - 1U)) /*!< maximum number of variables that can be stored \
+ */
+
+uint32_t EmulatedEE_ErasePage(uint32_t PageAddress);
+uint32_t EmulatedEE_GetValidPage(void);
+uint32_t EmulatedEE_GetWriteablePage(void);
+uint32_t EmulatedEE_DirectHwWrite(uint32_t Address, uint32_t Data);
+uint32_t EmulatedEE_CopyDataToNewPage(uint32_t ValidPage);
+uint32_t EmulatedEE_FormatSpace(void);
+uint32_t EmulatedEE_CheckPageDateFull(void);
+uint32_t EmulatedEE_InitStateOnlyTransfer(uint32_t TransferPage);
+uint32_t EmulatedEE_InitStateValidTransfer(uint32_t ValidPage, uint32_t TransferPage);
+uint32_t EmulatedEE_ReadData(uint32_t Address, uint32_t *Data);
+uint32_t EmulatedEE_WriteData(uint32_t Address, uint32_t Data);
+uint32_t EmulatedEE_Init(void);
+
+#endif
diff --git a/FlashEEPROMEmulation/Driver/__driver_Flash_API.S b/FlashEEPROMEmulation/Driver/__driver_Flash_API.S
new file mode 100644
index 0000000000000000000000000000000000000000..2745d192e8b5c4dbc04398fad1d8d0a1c742c7d2
--- /dev/null
+++ b/FlashEEPROMEmulation/Driver/__driver_Flash_API.S
@@ -0,0 +1,898 @@
+
+//Lib_Version, "V2.0.2.230925"
+ .text
+//###############################################################################
+ .EQU FLASH_WORK_CLR, 0x50AF0007
+ .EQU FLASH_WORK_CMD, 0x50AF0001
+
+ .EQU Function_Parameter_Validate, 0x5A5A6688
+ .EQU CMD_SUCCESS, 0x00
+ .EQU CMD_ERROR, 0xAA
+ .EQU PARAM_ERROR, 0x0C
+ .EQU TimeOutCountValue, 50000
+//###############################################################################
+.macro __FLASH_Function__ name
+ .section .text$\name
+ .align 1
+ .export \name
+ .type \name, @function
+ .func \name
+\name:
+.endm
+
+.macro __RAM_Function__ name
+ .section .indata$\name
+ .align 1
+ .export \name
+ .type \name, @function
+ .func \name
+\name:
+.endm
+
+.macro __End_Function__ name
+ .size \name, .-\name
+ .endfunc
+.endm
+//###############################################################################
+ .SET __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN , 0
+ .SET __FLASH_Driver_Use_LOCK_UNLOCK_Function, 0
+
+//###############################################################################
+.if 0
+ .SET __FLASH_API_LIKE_A150, 1
+.else
+.if 1
+ .SET __FLASH_API_LIKE_A156, 1
+.else
+ .SET __FLASH_API_LIKE_A158, 1
+.endif
+.endif
+// .if __FLASH_API_LIKE_A158
+.if 0
+ .EQU __FLASH_MAX_SIZE__, (2048*1024-1)
+.else
+ .EQU __FLASH_MAX_SIZE__, (512*1024-1)
+.endif
+ .EQU __FLASH_MIN_SIZE__, (0) //erase from address 0
+
+
+//###############################################################################
+
+.ifdef __FLASH_API_LIKE_A150
+ .SET FLASH_KEY1, 0x87654321
+ .SET FLASH_KEY2, 0x05040302
+ .SET FLASH_KEY3, 0x789ABCDE
+ .SET FLASH_KEY4, 0x16151413
+.else
+.ifdef __FLASH_API_LIKE_A156
+ .SET FLASH_KEY1, 0x27654330;
+ .SET FLASH_KEY2, 0x81040304
+ .SET FLASH_KEY3, 0x7896dcde
+ .SET FLASH_KEY4, 0x92151407
+.else
+.ifdef __FLASH_API_LIKE_A158
+ .SET FLASH_KEY1, 0x27654330;
+ .SET FLASH_KEY2, 0x81040304
+ .SET FLASH_KEY3, 0x7896dcde
+ .SET FLASH_KEY4, 0x92151407
+.else
+ .error "Err config"
+.endif
+.endif
+.endif
+//###############################################################################
+ .SET FLASH_ISPCON0 , 0x40200100
+ .SET FLASH_ISPCON1 , 0x40200104
+ .SET FLASH_ISPCMD , 0x40200108
+ .SET FLASH_ISPTRG , 0x4020010C
+ .SET FLASH_ISPADDR , 0x4020011C
+ .SET FLASH_STATE , 0x40200120
+ .SET FLASH_NVMUNLOCK , 0x40200128
+ .SET FLASH_PROUNLOCK , 0x4020012C
+###############################################################################
+ __RAM_Function__ __FLASH_UNLOCK_FUNCTION__
+ SUB sp,#32
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ ST.w [sp+#0],r0
+ LD R4,#FLASH_KEY1
+ ST.w [sp+#1],R4
+
+ ST.w [sp+#2],r0
+ LD R4,#FLASH_KEY2
+ ST.w [sp+#3],R4
+
+ ST.w [sp+#4],r1
+ LD R4,#FLASH_KEY3
+ ST.w [sp+#5],R4
+
+ ST.w [sp+#6],r1
+ LD R4,#FLASH_KEY4
+ ST.w [sp+#7],R4
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key)
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_UNLOCK
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_UNLOCK
+ //++++++++++++++++++++++++++++++++++++++++++++++if(isopen == 0xAA55)
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_UNLOCK
+ MOV R2,#0xAA55
+ CMP R0,R2
+ JZ Cond_OPEN_IN_UNLOCK
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ JMP Return_CMD_SUCCESS_IN_UNLOCK
+Cond_OPEN_IN_UNLOCK:
+ //++++++++++++++++++++++++++++++++++++++++++++++ key1 key2
+ LD.w r0,[SP + #1]
+ LD.w r1,[SP + #3]
+ LD r2,#FLASH_NVMUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_UNLOCK
+ MOV R2,#0xAA55
+ CMP R0,R2
+ JNZ Return_CMD_SUCCESS_IN_UNLOCK
+ //++++++++++++++++++++++++++++++++++++++++++++++ key3 key4
+ LD.w r0,[SP + #5]
+ LD.w r1,[SP + #7]
+ LD r2,#FLASH_PROUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_UNLOCK
+ MOV R2,#0xAA55
+ CMP R0,R2
+ JNZ Return_CMD_SUCCESS_IN_UNLOCK
+ //++++++++++++++++++++++++++++++++++++++++++++++
+Return_CMD_SUCCESS_IN_UNLOCK:
+ MOV R0,#0
+ JMP Return_PUSH_POP_IN_UNLOCK
+Return_PARAM_ERROR_IN_UNLOCK:
+ MOV R0,#PARAM_ERROR
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+//++++++++++++++++++++++++++++++++++++++++++++++
+Return_PUSH_POP_IN_UNLOCK:
+ ST.w [SP+#0],R0
+ ST.w [SP+#1],R0
+ ST.w [SP+#2],R0
+ ST.w [SP+#3],R0
+ ST.w [SP+#4],R0
+ ST.w [SP+#5],R0
+ ST.w [SP+#6],R0
+ ST.w [SP+#7],R0
+//++++++++++++++++++++++++++++++++++++++++++++++
+ ADD sp,#32
+ JMP lr
+ __End_Function__ __FLASH_UNLOCK_FUNCTION__
+
+//#########################################################################################
+ __RAM_Function__ __FLASH_Read_Byte__
+ LD.b r0,[r0]
+ JMP lr
+ __End_Function__ __FLASH_Read_Byte__
+//#########################################################################################
+ __RAM_Function__ __FLASH_Read_WORD__
+ LD.w r0,[r0]
+ JMP lr
+ __End_Function__ __FLASH_Read_WORD__
+//#########################################################################################
+ __RAM_Function__ __FLASH_Read_One__
+ LD.w r0,[r0]
+ JMP lr
+ __End_Function__ __FLASH_Read_One__
+#########################################################################################
+ __RAM_Function__ __FLASH_Erase__
+ SUB sp,#40
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ ST.w [sp+#0],r0
+ LD R4,#FLASH_KEY1
+ ST.w [sp+#1],R4
+
+ ST.w [sp+#2],r0
+ LD R4,#FLASH_KEY2
+ ST.w [sp+#3],R4
+
+ ST.w [sp+#4],r1
+ LD R4,#FLASH_KEY3
+ ST.w [sp+#5],R4
+
+ ST.w [sp+#6],r1
+ LD R4,#FLASH_KEY4
+ ST.w [sp+#7],R4
+
+ ST.w [sp+#8],r2
+ ST.w [sp+#9],r2
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key)
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ key1 key2
+ LD.w r0,[SP + #1]
+ LD.w r1,[SP + #3]
+ LD r2,#FLASH_NVMUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++ address check
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R4,#__FLASH_MAX_SIZE__
+ CMP R0,R4
+ JHI Return_PARAM_ERROR_IN_ERASE
+ MOVL R4,#0x3FF
+ ANL R1,R4
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R4,#__FLASH_MIN_SIZE__
+ CMP R4,R0
+ JHI Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ len check
+ LD.w r0,[SP + #8]
+ LD.w r1,[SP + #9]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R4,#0
+ CMP R0,R4
+ JZ Return_PARAM_ERROR_IN_ERASE
+
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key){
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ key3 key4
+ LD.w r0,[SP + #5]
+ LD.w r1,[SP + #7]
+ LD r2,#FLASH_PROUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key){
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++
+.if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ DSI
+.endif
+ //++++++++++++++++++++++++++++++++++++++++++++++ length 1K/2K aligned
+ERASE_NEXT_PAGE_IN_ERASE:
+ LD.w r0,[SP + #8]
+ LD.w r1,[SP + #9]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+.ifdef __FLASH_API_LIKE_A158
+ MOVL R2,#0x07FF
+.else
+ MOVL R2,#0x03FF
+.endif
+ ANL R2,R0,R2
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ address set
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R4,#__FLASH_MAX_SIZE__
+ CMP R0,R4
+ JHI Return_PARAM_ERROR_IN_ERASE
+ MOVL R4,#0x3FF
+ ANL R4,R1,R4
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ LD R4,#__FLASH_MIN_SIZE__
+ CMP R4,R0
+ JHI Return_PARAM_ERROR_IN_ERASE
+
+ LD R2,#FLASH_ISPADDR
+ ST.w [R2],R0
+ LD.w R3,[R2]
+ CMP R3,R1
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ set cmd
+ LD R2,#FLASH_ISPCMD
+ MOVL R0,#0x7FB
+ ST.w [R2],R0
+ LD.w R3,[R2]
+ CMP R3,R0
+ JNZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ run cmd
+ LD R2,#FLASH_ISPTRG
+ LD R0,#FLASH_WORK_CMD
+ ST.w [R2],R0
+ NOP
+ NOP
+ NOP
+ //++++++++++++++++++++++++++++++++++++++++++++++ wait event
+ LD R4,#TimeOutCountValue
+ERASE_WAIT_BIT_2_TBIT:
+ LD R3,#FLASH_STATE
+ LD.w R1,[R3]
+ JB R1,#2
+ JMP ERASE_END_BIT_2_TBIT
+ SUB R4,#1
+ JZ ERASE_END_BIT_2_TBIT
+ JMP ERASE_WAIT_BIT_2_TBIT
+ //++++++++++++++++++++++++++++++++++++++++++++++ is timeout find
+ERASE_END_BIT_2_TBIT:
+ CMP R4,#0
+ JZ Return_PARAM_ERROR_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ for next
+ LD.w r0,[SP + #4]
+ MOV R1,#1
+.ifdef __FLASH_API_LIKE_A158
+ LSL R1,#11
+.else
+ LSL R1,#10
+.endif
+ ADD R0,R1
+ ST.w [SP+#4],R0
+ ST.w [SP+#6],R0
+
+ LD.w r0,[SP + #8]
+ SUB R0,R1
+ ST.w [SP + #8],R0
+ ST.w [SP + #9],R0
+
+ JHI ERASE_NEXT_PAGE_IN_ERASE
+ //++++++++++++++++++++++++++++++++++++++++++++++ ok
+ MOV R0,#0
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ //++++++++++++++++++++++++++++++++++++++++++++++ ng
+Return_CMD_SUCCESS_IN_ERASE:
+ MOV R0,#0
+ JMP Return_PUSH_POP_IN_ERASE
+Return_PARAM_ERROR_IN_ERASE:
+ MOV R0,#PARAM_ERROR
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+//++++++++++++++++++++++++++++++++++++++++++++++
+Return_PUSH_POP_IN_ERASE:
+ //++++++++++++++++++++++++++++++++++++++++++++++
+.if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ ENI
+.endif
+ ST.w [SP+#0],R0
+ ST.w [SP+#1],R0
+ ST.w [SP+#2],R0
+ ST.w [SP+#3],R0
+ ST.w [SP+#4],R0
+ ST.w [SP+#5],R0
+ ST.w [SP+#6],R0
+ ST.w [SP+#7],R0
+//++++++++++++++++++++++++++++++++++++++++++++++
+ ADD sp,#40
+ JMP lr
+ __End_Function__ __FLASH_Erase__
+###########################################################################
+ __RAM_Function__ __FLASH_Program__
+ PUSH R5
+ SUB sp,#48
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ ST.w [sp+#0],r0
+ LD R4,#FLASH_KEY1
+ ST.w [sp+#1],R4
+
+ ST.w [sp+#2],r0
+ LD R4,#FLASH_KEY2
+ ST.w [sp+#3],R4
+
+ ST.w [sp+#4],r1
+ LD R4,#FLASH_KEY3
+ ST.w [sp+#5],R4
+
+ ST.w [sp+#6],r1
+ LD R4,#FLASH_KEY4
+ ST.w [sp+#7],R4
+
+ ST.w [sp+#8],r2
+ ST.w [sp+#9],r2
+ ST.w [sp+#10],r3
+ ST.w [sp+#11],r3
+ //++++++++++++++++++++++++++++++++++++++++++++++ clear syc
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ //++++++++++++++++++++++++++++++++++++++++++++++ address check
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ LD R4,#__FLASH_MAX_SIZE__
+ CMP R0,R4
+ JHI Return_PARAM_ERROR_IN_FAST
+ MOVL R4,#0x1FF
+ ANL R1,R4
+ JNZ Return_PARAM_ERROR_IN_FAST
+ LD R4,#__FLASH_MIN_SIZE__
+ CMP R4,R0
+ JHI Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++ len check
+ LD.w r0,[SP + #8]
+ LD.w r1,[SP + #9]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ LD R4,#0
+ CMP R0,R4
+ JZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key)
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++ key1 key2
+ LD.w r0,[SP + #1]
+ LD.w r1,[SP + #3]
+ LD r2,#FLASH_NVMUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key){
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++ key3 key4
+ LD.w r0,[SP + #5]
+ LD.w r1,[SP + #7]
+ LD r2,#FLASH_PROUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key){
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++ address re same check
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++ length 512/1024 aligned
+ LD.w r0,[SP + #8]
+ LD.w r1,[SP + #9]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+.ifdef __FLASH_API_LIKE_A158
+ MOVL R2,#0x03FF
+.else
+ MOVL R2,#0x01FF
+.endif
+ ANL R0,R2
+ JNZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++
+.if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ DSI
+.endif
+ //++++++++++++++++++++++++++++++++++++++++++++++ dwen bit 3 set
+ LD R2,#FLASH_ISPCON0
+ SET [R2],#3
+ LD.b R3,[R2]
+ MOV R2,#0x4B
+ CMP R3,R2
+ JNZ Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++ cmd page write
+ LD R2,#FLASH_ISPCMD
+ MOVL R0,#0x7e5
+ MOVL R1,#0x7e5
+ ST.w [R2],R0
+ LD.w R3,[R2]
+ CMP R3,R1
+ JZ Fast_Process_Start
+ //++ cmd failed
+ LD R2,#FLASH_ISPCON0
+ LD R0,#FLASH_WORK_CLR
+ ST.w [R2],R0
+ .if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ ENI
+ .endif
+ JMP Return_PARAM_ERROR_IN_FAST
+ //++++++++++++++++++++++++++++++++++++++++++++++
+Fast_Process_Start:
+ LD.w R0,[SP + #4]
+ LD.w R1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+
+ LD.w R1,[SP + #8]
+ LD.w R2,[SP + #9]
+ CMP R2,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+
+ LD.w R2,[SP + #10]
+ LD.w R3,[SP + #11]
+ CMP R2,R3
+ JNZ Return_PARAM_ERROR_IN_FAST
+
+ JMP FAST_FIRST_HALF_PAGE
+ //++++++++++++++++++++++++++++++++++++++++++++++
+FAST_NEXT_HALF_PAGE:
+ LD R3,#FLASH_ISPCMD
+ MOVL R4,#0x7e5
+ MOVL R5,#0x7e5
+ ST.w [R3],R4
+ LD.w R4,[R3]
+ CMP R4,R5
+ JNZ Return_PARAM_ERROR_IN_FAST
+
+FAST_FIRST_HALF_PAGE:
+ LD R3,#FLASH_ISPTRG
+ LD R4,#FLASH_WORK_CMD
+ ST.w [R3],R4
+ NOP
+ NOP
+ NOP
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ MOV R4,#64
+ //++++++++++++++++++++++++++++++++++++++++++++++
+Fast_DATE_TRAN:
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+.ifdef __FLASH_API_LIKE_A158
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+ SUB R1,#16
+.else
+ SUB R1,#8
+.endif
+ //---------------------------------------
+ LD R3,#TimeOutCountValue
+FAST_WAIT_BIT_3_TBUSY:
+ LD R5,#FLASH_STATE
+ JB [R5],#3
+ JMP Fast_DATE_IF_TRAN
+ SUB R3,#1
+ JZ FAST_END_BIT_3_TBUSY_TIMEOUT
+ JMP FAST_WAIT_BIT_3_TBUSY
+
+FAST_END_BIT_3_TBUSY_TIMEOUT:
+ MOV R0,#0x55555555
+ JMP Return_TimeOut
+ //---------------------------------------
+Fast_DATE_IF_TRAN:
+
+ MOV R3,R4
+ CMP R3,#65
+ JHI Return_PARAM_ERROR_IN_FAST
+ SUB R4,#1
+ JNZ Fast_DATE_TRAN
+ //++++++++++++++++++++++++++++++++++++++++++++++
+
+ LD R3,#TimeOutCountValue
+FAST_WAIT_BIT_2_TBIT:
+ LD R5,#FLASH_STATE
+ JB [R5],#2
+ JMP FAST_PAGE_HALF_FINISH
+ SUB R3,#1
+ JZ FAST_TIMEOUT_BIT_2_TBIT
+ JMP FAST_WAIT_BIT_2_TBIT
+ //++++++++++++++++++++++++++++++++++++++++++++++
+FAST_TIMEOUT_BIT_2_TBIT:
+ MOV R0,#0xAAAAAAAA
+ JMP Return_TimeOut
+
+FAST_PAGE_HALF_FINISH:
+ //++++++++++++++++++++++++++++++++++++++++++++++
+.ifdef __FLASH_API_LIKE_A158
+ MOVL R3,#0x03FF
+.else
+ MOVL R3,#0x01FF
+.endif
+ ANL R3,R1
+ JNZ Return_PARAM_ERROR_IN_FAST
+ CMP R1,#0
+ JNZ FAST_NEXT_HALF_PAGE
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+Return_CMD_SUCCESS_IN_FAST:
+ MOV R0,#0
+ JMP Return_PUSH_POP_IN_FAST
+
+Return_PARAM_ERROR_IN_FAST:
+ MOV R0,#PARAM_ERROR
+
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ JMP Return_PUSH_POP_IN_FAST
+
+Return_TimeOut:
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+//++++++++++++++++++++++++++++++++++++++++++++++
+Return_PUSH_POP_IN_FAST:
+ .if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ ENI
+ .endif
+ ST.w [SP+#0],R0
+ ST.w [SP+#1],R0
+ ST.w [SP+#2],R0
+ ST.w [SP+#3],R0
+ ST.w [SP+#4],R0
+ ST.w [SP+#5],R0
+ ST.w [SP+#6],R0
+ ST.w [SP+#7],R0
+ ST.w [SP+#8],R0
+ ST.w [SP+#9],R0
+ ST.w [SP+#10],R0
+ ST.w [SP+#11],R0
+//++++++++++++++++++++++++++++++++++++++++++++++
+ ADD sp,#48
+ POP R5
+ JMP lr
+ __End_Function__ __FLASH_Program__
+#########################################################################################
+ __RAM_Function__ __FLASH_Program_NBytes__
+ PUSH R5
+ SUB sp,#48
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ ST.w [sp+#0],r0
+ LD R4,#FLASH_KEY1
+ ST.w [sp+#1],R4
+
+ ST.w [sp+#2],r0
+ LD R4,#FLASH_KEY2
+ ST.w [sp+#3],R4
+
+ ST.w [sp+#4],r1
+ LD R4,#FLASH_KEY3
+ ST.w [sp+#5],R4
+
+ ST.w [sp+#6],r1
+ LD R4,#FLASH_KEY4
+ ST.w [sp+#7],R4
+
+ ST.w [sp+#8],r2
+ ST.w [sp+#9],r2
+ ST.w [sp+#10],r3
+ ST.w [sp+#11],r3
+ //++++++++++++++++++++++++++++++++++++++++++++++ clear syc
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+ //++++++++++++++++++++++++++++++++++++++++++++++ address check
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ LD R4,#__FLASH_MAX_SIZE__
+ CMP R0,R4
+ JHI Return_PARAM_ERROR_IN_NBytes
+ MOVL R4,#0x7
+ ANL R1,R4
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ LD R4,#__FLASH_MIN_SIZE__
+ CMP R4,R0
+ JHI Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++ len check
+ LD.w r0,[SP + #8]
+ LD.w r1,[SP + #9]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ LD R4,#0
+ CMP R0,R4
+ JZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key)
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++ key1 key2
+ LD.w r0,[SP + #1]
+ LD.w r1,[SP + #3]
+ LD r2,#FLASH_NVMUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key){
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++ key3 key4
+ LD.w r0,[SP + #5]
+ LD.w r1,[SP + #7]
+ LD r2,#FLASH_PROUNLOCK
+ ST.w [R2],R0
+ ST.w [R2],R1
+ //++++++++++++++++++++++++++++++++++++++++++++++if(Function_Parameter_Validate != key){
+ LD.w r0,[SP + #0]
+ LD.w r1,[SP + #2]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ LD R2,#Function_Parameter_Validate
+ CMP R0,R2
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++ address re same check
+ LD.w r0,[SP + #4]
+ LD.w r1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++ length 8aligned
+ LD.w r0,[SP + #8]
+ LD.w r1,[SP + #9]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ MOV R2,#0x07
+ ANL R0,R2
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++
+.if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ DSI
+.endif
+ //++++++++++++++++++++++++++++++++++++++++++++++ dwen bit 3 set
+ LD R2,#FLASH_ISPCON0
+ SET [R2],#3
+ LD.b R3,[R2]
+ MOV R2,#0x4B
+ CMP R3,R2
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++ cmd word write
+ LD R2,#FLASH_ISPCMD
+ MOVL R0,#0x7f5
+ MOVL R1,#0x7f5
+ ST.w [R2],R0
+ LD.w R3,[R2]
+ CMP R3,R1
+ JZ NBytes_Process_Start
+ //++ cmd failed
+ LD R2,#FLASH_ISPCON0
+ LD R0,#FLASH_WORK_CLR
+ ST.w [R2],R0
+ .if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ ENI
+ .endif
+ JMP Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++
+NBytes_Process_Start:
+ LD.w R0,[SP + #4]
+ LD.w R1,[SP + #6]
+ CMP R0,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+
+ LD.w R1,[SP + #8]
+ LD.w R2,[SP + #9]
+ CMP R2,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+
+ LD.w R2,[SP + #10]
+ LD.w R3,[SP + #11]
+ CMP R2,R3
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ //++++++++++++++++++++++++++++++++++++++++++++++
+NBytes_DATE_TRAN:
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+.ifdef __FLASH_API_LIKE_A158
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+ LD.w R3,[R2++]
+ ST.w [R0++],R3
+ SUB R1,#16
+.else
+ SUB R1,#8
+.endif
+ LD R3,#FLASH_ISPTRG
+ LD R4,#FLASH_WORK_CMD
+ ST.w [R3],R4
+ NOP
+ NOP
+ NOP
+ //---------------------------------------
+ LD R3,#TimeOutCountValue
+NBytes_WAIT_BIT_2_TBIT:
+ LD R5,#FLASH_STATE
+ JB [R5],#2
+ JMP NBytes_DATE_IF_TRAN
+ SUB R3,#1
+ JZ NBytes_END_BIT_2_TBIT_TIMEOUT
+ JMP NBytes_WAIT_BIT_2_TBIT
+ //---------------------------------------
+NBytes_DATE_IF_TRAN:
+.ifdef __FLASH_API_LIKE_A158
+ MOVL R3,#0x0F
+.else
+ MOVL R3,#0x07
+.endif
+ ANL R3,R1
+ JNZ Return_PARAM_ERROR_IN_NBytes
+ CMP R1,#0
+ JNZ NBytes_DATE_TRAN
+ //++++++++++++++++++++++++++++++++++++++++++++++
+NBytes_END_BIT_2_TBIT_TIMEOUT:
+NBytes_FINSH_BIT_2_TBIT:
+ //++++++++++++++++++++++++++++++++++++++++++++++
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+Return_CMD_SUCCESS_IN_NBytes:
+ MOV R0,#0
+ JMP Return_PUSH_POP_IN_NBytes
+Return_PARAM_ERROR_IN_NBytes:
+ MOV R0,#PARAM_ERROR
+
+ LD R2,#FLASH_WORK_CLR
+ LD R3,#FLASH_ISPCON0
+ ST.w [R3],R2
+//++++++++++++++++++++++++++++++++++++++++++++++
+Return_PUSH_POP_IN_NBytes:
+ .if __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+ ENI
+ .endif
+ ST.w [SP+#0],R0
+ ST.w [SP+#1],R0
+ ST.w [SP+#2],R0
+ ST.w [SP+#3],R0
+ ST.w [SP+#4],R0
+ ST.w [SP+#5],R0
+ ST.w [SP+#6],R0
+ ST.w [SP+#7],R0
+ ST.w [SP+#8],R0
+ ST.w [SP+#9],R0
+ ST.w [SP+#10],R0
+ ST.w [SP+#11],R0
+//++++++++++++++++++++++++++++++++++++++++++++++
+ ADD sp,#48
+ POP R5
+ JMP LR
+ __End_Function__ __FLASH_Program_NBytes__
+
\ No newline at end of file
diff --git a/FlashEEPROMEmulation/Driver/__driver_Flash_API.h b/FlashEEPROMEmulation/Driver/__driver_Flash_API.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0a6d58f57ab7ca0104a789f2cfe8c75eb49025c
--- /dev/null
+++ b/FlashEEPROMEmulation/Driver/__driver_Flash_API.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * Shanghai ChipON Micro-Electronic Co.,Ltd
+ ******************************************************************************
+ * @File Name : __driver_Flash_API.h
+ * @Author : ChipON AE/FAE Group
+ * @Date : 2023-09-18
+ * @Chip Version : A02
+ * @HW Version : KF32A136-MINI-EVB_V1.0
+ * @Example Version : V2.1.2.230918_release
+ * @Description :
+ *****************************************************************************
+ * Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
+ * All rights reserved.
+ *
+ * This software is copyright protected and proprietary to
+ * Shanghai ChipON Micro-Electronic Co.,Ltd.
+ ******************************************************************************/
+
+#ifndef DRIVER_FLASH_OP_API_HEAD_H_
+#define DRIVER_FLASH_OP_API_HEAD_H_
+//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ user config 1
+
+#define Function_Parameter_Validate 0x5A5A6688
+
+#define CMD_SUCCESS 0x00
+#define CMD_ERROR 0xAA
+#define PARAM_ERROR 0x0C
+
+#define TimeOutCountValue 5000000
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#define __FLASH__ __attribute__((section(".text")))
+#define __RAM__ __attribute__((section(".indata")))
+
+#define optimize_Os __attribute__((optimize("-Os")))
+#define optimize_O2 __attribute__((optimize("-O2")))
+#define optimize_O0 __attribute__((optimize("-O0")))
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ user config
+
+// Macro to select flash function with isr close and open
+#if 1
+#define __FLASH_ERASE_WRITE_ISR_CLOSE_AND_OPEN
+#endif
+
+// Macro to select flash function with unlock code
+#if 0
+ #define __FLASH_Driver_Use_LOCK_UNLOCK_Function
+#endif
+
+//Macro select flash parm
+#if 1
+ #if 1
+ #define __FLASH_API_LIKE_A150
+ #else
+ #define __FLASH_API_LIKE_A156
+ #endif
+#endif
+
+
+#define __FLASH_MAX_SIZE__ (512*1024)
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+unsigned char __FLASH_Read_Byte__(unsigned int address);
+unsigned int __FLASH_Read_WORD__(unsigned int address);
+unsigned int __FLASH_Read_One__(unsigned int address);
+unsigned int __FLASH_Read__(unsigned int address,unsigned int length,unsigned int buffers[]);
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+unsigned int __FLASH_UNLOCK_FUNCTION__(volatile unsigned int key,volatile unsigned int isopen);
+
+unsigned int __FLASH_Erase__(volatile unsigned key,volatile unsigned int WriteAddr,
+ volatile unsigned int DataLength);
+unsigned int __FLASH_Program__(volatile unsigned int key,volatile unsigned int WriteAddr,
+ volatile unsigned int DataLength,unsigned int WriteData[]);
+unsigned int __FLASH_Program_NBytes__(volatile unsigned int key,volatile unsigned int WriteAddr,
+ volatile unsigned int DataLength,unsigned int WriteData[]);
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ user config 1
+#endif /* DRIVER_FLASH_OP_API_HEAD_H_ */
diff --git a/FlashEEPROMEmulation/Driver/fee.c b/FlashEEPROMEmulation/Driver/fee.c
new file mode 100644
index 0000000000000000000000000000000000000000..6208477aa1e03e407803a3f4143733c6c41cba29
--- /dev/null
+++ b/FlashEEPROMEmulation/Driver/fee.c
@@ -0,0 +1,223 @@
+/******************************************************************************
+ * Shanghai ChipON Micro-Electronic Co.,Ltd
+ ******************************************************************************
+ * @File Name : fee.c
+ * @Author : ChipON AE/FAE Group
+ * @Date : 2024-03-15
+ * @Version : V0.2.0
+ * @Description : This file provides Driver for flash emulation of EEPROMs
+ ******************************************************************************
+ * Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
+ * All rights reserved.
+ *
+ * This software is copyright protected and proprietary to
+ * Shanghai ChipON Micro-Electronic Co.,Ltd.
+ *****************************************************************************/
+
+/******************************************************************************
+ ** Include Files
+ ******************************************************************************/
+#include
+#include
+
+#include "__Kungfu32_chipmodel_define.h"
+#include "__driver_Flash_API.h"
+#include "EmulatedEE.h"
+#include "fee.h"
+
+/******************************************************************************
+ * Macro Definitions
+ ******************************************************************************/
+
+/**
+ * @brief Fee access to the maximum space
+ */
+#define FEE_EEPROM_ADDR_MAX ((EE_PAGE_SIZE / 2U) - 5U)
+/******************************************************************************
+ * Constants
+ ******************************************************************************/
+
+/******************************************************************************
+ * Type definitions
+ ******************************************************************************/
+
+/******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/**
+ * @brief Fee state
+ */
+static FEE_StateEnumType FeeState = FEE_UNINIT;
+/******************************************************************************
+ * Function definitions
+ ******************************************************************************/
+/**
+ * @brief The function initializes Fee module.
+ *
+ */
+void FEE_Init(void)
+{
+ FeeState = FEE_INIT;
+ EmulatedEE_Init();
+ FeeState = FEE_IDLE;
+}
+
+/**
+ * @brief Write one or more 4 Bytes Block to Emulated Eeprom.
+ *
+ * @details The address range for writing is 0 to 511 bytes
+ *
+ * @param WriteAddr Target address in Emulated Eeprom memory.
+ * @param DataLength Number of bytes to write.
+ * @param Buffers Pointer to source data buffer.
+ *
+ * @return bool
+ * @retval true write success
+ * @retval false write failed
+ */
+FEE_StatusType FEE_Write(uint32_t WriteAddr, uint32_t DataLength, const uint32_t *Buffers)
+{
+ uint32_t kvRetVal;
+ FEE_StatusType kvStatus = FEE_STATUS_OK;
+
+ if ((WriteAddr + DataLength) > (FEE_EEPROM_ADDR_MAX + 1U))
+ {
+ return FEE_STATUS_PARAM_ERR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ if (((DataLength & 0x3U) > 0U) || (0U == DataLength))
+ {
+ return FEE_STATUS_PARAM_ERR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ if (Buffers == NULL)
+ {
+ return FEE_STATUS_PARAM_ERR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+#if FEE_WRITE_ISR_LOCK_ENABLE
+ kvIntState = (INT_CTL0 & INT_CTL0_AIE);
+ SFR_CLR_BIT_ASM(INT_CTL0, INT_CTL0_AIE_POS);
+#endif
+ /** EE_Write Lock*/
+ if (FeeState == FEE_IDLE)
+ {
+ FeeState = FEE_WRITE;
+ }
+ else
+ {
+ return false;
+ }
+#if FEE_WRITE_ISR_LOCK_ENABLE
+ if (kvIntState != 0)
+ SFR_SET_BIT_ASM(INT_CTL0, INT_CTL0_AIE_POS);
+#endif
+
+ for (uint32_t i = 0U; i < DataLength; i += 4U)
+ {
+
+ kvRetVal = EmulatedEE_WriteData(WriteAddr + i, Buffers[i / 4U]);
+
+ if (kvRetVal != CMD_SUCCESS)
+ {
+ kvStatus = FEE_STATUS_ERROR;
+ break;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ FeeState = FEE_IDLE;
+
+ return kvStatus;
+}
+
+/**
+ * @brief Reads from Emulated Eeprom memory.
+ *
+ * @param ReadAddr Read address in Emulated Eeprom memory.
+ * @param DataLength Number of bytes to read.
+ * @param Buffers Pointer to target data buffer.
+ * @retval true
+ * @retval false
+ */
+FEE_StatusType FEE_Read(uint32_t ReadAddr, uint32_t DataLength, uint32_t *Buffers)
+{
+ uint32_t kvRetVal;
+ FEE_StatusType kvStatus = FEE_STATUS_OK;
+
+ if ((ReadAddr + DataLength) > (FEE_EEPROM_ADDR_MAX + 1U))
+ {
+ return FEE_STATUS_PARAM_ERR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ if (((ReadAddr & 0x3U) > 0U) || (0U == DataLength))
+ {
+ return FEE_STATUS_PARAM_ERR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ if (Buffers == NULL)
+ {
+ return FEE_STATUS_PARAM_ERR;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+
+ for (uint32_t i = 0U; i < DataLength; i += 4U)
+ {
+ kvRetVal = EmulatedEE_ReadData(ReadAddr + i, &Buffers[i / 4U]);
+
+ if (kvRetVal != CMD_SUCCESS)
+ {
+ kvStatus = FEE_STATUS_ERROR;
+ break;
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+
+ return kvStatus;
+}
+
+/**
+ * @brief Get Fee Current Status
+ *
+ * @return FEE_StateEnumType
+ * @retval FEE_UNINIT
+ * @retval FEE_INIT
+ * @retval FEE_WRITE
+ * @retval FEE_IDLE
+ */
+FEE_StateEnumType FEE_GetStatus(void)
+{
+ return FeeState;
+}
+
+/* EOF */
diff --git a/FlashEEPROMEmulation/Driver/fee.h b/FlashEEPROMEmulation/Driver/fee.h
new file mode 100644
index 0000000000000000000000000000000000000000..a0caecdf3c6cdcbc908a36ab55f90cea1ec2a2a5
--- /dev/null
+++ b/FlashEEPROMEmulation/Driver/fee.h
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Shanghai ChipON Micro-Electronic Co.,Ltd
+ ******************************************************************************
+ * @File Name : fee.h
+ * @Author : ChipON AE/FAE Group
+ * @Date : 2024-03-15
+ * @Version : V0.2.0
+ * @Description : This file provides Driver for flash emulation of EEPROMs
+ ******************************************************************************
+ * Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
+ * All rights reserved.
+ *
+ * This software is copyright protected and proprietary to
+ * Shanghai ChipON Micro-Electronic Co.,Ltd.
+ *****************************************************************************/
+#ifndef FEE_H
+#define FEE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ ** Include Files
+ ******************************************************************************/
+#include
+#include
+/******************************************************************************
+ * Macro or Inline
+ ******************************************************************************/
+
+/******************************************************************************
+ ** Typedef Definitions
+ ******************************************************************************/
+/**
+ * @brief fee status
+ */
+typedef enum
+{
+ /** @brief fee status ok */
+ FEE_STATUS_OK,
+ /** @brief */
+ FEE_STATUS_PARAM_ERR = 0x0CU,
+ /** @brief */
+ FEE_STATUS_ERROR = 0xAAU,
+} FEE_StatusType;
+typedef enum
+{
+ FEE_UNINIT,
+ FEE_INIT,
+ FEE_WRITE,
+ FEE_IDLE,
+} FEE_StateEnumType;
+
+/******************************************************************************
+ * Export Variables
+ ******************************************************************************/
+
+/******************************************************************************
+ * Export Functions
+ ******************************************************************************/
+/**
+ * @brief The function initializes Fee module.
+ *
+ */
+void FEE_Init(void);
+
+/**
+ * @brief Write one or more 4 Bytes Block to Emulated Eeprom.
+ *
+ * @details The address range for writing is 0 to 511 bytes
+ *
+ * @param WriteAddr Target address in Emulated Eeprom memory.
+ * @param DataLength Number of bytes to write.
+ * @param Buffers Pointer to source data buffer.
+ *
+ * @return bool
+ * @retval true write success
+ * @retval false write failed
+ */
+FEE_StatusType FEE_Write(uint32_t WriteAddr, uint32_t DataLength, const uint32_t *Buffers);
+
+/**
+ * @brief Reads from Emulated Eeprom memory.
+ *
+ * @param ReadAddr Read address in Emulated Eeprom memory.
+ * @param DataLength Number of bytes to read.
+ * @param Buffers Pointer to target data buffer.
+ *
+ * @return bool
+ * @retval true read success
+ * @retval false read failed
+ */
+FEE_StatusType FEE_Read(uint32_t ReadAddr, uint32_t DataLength, uint32_t *Buffers);
+
+/**
+ * @brief Get Fee Current Status
+ *
+ * @return FEE_StateEnumType
+ * @retval FEE_UNINIT
+ * @retval FEE_INIT
+ * @retval FEE_WRITE
+ * @retval FEE_IDLE
+ */
+FEE_StateEnumType FEE_GetStatus(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* EOF */
diff --git a/FlashEEPROMEmulation/README.md b/FlashEEPROMEmulation/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..836abb115a45cee4a865298405eb4cd6d2a9db2c
--- /dev/null
+++ b/FlashEEPROMEmulation/README.md
@@ -0,0 +1,46 @@
+#### 文件所有
+
+本文适用于KF32A136的Flash模拟EEPROM操作的示例例程,例程文件名:FlashEEPROMEmulation
+
+* * *
+
+
+#### 版权说明
+
+目前的固件只是为了给使用者提供指导,目的是向客户提供有关产品的代码信息,
+
+与使用者的产品信息和代码无关。因此,对于因此类固件内容和(或)客户使用此
+
+处包含的与其产品相关的编码信息而引起的任何索赔,上海芯旺微电子技术有限公
+
+司不承担任何直接、间接或后果性损害赔偿责任
+
+* * *
+
+
+#### Flash说明
+
+* KF32A136有两块Flash,分别为保存代码的数据区和信息区
+* 提供数据区域Flash的操作接口,包括读取、擦除、页写入、字节写入、比较等函数
+* FLash的写入过程,关闭了全局中断,若在调用之前打开了全局中断,结束后会主动恢复
+
+##### 使用说明
+
+* 程序下载后可以通过 KF32A136 开发板板载串口观察程序运行输出
+
+1. 写508数据,读取508数据,读出后和写入数据比较,看写、读是否一致
+2. Fee写或读出错后,打印出不同数据并报错
+
+* * *
+##### 注意事项
+
+1. 写接口要求
+ - 地址+写长度不能大于511
+ - 地址要求4的整数倍
+ - 写的长度要求4的整数倍
+ - 写长度不为0
+2. 读接口要求
+ - 地址+读长度不能大于511
+ - 地址要求4的整数倍
+ - 读的长度要求4的整数倍
+ - 读长度不为0
diff --git a/FlashEEPROMEmulation/__Kungfu32_chipmodel_define.h b/FlashEEPROMEmulation/__Kungfu32_chipmodel_define.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc336b2f4b5907dc2851397c53884c3ec178957c
--- /dev/null
+++ b/FlashEEPROMEmulation/__Kungfu32_chipmodel_define.h
@@ -0,0 +1,17 @@
+/****************************************************************************************
+ * Auto File.Recreate By ChipType Change,Don't Edit And Write Code here!!!
+ * Auto File.Recreate By ChipType Change,Don't Edit And Write Code here!!!
+ * Auto File.Recreate By ChipType Change,Don't Edit And Write Code here!!!
+ *
+ * Inlcude this File,Useful For Peripheral Or Application ,Implement Different By ChipType
+ ****************************************************************************************/
+
+#ifndef __Kungfu32_chipmodel_define
+#define __Kungfu32_chipmodel_define
+
+#ifndef KF32A136KQS
+#define KF32A136KQS
+#endif
+
+#endif /* __Kungfu32_chipmodel_define */
+
diff --git a/FlashEEPROMEmulation/_config/startup.c b/FlashEEPROMEmulation/_config/startup.c
new file mode 100644
index 0000000000000000000000000000000000000000..898a5c2971ed334221fcb2626e60a0b8b6f9c136
--- /dev/null
+++ b/FlashEEPROMEmulation/_config/startup.c
@@ -0,0 +1,54 @@
+
+#ifndef HWREG
+#define HWREG(x) (*((volatile unsigned int *)(x)))
+#endif
+//################# auto value variable from tool #############//
+extern unsigned int __text_end__;
+extern unsigned int __bss_start__;
+extern unsigned int __bss_end__;
+extern unsigned int __data_start__;
+
+//#define Project_Type__cplusplus
+#ifdef Project_Type__cplusplus
+extern unsigned int __init_class_start;
+extern unsigned int __init_class_end;
+#endif
+//####################################################################//
+extern int main();
+//####################################################################//
+void startup()
+{
+ unsigned int *s,*begin,*end;
+#ifdef Project_Type__cplusplus
+ void (*pf)(void);
+#endif
+//############# init work for the chip #############//
+// HWREG(0x40000000)=1;
+ HWREG(0x40000000)=0;
+//############# init variable who have initialization #############//
+ s = (unsigned int*)&__text_end__;
+ begin = (unsigned int*)&__data_start__;
+ end = (unsigned int*)&__bss_start__;
+ while(begin < end)
+ *begin++ = *s++;
+//############# init class who have initialization(C++) #############//
+#ifdef Project_Type__cplusplus
+ begin = (unsigned int*)&__init_class_start;
+ end = (unsigned int*)&__init_class_end;
+ while(begin>>\r\n");
+
+ // Retrieve the current state of the Fee
+ FeeState = FEE_GetStatus();
+
+ // If the state is not idle, output an error message and terminate the function
+ if (FeeState != FEE_IDLE)
+ {
+ kf_printf("FeeState State Err [%d][%s:%d]\r\n", FeeState, __func__, __LINE__);
+ return;
+ }
+
+ // Populate the write buffer with incrementing values as test data
+ for (int i = 0; i < 127; i++)
+ {
+ write_buffer[i] = i;
+ }
+
+ // Write the buffer contents into the Fee
+ FEE_Write(0, 127 * 4, write_buffer); // Assuming FEE_Write accepts starting address, byte count, and data pointer as parameters
+
+ // Clear the read buffer in preparation for receiving read data
+ memset(&read_buffer, 0, 64);
+
+ // Read data from the Fee into the read buffer
+ FEE_Read(0, 127 * 4, (uint32_t *)&read_buffer); // Assuming FEE_Read accepts starting address, byte count, and data pointer as parameters
+
+ // Verify that the read data matches the written data exactly
+ for (int i = 0; i < 127; i++)
+ {
+ if (read_buffer[i] != write_buffer[i])
+ {
+ // If a mismatch is found, output detailed data differences and an error message, then terminate the function
+ FEE_PrintfData(read_buffer, write_buffer, 127);
+ kf_printf("Fee Write or Read Err [%d][%s:%d]\r\n", i, __func__, __LINE__);
+ return;
+ }
+ }
+
+ // Retrieve and check the current state of the Fee once more
+ FeeState = FEE_GetStatus();
+
+ // If the state is not idle, output an error message and terminate the function
+ if (FeeState != FEE_IDLE)
+ {
+ kf_printf("FeeState State Err [%d][%s:%d]\r\n", FeeState, __func__, __LINE__);
+ return;
+ }
+
+ // Output the successful completion of the function
+ kf_printf("\r\n%s %s", __FUNCTION__, "Pass >>>\r\n");
+}
+
+int main(void)
+{
+ /* Initialize the system clock is 120M */
+ SystemInit(120);
+ /*Initialize the print function*/
+ kfLog_Init();
+ /* Setup SysTick Timer as delay function, and input frequency is 120M */
+ systick_delay_init(120);
+ FEE_Init();
+ while (1)
+ {
+ FEE_example();
+ systick_delay_ms(1000);
+ }
+}
+
+/**
+ * @brief : Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param[in] file pointer to the source file name
+ * @param[in] line assert_param error line source number
+ * @param[out] None
+ * @retval :None
+ */
+void check_failed(uint8_t *File, uint32_t Line)
+{
+ /* User can add his own implementation to report the file name and line number,
+ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+
+ /* Infinite loop */
+ while (1)
+ {
+ ;
+ }
+};