mirror of https://github.com/rusefi/wideband.git
87 lines
1.8 KiB
C++
87 lines
1.8 KiB
C++
#include "flash.h"
|
|
#include "hal.h"
|
|
|
|
|
|
/**
|
|
* @brief Wait for the flash operation to finish.
|
|
*/
|
|
static void flashWaitWhileBusy()
|
|
{
|
|
while (FLASH->SR & FLASH_SR_BSY) ;
|
|
}
|
|
|
|
static void flashUnlock() {
|
|
/* Check if unlock is really needed */
|
|
if (!(FLASH->CR & FLASH_CR_LOCK))
|
|
return;
|
|
|
|
/* Write magic unlock sequence */
|
|
FLASH->KEYR = 0x45670123;
|
|
FLASH->KEYR = 0xCDEF89AB;
|
|
}
|
|
|
|
static void flashLock() {
|
|
FLASH->CR |= FLASH_CR_LOCK;
|
|
}
|
|
|
|
void Flash::ErasePage(uint8_t pageIdx) {
|
|
flashUnlock();
|
|
|
|
// Wait for flash to be not busy
|
|
flashWaitWhileBusy();
|
|
|
|
// page erase mode
|
|
FLASH->CR |= FLASH_CR_PER;
|
|
|
|
// Set page number
|
|
FLASH->AR = pageIdx * 1024;
|
|
|
|
// Start the erase operation
|
|
FLASH->CR |= FLASH_CR_STRT;
|
|
|
|
// Must wait at least one cycle before reading FLASH_SR_BSY
|
|
__asm__ __volatile__("nop");
|
|
|
|
// Wait for flash to be not busy
|
|
flashWaitWhileBusy();
|
|
|
|
// clear page erase bit
|
|
FLASH->CR &= ~FLASH_CR_PER;
|
|
|
|
// Relock flash
|
|
flashLock();
|
|
}
|
|
|
|
static void flashWriteData(flashaddr_t address, const flashdata_t data) {
|
|
/* Enter flash programming mode */
|
|
FLASH->CR |= FLASH_CR_PG;
|
|
|
|
/* Write the data */
|
|
*(flashdata_t*) address = data;
|
|
|
|
/* Wait for completion */
|
|
flashWaitWhileBusy();
|
|
|
|
/* Exit flash programming mode */
|
|
FLASH->CR &= ~FLASH_CR_PG;
|
|
}
|
|
|
|
void Flash::Write(flashaddr_t address, const uint8_t* buffer, size_t size) {
|
|
/* Unlock flash for write access */
|
|
flashUnlock();
|
|
|
|
/* Wait for any busy flags */
|
|
flashWaitWhileBusy();
|
|
|
|
//Copy data directly from buffer's data to flash
|
|
while (size >= sizeof(flashdata_t)) {
|
|
flashWriteData(address, *(const flashdata_t*) buffer);
|
|
address += sizeof(flashdata_t);
|
|
buffer += sizeof(flashdata_t);
|
|
size -= sizeof(flashdata_t);
|
|
}
|
|
|
|
/* Lock flash again */
|
|
flashLock();
|
|
}
|