From ae079c1fc5d990ba55714d4b3a51b19f96edaec4 Mon Sep 17 00:00:00 2001
From: WXK <287788329@qq.com>
Date: 星期四, 24 四月 2025 16:01:43 +0800
Subject: [PATCH] 改为中断来低电平触发发送当前扫描数据,3s内扫描不到的会退出,串口来55 AA 75 70 64 61 74 65,进入升级模式

---
 01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_fmc.c |  174 ++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 120 insertions(+), 54 deletions(-)

diff --git a/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_fmc.c b/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_fmc.c
index a731475..5a93fc5 100644
--- a/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_fmc.c
+++ b/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/peripheral/src/pan_fmc.c
@@ -14,6 +14,7 @@
 #define BIT(x)   (0x1UL << (x))
 
 FLASH_IDS_T flash_ids = {0};
+uint8_t ft_chip_info;
 
 static void FMC_TrigErrorHandler(FLCTL_T *fmc)
 {
@@ -26,6 +27,11 @@
         FMC_ReadByte(FLCTL, 0x1000, CMD_DREAD);
         FMC_WriteDisable(FLCTL);
     }
+}
+
+void FMC_ParamsSet(OTP_STRUCT_T *otp)
+{
+    ft_chip_info = otp->m.chip_info;
 }
 
 void FMC_GetFlashUniqueId(FLCTL_T *fmc)
@@ -52,6 +58,10 @@
 	flash_ids.manufacturer_id = FLCTL_BUFF->X_FL_BUFFER[0];
 	flash_ids.memory_type_id = FLCTL_BUFF->X_FL_BUFFER[1];
 	flash_ids.memory_density_id = FLCTL_BUFF->X_FL_BUFFER[2];
+
+    if (((ft_chip_info & 0x1F) == 0x2) && (flash_ids.manufacturer_id == 0xC4)) {
+        flash_ids.memory_density_id = 0x12;
+    }
 }
 
 void FMC_SetFlashCapacity(FLCTL_T *fmc)
@@ -171,6 +181,18 @@
   */
 int FMC_Erase(FLCTL_T *fmc,unsigned int Addr,unsigned char cmd)
 {
+#if FMC_DBG_LOG
+   if (cmd == CMD_ERASE_SECTOR) {
+       SYS_TEST("Erase Addr: 0x%08x (Sector Erase)\n", Addr);
+   } else if (cmd == CMD_ERASE_32K) {
+       SYS_TEST("Erase Addr: 0x%08x (BLK32k Erase)\n", Addr);
+   } else if (cmd == CMD_ERASE_64K) {
+       SYS_TEST("Erase Addr: 0x%08x (BLK64k Erase)\n", Addr);
+   } else {
+       SYS_TEST("Unhandled Erase CMD, Addr: 0x%08x, CMD: %d\n", Addr, cmd);
+   }
+#endif
+
 	unsigned char offset = 0;
 	unsigned char bytes_num_w;
 
@@ -193,7 +215,7 @@
 	fmc->X_FL_TRIG = CMD_TRIG;
 	while(fmc->X_FL_TRIG){}
     FMC_TrigErrorHandler(fmc);
-	while(FMC_ReadStatusReg(fmc,CMD_READ_STATUS_L) & Write_In_Process_Msk) {}
+//	while(FMC_ReadStatusReg(fmc,CMD_READ_STATUS_L) & Write_In_Process_Msk) {}
 	return 0;
 }
 
@@ -213,6 +235,11 @@
     if (addr >= FMC_GetFlashCodeAreaSize(fmc)) {
         return -1;
     }
+
+    // Ensure we will not touch the flash INFO area
+    fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
+    fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
+
     return FMC_Erase(fmc,addr,CMD_ERASE_SECTOR);
 }
 
@@ -238,6 +265,11 @@
         || (addr < 0x7000)) {
         return -1;
     }
+
+    // Ensure we will not touch the flash INFO area
+    fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
+    fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
+
     return FMC_Erase(fmc,addr,CMD_ERASE_32K);
 }
 
@@ -263,25 +295,12 @@
         || (addr < 0xF000)) {
         return -1;
     }
-    return FMC_Erase(fmc,addr,CMD_ERASE_64K);
-}
 
-/**
-  * @brief Erase the whole flash memory.
-  *
-  * This function is used to erase all data in flash, include
-  * Code Area and Info Area.
-  *
-  * @note This API should only be used when you really know what
-  * you are doing.
-  *
-  * @param fmc: where fmc is a flash peripheral.
-  * @retval 0: Success.
-  * @retval -1: Fail.
-  */
-int FMC_EraseChip(FLCTL_T *fmc)
-{
-    return FMC_Erase(fmc,0x0,CMD_ERASE_CHIP);
+    // Ensure we will not touch the flash INFO area
+    fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
+    fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
+
+    return FMC_Erase(fmc,addr,CMD_ERASE_64K);
 }
 
 static void find_special_chunk_in_range(size_t chunk_pattern, uint32_t range_start_sector_idx, uint16_t range_sector_num,
@@ -331,7 +350,7 @@
         return -1;
     }
 
-    // Fine 32K blocks from the initial data chunk
+    // Find 32K blocks from the initial data chunk
     find_special_chunk_in_range(8, start_phy_sector_idx, sector_num, &block_32k_start_sector_idx, &block_32k_sector_num);
 
     if (block_32k_sector_num == 0) { // No 32k-block found
@@ -418,7 +437,7 @@
   * @brief  This function is used to read flash,
   * @param  fmc: where fmc is a flash peripheral.
 	* @param  Addr: where Addr is start address to read
-	* @param  cmd: where cmd can be CMD_FAST_READ or CMD_NOR_READ
+	* @param  cmd: where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD
   * @retval 4byte data
   */
 unsigned int FMC_ReadWord(FLCTL_T *fmc,unsigned int Addr, unsigned char cmd)
@@ -451,7 +470,7 @@
   * @brief  This function is used to read flash,
   * @param  fmc: where fmc is a flash peripheral.
 	* @param  Addr: where Addr is start address to read
-	* @param  cmd: where cmd can be CMD_FAST_READ or CMD_NOR_READ
+	* @param  cmd: where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD
   * @retval 1byte data
   */
 unsigned char FMC_ReadByte(FLCTL_T *fmc,unsigned int Addr,unsigned char cmd)
@@ -485,7 +504,7 @@
   * @brief  This function is used to read a page size (256 bytes) of data from flash
   * @param  fmc     where fmc is a flash peripheral.
   * @param  Addr    where Addr is start address to read
-  * @param  cmd     where cmd can be CMD_FAST_READ or CMD_NORM_READ
+  * @param  cmd     where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD
   * @retval Internal Buffer address
   */
 unsigned char *FMC_ReadPage(FLCTL_T *fmc,unsigned int Addr,unsigned char cmd)
@@ -544,16 +563,7 @@
 	return (unsigned char *)&(FLCTL_BUFF->X_FL_BUFFER[0]);
 }
 
-/**
-  * @brief  This function is used to read data stream from flash
-  * @param  fmc     where fmc is a flash peripheral.
-  * @param  Addr    where Addr is start address to read
-  * @param  cmd     where cmd can be CMD_FAST_READ or CMD_NORM_READ
-  * @param  buf     where buf is a buffer to store read data
-  * @param  len     where len is data length of bytes to read
-  * @retval None
-  */
-int FMC_ReadStream(FLCTL_T *fmc, unsigned int Addr, unsigned char cmd, unsigned char *buf, unsigned int len)
+static int FMC_ReadStreamInternal(FLCTL_T *fmc, unsigned int Addr, unsigned char cmd, unsigned char *buf, unsigned int len)
 {
     unsigned int tmp_addr = Addr;
     unsigned int tmp_size = len;
@@ -577,6 +587,24 @@
     }
 
     return 0;
+}
+
+/**
+  * @brief  This function is used to read data stream from flash
+  * @param  fmc     where fmc is a flash peripheral.
+  * @param  Addr    where Addr is start address to read
+  * @param  cmd     where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD
+  * @param  buf     where buf is a buffer to store read data
+  * @param  len     where len is data length of bytes to read
+  * @retval None
+  */
+int FMC_ReadStream(FLCTL_T *fmc, unsigned int Addr, unsigned char cmd, unsigned char *buf, unsigned int len)
+{
+    // Ensure we will not touch the flash INFO area
+    fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
+    fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
+
+    return FMC_ReadStreamInternal(fmc, Addr, cmd, buf, len);
 }
 /**
   * @brief  This function is used to write data to buffer,
@@ -707,17 +735,43 @@
     if (OffsetOfCurrPage + size > 256)
         return -1;
 
-    if(FMC_WriteEnable(fmc) == 0)
-        return -1;
-
-    // Fill the 256-Bytes FMC Write Buffer
-    for(size_t i = 0; i < 256; i++)
+    if (flash_ids.manufacturer_id == 0x85)
     {
-        if ((i >= OffsetOfCurrPage) && (i < OffsetOfCurrPage + size))
-            FLCTL_BUFF->X_FL_BUFFER[i] = *(buf++);
+        if (size < 256)
+        {
+            // Read page back
+            FMC_ReadPage(fmc, PageStartAddr, CMD_DREAD);
+            // Fill anticipatory data to fmc write buffer
+            for (size_t i = 0; i < size; i++)
+            {
+                FLCTL_BUFF->X_FL_BUFFER[OffsetOfCurrPage + i] = *(buf++);
+            }
+            // Erase current page
+            FMC_Erase(FLCTL, PageStartAddr, CMD_ERASE_PAGE);
+        }
         else
-            FLCTL_BUFF->X_FL_BUFFER[i] = 0xFF;
+        {
+            // Fill the 256-Bytes FMC Write Buffer
+            for (size_t i = 0; i < 256; i++)
+            {
+                FLCTL_BUFF->X_FL_BUFFER[i] = *(buf++);
+            }
+        }
     }
+    else
+    {
+        // Fill the 256-Bytes FMC Write Buffer
+        for (size_t i = 0; i < 256; i++)
+        {
+            if ((i >= OffsetOfCurrPage) && (i < OffsetOfCurrPage + size))
+                FLCTL_BUFF->X_FL_BUFFER[i] = *(buf++);
+            else
+                FLCTL_BUFF->X_FL_BUFFER[i] = 0xFF;
+        }
+    }
+
+    if (FMC_WriteEnable(fmc) == 0)
+        return -1;
 
     fmc->X_FL_CTL = (0<<8) | (0x04<<0);
     fmc->X_FL_CONFIG |= 0x1; //pp active
@@ -733,15 +787,7 @@
     return 0;
 }
 
-/**
-  * @brief  This function is used to write data stream to flash
-  * @param  fmc     where fmc is a flash peripheral
-  * @param  Addr    where Addr is start address to write, can be any valid address
-  * @param  buf     where buf is a buffer to store data to write
-  * @param  len     where len is data length of bytes to write
-  * @retval None
-  */
-int FMC_WriteStream(FLCTL_T *fmc, unsigned int Addr, unsigned char *buf, unsigned int len)
+static int FMC_WriteStreamInternal(FLCTL_T *fmc, unsigned int Addr, unsigned char *buf, unsigned int len)
 {
     unsigned int OffsetOfFirstPage = Addr % 256;
     unsigned int WriteSizeInFirstPage = (len < (256 - OffsetOfFirstPage)) ? len : (256 - OffsetOfFirstPage);
@@ -786,10 +832,27 @@
 }
 
 /**
+  * @brief  This function is used to write data stream to flash
+  * @param  fmc     where fmc is a flash peripheral
+  * @param  Addr    where Addr is start address to write, can be any valid address
+  * @param  buf     where buf is a buffer to store data to write
+  * @param  len     where len is data length of bytes to write
+  * @retval None
+  */
+int FMC_WriteStream(FLCTL_T *fmc, unsigned int Addr, unsigned char *buf, unsigned int len)
+{
+    // Ensure we will not touch the flash INFO area
+    fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
+    fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
+
+    return FMC_WriteStreamInternal(fmc, Addr, buf, len);
+}
+
+/**
   * @brief  This function is used to read data from the flash 4KB INFO area.
   * @param  fmc     where fmc is a flash peripheral.
   * @param  Addr    where Addr is start address to read, can be 0 ~ 4095
-  * @param  cmd     where cmd can be CMD_FAST_READ or CMD_NORM_READ
+  * @param  cmd     where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD
   * @param  buf     where buf is a buffer to store read data
   * @param  len     where len is data length of bytes to read
   * @retval 0   read success
@@ -805,7 +868,7 @@
     fmc->X_FL_CONFIG |= BIT1;   //set info_en bit
     fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
 
-    FMC_ReadStream(fmc, Addr, cmd, buf, len);
+    FMC_ReadStreamInternal(fmc, Addr, cmd, buf, len);
 
     fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
     fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
@@ -819,6 +882,9 @@
   * @param  Addr    where Addr is start address to write, can be 0 ~ 4095
   * @param  buf     where buf is a buffer to store data to write
   * @param  len     where len is data length of bytes to write
+  * @note   [CAUTION!] This is a dangerous API! It may destroy the calibrate
+  *         data of SoC, do not call this API if you are not sure the actual
+  *         behavior of it!
   * @retval 0   write success
   * @retval -1  write fail
   */
@@ -832,7 +898,7 @@
     fmc->X_FL_CONFIG |= BIT1;   //set info_en bit
     fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
 
-    FMC_WriteStream(fmc, Addr, buf, len);
+    FMC_WriteStreamInternal(fmc, Addr, buf, len);
 
     fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
     fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
@@ -853,7 +919,7 @@
     fmc->X_FL_CONFIG |= BIT1;   //set info_en bit
     fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit
 
-    ret = FMC_EraseSector(fmc, 0x0);
+    ret = FMC_Erase(fmc, 0x0, CMD_ERASE_SECTOR);
 
     fmc->X_FL_CONFIG &= ~BIT1;  //clear info_en bit
     fmc->X_FL_CONFIG |= BIT2;   //set tx_address_transaction bit

--
Gitblit v1.9.3