// // Created by cfif on 07.10.22. // #include "SystemDelayInterface.h" #include "InternalFlashPage.h" uint32_t iInternalFlashPage_ReadWord(uint32_t addressOnFlash) { return (*(__IO uint32_t *) (addressOnFlash)); } size_t sInternalFlashPage_Read( uint32_t pageAddress, size_t offset, uint8_t *data, size_t size ) { if ((offset & (uint32_t) 0x3) != 0) { // The offset is not a multiple of 4 return 0; } size_t left = size; while (left) { if (left >= 4) { *((uint32_t *) data) = iInternalFlashPage_ReadWord(pageAddress + offset); data += 4; offset += 4; left -= 4; } else { uint32_t word = iInternalFlashPage_ReadWord(pageAddress + offset); for (uint8_t sub_byte = 0; sub_byte < left; ++sub_byte) { *data = ((uint8_t *) &word)[sub_byte]; ++data; } offset += 4; left = 0; } } return size; } bool bInternalFlashPage_Clear( uint32_t pageAddress ) { flash_unlock(); // if (FLASH_OPERATE_DONE != flash_block_erase(pageAddress)) { // return false; // } if (FLASH_OPERATE_DONE != flash_sector_erase(pageAddress)) { flash_lock(); return false; } flash_lock(); return true; } bool bInternalFlashPage_ClearRange( uint32_t firstPageAddr, uint32_t totalSize ) { if (totalSize % FLASH_PAGE_SIZE) { return false; } uint32_t endAddr = firstPageAddr + totalSize; for (; firstPageAddr < endAddr; firstPageAddr += FLASH_PAGE_SIZE) { if (!bInternalFlashPage_Clear(firstPageAddr)) { return false; } } return true; } bool bInternalFlashPage_CopyRange( uint32_t targetPageAddr, uint32_t sourcePageAddr, uint32_t size ) { if (!bInternalFlashPage_ClearRange(targetPageAddr, size)) { return false; } flash_unlock(); for (size_t i = 0; i < size; ++i) { if (FLASH_OPERATE_DONE != flash_byte_program(targetPageAddr + i, (*(__IO uint8_t *) (sourcePageAddr + i)))) { flash_lock(); return i; } } flash_lock(); return size; /* flash_unlock(); uint32_t offset = 0; uint32_t word; while (offset < size) { word = iInternalFlashPage_ReadWord(sourcePageAddr + offset); if (FLASH_OPERATE_DONE != flash_word_program(targetPageAddr + offset, word)) { flash_lock(); // whole isn't written return offset; } offset += 4; } flash_lock(); return size; */ } size_t bInternalFlashPage_DumpFromRam( uint32_t beginPageAddr, void *sourceRamAddr, uint32_t size ) { size_t alignedSize = ((size / FLASH_PAGE_SIZE) + (size % FLASH_PAGE_SIZE ? 1 : 0)) * FLASH_PAGE_SIZE; if (!bInternalFlashPage_ClearRange(beginPageAddr, alignedSize)) { return 0; } flash_unlock(); for (size_t i = 0; i < size; ++i) { if (FLASH_OPERATE_DONE != flash_byte_program(beginPageAddr + i, ((uint8_t*)sourceRamAddr)[i])) { flash_lock(); return i; } } flash_lock(); return size; /* flash_unlock(); uint32_t offset = 0; uint32_t word; while (offset < size) { word = *(uint32_t *) (sourceRamAddr + offset); if (size < 4) { word = word & (0xFFFFFFFF >> (8 * (4 - size))); } if (FLASH_OPERATE_DONE != flash_word_program(beginPageAddr + offset, word)) { flash_lock(); // whole isn't written return offset; } offset += 4; } flash_lock(); return offset; */ } size_t sInternalFlashPage_Write( uint32_t pageAddress, size_t offset, uint8_t *data, size_t size ) { flash_unlock(); for (size_t i = 0; i < size; ++i) { if (FLASH_OPERATE_DONE != flash_byte_program(pageAddress + i + offset, data[i])) { flash_lock(); return i; } } flash_lock(); return size; /* flash_unlock(); size_t left = size; while (left) { if (left >= 4) { if (FLASH_OPERATE_DONE != flash_word_program(pageAddress + offset, *((uint32_t *) data))) { // whole isn't written return size - left; } data += 4; offset += 4; left -= 4; } else { uint32_t word; for (uint8_t sub_byte = 0; sub_byte < 4; ++sub_byte) { if (sub_byte < left) { ((uint8_t *) &word)[sub_byte] = *data; ++data; } else { ++size; ((uint8_t *) &word)[sub_byte] = 0; } } if (FLASH_OPERATE_DONE != flash_word_program(pageAddress + offset, word)) { // whole isn't written return size - left; } offset += 4; left = 0; } } flash_lock(); return size; */ }