#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, uint32_t targetcrc, uint32_t len) { int8_t ret = OP_STATUS_FAIL; uint32_t crc = 0; uint32_t init_crc = 0xFFFFFFFF; crc = CRC_Cal32(init_crc, ptrdata, len); crc = crc ^ init_crc; if (crc == targetcrc) { ret = OP_STATUS_OK; } return ret; } // extern int8_t NVM_FlashDriverCRCCheck(uint8_t *ptrdata, uint32_t targetcrc, uint32_t len) // { // int8_t ret = OP_STATUS_FAIL; // uint32_t crc = 0; // uint32_t init_crc = 0xFFFFFFFF; // crc = CRC_Cal32(init_crc, ptrdata, len); // crc = crc ^ init_crc; // if (crc == targetcrc) // { // 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; } } static void NVM_FlipEndian(void *address, uint16_t size) { uint8_t temp = 0; uint8_t i = 0; for (i = size; i > size / 2; i--) { temp = ((uint8_t *)address)[size - i]; ((uint8_t *)address)[size - i] = ((uint8_t *)address)[i - 1]; ((uint8_t *)address)[i - 1] = temp; } } extern uint8_t MEM_PartitionCRCOK(uint8_t partionid, uint32_t targetcrc) { uint8_t ret = 0; uint32_t length = 0; targetcrc = targetcrc ^ 0xFFFFFFFF; switch (partionid) { case MEM_PARTITION_CODEFLASH: length = *((uint32_t *)(APPCODE_START + 12)); NVM_FlipEndian((void *)&length, 4); length -= 4; ret = (OP_STATUS_OK == NVM_FlashCRCCheck((uint8_t *)(APPCODE_START + 4), targetcrc, length)); if (ret == 1) { // write present flag if (OP_STATUS_FAIL == Fbl_SetPresent()) { ret = 0; } } /* code */ break; case MEM_PARTITION_RAM: length = RAM_FALSH_DRIVE_LENGHT; ret = (OP_STATUS_OK == NVM_FlashCRCCheck(flashCode, targetcrc, length)); if (ret == 1) { Nvm_Flags.flash_driver_loaded = 1; } break; default: break; } return ret; }