You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/05/25 14:41:40 UTC
[nuttx] branch master updated (8943d528fd -> e06ce27f56)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from 8943d528fd arch/nrf52: add an option to configure QSPI sampling delay for RX data
new 5ff6c8b403 arch/nrf53: add HFCLK192M clock support
new 8b89730e61 arch/nrf53: add QSPI support
new e06ce27f56 boards/nrf5340-dk: add mx25 memory support
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/nrf53/Kconfig | 56 +++++
arch/arm/src/nrf53/Make.defs | 4 +
arch/arm/src/nrf53/hardware/nrf53_clock.h | 120 ++++++---
.../nrf52_qspi.h => nrf53/hardware/nrf53_qspi.h} | 95 ++++---
arch/arm/src/nrf53/nrf53_clockconfig.c | 22 ++
arch/arm/src/nrf53/nrf53_clockconfig.h | 16 ++
.../src/{nrf52/nrf52_qspi.c => nrf53/nrf53_qspi.c} | 278 +++++++++++----------
.../src/{nrf52/nrf52_qspi.h => nrf53/nrf53_qspi.h} | 12 +-
.../defconfig => qspi_cpuapp/#defconfig#} | 7 +-
.../configs/{nsh_cpuapp => qspi_cpuapp}/defconfig | 13 +-
boards/arm/nrf53/nrf5340-dk/include/board.h | 24 ++
boards/arm/nrf53/nrf5340-dk/src/Make.defs | 6 +-
boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h | 12 +
boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c | 10 +
.../nrf5340-dk/src/nrf53_mx25.c} | 16 +-
15 files changed, 458 insertions(+), 233 deletions(-)
copy arch/arm/src/{nrf52/hardware/nrf52_qspi.h => nrf53/hardware/nrf53_qspi.h} (68%)
copy arch/arm/src/{nrf52/nrf52_qspi.c => nrf53/nrf53_qspi.c} (72%)
copy arch/arm/src/{nrf52/nrf52_qspi.h => nrf53/nrf53_qspi.h} (87%)
copy boards/arm/nrf53/nrf5340-dk/configs/{nsh_cpuapp/defconfig => qspi_cpuapp/#defconfig#} (93%)
copy boards/arm/nrf53/nrf5340-dk/configs/{nsh_cpuapp => qspi_cpuapp}/defconfig (81%)
copy boards/arm/{nrf52/nrf52840-dk/src/nrf52_mx25.c => nrf53/nrf5340-dk/src/nrf53_mx25.c} (89%)
[nuttx] 01/03: arch/nrf53: add HFCLK192M clock support
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 5ff6c8b4032a3b9fcf519dded65bec6672520325
Author: raiden00pl <ra...@railab.me>
AuthorDate: Tue May 23 11:45:40 2023 +0200
arch/nrf53: add HFCLK192M clock support
The HFCLK192M clock is required for QSPI to work
---
arch/arm/src/nrf53/Kconfig | 29 ++++++++
arch/arm/src/nrf53/hardware/nrf53_clock.h | 120 ++++++++++++++++++++----------
arch/arm/src/nrf53/nrf53_clockconfig.c | 22 ++++++
arch/arm/src/nrf53/nrf53_clockconfig.h | 16 ++++
4 files changed, 148 insertions(+), 39 deletions(-)
diff --git a/arch/arm/src/nrf53/Kconfig b/arch/arm/src/nrf53/Kconfig
index 3c9976c62d..5f4a831156 100644
--- a/arch/arm/src/nrf53/Kconfig
+++ b/arch/arm/src/nrf53/Kconfig
@@ -28,6 +28,7 @@ config NRF53_APPCORE
select NRF53_HAVE_UART1
select NRF53_HAVE_I2C123
select NRF53_HAVE_SPI1234
+ select NRF53_HAVE_HFCLK192M
config NRF53_NETCORE
bool
@@ -98,6 +99,10 @@ config NRF53_HAVE_SPI1234
bool
default n
+config NRF53_HAVE_HFCLK192M
+ bool
+ default n
+
# Peripheral Selection
config NRF53_I2C_MASTER
@@ -296,6 +301,30 @@ endchoice
endif # NRF53_USE_LFCLK
+config NRF53_USE_HFCLK192M
+ bool "Enable HFCLK192M"
+ default n
+ depends on NRF53_HAVE_HFCLK192M
+ ---help---
+ Enable HFCLK192M clock.
+
+if NRF53_USE_HFCLK192M
+
+choice
+ prompt "HFCLK192M source"
+ default NRF53_HFCLK192M_192
+
+config NRF53_HFCLK192M_192
+ bool "HFCLK192M is 192MHz"
+
+config NRF53_HFCLK192M_96
+ bool "HFCLK192M is 96MHz"
+
+config NRF53_HFCLK192M_48
+ bool "HFCLK192M is 48MHz"
+
+endchoice
+
config NRF53_OSCILLATOR_LFXO
bool "Configure LFXO oscillator"
default y if NRF53_LFCLK_XTAL
diff --git a/arch/arm/src/nrf53/hardware/nrf53_clock.h b/arch/arm/src/nrf53/hardware/nrf53_clock.h
index ed5ae645c2..f52a70a922 100644
--- a/arch/arm/src/nrf53/hardware/nrf53_clock.h
+++ b/arch/arm/src/nrf53/hardware/nrf53_clock.h
@@ -34,51 +34,85 @@
/* Register offsets *********************************************************/
-#define NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET 0x0000 /* Start HFCLK crystal oscillator */
-#define NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET 0x0004 /* Stop HFCLK crystal oscillator */
-#define NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET 0x0008 /* Start LFCLK source */
-#define NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET 0x000c /* Stop LFCLK source */
-#define NRF53_CLOCK_TASKS_CAL_OFFSET 0x0010 /* Start calibration of LFRC oscillator */
- /* TODO: */
-#define NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET 0x0100 /* HFCLK oscillator started */
-#define NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET 0x0104 /* LFCLK started */
-#define NRF53_CLOCK_EVENTS_DONE_OFFSET 0x011c /* Calibration of LFCLK RC oscillator complete event */
- /* TODO: */
-#define NRF53_CLOCK_INTENSET_OFFSET 0x0304 /* Enable interrupt */
-#define NRF53_CLOCK_INTENCLR_OFFSET 0x0308 /* Disable interrupt */
- /* TODO: */
-#define NRF53_CLOCK_HFCLKRUN_OFFSET 0x0408 /* Status indicating that HFCLKSTART task has been triggered */
-#define NRF53_CLOCK_HFCLKSTAT_OFFSET 0x040c /* HFCLK status */
-#define NRF53_CLOCK_LFCLKRUN_OFFSET 0x0414 /* Status indicating that LFCLKSTART task has been triggered */
-#define NRF53_CLOCK_LFCLKSTAT_OFFSET 0x0418 /* LFCLK status */
-#define NRF53_CLOCK_LFCLKSRCCOPY_OFFSET 0x041c /* Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */
- /* TODO: */
-#define NRF53_CLOCK_LFCLKSRC_OFFSET 0x0518 /* Clock source for the LFCLK */
- /* TODO */
+#define NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET 0x0000 /* Start HFCLK crystal oscillator */
+#define NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET 0x0004 /* Stop HFCLK crystal oscillator */
+#define NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET 0x0008 /* Start LFCLK source */
+#define NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET 0x000c /* Stop LFCLK source */
+#define NRF53_CLOCK_TASKS_CAL_OFFSET 0x0010 /* Start calibration of LFRC oscillator */
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTART_OFFSET 0x0018 /* Start HFCLKAUDIO source */
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTOP_OFFSET 0x001c /* Stop HFCLKAUDIO source */
+#define NRF53_CLOCK_TASKS_HFCLK192MSTART_OFFSET 0x0020 /* Start HFCLK192M source as selected in HFCLK192MSRC */
+#define NRF53_CLOCK_TASKS_HFCLK192MSTOP_OFFSET 0x0024 /* Stop HFCLK192M source */
+ /* TODO: */
+#define NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET 0x0100 /* HFCLK oscillator started */
+#define NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET 0x0104 /* LFCLK started */
+#define NRF53_CLOCK_EVENTS_DONE_OFFSET 0x011c /* Calibration of LFCLK RC oscillator complete event */
+#define NRF53_CLOCK_EVENTS_HFCLKAUDIOSTARTED_OFFSET 0x0120 /* HFCLKAUDIO source started */
+#define NRF53_CLOCK_EVENTS_HFCLK192MSTARTED_OFFSET 0x0124 /* HFCLK192M source started */
+ /* TODO: */
+#define NRF53_CLOCK_INTENSET_OFFSET 0x0304 /* Enable interrupt */
+#define NRF53_CLOCK_INTENCLR_OFFSET 0x0308 /* Disable interrupt */
+ /* TODO: */
+#define NRF53_CLOCK_HFCLKRUN_OFFSET 0x0408 /* Status indicating that HFCLKSTART task has been triggered */
+#define NRF53_CLOCK_HFCLKSTAT_OFFSET 0x040c /* HFCLK status */
+#define NRF53_CLOCK_LFCLKRUN_OFFSET 0x0414 /* Status indicating that LFCLKSTART task has been triggered */
+#define NRF53_CLOCK_LFCLKSTAT_OFFSET 0x0418 /* LFCLK status */
+#define NRF53_CLOCK_LFCLKSRCCOPY_OFFSET 0x041c /* Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */
+#define NRF53_CLOCK_HFCLKAUDIORUN_OFFSET 0x0450 /* Status indicating that HFCLKAUDIOSTART task has been triggered */
+#define NRF53_CLOCK_HFCLKAUDIOSTAT_OFFSET 0x0454 /* Status indicating which HFCLKAUDIO source is running */
+#define NRF53_CLOCK_HFCLK192MRUN_OFFSET 0x0458 /* Status indicating that HFCLK192MSTART task has been triggered */
+#define NRF53_CLOCK_HFCLK192MSTAT_OFFSET 0x045c /* Status indicating which HFCLK192M source is running */
+#define NRF53_CLOCK_HFCLKSRC_OFFSET 0x0514 /* Clock source for HFCLK128M/HFCLK64M */
+#define NRF53_CLOCK_LFCLKSRC_OFFSET 0x0518 /* Clock source for the LFCLK */
+#define NRF53_CLOCK_HFCLKCTRL_OFFSET 0x0558 /* HFCLK128M frequency configuration */
+#define NRF53_CLOCK_HFCLKAUDIOFREQUENCY_OFFSET 0x055c /* Audio PLL frequency */
+#define NRF53_CLOCK_HFCLKALWAYSRUN_OFFSET 0x0570 /* Automatic or manual control of HFCLK128M/HFCLK64M */
+#define NRF53_CLOCK_LFCLKALWAYSRUN_OFFSET 0x0574 /* Automatic or manual control of LFCLK */
+#define NRF53_CLOCK_HFCLKAUDIOALWAYSRUN_OFFSET 0x057c /* Automatic or manual control of HFCLKAUDIO */
+#define NRF53_CLOCK_HFCLK192MSRC_OFFSET 0x0580 /* Clock source for HFCLK192M */
+#define NRF53_CLOCK_HFCLK192MALWAYSRUN_OFFSET 0x0584 /* Automatic or manual control of HFCLK192M */
+#define NRF53_CLOCK_HFCLK192MCTRL_OFFSET 0x05b8 /* HFCLK192M frequency configuration */
/* Register definitions *****************************************************/
-#define NRF53_CLOCK_TASKS_HFCLKSTART (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET)
-#define NRF53_CLOCK_TASKS_HFCLKSTOP (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET)
-#define NRF53_CLOCK_TASKS_LFCLKSTART (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET)
-#define NRF53_CLOCK_TASKS_LFCLKSTOP (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET)
-#define NRF53_CLOCK_TASKS_CAL (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_CAL_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKSTART (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKSTOP (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET)
+#define NRF53_CLOCK_TASKS_LFCLKSTART (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_LFCLKSTOP (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET)
+#define NRF53_CLOCK_TASKS_CAL (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_CAL_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTART (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKAUDIOSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTOP (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKAUDIOSTOP_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLK192MSTART (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLK192MSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLK192MSTOP (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLK192MSTOP_OFFSET)
/* TODO */
-#define NRF53_CLOCK_EVENTS_HFCLKSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET)
-#define NRF53_CLOCK_EVENTS_LFCLKSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET)
-#define NRF53_CLOCK_EVENTS_DONE (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_DONE_OFFSET)
+#define NRF53_CLOCK_EVENTS_HFCLKSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET)
+#define NRF53_CLOCK_EVENTS_LFCLKSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET)
+#define NRF53_CLOCK_EVENTS_DONE (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_DONE_OFFSET)
+#define NRF53_CLOCK_EVENTS_HFCLKAUDIOSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLKAUDIOSTARTED_OFFSET)
+#define NRF53_CLOCK_EVENTS_HFCLK192MSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLK192MSTARTED_OFFSET)
/* TODO */
-#define NRF53_CLOCK_INTENSET (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENSET_OFFSET)
-#define NRF53_CLOCK_INTENCLR (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENCLR_OFFSET)
-/* TODO */
-#define NRF53_CLOCK_HFCLKRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKRUN_OFFSET)
-#define NRF53_CLOCK_HFCLKSTAT (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKSTAT_OFFSET)
-#define NRF53_CLOCK_LFCLKRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKRUN_OFFSET)
-#define NRF53_CLOCK_LFCLKSTAT (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSTAT_OFFSET)
-#define NRF53_CLOCK_LFCLKSRCCOPY (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRCCOPY_OFFSET)
-/* TODO */
-#define NRF53_CLOCK_LFCLKSRC (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRC_OFFSET)
+#define NRF53_CLOCK_INTENSET (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENSET_OFFSET)
+#define NRF53_CLOCK_INTENCLR (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENCLR_OFFSET)
/* TODO */
+#define NRF53_CLOCK_HFCLKRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKRUN_OFFSET)
+#define NRF53_CLOCK_HFCLKSTAT (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKSTAT_OFFSET)
+#define NRF53_CLOCK_LFCLKRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKRUN_OFFSET)
+#define NRF53_CLOCK_LFCLKSTAT (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSTAT_OFFSET)
+#define NRF53_CLOCK_LFCLKSRCCOPY (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRCCOPY_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIORUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIORUN_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIOSTAT (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIOSTAT_OFFSET)
+#define NRF53_CLOCK_HFCLK192MRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MRUN_OFFSET)
+#define NRF53_CLOCK_HFCLK192MSTAT (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MSTAT_OFFSET)
+#define NRF53_CLOCK_HFCLKSRC (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKSRC_OFFSET)
+#define NRF53_CLOCK_LFCLKSRC (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRC_OFFSET)
+#define NRF53_CLOCK_HFCLKCTRL (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKCTRL_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIOFREQUENCY (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIOFREQUENCY_OFFSET)
+#define NRF53_CLOCK_HFCLKALWAYSRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_LFCLKALWAYSRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIOALWAYSRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIOALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_HFCLK192MSRC (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MSRC_OFFSET)
+#define NRF53_CLOCK_HFCLK192MALWAYSRUN (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_HFCLK192MCTRL (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MCTRL_OFFSET)
/* Register bit definitions *************************************************/
@@ -117,4 +151,12 @@
# define CLOCK_LFCLKSRC_SRC_LFXO (2 << CLOCK_LFCLKSTAT_SRC_SHIFT)
# define CLOCK_LFCLKSRC_SRC_LFSYNT (3 << CLOCK_LFCLKSTAT_SRC_SHIFT)
+/* HFCLK192MSRC Register */
+
+#define CLOCK_HFCLK192MSRC_SRC_SHIFT (0) /* Bits 0-1: HFCLK192M clock source */
+#define CLOCK_HFCLK192MSRC_SRC_MASK (3 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+# define CLOCK_HFCLK192MSRC_DIV1 (0 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+# define CLOCK_HFCLK192MSRC_DIV2 (1 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+# define CLOCK_HFCLK192MSRC_DIV4 (2 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+
#endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_CLOCK_H */
diff --git a/arch/arm/src/nrf53/nrf53_clockconfig.c b/arch/arm/src/nrf53/nrf53_clockconfig.c
index 27a6862789..19bb9a346c 100644
--- a/arch/arm/src/nrf53/nrf53_clockconfig.c
+++ b/arch/arm/src/nrf53/nrf53_clockconfig.c
@@ -106,4 +106,26 @@ void nrf53_clockconfig(void)
/* TODO: calibrate LFCLK RC oscillator */
#endif
#endif
+
+#ifdef CONFIG_NRF53_USE_HFCLK192M
+ /* Initialize HFCLK192M */
+
+#if defined(CONFIG_NRF53_HFCLK192M_192)
+ putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV1);
+#elif defined(CONFIG_NRF53_HFCLK192M_96)
+ putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV2);
+#elif defined(CONFIG_NRF53_HFCLK192M_48)
+ putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV4);
+#endif
+
+ /* Trigger HFCLK192M start */
+
+ putreg32(0x0, NRF53_CLOCK_EVENTS_HFCLK192MSTARTED);
+ putreg32(0x1, NRF53_CLOCK_TASKS_HFCLK192MSTART);
+
+ while (!getreg32(NRF53_CLOCK_EVENTS_HFCLK192MSTARTED))
+ {
+ /* Wait for HFCLK192M to be running */
+ }
+#endif
}
diff --git a/arch/arm/src/nrf53/nrf53_clockconfig.h b/arch/arm/src/nrf53/nrf53_clockconfig.h
index 050fce088b..e368253045 100644
--- a/arch/arm/src/nrf53/nrf53_clockconfig.h
+++ b/arch/arm/src/nrf53/nrf53_clockconfig.h
@@ -38,6 +38,22 @@
* (32k_clk)
*/
+/* HFCLK192M configuration */
+
+#ifdef CONFIG_NRF53_USE_HFCLK192M
+# if defined(CONFIG_NRF53_HFCLK192M_192)
+# define NRF53_PCLK192M_FREQ 192000000
+# elif defined(CONFIG_NRF53_HFCLK192M_96)
+# define NRF53_PCLK192M_FREQ 96000000
+# elif defined(CONFIG_NRF53_HFCLK192M_48)
+# define NRF53_PCLK192M_FREQ 48000000
+# else
+# error Invalid configuration
+# endif
+#else
+# define NRF53_PCLK192M_FREQ 0
+#endif
+
#ifndef __ASSEMBLY__
/****************************************************************************
[nuttx] 02/03: arch/nrf53: add QSPI support
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 8b89730e61673b2447d4c8514009ad126dae5956
Author: raiden00pl <ra...@railab.me>
AuthorDate: Tue May 23 11:45:16 2023 +0200
arch/nrf53: add QSPI support
---
arch/arm/src/nrf53/Kconfig | 27 +
arch/arm/src/nrf53/Make.defs | 4 +
arch/arm/src/nrf53/hardware/nrf53_qspi.h | 224 ++++++++
arch/arm/src/nrf53/nrf53_clockconfig.c | 6 +-
arch/arm/src/nrf53/nrf53_qspi.c | 942 +++++++++++++++++++++++++++++++
arch/arm/src/nrf53/nrf53_qspi.h | 52 ++
6 files changed, 1252 insertions(+), 3 deletions(-)
diff --git a/arch/arm/src/nrf53/Kconfig b/arch/arm/src/nrf53/Kconfig
index 5f4a831156..fc4a279b2b 100644
--- a/arch/arm/src/nrf53/Kconfig
+++ b/arch/arm/src/nrf53/Kconfig
@@ -29,6 +29,7 @@ config NRF53_APPCORE
select NRF53_HAVE_I2C123
select NRF53_HAVE_SPI1234
select NRF53_HAVE_HFCLK192M
+ select NRF53_HAVE_QSPI
config NRF53_NETCORE
bool
@@ -103,6 +104,10 @@ config NRF53_HAVE_HFCLK192M
bool
default n
+config NRF53_HAVE_QSPI
+ bool
+ default n
+
# Peripheral Selection
config NRF53_I2C_MASTER
@@ -212,6 +217,11 @@ config NRF53_UART1
select UART1_SERIALDRIVER
select NRF53_UART
+config NRF53_QSPI
+ bool "QSPI"
+ default n
+ depends on NRF53_HAVE_QSPI
+
config NRF53_TIMER0
bool "TIMER0"
select NRF53_TIMER
@@ -325,6 +335,8 @@ config NRF53_HFCLK192M_48
endchoice
+endif # NRF53_USE_HFCLK192M
+
config NRF53_OSCILLATOR_LFXO
bool "Configure LFXO oscillator"
default y if NRF53_LFCLK_XTAL
@@ -610,6 +622,21 @@ config NRF53_I2C_MASTER_COPY_BUF_SIZE
endmenu
+menu "QSPI Configuration"
+
+if NRF53_QSPI
+
+config NRF53_QSPI_RXDELAY
+ int "QSPI RX delay"
+ default 2
+ range 0 7
+ ---help---
+ The input serial data sampling delay.
+
+endif # NRF53_QSPI
+
+endmenu # QSPI Configuration
+
menuconfig NRF53_SOFTDEVICE_CONTROLLER
bool "SoftDevice Controller"
depends on ALLOW_BSDNORDIC_COMPONENTS
diff --git a/arch/arm/src/nrf53/Make.defs b/arch/arm/src/nrf53/Make.defs
index b56975db25..faf0f4a698 100644
--- a/arch/arm/src/nrf53/Make.defs
+++ b/arch/arm/src/nrf53/Make.defs
@@ -95,6 +95,10 @@ ifeq ($(CONFIG_USBDEV),y)
CHIP_CSRCS += nrf53_usbd.c
endif
+ifeq ($(CONFIG_NRF53_QSPI),y)
+CHIP_CSRCS += nrf53_qspi.c
+endif
+
ifeq ($(CONFIG_NRF53_SOFTDEVICE_CONTROLLER),y)
NRFXLIB_UNPACK := sdk-nrfxlib
diff --git a/arch/arm/src/nrf53/hardware/nrf53_qspi.h b/arch/arm/src/nrf53/hardware/nrf53_qspi.h
new file mode 100644
index 0000000000..7ac201aa43
--- /dev/null
+++ b/arch/arm/src/nrf53/hardware/nrf53_qspi.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+ * arch/arm/src/nrf53/hardware/nrf53_qspi.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H
+#define __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "hardware/nrf53_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register offsets *********************************************************/
+
+#define NRF53_QSPI_TASKS_ACTIVATE_OFFSET 0x0000 /* Activate QSPI interface */
+#define NRF53_QSPI_TASKS_READSTART_OFFSET 0x0004 /* Start transfer from external flash memory to internal RAM */
+#define NRF53_QSPI_TASKS_WRITESTART_OFFSET 0x0008 /* Start transfer from internal RAM to external flash memory */
+#define NRF53_QSPI_TASKS_ERASESTART_OFFSET 0x000c /* Start external flash memory erase operation */
+#define NRF53_QSPI_TASKS_DEACTIVATE_OFFSET 0x0010 /* Deactivate QSPI interface */
+#define NRF53_QSPI_EVENTS_READY_OFFSET 0x0100 /* QSPI peripheral is ready */
+#define NRF53_QSPI_INTEN_OFFSET 0x0300 /* Enable or disable interrupt */
+#define NRF53_QSPI_INTENSET_OFFSET 0x0304 /* Enable interrupt */
+#define NRF53_QSPI_INTENCLR_OFFSET 0x0308 /* Disable interrupt */
+#define NRF53_QSPI_ENABLE_OFFSET 0x0500 /* Enable QSPI peripheral */
+#define NRF53_QSPI_READ_SRC_OFFSET 0x0504 /* Flash memory source address */
+#define NRF53_QSPI_READ_DST_OFFSET 0x0508 /* RAM destination address */
+#define NRF53_QSPI_READ_CNT_OFFSET 0x050c /* Read transfer length */
+#define NRF53_QSPI_WRITE_SRC_OFFSET 0x0510 /* Flash destination address */
+#define NRF53_QSPI_WRITE_DST_OFFSET 0x0514 /* RAM source address */
+#define NRF53_QSPI_WRITE_CNT_OFFSET 0x0518 /* Write transfer length */
+#define NRF53_QSPI_ERASE_PTR_OFFSET 0x051c /* Start address of flash block to be erased */
+#define NRF53_QSPI_ERASE_LEN_OFFSET 0x0520 /* Size of block to be erased */
+#define NRF53_QSPI_PSEL_SCK_OFFSET 0x0524 /* Pin select for serial clock SCK */
+#define NRF53_QSPI_PSEL_CSN_OFFSET 0x0528 /* Pin select for chip select signal CSN */
+#define NRF53_QSPI_PSEL_IO0_OFFSET 0x0530 /* Pin select for serial data MOSI/IO0 */
+#define NRF53_QSPI_PSEL_IO1_OFFSET 0x0534 /* Pin select for serial data MISO/IO1 */
+#define NRF53_QSPI_PSEL_IO2_OFFSET 0x0538 /* Pin select for serial data IO2 */
+#define NRF53_QSPI_PSEL_IO3_OFFSET 0x053c /* Pin select for serial data IO3 */
+#define NRF53_QSPI_XIPOFFSET_OFFSET 0x0540 /* Address offset into the external memory for XIP */
+#define NRF53_QSPI_IFCONFIG0_OFFSET 0x0544 /* Interface configuration */
+#define NRF53_QSPI_XIPEN_OFFSET 0x054c /* Enable Execute in Place operation. */
+#define NRF53_QSPI_XIPENC_KEY0_OFFSET 0x0560 /* Bits 31:0 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_KEY1_OFFSET 0x0564 /* Bits 63:32 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_KEY2_OFFSET 0x0568 /* Bits 95:64 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_KEY3_OFFSET 0x056c /* Bits 95:64 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_NONCE0_OFFSET 0x0570 /* Bits 127:96 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_NONCE1_OFFSET 0x0574 /* Bits 31:0 of XIP NONCE */
+#define NRF53_QSPI_XIPENC_NONCE2_OFFSET 0x0578 /* Bits 63:32 of XIP NONCE */
+#define NRF53_QSPI_XIPENC_ENABLE_OFFSET 0x057c /* Enable stream cipher for XIP */
+#define NRF53_QSPI_DMAENC_KEY0_OFFSET 0x0580 /* Bits 31:0 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_KEY1_OFFSET 0x0584 /* Bits 63:32 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_KEY2_OFFSET 0x0588 /* Bits 95:64 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_KEY3_OFFSET 0x058c /* Bits 127:96 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_NONCE0_OFFSET 0x0590 /* Bits 31:0 of DMA NONCE */
+#define NRF53_QSPI_DMAENC_NONCE1_OFFSET 0x0594 /* Bits 63:32 of DMA NONCE */
+#define NRF53_QSPI_DMAENC_NONCE2_OFFSET 0x0598 /* Bits 95:64 of DMA NONCE */
+#define NRF53_QSPI_DMAENC_ENABLE_OFFSET 0x059c /* Enable stream cipher for EasyDMA */
+#define NRF53_QSPI_IFCONFIG1_OFFSET 0x0600 /* Interface configuration */
+#define NRF53_QSPI_STATUS_OFFSET 0x0604 /* Status register */
+#define NRF53_QSPI_DPMDUR_OFFSET 0x0614 /* DPM duration */
+#define NRF53_QSPI_ADDRCONF_OFFSET 0x0624 /* Extended address configuration. */
+#define NRF53_QSPI_CINSTRCONF_OFFSET 0x0634 /* Custom instruction configuration register. */
+#define NRF53_QSPI_CINSTRDAT0_OFFSET 0x0638 /* Custom instruction data register 0. */
+#define NRF53_QSPI_CINSTRDAT1_OFFSET 0x063c /* Custom instruction data register 1. */
+#define NRF53_QSPI_IFTIMING_OFFSET 0x0640 /* SPI interface timing. */
+
+/* Register Bitfield Definitions ********************************************/
+
+/* INTEN/INTENSET/INTENCLR */
+
+#define QSPI_INT_READY (1 << 0)
+
+/* ENABLE */
+
+#define QSPI_ENABLE_EN (1)
+#define QSPI_ENABLE_DIS (0)
+
+/* ERASE.LEN */
+
+#define QSPI_ERASE_SECTOR (0)
+#define QSPI_ERASE_PAGE (1)
+#define QSPI_ERASE_ALL (2)
+
+/* PSEL */
+
+#define QSPI_PSEL_PIN_SHIFT (0)
+#define QSPI_PSEL_PORT_SHIFT (5)
+#define QSPI_PSEL_CONNECT (1 << 31)
+
+/* IFCONFIG0 */
+
+#define QSPI_IFCONFIG0_READOC_SHIFT (0)
+#define QSPI_IFCONFIG0_READOC_MASK (0x7 << QSPI_IFCONFIG0_READOC_SHIFT)
+# define QSPI_IFCONFIG0_READOC_FASTREAD (0 << QSPI_IFCONFIG0_READOC_SHIFT)
+# define QSPI_IFCONFIG0_READOC_READ2O (1 << QSPI_IFCONFIG0_READOC_SHIFT)
+# define QSPI_IFCONFIG0_READOC_READ2IO (2 << QSPI_IFCONFIG0_READOC_SHIFT)
+# define QSPI_IFCONFIG0_READOC_READ4O (3 << QSPI_IFCONFIG0_READOC_SHIFT)
+# define QSPI_IFCONFIG0_READOC_READ4IO (4 << QSPI_IFCONFIG0_READOC_SHIFT)
+#define QSPI_IFCONFIG0_WRITEOC_SHIFT (3)
+#define QSPI_IFCONFIG0_WRITEOC_MASK (0x7 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+# define QSPI_IFCONFIG0_WRITEOC_PP (0 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+# define QSPI_IFCONFIG0_WRITEOC_PP2O (1 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+# define QSPI_IFCONFIG0_WRITEOC_PP4O (2 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+# define QSPI_IFCONFIG0_WRITEOC_PP4IO (3 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+#define QSPI_IFCONFIG0_ADDRMODE_24 (0 << 6)
+#define QSPI_IFCONFIG0_ADDRMODE_32 (1 << 6)
+#define QSPI_IFCONFIG0_DPMENABLE (1 << 7)
+#define QSPI_IFCONFIG0_PPSIZE_512 (1 << 12)
+
+/* IFCONFIG1 */
+
+#define QSPI_IFCONFIG1_SCKDELAY_SHIFT (0)
+#define QSPI_IFCONFIG1_SCKDELAY_MASK (0xff << QSPI_IFCONFIG1_SCKDELAY_SHIFT)
+#define QSPI_IFCONFIG1_DPMEN_EXIT (0 << 24)
+#define QSPI_IFCONFIG1_DPMEN_ENTER (1 << 24)
+#define QSPI_IFCONFIG1_SPIMODE_0 (0 << 25)
+#define QSPI_IFCONFIG1_SPIMODE_3 (1 << 25)
+#define QSPI_IFCONFIG1_SCKFREQ_SHIFT (28)
+#define QSPI_IFCONFIG1_SCKFREQ_MASK (0xf << QSPI_IFCONFIG1_SCKFREQ_SHIFT)
+
+/* STATUS */
+
+#define QSPI_STATUS_DPM (1 << 2)
+#define QSPI_STATUS_READY (1 << 3)
+#define QSPI_STATUS_SREG_SHIFT (24)
+#define QSPI_STATUS_SREG_MASK (0xff << QSPI_STATUS_SREG_SHIFT)
+
+/* DPMDUR */
+
+#define QSPI_DPMDUR_ENTER_SHIFT (0)
+#define QSPI_DPMDUR_ENTER_MASK (0xffff << QSPI_DPMDUR_ENTER_SHIFT)
+#define QSPI_DPMDUR_EXIT_SHIFT (16)
+#define QSPI_DPMDUR_EXIT_MASK (0xffff << QSPI_DPMDUR_EXIT_SHIFT)
+
+/* ADDRCONF */
+
+#define QSPI_ADDRCONF_OPCODE_SHIFT (0)
+#define QSPI_ADDRCONF_OPCODE_MASK (0xff << QSPI_ADDRCONF_OPCODE_SHIFT)
+#define QSPI_ADDRCONF_BYTE0_SHIFT (8)
+#define QSPI_ADDRCONF_BYTE0_MASK (0xff << QSPI_ADDRCONF_BYTE0_SHIFT)
+#define QSPI_ADDRCONF_BYTE1_SHIFT (16)
+#define QSPI_ADDRCONF_BYTE1_MASK (0xff << QSPI_ADDRCONF_BYTE1_SHIFT)
+#define QSPI_ADDRCONF_MODE_SHIFT (24)
+#define QSPI_ADDRCONF_MODE_MASK (0x3 << QSPI_ADDRCONF_MODE_SHIFT)
+# define QSPI_ADDRCONF_MODE_NOINSTR (0 << QSPI_ADDRCONF_MODE_SHIFT)
+# define QSPI_ADDRCONF_MODE_OPCODE (1 << QSPI_ADDRCONF_MODE_SHIFT)
+# define QSPI_ADDRCONF_MODE_OPBYTE0 (2 << QSPI_ADDRCONF_MODE_SHIFT)
+# define QSPI_ADDRCONF_MODE_ALL (3 << QSPI_ADDRCONF_MODE_SHIFT)
+#define QSPI_ADDRCONF_WIPWAIT (1 << 26)
+#define QSPI_ADDRCONF_WREN (1 << 27)
+
+/* CINSTRCONF */
+
+#define QSPI_CINSTRCONF_OPCODE_SHIFT (0)
+#define QSPI_CINSTRCONF_OPCODE_MASK (0xff << QSPI_CINSTRCONF_OPCODE_SHIFT)
+#define QSPI_CINSTRCONF_LENGTH_SHIFT (8)
+#define QSPI_CINSTRCONF_LENGTH_MASK (0xf << QSPI_CINSTRCONF_LENGTH_SHIFT)
+#define QSPI_CINSTRCONF_LENGTH(n) ((n) << QSPI_CINSTRCONF_LENGTH_SHIFT)
+#define QSPI_CINSTRCONF_LIO2 (1 << 12)
+#define QSPI_CINSTRCONF_LIO3 (1 << 13)
+#define QSPI_CINSTRCONF_WIPWAIT (1 << 14)
+#define QSPI_CINSTRCONF_WREN (1 << 15)
+#define QSPI_CINSTRCONF_LFEN (1 << 16)
+#define QSPI_CINSTRCONF_LFSTOP_STOP (1 << 17)
+
+/* CINSTRDAT0 */
+
+#define QSPI_CINSTRDAT0_BYTE0_SHIFT (0)
+#define QSPI_CINSTRDAT0_BYTE0_MASK (0xff << QSPI_CINSTRDAT0_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE0(n) ((n) << QSPI_CINSTRDAT0_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE1_SHIFT (8)
+#define QSPI_CINSTRDAT0_BYTE1_MASK (0xff << QSPI_CINSTRDAT0_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE1(n) ((n) << QSPI_CINSTRDAT0_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE2_SHIFT (16)
+#define QSPI_CINSTRDAT0_BYTE2_MASK (0xff << QSPI_CINSTRDAT0_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE2(n) ((n) << QSPI_CINSTRDAT0_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE3_SHIFT (24)
+#define QSPI_CINSTRDAT0_BYTE3_MASK (0xff << QSPI_CINSTRDAT0_BYTE3_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE3(n) ((n) << QSPI_CINSTRDAT0_BYTE3_SHIFT)
+
+/* CINSTRDAT1 */
+
+#define QSPI_CINSTRDAT1_BYTE0_SHIFT (0)
+#define QSPI_CINSTRDAT1_BYTE0_MASK (0xff << QSPI_CINSTRDAT1_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE0(n) ((n) << QSPI_CINSTRDAT1_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE1_SHIFT (8)
+#define QSPI_CINSTRDAT1_BYTE1_MASK (0xff << QSPI_CINSTRDAT1_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE1(n) ((n) << QSPI_CINSTRDAT1_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE2_SHIFT (16)
+#define QSPI_CINSTRDAT1_BYTE2_MASK (0xff << QSPI_CINSTRDAT1_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE2(n) ((n) << QSPI_CINSTRDAT1_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE3_SHIFT (24)
+#define QSPI_CINSTRDAT1_BYTE3_MASK (0xff << QSPI_CINSTRDAT1_BYTE3_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE3(n) ((n) << QSPI_CINSTRDAT1_BYTE3_SHIFT)
+
+/* IFTIMING */
+
+#define QSPI_IFTIMING_RXDELAY_SHIFT (8)
+#define QSPI_IFTIMING_RXDELAY_MASK (0xff << QSPI_IFTIMING_RXDELAY_SHIFT)
+#define QSPI_IFTIMING_RXDELAY(n) ((n) << QSPI_IFTIMING_RXDELAY_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H */
diff --git a/arch/arm/src/nrf53/nrf53_clockconfig.c b/arch/arm/src/nrf53/nrf53_clockconfig.c
index 19bb9a346c..e205b33634 100644
--- a/arch/arm/src/nrf53/nrf53_clockconfig.c
+++ b/arch/arm/src/nrf53/nrf53_clockconfig.c
@@ -111,11 +111,11 @@ void nrf53_clockconfig(void)
/* Initialize HFCLK192M */
#if defined(CONFIG_NRF53_HFCLK192M_192)
- putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV1);
+ putreg32(CLOCK_HFCLK192MSRC_DIV1, NRF53_CLOCK_HFCLK192MSRC);
#elif defined(CONFIG_NRF53_HFCLK192M_96)
- putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV2);
+ putreg32(CLOCK_HFCLK192MSRC_DIV2, NRF53_CLOCK_HFCLK192MSRC);
#elif defined(CONFIG_NRF53_HFCLK192M_48)
- putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV4);
+ putreg32(CLOCK_HFCLK192MSRC_DIV4, NRF53_CLOCK_HFCLK192MSRC);
#endif
/* Trigger HFCLK192M start */
diff --git a/arch/arm/src/nrf53/nrf53_qspi.c b/arch/arm/src/nrf53/nrf53_qspi.c
new file mode 100644
index 0000000000..7f06a96596
--- /dev/null
+++ b/arch/arm/src/nrf53/nrf53_qspi.c
@@ -0,0 +1,942 @@
+/****************************************************************************
+ * arch/arm/src/nrf53/nrf53_qspi.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/mutex.h>
+#include <nuttx/semaphore.h>
+#include <arch/board/board.h>
+
+#include "arm_internal.h"
+
+#include "hardware/nrf53_qspi.h"
+
+#include "nrf53_clockconfig.h"
+#include "nrf53_gpio.h"
+#include "nrf53_qspi.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if ((NRF53_PCLK192M_FREQ != 192000000) && (NRF53_PCLK192M_FREQ != 96000000))
+# error not supported PCLK192M frequency
+#endif
+
+/* QSPI frequency limits */
+
+#define NRF53_QSPI_FREQMAX (NRF53_PCLK192M_FREQ / (2 * 1))
+#define NRF53_QSPI_FREQMIN (NRF53_PCLK192M_FREQ / (2 * 16))
+
+/* Instruction handled by the NRF53 QSPI peripheral */
+
+#define QSPI_SECTOR_ERASE 0x20
+#define QSPI_BLOCK_ERASE 0xd8
+#define QSPI_ALL_ERASE 0xc7
+
+/* QSPI memory synchronization */
+
+#define MEMORY_SYNC() do { ARM_DSB(); ARM_ISB(); } while (0)
+
+/* Ensure that the DMA buffers are word-aligned. */
+
+#define ALIGN_SHIFT 2
+#define ALIGN_MASK 3
+#define ALIGN_UP(n) (((n)+ALIGN_MASK) & ~ALIGN_MASK)
+#define IS_ALIGNED(n) (((uint32_t)(n) & ALIGN_MASK) == 0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct nrf53_qspidev_s
+{
+ struct qspi_dev_s qspi; /* Externally visible part of the QSPI interface */
+ mutex_t lock; /* Assures mutually exclusive access to QSPI */
+ uint32_t base; /* QSPI base address */
+ uint32_t actual; /* Actual clock frequency */
+ uint32_t frequency; /* Requested clock frequency */
+ bool initialized; /* TRUE: Controller has been initialized */
+ uint8_t intf; /* QSPI controller number (0) */
+ uint8_t mode; /* Mode 0,3 */
+ sem_t op_sem; /* Block until complete */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helpers */
+
+static inline void nrf53_qspi_putreg(struct nrf53_qspidev_s *priv,
+ uint32_t offset,
+ uint32_t value);
+static inline uint32_t nrf53_qspi_getreg(struct nrf53_qspidev_s *priv,
+ uint32_t offset);
+static void nrf53_qspi_cinstrdata_get(struct nrf53_qspidev_s *priv,
+ struct qspi_cmdinfo_s *cmdinfo);
+static void nrf53_qspi_cinstrdata_put(struct nrf53_qspidev_s *priv,
+ struct qspi_cmdinfo_s *cmdinfo);
+
+/* QSPI operations */
+
+static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock);
+
+static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock);
+static uint32_t nrf53_qspi_setfrequency(struct qspi_dev_s *dev,
+ uint32_t frequency);
+static void nrf53_qspi_setmode(struct qspi_dev_s *dev,
+ enum qspi_mode_e mode);
+static void nrf53_qspi_setbits(struct qspi_dev_s *dev, int nbits);
+static int nrf53_qspi_command(struct qspi_dev_s *dev,
+ struct qspi_cmdinfo_s *cmdinfo);
+static int nrf53_qspi_memory(struct qspi_dev_s *dev,
+ struct qspi_meminfo_s *meminfo);
+static void *nrf53_qspi_alloc(struct qspi_dev_s *dev, size_t buflen);
+static void nrf53_qspi_free(struct qspi_dev_s *dev, void *buffer);
+
+static int nrf53_qspi_interrupt(int irq, void *context, void *arg);
+static int nrf53_qspi_hw_initialize(struct nrf53_qspidev_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct qspi_ops_s g_qspi_ops =
+{
+ .lock = nrf53_qspi_lock,
+ .setfrequency = nrf53_qspi_setfrequency,
+ .setmode = nrf53_qspi_setmode,
+ .setbits = nrf53_qspi_setbits,
+ .command = nrf53_qspi_command,
+ .memory = nrf53_qspi_memory,
+ .alloc = nrf53_qspi_alloc,
+ .free = nrf53_qspi_free,
+};
+
+static struct nrf53_qspidev_s g_qspi0_dev =
+{
+ .qspi =
+ {
+ .ops = &g_qspi_ops,
+ },
+ .lock = NXMUTEX_INITIALIZER,
+ .op_sem = SEM_INITIALIZER(0),
+ .base = NRF53_QSPI_BASE,
+ .intf = 0
+};
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_qspi_putreg
+ *
+ * Description:
+ * Put a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline void nrf53_qspi_putreg(struct nrf53_qspidev_s *priv,
+ uint32_t offset,
+ uint32_t value)
+{
+ putreg32(value, priv->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_getreg
+ *
+ * Description:
+ * Get a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline uint32_t nrf53_qspi_getreg(struct nrf53_qspidev_s *priv,
+ uint32_t offset)
+{
+ return getreg32(priv->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_lock
+ *
+ * Description:
+ * On QSPI buses where there are multiple devices, it will be necessary to
+ * lock QSPI to have exclusive access to the buses for a sequence of
+ * transfers. The bus should be locked before the chip is selected. After
+ * locking the QSPI bus, the caller should then also call the setfrequency,
+ * setbits, and setmode methods to make sure that the QSPI is properly
+ * configured for the device. If the QSPI bus is being shared, then it
+ * may have been left in an incompatible state.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * lock - true: Lock QSPI bus, false: unlock QSPI bus
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock)
+{
+ struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
+ int ret;
+
+ spiinfo("lock=%d\n", lock);
+ if (lock)
+ {
+ ret = nxmutex_lock(&priv->lock);
+ }
+ else
+ {
+ ret = nxmutex_unlock(&priv->lock);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_setfrequency
+ *
+ * Description:
+ * Set the QSPI frequency.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * frequency - The QSPI frequency requested
+ *
+ * Returned Value:
+ * Returns the actual frequency selected
+ *
+ ****************************************************************************/
+
+static uint32_t nrf53_qspi_setfrequency(struct qspi_dev_s *dev,
+ uint32_t frequency)
+{
+ struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
+ uint32_t sckfreq = 0;
+ uint32_t actual = 0;
+ uint32_t regval = 0;
+
+ spiinfo("frequency=%ld\n", frequency);
+ DEBUGASSERT(priv);
+
+ /* Check if the requested frequency is the same as the frequency
+ * selection
+ */
+
+ if (priv->frequency == frequency)
+ {
+ /* We are already at this frequency. Return the actual. */
+
+ return priv->actual;
+ }
+
+ /* Get prescaler */
+
+ if (frequency <= NRF53_QSPI_FREQMIN)
+ {
+ sckfreq = 15;
+ }
+ else if (frequency <= NRF53_QSPI_FREQMAX)
+ {
+ sckfreq = ((NRF53_PCLK192M_FREQ / 2) / frequency) - 1;
+ }
+ else
+ {
+ sckfreq = 0;
+ }
+
+ /* Modify register */
+
+ regval = nrf53_qspi_getreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET);
+ regval &= ~QSPI_IFCONFIG1_SCKFREQ_MASK;
+ regval |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_SHIFT;
+ nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET, regval);
+
+ /* Calculate the new actual frequency */
+
+ actual = NRF53_PCLK192M_FREQ / (2 * (sckfreq + 1));
+
+ /* Save the frequency setting */
+
+ priv->frequency = frequency;
+ priv->actual = actual;
+
+ spiinfo("Frequency %ld->%ld\n", frequency, actual);
+
+ return actual;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_setmode
+ *
+ * Description:
+ * Set the QSPI mode. Optional. See enum qspi_mode_e for mode definitions.
+ * NOTE: the NRF53 QSPI supports only modes 0 and 3.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * mode - The QSPI mode requested
+ *
+ * Returned Value:
+ * none
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_setmode(struct qspi_dev_s *dev, enum qspi_mode_e mode)
+{
+ struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
+ uint32_t regval = 0;
+
+ spiinfo("mode=%d\n", mode);
+
+ /* Has the mode changed? */
+
+ if (mode != priv->mode)
+ {
+ regval = nrf53_qspi_getreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET);
+
+ switch (mode)
+ {
+ case QSPIDEV_MODE0:
+ {
+ regval |= (QSPI_IFCONFIG1_SPIMODE_0);
+ break;
+ }
+
+ case QSPIDEV_MODE3:
+ {
+ regval |= (QSPI_IFCONFIG1_SPIMODE_3);
+ break;
+ }
+
+ case QSPIDEV_MODE1:
+ case QSPIDEV_MODE2:
+ {
+ spiinfo("unsupported mode=%d\n", mode);
+
+ /* No break here */
+ }
+ default:
+ {
+ DEBUGASSERT(0);
+ return;
+ }
+ }
+
+ /* Write new mode */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET, regval);
+
+ /* Save the mode so that subsequent re-configurations will be faster */
+
+ priv->mode = mode;
+ }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_setbits
+ *
+ * Description:
+ * Set the number of bits per word.
+ * NOTE: the NRF53 QSPI only supports 8 bits, so this does nothing.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * nbits - The number of bits requests
+ *
+ * Returned Value:
+ * none
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_setbits(struct qspi_dev_s *dev, int nbits)
+{
+ if (nbits != 8)
+ {
+ spiinfo("unsupported nbits=%d\n", nbits);
+ DEBUGASSERT(FALSE);
+ }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_cinstrdata_get
+ *
+ * Description:
+ * Get command data
+ *
+ * Input Parameters:
+ * priv - Device state structure.
+ * cmdinfo - Describes the command transfer to be performed.
+ *
+ * Returned Value:
+ * Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_cinstrdata_get(struct nrf53_qspidev_s *priv,
+ struct qspi_cmdinfo_s *cmdinfo)
+{
+ uint32_t regval = 0;
+ int i = 0;
+ uint8_t *buffer = cmdinfo->buffer;
+
+ DEBUGASSERT(cmdinfo->buflen <= 8);
+
+ /* Get Bytes 0-3 */
+
+ regval = nrf53_qspi_getreg(priv, NRF53_QSPI_CINSTRDAT0_OFFSET);
+
+ if (cmdinfo->buflen > 0)
+ {
+ for (i = 0; (i < 4) && (i < cmdinfo->buflen); i += 1)
+ {
+ buffer[i] = (regval >> (i * 8)) & 0xff;
+ }
+ }
+
+ /* Write Bytes 4-7 */
+
+ regval = nrf53_qspi_getreg(priv, NRF53_QSPI_CINSTRDAT1_OFFSET);
+
+ if (cmdinfo->buflen > 4)
+ {
+ for (i = 4; (i < 8) && (i < cmdinfo->buflen); i += 1)
+ {
+ buffer[i] = (regval >> ((i - 4) * 8)) & 0xff;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_cinstrdata_put
+ *
+ * Description:
+ * Put command data
+ *
+ * Input Parameters:
+ * priv - Device state structure.
+ * cmdinfo - Describes the command transfer to be performed.
+ *
+ * Returned Value:
+ * Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_cinstrdata_put(struct nrf53_qspidev_s *priv,
+ struct qspi_cmdinfo_s *cmdinfo)
+{
+ uint32_t regval = 0;
+ int i = 0;
+ uint8_t *buffer = cmdinfo->buffer;
+
+ DEBUGASSERT(cmdinfo->buflen <= 8);
+
+ regval = 0;
+
+ if (cmdinfo->buflen > 0)
+ {
+ for (i = 0; (i < 4) && (i < cmdinfo->buflen); i += 1)
+ {
+ regval |= (buffer[i] << (i * 8));
+ }
+ }
+
+ /* Write Bytes 0-3 */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRDAT0_OFFSET, regval);
+
+ regval = 0;
+ if (cmdinfo->buflen > 4)
+ {
+ for (i = 4; (i < 8) && (i < cmdinfo->buflen); i += 1)
+ {
+ regval |= (buffer[i] << ((i - 4) * 8));
+ }
+ }
+
+ /* Write Bytes 4-7 */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRDAT1_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_command
+ *
+ * Description:
+ * Perform one QSPI data transfer
+ *
+ * TODO: long frame mode not supported
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * cmdinfo - Describes the command transfer to be performed.
+ *
+ * Returned Value:
+ * Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_command(struct qspi_dev_s *dev,
+ struct qspi_cmdinfo_s *cmdinfo)
+{
+ struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
+ uint32_t regval = 0;
+
+ DEBUGASSERT(cmdinfo->cmd < 256);
+
+ if (QSPICMD_ISADDRESS(cmdinfo->flags))
+ {
+ /* Only ERASE commands supported */
+
+ switch (cmdinfo->cmd)
+ {
+ case QSPI_SECTOR_ERASE:
+ {
+ regval = QSPI_ERASE_SECTOR;
+ break;
+ }
+
+ case QSPI_BLOCK_ERASE:
+ {
+ regval = QSPI_ERASE_PAGE;
+ break;
+ }
+
+ case QSPI_ALL_ERASE:
+ {
+ regval = QSPI_ERASE_ALL;
+ break;
+ }
+
+ default:
+ {
+ /* Not supported addressed command */
+
+ DEBUGASSERT(0);
+ return -EINVAL;
+ }
+ }
+
+ /* Configure erase length */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_ERASE_LEN_OFFSET, regval);
+
+ /* Configure erase address */
+
+ regval = cmdinfo->addr;
+ nrf53_qspi_putreg(priv, NRF53_QSPI_ERASE_PTR_OFFSET, regval);
+
+ /* Start erase operation */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_ERASESTART_OFFSET, 1);
+
+ /* Wait for the READY event.
+ * TODO: add timeout.
+ *
+ * NOTE: READ event only signals that the erase operation
+ * has been started.
+ */
+
+ nxsem_wait(&priv->op_sem);
+
+ return OK;
+ }
+
+ if (QSPICMD_ISWRITE(cmdinfo->flags))
+ {
+ /* Write data to CINSTRDAT registers */
+
+ nrf53_qspi_cinstrdata_put(priv, cmdinfo);
+ }
+
+ /* Configure custom instruction */
+
+ regval = cmdinfo->cmd << QSPI_ADDRCONF_OPCODE_SHIFT;
+ regval |= QSPI_CINSTRCONF_LENGTH(cmdinfo->buflen + 1);
+
+ if (QSPICMD_ISWRITE(cmdinfo->flags))
+ {
+ /* Write request */
+
+ regval |= QSPI_CINSTRCONF_WREN;
+
+ /* Wait for write complete before sending command */
+
+ regval |= QSPI_CINSTRCONF_WIPWAIT;
+ }
+
+ /* IO2 and IO3 high during transmission of custom instruction */
+
+ regval |= QSPI_CINSTRCONF_LIO2 | QSPI_CINSTRCONF_LIO3;
+
+ /* Write CINSTRCONF register to initiate transfer */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRCONF_OFFSET, regval);
+
+ /* Wait for the READY event.
+ * TODO: add timeout.
+ */
+
+ nxsem_wait(&priv->op_sem);
+
+ if (QSPICMD_ISREAD(cmdinfo->flags))
+ {
+ /* Get response */
+
+ nrf53_qspi_cinstrdata_get(priv, cmdinfo);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_memory
+ *
+ * Description:
+ * Perform one QSPI memory transfer
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * meminfo - Describes the memory transfer to be performed.
+ *
+ * Returned Value:
+ * Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_memory(struct qspi_dev_s *dev,
+ struct qspi_meminfo_s *meminfo)
+{
+ struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_s *)dev;
+
+ DEBUGASSERT(meminfo->buffer != NULL && meminfo->buflen > 0);
+
+ if (QSPIMEM_ISWRITE(meminfo->flags))
+ {
+ /* Configure data transfer */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_SRC_OFFSET,
+ meminfo->addr);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_DST_OFFSET,
+ (uint32_t) meminfo->buffer);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_CNT_OFFSET,
+ meminfo->buflen);
+
+ /* Start WRITE task */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_WRITESTART_OFFSET, 1);
+ }
+ else
+ {
+ /* Configure data transfer */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_READ_SRC_OFFSET,
+ meminfo->addr);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_READ_DST_OFFSET,
+ (uint32_t) meminfo->buffer);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_READ_CNT_OFFSET,
+ meminfo->buflen);
+
+ /* Start READ task */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_READSTART_OFFSET, 1);
+ }
+
+ /* Wait for the READY event.
+ * TODO: add timeout.
+ */
+
+ nxsem_wait(&priv->op_sem);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_alloc
+ *
+ * Description:
+ * Allocate a buffer suitable for DMA data transfer
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * buflen - Buffer length to allocate in bytes
+ *
+ * Returned Value:
+ * Address of the allocated memory on success; NULL is returned on any
+ * failure.
+ *
+ ****************************************************************************/
+
+static void *nrf53_qspi_alloc(struct qspi_dev_s *dev, size_t buflen)
+{
+ return kmm_malloc(ALIGN_UP(buflen));
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_free
+ *
+ * Description:
+ * Free memory returned by QSPI_ALLOC
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * buffer - Buffer previously allocated via QSPI_ALLOC
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_free(struct qspi_dev_s *dev, void *buffer)
+{
+ if (buffer)
+ {
+ kmm_free(buffer);
+ }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_interrupt
+ *
+ * Description:
+ * Interrupt handler; we handle all QSPI cases -- reads, writes,
+ * automatic status polling, etc.
+ *
+ * Input Parameters:
+ * irq -
+ * context -
+ * qrg -
+ *
+ * Returned Value:
+ * OK means we handled it
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_interrupt(int irq, void *context, void *arg)
+{
+ struct nrf53_qspidev_s *priv = arg;
+
+ /* Clear READY event */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_EVENTS_READY_OFFSET, 0);
+
+ /* Signal TASK complete */
+
+ nxsem_post(&g_qspi0_dev.op_sem);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_hw_initialize
+ *
+ * Description:
+ * Initialize the QSPI peripheral from hardware reset.
+ *
+ * Input Parameters:
+ * priv - Device state structure.
+ *
+ * Returned Value:
+ * Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_hw_initialize(struct nrf53_qspidev_s *priv)
+{
+ uint32_t regval = 0;
+ int pin = 0;
+ int port = 0;
+ int ret = 0;
+
+ /* Only for QSPI0 */
+
+ DEBUGASSERT(priv->intf == 0);
+
+ /* Attach the interrupt handler */
+
+ ret = irq_attach(NRF53_IRQ_QSPI, nrf53_qspi_interrupt, priv);
+ if (ret < 0)
+ {
+ spierr("ERROR: Failed to attach QSPI irq\n");
+ return ret;
+ }
+
+ /* SCK pin */
+
+ nrf53_gpio_config(NRF53_QSPI0_SCK_PIN | GPIO_DRIVE_H0H1);
+ pin = GPIO_PIN_DECODE(NRF53_QSPI0_SCK_PIN);
+ port = GPIO_PORT_DECODE(NRF53_QSPI0_SCK_PIN);
+ regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_SCK_OFFSET, regval);
+
+ /* CSN pin */
+
+ nrf53_gpio_config(NRF53_QSPI0_CSN_PIN | GPIO_DRIVE_H0H1);
+ pin = GPIO_PIN_DECODE(NRF53_QSPI0_CSN_PIN);
+ port = GPIO_PORT_DECODE(NRF53_QSPI0_CSN_PIN);
+ regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_CSN_OFFSET, regval);
+
+ /* IO0 pin */
+
+ nrf53_gpio_config(NRF53_QSPI0_IO0_PIN | GPIO_DRIVE_H0H1);
+ pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO0_PIN);
+ port = GPIO_PORT_DECODE(NRF53_QSPI0_IO0_PIN);
+ regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO0_OFFSET, regval);
+
+ /* IO1 pin */
+
+ nrf53_gpio_config(NRF53_QSPI0_IO1_PIN | GPIO_DRIVE_H0H1);
+ pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO1_PIN);
+ port = GPIO_PORT_DECODE(NRF53_QSPI0_IO1_PIN);
+ regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO1_OFFSET, regval);
+
+ /* IO2 pin */
+
+ nrf53_gpio_config(NRF53_QSPI0_IO2_PIN | GPIO_DRIVE_H0H1);
+ pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO2_PIN);
+ port = GPIO_PORT_DECODE(NRF53_QSPI0_IO2_PIN);
+ regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO2_OFFSET, regval);
+
+ /* IO3 pin */
+
+ nrf53_gpio_config(NRF53_QSPI0_IO3_PIN | GPIO_DRIVE_H0H1);
+ pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO3_PIN);
+ port = GPIO_PORT_DECODE(NRF53_QSPI0_IO3_PIN);
+ regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+ nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO3_OFFSET, regval);
+
+ /* Configure quad data line SPI */
+
+ regval = (QSPI_IFCONFIG0_READOC_READ4IO | QSPI_IFCONFIG0_WRITEOC_PP4IO);
+ regval |= QSPI_IFCONFIG0_PPSIZE_512;
+ nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG0_OFFSET, regval);
+
+ /* Enable READY interrupt */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_INTENSET_OFFSET, QSPI_INT_READY);
+
+ /* Configure RX delay */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_IFTIMING_OFFSET,
+ QSPI_IFTIMING_RXDELAY(CONFIG_NRF53_QSPI_RXDELAY));
+
+ /* Enable QSPI interrupts */
+
+ up_enable_irq(NRF53_IRQ_QSPI);
+
+ /* Enable QSPI */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_ENABLE_OFFSET, 1);
+
+ /* Activate QSPI */
+
+ nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_ACTIVATE_OFFSET, 1);
+
+ /* Wait for READY event.
+ * TODO: add timeout.
+ */
+
+ nxsem_wait(&priv->op_sem);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_qspi_initialize
+ *
+ * Description:
+ * Initialize the selected QSPI port in master mode
+ *
+ * Input Parameters:
+ * intf - Interface number(must be zero)
+ *
+ * Returned Value:
+ * Valid QSPI device structure reference on success; a NULL on failure
+ *
+ ****************************************************************************/
+
+struct qspi_dev_s *nrf53_qspi_initialize(int intf)
+{
+ struct nrf53_qspidev_s *priv = NULL;
+ int ret = OK;
+
+ /* The NRF53 has only a single QSPI port */
+
+ spiinfo("intf: %d\n", intf);
+ DEBUGASSERT(intf == 0);
+
+ /* Select the QSPI interface */
+
+ if (intf == 0)
+ {
+ /* Select QSPI0 */
+
+ priv = &g_qspi0_dev;
+ }
+ else
+ {
+ spierr("ERROR: QSPI%d not supported\n", intf);
+ return NULL;
+ }
+
+ /* Has the QSPI hardware been initialized? */
+
+ if (!priv->initialized)
+ {
+ /* Perform hardware initialization. Puts the QSPI into an active
+ * state.
+ */
+
+ ret = nrf53_qspi_hw_initialize(priv);
+ if (ret < 0)
+ {
+ spierr("ERROR: Failed to initialize QSPI hardware\n");
+ irq_detach(NRF53_IRQ_QSPI);
+ return NULL;
+ }
+
+ /* Enable interrupts at the NVIC */
+
+ priv->initialized = true;
+ }
+
+ return &priv->qspi;
+}
diff --git a/arch/arm/src/nrf53/nrf53_qspi.h b/arch/arm/src/nrf53/nrf53_qspi.h
new file mode 100644
index 0000000000..f0c1d3a660
--- /dev/null
+++ b/arch/arm/src/nrf53/nrf53_qspi.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * arch/arm/src/nrf53/nrf53_qspi.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H
+#define __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/spi/qspi.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_qspi_initialize
+ *
+ * Description:
+ * Initialize the selected QSPI port in master mode
+ *
+ * Input Parameters:
+ * intf - Interface number(must be zero)
+ *
+ * Returned Value:
+ * Valid QSPI device structure reference on success; a NULL on failure
+ *
+ ****************************************************************************/
+
+struct qspi_dev_s *nrf53_qspi_initialize(int intf);
+
+#endif /* __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H */
[nuttx] 03/03: boards/nrf5340-dk: add mx25 memory support
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit e06ce27f566656dd25f943f7935bebcf6045d59d
Author: raiden00pl <ra...@railab.me>
AuthorDate: Tue May 23 12:00:07 2023 +0200
boards/nrf5340-dk: add mx25 memory support
From now on-board QSPI memory is supported.
---
.../nrf5340-dk/configs/qspi_cpuapp/#defconfig# | 44 +++++++++
.../nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig | 50 ++++++++++
boards/arm/nrf53/nrf5340-dk/include/board.h | 24 +++++
boards/arm/nrf53/nrf5340-dk/src/Make.defs | 6 +-
boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h | 12 +++
boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c | 10 ++
boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c | 107 +++++++++++++++++++++
7 files changed, 252 insertions(+), 1 deletion(-)
diff --git a/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/#defconfig# b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/#defconfig#
new file mode 100644
index 0000000000..ba94923f38
--- /dev/null
+++ b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/#defconfig#
@@ -0,0 +1,44 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="nrf5340-dk"
+CONFIG_ARCH_BOARD_NRF5340_DK=y
+CONFIG_ARCH_CHIP="nrf53"
+CONFIG_ARCH_CHIP_NRF5340=y
+CONFIG_ARCH_CHIP_NRF5340_CPUAPP=y
+CONFIG_ARCH_CHIP_NRF53=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_STDARG_H=y
+CONFIG_BOARD_LOOPSPERMSEC=5500
+CONFIG_EXPERIMENTAL=y
+CONFIG_FS_LITTLEFS=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_MM_REGIONS=2
+CONFIG_MTD=y
+CONFIG_MTD_MX25RXX=y
+CONFIG_NRF52_QSPI=y
+CONFIG_NRF53_UART0=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=524288
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=26
+CONFIG_START_MONTH=3
+CONFIG_SYMTAB_ORDEREDBYNAME=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig
new file mode 100644
index 0000000000..5ff9c59011
--- /dev/null
+++ b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig
@@ -0,0 +1,50 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="nrf5340-dk"
+CONFIG_ARCH_BOARD_NRF5340_DK=y
+CONFIG_ARCH_CHIP="nrf53"
+CONFIG_ARCH_CHIP_NRF5340=y
+CONFIG_ARCH_CHIP_NRF5340_CPUAPP=y
+CONFIG_ARCH_CHIP_NRF53=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_STDARG_H=y
+CONFIG_BOARD_LOOPSPERMSEC=5500
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FS_LITTLEFS=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_MM_REGIONS=2
+CONFIG_MTD=y
+CONFIG_MTD_MX25RXX=y
+CONFIG_MX25RXX_QSPI_FREQUENCY=98000000
+CONFIG_MX25RXX_QSPI_READ_FREQUENCY=98000000
+CONFIG_NRF53_QSPI=y
+CONFIG_NRF53_QSPI_RXDELAY=1
+CONFIG_NRF53_UART0=y
+CONFIG_NRF53_USE_HFCLK192M=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=524288
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=26
+CONFIG_START_MONTH=3
+CONFIG_SYMTAB_ORDEREDBYNAME=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/nrf53/nrf5340-dk/include/board.h b/boards/arm/nrf53/nrf5340-dk/include/board.h
index 5ee9b31916..e535d03f0a 100644
--- a/boards/arm/nrf53/nrf5340-dk/include/board.h
+++ b/boards/arm/nrf53/nrf5340-dk/include/board.h
@@ -155,4 +155,28 @@
#define NRF53_ADC_CH2_PIN (GPIO_MCUSEL_APP | GPIO_INPUT | GPIO_PORT0 | GPIO_PIN(6))
#define NRF53_ADC_CH3_PIN (GPIO_MCUSEL_APP | GPIO_INPUT | GPIO_PORT0 | GPIO_PIN(7))
+/* QSPI Pins ****************************************************************/
+
+/* QSPI0
+ * QSPI CS - P0.18
+ * QSPI SCK - P0.17
+ * QSPI IO0 - P0.13
+ * QSPI IO1 - P0.14
+ * QSPI IO2 - P0.15
+ * QSPI IO3 - P0.16
+ */
+
+#define NRF53_QSPI0_CSN_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+ GPIO_VALUE_ONE | GPIO_PORT0 | GPIO_PIN(18))
+#define NRF53_QSPI0_SCK_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+ GPIO_PORT0 | GPIO_PIN(17))
+#define NRF53_QSPI0_IO0_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+ GPIO_PORT0 | GPIO_PIN(13))
+#define NRF53_QSPI0_IO1_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+ GPIO_PORT0 | GPIO_PIN(14))
+#define NRF53_QSPI0_IO2_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+ GPIO_PORT0 | GPIO_PIN(15))
+#define NRF53_QSPI0_IO3_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+ GPIO_PORT0 | GPIO_PIN(16))
+
#endif /* __BOARDS_ARM_NRF53_NRF5340_DK_INCLUDE_BOARD_H */
diff --git a/boards/arm/nrf53/nrf5340-dk/src/Make.defs b/boards/arm/nrf53/nrf5340-dk/src/Make.defs
index d28956f307..3ce6ef9935 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/Make.defs
+++ b/boards/arm/nrf53/nrf5340-dk/src/Make.defs
@@ -56,6 +56,10 @@ ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
CSRCS += nrf53_composite.c
endif
+ifeq ($(CONFIG_NRF53_QSPI),y)
+CSRCS += nrf53_mx25.c
+endif
+
DEPPATH += --dep-path board
VPATH += :board
-CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
\ No newline at end of file
+CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h b/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h
index 4b0b0ecef7..0b52d1d2a2 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h
@@ -118,5 +118,17 @@ int nrf53_pwm_setup(void);
int nrf53_adc_setup(void);
#endif
+/****************************************************************************
+ * Name: nrf53_mx25_initialize
+ *
+ * Description:
+ * Initialize the MX25RXX QSPI memeory
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NRF53_QSPI
+int nrf53_mx25_initialize(void);
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_NRF53_NRF5340_DK_SRC_NRF5340_DK_H */
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c b/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c
index d9698045a2..c59768f9f8 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c
@@ -285,6 +285,16 @@ int nrf53_bringup(void)
usbdev_rndis_initialize(mac);
#endif
+#ifdef CONFIG_NRF53_QSPI
+ /* Initialize the MX25 QSPU memory */
+
+ ret = nrf53_mx25_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: nrf53_mx25_initialize() failed: %d\n", ret);
+ }
+#endif
+
/* Initialize BLE */
#ifdef CONFIG_NRF53_APPCORE
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c b/boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c
new file mode 100644
index 0000000000..6b5fb81570
--- /dev/null
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c
@@ -0,0 +1,107 @@
+/****************************************************************************
+ * boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/spi/qspi.h>
+
+#include "nrf53_qspi.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_mx25_initialize
+ *
+ * Description:
+ * Initialize the MX25RXX QSPI memeory
+ *
+ ****************************************************************************/
+
+int nrf53_mx25_initialize(void)
+{
+ struct qspi_dev_s *qspi_dev;
+ struct mtd_dev_s *mtd_dev;
+ char blockdev[32];
+ int ret = -1;
+
+ /* Create an instance of the NRF53 QSPI device driver */
+
+ qspi_dev = nrf53_qspi_initialize(0);
+ if (!qspi_dev)
+ {
+ _err("nrf53_qspi_initialize() failed\n");
+ return -1;
+ }
+
+ _info("nrf53_qspi_initialize() successful\n");
+
+ /* Use the QSPI device instance to initialize the MX25 device */
+
+ mtd_dev = mx25rxx_initialize(qspi_dev, true);
+ if (!mtd_dev)
+ {
+ _err("mx25rxx_initialize() failed\n");
+ return -1;
+ }
+
+ /* Configure the device with no partition support */
+
+ snprintf(blockdev, sizeof(blockdev), "/dev/mtdqspi%d", 0);
+
+ ret = register_mtddriver(blockdev, mtd_dev, 0755, NULL);
+ if (ret != OK)
+ {
+ _err("register_mtddriver() failed: %d\n", ret);
+ return -1;
+ }
+
+ _info("register_mtddriver() successful\n");
+
+#ifdef CONFIG_FS_LITTLEFS
+ ret = nx_mount(blockdev, "/mnt/qspi", "littlefs", 0, NULL);
+ if (ret < 0)
+ {
+ ret = nx_mount(blockdev, "/mnt/qspi", "littlefs", 0,
+ "forceformat");
+ if (ret < 0)
+ {
+ _err("nx_mount() failed: %d\n", ret);
+ }
+ else
+ {
+ _info("nx_mount() successful\n");
+ }
+ }
+#endif
+
+ return ret;
+}