You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2020/09/29 06:19:18 UTC

[GitHub] [incubator-nuttx] Bhindhiya commented on a change in pull request #1910: Add RX65N SPI (RSPI) driver support

Bhindhiya commented on a change in pull request #1910:
URL: https://github.com/apache/incubator-nuttx/pull/1910#discussion_r496442440



##########
File path: arch/renesas/src/rx65n/rx65n_rspi_sw.c
##########
@@ -0,0 +1,2154 @@
+/****************************************************************************
+ * arch/renesas/src/rx65n/rx65n_rspi_sw.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 <sys/types.h>
+#include <stdint.h>
+#include <math.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+#include "up_arch.h"
+#include "rx65n_definitions.h"
+#include "rx65n_rspi.h"
+
+#include <arch/board/board.h>
+#include <arch/board/rx65n_gpio.h>
+
+#if defined(CONFIG_RX65N_RSPI0) || defined(CONFIG_RX65N_RSPI1) || defined(CONFIG_RX65N_RSPI2)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Default bit rate */
+
+#define RSPI_BRDV_DEFAULT 0
+
+/* The number of words that will fit in the Tx FIFO */
+
+#define RX65N_TXFIFO_WORDS BUFSIZE_4FRAME
+
+/* Interrupt priority */
+
+#define RX65N_RSPI_INTRRUPT_PRIO 15
+
+/* RSPI power on and off */
+
+#define RSPI_POWER_ON 0
+#define RSPI_POWER_OFF 1
+
+/* RSPI Register protection enable and disable */
+
+#define REG_PROTECTION_ON 1
+#define REG_PROTECTION_OFF 0
+
+/* Frequency divisor */
+
+enum FREQ_DIVISOR
+{
+  FREQ_DIVISOR_2 = 2,
+  FREQ_DIVISOR_4 = 4,
+  FREQ_DIVISOR_6 = 6,
+  FREQ_DIVISOR_8 = 8,
+  FREQ_DIVISOR_10 = 10,
+  FREQ_DIVISOR_12 = 12,
+  FREQ_DIVISOR_24 = 24,
+  FREQ_DIVISOR_48 = 48,
+  FREQ_DIVISOR_96 = 96,
+};
+
+/* The number of words that will fit in the buffer */
+
+enum BUF_SIZE
+{
+  BUFSIZE_1FRAME = 1,
+  BUFSIZE_2FRAME = 2,
+  BUFSIZE_3FRAME = 3,
+  BUFSIZE_4FRAME = 4,
+};
+
+/* RSPI events */
+
+typedef enum
+{
+  RSPI_EVT_TRANSFER_COMPLETE, /* The data transfer completed */
+  RSPI_EVT_TRANSFER_ABORTED,  /* The data transfer was aborted */
+  RSPI_EVT_ERR_MODE_FAULT,    /* Mode fault error */
+  RSPI_EVT_ERR_READ_OVF,      /* Read overflow */
+  RSPI_EVT_ERR_PARITY,        /* Parity error */
+  RSPI_EVT_ERR_UNDER_RUN,     /* Under run error */
+  RSPI_EVT_ERR_UNDEF          /* Undefined/unknown error event */
+} rspi_event_t;
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct rx65n_rspidev_s
+{
+  struct spi_dev_s  rspidev;  /* Externally visible part of the RSPI interface */
+  uint32_t  rspibase;         /* RSPIn base address */
+  uint32_t  rspiclock;        /* Clocking for the RSPI module */
+
+#ifndef CONFIG_SPI_POLLWAIT
+  uint8_t rspitxirq;  /* RSPI tx IRQ number */
+  uint8_t rspirxirq;  /* RSPI rx IRQ number */
+  uint8_t rspierirq;  /* RSPI error IRQ number */
+  uint8_t rspiidlirq; /* RSPI idle IRQ number */
+  uint32_t rspigrpbase;
+  uint32_t rspierimask;
+  uint32_t rspiidlimask;
+  sem_t waitsem;      /* Wait for transfer to complete */
+#endif
+
+  /* These following are the source and destination buffers of the transfer.
+   * they are retained in this structure so that they will be accessible
+   * from an interrupt handler.  The actual type of the buffer is uint8_t is
+   * nbits <=8 and uint16_t is nbits >8.
+   */
+
+  void *txbuffer;              /* Source buffer */
+  void *rxbuffer;              /* Destination buffer */
+
+  /* These are functions pointers that are configured to perform the
+   * appropriate transfer for the particular kind of exchange that is
+   * occurring.  Different functions may be selected depending on (1)
+   * if the tx or txbuffer is NULL and depending on the number of bits
+   * per word.
+   */
+
+  void (*txword)(struct rx65n_rspidev_s *priv);
+  void (*rxword)(struct rx65n_rspidev_s *priv);
+
+  bool initialized;   /* Has RSPI interface been initialized */
+  sem_t exclsem;      /* Held while chip is selected for mutual exclusion */
+  uint32_t frequency; /* Requested clock frequency */
+  uint32_t actual;    /* Actual clock frequency */
+
+  int	ntxwords;      /* Number of words left to transfer on the Tx Buffer */
+  int	nrxwords;      /* Number of words received on the Rx Buffer */
+  int	nwords;        /* Number of words to be exchanged */
+
+  uint8_t	nbits;     /* Width of word in bits (4 through 16) */
+  uint8_t	mode;      /* Mode 0,1,2,3 */
+  uint8_t	bufsize;   /* Buf size: 1,2,3 or 4 word */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helpers */
+
+static inline uint32_t rspi_getreg32(FAR struct rx65n_rspidev_s *priv,
+                                     uint8_t offset);
+static inline uint16_t rspi_getreg16(FAR struct rx65n_rspidev_s *priv,
+                                     uint8_t offset);
+static inline uint8_t rspi_getreg8(FAR struct rx65n_rspidev_s *priv,
+                                   uint8_t offset);
+static inline void rspi_putreg32(FAR struct rx65n_rspidev_s *priv,
+                                 uint8_t offset, uint32_t value);
+static inline void rspi_putreg16(FAR struct rx65n_rspidev_s *priv,
+                                 uint8_t offset, uint16_t value);
+static inline void rspi_putreg8(FAR struct rx65n_rspidev_s *priv,
+                                uint8_t offset, uint8_t value);
+
+/* SPI data transfer */
+
+static void rspi_txnull(struct rx65n_rspidev_s *priv);
+static void rspi_txuint32(struct rx65n_rspidev_s *priv);
+static void rspi_txuint16(struct rx65n_rspidev_s *priv);
+static void rspi_txuint8(struct rx65n_rspidev_s *priv);
+static void rspi_rxnull(struct rx65n_rspidev_s *priv);
+static void rspi_rxuint32(struct rx65n_rspidev_s *priv);
+static void rspi_rxuint16(struct rx65n_rspidev_s *priv);
+static void rspi_rxuint8(struct rx65n_rspidev_s *priv);
+static void rspi_performtx(struct rx65n_rspidev_s *priv);
+static inline void rspi_performrx(struct rx65n_rspidev_s *priv);
+static int rspi_transfer(struct rx65n_rspidev_s *priv, const void *txbuffer,
+                           void *rxbuffer, unsigned int nwords);
+
+/* Interrupt handling */
+
+#ifndef CONFIG_SPI_POLLWAIT
+static inline struct rx65n_rspidev_s *rspi_mapirq(int irq);
+static int rspi_idlinterrupt(int irq, void *context, FAR void *arg);
+static int rspi_erinterrupt(int irq, void *context, FAR void *arg);
+static int rspi_txinterrupt(int irq, void *context, FAR void *arg);
+static int rspi_rxinterrupt(int irq, void *context, FAR void *arg);
+#endif
+
+/* SPI methods */
+
+static int   rspi_lock(FAR struct spi_dev_s *dev, bool lock);
+static uint32_t rspi_setfrequency(FAR struct spi_dev_s *dev,
+                                  uint32_t frequency);
+static void  rspi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
+static void  rspi_setbits(FAR struct spi_dev_s *dev, int nbits);
+#ifdef CONFIG_SPI_HWFEATURES
+static int  rspi_hwfeatures(FAR struct spi_dev_s *dev,
+                                  spi_hwfeatures_t features);
+#endif
+static uint32_t rspi_send(FAR struct spi_dev_s *dev, uint32_t wd);
+static void rspi_exchange(FAR struct spi_dev_s *dev,
+                               FAR const void *txbuffer,
+                                FAR void *rxbuffer, size_t nwords);
+#ifdef CONFIG_SPI_TRIGGER
+static int  rspi_trigger(FAR struct spi_dev_s *dev);
+#endif
+#ifndef CONFIG_SPI_EXCHANGE
+static void rspi_sndblock(FAR struct spi_dev_s *dev,
+                            FAR const void *txbuffer,
+                                size_t nwords);
+static void  rspi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
+                                 size_t nwords);
+#endif
+
+/* Initialization */
+
+static void  rspi_bus_initialize(FAR struct rx65n_rspidev_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_RX65N_RSPI0
+static const struct spi_ops_s g_rspi0ops =
+{
+  .lock = rspi_lock,
+  .select = rx65n_rspi0select,
+  .setfrequency = rspi_setfrequency,
+  .setmode = rspi_setmode,
+  .setbits = rspi_setbits,
+#ifdef CONFIG_SPI_HWFEATURES
+  .hwfeatures = rspi_hwfeatures,
+#endif
+  .status = rx65n_rspi0status,
+#ifdef CONFIG_SPI_CMDDATA
+  .cmddata = rx65n_rspi0cmddata,
+#endif
+  .send = rspi_send,
+#ifdef CONFIG_SPI_EXCHANGE
+  .exchange = rspi_exchange,
+#else
+  .sndblock = rspi_sndblock,
+  .recvblock = rspi_recvblock,
+#endif
+
+#ifdef CONFIG_SPI_CALLBACK
+  .registercallback = rx65n_rspi0register,  /* Provided externally */
+#else
+  .registercallback = NULL,
+#endif
+};
+
+static struct rx65n_rspidev_s g_rspi0dev =
+{
+  .rspidev   =
+    {
+      &g_rspi0ops
+    },
+  .rspibase  = RX65N_RSPI0_BASE,
+  .rspiclock = RX65N_PCLK_FREQUENCY,
+#ifndef CONFIG_SPI_POLLWAIT
+  .rspitxirq  = RX65N_SPTI0_IRQ,
+  .rspirxirq  = RX65N_SPRI0_IRQ,
+  .rspierirq  = RX65N_SPEI0_IRQ,
+  .rspiidlirq  = RX65N_SPII0_IRQ,
+  .rspigrpbase = RX65N_GRPAL0_ADDR,
+  .rspierimask = RX65N_GRPAL0_SPEI0_MASK,
+  .rspiidlimask = RX65N_GRPAL0_SPII0_MASK,
+#endif
+};
+#endif
+
+#ifdef CONFIG_RX65N_RSPI1
+static const struct spi_ops_s g_rspi1ops =
+{
+  .lock = rspi_lock,
+  .select = rx65n_rspi1select,
+  .setfrequency = rspi_setfrequency,
+  .setmode = rspi_setmode,
+  .setbits = rspi_setbits,
+#ifdef CONFIG_SPI_HWFEATURES
+  .hwfeatures = rspi_hwfeatures,
+#endif
+  .status = rx65n_rspi1status,
+#ifdef CONFIG_SPI_CMDDATA
+  .cmddata = rx65n_rspi1cmddata,
+#endif
+  .send = rspi_send,
+#ifdef CONFIG_SPI_EXCHANGE
+  .exchange = rspi_exchange,
+#else
+  .sndblock = rspi_sndblock,
+  .recvblock = rspi_recvblock,
+#endif
+#ifdef CONFIG_SPI_TRIGGER
+  .trigger = rspi_trigger,
+#endif
+#ifdef CONFIG_SPI_CALLBACK
+  .registercallback = rx65n_rspi1register,  /* Provided externally */
+#else
+  .registercallback = NULL,
+#endif
+};
+
+static struct rx65n_rspidev_s g_rspi1dev =
+{
+  .rspidev   =
+    {
+      &g_rspi1ops
+    },
+  .rspibase  = RX65N_RSPI1_BASE,
+  .rspiclock = RX65N_PCLK_FREQUENCY,
+#ifndef CONFIG_SPI_POLLWAIT
+  .rspitxirq  = RX65N_SPTI1_IRQ,
+  .rspirxirq  = RX65N_SPRI1_IRQ,
+  .rspierirq  = RX65N_SPEI1_IRQ,
+  .rspiidlirq  = RX65N_SPII1_IRQ,
+  .rspigrpbase = RX65N_GRPAL0_ADDR,
+  .rspierimask = RX65N_GRPAL0_SPEI1_MASK,
+  .rspiidlimask = RX65N_GRPAL0_SPII1_MASK,
+#endif
+};
+#endif
+
+#ifdef CONFIG_RX65N_RSPI2
+static const struct spi_ops_s g_rspi2ops =
+{
+  .lock = rspi_lock,
+  .select = rx65n_rspi2select,
+  .setfrequency = rspi_setfrequency,
+  .setmode = rspi_setmode,
+  .setbits = rspi_setbits,
+#ifdef CONFIG_SPI_HWFEATURES
+  .hwfeatures = rspi_hwfeatures,
+#endif
+  .status = rx65n_rspi2status,
+#ifdef CONFIG_SPI_CMDDATA
+  .cmddata = rx65n_rspi2cmddata,
+#endif
+  .send = rspi_send,
+#ifdef CONFIG_SPI_EXCHANGE
+  .exchange = rspi_exchange,
+#else
+  .sndblock = rspi_sndblock,
+  .recvblock = rspi_recvblock,
+#endif
+#ifdef CONFIG_SPI_TRIGGER
+  .trigger = rspi_trigger,
+#endif
+#ifdef CONFIG_SPI_CALLBACK
+  .registercallback = rx65n_rspi2register,  /* Provided externally */
+#else
+  .registercallback = NULL,
+#endif
+};
+
+static struct rx65n_rspidev_s g_rspi2dev =
+{
+  .rspidev   =
+    {
+      &g_rspi2ops
+    },
+  .rspibase  = RX65N_RSPI2_BASE,
+  .rspiclock = RX65N_PCLK_FREQUENCY,
+#ifndef CONFIG_SPI_POLLWAIT
+  .rspitxirq  = RX65N_SPTI2_IRQ,
+  .rspirxirq  = RX65N_SPRI2_IRQ,
+  .rspierirq  = RX65N_SPEI2_IRQ,
+  .rspiidlirq  = RX65N_SPII2_IRQ,
+  .rspigrpbase = RX65N_GRPAL0_ADDR,
+  .rspierimask = RX65N_GRPAL0_SPEI2_MASK,
+  .rspiidlimask = RX65N_GRPAL0_SPII2_MASK,
+#endif
+};
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name:  rx65n_rspi0/1/2 select and rx65n_rspi0/1/2 status
+ *
+ * Description:
+ * The external functions, rx65n_rspi0/1/2 select, rx65n_rspi0/1/2 status,and
+ * rx65n_rspi0/1/2 cmddata must be provided by board-specific logic. These
+ * are implementations of the select, status, and cmddata methods of the SPI
+ * interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All
+ * other methods (including rx65n_rspibus_initialize()) are provided by
+ * common R656N logic.  To use thiscommon SPI logic on your board:
+ *
+ *   1. Provide logic in stm32_boardinitialize() to configure SPI chip select
+ *      pins.
+ *   2. Provide stm32_spi1/2/...select() and stm32_spi1/2/...status()
+ *      functions in your board-specific logic.  These functions will
+ *      perform chip selection and status operations using GPIOs in the
+ *      way your board is configured.
+ *   3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file,
+ *      then provide stm32_spi1/2/...cmddata() functions in your
+ *      board-specific logic.These functions will perform cmd/data
+ *      selection operations using GPIOs in the way your board is configured.
+ *   4. Add a calls to stm32_spibus_initialize() in your low level
+ *      application initialization logic
+ *   5. The handle returned by stm32_spibus_initialize() may then be used to
+ *      bind the SPI driver to higher level logic (e.g., calling
+ *      mmcsd_spislotinitialize(), for example, will bind the SPI driver to
+ *      the SPI MMC/SD driver).
+ *
+ ****************************************************************************/
+#ifdef CONFIG_RX65N_RSPI0
+void rx65n_rspi0select(FAR struct spi_dev_s *dev, uint32_t devid,
+                       bool selected)
+{
+  spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
+                                                   "de-assert");
+}
+
+uint8_t rx65n_rspi0status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+  return 0;
+}
+
+int rx65n_rspi0cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+  return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_RX65N_RSPI1
+void rx65n_rspi1select(FAR struct spi_dev_s *dev, uint32_t devid,
+                       bool selected)
+{
+  spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
+                                                         "de-assert");
+}
+
+uint8_t rx65n_rspi1status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+  return 0;
+}
+
+int rx65n_rspi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+  return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_RX65N_RSPI2
+void rx65n_rspi2select(FAR struct spi_dev_s *dev, uint32_t devid,
+                       bool selected)
+{
+  spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
+                                                          "de-assert");
+}
+
+uint8_t rx65n_rspi2status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+  return 0;
+}
+
+int rx65n_rspi2cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+  return -ENODEV;
+}
+#endif
+
+/****************************************************************************
+ * Name: rx65n_rspi0/1/2register
+ *
+ * Description:
+ * If the board supports a card detect callback to inform the SPI-based
+ * MMC/SD driver when an SD card is inserted or removed, then
+ * CONFIG_SPI_CALLBACK should be defined and the following function(s)
+ * must be implemented. These functions implements the registercallback
+ * method of the SPI interface (see include/nuttx/spi/spi.h for details)
+ *
+ * Input Parameters:
+ *   dev -      Device-specific state data
+ *   callback - The function to call on the media change
+ *   arg -      A caller provided value to return with the callback
+ *
+ * Returned Value:
+ *   0 on success; negated errno on failure.
+ *
+ ****************************************************************************/
+#ifdef CONFIG_SPI_CALLBACK
+#ifdef CONFIG_RX65N_RSPI0
+int rx65n_rspi0register(FAR struct spi_dev_s *dev,
+                        spi_mediachange_t callback,
+                       FAR void *arg)
+{
+  spiinfo("INFO: Registering rspi0 device\n");
+  return OK;
+}
+#endif
+
+#ifdef CONFIG_RX65N_RSPI1
+int rx65n_rspi1register(FAR struct spi_dev_s *dev,
+                        spi_mediachange_t callback,
+                       FAR void *arg)
+{
+  spiinfo("INFO: Registering rspi1 device\n");
+  return OK;
+}
+#endif
+
+#ifdef CONFIG_RX65N_RSPI2
+int rx65n_rspi2register(FAR struct spi_dev_s *dev,
+                         spi_mediachange_t callback,
+                       FAR void *arg)
+{
+  spiinfo("INFO: Registering rspi2 device\n");
+  return OK;
+}
+#endif
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rspi_getreg32
+ *
+ * Description:
+ *   Read the RSPI register at this offeset
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   offset - Offset to the SPI register from the register base address
+ *
+ * Returned Value:
+ *   Value of the register at this offset
+ *
+ ****************************************************************************/
+
+static inline uint32_t rspi_getreg32(struct rx65n_rspidev_s *priv,
+                                     uint8_t offset)
+{
+  return getreg32(priv->rspibase + offset);
+}
+
+/****************************************************************************
+ * Name: rspi_getreg16
+ *
+ * Description:
+ *   Read the RSPI register at this offeset
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   offset - Offset to the SPI register from the register base address
+ *
+ * Returned Value:
+ *   Value of the register at this offset
+ *
+ ****************************************************************************/
+
+static inline uint16_t rspi_getreg16(struct rx65n_rspidev_s *priv,
+                                     uint8_t offset)
+{
+  return getreg16(priv->rspibase + offset);
+}
+
+/****************************************************************************
+ * Name: rspi_getreg8
+ *
+ * Description:
+ *   Read the RSPI register at this offeset
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   offset - Offset to the SPI register from the register base address
+ *
+ * Returned Value:
+ *   Value of the register at this offset
+ *
+ ****************************************************************************/
+
+static inline uint8_t rspi_getreg8(struct rx65n_rspidev_s *priv,
+                                   uint8_t offset)
+{
+  return getreg8(priv->rspibase + offset);
+}
+
+/****************************************************************************
+ * Name: rspi_putreg32
+ *
+ * Description:
+ *   Write the value to the RSPI register at this offeset
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   offset - Offset to the SPI register from the register base address
+ *   value  - Value to write
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void rspi_putreg32(struct rx65n_rspidev_s *priv,
+                              uint8_t offset, uint32_t value)
+{
+  putreg32(value, priv->rspibase + offset);
+}
+
+/****************************************************************************
+ * Name: rspi_putreg16
+ *
+ * Description:
+ *   Write the value to the RSPI register at this offeset
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   offset - Offset to the SPI register from the register base address
+ *   value  - Value to write
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void rspi_putreg16(struct rx65n_rspidev_s *priv,
+                              uint8_t offset, uint16_t value)
+{
+  putreg16(value, priv->rspibase + offset);
+}
+
+/****************************************************************************
+ * Name: rspi_putreg8
+ *
+ * Description:
+ *   Write the value to the RSPI register at this offeset
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   offset - Offset to the SPI register from the register base address
+ *   value  - Value to write
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void rspi_putreg8(struct rx65n_rspidev_s *priv,
+                              uint8_t offset, uint8_t value)
+{
+  putreg8(value, priv->rspibase + offset);
+}
+
+/****************************************************************************
+ * Name: rspi_txnull, rspi_txuint16, and rspi_txuint8
+ *
+ * Description:
+ *   Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update
+ *   the txbuffer pointer appropriately.  The selected function depends
+ *   on (1) if there is a source txbuffer provided, and (2) if the
+ *   number of bits per word is <=8 or >8.
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void rspi_txnull(struct rx65n_rspidev_s *priv)
+{
+  rspi_putreg32(priv, RX65N_RSPI_SPDR_OFFSET, 0xffff);
+}
+
+static void rspi_txuint32(struct rx65n_rspidev_s *priv)
+{
+  uint32_t *ptr = (uint32_t *)priv->txbuffer;
+  rspi_putreg32(priv, RX65N_RSPI_SPDR_OFFSET, *ptr++);
+  priv->txbuffer = (void *)ptr;
+}
+
+static void rspi_txuint16(struct rx65n_rspidev_s *priv)
+{
+  uint16_t *ptr = (uint16_t *)priv->txbuffer;
+  rspi_putreg16(priv, RX65N_RSPI_SPDR_OFFSET, *ptr++);
+  priv->txbuffer = (void *)ptr;
+}
+
+static void rspi_txuint8(struct rx65n_rspidev_s *priv)
+{
+  uint8_t *ptr = (uint8_t *)priv->txbuffer;
+  rspi_putreg8(priv, RX65N_RSPI_SPDR_OFFSET, *ptr++);
+  priv->txbuffer = (void *)ptr;
+}
+
+/****************************************************************************
+ * Name: rspi_rxnull,rspi_rxuint16, and rspi_rxuint8
+ *
+ * Description:
+ *   Discard input, save a uint8_t, or or save a uint16_t from Tx FIFO in the
+ *   user rxvbuffer and update the rxbuffer pointer appropriately.  The
+ *   selected function dependes on (1) if there is a destination rxbuffer
+ *   provided, and (2) if the number of bits per word is <=8 or >8.
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void rspi_rxnull(struct rx65n_rspidev_s *priv)
+{
+  rspi_getreg32(priv, RX65N_RSPI_SPDR_OFFSET);
+}
+
+static void rspi_rxuint32(struct rx65n_rspidev_s *priv)
+{
+  uint32_t *ptr = (uint32_t *)priv->rxbuffer;
+  *ptr++ = (uint32_t)rspi_getreg32(priv, RX65N_RSPI_SPDR_OFFSET);
+  priv->rxbuffer = (void *)ptr;
+}
+
+static void rspi_rxuint16(struct rx65n_rspidev_s *priv)
+{
+  uint16_t *ptr = (uint16_t *)priv->rxbuffer;
+  *ptr++ = (uint16_t)rspi_getreg16(priv, RX65N_RSPI_SPDR_OFFSET);
+  priv->rxbuffer = (void *)ptr;
+}
+
+static void rspi_rxuint8(struct rx65n_rspidev_s *priv)
+{
+  uint8_t *ptr = (uint8_t *)priv->rxbuffer;
+  *ptr++ = (uint8_t)rspi_getreg8(priv, RX65N_RSPI_SPDR_OFFSET);
+  priv->rxbuffer = (void *)ptr;
+}
+
+/****************************************************************************
+ * Name: rspi_performtx
+ *
+ * Description:
+ *   If the Tx FIFO is empty, then transfer as many words as we can to
+ *   the FIFO.
+ *
+ * Input Parameters:
+ *
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void rspi_performtx(struct rx65n_rspidev_s *priv)
+{
+  uint8_t regval8;
+  int ntxd = 0;  /* Number of words written to Tx FIFO */
+
+  /* Check if the Tx FIFO is empty */
+
+  if ((rspi_getreg8(priv, RX65N_RSPI_SPSR_OFFSET) & RSPI_SPSR_SPTEF) != 0)
+    {
+      /* Check if all of the Tx words have been sent */
+
+      if (priv->ntxwords > 0)
+        {
+          /* No..
+           * Transfer more words until either the TxFIFO is full or
+           * until all of the user provided data has been sent.
+           */
+
+          for (; ntxd < priv->ntxwords && ntxd < priv->bufsize; ntxd++)
+            {
+              priv->txword(priv);
+            }
+
+          /* Update the count of words to be transferred */
+
+          priv->ntxwords -= ntxd;
+
+          /* Add dummy data in FIFO to make it full */
+
+          if (ntxd < priv->bufsize)
+            {
+              while (ntxd != priv->bufsize)
+                {
+                  rspi_txnull(priv);
+                  ntxd++;
+                }
+            }
+        }
+      else
+        {
+          /* Yes.. The transfer is complete,
+           * disable Tx FIFO empty interrupt
+           */
+
+          regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR_OFFSET);
+          regval8 &= ~RSPI_SPCR_SPTIE;
+          rspi_putreg8(priv, RX65N_RSPI_SPCR_OFFSET, regval8);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: rspi_performrx
+ *
+ * Description:
+ *   Transfer as many bytes as possible from the Rx FIFO to the user Rx
+ *   buffer (if one was provided).
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void rspi_performrx(struct rx65n_rspidev_s *priv)
+{
+  /* Loop while data is available in the Rx FIFO (SPRXn) */
+
+  while ((rspi_getreg8(priv, RX65N_RSPI_SPSR_OFFSET) & RSPI_SPSR_SPRF) != 0)
+    {
+      /* Have all of the requested words been transferred from the Rx FIFO? */
+
+      if (priv->nrxwords < priv->nwords)
+        {
+          /* No.. Read more data from Rx FIFO */
+
+          priv->rxword(priv);
+          priv->nrxwords++;
+        }
+      else
+        {
+          rspi_rxnull(priv); /* Reading dummy data send */
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: rspi_startxfr
+ *
+ * Description:
+ *   If data was added to the Tx FIFO, then start the exchange
+ *
+ * Input Parameters:
+ *   priv  - Device-specific state data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void rspi_startxfr(struct rx65n_rspidev_s *priv)
+{
+  uint8_t regval8;
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR_OFFSET);
+  regval8 |= RSPI_SPCR_SPE;
+  rspi_putreg8(priv, RX65N_RSPI_SPCR_OFFSET, regval8);
+}
+
+/****************************************************************************
+ * Name: rspi_transfer
+ *
+ * Description:
+ *   Exchange a block data with the SPI device
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   txbuffer - The buffer of data to send to the device (may be NULL).
+ *   rxbuffer - The buffer to receive data from the device (may be NULL).
+ *   nwords   - The total number of words to be exchanged.  If the interface
+ *              uses <= 8 bits per word, then this is the number of
+ *              uint8_t's; if the interface uses >8 bits per word, then this
+ *              is the number of uint16_t's
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+static int rspi_transfer(struct rx65n_rspidev_s *priv, const void *txbuffer,
+                        void *rxbuffer, unsigned int nwords)
+{
+  uint8_t regval8;
+#ifndef CONFIG_SPI_POLLWAIT
+  irqstate_t flags;
+#endif
+
+  /* Set up to perform the transfer */
+
+  priv->txbuffer = (uint8_t *)txbuffer; /* Source buffer */
+  priv->rxbuffer = (uint8_t *)rxbuffer; /* Destination buffer */
+  priv->ntxwords = nwords;              /* Number of words left to send */
+  priv->nrxwords = 0;                   /* Number of words received */
+  priv->nwords = nwords;                /* Total number of exchanges */
+
+  /* Set up the low-level data transfer function pointers */
+
+  if (priv->nbits > 16)
+    {
+      priv->txword = rspi_txuint32;
+      priv->rxword = rspi_rxuint32;
+    }
+
+  if (priv->nbits > 8)
+    {
+      priv->txword = rspi_txuint16;
+      priv->rxword = rspi_rxuint16;
+    }
+  else
+    {
+      priv->txword = rspi_txuint8;
+      priv->rxword = rspi_rxuint8;
+    }
+
+  if (!txbuffer)
+    {
+      priv->txword = rspi_txnull;
+    }
+
+  if (!rxbuffer)
+    {
+      priv->rxword = rspi_rxnull;
+    }
+
+  /* Copied data to start the sequence (saves one interrupt) */
+
+#ifndef CONFIG_SPI_POLLWAIT
+  flags = enter_critical_section();
+
+  /* Enable interrupt */
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR_OFFSET);
+  regval8 |= (RSPI_SPCR_SPEIE | RSPI_SPCR_SPTIE | RSPI_SPCR_SPRIE);
+  rspi_putreg8(priv, RX65N_RSPI_SPCR_OFFSET, regval8);
+
+  /* Start transmission */
+
+  rspi_performtx(priv);
+  rspi_startxfr(priv);
+
+  /* Enable Idle interrupt */
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR2_OFFSET);
+  regval8 |= (RSPI_SPCR2_SPIIE); /* RSPI Idle Interrupt Enable */
+  rspi_putreg8(priv, RX65N_RSPI_SPCR2_OFFSET, regval8);
+
+  leave_critical_section(flags);
+
+  /* Wait for the transfer to complete.  Since there is no handshake
+   * with SPI, the following should complete even if there are problems
+   * with the transfer, so it should be safe with no timeout.
+   */
+
+  /* Wait to be signaled from the interrupt handler */
+
+  return nxsem_wait_uninterruptible(&priv->waitsem);
+
+#else
+  /* Perform the transfer using polling logic.  This will totally
+   * dominate the CPU until the transfer is complete.  Only recommended
+   * if (1) your SPI is very fast, and (2) if you only use very short
+   * transfers.
+   */
+
+  do
+    {
+      /* Handle outgoing Tx FIFO transfers */
+
+      rspi_performtx(priv);
+
+      /* Handle incoming Rx FIFO transfers */
+
+      rspi_performrx(priv);
+
+      /* Resume the transfer */
+
+      rspi_startxfr(priv);
+
+      /* If there are other threads at this same priority level,
+       * the following may help:
+       */
+
+      sched_yield();
+    }
+  while (priv->nrxwords < priv->nwords);
+
+  return OK;
+#endif
+}
+
+/****************************************************************************
+ * Name: rspi_mapirq
+ *
+ * Description:
+ *   Map an IRQ number into the appropriate SPI device
+ *
+ * Input Parameters:
+ *   irq   - The IRQ number to be mapped
+ *
+ * Returned Value:
+ *   On success, a reference to the private data structgure for this IRQ.
+ *   NULL on failure.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_POLLWAIT
+static inline struct rx65n_rspidev_s *rspi_mapirq(int irq)
+{
+  switch (irq)
+    {
+#ifdef CONFIG_RX65N_RSPI0
+      case RX65N_SPRI0_IRQ:
+      case RX65N_SPTI0_IRQ:
+      case RX65N_SPEI0_IRQ:
+      case RX65N_SPII0_IRQ:
+        return &g_rspi0dev;
+#endif
+#ifdef CONFIG_RX65N_RSPI1
+      case RX65N_SPRI1_IRQ:
+      case RX65N_SPTI1_IRQ:
+      case RX65N_SPEI1_IRQ:
+      case RX65N_SPII1_IRQ:
+        return &g_rspi1dev;
+#endif
+#ifdef CONFIG_RX65N_RSPI2
+      case RX65N_SPRI2_IRQ:
+      case RX65N_SPTI2_IRQ:
+      case RX65N_SPEI2_IRQ:
+      case RX65N_SPII2_IRQ:
+        return &g_rspi2dev;
+#endif
+      default:
+        return NULL;
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_errhandle
+ *
+ * Description:
+ *  RSPI common error handler
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   bus   - channel number
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_POLLWAIT
+static void rspi_errhandle(struct rx65n_rspidev_s *priv, uint8_t bus)
+{
+  uint8_t regval8;
+
+  rspi_event_t event = RSPI_EVT_ERR_UNDEF;
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPSR_OFFSET);
+
+  /* Identify and clear error condition . */
+
+  if (regval8 & RSPI_SPSR_OVRF)
+    {
+      /* Overrun error */
+
+      if (RSPI_EVT_ERR_UNDEF == event)
+        {
+          event = RSPI_EVT_ERR_READ_OVF;
+        }
+
+      /* Clear error source: OVRF flag. */
+
+      regval8 &= (~RSPI_SPSR_OVRF);
+      rspi_putreg8(priv, RX65N_RSPI_SPSR_OFFSET, regval8);
+    }
+
+  if (regval8 & RSPI_SPSR_MODF)
+    {
+      if (regval8 & RSPI_SPSR_UDRF)
+        {
+          if (RSPI_EVT_ERR_UNDEF == event)
+            {
+                event = RSPI_EVT_ERR_UNDER_RUN;
+            }
+
+          /* Clear error source : MODF flag and UDRF */
+
+          regval8 &= RSPI_SPSR_MODF_UDRF_MASK;
+          rspi_putreg8(priv, RX65N_RSPI_SPSR_OFFSET, regval8);
+        }
+      else
+        {
+          if (RSPI_EVT_ERR_UNDEF == event)
+            {
+                event = RSPI_EVT_ERR_MODE_FAULT;
+            }
+
+          /* Clear error source : MODF flag */
+
+          regval8 &= (~RSPI_SPSR_MODF);
+          rspi_putreg8(priv, RX65N_RSPI_SPSR_OFFSET, regval8);
+        }
+    }
+
+  if (regval8 & RSPI_SPSR_PERF)
+    {
+      if (RSPI_EVT_ERR_UNDEF == event)
+        {
+           event = RSPI_EVT_ERR_PARITY;
+        }
+
+      /* Clear error source: PERF flag */
+
+      regval8 &= (~RSPI_SPSR_PERF);
+      rspi_putreg8(priv, RX65N_RSPI_SPSR_OFFSET, regval8);
+    }
+
+  /* Disable the RSPI operation . */
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR_OFFSET);
+  regval8 &= (~(RSPI_SPCR_SPTIE | RSPI_SPCR_SPRIE | RSPI_SPCR_SPE));
+  rspi_putreg8(priv, RX65N_RSPI_SPCR_OFFSET, regval8);
+
+  /* Yes, wake up the waiting thread . */
+
+  nxsem_post(&priv->waitsem);
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_idlinterrupt
+ *
+ * Description:
+ *  RSPI IDLE interrupt handler invoke on transmission/reception completion
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_POLLWAIT
+static int rspi_idlinterrupt(int irq, void *context, FAR void *arg)
+{
+  uint8_t regval8;
+
+  struct rx65n_rspidev_s *priv = rspi_mapirq(irq);
+
+  DEBUGASSERT(priv != NULL);
+
+  /* Disable Idle interrupt in SPCR2 */
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR2_OFFSET);
+  regval8 &= ~(RSPI_SPCR2_SPIIE); /* RSPI Idle Interrupt Enable */
+  rspi_putreg8(priv, RX65N_RSPI_SPCR2_OFFSET, regval8);
+
+  /* Disable ransmit/receive interrupt */
+
+  regval8 = rspi_getreg8(priv, RX65N_RSPI_SPCR_OFFSET);
+  regval8 &= ~(RSPI_SPCR_SPRIE | RSPI_SPCR_SPTIE);
+  rspi_putreg8(priv, RX65N_RSPI_SPCR_OFFSET, regval8);
+
+  /* Yes, wake up the waiting thread */
+
+  nxsem_post(&priv->waitsem);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_erinterrupt
+ *
+ * Description:
+ *   RSPI common error interrupt handler
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_POLLWAIT
+static int rspi_erinterrupt(int irq, void *context, FAR void *arg)
+{
+  struct rx65n_rspidev_s *priv = rspi_mapirq(irq);
+
+  DEBUGASSERT(priv != NULL);
+
+#ifdef CONFIG_RX65N_RSPI0
+  rspi_errhandle(priv, RX65N_RSPI_CHANNEL0);
+#endif
+
+#ifdef CONFIG_RX65N_RSPI1
+  rspi_errhandle(priv, RX65N_RSPI_CHANNEL1);
+#endif
+
+#ifdef CONFIG_RX65N_RSPI2
+  rspi_errhandle(priv, RX65N_RSPI_CHANNEL2);
+#endif
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_rxinterrupt
+ *
+ * Description:
+ *   Receive buffer full interrupt handler to process a block data from SPI
+ *   device
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   rxbuffer - The buffer to receive data from the device (may be NULL).
+ *   nwords   - The total number of words to be exchanged.  If the interface
+ *              uses <= 8 bits per word, then this is the number of
+ *              uint8_t's; if the interface uses >8 bits per word, then this
+ *              is the number of uint16_t's
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_POLLWAIT
+static int rspi_rxinterrupt(int irq, void *context, FAR void *arg)
+{
+  struct rx65n_rspidev_s *priv = rspi_mapirq(irq);
+
+  DEBUGASSERT(priv != NULL);
+
+  /* Handle incoming Rx FIFO transfers */
+
+  rspi_performrx(priv);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_txinterrupt
+ *
+ * Description:
+ *   Transmit buffer empty interrupt handler to process a block data for SPI
+ *   device
+ *
+ * Input Parameters:
+ *   priv   - Device-specific state data
+ *   txbuffer - The buffer of data to send to the device (may be NULL).
+ *   nwords   - The total number of words to be exchanged.  If the interface
+ *              uses <= 8 bits per word, then this is the number of
+ *              uint8_t's; if the interface uses >8 bits per word, then this
+ *              is the number of uint16_t's
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_POLLWAIT
+static int rspi_txinterrupt(int irq, void *context, FAR void *arg)
+{
+  struct rx65n_rspidev_s *priv = rspi_mapirq(irq);
+
+  DEBUGASSERT(priv != NULL);
+
+  /* Handle outgoing Tx FIFO transfers */
+
+  rspi_performtx(priv);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_lock
+ *
+ * Description:
+ *   On SPI buses where there are multiple devices, it will be necessary to
+ *   lock SPI 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 SPI bus, the caller should then also call the setfrequency,
+ *   setbits, and setmode methods to make sure that the SPI is properly
+ *   configured for the device.  If the SPI bus is being shared, then it
+ *   may have been left in an incompatible state.
+ *
+ * Input Parameters:
+ *   dev  - Device-specific state data
+ *   lock - true: Lock spi bus, false: unlock SPI bus
+ *
+ * Returned Value:
+ *   0: success, <0:Negated error number on failure
+ *
+ ****************************************************************************/
+
+static int rspi_lock(FAR struct spi_dev_s *dev, bool lock)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+  int ret;
+
+  if (lock)
+    {
+      ret = nxsem_wait_uninterruptible(&priv->exclsem);
+    }
+  else
+    {
+      ret = nxsem_post(&priv->exclsem);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: rspi_setfrequency
+ *
+ * Description:
+ *   Set the RSPI frequency.
+ *
+ * Input Parameters:
+ *   dev -       Device-specific state data
+ *   frequency - The SPI frequency requested
+ *
+ * Returned Value:
+ *   Returns the actual frequency selected
+ *
+ ****************************************************************************/
+
+static uint32_t rspi_setfrequency(FAR struct spi_dev_s *dev,
+                                 uint32_t frequency)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+  uint32_t actual;
+
+  DEBUGASSERT(priv);
+  actual = priv->actual;
+
+  if (frequency != priv->frequency)
+    {
+      /* Below formula used to calculate bit rate
+       * Bit rate f(PCLK)/(2 � (n + 1) � 2^N) .
+       * n denotes SPBR setting (0,1,2..255) .
+       * N denotes a BRDV[1:0] bit setting (0, 1, 2, 3) .
+       */
+
+      uint16_t regval16;
+      uint32_t brdv;
+      uint8_t spbr;
+
+      /* N=0 as per fit code */
+
+      brdv = RSPI_BRDV_DEFAULT;
+
+      DEBUGASSERT(brdv < 4);
+
+      if (frequency >= priv->rspiclock / FREQ_DIVISOR_2)
+        {
+          actual   = priv->rspiclock / FREQ_DIVISOR_2;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_4)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_4;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_6)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_6;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_8)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_8;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_10)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_10;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_12)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_12;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_24)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_24;
+        }
+      else if (frequency >= priv->rspiclock / FREQ_DIVISOR_48)
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_48;
+        }
+      else /* (frequency >= priv->rspiclock / FREQ_DIVISOR_96) */
+        {
+          actual   = priv->rspiclock /  FREQ_DIVISOR_96;
+        }
+
+      /* Calculate n and set the n in SPBR */
+
+      spbr =  (priv->rspiclock / (2 * actual * ((1 << brdv)))) - 1;
+      rspi_putreg8(priv, RX65N_RSPI_SPBR_OFFSET, spbr);
+
+      /* Set the N as BRDV[1:0] in SPCMD0 b2 and b3 */
+
+      regval16 = rspi_getreg16(priv, RX65N_RSPI_SPCMD0_OFFSET);
+      regval16 &= ~(RSPI_SPCMD_BRDV_MASK);
+      regval16 |= (brdv << 2);
+      rspi_putreg16(priv, RX65N_RSPI_SPCMD0_OFFSET, regval16);
+
+      /* Save the frequency and actual frequency in RSPI device structure */
+
+      priv->frequency = frequency;
+      priv->actual    = actual;
+    }
+
+  return actual;
+}
+
+/****************************************************************************
+ * Name: rspi_setmode
+ *
+ * Description:
+ *   Set the SPI mode. Optional.  See enum spi_mode_e for mode definitions
+ *
+ * Input Parameters:
+ *   dev -  Device-specific state data
+ *   mode - The SPI mode requested
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+static void rspi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+
+  uint16_t regval16;
+
+  if (priv && mode != priv->mode)
+    {
+      uint32_t modebits;
+
+      /* Select the CTL register bits based on the selected mode */
+
+      switch (mode)
+        {
+          case SPIDEV_MODE0: /* CPOL=0 CHPHA=0 */
+            modebits = 0;
+            break;
+
+          case SPIDEV_MODE1: /* CPOL=0 CHPHA=1 */
+            modebits = RSPI_SPCMD_PHA;
+            break;
+
+          case SPIDEV_MODE2: /* CPOL=1 CHPHA=0 */
+            modebits = RSPI_SPCMD_POL;
+            break;
+
+          case SPIDEV_MODE3: /* CPOL=1 CHPHA=1 */
+            modebits = RSPI_SPCMD_PHA | RSPI_SPCMD_POL;
+            break;
+
+          default:
+            spiwarn("Warning: Unsupported RSPI mode: %d\n", mode);
+            return;
+        }
+
+      /* Then set the selected mode */
+
+      regval16 = rspi_getreg16(priv, RX65N_RSPI_SPCMD0_OFFSET);
+      regval16 &= ~(RSPI_SPCMD_PHA | RSPI_SPCMD_POL);
+      regval16 |= modebits;
+      rspi_putreg16(priv, RX65N_RSPI_SPCMD0_OFFSET, regval16);
+
+      /* Save the mode so that subsequent re-configurations will be faster */
+
+      priv->mode = mode;
+    }
+}
+
+/****************************************************************************
+ * Name: rspi_setbits
+ *
+ * Description:
+ *   Set the number of bits per word.
+ *
+ * Input Parameters:
+ *   dev -  Device-specific state data
+ *   nbits - The number of bits requests
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+static void rspi_setbits(FAR struct spi_dev_s *dev, int nbits)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+
+  uint8_t regval8;
+  uint16_t regval16;
+
+  if (priv && nbits != priv->nbits && nbits > 0 && nbits <= 16)
+    {
+      if (nbits >= 4 && nbits <= 8)
+        {
+          regval8 = rspi_getreg8(priv, RX65N_RSPI_SPDCR_OFFSET);
+          regval8 |= RSPI_SPDCR_SPBYT;
+          rspi_putreg8(priv, RX65N_RSPI_SPDCR_OFFSET, regval8);
+        }
+      else if (nbits > 8 && nbits <= 16)
+        {
+          regval8 = rspi_getreg8(priv, RX65N_RSPI_SPDCR_OFFSET);
+          regval8 &= ~(RSPI_SPDCR_SPLW | RSPI_SPDCR_SPBYT);
+          rspi_putreg8(priv, RX65N_RSPI_SPDCR_OFFSET, regval8);
+        }
+      else
+        {
+          spierr("ERROR: RSPI not supporting: %d bit word\n", nbits);
+        }
+
+      /* Configure command data register for this transfer */
+
+      regval16 = rspi_getreg16(priv, RX65N_RSPI_SPCMD0_OFFSET);
+      regval16 |= (RSPI_SPCMD_SPB_MASK & ((nbits - 1) << 8));
+      rspi_putreg16(priv, RX65N_RSPI_SPCMD0_OFFSET, regval16);
+
+      priv->nbits   = nbits;
+    }
+  else
+    {
+      spiwarn("Warning: Unsupported RSPI Word width: %d\n", nbits);
+    }
+}
+
+/****************************************************************************
+ * Name: rspi_send
+ *
+ * Description:
+ *   Exchange one word on RSPI
+ *
+ * Input Parameters:
+ *   dev - Device-specific state data
+ *   wd  - The word to send.  the size of the data is determined by the
+ *         number of bits selected for the SPI interface.
+ *
+ * Returned Value:
+ *   response
+ *
+ ****************************************************************************/
+
+static uint32_t rspi_send(FAR struct spi_dev_s *dev, uint32_t wd)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+  uint32_t response = 0;
+
+  rspi_transfer(priv, &wd, &response, 1);
+  return response;
+}
+
+/****************************************************************************
+ * Name: rspi_exchange
+ *
+ * Description:
+ *   Exahange a block of data from SPI. Required.
+ *
+ * Input Parameters:
+ *   dev      - Device-specific state data
+ *   buffer   - A pointer to the buffer of data to be sent
+ *   rxbuffer - A pointer to the buffer in which to receive data
+ *   nwords   - the length of data that to be exchanged in units of words.
+ *              The wordsize is determined by the number of bits-per-word
+ *              selected for the SPI interface.  If nbits <= 8, the data is
+ *              packed into uint8_t's; if nbits >8, the data is packed into
+ *              uint16_t's
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SPI_EXCHANGE
+static void rspi_exchange(FAR struct spi_dev_s *dev,
+                            FAR const void *txbuffer,
+                         FAR void *rxbuffer, size_t nwords)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+  rspi_transfer(priv, txbuffer, rxbuffer, nwords);
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_sndblock
+ *
+ * Description:
+ *   Send a block of data on SPI
+ *
+ * Input Parameters:
+ *   dev -    Device-specific state data
+ *   buffer - A pointer to the buffer of data to be sent
+ *   nwords - the length of data to send from the buffer in number of words.
+ *            The wordsize is determined by the number of bits-per-word
+ *            selected for the SPI interface.  If nbits <= 8, the data is
+ *            packed into uint8_t's; if nbits >8, the data is packed into
+ *            uint16_t's
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_EXCHANGE
+static void rspi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
+                         size_t nwords)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+  rspi_transfer(priv, buffer, NULL, nwords);
+}
+#endif
+
+/****************************************************************************
+ * Name: rspi_recvblock
+ *
+ * Description:
+ *   Revice a block of data from SPI
+ *
+ * Input Parameters:
+ *   dev -    Device-specific state data
+ *   buffer - A pointer to the buffer in which to receive data
+ *   nwords - the length of data that can be received in the buffer in number
+ *            of words.  The wordsize is determined by the number of
+ *            bits-per-word selected for the SPI interface.  If nbits <= 8,
+ *            the data is packed into uint8_t's; if nbits >8, the data is
+ *            packed into uint16_t's
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_SPI_EXCHANGE
+static void rspi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
+                          size_t nwords)
+{
+  struct rx65n_rspidev_s *priv = (struct rx65n_rspidev_s *)dev;
+  rspi_transfer(priv, NULL, buffer, nwords);
+}
+#endif
+
+/****************************************************************************
+ * Function Name: rspi_interrupt_init
+ * Description  : Configure ICU for RSPI interrupt
+ * Arguments    : none
+ * Return Value : none
+ ****************************************************************************/
+
+void rspi_interrupt_init(FAR struct rx65n_rspidev_s *priv, uint8_t bus)
+{
+  /* Enable error interrupt source bit */
+
+  IEN(ICU, GROUPAL0) = 0;  /* Disable Group AL0 interrupts */
+  IR(ICU, GROUPAL0)  = 0;  /* Clear interrupt flag */
+  IPR(ICU, GROUPAL0) = RX65N_RSPI_INTRRUPT_PRIO;
+  IEN(ICU, GROUPAL0) = 1;  /* Enable Group AL0 interrupt */
+
+#ifdef CONFIG_RX65N_RSPI0
+  if (bus == RX65N_RSPI_CHANNEL0)
+    {
+      /* Configure Transmit empty buffer interrupt source bit */
+
+      IEN(RSPI0, SPTI0) = 0;  /* Disable SPTI0 interrupts */
+      IR(RSPI0, SPTI0)  = 0;  /* Clear interrupt flag */
+      IPR(RSPI0, SPTI0) = RX65N_RSPI_INTRRUPT_PRIO;
+      IEN(RSPI0, SPTI0) = 1;  /* Enable SPTI0 interrupt */
+      ICU.IER[04].BIT.IEN7 = 1;
+
+      /* Configure Receive buffer full interrupt source bit */
+
+      IEN(RSPI0, SPRI0) = 0; /* Disable SPRI0 interrupts */
+      IR(RSPI0, SPRI0) = 0;  /* Clear interrupt flag */
+      IPR(RSPI0, SPRI0) = RX65N_RSPI_INTRRUPT_PRIO;
+      IEN(RSPI0, SPRI0) = 1; /* Enable SPRI0 interrupt */
+      ICU.IER[04].BIT.IEN6 = 1;
+
+      /* Enable error interrupt source bit */
+
+      ICU.GENAL0.BIT.EN17 = 1;
+
+      /* Enable Idle interrupt source bit */
+
+      ICU.GENAL0.BIT.EN16 = 1;
+    }
+#endif
+
+#ifdef CONFIG_RX65N_RSPI1
+  if (bus == RX65N_RSPI_CHANNEL1)
+    {
+      /* Configure Transmit empty buffer interrupt */
+
+      IEN(RSPI1, SPTI1) = 0;  /* Disable SPTI1 interrupts */
+      IR(RSPI1, SPTI1)  = 0;  /* Clear interrupt flag */
+      IPR(RSPI1, SPTI1) = RX65N_RSPI_INTRRUPT_PRIO;
+      IEN(RSPI1, SPTI1) = 1;  /* Enable SPTI1 interrupt */
+      ICU.IER[05].BIT.IEN1 = 1;
+
+      /* Configure Receive buffer full interrupt */
+
+      IEN(RSPI1, SPRI1) = 0;  /* Disable SPRI1 interrupts */
+      IR(RSPI1,  SPRI1) = 0;  /* Clear interrupt flag */
+      IPR(RSPI1, SPRI1) = RX65N_RSPI_INTRRUPT_PRIO;
+      IEN(RSPI1, SPRI1) = 1;  /* Enable SPRI1 interrupt */
+      ICU.IER[05].BIT.IEN0 = 1;

Review comment:
       Thank you for the comments.
   
   The comments have been addressed in 285d16d.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org