// // Created by cfif on 07.10.22. // #include "InternalFlashPage.h" #include "StorageOnFlashFlagchip.h" static uint32_t xStorageOnFlashArtery_Crc(uint8_t *data, size_t len) { uint32_t crc = 0; uint8_t *end = data + len; while (data < end) { crc += *data; ++data; } return crc; } static uint32_t xStorageOnFlashArtery_CrcFlash(uint8_t *addressOnFlash, size_t len) { uint32_t crc = 0; size_t left = len; uint8_t *end = addressOnFlash + len; uint32_t word; while (addressOnFlash < end) { word = iInternalFlashPage_ReadWord((uint32_t) addressOnFlash); for (uint8_t sub_byte = 0; (sub_byte < 4) && (left); ++sub_byte) { crc += ((uint8_t *) &word)[sub_byte]; --left; } addressOnFlash += 4; } return crc; } static eStorageStatus xStorageOnFlashFlagchip_DumpOn( tStorageOnFlashFlagchip *env, uint32_t dataCrc, uint32_t pageAddress, void *data, size_t size ) { // if (!bInternalFlashPage_Clear(pageAddress)) { // return STORAGE_ERR_DEVICE; // } // // size_t dataSizeOnFlash = sInternalFlashPage_Write(pageAddress, 0x0, env->data, env->size); size_t dataSizeOnFlash = bInternalFlashPage_DumpFromRam(pageAddress, data, size); if (dataSizeOnFlash < size) { return STORAGE_ERR_DEVICE; } if (sInternalFlashPage_Write(pageAddress, dataSizeOnFlash, (uint8_t *) &dataCrc, 4) != 4) { return STORAGE_ERR_DEVICE; } uint32_t flashCalcCrc = xStorageOnFlashArtery_CrcFlash((uint8_t *) pageAddress, size); uint32_t flashReedCrc = iInternalFlashPage_ReadWord(pageAddress + dataSizeOnFlash); if ((flashCalcCrc == flashReedCrc) && (flashCalcCrc == dataCrc)) { return STORAGE_OK; } else { return STORAGE_ERR_DATA; } } static uint8_t xStorageOnFlashFlagchip_Dump(tStorageOnFlashFlagchip *env, void *data, size_t size) { uint32_t crc = xStorageOnFlashArtery_Crc(data, size); if (xStorageOnFlashFlagchip_DumpOn(env, crc, env->recoveryFlashPageAddress, data, size) != STORAGE_OK) { return STORAGE_ERR_DEVICE; } if (xStorageOnFlashFlagchip_DumpOn(env, crc, env->mainFlashPageAddress, data, size) != STORAGE_OK) { return STORAGE_ERR_DEVICE; } return STORAGE_OK; } eStorageStatus xStorageOnFlashFlagchip_Load(tStorageOnFlashFlagchip *env, void *data, size_t size) { size_t dataSizeOnFlash = size;//(size + 3) & (~3); // выравниваем до кратного 4 (целое количество слов) uint32_t recoveryCrcCalc = xStorageOnFlashArtery_CrcFlash((uint8_t *) env->recoveryFlashPageAddress, size); uint32_t recoveryCrcReed = iInternalFlashPage_ReadWord(env->recoveryFlashPageAddress + dataSizeOnFlash); uint32_t mainCrcCalc = xStorageOnFlashArtery_CrcFlash((uint8_t *) env->mainFlashPageAddress, size); uint32_t mainCrcReed = iInternalFlashPage_ReadWord(env->mainFlashPageAddress + dataSizeOnFlash); bool recoveryCrcOk = (recoveryCrcCalc == recoveryCrcReed); bool mainCrcOk = (mainCrcReed == mainCrcCalc); if (recoveryCrcOk && mainCrcOk) { if (recoveryCrcReed == mainCrcReed) { sInternalFlashPage_Read(env->mainFlashPageAddress, 0x0, data, size); return STORAGE_OK; } else { sInternalFlashPage_Read(env->recoveryFlashPageAddress, 0x0, data, size); return xStorageOnFlashFlagchip_DumpOn(env, recoveryCrcCalc, env->mainFlashPageAddress, data, size); } } else if (recoveryCrcOk || mainCrcOk) { if (recoveryCrcOk) { sInternalFlashPage_Read(env->recoveryFlashPageAddress, 0x0, data, size); return xStorageOnFlashFlagchip_DumpOn(env, recoveryCrcCalc, env->mainFlashPageAddress, data, size); } else { sInternalFlashPage_Read(env->mainFlashPageAddress, 0x0, data, size); return xStorageOnFlashFlagchip_DumpOn(env, mainCrcCalc, env->recoveryFlashPageAddress, data, size); } } else { return STORAGE_ERR_DATA; } } void vStorageOnFlashFlagchip_Init( tStorageOnFlashFlagchip *env, uint32_t mainPage, uint32_t recoveryPage ) { env->mainFlashPageAddress = mainPage; env->recoveryFlashPageAddress = recoveryPage; } tStorageInterface xStorageOnFlashFlagchip_GetInterface(tStorageOnFlashFlagchip *env) { return (tStorageInterface) { .env = env, .load = (StorageIOTransaction) xStorageOnFlashFlagchip_Load, .dump = (StorageIOTransaction) xStorageOnFlashFlagchip_Dump, }; }