execUserFlashInit()
{
  // This is already implemented in I-Jet/CMSISDAP/J-Link support.
  if(!(__driverType("ijet") || __driverType("cmsisdap") || __driverType("jlink")))
  {
    // Enable DBGMCU clock (RCC_APB1ENR)
    __writeMemory32(0x08000000, 0x4002103C, "Memory");
    // Stop WDTs when CPU is halted, DBG_IWDG_STOP、DBG_WWDG_STOP
    __writeMemory32(0x00001800, 0x40015808, "Memory");
  }

  // Check if readout protection is enabled
  if (0x55 & __readMemory32(0x40022020,"Memory"))
  {

	if (!__messageBoxYesCancel("Do you want to perform mass erase to unlock the device?", "Unlocking device"))
    {
      __abortLaunch("Unlock cancelled. Debug session cannot continue.");
    }
	
    __writeMemory32(0x45670123, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY1;
    __writeMemory32(0xCDEF89AB, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY2;
	
    __writeMemory32(0x08192A3B, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY1;
    __writeMemory32(0x4C5D6E7F, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY2;

    __writeMemory32(((__readMemory32(0x40022020,"Memory")&0xFFFFFF00)|0xaa), 0x40022020, "Memory"); // FLASH_OPTR
    __writeMemory32(0x01020000, 0x40022014, "Memory"); // SET FLASH_CR_OPTSTRT
	
	__writeMemory32(0xFFFFFFFFFF, 0x40022080, "Memory");
	
	__delay(100);
    // Wait while FLASH busy
    while(0x00010000 & __readMemory32(0x40022010,"Memory"))
    {
      __delay(100);
    }

	//while(0x1 & __readMemory32(0x40022010,"Memory"))//eop
   // {
     // __delay(100);
    //}
	
	__writeMemory32((__readMemory32(0x40022010,"Memory")|0x1), 0x40022010, "Memory"); // set eop
	
	__writeMemory32((__readMemory32(0x40022014,"Memory")&0xFEFDFFFF), 0x40022014, "Memory"); // CLEAR
	
	__writeMemory32((__readMemory32(0x40022014,"Memory")|0x08000000), 0x40022014, "Memory"); // SET OBL
    __message "Reloading option bytes ...";

    // Set FLASH->CR.OBL_LAUNCH to reload RDP option bytes
    // This will trigger a system reset
    if(__driverType("ijet") || __driverType("cmsisdap"))
    {
      __probeCmd("/noerror dap.w 0x40022014 0x08000000 0");
      __delay(5);
      __probeCmd("j.i /force");
      // Halt CPU;
      __writeMemory32(0xA05F0003, 0xE000EDF0, "Memory");
      while(!(0x00030000 & __readMemory32(0xE000EDF0, "Memory")));
      __probeCmd("refresh");
      __probeCmd("refresh");
    }
    else
    {
      __writeMemory32(0x08000000, 0x40022014, "Memory"); // Option byte reload
      __delay(5);
      __hwReset(0);
    }
  }
}

execUserFlashExit()
{
}
