Hello @Shaf ,
I could not reproduce your issue. You can find the full example below.
For the RDP configuration:
- Wait until the flash is not busy
- Unlock the flash
- Unlock the option bytes
- Save the current content of the OPTR register in a temporary variable
- Make the necessary changes to that variable by setting the RDP level
- Write the temporary variable back to the OPTR register and start programming
- Launch the option byte reload operation, which will cause a system reset
- Lock the flash and the option byte registers
In the example below, I used the C0 BSP to control the LED and the user button, but you can use HAL for that instead.
The example waits for the user button press and, depending on the current RDP level, either enables or disables flash access.
For each RDP level state, you need to power cycle the board by unplugging and reconnecting the power supply, such as the USB cable.
Also, you cannot use the debugger session after RDP Level 1 is set. You need to close the debug session and power cycle the board.
typedef enum {
e_SUCCESS = 0, e_ERROR, e_FLASH_UNLOCKED , e_FLASH_OPT_UNLOCKED
} eFLASH_ErrorType_t;
eFLASH_ErrorType_t CheckFlashBusy() {
while (FLASH->SR & FLASH_SR_BSY1) {
}
return e_SUCCESS;
}
eFLASH_ErrorType_t flashUnlock(){
if (FLASH->CR & FLASH_CR_LOCK)
{
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR= FLASH_KEY2;
return e_FLASH_UNLOCKED ;
}
return e_ERROR;
}
eFLASH_ErrorType_t flashOptUnlock() {
if (FLASH->CR & FLASH_CR_OPTLOCK) {
FLASH->OPTKEYR = FLASH_OPTKEY1;
FLASH->OPTKEYR = FLASH_OPTKEY2;
return e_FLASH_OPT_UNLOCKED;
}
return e_ERROR;
}
eFLASH_ErrorType_t FlashReadWriteEnable(void)
{
eFLASH_ErrorType_t err_code = e_SUCCESS;
err_code = CheckFlashBusy();
if (err_code == e_SUCCESS) {
err_code = flashUnlock();
if (err_code == e_FLASH_UNLOCKED) {
err_code = flashOptUnlock();
if (err_code == e_FLASH_OPT_UNLOCKED) {
uint32_t optr = FLASH->OPTR;
optr &= ~FLASH_OPTR_RDP_Msk;
optr |= (0xBB << FLASH_OPTR_RDP_Pos);
FLASH->OPTR = optr;
FLASH->CR |= FLASH_CR_OPTSTRT;
err_code = CheckFlashBusy();
if (err_code == e_SUCCESS) {
FLASH->CR |= FLASH_CR_OBL_LAUNCH;
// lock the flash
FLASH->CR |= FLASH_CR_LOCK;
FLASH->CR |= FLASH_CR_OPTLOCK ;
// This will perform a system reset
return e_ERROR;
}
}
}
}
return e_SUCCESS;
}
eFLASH_ErrorType_t FlashReadWriteDisable(void)
{
eFLASH_ErrorType_t err_code = e_SUCCESS;
err_code = CheckFlashBusy();
if (err_code == e_SUCCESS) {
err_code = flashUnlock();
if (err_code == e_FLASH_UNLOCKED) {
err_code = flashOptUnlock();
if (err_code == e_FLASH_OPT_UNLOCKED) {
uint32_t optr = FLASH->OPTR;
optr &= ~FLASH_OPTR_RDP_Msk;
optr |= ( 0xAA << FLASH_OPTR_RDP_Pos);
FLASH->OPTR = optr;
FLASH->CR |= FLASH_CR_OPTSTRT;
err_code = CheckFlashBusy();
if (err_code == e_SUCCESS) {
// This will perform a system reset
FLASH->CR |= FLASH_CR_OBL_LAUNCH;
// lock the flash
FLASH->CR |= FLASH_CR_LOCK;
FLASH->CR |= FLASH_CR_OPTLOCK ;
}
}
}
}
return err_code;
}
// main
int main(void) {
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Initialize leds */
BSP_LED_Init(LED_GREEN);
BSP_LED_Init(LED_BLUE);
/* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
uint32_t state = 0;
if ((FLASH->OPTR & FLASH_OPTR_RDP) == 0xBB) {
BSP_LED_On(LED_BLUE);
state = 1;
} else if ((FLASH->OPTR & FLASH_OPTR_RDP) == 0xAA) {
BSP_LED_On(LED_GREEN);
state = 2;
}
if (BSP_PB_GetState(BUTTON_USER) == 0) {
if (state == 1) {
FlashReadWriteDisable();
} else if (state == 2) {
FlashReadWriteEnable();
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Best regards,