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);
+        }
     }
 }