#include "flash.h" #include namespace Ion { namespace Flash { namespace Device { static inline void wait() { // Wait for pending Flash operations to complete while (FLASH.SR()->getBSY()) { } } static void open() { // Unlock the Flash configuration register if needed if (FLASH.CR()->getLOCK()) { FLASH.KEYR()->set(0x45670123); FLASH.KEYR()->set(0xCDEF89AB); } assert(FLASH.CR()->getLOCK() == false); // Set the programming parallelism FLASH.CR()->setPSIZE(MemoryAccessWidth); } static void close() { // Lock the Flash configuration register assert(!FLASH.CR()->getMER()); assert(!FLASH.CR()->getSER()); assert(!FLASH.CR()->getPG()); FLASH.CR()->setLOCK(true); // Purge Data and instruction cache if (FLASH.ACR()->getDCEN()) { FLASH.ACR()->setDCEN(false); FLASH.ACR()->setDCRST(true); FLASH.ACR()->setDCRST(false); FLASH.ACR()->setDCEN(true); } if (FLASH.ACR()->getICEN()) { FLASH.ACR()->setICEN(false); FLASH.ACR()->setICRST(true); FLASH.ACR()->setICRST(false); FLASH.ACR()->setICEN(true); } } static void typed_memcpy(uint8_t * source, uint8_t * destination, size_t length) { MemoryAccessType * src = reinterpret_cast(source); MemoryAccessType * dst = reinterpret_cast(destination); for (size_t i=0; isetMER(true); FLASH.CR()->setSTRT(true); wait(); FLASH.CR()->setMER(false); close(); } void EraseSector(int i) { assert(i >= 0 && i < NumberOfSectors); open(); FLASH.CR()->setSNB(i); FLASH.CR()->setSER(true); FLASH.CR()->setSTRT(true); wait(); FLASH.CR()->setSNB(0); FLASH.CR()->setSER(false); close(); } void WriteMemory(uint8_t * source, uint8_t * destination, size_t length) { open(); FLASH.CR()->setPG(true); typed_memcpy(source, destination, length); wait(); FLASH.CR()->setPG(false); close(); } } } }