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

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

commit 0c4d66dcf07f0b8e32508dc425c8804f6659ca6e
Author: jturnsek <jernej.turn...@gmail.com>
AuthorDate: Mon Apr 12 09:12:16 2021 +0200

    FlexSPI NOR driver added
---
 .../arm/imxrt/imxrt1064-evk/configs/nsh/defconfig  |   2 +
 boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h |   4 +-
 boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c |   9 +
 .../imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c    | 701 +++++++++++++++++++++
 4 files changed, 714 insertions(+), 2 deletions(-)

diff --git a/boards/arm/imxrt/imxrt1064-evk/configs/nsh/defconfig 
b/boards/arm/imxrt/imxrt1064-evk/configs/nsh/defconfig
index 1d7f1bb..210debd 100644
--- a/boards/arm/imxrt/imxrt1064-evk/configs/nsh/defconfig
+++ b/boards/arm/imxrt/imxrt1064-evk/configs/nsh/defconfig
@@ -37,3 +37,5 @@ CONFIG_START_DAY=14
 CONFIG_START_MONTH=3
 CONFIG_SYSTEM_NSH=y
 CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_IMXRT_FLEXSPI1=y
+CONFIG_MTD=y
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
index f6b16a3..8376c5d 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
@@ -313,8 +313,8 @@ void imxrt_lcd_initialize(void);
 int imxrt_usbhost_initialize(void);
 #endif
 
-#ifdef CONFIG_MTD_FLEXSPI_NOR
-int imxrt_flexspi_nor_setup(void);
+#ifdef CONFIG_IMXRT_FLEXSPI
+int imxrt_flexspi_nor_initialize(void);
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
index 0014941..1d8dfd6 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
@@ -278,6 +278,15 @@ int imxrt_bringup(void)
   usbdev_serialinitialize(0);
 #endif
 
+#ifdef CONFIG_IMXRT_FLEXSPI
+  ret = imxrt_flexspi_nor_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+              "ERROR: imxrt_flexspi_nor_initialize failed: %d\n", ret);
+    }
+#endif /* CONFIG_IMXRT_FLEXSPI */
+
   UNUSED(ret);
   return OK;
 }
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c
new file mode 100644
index 0000000..07df334
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c
@@ -0,0 +1,701 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.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 <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/signal.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/mtd/mtd.h>
+
+#include "imxrt_flexspi.h"
+#include "imxrt1064-evk.h"
+#include "hardware/imxrt_pinmux.h"
+
+#ifdef CONFIG_IMXRT_FLEXSPI
+
+#define NOR_PAGE_SIZE   0x0100U
+#define NOR_SECTOR_SIZE 0x1000U
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+enum
+{
+  /* SPI instructions */
+
+  READ_ID,
+  READ_STATUS_REG,
+  WRITE_STATUS_REG,
+  WRITE_ENABLE,
+  ERASE_SECTOR,
+  ERASE_CHIP,
+
+  /* Quad SPI instructions */
+
+  READ_FAST_QUAD_OUTPUT,
+  PAGE_PROGRAM_QUAD_INPUT,
+  ENTER_QPI,
+};
+
+static const uint32_t g_flexspi_nor_lut[][4] =
+{
+  [READ_ID] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x9f,
+        FLEXSPI_COMMAND_READ_SDR,  FLEXSPI_1PAD, 0x04),
+  },
+
+  [READ_STATUS_REG] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x05,
+        FLEXSPI_COMMAND_READ_SDR,  FLEXSPI_1PAD, 0x04),
+  },
+
+  [WRITE_STATUS_REG] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x01,
+        FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04),
+  },
+
+  [WRITE_ENABLE] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x06,
+        FLEXSPI_COMMAND_STOP,      FLEXSPI_1PAD, 0),
+  },
+
+  [ERASE_SECTOR] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x20,
+        FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18),
+  },
+
+  [ERASE_CHIP] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0xc7,
+        FLEXSPI_COMMAND_STOP,      FLEXSPI_1PAD, 0),
+  },
+
+  [READ_FAST_QUAD_OUTPUT] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x6b,
+        FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18),
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x08,
+        FLEXSPI_COMMAND_READ_SDR,  FLEXSPI_4PAD, 0x04),
+  },
+
+  [PAGE_PROGRAM_QUAD_INPUT] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x32,
+        FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18),
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_4PAD, 0x04,
+        FLEXSPI_COMMAND_STOP,      FLEXSPI_1PAD, 0),
+  },
+
+  [ENTER_QPI] =
+  {
+    FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR,       FLEXSPI_1PAD, 0x35,
+        FLEXSPI_COMMAND_STOP,      FLEXSPI_1PAD, 0),
+  },
+};
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* FlexSPI NOR device private data */
+
+struct imxrt_flexspi_nor_dev_s
+{
+  struct mtd_dev_s mtd;
+  struct flexspi_dev_s *flexspi;   /* Saved FlexSPI interface instance */
+  uint8_t *ahb_base;
+  enum flexspi_port_e port;
+  struct flexspi_device_config_s *config;
+};
+
+/****************************************************************************
+ * Private Functions Prototypes
+ ****************************************************************************/
+
+/* MTD driver methods */
+
+static int imxrt_flexspi_nor_erase(FAR struct mtd_dev_s *dev,
+                                   off_t startblock,
+                                   size_t nblocks);
+static ssize_t imxrt_flexspi_nor_read(FAR struct mtd_dev_s *dev,
+                                      off_t offset,
+                                      size_t nbytes,
+                                      FAR uint8_t *buffer);
+static ssize_t imxrt_flexspi_nor_bread(FAR struct mtd_dev_s *dev,
+                                       off_t startblock,
+                                       size_t nblocks,
+                                       FAR uint8_t *buffer);
+static ssize_t imxrt_flexspi_nor_bwrite(FAR struct mtd_dev_s *dev,
+                                        off_t startblock,
+                                        size_t nblocks,
+                                        FAR const uint8_t *buffer);
+static int imxrt_flexspi_nor_ioctl(FAR struct mtd_dev_s *dev,
+                                   int cmd,
+                                   unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct flexspi_device_config_s g_flexspi_device_config =
+{
+  .flexspi_root_clk = 120000000,
+  .flash_size = 8192,
+  .cs_interval_unit = FLEXSPI_CS_INTERVAL_UNIT1_SCK_CYCLE,
+  .cs_interval = 0,
+  .cs_hold_time = 3,
+  .cs_setup_time = 3,
+  .data_valid_time = 0,
+  .columnspace = 0,
+  .enable_word_address = 0,
+  .awr_seq_index = 0,
+  .awr_seq_number = 0,
+  .ard_seq_index = READ_FAST_QUAD_OUTPUT,
+  .ard_seq_number = 1,
+  .ahb_write_wait_unit = FLEXSPI_AHB_WRITE_WAIT_UNIT2_AHB_CYCLE,
+  .ahb_write_wait_interval = 0
+};
+
+static struct imxrt_flexspi_nor_dev_s g_flexspi_nor =
+{
+  .mtd =
+          {
+            .erase  = imxrt_flexspi_nor_erase,
+            .bread  = imxrt_flexspi_nor_bread,
+            .bwrite = imxrt_flexspi_nor_bwrite,
+            .read   = imxrt_flexspi_nor_read,
+            .ioctl  = imxrt_flexspi_nor_ioctl,
+#ifdef CONFIG_MTD_BYTE_WRITE
+            .write  = NULL,
+#endif
+            .name   = "imxrt_flexspi_nor"
+          },
+  .flexspi = (void *)0,
+  .ahb_base = (uint8_t *) 0x60000000,
+  .port = FLEXSPI_PORT_A1,
+  .config = &g_flexspi_device_config
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imxrt_flexspi_nor_get_vendor_id(
+                const struct imxrt_flexspi_nor_dev_s *dev,
+    uint8_t *vendor_id)
+{
+  uint32_t buffer = 0;
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = 0,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_READ,
+    .seq_number = 1,
+    .seq_index = READ_ID,
+    .data = &buffer,
+    .data_size = 1,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  *vendor_id = buffer;
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_read_status(
+                const struct imxrt_flexspi_nor_dev_s *dev,
+                uint32_t *status)
+{
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = 0,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_READ,
+    .seq_number = 1,
+    .seq_index = READ_STATUS_REG,
+    .data = status,
+    .data_size = 1,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_write_status(
+                const struct imxrt_flexspi_nor_dev_s *dev,
+    uint32_t *status)
+{
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = 0,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_WRITE,
+    .seq_number = 1,
+    .seq_index = WRITE_STATUS_REG,
+    .data = status,
+    .data_size = 1,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_write_enable(
+                const struct imxrt_flexspi_nor_dev_s *dev)
+{
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = 0,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_COMMAND,
+    .seq_number = 1,
+    .seq_index = WRITE_ENABLE,
+    .data = NULL,
+    .data_size = 0,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_erase_sector(
+                const struct imxrt_flexspi_nor_dev_s *dev,
+  off_t offset)
+{
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = offset,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_COMMAND,
+    .seq_number = 1,
+    .seq_index = ERASE_SECTOR,
+    .data = NULL,
+    .data_size = 0,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_erase_chip(
+                const struct imxrt_flexspi_nor_dev_s *dev)
+{
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = 0,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_COMMAND,
+    .seq_number = 1,
+    .seq_index = ERASE_CHIP,
+    .data = NULL,
+    .data_size = 0,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_page_program(
+                      const struct imxrt_flexspi_nor_dev_s *dev,
+                      off_t offset,
+                      const void *buffer,
+                      size_t len)
+{
+  int stat;
+
+  struct flexspi_transfer_s transfer =
+  {
+    .device_address = offset,
+    .port = dev->port,
+    .cmd_type = FLEXSPI_WRITE,
+    .seq_number = 1,
+    .seq_index = PAGE_PROGRAM_QUAD_INPUT,
+    .data = (uint32_t *) buffer,
+    .data_size = len,
+  };
+
+  stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer);
+  if (stat != 0)
+    {
+      return -EIO;
+    }
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_wait_bus_busy(
+                const struct imxrt_flexspi_nor_dev_s *dev)
+{
+  uint32_t status = 0;
+  int ret;
+
+  do
+    {
+      ret = imxrt_flexspi_nor_read_status(dev, &status);
+      if (ret)
+        {
+          return ret;
+        }
+    }
+  while (status & 1);
+
+  return 0;
+}
+
+static int imxrt_flexspi_nor_enable_quad_mode(
+                const struct imxrt_flexspi_nor_dev_s *dev)
+{
+  uint32_t status = 0x40;
+
+  imxrt_flexspi_nor_write_status(dev, &status);
+  imxrt_flexspi_nor_wait_bus_busy(dev);
+  FLEXSPI_SOFTWARE_RESET(dev->flexspi);
+
+  return 0;
+}
+
+static ssize_t imxrt_flexspi_nor_read(FAR struct mtd_dev_s *dev,
+                                      off_t offset,
+                                      size_t nbytes,
+                                      FAR uint8_t *buffer)
+{
+  FAR struct imxrt_flexspi_nor_dev_s *priv =
+                  (FAR struct imxrt_flexspi_nor_dev_s *)dev;
+  uint8_t *src;
+
+  finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
+
+  if (priv->port >= FLEXSPI_PORT_COUNT)
+    {
+      return -EIO;
+    }
+
+  src = priv->ahb_base + offset;
+
+  memcpy(buffer, src, nbytes);
+
+  finfo("return nbytes: %d\n", (int)nbytes);
+  return (ssize_t)nbytes;
+}
+
+static ssize_t imxrt_flexspi_nor_bread(FAR struct mtd_dev_s *dev,
+                                       off_t startblock,
+                                       size_t nblocks,
+                                       FAR uint8_t *buffer)
+{
+  ssize_t nbytes;
+
+  finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
+
+  /* On this device, we can handle the block read just like the byte-oriented
+   * read
+   */
+
+  nbytes = imxrt_flexspi_nor_read(dev, startblock * NOR_PAGE_SIZE,
+                                  nblocks * NOR_PAGE_SIZE, buffer);
+  if (nbytes > 0)
+    {
+      nbytes /= NOR_PAGE_SIZE;
+    }
+
+  return nbytes;
+}
+
+static ssize_t imxrt_flexspi_nor_bwrite(FAR struct mtd_dev_s *dev,
+                                        off_t startblock,
+                                        size_t nblocks,
+                                        FAR const uint8_t *buffer)
+{
+  FAR struct imxrt_flexspi_nor_dev_s *priv =
+                  (FAR struct imxrt_flexspi_nor_dev_s *)dev;
+  size_t len = nblocks * NOR_PAGE_SIZE;
+  off_t offset = startblock * NOR_PAGE_SIZE;
+  uint8_t *src = (uint8_t *) buffer;
+  uint8_t *dst = priv->ahb_base + startblock * NOR_PAGE_SIZE;
+  int i;
+
+  finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
+
+  while (len)
+    {
+      i = MIN(NOR_PAGE_SIZE, len);
+      imxrt_flexspi_nor_write_enable(priv);
+      imxrt_flexspi_nor_page_program(priv, offset, src, i);
+      imxrt_flexspi_nor_wait_bus_busy(priv);
+      FLEXSPI_SOFTWARE_RESET(priv->flexspi);
+      offset += i;
+      len -= i;
+    }
+
+#ifdef CONFIG_ARMV7M_DCACHE
+  up_invalidate_dcache((uintptr_t)dst,
+                       (uintptr_t)dst + nblocks * NOR_PAGE_SIZE);
+#endif
+
+  return nblocks;
+}
+
+static int imxrt_flexspi_nor_erase(FAR struct mtd_dev_s *dev,
+                                   off_t startblock,
+                                   size_t nblocks)
+{
+  FAR struct imxrt_flexspi_nor_dev_s *priv =
+                  (FAR struct imxrt_flexspi_nor_dev_s *)dev;
+  size_t blocksleft = nblocks;
+  uint8_t *dst = priv->ahb_base + startblock * NOR_SECTOR_SIZE;
+
+  finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
+
+  while (blocksleft-- > 0)
+    {
+      /* Erase each sector */
+
+      imxrt_flexspi_nor_write_enable(priv);
+      imxrt_flexspi_nor_erase_sector(priv, startblock * NOR_SECTOR_SIZE);
+      imxrt_flexspi_nor_wait_bus_busy(priv);
+      FLEXSPI_SOFTWARE_RESET(priv->flexspi);
+      startblock++;
+    }
+
+#ifdef CONFIG_ARMV7M_DCACHE
+  up_invalidate_dcache((uintptr_t)dst,
+                       (uintptr_t)dst + nblocks * NOR_SECTOR_SIZE);
+#endif
+
+  return (int)nblocks;
+}
+
+static int imxrt_flexspi_nor_ioctl(FAR struct mtd_dev_s *dev,
+                                   int cmd,
+                                   unsigned long arg)
+{
+  FAR struct imxrt_flexspi_nor_dev_s *priv =
+                  (FAR struct imxrt_flexspi_nor_dev_s *)dev;
+  int ret = -EINVAL; /* Assume good command with bad parameters */
+
+  finfo("cmd: %d \n", cmd);
+
+  switch (cmd)
+    {
+      case MTDIOC_GEOMETRY:
+        {
+          FAR struct mtd_geometry_s *geo =
+            (FAR struct mtd_geometry_s *)((uintptr_t)arg);
+
+          if (geo)
+            {
+              /* Populate the geometry structure with information need to
+               * know the capacity and how to access the device.
+               *
+               * NOTE:
+               * that the device is treated as though it where just an array
+               * of fixed size blocks.  That is most likely not true, but the
+               * client will expect the device logic to do whatever is
+               * necessary to make it appear so.
+               */
+
+              geo->blocksize    = (NOR_PAGE_SIZE);
+              geo->erasesize    = (NOR_SECTOR_SIZE);
+              geo->neraseblocks = 2048; /* 8MB only */
+
+              ret               = OK;
+
+              finfo("blocksize: %lu erasesize: %lu neraseblocks: %lu\n",
+                    geo->blocksize, geo->erasesize, geo->neraseblocks);
+            }
+        }
+        break;
+
+      case MTDIOC_BULKERASE:
+        {
+          /* Erase the entire device */
+
+          imxrt_flexspi_nor_write_enable(priv);
+          imxrt_flexspi_nor_erase_chip(priv);
+          imxrt_flexspi_nor_wait_bus_busy(priv);
+          FLEXSPI_SOFTWARE_RESET(priv->flexspi);
+        }
+        break;
+
+      case MTDIOC_PROTECT:
+
+        /* TODO */
+
+        break;
+
+      case MTDIOC_UNPROTECT:
+
+        /* TODO */
+
+        break;
+
+      default:
+        ret = -ENOTTY; /* Bad/unsupported command */
+        break;
+    }
+
+  finfo("return %d\n", ret);
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt_flexspi_nor_initialize
+ *
+ * Description:
+ *  This function is called by board-bringup logic to configure the
+ *  flash device.
+ *
+ * Returned Value:
+ *   Zero is returned on success.  Otherwise, a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int imxrt_flexspi_nor_initialize(void)
+{
+  uint8_t vendor_id;
+#ifdef CONFIG_FS_LITTLEFS
+  FAR struct mtd_dev_s *mtd_dev = &g_flexspi_nor.mtd;
+  int ret = -1;
+#endif
+  /* Configure multiplexed pins as connected on the board */
+
+  imxrt_config_gpio(GPIO_FLEXSPI_DQS);
+  imxrt_config_gpio(GPIO_FLEXSPI_CS);
+  imxrt_config_gpio(GPIO_FLEXSPI_IO0);
+  imxrt_config_gpio(GPIO_FLEXSPI_IO1);
+  imxrt_config_gpio(GPIO_FLEXSPI_IO2);
+  imxrt_config_gpio(GPIO_FLEXSPI_IO3);
+  imxrt_config_gpio(GPIO_FLEXSPI_SCK);
+
+  g_flexspi_nor.flexspi = imxrt_flexspi_initialize(0);
+  if (!g_flexspi_nor.flexspi)
+    {
+      return -1;
+    }
+
+  FLEXSPI_SET_DEVICE_CONFIG(g_flexspi_nor.flexspi,
+                            g_flexspi_nor.config,
+                            g_flexspi_nor.port);
+  FLEXSPI_UPDATE_LUT(g_flexspi_nor.flexspi,
+                     0,
+                     (const uint32_t *)g_flexspi_nor_lut,
+                     sizeof(g_flexspi_nor_lut) / 4);
+  FLEXSPI_SOFTWARE_RESET(g_flexspi_nor.flexspi);
+
+  if (imxrt_flexspi_nor_get_vendor_id(&g_flexspi_nor, &vendor_id))
+    {
+      return -EIO;
+    }
+
+  if (imxrt_flexspi_nor_enable_quad_mode(&g_flexspi_nor))
+    {
+      return -EIO;
+    }
+
+#ifdef CONFIG_FS_LITTLEFS
+  /* Register the MTD driver so that it can be accessed from the
+   * VFS.
+   */
+
+  ret = register_mtddriver("/dev/nor", mtd_dev, 0755, NULL);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to register MTD driver: %d\n",
+             ret);
+    }
+
+  /* mtd_dev->ioctl(mtd_dev, MTDIOC_BULKERASE, 0); */
+
+  /* Mount the LittleFS file system */
+
+  ret = nx_mount("/dev/nor", "/mnt/lfs", "littlefs", 0,
+                 "autoformat");
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to mount LittleFS at /mnt/lfs: %d\n",
+             ret);
+    }
+#endif
+
+  return 0;
+}
+
+#endif /* CONFIG_IMXRT_FLEXSPI */

Reply via email to