static int flash_stm32_write_protection(struct device *dev, bool enable) { struct flash_stm32_priv *p = dev->driver_data; #if defined(CONFIG_SOC_SERIES_STM32F4X) struct stm32f4x_flash *regs = p->regs; #elif defined(CONFIG_SOC_SERIES_STM32L4X) struct stm32l4x_flash *regs = p->regs; #endif int rc = 0; k_sem_take(&p->sem, K_FOREVER); if (enable) { rc = flash_stm32_wait_flash_idle(p); if (rc) { k_sem_give(&p->sem); return rc; } regs->cr |= FLASH_CR_LOCK; } else { if (regs->cr & FLASH_CR_LOCK) { regs->keyr = FLASH_KEY1; regs->keyr = FLASH_KEY2; } } k_sem_give(&p->sem); return rc; }
static int write_dword(struct device *dev, off_t offset, u64_t val) { volatile u32_t *flash = (u32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); struct stm32l4x_flash *regs = FLASH_STM32_REGS(dev); u32_t tmp; int rc; /* if the control register is locked, do not fail silently */ if (regs->cr & FLASH_CR_LOCK) { return -EIO; } /* Check that no Flash main memory operation is ongoing */ rc = flash_stm32_wait_flash_idle(dev); if (rc < 0) { return rc; } /* Check if this double word is erased */ if (flash[0] != 0xFFFFFFFFUL || flash[1] != 0xFFFFFFFFUL) { return -EIO; } /* Set the PG bit */ regs->cr |= FLASH_CR_PG; /* Flush the register write */ tmp = regs->cr; /* Perform the data write operation at the desired memory address */ flash[0] = (u32_t)val; flash[1] = (u32_t)(val >> 32); /* Wait until the BSY bit is cleared */ rc = flash_stm32_wait_flash_idle(dev); /* Clear the PG bit */ regs->cr &= (~FLASH_CR_PG); return rc; }
static int erase_page(struct device *dev, unsigned int page) { struct stm32l4x_flash *regs = FLASH_STM32_REGS(dev); u32_t tmp; int rc; /* if the control register is locked, do not fail silently */ if (regs->cr & FLASH_CR_LOCK) { return -EIO; } /* Check that no Flash memory operation is ongoing */ rc = flash_stm32_wait_flash_idle(dev); if (rc < 0) { return rc; } /* Set the PER bit and select the page you wish to erase */ regs->cr |= FLASH_CR_PER; #ifdef FLASH_CR_BKER regs->cr &= ~FLASH_CR_BKER_Msk; /* Select bank, only for DUALBANK devices */ if (page >= 256) regs->cr |= FLASH_CR_BKER; #endif regs->cr &= ~FLASH_CR_PNB_Msk; regs->cr |= ((page % 256) << 3); /* Set the STRT bit */ regs->cr |= FLASH_CR_STRT; /* flush the register write */ tmp = regs->cr; /* Wait for the BSY bit */ rc = flash_stm32_wait_flash_idle(dev); regs->cr &= ~FLASH_CR_PER; return rc; }
static int erase_page(struct device *dev, unsigned int page) { struct stm32f3x_flash *regs = FLASH_STM32_REGS(dev); u32_t page_address = CONFIG_FLASH_BASE_ADDRESS; int rc; /* if the control register is locked, do not fail silently */ if (regs->cr & FLASH_CR_LOCK) { return -EIO; } /* Check that no Flash memory operation is ongoing */ rc = flash_stm32_wait_flash_idle(dev); if (rc < 0) { return rc; } page_address += page * FLASH_PAGE_SIZE; /* Set the PER bit and select the page you wish to erase */ regs->cr |= FLASH_CR_PER; /* Set page address */ regs->ar = page_address; /* Give some time to write operation to complete */ rc = flash_stm32_wait_flash_idle(dev); if (rc < 0) { return rc; } /* Set the STRT bit */ regs->cr |= FLASH_CR_STRT; /* Wait for the BSY bit */ rc = flash_stm32_wait_flash_idle(dev); regs->cr &= ~FLASH_CR_PER; return rc; }