Гхм. Соль/перец по вкусу // настройки Option Bytes
#ifdef NDEBUG
# define STM_OB_RDP 0xAA55
# define STM_OB_USER 0xC03F
# define STM_OB_WRP0 0x01FE
#else
# define STM_OB_RDP 0x55AA
# define STM_OB_USER 0x807F
# define STM_OB_WRP0 0x00FF
#endif // NDEBUG
// включает защиту от записи и чтения
void flash_protect(void)
{
// проверим, не было ли прошито раньше?
if ( (OB->RDP == STM_OB_RDP) &&
(OB->USER == STM_OB_USER) &&
(OB->WRP0 == STM_OB_WRP0)
)
{
return;
}
if (FLASH->CR & FLASH_CR_LOCK)
{
FLASH->KEYR = FLASH_FKEY1;
__DSB();
FLASH->KEYR = FLASH_FKEY2;
__DSB();
}
if (!(FLASH->CR & FLASH_CR_OPTWRE))
{
FLASH->OPTKEYR = FLASH_FKEY1;
__DSB();
FLASH->OPTKEYR = FLASH_FKEY2;
__DSB();
}
while (FLASH->SR & FLASH_SR_BSY)
{
__ISB();
}
FLASH->CR |= FLASH_CR_OPTER;
__DSB();
FLASH->CR |= FLASH_CR_STRT;
__DSB();
while (FLASH->SR & FLASH_SR_BSY)
{
__ISB();
}
if (FLASH->SR & FLASH_SR_EOP)
{
FLASH->SR = FLASH_SR_EOP;
}
__DSB();
FLASH->CR &= ~FLASH_CR_OPTER;
__DSB();
FLASH->CR |= FLASH_CR_OPTPG;
__DSB();
OB->RDP = STM_OB_RDP;
__DSB();
while (FLASH->SR & FLASH_SR_BSY)
{
__ISB();
}
FLASH->SR = FLASH_SR_EOP;
__DSB();
OB->USER = STM_OB_USER;
__DSB();
while (FLASH->SR & FLASH_SR_BSY)
{
__ISB();
}
FLASH->SR = FLASH_SR_EOP;
__DSB();
OB->WRP0 = STM_OB_WRP0;
__DSB();
while (FLASH->SR & FLASH_SR_BSY)
{
__ISB();
}
FLASH->SR = FLASH_SR_EOP;
__DSB();
FLASH->CR &= ~FLASH_CR_OPTPG;
__DSB();
FLASH->CR |= FLASH_CR_LOCK;
}