/** ******************************************************************************* * @file iap/iap_ymodem_boot/source/flash.c * @brief This file provides firmware functions to manage the Flash driver. @verbatim Change Logs: Date Author Notes 2022-03-31 CDT First version @endverbatim ******************************************************************************* * Copyright (C) 2022-2023, Xiaohua Semiconductor Co., Ltd. All rights reserved. * * This software component is licensed by XHSC under BSD 3-Clause license * (the "License"); You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ******************************************************************************* */ /******************************************************************************* * Include files ******************************************************************************/ #include "hdl_flash.h" #include "hdl_clk.h" /******************************************************************************* * Local type definitions ('typedef') ******************************************************************************/ /******************************************************************************* * Local pre-processor symbols/macros ('#define') ******************************************************************************/ /******************************************************************************* * Global variable definitions (declared in header file with 'extern') ******************************************************************************/ /******************************************************************************* * Local function prototypes ('static') ******************************************************************************/ /******************************************************************************* * Local variable definitions ('static') ******************************************************************************/ /******************************************************************************* * Function implementation - global ('extern') and local ('static') ******************************************************************************/ int32_t hdl_flash_unlock(void) { LL_PERIPH_WE(LL_PERIPH_EFM ); /* Wait flash ready. */ while (SET != EFM_GetStatus(EFM_FLAG_RDY)) { ; } //½âËøEFM EFM_FWMC_Cmd(ENABLE); EFM_CacheCmd(ENABLE); return LL_OK; } int32_t hdl_flash_lock(void){ /* Peripheral registers write protected */ EFM_CacheCmd(DISABLE); EFM_FWMC_Cmd(DISABLE); LL_PERIPH_WP(LL_PERIPH_EFM ); return LL_OK; } /** * @brief Check address alignment. * @param u32Addr Flash address * @retval An en_result_t enumeration value: * - LL_OK: Address aligned * - LL_ERR: Address unaligned */ int32_t hdl_flash_check_addralign(uint32_t u32Addr) { uint32_t u32Step = FLASH_SECTOR_SIZE; if (VECT_TAB_STEP > FLASH_SECTOR_SIZE) { u32Step = VECT_TAB_STEP; } if ((u32Addr % u32Step) != 0UL) { return LL_ERR; } return LL_OK; } /** * @brief Erase flash sector. * @param u32Addr Flash address * @param u32Size Firmware size (0: current address sector) * @retval An en_result_t enumeration value: * - LL_OK: Erase succeeded * - LL_ERR: Erase timeout * - LL_ERR_INVD_PARAM: The parameters is invalid. */ int32_t hdl_flash_erase_sector(uint32_t u32Addr, uint32_t u32Size) { uint32_t i; uint32_t u32PageNum; if (u32Addr >= (FLASH_BASE + FLASH_SIZE)) { return LL_ERR_INVD_PARAM; } if (u32Size == 0U) { return EFM_SectorErase(u32Addr); } else { u32PageNum = u32Size / FLASH_SECTOR_SIZE; if ((u32Size % FLASH_SECTOR_SIZE) != 0UL) { u32PageNum += 1U; } for (i = 0; i < u32PageNum; i++) { if (LL_OK != EFM_SectorErase(u32Addr + (i * FLASH_SECTOR_SIZE))) { return LL_ERR; } } } return LL_OK; } /** * @brief Write data to flash. * @param u32Addr Flash address * @param pu8Buff Pointer to the buffer to be written * @param u32Len Buffer length * @retval int32_t: * - LL_OK: Program successful. * - LL_ERR_INVD_PARAM: The parameters is invalid. * - LL_ERR_NOT_RDY: EFM if not ready. * - LL_ERR_ADDR_ALIGN: Address alignment error */ int32_t hdl_flash_write_data(uint32_t u32Addr, uint8_t *pu8Buff, uint32_t u32Len) { if ((pu8Buff == NULL) || (u32Len == 0U) || ((u32Addr + u32Len) > (FLASH_BASE + FLASH_SIZE))) { return LL_ERR_INVD_PARAM; } if (0UL != (u32Addr % 4U)) { return LL_ERR_ADDR_ALIGN; } return EFM_Program(u32Addr, pu8Buff, u32Len); } /** * @brief Read data from flash. * @param u32Addr Flash address * @param pu8Buff Pointer to the buffer to be reading * @param u32Len Buffer length * @retval int32_t: * - LL_OK: Read data succeeded * - LL_ERR_INVD_PARAM: The parameters is invalid * - LL_ERR_ADDR_ALIGN: Address alignment error */ int32_t hdl_flash_read_data(uint32_t u32Addr, uint8_t *pu8Buff, uint32_t u32Len) { uint32_t i; uint32_t u32WordLength, u8ByteRemain; uint32_t *pu32ReadBuff; __IO uint32_t *pu32FlashAddr; uint8_t *pu8Byte; __IO uint8_t *pu8FlashAddr; if ((pu8Buff == NULL) || (u32Len == 0U) || ((u32Addr + u32Len) > (FLASH_BASE + FLASH_SIZE))) { return LL_ERR_INVD_PARAM; } if (0UL != (u32Addr % 4U)) { return LL_ERR_ADDR_ALIGN; } pu32ReadBuff = (uint32_t *)(uint32_t)pu8Buff; pu32FlashAddr = (uint32_t *)u32Addr; u32WordLength = u32Len / 4U; u8ByteRemain = u32Len % 4U; /* Read data */ for (i = 0UL; i < u32WordLength; i++) { *(pu32ReadBuff++) = *(pu32FlashAddr++); } if (0UL != u8ByteRemain) { pu8Byte = (uint8_t *)pu32ReadBuff; pu8FlashAddr = (uint8_t *)pu32FlashAddr; for (i = 0UL; i < u8ByteRemain; i++) { *(pu8Byte++) = *(pu8FlashAddr++); } } return LL_OK; } /****************************************************************************** * EOF (not truncated) *****************************************************************************/