This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr402
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit dad5d6865d88fc42648d762b861d3e5c783d430f
Author: Joshua Lange <[email protected]>
AuthorDate: Tue Feb 18 19:03:07 2020 -0600

    Fixed some issues with internal flash driver on STM32H7
---
 arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h |   2 +-
 arch/arm/src/stm32h7/stm32_flash.c                | 141 +++++++++++++++++++++-
 arch/arm/src/stm32h7/stm32_flash.h                | 100 +++++++++++++++
 3 files changed, 236 insertions(+), 7 deletions(-)

diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h 
b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h
index 3de570d..976c67a 100644
--- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h
+++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_flash.h
@@ -168,7 +168,7 @@
 #define FLASH_CR_START                 (1 << 7)   /* Bit 7: Erase start */
 #define FLASH_CR_SNB_SHIFT             (8)        /* Bits 8-10: Sector number 
*/
 #define FLASH_CR_SNB_MASK              (15 << FLASH_CR_SNB_SHIFT)  /* Used to 
clear FLASH_CR_SNB bits */
-#  define FLASH_CR_SNB(n)              ((uint32_t)(n & 0x7) << 
FLASH_CR_SNB_SHIFT) /* Sector n, n=0..7 */
+#  define FLASH_CR_SNB(n)              ((uint32_t)((n) & 0x7) << 
FLASH_CR_SNB_SHIFT) /* Sector n, n=0..7 */
                                                   /* Bits 11-13: Reserved */
 #define FLASH_CR_SPSS2                 (1 << 14)  /* Bit 14: Bank1 Reserved, 
Bank 2 special sector selection bit */
 #define FLASH_CR_CRCEN                 (1 << 15)  /* Bit 15: CRC control 
enable */
diff --git a/arch/arm/src/stm32h7/stm32_flash.c 
b/arch/arm/src/stm32h7/stm32_flash.c
index e676697..0881eac 100644
--- a/arch/arm/src/stm32h7/stm32_flash.c
+++ b/arch/arm/src/stm32h7/stm32_flash.c
@@ -193,7 +193,7 @@ static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv 
=
  *****************************************************************************/
 
 static inline uint32_t stm32h7_flash_getreg32(FAR struct stm32h7_flash_priv_s
-                                            *priv, uint8_t offset)
+                                            *priv, uint32_t offset)
 {
   return getreg32(priv->ifbase + offset);
 }
@@ -207,7 +207,7 @@ static inline uint32_t stm32h7_flash_getreg32(FAR struct 
stm32h7_flash_priv_s
  ****************************************************************************/
 
 static inline void stm32h7_flash_putreg32(FAR struct stm32h7_flash_priv_s
-                                          *priv, uint8_t offset,
+                                          *priv, uint32_t offset,
                                           uint32_t value)
 {
   putreg32(value, priv->ifbase + offset);
@@ -222,7 +222,7 @@ static inline void stm32h7_flash_putreg32(FAR struct 
stm32h7_flash_priv_s
  *****************************************************************************/
 
 static inline void stm32h7_flash_modifyreg32(FAR struct stm32h7_flash_priv_s
-                                             *priv, uint8_t offset,
+                                             *priv, uint32_t offset,
                                              uint32_t clearbits,
                                              uint32_t setbits)
 {
@@ -330,6 +330,73 @@ FAR struct stm32h7_flash_priv_s * 
stm32h7_flash_bank(size_t address)
   return priv;
 }
 
+/*****************************************************************************
+ * Name: stm32h7_unlock_flashopt
+ *
+ * Description:
+ *   Unlock the flash option bytes
+ *
+ *****************************************************************************/
+
+static void stm32h7_unlock_flashopt(FAR struct stm32h7_flash_priv_s *priv)
+{
+  while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) & FLASH_SR_BSY)
+    {
+    }
+
+  if (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & 
FLASH_OPTCR_OPTLOCK)
+    {
+      /* Unlock sequence */
+
+      stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, FLASH_OPTKEY1);
+      stm32h7_flash_putreg32(priv, STM32_FLASH_OPTKEYR_OFFSET, FLASH_OPTKEY2);
+    }
+}
+
+/*****************************************************************************
+ * Name: stm32h7_lock_flashopt
+ *
+ * Description:
+ *   Lock the flash option bytes
+ *
+ *****************************************************************************/
+
+static void stm32h7_lock_flashopt(FAR struct stm32h7_flash_priv_s *priv)
+{
+  stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, 
FLASH_OPTCR_OPTLOCK);
+}
+
+/*****************************************************************************
+ * Name: stm32h7_save_flashopt
+ *
+ * Description:
+ *   Save the flash option bytes to non-volatile storage.
+ *
+ *****************************************************************************/
+
+static void stm32h7_save_flashopt(FAR struct stm32h7_flash_priv_s *priv)
+{
+  while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
+        (FLASH_SR_BSY | FLASH_SR_CRCBUSY))
+    {
+    }
+  while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR2_OFFSET) &
+        (FLASH_SR_BSY | FLASH_SR_CRCBUSY))
+    {
+    }
+
+  /* Can only write flash options if the option control reg is unlocked */
+  if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_OPTCR_OFFSET) & 
FLASH_OPTCR_OPTLOCK))
+    {
+      stm32h7_flash_modifyreg32(priv, STM32_FLASH_OPTCR_OFFSET, 0, 
FLASH_OPTCR_OPTSTRT);
+    }
+
+  /* Wait for the update to complete */
+  while (stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET) & 
FLASH_OPTSR_BUSYV)
+    {
+    }
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -423,6 +490,67 @@ int stm32h7_flash_writeprotect(size_t block, bool enabled)
   return rv;
 }
 
+/****************************************************************************
+ * Name: stm32h7_flash_getopt
+ *
+ * Description:
+ *   Returns the current flash option bytes from the FLASH_OPTSR_CR register.
+ *
+ ****************************************************************************/
+
+uint32_t stm32h7_flash_getopt(void)
+{
+  struct stm32h7_flash_priv_s *priv;
+  priv = stm32h7_flash_bank(STM32_FLASH_BANK1);
+  if (priv)
+    {
+      return stm32h7_flash_getreg32(priv, STM32_FLASH_OPTSR_CUR_OFFSET);
+    }
+  return 0;
+}
+
+/****************************************************************************
+ * Name: stm32h7_flash_optmodify
+ *
+ * Description:
+ *   Modifies the current flash option bytes, given bits to set and clear.
+ *
+ ****************************************************************************/
+
+void stm32h7_flash_optmodify(uint32_t clear, uint32_t set)
+{
+  struct stm32h7_flash_priv_s *priv;
+  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);
+  }
+}
+
+/****************************************************************************
+ * Name: stm32h7_flash_swapbanks
+ *
+ * Description:
+ *   Swaps banks 1 and 2 in the processor's memory map.  Takes effect
+ *   the next time the system is reset.
+ *
+ ****************************************************************************/
+
+void stm32h7_flash_swapbanks(void)
+{
+  uint32_t opts = stm32h7_flash_getopt();
+  if (opts & FLASH_OPTCR_SWAPBANK)
+    {
+      stm32h7_flash_optmodify(FLASH_OPTCR_SWAPBANK, 0);
+    }
+  else
+    {
+      stm32h7_flash_optmodify(0, FLASH_OPTCR_SWAPBANK);
+    }
+}
+
 size_t up_progmem_pagesize(size_t page)
 {
   return FLASH_SECTOR_SIZE;
@@ -508,11 +636,12 @@ ssize_t up_progmem_eraseblock(size_t block)
 
   stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_SER);
   stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK,
-                            FLASH_CR_SNB(block));
+                            FLASH_CR_SNB(block - priv->stblock));
 
   stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_START);
 
-  while (stm32h7_flash_getreg32(priv, STM32_FLASH_CR1_OFFSET) & FLASH_SR_BSY)
+  while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
+        (FLASH_SR_BSY | FLASH_SR_QW))
     {
     }
 
@@ -600,7 +729,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, 
size_t count)
       ARM_ISB();
 
       while (stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
-             FLASH_SR_BSY)
+             (FLASH_SR_BSY | FLASH_SR_QW))
         {
         }
 
diff --git a/arch/arm/src/stm32h7/stm32_flash.h 
b/arch/arm/src/stm32h7/stm32_flash.h
new file mode 100644
index 0000000..ca2696a
--- /dev/null
+++ b/arch/arm/src/stm32h7/stm32_flash.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * arch/arm/src/stm32h7/stm32_fflash.h
+ *
+ *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
+ *   Author: Joshua Lange <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32H7_STM32_FLASH_H
+#define __ARCH_ARM_SRC_STM32H7_STM32_FLASH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "hardware/stm32_flash.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: stm32h7_flash_getopt
+ *
+ * Description:
+ *   Returns the current flash option bytes from the FLASH_OPTSR_CR register.
+ *
+ ****************************************************************************/
+
+uint32_t stm32h7_flash_getopt(void);
+
+/****************************************************************************
+ * Name: stm32h7_flash_optmodify
+ *
+ * Description:
+ *   Modifies the current flash option bytes, given bits to set and clear.
+ *
+ ****************************************************************************/
+
+void stm32h7_flash_optmodify(uint32_t clear, uint32_t set);
+
+/****************************************************************************
+ * Name: stm32h7_flash_swapbanks
+ *
+ * Description:
+ *   Swaps banks 1 and 2 in the processor's memory map.  Takes effect
+ *   the next time the system is reset.
+ *
+ ****************************************************************************/
+
+void stm32h7_flash_swapbanks(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32H7_STM32_FLASH_H */

Reply via email to