Skip to content

Commit

Permalink
drivers: flash: stm32 flash driver common functions
Browse files Browse the repository at this point in the history
Move the flash_stm32_write_protection and
flash_stm32_option_bytes_lock functions to a common
file for stm32 devices including stm32h7

Signed-off-by: Francois Ramu <[email protected]>
  • Loading branch information
FRASTM committed Nov 25, 2024
1 parent 8fb0cef commit ab996d4
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 158 deletions.
197 changes: 60 additions & 137 deletions drivers/flash/flash_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ static const struct flash_parameters flash_stm32_parameters = {
#endif
};

static int flash_stm32_write_protection(const struct device *dev, bool enable);

bool __weak flash_stm32_valid_range(const struct device *dev, off_t offset,
uint32_t len, bool write)
{
Expand All @@ -59,6 +57,66 @@ int __weak flash_stm32_check_configuration(void)
}


Check notice on line 59 in drivers/flash/flash_stm32.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/flash/flash_stm32.c:59 -

Check notice on line 59 in drivers/flash/flash_stm32.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/flash/flash_stm32.c:59 -
int flash_stm32_write_protection(const struct device *dev, bool enable)
{
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);

int rc = 0;

if (enable) {
rc = flash_stm32_wait_flash_idle(dev);
if (rc) {
flash_stm32_sem_give(dev);
return rc;
}
}

#if defined(FLASH_SECURITY_NS)
if (enable) {
regs->NSCR |= FLASH_STM32_NSLOCK;
} else {
if (regs->NSCR & FLASH_STM32_NSLOCK) {
regs->NSKEYR = FLASH_KEY1;
regs->NSKEYR = FLASH_KEY2;
}
}
#elif defined(FLASH_CR_LOCK)
if (enable) {
regs->CR |= FLASH_CR_LOCK;
} else {
if (regs->CR & FLASH_CR_LOCK) {
regs->KEYR = FLASH_KEY1;
regs->KEYR = FLASH_KEY2;
}
}
#else
if (enable) {
regs->PECR |= FLASH_PECR_PRGLOCK;
regs->PECR |= FLASH_PECR_PELOCK;
} else {
if (regs->PECR & FLASH_PECR_PRGLOCK) {
LOG_DBG("Disabling write protection");
regs->PEKEYR = FLASH_PEKEY1;
regs->PEKEYR = FLASH_PEKEY2;
regs->PRGKEYR = FLASH_PRGKEY1;
regs->PRGKEYR = FLASH_PRGKEY2;
}
if (FLASH->PECR & FLASH_PECR_PRGLOCK) {
LOG_ERR("Unlock failed");
rc = -EIO;
}
}
#endif /* FLASH_SECURITY_NS */

if (enable) {
LOG_DBG("Enable write protection");
} else {
LOG_DBG("Disable write protection");
}

return rc;
}

#if !defined(CONFIG_SOC_SERIES_STM32WBX)
static int flash_stm32_check_status(const struct device *dev)
{
Expand Down Expand Up @@ -228,141 +286,6 @@ static int flash_stm32_write(const struct device *dev, off_t offset,
return rc;
}

static int flash_stm32_write_protection(const struct device *dev, bool enable)
{
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);

int rc = 0;

if (enable) {
rc = flash_stm32_wait_flash_idle(dev);
if (rc) {
flash_stm32_sem_give(dev);
return rc;
}
}

#if defined(FLASH_SECURITY_NS)
if (enable) {
regs->NSCR |= FLASH_STM32_NSLOCK;
} else {
if (regs->NSCR & FLASH_STM32_NSLOCK) {
regs->NSKEYR = FLASH_KEY1;
regs->NSKEYR = FLASH_KEY2;
}
}
#elif defined(FLASH_CR_LOCK)
if (enable) {
regs->CR |= FLASH_CR_LOCK;
} else {
if (regs->CR & FLASH_CR_LOCK) {
regs->KEYR = FLASH_KEY1;
regs->KEYR = FLASH_KEY2;
}
}
#else
if (enable) {
regs->PECR |= FLASH_PECR_PRGLOCK;
regs->PECR |= FLASH_PECR_PELOCK;
} else {
if (regs->PECR & FLASH_PECR_PRGLOCK) {
LOG_DBG("Disabling write protection");
regs->PEKEYR = FLASH_PEKEY1;
regs->PEKEYR = FLASH_PEKEY2;
regs->PRGKEYR = FLASH_PRGKEY1;
regs->PRGKEYR = FLASH_PRGKEY2;
}
if (FLASH->PECR & FLASH_PECR_PRGLOCK) {
LOG_ERR("Unlock failed");
rc = -EIO;
}
}
#endif /* FLASH_SECURITY_NS */

if (enable) {
LOG_DBG("Enable write protection");
} else {
LOG_DBG("Disable write protection");
}

return rc;
}

int flash_stm32_option_bytes_lock(const struct device *dev, bool enable)
{
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);

#if defined(FLASH_OPTCR_OPTLOCK) /* F2, F4, F7 */
if (enable) {
regs->OPTCR |= FLASH_OPTCR_OPTLOCK;
} else if (regs->OPTCR & FLASH_OPTCR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPT_KEY1;
regs->OPTKEYR = FLASH_OPT_KEY2;
}
#else
int rc;

/* Unlock CR/PECR/NSCR register if needed. */
if (!enable) {
rc = flash_stm32_write_protection(dev, false);
if (rc) {
return rc;
}
}
#if defined(FLASH_CR_OPTWRE) /* F0, F1 and F3 */
if (enable) {
regs->CR &= ~FLASH_CR_OPTWRE;
} else if (!(regs->CR & FLASH_CR_OPTWRE)) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_CR_OPTLOCK) /* G0, G4, L4, WB and WL */
if (enable) {
regs->CR |= FLASH_CR_OPTLOCK;
} else if (regs->CR & FLASH_CR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_PECR_OPTLOCK) /* L0 and L1 */
if (enable) {
regs->PECR |= FLASH_PECR_OPTLOCK;
} else if (regs->PECR & FLASH_PECR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_NSCR_OPTLOCK) /* L5 and U5 */
if (enable) {
regs->NSCR |= FLASH_NSCR_OPTLOCK;
} else if (regs->NSCR & FLASH_NSCR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_NSCR1_OPTLOCK) /* WBA */
if (enable) {
regs->NSCR1 |= FLASH_NSCR1_OPTLOCK;
} else if (regs->NSCR1 & FLASH_NSCR1_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#endif
/* Lock CR/PECR/NSCR register if needed. */
if (enable) {
rc = flash_stm32_write_protection(dev, true);
if (rc) {
return rc;
}
}
#endif

if (enable) {
LOG_DBG("Option bytes locked");
} else {
LOG_DBG("Option bytes unlocked");
}

return 0;
}

#if defined(CONFIG_FLASH_EX_OP_ENABLED) && defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS)
int flash_stm32_control_register_disable(const struct device *dev)
{
Expand Down
3 changes: 2 additions & 1 deletion drivers/flash/flash_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ struct flash_stm32_priv {
#error RDP1 byte has to be different than RDP0 and RDP2 byte
#endif

int flash_stm32_write_protection(const struct device *dev, bool enable);

#ifdef CONFIG_FLASH_PAGE_LAYOUT
static inline bool flash_stm32_range_exists(const struct device *dev,
off_t offset,
Expand All @@ -272,7 +274,6 @@ static inline bool flash_stm32_range_exists(const struct device *dev,
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */


#if defined(CONFIG_MULTITHREADING)
/*
* This is named flash_stm32_sem_take instead of flash_stm32_lock (and
Expand Down
79 changes: 79 additions & 0 deletions drivers/flash/flash_stm32_ex_op.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

LOG_MODULE_REGISTER(flash_stm32_ex_op, CONFIG_FLASH_LOG_LEVEL);

/* Function definition is in the flash_stm32 driver for flash w/o FLASH_OPTCR_OPTLOCK */
extern int flash_stm32_write_protection(const struct device *dev, bool enable);

#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in,
void *out)
Expand Down Expand Up @@ -258,3 +261,79 @@ int flash_stm32_ex_op(const struct device *dev, uint16_t code,

return rv;
}

int flash_stm32_option_bytes_lock(const struct device *dev, bool enable)
{
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);

#if defined(FLASH_OPTCR_OPTLOCK) /* F2, F4, F7 or H7 */
if (enable) {
regs->OPTCR |= FLASH_OPTCR_OPTLOCK;
} else if (regs->OPTCR & FLASH_OPTCR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPT_KEY1;
regs->OPTKEYR = FLASH_OPT_KEY2;
}
#else
int rc;

/* Unlock CR/PECR/NSCR register if needed. */
if (!enable) {
rc = flash_stm32_write_protection(dev, false);
if (rc) {
return rc;
}
}
#if defined(FLASH_CR_OPTWRE) /* F0, F1 and F3 */
if (enable) {
regs->CR &= ~FLASH_CR_OPTWRE;
} else if (!(regs->CR & FLASH_CR_OPTWRE)) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_CR_OPTLOCK) /* G0, G4, L4, WB and WL */
if (enable) {
regs->CR |= FLASH_CR_OPTLOCK;
} else if (regs->CR & FLASH_CR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_PECR_OPTLOCK) /* L0 and L1 */
if (enable) {
regs->PECR |= FLASH_PECR_OPTLOCK;
} else if (regs->PECR & FLASH_PECR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_NSCR_OPTLOCK) /* L5 and U5 */
if (enable) {

Check notice on line 308 in drivers/flash/flash_stm32_ex_op.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/flash/flash_stm32_ex_op.c:308 -#if defined(FLASH_CR_OPTWRE) /* F0, F1 and F3 */ +#if defined(FLASH_CR_OPTWRE) /* F0, F1 and F3 */ if (enable) { regs->CR &= ~FLASH_CR_OPTWRE; } else if (!(regs->CR & FLASH_CR_OPTWRE)) { regs->OPTKEYR = FLASH_OPTKEY1; regs->OPTKEYR = FLASH_OPTKEY2; } -#elif defined(FLASH_CR_OPTLOCK) /* G0, G4, L4, WB and WL */ +#elif defined(FLASH_CR_OPTLOCK) /* G0, G4, L4, WB and WL */ if (enable) { regs->CR |= FLASH_CR_OPTLOCK; } else if (regs->CR & FLASH_CR_OPTLOCK) { regs->OPTKEYR = FLASH_OPTKEY1; regs->OPTKEYR = FLASH_OPTKEY2; } -#elif defined(FLASH_PECR_OPTLOCK) /* L0 and L1 */ +#elif defined(FLASH_PECR_OPTLOCK) /* L0 and L1 */ if (enable) { regs->PECR |= FLASH_PECR_OPTLOCK; } else if (regs->PECR & FLASH_PECR_OPTLOCK) { regs->OPTKEYR = FLASH_OPTKEY1; regs->OPTKEYR = FLASH_OPTKEY2; } -#elif defined(FLASH_NSCR_OPTLOCK) /* L5 and U5 */ +#elif defined(FLASH_NSCR_OPTLOCK) /* L5 and U5 */

Check notice on line 308 in drivers/flash/flash_stm32_ex_op.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/flash/flash_stm32_ex_op.c:308 -#if defined(FLASH_CR_OPTWRE) /* F0, F1 and F3 */ +#if defined(FLASH_CR_OPTWRE) /* F0, F1 and F3 */ if (enable) { regs->CR &= ~FLASH_CR_OPTWRE; } else if (!(regs->CR & FLASH_CR_OPTWRE)) { regs->OPTKEYR = FLASH_OPTKEY1; regs->OPTKEYR = FLASH_OPTKEY2; } -#elif defined(FLASH_CR_OPTLOCK) /* G0, G4, L4, WB and WL */ +#elif defined(FLASH_CR_OPTLOCK) /* G0, G4, L4, WB and WL */ if (enable) { regs->CR |= FLASH_CR_OPTLOCK; } else if (regs->CR & FLASH_CR_OPTLOCK) { regs->OPTKEYR = FLASH_OPTKEY1; regs->OPTKEYR = FLASH_OPTKEY2; } -#elif defined(FLASH_PECR_OPTLOCK) /* L0 and L1 */ +#elif defined(FLASH_PECR_OPTLOCK) /* L0 and L1 */ if (enable) { regs->PECR |= FLASH_PECR_OPTLOCK; } else if (regs->PECR & FLASH_PECR_OPTLOCK) { regs->OPTKEYR = FLASH_OPTKEY1; regs->OPTKEYR = FLASH_OPTKEY2; } -#elif defined(FLASH_NSCR_OPTLOCK) /* L5 and U5 */ +#elif defined(FLASH_NSCR_OPTLOCK) /* L5 and U5 */
regs->NSCR |= FLASH_NSCR_OPTLOCK;
} else if (regs->NSCR & FLASH_NSCR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#elif defined(FLASH_NSCR1_OPTLOCK) /* WBA */
if (enable) {
regs->NSCR1 |= FLASH_NSCR1_OPTLOCK;
} else if (regs->NSCR1 & FLASH_NSCR1_OPTLOCK) {
regs->OPTKEYR = FLASH_OPTKEY1;
regs->OPTKEYR = FLASH_OPTKEY2;
}
#endif
/* Lock CR/PECR/NSCR register if needed. */
if (enable) {
rc = flash_stm32_write_protection(dev, true);
if (rc) {
return rc;
}
}
#endif

if (enable) {
LOG_DBG("Option bytes locked");
} else {
LOG_DBG("Option bytes unlocked");
}

return 0;
}

20 changes: 0 additions & 20 deletions drivers/flash/flash_stm32h7x.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,6 @@ void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
}

Check notice on line 114 in drivers/flash/flash_stm32h7x.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/flash/flash_stm32h7x.c:114 - write_optb(dev, FLASH_OPTSR_RDP_Msk, - (uint32_t)level << FLASH_OPTSR_RDP_Pos); + write_optb(dev, FLASH_OPTSR_RDP_Msk, (uint32_t)level << FLASH_OPTSR_RDP_Pos);

Check notice on line 114 in drivers/flash/flash_stm32h7x.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/flash/flash_stm32h7x.c:114 - write_optb(dev, FLASH_OPTSR_RDP_Msk, - (uint32_t)level << FLASH_OPTSR_RDP_Pos); + write_optb(dev, FLASH_OPTSR_RDP_Msk, (uint32_t)level << FLASH_OPTSR_RDP_Pos);
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */

int flash_stm32_option_bytes_lock(const struct device *dev, bool enable)
{
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);

if (enable) {
regs->OPTCR |= FLASH_OPTCR_OPTLOCK;
} else if (regs->OPTCR & FLASH_OPTCR_OPTLOCK) {
regs->OPTKEYR = FLASH_OPT_KEY1;
regs->OPTKEYR = FLASH_OPT_KEY2;
}

if (enable) {
LOG_DBG("Option bytes locked");
} else {
LOG_DBG("Option bytes unlocked");
}

return 0;
}

bool flash_stm32_valid_range(const struct device *dev, off_t offset, uint32_t len, bool write)
{
#if defined(DUAL_BANK)
Expand Down

0 comments on commit ab996d4

Please sign in to comment.