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