You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/05/14 23:28:00 UTC
[incubator-nuttx] branch master updated (573f027 -> 1e0f416)
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.
from 573f027 netdev_ioctl: Update a comment
new f9a886f arch/arm/src/stm32h7/stm32_flash.c: Lock flash option register
new de8f3b7 arch/arm/src/stm32h7/stm32_flash.c: fix write and erase
new 1e0f416 arch/arm/src/stm32h7: Make flash program size configurable
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/arm/src/stm32h7/Kconfig | 14 ++
arch/arm/src/stm32h7/stm32_flash.c | 364 ++++++++++++++++++++++++-------------
2 files changed, 255 insertions(+), 123 deletions(-)
[incubator-nuttx] 03/03: arch/arm/src/stm32h7: Make flash program
size configurable
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 1e0f416a9337d8b181f4b7c27b6689bfd2d20eb2
Author: Jukka Laitinen <ju...@intel.com>
AuthorDate: Thu May 14 13:08:04 2020 +0300
arch/arm/src/stm32h7: Make flash program size configurable
Signed-off-by: Jukka Laitinen <ju...@intel.com>
---
arch/arm/src/stm32h7/Kconfig | 14 ++++++++++++++
arch/arm/src/stm32h7/stm32_flash.c | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig
index 8cc0672..eba848d 100644
--- a/arch/arm/src/stm32h7/Kconfig
+++ b/arch/arm/src/stm32h7/Kconfig
@@ -297,6 +297,20 @@ config STM32H7_FLASH_OVERRIDE_I
endchoice # "Override Flash Size Designator"
+config STM32H7_FLASH_CR_PSIZE
+ int "Flash program size width"
+ depends on ARCH_CHIP_STM32H7
+ default 3
+ range 0 3
+ ---help---
+ On some hardware the fastest 64 bit wide flash writes cause too
+ high power consumption which may compromize the system stability.
+ This option can be used to reduce the program size. The options are:
+ 0: 8 bits
+ 1: 16 bits
+ 2: 32 bits
+ 3: 64 bits (default)
+
config STM32H7_AXI_SRAM_CORRUPTION_WAR
bool "Errata 2.2.9 Reading from AXI SRAM data read corruption Workaround"
default y
diff --git a/arch/arm/src/stm32h7/stm32_flash.c b/arch/arm/src/stm32h7/stm32_flash.c
index 9a3560b..cd9d74f 100644
--- a/arch/arm/src/stm32h7/stm32_flash.c
+++ b/arch/arm/src/stm32h7/stm32_flash.c
@@ -140,6 +140,12 @@
#endif
+#ifndef CONFIG_STM32H7_FLASH_CR_PSIZE
+#define FLASH_CR_PSIZE FLASH_CR_PSIZE_X64
+#else
+#define FLASH_CR_PSIZE (CONFIG_STM32H7_FLASH_CR_PSIZE << FLASH_CR_PSIZE_SHIFT)
+#endif
+
#define FLASH_KEY1 0x45670123
#define FLASH_KEY2 0xcdef89ab
#define FLASH_OPTKEY1 0x08192a3b
@@ -871,7 +877,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
stm32h7_unlock_flash(priv);
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET,
- FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE_X32);
+ FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE);
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_PG);
[incubator-nuttx] 02/03: arch/arm/src/stm32h7/stm32_flash.c: fix
write and erase
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit de8f3b73d51d1c600cdf5c37714a136d9cbdee4a
Author: Jari Nippula <ja...@intel.com>
AuthorDate: Tue Dec 10 09:21:03 2019 +0200
arch/arm/src/stm32h7/stm32_flash.c: fix write and erase
Correct flash write and erase functions, they inherit some
broken code from other platforms. Also fix the confusion between
eraseblock(sector) and page sizes.
Signed-off-by: Jari Nippula <ja...@intel.com>
---
arch/arm/src/stm32h7/stm32_flash.c | 331 ++++++++++++++++++++++++-------------
1 file changed, 214 insertions(+), 117 deletions(-)
diff --git a/arch/arm/src/stm32h7/stm32_flash.c b/arch/arm/src/stm32h7/stm32_flash.c
index 269652d..9a3560b 100644
--- a/arch/arm/src/stm32h7/stm32_flash.c
+++ b/arch/arm/src/stm32h7/stm32_flash.c
@@ -89,6 +89,7 @@
#define _K(x) ((x)*1024)
#define FLASH_SECTOR_SIZE _K(128)
+#define FLASH_PAGE_SIZE 32
#if !defined(CONFIG_STM32H7_FLASH_OVERRIDE_DEFAULT) && \
!defined(CONFIG_STM32H7_FLASH_OVERRIDE_B) && \
@@ -124,28 +125,31 @@
#if defined(CONFIG_STM32H7_FLASH_CONFIG_B)
-# define STM32_FLASH_NPAGES 1
+# define STM32_FLASH_NBLOCKS 1
# define STM32_FLASH_SIZE _K(1 * 128)
#elif defined(CONFIG_STM32H7_FLASH_CONFIG_G)
-# define STM32_FLASH_NPAGES 8
+# define STM32_FLASH_NBLOCKS 8
# define STM32_FLASH_SIZE _K(8 * 128)
#elif defined(CONFIG_STM32H7_FLASH_CONFIG_I)
-# define STM32_FLASH_NPAGES 16
+# define STM32_FLASH_NBLOCKS 16
# define STM32_FLASH_SIZE _K(16 * 128)
#endif
-#define FLASH_KEY1 0x45670123
-#define FLASH_KEY2 0xcdef89ab
-#define FLASH_OPTKEY1 0x08192a3b
-#define FLASH_OPTKEY2 0x4c5d6e7f
-#define FLASH_ERASEDVALUE 0xff
+#define FLASH_KEY1 0x45670123
+#define FLASH_KEY2 0xcdef89ab
+#define FLASH_OPTKEY1 0x08192a3b
+#define FLASH_OPTKEY2 0x4c5d6e7f
+#define FLASH_ERASEDVALUE 0xff
+#define FLASH_ERASEDVALUE_DW 0xffffffff
+#define PROGMEM_NBLOCKS STM32_FLASH_NBLOCKS
+#define FLASH_NPAGES (STM32_FLASH_SIZE / FLASH_PAGE_SIZE)
-#define PROGMEM_NBLOCKS STM32_FLASH_NPAGES
+#define FLASH_TIMEOUT_VALUE 500000 /* 5s */
/****************************************************************************
* Private Types
@@ -157,6 +161,7 @@ struct stm32h7_flash_priv_s
uint32_t ifbase; /* FLASHIF interface base address */
uint32_t base; /* FLASH base address */
uint32_t stblock; /* The first Block Number */
+ uint32_t stpage; /* The first Page Number */
};
/****************************************************************************
@@ -169,14 +174,16 @@ static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv =
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET,
.base = STM32_FLASH_BANK1,
.stblock = 0,
+ .stpage = 0,
};
-#if STM32_FLASH_NPAGES > 1
+#if STM32_FLASH_NBLOCKS > 1
static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv =
{
.sem = SEM_INITIALIZER(1),
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET,
.base = STM32_FLASH_BANK2,
.stblock = PROGMEM_NBLOCKS / 2,
+ .stpage = FLASH_NPAGES / 2,
};
#endif
@@ -324,7 +331,7 @@ FAR struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address)
return NULL;
}
-#if STM32_FLASH_NPAGES > 1
+#if STM32_FLASH_NBLOCKS > 1
if (address >= stm32h7_flash_bank2_priv.base)
{
priv = &stm32h7_flash_bank2_priv;
@@ -335,6 +342,99 @@ FAR struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address)
}
/****************************************************************************
+ * Name: stm32h7_israngeerased
+ *
+ * Description:
+ * Returns count of non-erased words
+ *
+ ****************************************************************************/
+
+static int stm32h7_israngeerased(size_t startaddress, size_t size)
+{
+ uint32_t *addr;
+ uint8_t *baddr;
+ size_t count = 0;
+ size_t bwritten = 0;
+
+ if (!stm32h7_flash_bank(startaddress) ||
+ !stm32h7_flash_bank(startaddress + size))
+ {
+ return -EIO;
+ }
+
+ addr = (uint32_t *)startaddress;
+ while (count + 4 <= size)
+ {
+ if (getreg32(addr) != FLASH_ERASEDVALUE_DW)
+ {
+ bwritten++;
+ }
+
+ addr++;
+ count += 4;
+ }
+
+ baddr = (uint8_t *)addr;
+ while (count < size)
+ {
+ if (getreg8(baddr) != FLASH_ERASEDVALUE)
+ {
+ bwritten++;
+ }
+
+ count++;
+ }
+
+ return bwritten;
+}
+
+/****************************************************************************
+ * Name: stm32h7_wait_for_last_operation()
+ *
+ * Description:
+ * Wait for last write/erase operation to finish
+ * Return error in case of timeout
+ *
+ * Input Parameters:
+ * priv - Flash bank based config
+ *
+ * Returned Value:
+ * Zero or error value
+ *
+ * ETIME: Timeout while waiting for previous write/erase operation to
+ * complete
+ *
+ ****************************************************************************/
+
+static int stm32h7_wait_for_last_operation(FAR struct stm32h7_flash_priv_s
+ *priv)
+{
+ int i;
+ bool timeout = true;
+
+ ARM_DSB();
+
+ for (i = 0; i < FLASH_TIMEOUT_VALUE; i++)
+ {
+ if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
+ (FLASH_SR_QW | FLASH_SR_BSY | FLASH_SR_WBNE)))
+ {
+ timeout = false;
+ break;
+ }
+
+ usleep(1000);
+ }
+
+ if (timeout)
+ {
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+/****************************************************************************
* Name: stm32h7_unlock_flashopt
*
* Description:
@@ -505,11 +605,11 @@ int stm32h7_flash_writeprotect(size_t block, bool enabled)
{
if (enabled)
{
- clearbits = 1 << block % (STM32_FLASH_NPAGES / 2);
+ clearbits = 1 << block % (STM32_FLASH_NBLOCKS / 2);
}
else
{
- setbits = 1 << block % (STM32_FLASH_NPAGES / 2);
+ setbits = 1 << block % (STM32_FLASH_NBLOCKS / 2);
}
stm32h7_flash_modifyreg32(priv, STM32_FLASH_WPSN_PRG1R_OFFSET,
@@ -591,7 +691,7 @@ void stm32h7_flash_swapbanks(void)
size_t up_progmem_pagesize(size_t page)
{
- return FLASH_SECTOR_SIZE;
+ return FLASH_PAGE_SIZE;
}
ssize_t up_progmem_getpage(size_t addr)
@@ -605,20 +705,19 @@ ssize_t up_progmem_getpage(size_t addr)
return -EFAULT;
}
- return priv->stblock + ((addr - priv->base) / FLASH_SECTOR_SIZE);
+ return priv->stpage + ((addr - priv->base) / FLASH_PAGE_SIZE);
}
size_t up_progmem_getaddress(size_t page)
{
struct stm32h7_flash_priv_s *priv;
-
- if (page >= STM32_FLASH_NPAGES)
+ if (page >= FLASH_NPAGES)
{
return SIZE_MAX;
}
- priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (page * FLASH_SECTOR_SIZE));
- return priv->base + (page - priv->stblock) * FLASH_SECTOR_SIZE;
+ priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (page * FLASH_PAGE_SIZE));
+ return priv->base + (page - priv->stpage) * FLASH_PAGE_SIZE;
}
size_t up_progmem_neraseblocks(void)
@@ -637,7 +736,7 @@ ssize_t up_progmem_ispageerased(size_t page)
size_t count;
size_t bwritten = 0;
- if (page >= STM32_FLASH_NPAGES)
+ if (page >= FLASH_NPAGES)
{
return -EFAULT;
}
@@ -656,17 +755,23 @@ ssize_t up_progmem_ispageerased(size_t page)
return bwritten;
}
+size_t up_progmem_erasesize(size_t block)
+{
+ return FLASH_SECTOR_SIZE;
+}
+
ssize_t up_progmem_eraseblock(size_t block)
{
struct stm32h7_flash_priv_s *priv;
int ret;
+ size_t block_address = STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE);
if (block >= PROGMEM_NBLOCKS)
{
return -EFAULT;
}
- priv = stm32h7_flash_bank(STM32_FLASH_BANK1 + (block * FLASH_SECTOR_SIZE));
+ priv = stm32h7_flash_bank(block_address);
ret = stm32h7_flash_sem_lock(priv);
if (ret < 0)
@@ -674,6 +779,11 @@ ssize_t up_progmem_eraseblock(size_t block)
return (ssize_t)ret;
}
+ if (stm32h7_wait_for_last_operation(priv))
+ {
+ return -EIO;
+ }
+
/* Get flash ready and begin erasing single block */
stm32h7_unlock_flash(priv);
@@ -684,19 +794,26 @@ ssize_t up_progmem_eraseblock(size_t block)
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_START);
- while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
- (FLASH_SR_BSY | FLASH_SR_QW))
+ /* Wait for erase operation to complete */
+
+ if (stm32h7_wait_for_last_operation(priv))
{
+ return -EIO;
}
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SER, 0);
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK,
+ 0);
+
+ stm32h7_lock_flash(priv);
+
stm32h7_flash_sem_unlock(priv);
/* Verify */
- if (up_progmem_ispageerased(block) == 0)
+ if (stm32h7_israngeerased(block_address, up_progmem_erasesize(block)) == 0)
{
- return up_progmem_pagesize(block); /* success */
+ return up_progmem_erasesize(block); /* success */
}
else
{
@@ -704,24 +821,19 @@ ssize_t up_progmem_eraseblock(size_t block)
}
}
-size_t up_progmem_erasesize(size_t block)
-{
- return FLASH_SECTOR_SIZE;
-}
-
ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
{
struct stm32h7_flash_priv_s *priv;
- uint64_t *fp;
- uint64_t *rp;
- uint8_t *byte = (uint8_t *) buf;
- uint64_t *ll = (uint64_t *) buf;
+ uint32_t *fp;
+ uint32_t *rp;
+ uint32_t *ll = (uint32_t *) buf;
+ size_t faddr;
size_t written = count;
- const size_t blocksize = 32; /* 256 bit, 32 bytes per block */
- const size_t llperblock = blocksize / sizeof(uint64_t);
- size_t bcount = count / blocksize;
- size_t remaining = count % blocksize;
int ret;
+ const size_t pagesize = up_progmem_pagesize(0); /* 256 bit, 32 bytes per page */
+ const size_t llperpage = pagesize / sizeof(uint32_t);
+ size_t pcount = count / pagesize;
+ uint32_t sr;
priv = stm32h7_flash_bank(addr);
@@ -744,26 +856,40 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
return (ssize_t)ret;
}
+ /* Check address and count alignment */
+
+ DEBUGASSERT(!(addr % pagesize));
+ DEBUGASSERT(!(count % pagesize));
+
+ if (stm32h7_wait_for_last_operation(priv))
+ {
+ return -EIO;
+ }
+
/* Get flash ready and begin flashing */
stm32h7_unlock_flash(priv);
- stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_PG);
-
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET,
- FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE_X64);
+ FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE_X32);
- ARM_DSB();
- ARM_ISB();
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_PG);
- for (ll = (uint64_t *) buf; bcount;
- bcount -= 1, ll += llperblock, addr += blocksize)
+ for (ll = (uint32_t *) buf, faddr = addr; pcount;
+ pcount -= 1, ll += llperpage, faddr += pagesize)
{
- fp = (uint64_t *) addr;
+ fp = (uint32_t *) faddr;
rp = ll;
- /* Write 4 64 bit word and wait to complete */
+ ARM_DSB();
+ ARM_ISB();
+ /* Write 8 32 bit word and wait to complete */
+
+ *fp++ = *rp++;
+ *fp++ = *rp++;
+ *fp++ = *rp++;
+ *fp++ = *rp++;
*fp++ = *rp++;
*fp++ = *rp++;
*fp++ = *rp++;
@@ -777,94 +903,65 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
ARM_DSB();
ARM_ISB();
- while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
- (FLASH_SR_BSY | FLASH_SR_QW))
+ if (stm32h7_wait_for_last_operation(priv))
{
+ return -EIO;
}
- /* Verify */
-
- if (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
- FLASH_CR_SER)
- {
- written = -EROFS;
- break;
- }
- else
+ sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET);
+ if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR))
{
- fp = (uint64_t *) addr;
- rp = ll;
-
- if (*fp++ != *rp++ ||
- *fp++ != *rp++ ||
- *fp++ != *rp++ ||
- *fp++ != *rp++)
- {
- written = -EIO;
- break;
- }
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET,
+ FLASH_CR_PG,
+ 0);
+
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET,
+ 0, ~0);
+ stm32h7_lock_flash(priv);
+ stm32h7_flash_sem_unlock(priv);
+ return -EIO;
}
}
- if (remaining)
- {
- for (byte = (uint8_t *) ll, count = remaining; count;
- count -= 1, byte++, addr += 1)
- {
- /* Write the remaining */
-
- putreg8(*byte, addr);
- }
-
- /* Data synchronous Barrier (DSB) just after the write operation. This
- * will force the CPU to respect the sequence of instruction (no
- * optimization).
- */
-
- ARM_DSB();
- ARM_ISB();
-
- /* Force the fractional write */
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_PG, 0);
- stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0,
- FLASH_CR_FW);
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET,
+ 0, ~0);
+ stm32h7_lock_flash(priv);
- ARM_DSB();
- ARM_ISB();
+ /* Verify */
- while (stm32h7_flash_getreg32(priv, STM32_FLASH_CR1_OFFSET) &
- FLASH_CR_FW)
- {
- }
+ for (ll = (uint32_t *) buf, faddr = addr, pcount = count / pagesize;
+ pcount; pcount -= 1, ll += llperpage, faddr += pagesize)
+ {
+ fp = (uint32_t *) faddr;
+ rp = ll;
- while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
- FLASH_SR_BSY)
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET,
+ 0, ~0);
+ if ((*fp++ != *rp++) ||
+ (*fp++ != *rp++) ||
+ (*fp++ != *rp++) ||
+ (*fp++ != *rp++) ||
+ (*fp++ != *rp++) ||
+ (*fp++ != *rp++) ||
+ (*fp++ != *rp++) ||
+ (*fp++ != *rp++))
{
+ written = -EIO;
+ break;
}
- /* Verify */
-
- if (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
- FLASH_CR_SER)
+ sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET);
+ if (sr & (FLASH_SR_SNECCERR | FLASH_SR_DBECCERR))
{
- written = -EROFS;
- }
- else
- {
- addr -= remaining;
- for (byte = (uint8_t *) ll, count = remaining; count;
- count -= 1, byte++, addr += 1)
- {
- if (getreg8(addr) != *byte)
- {
- written = -EIO;
- break;
- }
- }
+ written = -EIO;
+ break;
}
}
- stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_PG, 0);
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET,
+ 0, ~0);
stm32h7_flash_sem_unlock(priv);
return written;
}
[incubator-nuttx] 01/03: arch/arm/src/stm32h7/stm32_flash.c: Lock
flash option register
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit f9a886f8b7a2211ed2e7957778f96118e27ae69c
Author: Jukka Laitinen <ju...@intel.com>
AuthorDate: Fri Apr 17 15:00:06 2020 +0300
arch/arm/src/stm32h7/stm32_flash.c: Lock flash option register
If the flash option register was locked before modifying it, return
it to the locked state after modify.
Signed-off-by: Jukka Laitinen <ju...@intel.com>
---
arch/arm/src/stm32h7/stm32_flash.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/arch/arm/src/stm32h7/stm32_flash.c b/arch/arm/src/stm32h7/stm32_flash.c
index 85f4498..269652d 100644
--- a/arch/arm/src/stm32h7/stm32_flash.c
+++ b/arch/arm/src/stm32h7/stm32_flash.c
@@ -339,11 +339,14 @@ FAR struct stm32h7_flash_priv_s * stm32h7_flash_bank(size_t address)
*
* Description:
* Unlock the flash option bytes
+ * Returns true if the flash was locked before, false otherwise
*
****************************************************************************/
-static void stm32h7_unlock_flashopt(FAR struct stm32h7_flash_priv_s *priv)
+static bool stm32h7_unlock_flashopt(FAR struct stm32h7_flash_priv_s *priv)
{
+ bool ret = false;
+
while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & FLASH_SR_BSY)
{
}
@@ -357,7 +360,13 @@ static void stm32h7_unlock_flashopt(FAR struct stm32h7_flash_priv_s *priv)
FLASH_OPTKEY1);
stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET,
FLASH_OPTKEY2);
+
+ /* Was locked before and now unlocked */
+
+ ret = true;
}
+
+ return ret;
}
/****************************************************************************
@@ -439,7 +448,7 @@ int stm32h7_flash_unlock(size_t addr)
stm32h7_flash_sem_unlock(priv);
}
- return ret:;
+ return ret;
}
/****************************************************************************
@@ -542,13 +551,19 @@ uint32_t stm32h7_flash_getopt(void)
void stm32h7_flash_optmodify(uint32_t clear, uint32_t set)
{
struct stm32h7_flash_priv_s *priv;
+ bool was_locked;
+
priv = stm32h7_flash_bank(STM32_FLASH_BANK1);
if (priv)
{
- stm32h7_unlock_flashopt(priv);
- stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTSR_PRG_OFFSET,
- clear, set);
- stm32h7_save_flashopt(priv);
+ was_locked = stm32h7_unlock_flashopt(priv);
+ stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTSR_PRG_OFFSET,
+ clear, set);
+ stm32h7_save_flashopt(priv);
+ if (was_locked)
+ {
+ stm32h7_lock_flashopt(priv);
+ }
}
}