#include "nvm.h" #include "eeprom_emul.h" #include "typedef.h" #include #include "fbl_def.h" #include "fbl_ap.h" #include "did.h" #include "xl_crc.h" #include "flash_interface.h" NVM_FLAGS_Ts Nvm_Flags; uint8_t Mem_PartionTempBuff[MEM_MAX_TEMP_BUFF_NUM][FBL_MEM_SEGMENT_SIZE]; uint8_t flashCode[RAM_FALSH_DRIVE_LENGHT + 4] __attribute__((section(".flashdriver_ram"))); const uint8_t prensnt[8] = {0x73, 0x6a, 0x29, 0x3e, 0x51, 0x34, 0xaa, 0xef}; const uint8_t prensntmask[8] = {0x8c, 0x95, 0xd6, 0xc1, 0xae, 0xcb, 0x55, 0x10}; static uint64_t present_temp = 0; extern void NVM_Init(void) { Nvm_Flags.shutdown_requested = 0u; Nvm_Flags.force_shutdown = 0u; Nvm_Flags.halt_requested = 0u; Nvm_Flags.halted = 0u; Nvm_Flags.busy = 0u; Nvm_Flags.ee_error = 0; Nvm_Flags.flash_driver_loaded = 0; Nvm_Flags.erased = 0; Nvm_Flags.ee_error = (EE_OK != EE_Init(EE_CONDITIONAL_ERASE)) ? 1 : 0; } bool NVM_Is_Busy(void) { return (Nvm_Flags.busy != 0); } static void FblReadPattern(uint8_t *data, uint32_t addr) { uint32_t temp = *((uint32_t *)(addr)); data[0] = (uint8_t)temp; data[1] = (uint8_t)(temp >> 8); data[2] = (uint8_t)(temp >> 16); data[3] = (uint8_t)(temp >> 24); temp = *((uint32_t *)(addr + 4)); data[4] = (uint8_t)temp; data[5] = (uint8_t)(temp >> 8); data[6] = (uint8_t)(temp >> 16); data[7] = (uint8_t)(temp >> 24); } /** * @brief load program data blcok to ram * * @param data */ extern int8_t Fbl_CheckPresent() { int8_t rtn = 1; uint8_t i = 1; uint8_t prensnttemp[8] = {0}; uint8_t prensntmasktemp[8] = {0}; FblReadPattern(prensnttemp, APP_PRESENT_ADDR); FblReadPattern(prensntmasktemp, APP_PRESENT_MASK_ADDR); for (i = 0; i < APPPresencePatternSize; i++) { if ((prensnttemp[i] + prensntmasktemp[i]) != 0xff) { rtn = 0; break; } } return rtn; } extern uint8_t ApplFblIsValidApp() { return Fbl_CheckPresent(); } extern int8_t Fbl_SetPresent(void) { int8_t rtn = OP_STATUS_FAIL; EE_Status retValue1 = EE_WRITE_ERROR; EE_Status retValue2 = EE_WRITE_ERROR; present_temp = *(uint64_t *)prensnt; retValue1 = FI_WriteDoubleWord(APP_PRESENT_ADDR, present_temp); present_temp = *(uint64_t *)prensntmask; retValue2 = FI_WriteDoubleWord(APP_PRESENT_MASK_ADDR, present_temp); if ((retValue1 == EE_OK) && (retValue2 == EE_OK)) { // rtn = OP_STATUS_OK; rtn = DID_SaveProgamDataToNvm(); } return rtn; } extern int8_t NVM_EraseData(uint32_t startaddr, uint32_t length) { int8_t ret = OP_STATUS_FAIL; uint32_t page = 48u; uint16_t nbpage = length % FLASH_PAGE_SIZE; if (nbpage) { nbpage = length / FLASH_PAGE_SIZE + 1; } else { nbpage = length / FLASH_PAGE_SIZE; } page = PAGE(startaddr); if (EE_OK != FI_PageErase(PAGE(APP_PRESENT_ADDR), 1)) // erase the flash present part. clear the valid flag { return OP_STATUS_FAIL; } if (EE_OK != FI_PageErase(page, nbpage)) // erase all falsh to 0xff { return OP_STATUS_FAIL; } return OP_STATUS_OK; } extern int8_t NVM_FlashCRCCheck(uint8_t *ptrdata) { int8_t ret = OP_STATUS_FAIL; uint32_t crc = 0; uint32_t init_crc = 0xFFFFFFFF; crc = CRC_Cal32(init_crc, ptrdata + 4, RAM_FALSH_DRIVE_LENGHT); crc = crc ^ init_crc; if (crc == *((uint32_t *)ptrdata)) { ret = OP_STATUS_OK; } return ret; } extern int8_t NVM_ReInitFlashDriveRam(void) { memset((void *)flashCode, 0x0, RAM_FALSH_DRIVE_LENGHT + 4); } extern int8_t NEM_WriteData(MEM_OPERATION_Ts *op) { int8_t ret = OP_STATUS_FAIL; uint16_t i = 0; EE_Status result = EE_OK; // MEM_OPERATION_Ts *op_temp = op; switch (op->partition_id) { case MEM_PARTITION_RAM: memcpy((void *)op->start_addr, op->p_buffer, op->size_in_bytes); ret = OP_STATUS_OK; break; case MEM_PARTITION_CODEFLASH: for (i = 0; i < op->size_in_bytes; i += EE_ELEMENT_SIZE) { result += FI_WriteDoubleWord(op->start_addr, *((uint64_t *)op->p_buffer)); op->start_addr += EE_ELEMENT_SIZE; op->p_buffer += EE_ELEMENT_SIZE; } if (result == EE_OK) { ret = OP_STATUS_OK; } break; default: ret = OP_STATUS_FAIL; break; } } extern uint8_t MEM_PartitionCRCOK(uint8_t partionid) { uint8_t ret = 0; switch (partionid) { case MEM_PARTITION_CODEFLASH: ret = (OP_STATUS_OK == NVM_FlashCRCCheck((uint8_t *)APPCODE_START)); if (ret == 1) { // write present flag if (OP_STATUS_FAIL == Fbl_SetPresent()) { ret = 0; } } /* code */ break; case MEM_PARTITION_RAM: ret = (OP_STATUS_OK == NVM_FlashCRCCheck(flashCode)); if (ret == 1) { Nvm_Flags.flash_driver_loaded = 1; } break; default: break; } return ret; }