OpenSolo/artoo/src/stm32/mcuflash.h

115 lines
2.5 KiB
C++

#ifndef MCU_FLASH_H
#define MCU_FLASH_H
/*
* Routines for managing the internal MCU flash on the STM32.
* Typical endurance is minimum 10 kcycles.
*/
#include "hw.h"
class McuFlash
{
public:
// high-density line specific values
static const unsigned PAGE_SIZE = 2048;
static const unsigned NUM_PAGES = 128;
static const uint32_t START_ADDR = 0x8000000;
static const uint32_t END_ADDR = START_ADDR + (NUM_PAGES * PAGE_SIZE);
enum CrBits {
CR_PG = (1 << 0),
CR_PER = (1 << 1),
CR_MER = (1 << 2),
CR_OPTPG = (1 << 4),
CR_OPTER = (1 << 5),
CR_STRT = (1 << 6),
CR_LOCK = (1 << 7),
CR_OPTWRE = (1 << 9),
CR_ERRIE = (1 << 10),
CR_EOPIE = (1 << 12),
};
enum SrBits {
SR_BSY = (1 << 0),
SR_PGERR = (1 << 2),
SR_WRPRTERR = (1 << 4),
SR_EOP = (1 << 5),
};
static inline bool isLocked() {
return FLASH.CR & CR_LOCK;
}
static inline void unlock() {
FLASH.KEYR = KEY1;
FLASH.KEYR = KEY2;
}
static inline void lock() {
FLASH.CR |= CR_LOCK;
}
static inline void unlockOptionBytes() {
FLASH.OPTKEYR = KEY1;
FLASH.OPTKEYR = KEY2;
}
/*
* Programming (synchronous for now):
* - beginProgramming()
* - one or more calls to programHalfWord()
* - endProgramming()
*/
static inline void beginProgramming() {
FLASH.CR |= CR_PG;
}
static bool programHalfWord(uint16_t halfword, uint32_t address);
static inline void endProgramming() {
waitForPreviousOperation();
FLASH.CR &= ~CR_PG;
}
/*
* Erasing must occur a page at a time.
*/
static bool erasePage(uint32_t address);
static bool readOutProtectionIsEnabled() {
return (FLASH.OBR & (1 << 1)) != 0;
}
enum OptionByte {
OptionRDP,
OptionUSER,
OptionDATA0,
OptionDATA1,
OptionWRP0,
OptionWRP1,
OptionWRP2,
OptionWRP3,
};
static bool eraseOptionBytes(bool enableRDP = false);
static bool setOptionByte(OptionByte ob, uint16_t value);
private:
static const uint16_t RDP_DISABLE_KEY = 0x00A5;
static const uint32_t KEY1 = 0x45670123;
static const uint32_t KEY2 = 0xCDEF89AB;
enum Status {
StatusComplete,
StatusProgrammingErr,
StatusWriteProtectErr
};
static Status waitForPreviousOperation();
};
#endif // MCU_FLASH_H