Beispiel #1
0
void memory_protect(void) {
#if MEMORY_PROTECT
  // Reference STM32F205 Flash programming manual revision 5
  // http://www.st.com/resource/en/programming_manual/cd00233952.pdf Section 2.6
  // Option bytes
  //                     set RDP level 2                   WRP for sectors 0 and
  //                     1            flash option control register matches
  if (((FLASH_OPTION_BYTES_1 & 0xFFEC) == 0xCCEC) &&
      ((FLASH_OPTION_BYTES_2 & 0xFFF) == 0xFFC) &&
      (FLASH_OPTCR == 0x0FFCCCED)) {
    return;  // already set up correctly - bail out
  }
  for (int i = FLASH_STORAGE_SECTOR_FIRST; i <= FLASH_STORAGE_SECTOR_LAST;
       i++) {
    flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
  }
  flash_unlock_option_bytes();
  // Section 2.8.6 Flash option control register (FLASH_OPTCR)
  //   Bits 31:28 Reserved, must be kept cleared.
  //   Bits 27:16 nWRP: Not write protect: write protect bootloader code in
  //   flash main memory sectors 0 and 1 (Section 2.3; table 2) Bits 15:8 RDP:
  //   Read protect: level 2 chip read protection active Bits 7:5 USER: User
  //   option bytes: no reset on standby, no reset on stop, software watchdog
  //   Bit 4 Reserved, must be kept cleared.
  //   Bits 3:2 BOR_LEV: BOR reset Level: BOR off
  //   Bit 1 OPTSTRT: Option start: ignored by flash_program_option_bytes
  //   Bit 0 OPTLOCK: Option lock: ignored by flash_program_option_bytes
  flash_program_option_bytes(0x0FFCCCEC);
  flash_lock_option_bytes();
#endif
}
Beispiel #2
0
void flash_program_option_bytes(u32 data)
{
	flash_wait_for_last_operation();

	if (FLASH_OPTCR & FLASH_OPTLOCK)
		flash_unlock_option_bytes();

	FLASH_OPTCR = data & ~0x3;
	FLASH_OPTCR |= FLASH_OPTSTRT;	/* Enable option byte programming. */
	flash_wait_for_last_operation();
}
Beispiel #3
0
void flash_program_option_bytes(u32 address, u16 data)
{
	flash_wait_for_last_operation();

	if ((FLASH_CR & FLASH_CR_OPTWRE) == 0)
		flash_unlock_option_bytes();

	FLASH_CR |= FLASH_CR_OPTPG;	/* Enable option byte programming. */
	(*(volatile u16 *)address) = data;
	flash_wait_for_last_operation();
	FLASH_CR &= ~FLASH_CR_OPTPG;	/* Disable option byte programming. */
}
Beispiel #4
0
void flash_erase_option_bytes(void)
{
	flash_wait_for_last_operation();

	if ((FLASH_CR & FLASH_CR_OPTWRE) == 0)
		flash_unlock_option_bytes();

	FLASH_CR |= FLASH_CR_OPTER;	/* Enable option byte erase. */
	FLASH_CR |= FLASH_CR_STRT;
	flash_wait_for_last_operation();
	FLASH_CR &= ~FLASH_CR_OPTER;	/* Disable option byte erase. */
}
Beispiel #5
0
void flash_program_option_bytes(uint32_t address, uint16_t data)
{
	flash_wait_for_last_operation();

	if ((FLASH_CR & FLASH_CR_OPTWRE) == 0) {
		flash_unlock_option_bytes();
	}

	FLASH_CR |= FLASH_CR_OPTPG;	/* Enable option byte programming. */
	MMIO16(address) = data;
	flash_wait_for_last_operation();
	FLASH_CR &= ~FLASH_CR_OPTPG;	/* Disable option byte programming. */
}
/** Unlock a sector of the STM flash memory.
 * Locked sectors can not be erased or programmed.
 *
 * \param sector Number of the sector to unlock.
 * \return Error code
 */
u8 stm_flash_unlock_sector(u8 sector)
{
  /* Check that sector argument is valid. */
  if (sector >= STM_FLASH_N_SECTORS)
    return FLASH_INVALID_SECTOR;

  flash_unlock_option_bytes();
  while (FLASH_SR & FLASH_SR_BSY) ;
  FLASH_OPTCR |= (1 << (16+sector));
  FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT;
  while (FLASH_SR & FLASH_SR_BSY) ;

  return FLASH_OK;
}
Beispiel #7
0
void memory_unlock(void) {
#ifndef EMULATOR
    // This exercises a bug in the STM32F2 that allows writing to read-only
    // sectors of flash.
    flash_unlock_option_bytes();
    
#ifdef DEBUG_ON
    // 0xFFFAAEC: remove wp from all sectors, no RDP (unless previously set to level 2 which is irreversible), 
    // disable configurable resets. Low order two bits are don't care.
    flash_program_option_bytes(0x0FFFAAEC);
#else
    // Even though level 2 is described as sticky, this chip has a proven bug related to this register so 
    // to be sure rewrite the level two value for RDP for non-debug builds.
    flash_program_option_bytes(0x0FFFCCEC);
#endif

    flash_lock_option_bytes();
#endif
}
Beispiel #8
0
/*
 * memory_protect() - Set option bytes for memory protection
 *
 * INPUT
 *     none
 * OUTPUT
 *     none
 */
void memory_protect(void)
{
#ifndef EMULATOR
    /*                     set RDP level 2                   WRP for sectors 0,5,6  */
    if((((*OPTION_BYTES_1) & 0xFFFF) == OPTION_RDP) && (((*OPTION_BYTES_2) & 0xFFFF) == OPTION_WRP))
    {
        return; // already set up correctly - bail out
    }

    flash_unlock_option_bytes();
    /*                              WRP +    RDP */

#if !defined(DEBUG_ON)  // safety check to make sure mem protect disabled in debug builds
    flash_program_option_bytes((uint32_t)OPTION_WRP << 16 | OPTION_RDP);  //RDP BLevel 2 (Irreversible)
#endif

    flash_lock_option_bytes();
#else
    printf("memory protect ON\n");
#endif
}
Beispiel #9
0
// Remove write-protection on all flash sectors.
//
// This is an undocumented feature/bug of STM32F205/F405 microcontrollers,
// where flash controller reads its write protection bits from FLASH_OPTCR
// register not from OPTION_BYTES, rendering write protection useless.
// This behaviour is fixed in future designs of flash controller used for
// example in STM32F427, where the protection bits are read correctly
// from OPTION_BYTES and not form FLASH_OPCTR register.
//
// Read protection is unaffected and always stays locked to the desired value.
void memory_write_unlock(void) {
  flash_unlock_option_bytes();
  flash_program_option_bytes(0x0FFFCCEC);
  flash_lock_option_bytes();
}