You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/06/29 21:32:08 UTC

[incubator-nuttx] branch master updated (31cddc922c -> 43685aefc8)

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

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


    from 31cddc922c xtensa/esp32s2: Sync GPIO driver implementation with ESP32-S3
     new 0657621848 xtensa/esp32s2: Add driver for I2C peripheral in Master mode
     new 01b3ddd22f esp32s2-saola-1: Add support for I2C chardev driver
     new 43685aefc8 esp32s2-saola-1: Add support for BMP180 pressure sensor

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/xtensa/src/esp32s2/Kconfig                    |   58 +
 arch/xtensa/src/esp32s2/Make.defs                  |    4 +
 .../src/esp32s2/esp32s2_i2c.c}                     |  872 +++++----
 .../{esp32/esp32_i2c.h => esp32s2/esp32s2_i2c.h}   |   41 +-
 arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.h     | 1992 ++++++++++++++++++++
 arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h     |    2 +-
 arch/xtensa/src/esp32s2/hardware/esp32s2_system.h  |   91 +-
 .../esp32s2-saola-1/configs/{nsh => i2c}/defconfig |   22 +-
 .../xtensa/esp32s2/esp32s2-saola-1/src/Make.defs   |    8 +
 .../esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h  |   35 +
 .../esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.c}  |   42 +-
 .../esp32s2-saola-1/src/esp32s2_board_i2c.c}       |   51 +-
 .../esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c  |   25 +
 13 files changed, 2714 insertions(+), 529 deletions(-)
 copy arch/{risc-v/src/esp32c3/esp32c3_i2c.c => xtensa/src/esp32s2/esp32s2_i2c.c} (64%)
 copy arch/xtensa/src/{esp32/esp32_i2c.h => esp32s2/esp32s2_i2c.h} (78%)
 create mode 100644 arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.h
 copy boards/xtensa/esp32s2/esp32s2-saola-1/configs/{nsh => i2c}/defconfig (73%)
 copy boards/{arm/stm32/common/src/stm32_ms5611.c => xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.c} (72%)
 copy boards/{risc-v/esp32c3/esp32c3-devkit/src/esp32c3_i2c.c => xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_board_i2c.c} (76%)


[incubator-nuttx] 01/03: xtensa/esp32s2: Add driver for I2C peripheral in Master mode

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0657621848648f20149c550da45cc32e3321a499
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Wed Jun 15 15:35:54 2022 -0300

    xtensa/esp32s2: Add driver for I2C peripheral in Master mode
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 arch/xtensa/src/esp32s2/Kconfig                   |   58 +
 arch/xtensa/src/esp32s2/Make.defs                 |    4 +
 arch/xtensa/src/esp32s2/esp32s2_i2c.c             | 1702 ++++++++++++++++++
 arch/xtensa/src/esp32s2/esp32s2_i2c.h             |   91 +
 arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.h    | 1992 +++++++++++++++++++++
 arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h    |    2 +-
 arch/xtensa/src/esp32s2/hardware/esp32s2_system.h |   91 +-
 7 files changed, 3893 insertions(+), 47 deletions(-)

diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig
index 3f1de8c51a..01c68a72b4 100644
--- a/arch/xtensa/src/esp32s2/Kconfig
+++ b/arch/xtensa/src/esp32s2/Kconfig
@@ -15,6 +15,7 @@ config ARCH_CHIP_ESP32S2WROVER
 	bool "ESP32-S2-WROVER"
 	select ESP32S2_FLASH_4M
 	select ESP32S2_PSRAM_2M
+	select ARCH_HAVE_I2CRESET
 	---help---
 		Generic module with an embedded ESP32-S2
 
@@ -232,6 +233,10 @@ config ESP32S2_UART
 	bool
 	default n
 
+config ESP32S2_I2C
+	bool
+	default n
+
 config ESP32S2_TIMER
 	bool
 	default n
@@ -320,6 +325,18 @@ config ESP32S2_UART1
 	select UART1_SERIALDRIVER
 	select ARCH_HAVE_SERIAL_TERMIOS
 
+config ESP32S2_I2C0
+	bool "I2C 0"
+	default n
+	select ESP32S2_I2C
+	select I2C
+
+config ESP32S2_I2C1
+	bool "I2C 1"
+	default n
+	select ESP32S2_I2C
+	select I2C
+
 config ESP32S2_RT_TIMER
 	bool "Real-time Timer"
 	select ESP32S2_TIMER
@@ -401,6 +418,47 @@ endif # ESP32S2_UART1
 
 endmenu # UART Configuration
 
+menu "I2C Configuration"
+	depends on ESP32S2_I2C
+
+if ESP32S2_I2C0
+
+config ESP32S2_I2C0_SCLPIN
+	int "I2C0 SCL Pin"
+	default 19
+	range 0 46
+
+config ESP32S2_I2C0_SDAPIN
+	int "I2C0 SDA Pin"
+	default 18
+	range 0 46
+
+endif # ESP32S2_I2C0
+
+if ESP32S2_I2C1
+
+config ESP32S2_I2C1_SCLPIN
+	int "I2C1 SCL Pin"
+	default 6
+	range 0 46
+
+config ESP32S2_I2C1_SDAPIN
+	int "I2C1 SDA Pin"
+	default 7
+	range 0 46
+
+endif # ESP32S2_I2C1
+
+config ESP32S2_I2CTIMEOSEC
+	int "Timeout seconds"
+	default 0
+
+config ESP32S2_I2CTIMEOMS
+	int "Timeout milliseconds"
+	default 500
+
+endmenu # I2C Configuration
+
 menu "SPI Flash Configuration"
 	depends on ESP32S2_SPIFLASH
 
diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs
index c94c293526..46d6f1c847 100644
--- a/arch/xtensa/src/esp32s2/Make.defs
+++ b/arch/xtensa/src/esp32s2/Make.defs
@@ -84,6 +84,10 @@ ifeq ($(CONFIG_ESP32S2_RNG),y)
 CHIP_CSRCS += esp32s2_rng.c
 endif
 
+ifeq ($(CONFIG_ESP32S2_I2C),y)
+CHIP_CSRCS += esp32s2_i2c.c
+endif
+
 ifeq ($(CONFIG_ESP32S2_TIMER),y)
 CHIP_CSRCS += esp32s2_tim.c
 ifeq ($(CONFIG_TIMER),y)
diff --git a/arch/xtensa/src/esp32s2/esp32s2_i2c.c b/arch/xtensa/src/esp32s2/esp32s2_i2c.c
new file mode 100644
index 0000000000..6fde13a276
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/esp32s2_i2c.c
@@ -0,0 +1,1702 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/esp32s2_i2c.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>
+
+#ifdef CONFIG_ESP32S2_I2C
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include <nuttx/irq.h>
+#include <nuttx/i2c/i2c_master.h>
+#include <nuttx/semaphore.h>
+
+#include <arch/board/board.h>
+
+#include "esp32s2_gpio.h"
+#include "esp32s2_i2c.h"
+#include "esp32s2_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32s2_gpio_sigmap.h"
+#include "hardware/esp32s2_i2c.h"
+#include "hardware/esp32s2_soc.h"
+#include "hardware/esp32s2_system.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Command format */
+
+#define I2C_BASE_CMD(_cmd, _check_ack) (((_cmd) << 11) | \
+                                        ((_check_ack) << 8))
+
+#define I2C_SEND_CMD(_cmd, _check_ack, _bytes) (((_cmd) << 11) | \
+                                                ((_check_ack) << 8) | \
+                                                (_bytes))
+
+#define I2C_RECV_CMD(_cmd, _ack_val, _bytes) (((_cmd) << 11) | \
+                                              ((_ack_val) << 10) | \
+                                              (_bytes))
+
+/* Helper */
+
+#ifdef CONFIG_I2C_POLLED
+#define TIMESPEC_TO_US(sec, nano)  ((sec) * USEC_PER_SEC + (nano) / NSEC_PER_USEC)
+#endif
+
+#define ESP32S2_I2CTIMEOTICKS \
+    (SEC2TICK(CONFIG_ESP32S2_I2CTIMEOSEC) + MSEC2TICK(CONFIG_ESP32S2_I2CTIMEOMS))
+
+/* Default option */
+
+#define I2C_FIFO_SIZE (32)
+
+#define I2C_FILTER_CYC_NUM_DEF (7)
+
+#define I2C_CLK_FREQ_DEF (100 * 1000)
+
+#define I2C_INT_ERR_MASK (I2C_NACK_INT_ENA | \
+                          I2C_TIME_OUT_INT_ENA | \
+                          I2C_ARBITRATION_LOST_INT_ENA)
+
+#define I2C_SCL_CYC_NUM_DEF 9
+
+/* Access I2C FIFO Data registers via Peripheral Bus 2 (PeriBus2).
+ * Refer to ESP32-S2 Technical Reference Manual, section 3.3.5 for further
+ * details.
+ */
+
+#define FIFO_DATA_REG(i) (0x60013000 + (i) * 0x14000 + 0x001c)
+
+/* I2C event trace logic.
+ * NOTE: trace uses the internal, non-standard, low-level debug interface
+ * syslog() but does not require that any other debug is enabled.
+ */
+
+#ifndef CONFIG_I2C_TRACE
+#  define i2c_tracereset(p)
+#  define i2c_tracenew(p,s)
+#  define i2c_traceevent(p,e,a,s)
+#  define i2c_tracedump(p)
+#endif
+
+#ifndef CONFIG_I2C_NTRACE
+#  define CONFIG_I2C_NTRACE 32
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* I2C state */
+
+enum esp32s2_i2cstate_e
+{
+  I2CSTATE_IDLE = 0,
+  I2CSTATE_PROC,
+  I2CSTATE_STOP,
+#ifndef CONFIG_I2C_POLLED
+  I2CSTATE_FINISH,
+#endif
+  I2CSTATE_ERROR
+};
+
+/* I2C hardware command */
+
+enum i2c_opmode_e
+{
+  I2C_CMD_RESTART = 0,        /* I2C restart command */
+  I2C_CMD_WRITE,              /* I2C write command */
+  I2C_CMD_READ,               /* I2C read command */
+  I2C_CMD_STOP,               /* I2C stop command */
+  I2C_CMD_END                 /* I2C end command */
+};
+
+#ifdef CONFIG_I2C_TRACE
+
+/* Trace events */
+
+enum esp32s2_trace_e
+{
+  I2CEVENT_NONE = 0,      /* No events have occurred with this status */
+  I2CEVENT_SENDADDR,      /* Start/Master bit set and address sent, param = addr */
+  I2CEVENT_SENDBYTE,      /* Send byte, param = bytes */
+  I2CEVENT_RCVMODEEN,     /* Receive mode enabled, param = 0 */
+  I2CEVENT_RCVBYTE,       /* Read more dta, param = bytes */
+  I2CEVENT_STOP,          /* Last byte sten, send stop, param = length */
+  I2CEVENT_ERROR          /* Error occurred, param = 0 */
+};
+
+/* Trace data */
+
+struct esp32s2_trace_s
+{
+  uint32_t status;            /* I2C 32-bit SR status */
+  uint32_t count;             /* Interrupt count when status change */
+  enum esp32s2_trace_e event; /* Last event that occurred with this status */
+  uint32_t parm;              /* Parameter associated with the event */
+  clock_t time;               /* First of event or first status */
+};
+
+#endif /* CONFIG_I2C_TRACE */
+
+/* I2C Device hardware configuration */
+
+struct esp32s2_i2c_config_s
+{
+  uint32_t clk_freq;          /* Clock frequency */
+
+  uint8_t scl_pin;            /* GPIO configuration for SCL as SCL */
+  uint8_t sda_pin;            /* GPIO configuration for SDA as SDA */
+
+#ifndef CONFIG_I2C_POLLED
+  uint8_t periph;             /* Peripheral ID */
+  uint8_t irq;                /* Interrupt ID */
+#endif
+
+  uint32_t clk_bit;           /* Clock enable bit */
+  uint32_t rst_bit;           /* I2C reset bit */
+
+  uint32_t scl_insig;         /* I2C SCL input signal index */
+  uint32_t scl_outsig;        /* I2C SCL output signal index */
+
+  uint32_t sda_insig;         /* I2C SDA input signal index */
+  uint32_t sda_outsig;        /* I2C SDA output signal index */
+};
+
+/* I2C Device Private Data */
+
+struct esp32s2_i2c_priv_s
+{
+  const struct i2c_ops_s *ops; /* Standard I2C operations */
+
+  uint32_t id;                 /* I2C instance */
+
+  /* Port configuration */
+
+  const struct esp32s2_i2c_config_s *config;
+  int refs;                    /* Reference count */
+  sem_t sem_excl;              /* Mutual exclusion semaphore */
+
+#ifndef CONFIG_I2C_POLLED
+  sem_t sem_isr;               /* Interrupt wait semaphore */
+  int cpuint;                  /* CPU interrupt assigned to this I2C */
+#endif
+
+  /* I2C work state (see enum esp32s2_i2cstate_e) */
+
+  volatile enum esp32s2_i2cstate_e i2cstate;
+
+  struct i2c_msg_s *msgv;      /* Message list */
+
+  uint8_t msgid;               /* Current message ID */
+  ssize_t bytes;               /* Processed data bytes */
+
+  uint32_t error;              /* I2C transform error */
+
+  bool ready_read;             /* If I2C has read data */
+
+  uint32_t clk_freq;           /* Current I2C Clock frequency */
+
+#ifdef CONFIG_I2C_TRACE
+  /* I2C trace support */
+
+  int tndx;                    /* Trace array index */
+  clock_t start_time;          /* Time when the trace was started */
+
+  /* The actual trace data */
+
+  struct esp32s2_trace_s trace[CONFIG_I2C_NTRACE];
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void i2c_init_clock(struct esp32s2_i2c_priv_s *priv,
+                           uint32_t clock);
+static void i2c_init(struct esp32s2_i2c_priv_s *priv);
+static void i2c_deinit(struct esp32s2_i2c_priv_s *priv);
+static int i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgs,
+                        int count);
+static inline void i2c_process(struct esp32s2_i2c_priv_s *priv,
+                               uint32_t status);
+static void i2c_sem_init(struct esp32s2_i2c_priv_s *priv);
+static void i2c_sem_destroy(struct esp32s2_i2c_priv_s *priv);
+static void i2c_sem_post(struct esp32s2_i2c_priv_s *priv);
+static int i2c_sem_wait(struct esp32s2_i2c_priv_s *priv);
+#ifndef CONFIG_I2C_POLLED
+static int i2c_sem_waitdone(struct esp32s2_i2c_priv_s *priv);
+#endif
+#ifdef CONFIG_I2C_POLLED
+static int i2c_polling_waitdone(struct esp32s2_i2c_priv_s *priv);
+#endif
+static void i2c_clear_bus(struct esp32s2_i2c_priv_s *priv);
+static void i2c_reset_fsmc(struct esp32s2_i2c_priv_s *priv);
+#ifdef CONFIG_I2C_RESET
+static int i2c_reset(struct i2c_master_s *dev);
+#endif
+
+#ifdef CONFIG_I2C_TRACE
+static void i2c_tracereset(struct esp32s2_i2c_priv_s *priv);
+static void i2c_tracenew(struct esp32s2_i2c_priv_s *priv, uint32_t status);
+static void i2c_traceevent(struct esp32s2_i2c_priv_s *priv,
+                           enum esp32s2_trace_e event,
+                           uint32_t parm,
+                           uint32_t status);
+static void i2c_tracedump(struct esp32s2_i2c_priv_s *priv);
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* I2C interface */
+
+static const struct i2c_ops_s g_esp32s2_i2c_ops =
+{
+  .transfer = i2c_transfer
+#ifdef CONFIG_I2C_RESET
+  , .reset  = i2c_reset
+#endif
+};
+
+/* I2C device structures */
+
+#ifdef CONFIG_ESP32S2_I2C0
+static const struct esp32s2_i2c_config_s g_esp32s2_i2c0_config =
+{
+  .clk_freq   = I2C_CLK_FREQ_DEF,
+  .scl_pin    = CONFIG_ESP32S2_I2C0_SCLPIN,
+  .sda_pin    = CONFIG_ESP32S2_I2C0_SDAPIN,
+#ifndef CONFIG_I2C_POLLED
+  .periph     = ESP32S2_PERIPH_I2C_EXT0,
+  .irq        = ESP32S2_IRQ_I2C_EXT0,
+#endif
+  .clk_bit    = SYSTEM_I2C_EXT0_CLK_EN,
+  .rst_bit    = SYSTEM_I2C_EXT0_RST,
+  .scl_insig  = I2CEXT0_SCL_IN_IDX,
+  .scl_outsig = I2CEXT0_SCL_OUT_IDX,
+  .sda_insig  = I2CEXT0_SDA_IN_IDX,
+  .sda_outsig = I2CEXT0_SDA_OUT_IDX
+};
+
+static struct esp32s2_i2c_priv_s g_esp32s2_i2c0_priv =
+{
+  .ops        = &g_esp32s2_i2c_ops,
+  .id         = ESP32S2_I2C0,
+  .config     = &g_esp32s2_i2c0_config,
+  .refs       = 0,
+  .i2cstate   = I2CSTATE_IDLE,
+  .msgv       = NULL,
+  .msgid      = 0,
+  .bytes      = 0,
+  .ready_read = false
+};
+#endif /* CONFIG_ESP32S2_I2C0 */
+
+#ifdef CONFIG_ESP32S2_I2C1
+static const struct esp32s2_i2c_config_s g_esp32s2_i2c1_config =
+{
+  .clk_freq   = I2C_CLK_FREQ_DEF,
+  .scl_pin    = CONFIG_ESP32S2_I2C1_SCLPIN,
+  .sda_pin    = CONFIG_ESP32S2_I2C1_SDAPIN,
+#ifndef CONFIG_I2C_POLLED
+  .periph     = ESP32S2_PERIPH_I2C_EXT1,
+  .irq        = ESP32S2_IRQ_I2C_EXT1,
+#endif
+  .clk_bit    = SYSTEM_I2C_EXT1_CLK_EN,
+  .rst_bit    = SYSTEM_I2C_EXT1_RST,
+  .scl_insig  = I2CEXT1_SCL_IN_IDX,
+  .scl_outsig = I2CEXT1_SCL_OUT_IDX,
+  .sda_insig  = I2CEXT1_SDA_IN_IDX,
+  .sda_outsig = I2CEXT1_SDA_OUT_IDX
+};
+
+static struct esp32s2_i2c_priv_s g_esp32s2_i2c1_priv =
+{
+  .ops        = &g_esp32s2_i2c_ops,
+  .id         = ESP32S2_I2C1,
+  .config     = &g_esp32s2_i2c1_config,
+  .refs       = 0,
+  .i2cstate   = I2CSTATE_IDLE,
+  .msgv       = NULL,
+  .msgid      = 0,
+  .bytes      = 0,
+  .ready_read = false
+};
+#endif /* CONFIG_ESP32S2_I2C1 */
+
+/* Trace events strings */
+
+#ifdef CONFIG_I2C_TRACE
+static const char *g_trace_names[] =
+{
+  "NONE      ",
+  "SENDADDR  ",
+  "SENDBYTE  ",
+  "RCVMODEEN ",
+  "RCVBYTE   ",
+  "STOP      ",
+  "ERROR     "
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: i2c_reset_fifo
+ *
+ * Description:
+ *   Reset I2C RX and TX hardware FIFO.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_reset_fifo(struct esp32s2_i2c_priv_s *priv)
+{
+  uint32_t bits = I2C_TX_FIFO_RST | I2C_RX_FIFO_RST;
+
+  modifyreg32(I2C_FIFO_CONF_REG(priv->id), 0, bits);
+  modifyreg32(I2C_FIFO_CONF_REG(priv->id), bits, 0);
+}
+
+/****************************************************************************
+ * Name: i2c_intr_enable
+ *
+ * Description:
+ *   Enable I2C interrupts.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_intr_enable(struct esp32s2_i2c_priv_s *priv)
+{
+  putreg32(UINT32_MAX, I2C_INT_CLR_REG(priv->id));
+
+  putreg32(I2C_TRANS_COMPLETE_INT_ENA | I2C_END_DETECT_INT_ENA |
+           I2C_INT_ERR_MASK, I2C_INT_ENA_REG(priv->id));
+}
+
+/****************************************************************************
+ * Name: i2c_intr_disable
+ *
+ * Description:
+ *   Disable I2C interrupts.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_intr_disable(struct esp32s2_i2c_priv_s *priv)
+{
+  putreg32(0, I2C_INT_ENA_REG(priv->id));
+
+  putreg32(UINT32_MAX, I2C_INT_CLR_REG(priv->id));
+}
+
+/****************************************************************************
+ * Name: i2c_sendstart
+ *
+ * Description:
+ *   Send I2C start signal.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_sendstart(struct esp32s2_i2c_priv_s *priv)
+{
+  struct i2c_msg_s *msg = &priv->msgv[priv->msgid];
+
+  /* Write I2C command registers */
+
+  putreg32(I2C_BASE_CMD(I2C_CMD_RESTART, 0), I2C_COMD0_REG(priv->id));
+  putreg32(I2C_SEND_CMD(I2C_CMD_WRITE, 1, 1), I2C_COMD1_REG(priv->id));
+  putreg32(I2C_BASE_CMD(I2C_CMD_END, 0), I2C_COMD2_REG(priv->id));
+
+  /* Write data to FIFO register */
+
+  if ((msg->flags & I2C_M_READ) == 0)
+    {
+      putreg32(I2C_WRITEADDR8(msg->addr), FIFO_DATA_REG(priv->id));
+    }
+  else
+    {
+      putreg32(I2C_READADDR8(msg->addr), FIFO_DATA_REG(priv->id));
+    }
+
+  /* Enable I2C master TX interrupt */
+
+  i2c_intr_enable(priv);
+
+  /* Configure the I2C to trigger a transaction */
+
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_TRANS_START);
+}
+
+/****************************************************************************
+ * Name: i2c_senddata
+ *
+ * Description:
+ *   Send I2C data.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_senddata(struct esp32s2_i2c_priv_s *priv)
+{
+  struct i2c_msg_s *msg = &priv->msgv[priv->msgid];
+  int n = msg->length - priv->bytes;
+
+  n = n < I2C_FIFO_SIZE ? n : I2C_FIFO_SIZE;
+
+  putreg32(I2C_SEND_CMD(I2C_CMD_WRITE, 1, n), I2C_COMD0_REG(priv->id));
+  putreg32(I2C_BASE_CMD(I2C_CMD_END, 0), I2C_COMD1_REG(priv->id));
+
+  for (int i = 0; i < n; i++)
+    {
+      putreg32(msg->buffer[priv->bytes + i], FIFO_DATA_REG(priv->id));
+    }
+
+  priv->bytes += n;
+
+  /* Enable I2C master TX interrupt */
+
+  i2c_intr_enable(priv);
+
+  /* Configure the I2C to trigger a transaction */
+
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_TRANS_START);
+}
+
+/****************************************************************************
+ * Name: i2c_recvdata
+ *
+ * Description:
+ *   Transfer data from the FIFO to the driver buffer.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_recvdata(struct esp32s2_i2c_priv_s *priv)
+{
+  struct i2c_msg_s *msg = &priv->msgv[priv->msgid];
+  uint32_t cmd = getreg32(I2C_COMD0_REG(priv->id));
+  uint8_t n = cmd & 0xff;
+  uint32_t data = 0;
+
+  for (int i = 0; i < n; i++)
+    {
+      data = getreg32(FIFO_DATA_REG(priv->id));
+      msg->buffer[priv->bytes + i] = data & 0xff;
+    }
+
+  priv->bytes += n;
+}
+
+/****************************************************************************
+ * Name: i2c_startrecv
+ *
+ * Description:
+ *   Configure I2C to prepare receiving data and it will create an interrupt
+ *   to receive real data.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_startrecv(struct esp32s2_i2c_priv_s *priv)
+{
+  int ack_value;
+  struct i2c_msg_s *msg = &priv->msgv[priv->msgid];
+  int n = msg->length - priv->bytes;
+
+  if (n > 1)
+    {
+      n -= 1;
+      n = n < I2C_FIFO_SIZE ? n : I2C_FIFO_SIZE;
+      ack_value = 0;
+    }
+  else
+    {
+      ack_value = 1;
+    }
+
+  putreg32(I2C_RECV_CMD(I2C_CMD_READ, ack_value, n),
+           I2C_COMD0_REG(priv->id));
+  putreg32(I2C_BASE_CMD(I2C_CMD_END, 0), I2C_COMD1_REG(priv->id));
+
+  /* Enable I2C master RX interrupt */
+
+  i2c_intr_enable(priv);
+
+  /* Configure the I2C to trigger a transaction */
+
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_TRANS_START);
+}
+
+/****************************************************************************
+ * Name: i2c_sendstop
+ *
+ * Description:
+ *   Send I2C STOP signal.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_sendstop(struct esp32s2_i2c_priv_s *priv)
+{
+  putreg32(I2C_BASE_CMD(I2C_CMD_STOP, 0), I2C_COMD0_REG(priv->id));
+
+  /* Enable I2C master TX interrupt */
+
+  i2c_intr_enable(priv);
+
+  /* Configure the I2C to trigger a transaction */
+
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_TRANS_START);
+}
+
+/****************************************************************************
+ * Name: i2c_init_clock
+ *
+ * Description:
+ *   Initialize I2C hardware clock.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *   bus_freq      - Clock frequency of the I2C bus in Hz.
+ *
+ ****************************************************************************/
+
+static void i2c_init_clock(struct esp32s2_i2c_priv_s *priv,
+                           uint32_t bus_freq)
+{
+  if (bus_freq == priv->clk_freq)
+    {
+      return;
+    }
+
+  uint32_t reg_value = 0;
+  uint32_t scl_low = 0;
+  uint32_t scl_high = 0;
+  uint32_t scl_wait_high = 0;
+  uint32_t sda_hold = 0;
+  uint32_t sda_sample = 0;
+  uint32_t setup = 0;
+  uint32_t hold = 0;
+  uint32_t timeout = 0;
+  uint32_t source_clk = APB_CLK_FREQ;
+  uint32_t half_cycle = source_clk / bus_freq / 2;
+
+  scl_low       = half_cycle - 1;
+  putreg32(scl_low, I2C_SCL_LOW_PERIOD_REG(priv->id));
+
+  /* By default, scl_wait_high must be less than scl_high */
+
+  scl_high      = half_cycle / 2 + 2;
+  scl_wait_high = half_cycle - scl_high;
+
+  reg_value     = VALUE_TO_FIELD(scl_high, I2C_SCL_HIGH_PERIOD);
+  reg_value    |= VALUE_TO_FIELD(scl_wait_high, I2C_SCL_WAIT_HIGH_PERIOD);
+  putreg32(reg_value, I2C_SCL_HIGH_PERIOD_REG(priv->id));
+
+  sda_hold      = half_cycle / 2;
+  putreg32(sda_hold, I2C_SDA_HOLD_REG(priv->id));
+
+  /* scl_wait_high < sda_sample <= scl_high */
+
+  sda_sample    = half_cycle / 2 - 1;
+  putreg32(sda_sample, I2C_SDA_SAMPLE_REG(priv->id));
+
+  setup         = half_cycle;
+  putreg32(setup, I2C_SCL_RSTART_SETUP_REG(priv->id));
+  putreg32(setup, I2C_SCL_STOP_SETUP_REG(priv->id));
+
+  hold          = half_cycle;
+  putreg32(hold - 1, I2C_SCL_START_HOLD_REG(priv->id));
+  putreg32(hold, I2C_SCL_STOP_HOLD_REG(priv->id));
+
+  /* By default, we set the timeout value to 10 bus cycles */
+
+  timeout       = half_cycle * 20;
+  reg_value     = I2C_TIME_OUT_EN;
+  reg_value    |= VALUE_TO_FIELD(timeout, I2C_TIME_OUT_VALUE);
+  putreg32(reg_value, I2C_TO_REG(priv->id));
+
+  /* Set current bus clock frequency */
+
+  priv->clk_freq = bus_freq;
+}
+
+/****************************************************************************
+ * Name: i2c_init
+ *
+ * Description:
+ *   Initialize I2C hardware.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_init(struct esp32s2_i2c_priv_s *priv)
+{
+  const struct esp32s2_i2c_config_s *config = priv->config;
+
+  esp32s2_gpiowrite(config->scl_pin, 1);
+  esp32s2_configgpio(config->scl_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
+  esp32s2_gpio_matrix_out(config->scl_pin, config->scl_outsig, 0, 0);
+  esp32s2_gpio_matrix_in(config->scl_pin, config->scl_insig, 0);
+
+  esp32s2_gpiowrite(config->sda_pin, 1);
+  esp32s2_configgpio(config->sda_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
+  esp32s2_gpio_matrix_out(config->sda_pin, config->sda_outsig, 0, 0);
+  esp32s2_gpio_matrix_in(config->sda_pin, config->sda_insig, 0);
+
+  /* Enable I2C hardware */
+
+  modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, 0, config->clk_bit);
+  modifyreg32(SYSTEM_PERIP_RST_EN0_REG, config->rst_bit, 0);
+
+  /* Disable I2C interrupts */
+
+  i2c_intr_disable(priv);
+
+  /* Initialize I2C Master */
+
+  putreg32(I2C_MS_MODE | I2C_CLK_EN | I2C_SCL_FORCE_OUT | I2C_SDA_FORCE_OUT,
+           I2C_CTR_REG(priv->id));
+
+  /* Set FIFO mode */
+
+  modifyreg32(I2C_FIFO_CONF_REG(priv->id), I2C_NONFIFO_EN, 0);
+
+  /* Ensure I2C data mode is set to MSB */
+
+  modifyreg32(I2C_CTR_REG(priv->id), I2C_TX_LSB_FIRST | I2C_RX_LSB_FIRST, 0);
+
+  i2c_reset_fifo(priv);
+
+  /* Configure the hardware filter function */
+
+  putreg32(I2C_SCL_FILTER_EN |
+             VALUE_TO_FIELD(I2C_FILTER_CYC_NUM_DEF, I2C_SCL_FILTER_THRES),
+           I2C_SCL_FILTER_CFG_REG(priv->id));
+  putreg32(I2C_SDA_FILTER_EN |
+             VALUE_TO_FIELD(I2C_FILTER_CYC_NUM_DEF, I2C_SDA_FILTER_THRES),
+           I2C_SDA_FILTER_CFG_REG(priv->id));
+
+  /* Set I2C source clock */
+
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_REF_ALWAYS_ON);
+
+  /* Configure I2C bus frequency */
+
+  i2c_init_clock(priv, config->clk_freq);
+}
+
+/****************************************************************************
+ * Name: i2c_deinit
+ *
+ * Description:
+ *   Disable I2C hardware.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_deinit(struct esp32s2_i2c_priv_s *priv)
+{
+  const struct esp32s2_i2c_config_s *config = priv->config;
+
+  priv->clk_freq = 0;
+
+  modifyreg32(SYSTEM_PERIP_RST_EN0_REG, 0, config->rst_bit);
+  modifyreg32(SYSTEM_PERIP_CLK_EN0_REG, config->clk_bit, 0);
+}
+
+/****************************************************************************
+ * Name: i2c_reset_fsmc
+ *
+ * Description:
+ *   Reset I2C hardware state machine and registers.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_reset_fsmc(struct esp32s2_i2c_priv_s *priv)
+{
+  /* Reset FSM machine */
+
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_FSM_RST);
+
+  i2c_clear_bus(priv);
+}
+
+/****************************************************************************
+ * Name: i2c_sem_waitdone
+ *
+ * Description:
+ *   Wait for a transfer to complete.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success. A negated errno value is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_I2C_POLLED
+static int i2c_sem_waitdone(struct esp32s2_i2c_priv_s *priv)
+{
+  /* Wait on ISR semaphore */
+
+  return nxsem_tickwait_uninterruptible(&priv->sem_isr,
+                                        ESP32S2_I2CTIMEOTICKS);
+}
+#endif
+
+/****************************************************************************
+ * Name: i2c_polling_waitdone
+ *
+ * Description:
+ *   Wait for a transfer to complete by polling status interrupt registers,
+ *   which indicates the status of the I2C operations. This function is only
+ *   used in polling driven mode.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ * Returned Values:
+ *   Zero (OK) is returned on successfull transfer. -ETIMEDOUT is returned
+ *   in case a transfer didn't finish within the timeout interval. And ERROR
+ *   is returned in case of any I2C error during the transfer has happened.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_POLLED
+static int i2c_polling_waitdone(struct esp32s2_i2c_priv_s *priv)
+{
+  int ret;
+  clock_t current;
+  clock_t timeout;
+  uint32_t status = 0;
+
+  /* Get the current absolute time and add an offset as timeout.
+   * Preferable to use monotonic, so in case the time changes,
+   * the time reference is kept, i.e., current time can't jump
+   * forward and backwards.
+   */
+
+  current = clock_systime_ticks();
+  timeout = current + SEC2TICK(10);
+
+  /* Loop while a transfer is in progress
+   * and an error didn't occur within the timeout
+   */
+
+  while ((current < timeout) && (priv->error == 0))
+    {
+      /* Check if any interrupt triggered, clear them
+       * process the operation.
+       */
+
+      status = getreg32(I2C_INT_STATUS_REG(priv->id));
+      if (status != 0)
+        {
+          /* Check if the stop operation ended. Don't use
+           * I2CSTATE_FINISH, because it is set before the stop
+           * signal really ends. This works for interrupts because
+           * the i2c_state is checked in the next interrupt when
+           * stop signal has concluded. This is not the case of
+           * polling.
+           */
+
+          if ((status & I2C_TRANS_COMPLETE_INT_ST) != 0)
+            {
+              putreg32(status, I2C_INT_CLR_REG(priv->id));
+              break;
+            }
+
+          putreg32(status, I2C_INT_CLR_REG(priv->id));
+          i2c_process(priv, status);
+        }
+
+      /* Update current time */
+
+      current = clock_systime_ticks();
+    }
+
+  /* Return a negated value in case of timeout, and in the other scenarios
+   * return a positive value.
+   * The transfer function will check the status of priv to check the other
+   * scenarios.
+   */
+
+  if (current >= timeout)
+    {
+      ret = -ETIMEDOUT;
+    }
+  else if (priv->error != 0)
+    {
+      ret = ERROR;
+    }
+  else
+    {
+      ret = OK;
+    }
+
+  /* Disable all interrupts */
+
+  i2c_intr_disable(priv);
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: i2c_sem_wait
+ *
+ * Description:
+ *   Take the exclusive access, waiting as necessary.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success. A negated errno value is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int i2c_sem_wait(struct esp32s2_i2c_priv_s *priv)
+{
+  return nxsem_wait_uninterruptible(&priv->sem_excl);
+}
+
+/****************************************************************************
+ * Name: i2c_sem_post
+ *
+ * Description:
+ *   Release the mutual exclusion semaphore.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_sem_post(struct esp32s2_i2c_priv_s *priv)
+{
+  nxsem_post(&priv->sem_excl);
+}
+
+/****************************************************************************
+ * Name: i2c_sem_destroy
+ *
+ * Description:
+ *   Destroy semaphores.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_sem_destroy(struct esp32s2_i2c_priv_s *priv)
+{
+  nxsem_destroy(&priv->sem_excl);
+#ifndef CONFIG_I2C_POLLED
+  nxsem_destroy(&priv->sem_isr);
+#endif
+}
+
+/****************************************************************************
+ * Name: i2c_sem_init
+ *
+ * Description:
+ *   Initialize semaphores.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_sem_init(struct esp32s2_i2c_priv_s *priv)
+{
+  nxsem_init(&priv->sem_excl, 0, 1);
+
+  /* This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+#ifndef CONFIG_I2C_POLLED
+  nxsem_init(&priv->sem_isr, 0, 0);
+  nxsem_set_protocol(&priv->sem_isr, SEM_PRIO_NONE);
+#endif
+}
+
+/****************************************************************************
+ * Device Driver Operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: i2c_transfer
+ *
+ * Description:
+ *   Generic I2C transfer function.
+ *
+ * Parameters:
+ *   dev           - Device-specific state data
+ *   msgs          - A pointer to a set of message descriptors
+ *   count         - The number of transfers to perform
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success. A negated errno value is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgs,
+                        int count)
+{
+  int ret = OK;
+  struct esp32s2_i2c_priv_s *priv = (struct esp32s2_i2c_priv_s *)dev;
+
+  DEBUGASSERT(count > 0);
+
+  ret = i2c_sem_wait(priv);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* If previous state is different than idle,
+   * reset the FSMC to the idle state.
+   */
+
+  if (priv->i2cstate != I2CSTATE_IDLE)
+    {
+      i2c_reset_fsmc(priv);
+      priv->i2cstate = I2CSTATE_IDLE;
+    }
+
+  /* Transfer the messages to the internal struct
+   * and loop count times to make all transfers.
+   */
+
+  priv->msgv = msgs;
+
+  for (int i = 0; i < count; i++)
+    {
+      /* Clear TX and RX FIFOs. */
+
+      i2c_reset_fifo(priv);
+
+      priv->bytes      = 0;
+      priv->msgid      = i;
+      priv->ready_read = false;
+      priv->error      = 0;
+      priv->i2cstate   = I2CSTATE_PROC;
+
+      /* Set the SCLK frequency for the current msg. */
+
+      i2c_init_clock(priv, msgs[i].frequency);
+
+      if ((msgs[i].flags & I2C_M_NOSTART) != 0)
+        {
+          i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->bytes,
+                         getreg32(I2C_SR_REG(priv->id)));
+          i2c_senddata(priv);
+
+          if (priv->bytes == msgs[i].length)
+            {
+              if ((msgs[i].flags & I2C_M_NOSTOP) == 0)
+                {
+                  priv->i2cstate = I2CSTATE_STOP;
+                }
+#ifndef CONFIG_I2C_POLLED
+              else
+                {
+                  priv->i2cstate = I2CSTATE_FINISH;
+                }
+#endif
+            }
+        }
+      else
+        {
+          /* Reset I2C trace logic */
+
+          i2c_tracereset(priv);
+
+          i2c_traceevent(priv, I2CEVENT_SENDADDR, msgs[i].addr,
+                         getreg32(I2C_SR_REG(priv->id)));
+
+          i2c_sendstart(priv);
+        }
+
+#ifndef CONFIG_I2C_POLLED
+      if (i2c_sem_waitdone(priv) < 0)
+        {
+          /* Timed out - transfer was not completed within the timeout */
+
+          i2cerr("Message %" PRIu8 " timed out.\n", priv->msgid);
+          ret = -ETIMEDOUT;
+          break;
+        }
+      else
+        {
+          if (priv->error != 0)
+            {
+              /* An error occurred */
+
+              i2cerr("Transfer error %" PRIu32 "\n", priv->error);
+              ret = -EIO;
+              break;
+            }
+          else
+            {
+              /* Successful transfer, update the I2C state to idle */
+
+              priv->i2cstate = I2CSTATE_IDLE;
+              ret = OK;
+            }
+        }
+#else
+      ret = i2c_polling_waitdone(priv);
+      if (ret < 0)
+        {
+          if (ret == -ETIMEDOUT)
+            {
+              break;
+            }
+          else
+            {
+              ret = -EIO;
+              break;
+            }
+        }
+      else
+        {
+          /* Successful transfer, update the I2C state to idle */
+
+          priv->i2cstate = I2CSTATE_IDLE;
+          ret = OK;
+        }
+#endif
+
+      i2cinfo("Message %" PRIu8 " transfer complete.\n", priv->msgid);
+    }
+
+  /* Dump the trace result */
+
+  i2c_tracedump(priv);
+
+  i2c_sem_post(priv);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: i2c_clear_bus
+ *
+ * Description:
+ *   Clear I2C bus, when the slave is stuck in a deadlock and keeps pulling
+ *   the bus low, master can control the SCL bus to generate 9 CLKs.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+static void i2c_clear_bus(struct esp32s2_i2c_priv_s *priv)
+{
+  modifyreg32(I2C_SCL_SP_CONF_REG(priv->id),
+              I2C_SCL_RST_SLV_EN | I2C_SCL_RST_SLV_NUM_M,
+              VALUE_TO_FIELD(I2C_SCL_CYC_NUM_DEF, I2C_SCL_RST_SLV_NUM));
+
+  modifyreg32(I2C_SCL_SP_CONF_REG(priv->id), 0, I2C_SCL_RST_SLV_EN);
+}
+
+/****************************************************************************
+ * Name: i2c_reset
+ *
+ * Description:
+ *   Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
+ *
+ * Input Parameters:
+ *   dev   - Device-specific state data
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_RESET
+static int i2c_reset(struct i2c_master_s *dev)
+{
+  irqstate_t flags;
+  struct esp32s2_i2c_priv_s *priv = (struct esp32s2_i2c_priv_s *)dev;
+
+  DEBUGASSERT(dev != NULL);
+  DEBUGASSERT(priv->refs > 0);
+
+  flags = enter_critical_section();
+
+  i2c_reset_fsmc(priv);
+
+  /* Clear bus */
+
+  i2c_clear_bus(priv);
+
+  priv->i2cstate   = I2CSTATE_IDLE;
+  priv->msgid      = 0;
+  priv->bytes      = 0;
+  priv->ready_read = false;
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: i2c_traceclear
+ *
+ * Description:
+ *   Set I2C trace fields to default value.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_TRACE
+static void i2c_traceclear(struct esp32s2_i2c_priv_s *priv)
+{
+  struct esp32s2_trace_s *trace = &priv->trace[priv->tndx];
+
+  trace->status = 0;
+  trace->count  = 0;
+  trace->event  = I2CEVENT_NONE;
+  trace->parm   = 0;
+  trace->time   = 0;
+}
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Name: i2c_tracereset
+ *
+ * Description:
+ *   Reset the trace info for a new data collection.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_TRACE
+static void i2c_tracereset(struct esp32s2_i2c_priv_s *priv)
+{
+  priv->tndx       = 0;
+  priv->start_time = clock_systime_ticks();
+  i2c_traceclear(priv);
+}
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Name: i2c_tracenew
+ *
+ * Description:
+ *   Create a new trace entry.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *   status        - Current value of I2C status register.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_TRACE
+static void i2c_tracenew(struct esp32s2_i2c_priv_s *priv, uint32_t status)
+{
+  struct esp32s2_trace_s *trace = &priv->trace[priv->tndx];
+
+  /* Check if the current entry is already initialized or if its status had
+   * already changed
+   */
+
+  if (trace->count == 0 || status != trace->status)
+    {
+      /* Check whether the status changed */
+
+      if (trace->count != 0)
+        {
+          /* Bump up the trace index (unless we are out of trace entries) */
+
+          if (priv->tndx >= (CONFIG_I2C_NTRACE - 1))
+            {
+              i2cerr("ERROR: Trace table overflow\n");
+              return;
+            }
+
+          priv->tndx++;
+          trace = &priv->trace[priv->tndx];
+        }
+
+      /* Initialize the new trace entry */
+
+      i2c_traceclear(priv);
+      trace->status = status;
+      trace->count  = 1;
+      trace->time   = clock_systime_ticks();
+    }
+  else
+    {
+      /* Just increment the count of times that we have seen this status */
+
+      trace->count++;
+    }
+}
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Name: i2c_traceevent
+ *
+ * Description:
+ *   Record a new trace event.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *   event         - Event to be recorded on the trace.
+ *   parm          - Parameter associated with the event.
+ *   status        - Current value of I2C status register.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_TRACE
+static void i2c_traceevent(struct esp32s2_i2c_priv_s *priv,
+                           enum esp32s2_trace_e event,
+                           uint32_t parm,
+                           uint32_t status)
+{
+  /* Check for new trace setup */
+
+  i2c_tracenew(priv, status);
+
+  if (event != I2CEVENT_NONE)
+    {
+      struct esp32s2_trace_s *trace = &priv->trace[priv->tndx];
+
+      /* Initialize the new trace entry */
+
+      trace->event  = event;
+      trace->parm   = parm;
+
+      /* Bump up the trace index (unless we are out of trace entries) */
+
+      if (priv->tndx >= (CONFIG_I2C_NTRACE - 1))
+        {
+          i2cerr("ERROR: Trace table overflow\n");
+          return;
+        }
+
+      priv->tndx++;
+      i2c_traceclear(priv);
+    }
+}
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Name: i2c_tracedump
+ *
+ * Description:
+ *   Dump the trace results.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_TRACE
+static void i2c_tracedump(struct esp32s2_i2c_priv_s *priv)
+{
+  syslog(LOG_DEBUG, "Elapsed time: %" PRIu32 "\n",
+         clock_systime_ticks() - priv->start_time);
+
+  for (int i = 0; i < priv->tndx; i++)
+    {
+      struct esp32s2_trace_s *trace = &priv->trace[i];
+      syslog(LOG_DEBUG,
+             "%2d. STATUS: %08" PRIx32 " COUNT: %3" PRIu32 " EVENT: %s(%2d)"
+             " PARM: %08" PRIx32 " TIME: %" PRIu32 "\n",
+             i + 1, trace->status, trace->count, g_trace_names[trace->event],
+             trace->event, trace->parm, trace->time - priv->start_time);
+    }
+}
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Name: i2c_irq
+ *
+ * Description:
+ *   This is the common I2C interrupt handler. It will be invoked when an
+ *   interrupt is received on the device.
+ *
+ * Parameters:
+ *   cpuint        - CPU interrupt index
+ *   context       - Context data from the ISR
+ *   arg           - Opaque pointer to the internal driver state structure.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success. A negated errno value is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_I2C_POLLED
+static int i2c_irq(int cpuint, void *context, void *arg)
+{
+  struct esp32s2_i2c_priv_s *priv = (struct esp32s2_i2c_priv_s *)arg;
+
+  /* Get the interrupt status and clear the interrupts that
+   * triggered.
+   */
+
+  uint32_t irq_status = getreg32(I2C_INT_STATUS_REG(priv->id));
+  putreg32(irq_status, I2C_INT_CLR_REG(priv->id));
+
+  i2c_process(priv, irq_status);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: i2c_process
+ *
+ * Description:
+ *   This routine manages the transfer. It's called after some specific
+ *   commands from the I2C controller are executed or in case of errors.
+ *   It's responsible for writing/reading operations and transferring data
+ *   from/to FIFO.
+ *   It's called in the interrupt and polled driven mode.
+ *
+ * Parameters:
+ *   priv          - Pointer to the internal driver state structure.
+ *   status        - The current interrupt status register.
+ *
+ ****************************************************************************/
+
+static void i2c_process(struct esp32s2_i2c_priv_s *priv, uint32_t status)
+{
+  struct i2c_msg_s *msg = &priv->msgv[priv->msgid];
+
+  /* Check for any errors */
+
+  if ((I2C_INT_ERR_MASK & status) != 0)
+    {
+      /* Save the errors, register the error event, disable interrupts
+       * and release the semaphore to conclude the transfer.
+       */
+
+      priv->error = status & I2C_INT_ERR_MASK;
+      priv->i2cstate = I2CSTATE_ERROR;
+      i2c_traceevent(priv, I2CEVENT_ERROR, priv->error,
+                     getreg32(I2C_SR_REG(priv->id)));
+      i2c_intr_disable(priv);
+#ifndef CONFIG_I2C_POLLED
+      nxsem_post(&priv->sem_isr);
+#endif
+    }
+  else /* If no error */
+    {
+      /* If a transfer has just initialized */
+
+      if (priv->i2cstate == I2CSTATE_PROC)
+        {
+          /* Check the flags to perform a read or write operation */
+
+          if ((msg->flags & I2C_M_READ) != 0)
+            {
+              /* RX FIFO has available data */
+
+              if (priv->ready_read)
+                {
+                  i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->bytes,
+                                 getreg32(I2C_SR_REG(priv->id)));
+                  i2c_recvdata(priv);
+
+                  priv->ready_read = false;
+                }
+
+              /* Received all data. Finish the transaction
+               * and update the I2C state.
+               */
+
+              if (priv->bytes == msg->length)
+                {
+                  i2c_traceevent(priv, I2CEVENT_STOP, msg->length,
+                                 getreg32(I2C_SR_REG(priv->id)));
+                  i2c_sendstop(priv);
+#ifndef CONFIG_I2C_POLLED
+                  priv->i2cstate = I2CSTATE_FINISH;
+#endif
+                }
+              else /* Start a receive operation */
+                {
+                  i2c_traceevent(priv, I2CEVENT_RCVMODEEN, 0,
+                                 getreg32(I2C_SR_REG(priv->id)));
+                  i2c_startrecv(priv);
+
+                  priv->ready_read = true;
+                }
+            }
+          else /* Write operation */
+            {
+              i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->bytes,
+                             getreg32(I2C_SR_REG(priv->id)));
+              i2c_senddata(priv);
+
+              /* Finally sent the entire message. Update the I2C state to
+               * send a stop signal in the next interrupt.
+               */
+
+              if (priv->bytes == msg->length)
+                {
+                  if ((msg->flags & I2C_M_NOSTOP) == 0)
+                    {
+                      priv->i2cstate = I2CSTATE_STOP;
+                    }
+#ifndef CONFIG_I2C_POLLED
+                  else
+                    {
+                      priv->i2cstate = I2CSTATE_FINISH;
+                    }
+#endif
+                }
+            }
+        }
+      else if (priv->i2cstate == I2CSTATE_STOP)
+        {
+          /* Transmitted all data. Finish the transaction sending a stop
+           * and update the I2C state.
+           */
+
+          i2c_traceevent(priv, I2CEVENT_STOP, msg->length,
+                         getreg32(I2C_SR_REG(priv->id)));
+          i2c_sendstop(priv);
+#ifndef CONFIG_I2C_POLLED
+          priv->i2cstate = I2CSTATE_FINISH;
+#endif
+        }
+#ifndef CONFIG_I2C_POLLED
+      else if (priv->i2cstate == I2CSTATE_FINISH)
+        {
+          /* Disable all interrupts and release the semaphore */
+
+          i2c_intr_disable(priv);
+          nxsem_post(&priv->sem_isr);
+        }
+#endif
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32s2_i2cbus_initialize
+ *
+ * Description:
+ *   Initialize the selected I2C port. And return a pointer to an unique
+ *   instance of struct i2c_master_s. This function may be called to obtain
+ *   multiple instances of the interface, each of which may be set up with a
+ *   different frequency and slave address.
+ *
+ * Parameters:
+ *   port          - Port number of the I2C interface to be initialized.
+ *
+ * Returned Value:
+ *   Pointer to valid I2C device structure is returned on success.
+ *   A NULL pointer is returned on failure.
+ *
+ ****************************************************************************/
+
+struct i2c_master_s *esp32s2_i2cbus_initialize(int port)
+{
+  irqstate_t flags;
+  struct esp32s2_i2c_priv_s *priv;
+#ifndef CONFIG_I2C_POLLED
+  const struct esp32s2_i2c_config_s *config;
+  int ret;
+#endif
+
+  switch (port)
+    {
+#ifdef CONFIG_ESP32S2_I2C0
+      case ESP32S2_I2C0:
+        priv = &g_esp32s2_i2c0_priv;
+        break;
+#endif
+#ifdef CONFIG_ESP32S2_I2C1
+      case ESP32S2_I2C1:
+        priv = &g_esp32s2_i2c1_priv;
+        break;
+#endif
+      default:
+        return NULL;
+    }
+
+  flags = enter_critical_section();
+
+  if (priv->refs++ != 0)
+    {
+      leave_critical_section(flags);
+
+      return (struct i2c_master_s *)priv;
+    }
+
+#ifndef CONFIG_I2C_POLLED
+  config = priv->config;
+
+  /* Set up to receive peripheral interrupts on the current CPU */
+
+  priv->cpuint = esp32s2_setup_irq(config->periph, 1, ESP32S2_CPUINT_LEVEL);
+  if (priv->cpuint < 0)
+    {
+      /* Failed to allocate a CPU interrupt of this type */
+
+      leave_critical_section(flags);
+
+      return NULL;
+    }
+
+  ret = irq_attach(config->irq, i2c_irq, priv);
+  if (ret != OK)
+    {
+      esp32s2_teardown_irq(config->periph, priv->cpuint);
+
+      leave_critical_section(flags);
+
+      return NULL;
+    }
+
+  up_enable_irq(config->irq);
+#endif
+
+  i2c_sem_init(priv);
+
+  i2c_init(priv);
+
+  leave_critical_section(flags);
+
+  return (struct i2c_master_s *)priv;
+}
+
+/****************************************************************************
+ * Name: esp32s2_i2cbus_uninitialize
+ *
+ * Description:
+ *   De-initialize the selected I2C port and power down the device.
+ *
+ * Parameters:
+ *   dev           - Device structure as returned by
+ *                   esp32s2_i2cbus_initialize()
+ *
+ * Returned Value:
+ *   OK is returned on success. ERROR is returned when internal reference
+ *   count mismatches or dev points to invalid hardware device.
+ *
+ ****************************************************************************/
+
+int esp32s2_i2cbus_uninitialize(struct i2c_master_s *dev)
+{
+  irqstate_t flags;
+  struct esp32s2_i2c_priv_s *priv = (struct esp32s2_i2c_priv_s *)dev;
+
+  DEBUGASSERT(dev != NULL);
+
+  if (priv->refs == 0)
+    {
+      return ERROR;
+    }
+
+  flags = enter_critical_section();
+
+  if (--priv->refs)
+    {
+      leave_critical_section(flags);
+      return OK;
+    }
+
+  leave_critical_section(flags);
+
+#ifndef CONFIG_I2C_POLLED
+  up_disable_irq(priv->config->irq);
+  esp32s2_teardown_irq(priv->config->periph, priv->cpuint);
+#endif
+
+  i2c_deinit(priv);
+
+  i2c_sem_destroy(priv);
+
+  return OK;
+}
+
+#endif /* CONFIG_ESP32S2_I2C */
diff --git a/arch/xtensa/src/esp32s2/esp32s2_i2c.h b/arch/xtensa/src/esp32s2/esp32s2_i2c.h
new file mode 100644
index 0000000000..51df9472f6
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/esp32s2_i2c.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/esp32s2_i2c.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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifndef __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_I2C_H
+#define __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_I2C_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/i2c/i2c_master.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ESP32S2_I2C0
+#  define ESP32S2_I2C0 0
+#endif
+
+#ifdef CONFIG_ESP32S2_I2C1
+#  define ESP32S2_I2C1 1
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32s2_i2cbus_initialize
+ *
+ * Description:
+ *   Initialize the selected I2C port. And return a unique instance of struct
+ *   struct i2c_master_s.  This function may be called to obtain multiple
+ *   instances of the interface, each of which may be set up with a
+ *   different frequency and slave address.
+ *
+ * Input Parameters:
+ *   Port number (for hardware that has multiple I2C interfaces)
+ *
+ * Returned Value:
+ *   Valid I2C device structure reference on success; a NULL on failure
+ *
+ ****************************************************************************/
+
+struct i2c_master_s *esp32s2_i2cbus_initialize(int port);
+
+/****************************************************************************
+ * Name: esp32s2_i2cbus_uninitialize
+ *
+ * Description:
+ *   De-initialize the selected I2C port, and power down the device.
+ *
+ * Input Parameters:
+ *   Device structure as returned by the esp32s2_i2cbus_initialize()
+ *
+ * Returned Value:
+ *   OK on success, ERROR when internal reference count mismatch or dev
+ *   points to invalid hardware device.
+ *
+ ****************************************************************************/
+
+int esp32s2_i2cbus_uninitialize(struct i2c_master_s *dev);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_XTENSA_SRC_ESP32S2_ESP32S2_I2C_H */
diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.h
new file mode 100644
index 0000000000..15487731d2
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.h
@@ -0,0 +1,1992 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/hardware/esp32s2_i2c.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_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_I2C_H
+#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_I2C_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32s2_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* I2C_SCL_LOW_PERIOD_REG register
+ * Configures the low level width of the SCL clock
+ */
+
+#define I2C_SCL_LOW_PERIOD_REG(i) (REG_I2C_BASE(i) + 0x0)
+
+/* I2C_SCL_LOW_PERIOD : R/W; bitpos: [13:0]; default: 0;
+ * This register is used to configure for how long SCL remains low in master
+ * mode, in I2C module clock cycles.
+ */
+
+#define I2C_SCL_LOW_PERIOD    0x00003fff
+#define I2C_SCL_LOW_PERIOD_M  (I2C_SCL_LOW_PERIOD_V << I2C_SCL_LOW_PERIOD_S)
+#define I2C_SCL_LOW_PERIOD_V  0x00003fff
+#define I2C_SCL_LOW_PERIOD_S  0
+
+/* I2C_CTR_REG register
+ * Transmission setting
+ */
+
+#define I2C_CTR_REG(i) (REG_I2C_BASE(i) + 0x4)
+
+/* I2C_REF_ALWAYS_ON : R/W; bitpos: [11]; default: 1;
+ * This register is used to control the REF_TICK.
+ */
+
+#define I2C_REF_ALWAYS_ON    (BIT(11))
+#define I2C_REF_ALWAYS_ON_M  (I2C_REF_ALWAYS_ON_V << I2C_REF_ALWAYS_ON_S)
+#define I2C_REF_ALWAYS_ON_V  0x00000001
+#define I2C_REF_ALWAYS_ON_S  11
+
+/* I2C_FSM_RST : R/W; bitpos: [10]; default: 0;
+ * This register is used to reset the SCL_FSM.
+ */
+
+#define I2C_FSM_RST    (BIT(10))
+#define I2C_FSM_RST_M  (I2C_FSM_RST_V << I2C_FSM_RST_S)
+#define I2C_FSM_RST_V  0x00000001
+#define I2C_FSM_RST_S  10
+
+/* I2C_ARBITRATION_EN : R/W; bitpos: [9]; default: 1;
+ * This is the enable bit for I2C bus arbitration function.
+ */
+
+#define I2C_ARBITRATION_EN    (BIT(9))
+#define I2C_ARBITRATION_EN_M  (I2C_ARBITRATION_EN_V << I2C_ARBITRATION_EN_S)
+#define I2C_ARBITRATION_EN_V  0x00000001
+#define I2C_ARBITRATION_EN_S  9
+
+/* I2C_CLK_EN : R/W; bitpos: [8]; default: 0;
+ * Reserved.
+ */
+
+#define I2C_CLK_EN    (BIT(8))
+#define I2C_CLK_EN_M  (I2C_CLK_EN_V << I2C_CLK_EN_S)
+#define I2C_CLK_EN_V  0x00000001
+#define I2C_CLK_EN_S  8
+
+/* I2C_RX_LSB_FIRST : R/W; bitpos: [7]; default: 0;
+ * This bit is used to control the storage mode for received data.
+ *
+ * 1: receive data from the least significant bit.
+ *
+ * 0: receive data from the most significant bit.
+ */
+
+#define I2C_RX_LSB_FIRST    (BIT(7))
+#define I2C_RX_LSB_FIRST_M  (I2C_RX_LSB_FIRST_V << I2C_RX_LSB_FIRST_S)
+#define I2C_RX_LSB_FIRST_V  0x00000001
+#define I2C_RX_LSB_FIRST_S  7
+
+/* I2C_TX_LSB_FIRST : R/W; bitpos: [6]; default: 0;
+ * This bit is used to control the sending mode for data needing to be sent.
+ *
+ * 1: send data from the least significant bit.
+ *
+ * 0: send data from the most significant bit.
+ */
+
+#define I2C_TX_LSB_FIRST    (BIT(6))
+#define I2C_TX_LSB_FIRST_M  (I2C_TX_LSB_FIRST_V << I2C_TX_LSB_FIRST_S)
+#define I2C_TX_LSB_FIRST_V  0x00000001
+#define I2C_TX_LSB_FIRST_S  6
+
+/* I2C_TRANS_START : R/W; bitpos: [5]; default: 0;
+ * Set this bit to start sending the data in TX FIFO.
+ */
+
+#define I2C_TRANS_START    (BIT(5))
+#define I2C_TRANS_START_M  (I2C_TRANS_START_V << I2C_TRANS_START_S)
+#define I2C_TRANS_START_V  0x00000001
+#define I2C_TRANS_START_S  5
+
+/* I2C_MS_MODE : R/W; bitpos: [4]; default: 0;
+ * Set this bit to configure the module as an I2C Master. Clear this bit to
+ * configure the module as an I2C Slave.
+ */
+
+#define I2C_MS_MODE    (BIT(4))
+#define I2C_MS_MODE_M  (I2C_MS_MODE_V << I2C_MS_MODE_S)
+#define I2C_MS_MODE_V  0x00000001
+#define I2C_MS_MODE_S  4
+
+/* I2C_RX_FULL_ACK_LEVEL : R/W; bitpos: [3]; default: 1;
+ * This register is used to configure the ACK value that need to sent by
+ * master when the rx_fifo_cnt has reached the threshold.
+ */
+
+#define I2C_RX_FULL_ACK_LEVEL    (BIT(3))
+#define I2C_RX_FULL_ACK_LEVEL_M  (I2C_RX_FULL_ACK_LEVEL_V << I2C_RX_FULL_ACK_LEVEL_S)
+#define I2C_RX_FULL_ACK_LEVEL_V  0x00000001
+#define I2C_RX_FULL_ACK_LEVEL_S  3
+
+/* I2C_SAMPLE_SCL_LEVEL : R/W; bitpos: [2]; default: 0;
+ * This register is used to select the sample mode.
+ *
+ * 1: sample SDA data on the SCL low level.
+ *
+ * 0: sample SDA data on the SCL high level.
+ */
+
+#define I2C_SAMPLE_SCL_LEVEL    (BIT(2))
+#define I2C_SAMPLE_SCL_LEVEL_M  (I2C_SAMPLE_SCL_LEVEL_V << I2C_SAMPLE_SCL_LEVEL_S)
+#define I2C_SAMPLE_SCL_LEVEL_V  0x00000001
+#define I2C_SAMPLE_SCL_LEVEL_S  2
+
+/* I2C_SCL_FORCE_OUT : R/W; bitpos: [1]; default: 1;
+ * 0: direct output. 1: open drain output.
+ */
+
+#define I2C_SCL_FORCE_OUT    (BIT(1))
+#define I2C_SCL_FORCE_OUT_M  (I2C_SCL_FORCE_OUT_V << I2C_SCL_FORCE_OUT_S)
+#define I2C_SCL_FORCE_OUT_V  0x00000001
+#define I2C_SCL_FORCE_OUT_S  1
+
+/* I2C_SDA_FORCE_OUT : R/W; bitpos: [0]; default: 1;
+ * 0: direct output. 1: open drain output.
+ */
+
+#define I2C_SDA_FORCE_OUT    (BIT(0))
+#define I2C_SDA_FORCE_OUT_M  (I2C_SDA_FORCE_OUT_V << I2C_SDA_FORCE_OUT_S)
+#define I2C_SDA_FORCE_OUT_V  0x00000001
+#define I2C_SDA_FORCE_OUT_S  0
+
+/* I2C_SR_REG register
+ * Describe I2C work status
+ */
+
+#define I2C_SR_REG(i) (REG_I2C_BASE(i) + 0x8)
+
+/* I2C_SCL_STATE_LAST : RO; bitpos: [30:28]; default: 0;
+ * This field indicates the states of the state machine used to produce SCL.
+ *
+ * 0: Idle. 1: Start. 2: Negative edge. 3: Low. 4: Positive edge. 5: High.
+ * 6: Stop
+ */
+
+#define I2C_SCL_STATE_LAST    0x00000007
+#define I2C_SCL_STATE_LAST_M  (I2C_SCL_STATE_LAST_V << I2C_SCL_STATE_LAST_S)
+#define I2C_SCL_STATE_LAST_V  0x00000007
+#define I2C_SCL_STATE_LAST_S  28
+
+/* I2C_SCL_MAIN_STATE_LAST : RO; bitpos: [26:24]; default: 0;
+ * This field indicates the states of the I2C module state machine.
+ *
+ * 0: Idle. 1: Address shift. 2: ACK address. 3: RX data. 4: TX data. 5:
+ * Send ACK. 6: Wait ACK
+ */
+
+#define I2C_SCL_MAIN_STATE_LAST    0x00000007
+#define I2C_SCL_MAIN_STATE_LAST_M  (I2C_SCL_MAIN_STATE_LAST_V << I2C_SCL_MAIN_STATE_LAST_S)
+#define I2C_SCL_MAIN_STATE_LAST_V  0x00000007
+#define I2C_SCL_MAIN_STATE_LAST_S  24
+
+/* I2C_TXFIFO_CNT : RO; bitpos: [23:18]; default: 0;
+ * This field stores the amount of received data in RAM.
+ */
+
+#define I2C_TXFIFO_CNT    0x0000003f
+#define I2C_TXFIFO_CNT_M  (I2C_TXFIFO_CNT_V << I2C_TXFIFO_CNT_S)
+#define I2C_TXFIFO_CNT_V  0x0000003f
+#define I2C_TXFIFO_CNT_S  18
+
+/* I2C_STRETCH_CAUSE : RO; bitpos: [15:14]; default: 0;
+ * The cause of stretching SCL low in slave mode. 0:  stretching SCL low at
+ * the beginning of I2C read data state. 1: stretching SCL low when I2C TX
+ * FIFO is empty in slave mode. 2: stretching SCL low when I2C RX FIFO is
+ * full in slave mode.
+ */
+
+#define I2C_STRETCH_CAUSE    0x00000003
+#define I2C_STRETCH_CAUSE_M  (I2C_STRETCH_CAUSE_V << I2C_STRETCH_CAUSE_S)
+#define I2C_STRETCH_CAUSE_V  0x00000003
+#define I2C_STRETCH_CAUSE_S  14
+
+/* I2C_RXFIFO_CNT : RO; bitpos: [13:8]; default: 0;
+ * This field represents the amount of data needed to be sent.
+ */
+
+#define I2C_RXFIFO_CNT    0x0000003f
+#define I2C_RXFIFO_CNT_M  (I2C_RXFIFO_CNT_V << I2C_RXFIFO_CNT_S)
+#define I2C_RXFIFO_CNT_V  0x0000003f
+#define I2C_RXFIFO_CNT_S  8
+
+/* I2C_BYTE_TRANS : RO; bitpos: [6]; default: 0;
+ * This field changes to 1 when one byte is transferred.
+ */
+
+#define I2C_BYTE_TRANS    (BIT(6))
+#define I2C_BYTE_TRANS_M  (I2C_BYTE_TRANS_V << I2C_BYTE_TRANS_S)
+#define I2C_BYTE_TRANS_V  0x00000001
+#define I2C_BYTE_TRANS_S  6
+
+/* I2C_SLAVE_ADDRESSED : RO; bitpos: [5]; default: 0;
+ * When configured as an I2C Slave, and the address sent by the master is
+ * equal to the address of the slave, then this bit will be of high level.
+ */
+
+#define I2C_SLAVE_ADDRESSED    (BIT(5))
+#define I2C_SLAVE_ADDRESSED_M  (I2C_SLAVE_ADDRESSED_V << I2C_SLAVE_ADDRESSED_S)
+#define I2C_SLAVE_ADDRESSED_V  0x00000001
+#define I2C_SLAVE_ADDRESSED_S  5
+
+/* I2C_BUS_BUSY : RO; bitpos: [4]; default: 0;
+ * 1: the I2C bus is busy transferring data. 0: the I2C bus is in idle state.
+ */
+
+#define I2C_BUS_BUSY    (BIT(4))
+#define I2C_BUS_BUSY_M  (I2C_BUS_BUSY_V << I2C_BUS_BUSY_S)
+#define I2C_BUS_BUSY_V  0x00000001
+#define I2C_BUS_BUSY_S  4
+
+/* I2C_ARB_LOST : RO; bitpos: [3]; default: 0;
+ * When the I2C controller loses control of SCL line, this register changes
+ * to 1.
+ */
+
+#define I2C_ARB_LOST    (BIT(3))
+#define I2C_ARB_LOST_M  (I2C_ARB_LOST_V << I2C_ARB_LOST_S)
+#define I2C_ARB_LOST_V  0x00000001
+#define I2C_ARB_LOST_S  3
+
+/* I2C_TIME_OUT : RO; bitpos: [2]; default: 0;
+ * When the I2C controller takes more than I2C_TIME_OUT clocks to receive a
+ * data bit, this field changes to 1.
+ */
+
+#define I2C_TIME_OUT    (BIT(2))
+#define I2C_TIME_OUT_M  (I2C_TIME_OUT_V << I2C_TIME_OUT_S)
+#define I2C_TIME_OUT_V  0x00000001
+#define I2C_TIME_OUT_S  2
+
+/* I2C_SLAVE_RW : RO; bitpos: [1]; default: 0;
+ * When in slave mode, 1: master reads from slave. 0: master writes to slave.
+ */
+
+#define I2C_SLAVE_RW    (BIT(1))
+#define I2C_SLAVE_RW_M  (I2C_SLAVE_RW_V << I2C_SLAVE_RW_S)
+#define I2C_SLAVE_RW_V  0x00000001
+#define I2C_SLAVE_RW_S  1
+
+/* I2C_RESP_REC : RO; bitpos: [0]; default: 0;
+ * The received ACK value in master mode or slave mode. 0: ACK. 1: NACK.
+ */
+
+#define I2C_RESP_REC    (BIT(0))
+#define I2C_RESP_REC_M  (I2C_RESP_REC_V << I2C_RESP_REC_S)
+#define I2C_RESP_REC_V  0x00000001
+#define I2C_RESP_REC_S  0
+
+/* I2C_TO_REG register
+ * Setting time out control for receiving data
+ */
+
+#define I2C_TO_REG(i) (REG_I2C_BASE(i) + 0xc)
+
+/* I2C_TIME_OUT_EN : R/W; bitpos: [24]; default: 0;
+ * This is the enable bit for time out control.
+ */
+
+#define I2C_TIME_OUT_EN    (BIT(24))
+#define I2C_TIME_OUT_EN_M  (I2C_TIME_OUT_EN_V << I2C_TIME_OUT_EN_S)
+#define I2C_TIME_OUT_EN_V  0x00000001
+#define I2C_TIME_OUT_EN_S  24
+
+/* I2C_TIME_OUT_VALUE : R/W; bitpos: [23:0]; default: 0;
+ * This register is used to configure the timeout for receiving a data bit
+ * in APB clock cycles.
+ */
+
+#define I2C_TIME_OUT_VALUE    0x00ffffff
+#define I2C_TIME_OUT_VALUE_M  (I2C_TIME_OUT_VALUE_V << I2C_TIME_OUT_VALUE_S)
+#define I2C_TIME_OUT_VALUE_V  0x00ffffff
+#define I2C_TIME_OUT_VALUE_S  0
+
+/* I2C_SLAVE_ADDR_REG register
+ * Local slave address setting
+ */
+
+#define I2C_SLAVE_ADDR_REG(i) (REG_I2C_BASE(i) + 0x10)
+
+/* I2C_ADDR_10BIT_EN : R/W; bitpos: [31]; default: 0;
+ * This field is used to enable the slave 10-bit addressing mode in master
+ * mode.
+ */
+
+#define I2C_ADDR_10BIT_EN    (BIT(31))
+#define I2C_ADDR_10BIT_EN_M  (I2C_ADDR_10BIT_EN_V << I2C_ADDR_10BIT_EN_S)
+#define I2C_ADDR_10BIT_EN_V  0x00000001
+#define I2C_ADDR_10BIT_EN_S  31
+
+/* I2C_SLAVE_ADDR : R/W; bitpos: [14:0]; default: 0;
+ * When configured as an I2C Slave, this field is used to configure the
+ * slave address.
+ */
+
+#define I2C_SLAVE_ADDR    0x00007fff
+#define I2C_SLAVE_ADDR_M  (I2C_SLAVE_ADDR_V << I2C_SLAVE_ADDR_S)
+#define I2C_SLAVE_ADDR_V  0x00007fff
+#define I2C_SLAVE_ADDR_S  0
+
+/* I2C_FIFO_ST_REG register
+ * FIFO status register
+ */
+
+#define I2C_FIFO_ST_REG(i) (REG_I2C_BASE(i) + 0x14)
+
+/* I2C_SLAVE_RW_POINT : RO; bitpos: [29:22]; default: 0;
+ * The received data in I2C slave mode.
+ */
+
+#define I2C_SLAVE_RW_POINT    0x000000ff
+#define I2C_SLAVE_RW_POINT_M  (I2C_SLAVE_RW_POINT_V << I2C_SLAVE_RW_POINT_S)
+#define I2C_SLAVE_RW_POINT_V  0x000000ff
+#define I2C_SLAVE_RW_POINT_S  22
+
+/* I2C_TX_UPDATE : WO; bitpos: [21]; default: 0;
+ * Write 0 or 1 to I2C_TX_UPDATE to update the value of I2C_TXFIFO_END_ADDR
+ * and I2C_TXFIFO_START_ADDR.
+ */
+
+#define I2C_TX_UPDATE    (BIT(21))
+#define I2C_TX_UPDATE_M  (I2C_TX_UPDATE_V << I2C_TX_UPDATE_S)
+#define I2C_TX_UPDATE_V  0x00000001
+#define I2C_TX_UPDATE_S  21
+
+/* I2C_RX_UPDATE : WO; bitpos: [20]; default: 0;
+ * Write 0 or 1 to I2C_RX_UPDATE to update the value of I2C_RXFIFO_END_ADDR
+ * and I2C_RXFIFO_START_ADDR.
+ */
+
+#define I2C_RX_UPDATE    (BIT(20))
+#define I2C_RX_UPDATE_M  (I2C_RX_UPDATE_V << I2C_RX_UPDATE_S)
+#define I2C_RX_UPDATE_V  0x00000001
+#define I2C_RX_UPDATE_S  20
+
+/* I2C_TXFIFO_END_ADDR : RO; bitpos: [19:15]; default: 0;
+ * This is the offset address of the last sent data, as described in
+ * I2C_NONFIFO_TX_THRES.
+ *
+ * The value refreshes when an I2C_TXFIFO_OVF_INT or I2C_TRANS_COMPLETE_INT
+ * interrupt is generated.
+ */
+
+#define I2C_TXFIFO_END_ADDR    0x0000001f
+#define I2C_TXFIFO_END_ADDR_M  (I2C_TXFIFO_END_ADDR_V << I2C_TXFIFO_END_ADDR_S)
+#define I2C_TXFIFO_END_ADDR_V  0x0000001f
+#define I2C_TXFIFO_END_ADDR_S  15
+
+/* I2C_TXFIFO_START_ADDR : RO; bitpos: [14:10]; default: 0;
+ * This is the offset address of the first sent data, as described in
+ * I2C_NONFIFO_TX_THRES.
+ */
+
+#define I2C_TXFIFO_START_ADDR    0x0000001f
+#define I2C_TXFIFO_START_ADDR_M  (I2C_TXFIFO_START_ADDR_V << I2C_TXFIFO_START_ADDR_S)
+#define I2C_TXFIFO_START_ADDR_V  0x0000001f
+#define I2C_TXFIFO_START_ADDR_S  10
+
+/* I2C_RXFIFO_END_ADDR : RO; bitpos: [9:5]; default: 0;
+ * This is the offset address of the last received data, as described in
+ * I2C_NONFIFO_RX_THRES. This value refreshes when an I2C_RXFIFO_UDF_INT or
+ * I2C_TRANS_COMPLETE_INT interrupt is generated.
+ */
+
+#define I2C_RXFIFO_END_ADDR    0x0000001f
+#define I2C_RXFIFO_END_ADDR_M  (I2C_RXFIFO_END_ADDR_V << I2C_RXFIFO_END_ADDR_S)
+#define I2C_RXFIFO_END_ADDR_V  0x0000001f
+#define I2C_RXFIFO_END_ADDR_S  5
+
+/* I2C_RXFIFO_START_ADDR : RO; bitpos: [4:0]; default: 0;
+ * This is the offset address of the last received data, as described in
+ * I2C_NONFIFO_RX_THRES.
+ */
+
+#define I2C_RXFIFO_START_ADDR    0x0000001f
+#define I2C_RXFIFO_START_ADDR_M  (I2C_RXFIFO_START_ADDR_V << I2C_RXFIFO_START_ADDR_S)
+#define I2C_RXFIFO_START_ADDR_V  0x0000001f
+#define I2C_RXFIFO_START_ADDR_S  0
+
+/* I2C_FIFO_CONF_REG register
+ * FIFO configuration register
+ */
+
+#define I2C_FIFO_CONF_REG(i) (REG_I2C_BASE(i) + 0x18)
+
+/* I2C_FIFO_PRT_EN : R/W; bitpos: [26]; default: 1;
+ * The control enable bit of FIFO pointer in non-FIFO mode. This bit
+ * controls the valid bits and the interrupts of TX/RX FIFO overflow,
+ * underflow, full and empty.
+ */
+
+#define I2C_FIFO_PRT_EN    (BIT(26))
+#define I2C_FIFO_PRT_EN_M  (I2C_FIFO_PRT_EN_V << I2C_FIFO_PRT_EN_S)
+#define I2C_FIFO_PRT_EN_V  0x00000001
+#define I2C_FIFO_PRT_EN_S  26
+
+/* I2C_NONFIFO_TX_THRES : R/W; bitpos: [25:20]; default: 21;
+ * When I2C sends more than I2C_NONFIFO_TX_THRES bytes of data, it will
+ * generate an I2C_TXFIFO_OVF_INT interrupt and update the current offset
+ * address of the sent data.
+ */
+
+#define I2C_NONFIFO_TX_THRES    0x0000003f
+#define I2C_NONFIFO_TX_THRES_M  (I2C_NONFIFO_TX_THRES_V << I2C_NONFIFO_TX_THRES_S)
+#define I2C_NONFIFO_TX_THRES_V  0x0000003f
+#define I2C_NONFIFO_TX_THRES_S  20
+
+/* I2C_NONFIFO_RX_THRES : R/W; bitpos: [19:14]; default: 21;
+ * When I2C receives more than I2C_NONFIFO_RX_THRES bytes of data, it will
+ * generate an I2C_RXFIFO_UDF_INT interrupt and update the current offset
+ * address of the received data.
+ */
+
+#define I2C_NONFIFO_RX_THRES    0x0000003f
+#define I2C_NONFIFO_RX_THRES_M  (I2C_NONFIFO_RX_THRES_V << I2C_NONFIFO_RX_THRES_S)
+#define I2C_NONFIFO_RX_THRES_V  0x0000003f
+#define I2C_NONFIFO_RX_THRES_S  14
+
+/* I2C_TX_FIFO_RST : R/W; bitpos: [13]; default: 0;
+ * Set this bit to reset TX FIFO.
+ */
+
+#define I2C_TX_FIFO_RST    (BIT(13))
+#define I2C_TX_FIFO_RST_M  (I2C_TX_FIFO_RST_V << I2C_TX_FIFO_RST_S)
+#define I2C_TX_FIFO_RST_V  0x00000001
+#define I2C_TX_FIFO_RST_S  13
+
+/* I2C_RX_FIFO_RST : R/W; bitpos: [12]; default: 0;
+ * Set this bit to reset RX FIFO.
+ */
+
+#define I2C_RX_FIFO_RST    (BIT(12))
+#define I2C_RX_FIFO_RST_M  (I2C_RX_FIFO_RST_V << I2C_RX_FIFO_RST_S)
+#define I2C_RX_FIFO_RST_V  0x00000001
+#define I2C_RX_FIFO_RST_S  12
+
+/* I2C_FIFO_ADDR_CFG_EN : R/W; bitpos: [11]; default: 0;
+ * When this bit is set to 1, the byte received after the I2C address byte
+ * represents the offset address in the I2C Slave RAM.
+ */
+
+#define I2C_FIFO_ADDR_CFG_EN    (BIT(11))
+#define I2C_FIFO_ADDR_CFG_EN_M  (I2C_FIFO_ADDR_CFG_EN_V << I2C_FIFO_ADDR_CFG_EN_S)
+#define I2C_FIFO_ADDR_CFG_EN_V  0x00000001
+#define I2C_FIFO_ADDR_CFG_EN_S  11
+
+/* I2C_NONFIFO_EN : R/W; bitpos: [10]; default: 0;
+ * Set this bit to enable APB non-FIFO mode.
+ */
+
+#define I2C_NONFIFO_EN    (BIT(10))
+#define I2C_NONFIFO_EN_M  (I2C_NONFIFO_EN_V << I2C_NONFIFO_EN_S)
+#define I2C_NONFIFO_EN_V  0x00000001
+#define I2C_NONFIFO_EN_S  10
+
+/* I2C_TXFIFO_WM_THRHD : R/W; bitpos: [9:5]; default: 4;
+ * The water mark threshold of TX FIFO in non-FIFO mode. When
+ * I2C_FIFO_PRT_EN is 1 and TX FIFO counter is smaller than
+ * I2C_TXFIFO_WM_THRHD[4:0], I2C_TXFIFO_WM_INT_RAW bit will be valid.
+ */
+
+#define I2C_TXFIFO_WM_THRHD    0x0000001f
+#define I2C_TXFIFO_WM_THRHD_M  (I2C_TXFIFO_WM_THRHD_V << I2C_TXFIFO_WM_THRHD_S)
+#define I2C_TXFIFO_WM_THRHD_V  0x0000001f
+#define I2C_TXFIFO_WM_THRHD_S  5
+
+/* I2C_RXFIFO_WM_THRHD : R/W; bitpos: [4:0]; default: 11;
+ * The water mark threshold of RX FIFO in non-FIFO mode. When
+ * I2C_FIFO_PRT_EN is 1 and RX FIFO counter is bigger than
+ * I2C_RXFIFO_WM_THRHD[4:0], I2C_RXFIFO_WM_INT_RAW bit will be valid.
+ */
+
+#define I2C_RXFIFO_WM_THRHD    0x0000001f
+#define I2C_RXFIFO_WM_THRHD_M  (I2C_RXFIFO_WM_THRHD_V << I2C_RXFIFO_WM_THRHD_S)
+#define I2C_RXFIFO_WM_THRHD_V  0x0000001f
+#define I2C_RXFIFO_WM_THRHD_S  0
+
+/* I2C_DATA_REG register
+ * RX FIFO read data
+ */
+
+#define I2C_DATA_REG(i) (REG_I2C_BASE(i) + 0x1c)
+
+/* I2C_FIFO_RDATA : RO; bitpos: [7:0]; default: 0;
+ * The value of RX FIFO read data.
+ */
+
+#define I2C_FIFO_RDATA    0x000000ff
+#define I2C_FIFO_RDATA_M  (I2C_FIFO_RDATA_V << I2C_FIFO_RDATA_S)
+#define I2C_FIFO_RDATA_V  0x000000ff
+#define I2C_FIFO_RDATA_S  0
+
+/* I2C_INT_RAW_REG register
+ * Raw interrupt status
+ */
+
+#define I2C_INT_RAW_REG(i) (REG_I2C_BASE(i) + 0x20)
+
+/* I2C_SLAVE_STRETCH_INT_RAW : RO; bitpos: [16]; default: 0;
+ * The raw interrupt bit for I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_SLAVE_STRETCH_INT_RAW    (BIT(16))
+#define I2C_SLAVE_STRETCH_INT_RAW_M  (I2C_SLAVE_STRETCH_INT_RAW_V << I2C_SLAVE_STRETCH_INT_RAW_S)
+#define I2C_SLAVE_STRETCH_INT_RAW_V  0x00000001
+#define I2C_SLAVE_STRETCH_INT_RAW_S  16
+
+/* I2C_DET_START_INT_RAW : RO; bitpos: [15]; default: 0;
+ * The raw interrupt bit for I2C_DET_START_INT interrupt.
+ */
+
+#define I2C_DET_START_INT_RAW    (BIT(15))
+#define I2C_DET_START_INT_RAW_M  (I2C_DET_START_INT_RAW_V << I2C_DET_START_INT_RAW_S)
+#define I2C_DET_START_INT_RAW_V  0x00000001
+#define I2C_DET_START_INT_RAW_S  15
+
+/* I2C_SCL_MAIN_ST_TO_INT_RAW : RO; bitpos: [14]; default: 0;
+ * The raw interrupt bit for I2C_SCL_MAIN_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_MAIN_ST_TO_INT_RAW    (BIT(14))
+#define I2C_SCL_MAIN_ST_TO_INT_RAW_M  (I2C_SCL_MAIN_ST_TO_INT_RAW_V << I2C_SCL_MAIN_ST_TO_INT_RAW_S)
+#define I2C_SCL_MAIN_ST_TO_INT_RAW_V  0x00000001
+#define I2C_SCL_MAIN_ST_TO_INT_RAW_S  14
+
+/* I2C_SCL_ST_TO_INT_RAW : RO; bitpos: [13]; default: 0;
+ * The raw interrupt bit for I2C_SCL_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_ST_TO_INT_RAW    (BIT(13))
+#define I2C_SCL_ST_TO_INT_RAW_M  (I2C_SCL_ST_TO_INT_RAW_V << I2C_SCL_ST_TO_INT_RAW_S)
+#define I2C_SCL_ST_TO_INT_RAW_V  0x00000001
+#define I2C_SCL_ST_TO_INT_RAW_S  13
+
+/* I2C_RXFIFO_UDF_INT_RAW : RO; bitpos: [12]; default: 0;
+ * The raw interrupt bit for I2C_RXFIFO_UDF_INT  interrupt.
+ */
+
+#define I2C_RXFIFO_UDF_INT_RAW    (BIT(12))
+#define I2C_RXFIFO_UDF_INT_RAW_M  (I2C_RXFIFO_UDF_INT_RAW_V << I2C_RXFIFO_UDF_INT_RAW_S)
+#define I2C_RXFIFO_UDF_INT_RAW_V  0x00000001
+#define I2C_RXFIFO_UDF_INT_RAW_S  12
+
+/* I2C_TXFIFO_OVF_INT_RAW : RO; bitpos: [11]; default: 0;
+ * The raw interrupt bit for I2C_TXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_TXFIFO_OVF_INT_RAW    (BIT(11))
+#define I2C_TXFIFO_OVF_INT_RAW_M  (I2C_TXFIFO_OVF_INT_RAW_V << I2C_TXFIFO_OVF_INT_RAW_S)
+#define I2C_TXFIFO_OVF_INT_RAW_V  0x00000001
+#define I2C_TXFIFO_OVF_INT_RAW_S  11
+
+/* I2C_NACK_INT_RAW : RO; bitpos: [10]; default: 0;
+ * The raw interrupt bit for I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_NACK_INT_RAW    (BIT(10))
+#define I2C_NACK_INT_RAW_M  (I2C_NACK_INT_RAW_V << I2C_NACK_INT_RAW_S)
+#define I2C_NACK_INT_RAW_V  0x00000001
+#define I2C_NACK_INT_RAW_S  10
+
+/* I2C_TRANS_START_INT_RAW : RO; bitpos: [9]; default: 0;
+ * The raw interrupt bit for the I2C_TRANS_START_INT interrupt.
+ */
+
+#define I2C_TRANS_START_INT_RAW    (BIT(9))
+#define I2C_TRANS_START_INT_RAW_M  (I2C_TRANS_START_INT_RAW_V << I2C_TRANS_START_INT_RAW_S)
+#define I2C_TRANS_START_INT_RAW_V  0x00000001
+#define I2C_TRANS_START_INT_RAW_S  9
+
+/* I2C_TIME_OUT_INT_RAW : RO; bitpos: [8]; default: 0;
+ * The raw interrupt bit for the I2C_TIME_OUT_INT interrupt.
+ */
+
+#define I2C_TIME_OUT_INT_RAW    (BIT(8))
+#define I2C_TIME_OUT_INT_RAW_M  (I2C_TIME_OUT_INT_RAW_V << I2C_TIME_OUT_INT_RAW_S)
+#define I2C_TIME_OUT_INT_RAW_V  0x00000001
+#define I2C_TIME_OUT_INT_RAW_S  8
+
+/* I2C_TRANS_COMPLETE_INT_RAW : RO; bitpos: [7]; default: 0;
+ * The raw interrupt bit for the I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_TRANS_COMPLETE_INT_RAW    (BIT(7))
+#define I2C_TRANS_COMPLETE_INT_RAW_M  (I2C_TRANS_COMPLETE_INT_RAW_V << I2C_TRANS_COMPLETE_INT_RAW_S)
+#define I2C_TRANS_COMPLETE_INT_RAW_V  0x00000001
+#define I2C_TRANS_COMPLETE_INT_RAW_S  7
+
+/* I2C_MST_TXFIFO_UDF_INT_RAW : RO; bitpos: [6]; default: 0;
+ * The raw interrupt bit for I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_MST_TXFIFO_UDF_INT_RAW    (BIT(6))
+#define I2C_MST_TXFIFO_UDF_INT_RAW_M  (I2C_MST_TXFIFO_UDF_INT_RAW_V << I2C_MST_TXFIFO_UDF_INT_RAW_S)
+#define I2C_MST_TXFIFO_UDF_INT_RAW_V  0x00000001
+#define I2C_MST_TXFIFO_UDF_INT_RAW_S  6
+
+/* I2C_ARBITRATION_LOST_INT_RAW : RO; bitpos: [5]; default: 0;
+ * The raw interrupt bit for the I2C_ARBITRATION_LOST_INT interrupt.
+ */
+
+#define I2C_ARBITRATION_LOST_INT_RAW    (BIT(5))
+#define I2C_ARBITRATION_LOST_INT_RAW_M  (I2C_ARBITRATION_LOST_INT_RAW_V << I2C_ARBITRATION_LOST_INT_RAW_S)
+#define I2C_ARBITRATION_LOST_INT_RAW_V  0x00000001
+#define I2C_ARBITRATION_LOST_INT_RAW_S  5
+
+/* I2C_BYTE_TRANS_DONE_INT_RAW : RO; bitpos: [4]; default: 0;
+ * The raw interrupt bit for the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_BYTE_TRANS_DONE_INT_RAW    (BIT(4))
+#define I2C_BYTE_TRANS_DONE_INT_RAW_M  (I2C_BYTE_TRANS_DONE_INT_RAW_V << I2C_BYTE_TRANS_DONE_INT_RAW_S)
+#define I2C_BYTE_TRANS_DONE_INT_RAW_V  0x00000001
+#define I2C_BYTE_TRANS_DONE_INT_RAW_S  4
+
+/* I2C_END_DETECT_INT_RAW : RO; bitpos: [3]; default: 0;
+ * The raw interrupt bit for the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_END_DETECT_INT_RAW    (BIT(3))
+#define I2C_END_DETECT_INT_RAW_M  (I2C_END_DETECT_INT_RAW_V << I2C_END_DETECT_INT_RAW_S)
+#define I2C_END_DETECT_INT_RAW_V  0x00000001
+#define I2C_END_DETECT_INT_RAW_S  3
+
+/* I2C_RXFIFO_OVF_INT_RAW : RO; bitpos: [2]; default: 0;
+ * The raw interrupt bit for I2C_RXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_RXFIFO_OVF_INT_RAW    (BIT(2))
+#define I2C_RXFIFO_OVF_INT_RAW_M  (I2C_RXFIFO_OVF_INT_RAW_V << I2C_RXFIFO_OVF_INT_RAW_S)
+#define I2C_RXFIFO_OVF_INT_RAW_V  0x00000001
+#define I2C_RXFIFO_OVF_INT_RAW_S  2
+
+/* I2C_TXFIFO_WM_INT_RAW : RO; bitpos: [1]; default: 0;
+ * The raw interrupt bit for I2C_TXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_TXFIFO_WM_INT_RAW    (BIT(1))
+#define I2C_TXFIFO_WM_INT_RAW_M  (I2C_TXFIFO_WM_INT_RAW_V << I2C_TXFIFO_WM_INT_RAW_S)
+#define I2C_TXFIFO_WM_INT_RAW_V  0x00000001
+#define I2C_TXFIFO_WM_INT_RAW_S  1
+
+/* I2C_RXFIFO_WM_INT_RAW : RO; bitpos: [0]; default: 0;
+ * The raw interrupt bit for I2C_RXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_RXFIFO_WM_INT_RAW    (BIT(0))
+#define I2C_RXFIFO_WM_INT_RAW_M  (I2C_RXFIFO_WM_INT_RAW_V << I2C_RXFIFO_WM_INT_RAW_S)
+#define I2C_RXFIFO_WM_INT_RAW_V  0x00000001
+#define I2C_RXFIFO_WM_INT_RAW_S  0
+
+/* I2C_INT_CLR_REG register
+ * Interrupt clear bits
+ */
+
+#define I2C_INT_CLR_REG(i) (REG_I2C_BASE(i) + 0x24)
+
+/* I2C_SLAVE_STRETCH_INT_CLR : WO; bitpos: [16]; default: 0;
+ * Set this bit to clear I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_SLAVE_STRETCH_INT_CLR    (BIT(16))
+#define I2C_SLAVE_STRETCH_INT_CLR_M  (I2C_SLAVE_STRETCH_INT_CLR_V << I2C_SLAVE_STRETCH_INT_CLR_S)
+#define I2C_SLAVE_STRETCH_INT_CLR_V  0x00000001
+#define I2C_SLAVE_STRETCH_INT_CLR_S  16
+
+/* I2C_DET_START_INT_CLR : WO; bitpos: [15]; default: 0;
+ * Set this bit to clear I2C_DET_START_INT interrupt.
+ */
+
+#define I2C_DET_START_INT_CLR    (BIT(15))
+#define I2C_DET_START_INT_CLR_M  (I2C_DET_START_INT_CLR_V << I2C_DET_START_INT_CLR_S)
+#define I2C_DET_START_INT_CLR_V  0x00000001
+#define I2C_DET_START_INT_CLR_S  15
+
+/* I2C_SCL_MAIN_ST_TO_INT_CLR : WO; bitpos: [14]; default: 0;
+ * Set this bit to clear I2C_SCL_MAIN_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_MAIN_ST_TO_INT_CLR    (BIT(14))
+#define I2C_SCL_MAIN_ST_TO_INT_CLR_M  (I2C_SCL_MAIN_ST_TO_INT_CLR_V << I2C_SCL_MAIN_ST_TO_INT_CLR_S)
+#define I2C_SCL_MAIN_ST_TO_INT_CLR_V  0x00000001
+#define I2C_SCL_MAIN_ST_TO_INT_CLR_S  14
+
+/* I2C_SCL_ST_TO_INT_CLR : WO; bitpos: [13]; default: 0;
+ * Set this bit to clear I2C_SCL_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_ST_TO_INT_CLR    (BIT(13))
+#define I2C_SCL_ST_TO_INT_CLR_M  (I2C_SCL_ST_TO_INT_CLR_V << I2C_SCL_ST_TO_INT_CLR_S)
+#define I2C_SCL_ST_TO_INT_CLR_V  0x00000001
+#define I2C_SCL_ST_TO_INT_CLR_S  13
+
+/* I2C_RXFIFO_UDF_INT_CLR : WO; bitpos: [12]; default: 0;
+ * Set this bit to clear I2C_RXFIFO_UDF_INT  interrupt.
+ */
+
+#define I2C_RXFIFO_UDF_INT_CLR    (BIT(12))
+#define I2C_RXFIFO_UDF_INT_CLR_M  (I2C_RXFIFO_UDF_INT_CLR_V << I2C_RXFIFO_UDF_INT_CLR_S)
+#define I2C_RXFIFO_UDF_INT_CLR_V  0x00000001
+#define I2C_RXFIFO_UDF_INT_CLR_S  12
+
+/* I2C_TXFIFO_OVF_INT_CLR : WO; bitpos: [11]; default: 0;
+ * Set this bit to clear I2C_TXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_TXFIFO_OVF_INT_CLR    (BIT(11))
+#define I2C_TXFIFO_OVF_INT_CLR_M  (I2C_TXFIFO_OVF_INT_CLR_V << I2C_TXFIFO_OVF_INT_CLR_S)
+#define I2C_TXFIFO_OVF_INT_CLR_V  0x00000001
+#define I2C_TXFIFO_OVF_INT_CLR_S  11
+
+/* I2C_NACK_INT_CLR : WO; bitpos: [10]; default: 0;
+ * Set this bit to clear I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_NACK_INT_CLR    (BIT(10))
+#define I2C_NACK_INT_CLR_M  (I2C_NACK_INT_CLR_V << I2C_NACK_INT_CLR_S)
+#define I2C_NACK_INT_CLR_V  0x00000001
+#define I2C_NACK_INT_CLR_S  10
+
+/* I2C_TRANS_START_INT_CLR : WO; bitpos: [9]; default: 0;
+ * Set this bit to clear the I2C_TRANS_START_INT interrupt.
+ */
+
+#define I2C_TRANS_START_INT_CLR    (BIT(9))
+#define I2C_TRANS_START_INT_CLR_M  (I2C_TRANS_START_INT_CLR_V << I2C_TRANS_START_INT_CLR_S)
+#define I2C_TRANS_START_INT_CLR_V  0x00000001
+#define I2C_TRANS_START_INT_CLR_S  9
+
+/* I2C_TIME_OUT_INT_CLR : WO; bitpos: [8]; default: 0;
+ * Set this bit to clear the I2C_TIME_OUT_INT interrupt.
+ */
+
+#define I2C_TIME_OUT_INT_CLR    (BIT(8))
+#define I2C_TIME_OUT_INT_CLR_M  (I2C_TIME_OUT_INT_CLR_V << I2C_TIME_OUT_INT_CLR_S)
+#define I2C_TIME_OUT_INT_CLR_V  0x00000001
+#define I2C_TIME_OUT_INT_CLR_S  8
+
+/* I2C_TRANS_COMPLETE_INT_CLR : WO; bitpos: [7]; default: 0;
+ * Set this bit to clear the I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_TRANS_COMPLETE_INT_CLR    (BIT(7))
+#define I2C_TRANS_COMPLETE_INT_CLR_M  (I2C_TRANS_COMPLETE_INT_CLR_V << I2C_TRANS_COMPLETE_INT_CLR_S)
+#define I2C_TRANS_COMPLETE_INT_CLR_V  0x00000001
+#define I2C_TRANS_COMPLETE_INT_CLR_S  7
+
+/* I2C_MST_TXFIFO_UDF_INT_CLR : WO; bitpos: [6]; default: 0;
+ * Set this bit to clear I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_MST_TXFIFO_UDF_INT_CLR    (BIT(6))
+#define I2C_MST_TXFIFO_UDF_INT_CLR_M  (I2C_MST_TXFIFO_UDF_INT_CLR_V << I2C_MST_TXFIFO_UDF_INT_CLR_S)
+#define I2C_MST_TXFIFO_UDF_INT_CLR_V  0x00000001
+#define I2C_MST_TXFIFO_UDF_INT_CLR_S  6
+
+/* I2C_ARBITRATION_LOST_INT_CLR : WO; bitpos: [5]; default: 0;
+ * Set this bit to clear the I2C_ARBITRATION_LOST_INT interrupt.
+ */
+
+#define I2C_ARBITRATION_LOST_INT_CLR    (BIT(5))
+#define I2C_ARBITRATION_LOST_INT_CLR_M  (I2C_ARBITRATION_LOST_INT_CLR_V << I2C_ARBITRATION_LOST_INT_CLR_S)
+#define I2C_ARBITRATION_LOST_INT_CLR_V  0x00000001
+#define I2C_ARBITRATION_LOST_INT_CLR_S  5
+
+/* I2C_BYTE_TRANS_DONE_INT_CLR : WO; bitpos: [4]; default: 0;
+ * Set this bit to clear the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_BYTE_TRANS_DONE_INT_CLR    (BIT(4))
+#define I2C_BYTE_TRANS_DONE_INT_CLR_M  (I2C_BYTE_TRANS_DONE_INT_CLR_V << I2C_BYTE_TRANS_DONE_INT_CLR_S)
+#define I2C_BYTE_TRANS_DONE_INT_CLR_V  0x00000001
+#define I2C_BYTE_TRANS_DONE_INT_CLR_S  4
+
+/* I2C_END_DETECT_INT_CLR : WO; bitpos: [3]; default: 0;
+ * Set this bit to clear the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_END_DETECT_INT_CLR    (BIT(3))
+#define I2C_END_DETECT_INT_CLR_M  (I2C_END_DETECT_INT_CLR_V << I2C_END_DETECT_INT_CLR_S)
+#define I2C_END_DETECT_INT_CLR_V  0x00000001
+#define I2C_END_DETECT_INT_CLR_S  3
+
+/* I2C_RXFIFO_OVF_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear I2C_RXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_RXFIFO_OVF_INT_CLR    (BIT(2))
+#define I2C_RXFIFO_OVF_INT_CLR_M  (I2C_RXFIFO_OVF_INT_CLR_V << I2C_RXFIFO_OVF_INT_CLR_S)
+#define I2C_RXFIFO_OVF_INT_CLR_V  0x00000001
+#define I2C_RXFIFO_OVF_INT_CLR_S  2
+
+/* I2C_TXFIFO_WM_INT_CLR : WO; bitpos: [1]; default: 0;
+ * Set this bit to clear I2C_TXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_TXFIFO_WM_INT_CLR    (BIT(1))
+#define I2C_TXFIFO_WM_INT_CLR_M  (I2C_TXFIFO_WM_INT_CLR_V << I2C_TXFIFO_WM_INT_CLR_S)
+#define I2C_TXFIFO_WM_INT_CLR_V  0x00000001
+#define I2C_TXFIFO_WM_INT_CLR_S  1
+
+/* I2C_RXFIFO_WM_INT_CLR : WO; bitpos: [0]; default: 0;
+ * Set this bit to clear I2C_RXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_RXFIFO_WM_INT_CLR    (BIT(0))
+#define I2C_RXFIFO_WM_INT_CLR_M  (I2C_RXFIFO_WM_INT_CLR_V << I2C_RXFIFO_WM_INT_CLR_S)
+#define I2C_RXFIFO_WM_INT_CLR_V  0x00000001
+#define I2C_RXFIFO_WM_INT_CLR_S  0
+
+/* I2C_INT_ENA_REG register
+ * Interrupt enable bits
+ */
+
+#define I2C_INT_ENA_REG(i) (REG_I2C_BASE(i) + 0x28)
+
+/* I2C_SLAVE_STRETCH_INT_ENA : R/W; bitpos: [16]; default: 0;
+ * The raw interrupt bit for I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_SLAVE_STRETCH_INT_ENA    (BIT(16))
+#define I2C_SLAVE_STRETCH_INT_ENA_M  (I2C_SLAVE_STRETCH_INT_ENA_V << I2C_SLAVE_STRETCH_INT_ENA_S)
+#define I2C_SLAVE_STRETCH_INT_ENA_V  0x00000001
+#define I2C_SLAVE_STRETCH_INT_ENA_S  16
+
+/* I2C_DET_START_INT_ENA : R/W; bitpos: [15]; default: 0;
+ * The raw interrupt bit for I2C_DET_START_INT interrupt.
+ */
+
+#define I2C_DET_START_INT_ENA    (BIT(15))
+#define I2C_DET_START_INT_ENA_M  (I2C_DET_START_INT_ENA_V << I2C_DET_START_INT_ENA_S)
+#define I2C_DET_START_INT_ENA_V  0x00000001
+#define I2C_DET_START_INT_ENA_S  15
+
+/* I2C_SCL_MAIN_ST_TO_INT_ENA : R/W; bitpos: [14]; default: 0;
+ * The raw interrupt bit for I2C_SCL_MAIN_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_MAIN_ST_TO_INT_ENA    (BIT(14))
+#define I2C_SCL_MAIN_ST_TO_INT_ENA_M  (I2C_SCL_MAIN_ST_TO_INT_ENA_V << I2C_SCL_MAIN_ST_TO_INT_ENA_S)
+#define I2C_SCL_MAIN_ST_TO_INT_ENA_V  0x00000001
+#define I2C_SCL_MAIN_ST_TO_INT_ENA_S  14
+
+/* I2C_SCL_ST_TO_INT_ENA : R/W; bitpos: [13]; default: 0;
+ * The raw interrupt bit for I2C_SCL_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_ST_TO_INT_ENA    (BIT(13))
+#define I2C_SCL_ST_TO_INT_ENA_M  (I2C_SCL_ST_TO_INT_ENA_V << I2C_SCL_ST_TO_INT_ENA_S)
+#define I2C_SCL_ST_TO_INT_ENA_V  0x00000001
+#define I2C_SCL_ST_TO_INT_ENA_S  13
+
+/* I2C_RXFIFO_UDF_INT_ENA : R/W; bitpos: [12]; default: 0;
+ * The raw interrupt bit for I2C_RXFIFO_UDF_INT  interrupt.
+ */
+
+#define I2C_RXFIFO_UDF_INT_ENA    (BIT(12))
+#define I2C_RXFIFO_UDF_INT_ENA_M  (I2C_RXFIFO_UDF_INT_ENA_V << I2C_RXFIFO_UDF_INT_ENA_S)
+#define I2C_RXFIFO_UDF_INT_ENA_V  0x00000001
+#define I2C_RXFIFO_UDF_INT_ENA_S  12
+
+/* I2C_TXFIFO_OVF_INT_ENA : R/W; bitpos: [11]; default: 0;
+ * The raw interrupt bit for I2C_TXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_TXFIFO_OVF_INT_ENA    (BIT(11))
+#define I2C_TXFIFO_OVF_INT_ENA_M  (I2C_TXFIFO_OVF_INT_ENA_V << I2C_TXFIFO_OVF_INT_ENA_S)
+#define I2C_TXFIFO_OVF_INT_ENA_V  0x00000001
+#define I2C_TXFIFO_OVF_INT_ENA_S  11
+
+/* I2C_NACK_INT_ENA : R/W; bitpos: [10]; default: 0;
+ * The raw interrupt bit for I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_NACK_INT_ENA    (BIT(10))
+#define I2C_NACK_INT_ENA_M  (I2C_NACK_INT_ENA_V << I2C_NACK_INT_ENA_S)
+#define I2C_NACK_INT_ENA_V  0x00000001
+#define I2C_NACK_INT_ENA_S  10
+
+/* I2C_TRANS_START_INT_ENA : R/W; bitpos: [9]; default: 0;
+ * The raw interrupt bit for the I2C_TRANS_START_INT interrupt.
+ */
+
+#define I2C_TRANS_START_INT_ENA    (BIT(9))
+#define I2C_TRANS_START_INT_ENA_M  (I2C_TRANS_START_INT_ENA_V << I2C_TRANS_START_INT_ENA_S)
+#define I2C_TRANS_START_INT_ENA_V  0x00000001
+#define I2C_TRANS_START_INT_ENA_S  9
+
+/* I2C_TIME_OUT_INT_ENA : R/W; bitpos: [8]; default: 0;
+ * The raw interrupt bit for the I2C_TIME_OUT_INT interrupt.
+ */
+
+#define I2C_TIME_OUT_INT_ENA    (BIT(8))
+#define I2C_TIME_OUT_INT_ENA_M  (I2C_TIME_OUT_INT_ENA_V << I2C_TIME_OUT_INT_ENA_S)
+#define I2C_TIME_OUT_INT_ENA_V  0x00000001
+#define I2C_TIME_OUT_INT_ENA_S  8
+
+/* I2C_TRANS_COMPLETE_INT_ENA : R/W; bitpos: [7]; default: 0;
+ * The raw interrupt bit for the I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_TRANS_COMPLETE_INT_ENA    (BIT(7))
+#define I2C_TRANS_COMPLETE_INT_ENA_M  (I2C_TRANS_COMPLETE_INT_ENA_V << I2C_TRANS_COMPLETE_INT_ENA_S)
+#define I2C_TRANS_COMPLETE_INT_ENA_V  0x00000001
+#define I2C_TRANS_COMPLETE_INT_ENA_S  7
+
+/* I2C_MST_TXFIFO_UDF_INT_ENA : R/W; bitpos: [6]; default: 0;
+ * The raw interrupt bit for I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_MST_TXFIFO_UDF_INT_ENA    (BIT(6))
+#define I2C_MST_TXFIFO_UDF_INT_ENA_M  (I2C_MST_TXFIFO_UDF_INT_ENA_V << I2C_MST_TXFIFO_UDF_INT_ENA_S)
+#define I2C_MST_TXFIFO_UDF_INT_ENA_V  0x00000001
+#define I2C_MST_TXFIFO_UDF_INT_ENA_S  6
+
+/* I2C_ARBITRATION_LOST_INT_ENA : R/W; bitpos: [5]; default: 0;
+ * The raw interrupt bit for the I2C_ARBITRATION_LOST_INT interrupt.
+ */
+
+#define I2C_ARBITRATION_LOST_INT_ENA    (BIT(5))
+#define I2C_ARBITRATION_LOST_INT_ENA_M  (I2C_ARBITRATION_LOST_INT_ENA_V << I2C_ARBITRATION_LOST_INT_ENA_S)
+#define I2C_ARBITRATION_LOST_INT_ENA_V  0x00000001
+#define I2C_ARBITRATION_LOST_INT_ENA_S  5
+
+/* I2C_BYTE_TRANS_DONE_INT_ENA : R/W; bitpos: [4]; default: 0;
+ * The raw interrupt bit for the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_BYTE_TRANS_DONE_INT_ENA    (BIT(4))
+#define I2C_BYTE_TRANS_DONE_INT_ENA_M  (I2C_BYTE_TRANS_DONE_INT_ENA_V << I2C_BYTE_TRANS_DONE_INT_ENA_S)
+#define I2C_BYTE_TRANS_DONE_INT_ENA_V  0x00000001
+#define I2C_BYTE_TRANS_DONE_INT_ENA_S  4
+
+/* I2C_END_DETECT_INT_ENA : R/W; bitpos: [3]; default: 0;
+ * The raw interrupt bit for the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_END_DETECT_INT_ENA    (BIT(3))
+#define I2C_END_DETECT_INT_ENA_M  (I2C_END_DETECT_INT_ENA_V << I2C_END_DETECT_INT_ENA_S)
+#define I2C_END_DETECT_INT_ENA_V  0x00000001
+#define I2C_END_DETECT_INT_ENA_S  3
+
+/* I2C_RXFIFO_OVF_INT_ENA : R/W; bitpos: [2]; default: 0;
+ * The raw interrupt bit for I2C_RXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_RXFIFO_OVF_INT_ENA    (BIT(2))
+#define I2C_RXFIFO_OVF_INT_ENA_M  (I2C_RXFIFO_OVF_INT_ENA_V << I2C_RXFIFO_OVF_INT_ENA_S)
+#define I2C_RXFIFO_OVF_INT_ENA_V  0x00000001
+#define I2C_RXFIFO_OVF_INT_ENA_S  2
+
+/* I2C_TXFIFO_WM_INT_ENA : R/W; bitpos: [1]; default: 0;
+ * The raw interrupt bit for I2C_TXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_TXFIFO_WM_INT_ENA    (BIT(1))
+#define I2C_TXFIFO_WM_INT_ENA_M  (I2C_TXFIFO_WM_INT_ENA_V << I2C_TXFIFO_WM_INT_ENA_S)
+#define I2C_TXFIFO_WM_INT_ENA_V  0x00000001
+#define I2C_TXFIFO_WM_INT_ENA_S  1
+
+/* I2C_RXFIFO_WM_INT_ENA : R/W; bitpos: [0]; default: 0;
+ * The raw interrupt bit for I2C_RXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_RXFIFO_WM_INT_ENA    (BIT(0))
+#define I2C_RXFIFO_WM_INT_ENA_M  (I2C_RXFIFO_WM_INT_ENA_V << I2C_RXFIFO_WM_INT_ENA_S)
+#define I2C_RXFIFO_WM_INT_ENA_V  0x00000001
+#define I2C_RXFIFO_WM_INT_ENA_S  0
+
+/* I2C_INT_STATUS_REG register
+ * Status of captured I2C communication events
+ */
+
+#define I2C_INT_STATUS_REG(i) (REG_I2C_BASE(i) + 0x2c)
+
+/* I2C_SLAVE_STRETCH_INT_ST : RO; bitpos: [16]; default: 0;
+ * The masked interrupt status bit for I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_SLAVE_STRETCH_INT_ST    (BIT(16))
+#define I2C_SLAVE_STRETCH_INT_ST_M  (I2C_SLAVE_STRETCH_INT_ST_V << I2C_SLAVE_STRETCH_INT_ST_S)
+#define I2C_SLAVE_STRETCH_INT_ST_V  0x00000001
+#define I2C_SLAVE_STRETCH_INT_ST_S  16
+
+/* I2C_DET_START_INT_ST : RO; bitpos: [15]; default: 0;
+ * The masked interrupt status bit for I2C_DET_START_INT interrupt.
+ */
+
+#define I2C_DET_START_INT_ST    (BIT(15))
+#define I2C_DET_START_INT_ST_M  (I2C_DET_START_INT_ST_V << I2C_DET_START_INT_ST_S)
+#define I2C_DET_START_INT_ST_V  0x00000001
+#define I2C_DET_START_INT_ST_S  15
+
+/* I2C_SCL_MAIN_ST_TO_INT_ST : RO; bitpos: [14]; default: 0;
+ * The masked interrupt status bit for I2C_SCL_MAIN_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_MAIN_ST_TO_INT_ST    (BIT(14))
+#define I2C_SCL_MAIN_ST_TO_INT_ST_M  (I2C_SCL_MAIN_ST_TO_INT_ST_V << I2C_SCL_MAIN_ST_TO_INT_ST_S)
+#define I2C_SCL_MAIN_ST_TO_INT_ST_V  0x00000001
+#define I2C_SCL_MAIN_ST_TO_INT_ST_S  14
+
+/* I2C_SCL_ST_TO_INT_ST : RO; bitpos: [13]; default: 0;
+ * The masked interrupt status bit for I2C_SCL_ST_TO_INT interrupt.
+ */
+
+#define I2C_SCL_ST_TO_INT_ST    (BIT(13))
+#define I2C_SCL_ST_TO_INT_ST_M  (I2C_SCL_ST_TO_INT_ST_V << I2C_SCL_ST_TO_INT_ST_S)
+#define I2C_SCL_ST_TO_INT_ST_V  0x00000001
+#define I2C_SCL_ST_TO_INT_ST_S  13
+
+/* I2C_RXFIFO_UDF_INT_ST : RO; bitpos: [12]; default: 0;
+ * The masked interrupt status bit for I2C_RXFIFO_UDF_INT  interrupt.
+ */
+
+#define I2C_RXFIFO_UDF_INT_ST    (BIT(12))
+#define I2C_RXFIFO_UDF_INT_ST_M  (I2C_RXFIFO_UDF_INT_ST_V << I2C_RXFIFO_UDF_INT_ST_S)
+#define I2C_RXFIFO_UDF_INT_ST_V  0x00000001
+#define I2C_RXFIFO_UDF_INT_ST_S  12
+
+/* I2C_TXFIFO_OVF_INT_ST : RO; bitpos: [11]; default: 0;
+ * The masked interrupt status bit for I2C_TXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_TXFIFO_OVF_INT_ST    (BIT(11))
+#define I2C_TXFIFO_OVF_INT_ST_M  (I2C_TXFIFO_OVF_INT_ST_V << I2C_TXFIFO_OVF_INT_ST_S)
+#define I2C_TXFIFO_OVF_INT_ST_V  0x00000001
+#define I2C_TXFIFO_OVF_INT_ST_S  11
+
+/* I2C_NACK_INT_ST : RO; bitpos: [10]; default: 0;
+ * The masked interrupt status bit for I2C_SLAVE_STRETCH_INT interrupt.
+ */
+
+#define I2C_NACK_INT_ST    (BIT(10))
+#define I2C_NACK_INT_ST_M  (I2C_NACK_INT_ST_V << I2C_NACK_INT_ST_S)
+#define I2C_NACK_INT_ST_V  0x00000001
+#define I2C_NACK_INT_ST_S  10
+
+/* I2C_TRANS_START_INT_ST : RO; bitpos: [9]; default: 0;
+ * The masked interrupt status bit for the I2C_TRANS_START_INT interrupt.
+ */
+
+#define I2C_TRANS_START_INT_ST    (BIT(9))
+#define I2C_TRANS_START_INT_ST_M  (I2C_TRANS_START_INT_ST_V << I2C_TRANS_START_INT_ST_S)
+#define I2C_TRANS_START_INT_ST_V  0x00000001
+#define I2C_TRANS_START_INT_ST_S  9
+
+/* I2C_TIME_OUT_INT_ST : RO; bitpos: [8]; default: 0;
+ * The masked interrupt status bit for the I2C_TIME_OUT_INT interrupt.
+ */
+
+#define I2C_TIME_OUT_INT_ST    (BIT(8))
+#define I2C_TIME_OUT_INT_ST_M  (I2C_TIME_OUT_INT_ST_V << I2C_TIME_OUT_INT_ST_S)
+#define I2C_TIME_OUT_INT_ST_V  0x00000001
+#define I2C_TIME_OUT_INT_ST_S  8
+
+/* I2C_TRANS_COMPLETE_INT_ST : RO; bitpos: [7]; default: 0;
+ * The masked interrupt status bit for the I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_TRANS_COMPLETE_INT_ST    (BIT(7))
+#define I2C_TRANS_COMPLETE_INT_ST_M  (I2C_TRANS_COMPLETE_INT_ST_V << I2C_TRANS_COMPLETE_INT_ST_S)
+#define I2C_TRANS_COMPLETE_INT_ST_V  0x00000001
+#define I2C_TRANS_COMPLETE_INT_ST_S  7
+
+/* I2C_MST_TXFIFO_UDF_INT_ST : RO; bitpos: [6]; default: 0;
+ * The masked interrupt status bit for I2C_TRANS_COMPLETE_INT interrupt.
+ */
+
+#define I2C_MST_TXFIFO_UDF_INT_ST    (BIT(6))
+#define I2C_MST_TXFIFO_UDF_INT_ST_M  (I2C_MST_TXFIFO_UDF_INT_ST_V << I2C_MST_TXFIFO_UDF_INT_ST_S)
+#define I2C_MST_TXFIFO_UDF_INT_ST_V  0x00000001
+#define I2C_MST_TXFIFO_UDF_INT_ST_S  6
+
+/* I2C_ARBITRATION_LOST_INT_ST : RO; bitpos: [5]; default: 0;
+ * The masked interrupt status bit for the I2C_ARBITRATION_LOST_INT
+ * interrupt.
+ */
+
+#define I2C_ARBITRATION_LOST_INT_ST    (BIT(5))
+#define I2C_ARBITRATION_LOST_INT_ST_M  (I2C_ARBITRATION_LOST_INT_ST_V << I2C_ARBITRATION_LOST_INT_ST_S)
+#define I2C_ARBITRATION_LOST_INT_ST_V  0x00000001
+#define I2C_ARBITRATION_LOST_INT_ST_S  5
+
+/* I2C_BYTE_TRANS_DONE_INT_ST : RO; bitpos: [4]; default: 0;
+ * The masked interrupt status bit for the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_BYTE_TRANS_DONE_INT_ST    (BIT(4))
+#define I2C_BYTE_TRANS_DONE_INT_ST_M  (I2C_BYTE_TRANS_DONE_INT_ST_V << I2C_BYTE_TRANS_DONE_INT_ST_S)
+#define I2C_BYTE_TRANS_DONE_INT_ST_V  0x00000001
+#define I2C_BYTE_TRANS_DONE_INT_ST_S  4
+
+/* I2C_END_DETECT_INT_ST : RO; bitpos: [3]; default: 0;
+ * The masked interrupt status bit for the I2C_END_DETECT_INT interrupt.
+ */
+
+#define I2C_END_DETECT_INT_ST    (BIT(3))
+#define I2C_END_DETECT_INT_ST_M  (I2C_END_DETECT_INT_ST_V << I2C_END_DETECT_INT_ST_S)
+#define I2C_END_DETECT_INT_ST_V  0x00000001
+#define I2C_END_DETECT_INT_ST_S  3
+
+/* I2C_RXFIFO_OVF_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for I2C_RXFIFO_OVF_INT interrupt.
+ */
+
+#define I2C_RXFIFO_OVF_INT_ST    (BIT(2))
+#define I2C_RXFIFO_OVF_INT_ST_M  (I2C_RXFIFO_OVF_INT_ST_V << I2C_RXFIFO_OVF_INT_ST_S)
+#define I2C_RXFIFO_OVF_INT_ST_V  0x00000001
+#define I2C_RXFIFO_OVF_INT_ST_S  2
+
+/* I2C_TXFIFO_WM_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for I2C_TXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_TXFIFO_WM_INT_ST    (BIT(1))
+#define I2C_TXFIFO_WM_INT_ST_M  (I2C_TXFIFO_WM_INT_ST_V << I2C_TXFIFO_WM_INT_ST_S)
+#define I2C_TXFIFO_WM_INT_ST_V  0x00000001
+#define I2C_TXFIFO_WM_INT_ST_S  1
+
+/* I2C_RXFIFO_WM_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for I2C_RXFIFO_WM_INT interrupt.
+ */
+
+#define I2C_RXFIFO_WM_INT_ST    (BIT(0))
+#define I2C_RXFIFO_WM_INT_ST_M  (I2C_RXFIFO_WM_INT_ST_V << I2C_RXFIFO_WM_INT_ST_S)
+#define I2C_RXFIFO_WM_INT_ST_V  0x00000001
+#define I2C_RXFIFO_WM_INT_ST_S  0
+
+/* I2C_SDA_HOLD_REG register
+ * Configures the hold time after a negative SCL edge
+ */
+
+#define I2C_SDA_HOLD_REG(i) (REG_I2C_BASE(i) + 0x30)
+
+/* I2C_SDA_HOLD_TIME : R/W; bitpos: [9:0]; default: 0;
+ * This register is used to configure the interval between changing the SDA
+ * output level and the falling edge of SCL, in I2C module clock cycles.
+ */
+
+#define I2C_SDA_HOLD_TIME    0x000003ff
+#define I2C_SDA_HOLD_TIME_M  (I2C_SDA_HOLD_TIME_V << I2C_SDA_HOLD_TIME_S)
+#define I2C_SDA_HOLD_TIME_V  0x000003ff
+#define I2C_SDA_HOLD_TIME_S  0
+
+/* I2C_SDA_SAMPLE_REG register
+ * Configures the sample time after a positive SCL edge
+ */
+
+#define I2C_SDA_SAMPLE_REG(i) (REG_I2C_BASE(i) + 0x34)
+
+/* I2C_SDA_SAMPLE_TIME : R/W; bitpos: [9:0]; default: 0;
+ * This register is used to configure the interval between the rising edge
+ * of SCL and the level sampling time of SDA, in I2C module clock cycles.
+ */
+
+#define I2C_SDA_SAMPLE_TIME    0x000003ff
+#define I2C_SDA_SAMPLE_TIME_M  (I2C_SDA_SAMPLE_TIME_V << I2C_SDA_SAMPLE_TIME_S)
+#define I2C_SDA_SAMPLE_TIME_V  0x000003ff
+#define I2C_SDA_SAMPLE_TIME_S  0
+
+/* I2C_SCL_HIGH_PERIOD_REG register
+ * Configures the high level width of the SCL clock
+ */
+
+#define I2C_SCL_HIGH_PERIOD_REG(i) (REG_I2C_BASE(i) + 0x38)
+
+/* I2C_SCL_WAIT_HIGH_PERIOD : R/W; bitpos: [27:14]; default: 0;
+ * This register is used to configure for the SCL_FSM's waiting period for
+ * SCL to go high in master mode, in I2C module clock cycles.
+ */
+
+#define I2C_SCL_WAIT_HIGH_PERIOD    0x00003fff
+#define I2C_SCL_WAIT_HIGH_PERIOD_M  (I2C_SCL_WAIT_HIGH_PERIOD_V << I2C_SCL_WAIT_HIGH_PERIOD_S)
+#define I2C_SCL_WAIT_HIGH_PERIOD_V  0x00003fff
+#define I2C_SCL_WAIT_HIGH_PERIOD_S  14
+
+/* I2C_SCL_HIGH_PERIOD : R/W; bitpos: [13:0]; default: 0;
+ * This register is used to configure for how long SCL remains high in
+ * master mode, in I2C module clock cycles.
+ */
+
+#define I2C_SCL_HIGH_PERIOD    0x00003fff
+#define I2C_SCL_HIGH_PERIOD_M  (I2C_SCL_HIGH_PERIOD_V << I2C_SCL_HIGH_PERIOD_S)
+#define I2C_SCL_HIGH_PERIOD_V  0x00003fff
+#define I2C_SCL_HIGH_PERIOD_S  0
+
+/* I2C_SCL_START_HOLD_REG register
+ * Configures the interval between pulling SDA low and pulling SCL low when
+ * the master generates a START condition
+ */
+
+#define I2C_SCL_START_HOLD_REG(i) (REG_I2C_BASE(i) + 0x40)
+
+/* I2C_SCL_START_HOLD_TIME : R/W; bitpos: [9:0]; default: 8;
+ * This register is used to configure  interval between pulling SDA low and
+ * pulling SCL low when the master generates a START condition, in I2C
+ * module clock cycles.
+ */
+
+#define I2C_SCL_START_HOLD_TIME    0x000003ff
+#define I2C_SCL_START_HOLD_TIME_M  (I2C_SCL_START_HOLD_TIME_V << I2C_SCL_START_HOLD_TIME_S)
+#define I2C_SCL_START_HOLD_TIME_V  0x000003ff
+#define I2C_SCL_START_HOLD_TIME_S  0
+
+/* I2C_SCL_RSTART_SETUP_REG register
+ * Configures the interval between the positive edge of SCL and the negative
+ * edge of SDA
+ */
+
+#define I2C_SCL_RSTART_SETUP_REG(i) (REG_I2C_BASE(i) + 0x44)
+
+/* I2C_SCL_RSTART_SETUP_TIME : R/W; bitpos: [9:0]; default: 8;
+ * This register is used to configure the interval between the positive edge
+ * of SCL and the negative edge of SDA for a RESTART condition, in I2C
+ * module clock cycles.
+ */
+
+#define I2C_SCL_RSTART_SETUP_TIME    0x000003ff
+#define I2C_SCL_RSTART_SETUP_TIME_M  (I2C_SCL_RSTART_SETUP_TIME_V << I2C_SCL_RSTART_SETUP_TIME_S)
+#define I2C_SCL_RSTART_SETUP_TIME_V  0x000003ff
+#define I2C_SCL_RSTART_SETUP_TIME_S  0
+
+/* I2C_SCL_STOP_HOLD_REG register
+ * Configures the delay after the SCL clock edge for a stop condition
+ */
+
+#define I2C_SCL_STOP_HOLD_REG(i) (REG_I2C_BASE(i) + 0x48)
+
+/* I2C_SCL_STOP_HOLD_TIME : R/W; bitpos: [13:0]; default: 0;
+ * This register is used to configure the delay after the STOP condition, in
+ * I2C module clock cycles.
+ */
+
+#define I2C_SCL_STOP_HOLD_TIME    0x00003fff
+#define I2C_SCL_STOP_HOLD_TIME_M  (I2C_SCL_STOP_HOLD_TIME_V << I2C_SCL_STOP_HOLD_TIME_S)
+#define I2C_SCL_STOP_HOLD_TIME_V  0x00003fff
+#define I2C_SCL_STOP_HOLD_TIME_S  0
+
+/* I2C_SCL_STOP_SETUP_REG register
+ * Configures the delay between the SDA and SCL positive edge for a stop
+ * condition
+ */
+
+#define I2C_SCL_STOP_SETUP_REG(i) (REG_I2C_BASE(i) + 0x4c)
+
+/* I2C_SCL_STOP_SETUP_TIME : R/W; bitpos: [9:0]; default: 0;
+ * This register is used to configure the time between the positive edge of
+ * SCL and the positive edge of SDA, in I2C module clock cycles.
+ */
+
+#define I2C_SCL_STOP_SETUP_TIME    0x000003ff
+#define I2C_SCL_STOP_SETUP_TIME_M  (I2C_SCL_STOP_SETUP_TIME_V << I2C_SCL_STOP_SETUP_TIME_S)
+#define I2C_SCL_STOP_SETUP_TIME_V  0x000003ff
+#define I2C_SCL_STOP_SETUP_TIME_S  0
+
+/* I2C_SCL_FILTER_CFG_REG register
+ * SCL filter configuration register
+ */
+
+#define I2C_SCL_FILTER_CFG_REG(i) (REG_I2C_BASE(i) + 0x50)
+
+/* I2C_SCL_FILTER_EN : R/W; bitpos: [4]; default: 1;
+ * This is the filter enable bit for SCL.
+ */
+
+#define I2C_SCL_FILTER_EN    (BIT(4))
+#define I2C_SCL_FILTER_EN_M  (I2C_SCL_FILTER_EN_V << I2C_SCL_FILTER_EN_S)
+#define I2C_SCL_FILTER_EN_V  0x00000001
+#define I2C_SCL_FILTER_EN_S  4
+
+/* I2C_SCL_FILTER_THRES : R/W; bitpos: [3:0]; default: 0;
+ * When a pulse on the SCL input has smaller width than this register value
+ * in I2C module clock cycles, the I2C controller will ignore that pulse.
+ */
+
+#define I2C_SCL_FILTER_THRES    0x0000000f
+#define I2C_SCL_FILTER_THRES_M  (I2C_SCL_FILTER_THRES_V << I2C_SCL_FILTER_THRES_S)
+#define I2C_SCL_FILTER_THRES_V  0x0000000f
+#define I2C_SCL_FILTER_THRES_S  0
+
+/* I2C_SDA_FILTER_CFG_REG register
+ * SDA filter configuration register
+ */
+
+#define I2C_SDA_FILTER_CFG_REG(i) (REG_I2C_BASE(i) + 0x54)
+
+/* I2C_SDA_FILTER_EN : R/W; bitpos: [4]; default: 1;
+ * This is the filter enable bit for SDA.
+ */
+
+#define I2C_SDA_FILTER_EN    (BIT(4))
+#define I2C_SDA_FILTER_EN_M  (I2C_SDA_FILTER_EN_V << I2C_SDA_FILTER_EN_S)
+#define I2C_SDA_FILTER_EN_V  0x00000001
+#define I2C_SDA_FILTER_EN_S  4
+
+/* I2C_SDA_FILTER_THRES : R/W; bitpos: [3:0]; default: 0;
+ * When a pulse on the SDA input has smaller width than this register value
+ * in I2C module clock cycles, the I2C controller will ignore that pulse.
+ */
+
+#define I2C_SDA_FILTER_THRES    0x0000000f
+#define I2C_SDA_FILTER_THRES_M  (I2C_SDA_FILTER_THRES_V << I2C_SDA_FILTER_THRES_S)
+#define I2C_SDA_FILTER_THRES_V  0x0000000f
+#define I2C_SDA_FILTER_THRES_S  0
+
+/* I2C_COMD0_REG register
+ * I2C command register 0
+ */
+
+#define I2C_COMD0_REG(i) (REG_I2C_BASE(i) + 0x58)
+
+/* I2C_COMMAND0_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 0 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND0_DONE    (BIT(31))
+#define I2C_COMMAND0_DONE_M  (I2C_COMMAND0_DONE_V << I2C_COMMAND0_DONE_S)
+#define I2C_COMMAND0_DONE_V  0x00000001
+#define I2C_COMMAND0_DONE_S  31
+
+/* I2C_COMMAND0 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 0. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND0    0x00003fff
+#define I2C_COMMAND0_M  (I2C_COMMAND0_V << I2C_COMMAND0_S)
+#define I2C_COMMAND0_V  0x00003fff
+#define I2C_COMMAND0_S  0
+
+/* I2C_COMD1_REG register
+ * I2C command register 1
+ */
+
+#define I2C_COMD1_REG(i) (REG_I2C_BASE(i) + 0x5c)
+
+/* I2C_COMMAND1_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 1 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND1_DONE    (BIT(31))
+#define I2C_COMMAND1_DONE_M  (I2C_COMMAND1_DONE_V << I2C_COMMAND1_DONE_S)
+#define I2C_COMMAND1_DONE_V  0x00000001
+#define I2C_COMMAND1_DONE_S  31
+
+/* I2C_COMMAND1 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 1. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND1    0x00003fff
+#define I2C_COMMAND1_M  (I2C_COMMAND1_V << I2C_COMMAND1_S)
+#define I2C_COMMAND1_V  0x00003fff
+#define I2C_COMMAND1_S  0
+
+/* I2C_COMD2_REG register
+ * I2C command register 2
+ */
+
+#define I2C_COMD2_REG(i) (REG_I2C_BASE(i) + 0x60)
+
+/* I2C_COMMAND2_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 2 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND2_DONE    (BIT(31))
+#define I2C_COMMAND2_DONE_M  (I2C_COMMAND2_DONE_V << I2C_COMMAND2_DONE_S)
+#define I2C_COMMAND2_DONE_V  0x00000001
+#define I2C_COMMAND2_DONE_S  31
+
+/* I2C_COMMAND2 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 2. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND2    0x00003fff
+#define I2C_COMMAND2_M  (I2C_COMMAND2_V << I2C_COMMAND2_S)
+#define I2C_COMMAND2_V  0x00003fff
+#define I2C_COMMAND2_S  0
+
+/* I2C_COMD3_REG register
+ * I2C command register 3
+ */
+
+#define I2C_COMD3_REG(i) (REG_I2C_BASE(i) + 0x64)
+
+/* I2C_COMMAND3_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 3 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND3_DONE    (BIT(31))
+#define I2C_COMMAND3_DONE_M  (I2C_COMMAND3_DONE_V << I2C_COMMAND3_DONE_S)
+#define I2C_COMMAND3_DONE_V  0x00000001
+#define I2C_COMMAND3_DONE_S  31
+
+/* I2C_COMMAND3 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 3. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND3    0x00003fff
+#define I2C_COMMAND3_M  (I2C_COMMAND3_V << I2C_COMMAND3_S)
+#define I2C_COMMAND3_V  0x00003fff
+#define I2C_COMMAND3_S  0
+
+/* I2C_COMD4_REG register
+ * I2C command register 4
+ */
+
+#define I2C_COMD4_REG(i) (REG_I2C_BASE(i) + 0x68)
+
+/* I2C_COMMAND4_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 4 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND4_DONE    (BIT(31))
+#define I2C_COMMAND4_DONE_M  (I2C_COMMAND4_DONE_V << I2C_COMMAND4_DONE_S)
+#define I2C_COMMAND4_DONE_V  0x00000001
+#define I2C_COMMAND4_DONE_S  31
+
+/* I2C_COMMAND4 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 4. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND4    0x00003fff
+#define I2C_COMMAND4_M  (I2C_COMMAND4_V << I2C_COMMAND4_S)
+#define I2C_COMMAND4_V  0x00003fff
+#define I2C_COMMAND4_S  0
+
+/* I2C_COMD5_REG register
+ * I2C command register 5
+ */
+
+#define I2C_COMD5_REG(i) (REG_I2C_BASE(i) + 0x6c)
+
+/* I2C_COMMAND5_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 5 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND5_DONE    (BIT(31))
+#define I2C_COMMAND5_DONE_M  (I2C_COMMAND5_DONE_V << I2C_COMMAND5_DONE_S)
+#define I2C_COMMAND5_DONE_V  0x00000001
+#define I2C_COMMAND5_DONE_S  31
+
+/* I2C_COMMAND5 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 5. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND5    0x00003fff
+#define I2C_COMMAND5_M  (I2C_COMMAND5_V << I2C_COMMAND5_S)
+#define I2C_COMMAND5_V  0x00003fff
+#define I2C_COMMAND5_S  0
+
+/* I2C_COMD6_REG register
+ * I2C command register 6
+ */
+
+#define I2C_COMD6_REG(i) (REG_I2C_BASE(i) + 0x70)
+
+/* I2C_COMMAND6_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 6 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND6_DONE    (BIT(31))
+#define I2C_COMMAND6_DONE_M  (I2C_COMMAND6_DONE_V << I2C_COMMAND6_DONE_S)
+#define I2C_COMMAND6_DONE_V  0x00000001
+#define I2C_COMMAND6_DONE_S  31
+
+/* I2C_COMMAND6 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 6. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND6    0x00003fff
+#define I2C_COMMAND6_M  (I2C_COMMAND6_V << I2C_COMMAND6_S)
+#define I2C_COMMAND6_V  0x00003fff
+#define I2C_COMMAND6_S  0
+
+/* I2C_COMD7_REG register
+ * I2C command register 7
+ */
+
+#define I2C_COMD7_REG(i) (REG_I2C_BASE(i) + 0x74)
+
+/* I2C_COMMAND7_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 7 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND7_DONE    (BIT(31))
+#define I2C_COMMAND7_DONE_M  (I2C_COMMAND7_DONE_V << I2C_COMMAND7_DONE_S)
+#define I2C_COMMAND7_DONE_V  0x00000001
+#define I2C_COMMAND7_DONE_S  31
+
+/* I2C_COMMAND7 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 7. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND7    0x00003fff
+#define I2C_COMMAND7_M  (I2C_COMMAND7_V << I2C_COMMAND7_S)
+#define I2C_COMMAND7_V  0x00003fff
+#define I2C_COMMAND7_S  0
+
+/* I2C_COMD8_REG register
+ * I2C command register 8
+ */
+
+#define I2C_COMD8_REG(i) (REG_I2C_BASE(i) + 0x78)
+
+/* I2C_COMMAND8_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 8 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND8_DONE    (BIT(31))
+#define I2C_COMMAND8_DONE_M  (I2C_COMMAND8_DONE_V << I2C_COMMAND8_DONE_S)
+#define I2C_COMMAND8_DONE_V  0x00000001
+#define I2C_COMMAND8_DONE_S  31
+
+/* I2C_COMMAND8 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 8. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND8    0x00003fff
+#define I2C_COMMAND8_M  (I2C_COMMAND8_V << I2C_COMMAND8_S)
+#define I2C_COMMAND8_V  0x00003fff
+#define I2C_COMMAND8_S  0
+
+/* I2C_COMD9_REG register
+ * I2C command register 9
+ */
+
+#define I2C_COMD9_REG(i) (REG_I2C_BASE(i) + 0x7c)
+
+/* I2C_COMMAND9_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 9 is done in I2C Master mode, this bit changes to high level.
+ */
+
+#define I2C_COMMAND9_DONE    (BIT(31))
+#define I2C_COMMAND9_DONE_M  (I2C_COMMAND9_DONE_V << I2C_COMMAND9_DONE_S)
+#define I2C_COMMAND9_DONE_V  0x00000001
+#define I2C_COMMAND9_DONE_S  31
+
+/* I2C_COMMAND9 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 9. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND9    0x00003fff
+#define I2C_COMMAND9_M  (I2C_COMMAND9_V << I2C_COMMAND9_S)
+#define I2C_COMMAND9_V  0x00003fff
+#define I2C_COMMAND9_S  0
+
+/* I2C_COMD10_REG register
+ * I2C command register 10
+ */
+
+#define I2C_COMD10_REG(i) (REG_I2C_BASE(i) + 0x80)
+
+/* I2C_COMMAND10_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 10 is done in I2C Master mode, this bit changes to high
+ * level.
+ */
+
+#define I2C_COMMAND10_DONE    (BIT(31))
+#define I2C_COMMAND10_DONE_M  (I2C_COMMAND10_DONE_V << I2C_COMMAND10_DONE_S)
+#define I2C_COMMAND10_DONE_V  0x00000001
+#define I2C_COMMAND10_DONE_S  31
+
+/* I2C_COMMAND10 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 10. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND10    0x00003fff
+#define I2C_COMMAND10_M  (I2C_COMMAND10_V << I2C_COMMAND10_S)
+#define I2C_COMMAND10_V  0x00003fff
+#define I2C_COMMAND10_S  0
+
+/* I2C_COMD11_REG register
+ * I2C command register 11
+ */
+
+#define I2C_COMD11_REG(i) (REG_I2C_BASE(i) + 0x84)
+
+/* I2C_COMMAND11_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 11 is done in I2C Master mode, this bit changes to high
+ * level.
+ */
+
+#define I2C_COMMAND11_DONE    (BIT(31))
+#define I2C_COMMAND11_DONE_M  (I2C_COMMAND11_DONE_V << I2C_COMMAND11_DONE_S)
+#define I2C_COMMAND11_DONE_V  0x00000001
+#define I2C_COMMAND11_DONE_S  31
+
+/* I2C_COMMAND11 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 11. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND11    0x00003fff
+#define I2C_COMMAND11_M  (I2C_COMMAND11_V << I2C_COMMAND11_S)
+#define I2C_COMMAND11_V  0x00003fff
+#define I2C_COMMAND11_S  0
+
+/* I2C_COMD12_REG register
+ * I2C command register 12
+ */
+
+#define I2C_COMD12_REG(i) (REG_I2C_BASE(i) + 0x88)
+
+/* I2C_COMMAND12_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 12 is done in I2C Master mode, this bit changes to high
+ * level.
+ */
+
+#define I2C_COMMAND12_DONE    (BIT(31))
+#define I2C_COMMAND12_DONE_M  (I2C_COMMAND12_DONE_V << I2C_COMMAND12_DONE_S)
+#define I2C_COMMAND12_DONE_V  0x00000001
+#define I2C_COMMAND12_DONE_S  31
+
+/* I2C_COMMAND12 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 12. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND12    0x00003fff
+#define I2C_COMMAND12_M  (I2C_COMMAND12_V << I2C_COMMAND12_S)
+#define I2C_COMMAND12_V  0x00003fff
+#define I2C_COMMAND12_S  0
+
+/* I2C_COMD13_REG register
+ * I2C command register 13
+ */
+
+#define I2C_COMD13_REG(i) (REG_I2C_BASE(i) + 0x8c)
+
+/* I2C_COMMAND13_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 13 is done in I2C Master mode, this bit changes to high
+ * level.
+ */
+
+#define I2C_COMMAND13_DONE    (BIT(31))
+#define I2C_COMMAND13_DONE_M  (I2C_COMMAND13_DONE_V << I2C_COMMAND13_DONE_S)
+#define I2C_COMMAND13_DONE_V  0x00000001
+#define I2C_COMMAND13_DONE_S  31
+
+/* I2C_COMMAND13 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 13. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND13    0x00003fff
+#define I2C_COMMAND13_M  (I2C_COMMAND13_V << I2C_COMMAND13_S)
+#define I2C_COMMAND13_V  0x00003fff
+#define I2C_COMMAND13_S  0
+
+/* I2C_COMD14_REG register
+ * I2C command register 14
+ */
+
+#define I2C_COMD14_REG(i) (REG_I2C_BASE(i) + 0x90)
+
+/* I2C_COMMAND14_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 14 is done in I2C Master mode, this bit changes to high
+ * level.
+ */
+
+#define I2C_COMMAND14_DONE    (BIT(31))
+#define I2C_COMMAND14_DONE_M  (I2C_COMMAND14_DONE_V << I2C_COMMAND14_DONE_S)
+#define I2C_COMMAND14_DONE_V  0x00000001
+#define I2C_COMMAND14_DONE_S  31
+
+/* I2C_COMMAND14 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 14. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND14    0x00003fff
+#define I2C_COMMAND14_M  (I2C_COMMAND14_V << I2C_COMMAND14_S)
+#define I2C_COMMAND14_V  0x00003fff
+#define I2C_COMMAND14_S  0
+
+/* I2C_COMD15_REG register
+ * I2C command register 15
+ */
+
+#define I2C_COMD15_REG(i) (REG_I2C_BASE(i) + 0x94)
+
+/* I2C_COMMAND15_DONE : R/W; bitpos: [31]; default: 0;
+ * When command 15 is done in I2C Master mode, this bit changes to high
+ * level.
+ */
+
+#define I2C_COMMAND15_DONE    (BIT(31))
+#define I2C_COMMAND15_DONE_M  (I2C_COMMAND15_DONE_V << I2C_COMMAND15_DONE_S)
+#define I2C_COMMAND15_DONE_V  0x00000001
+#define I2C_COMMAND15_DONE_S  31
+
+/* I2C_COMMAND15 : R/W; bitpos: [13:0]; default: 0;
+ * This is the content of command 15. It consists of three parts:
+ *
+ * op_code is the command, 0: RSTART. 1: WRITE. 2: READ. 3: STOP. 4: END.
+ *
+ * byte_num represents the number of bytes that need to be sent or received.
+ *
+ * ack_check_en, ack_exp and ack are used to control the ACK bit. See I2C
+ * cmd structure for more information.
+ */
+
+#define I2C_COMMAND15    0x00003fff
+#define I2C_COMMAND15_M  (I2C_COMMAND15_V << I2C_COMMAND15_S)
+#define I2C_COMMAND15_V  0x00003fff
+#define I2C_COMMAND15_S  0
+
+/* I2C_SCL_ST_TIME_OUT_REG register
+ * SCL status time out register
+ */
+
+#define I2C_SCL_ST_TIME_OUT_REG(i) (REG_I2C_BASE(i) + 0x98)
+
+/* I2C_SCL_ST_TO : R/W; bitpos: [23:0]; default: 256;
+ * The threshold value of SCL_FSM state unchanged period.
+ */
+
+#define I2C_SCL_ST_TO    0x00ffffff
+#define I2C_SCL_ST_TO_M  (I2C_SCL_ST_TO_V << I2C_SCL_ST_TO_S)
+#define I2C_SCL_ST_TO_V  0x00ffffff
+#define I2C_SCL_ST_TO_S  0
+
+/* I2C_SCL_MAIN_ST_TIME_OUT_REG register
+ * SCL main status time out register
+ */
+
+#define I2C_SCL_MAIN_ST_TIME_OUT_REG(i) (REG_I2C_BASE(i) + 0x9c)
+
+/* I2C_SCL_MAIN_ST_TO : R/W; bitpos: [23:0]; default: 256;
+ * The threshold value of SCL_MAIN_FSM state unchanged period.
+ */
+
+#define I2C_SCL_MAIN_ST_TO    0x00ffffff
+#define I2C_SCL_MAIN_ST_TO_M  (I2C_SCL_MAIN_ST_TO_V << I2C_SCL_MAIN_ST_TO_S)
+#define I2C_SCL_MAIN_ST_TO_V  0x00ffffff
+#define I2C_SCL_MAIN_ST_TO_S  0
+
+/* I2C_SCL_SP_CONF_REG register
+ * Power configuration register
+ */
+
+#define I2C_SCL_SP_CONF_REG(i) (REG_I2C_BASE(i) + 0xa0)
+
+/* I2C_SDA_PD_EN : R/W; bitpos: [7]; default: 0;
+ * The power down enable bit for the I2C output SDA line. 1: Power down. 0:
+ * Not power down. Set I2C_SDA_FORCE_OUT and I2C_SDA_PD_EN to 1 to stretch
+ * SDA low.
+ */
+
+#define I2C_SDA_PD_EN    (BIT(7))
+#define I2C_SDA_PD_EN_M  (I2C_SDA_PD_EN_V << I2C_SDA_PD_EN_S)
+#define I2C_SDA_PD_EN_V  0x00000001
+#define I2C_SDA_PD_EN_S  7
+
+/* I2C_SCL_PD_EN : R/W; bitpos: [6]; default: 0;
+ * The power down enable bit for the I2C output SCL line. 1: Power down. 0:
+ * Not power down. Set I2C_SCL_FORCE_OUT and I2C_SCL_PD_EN to 1 to stretch
+ * SCL low.
+ */
+
+#define I2C_SCL_PD_EN    (BIT(6))
+#define I2C_SCL_PD_EN_M  (I2C_SCL_PD_EN_V << I2C_SCL_PD_EN_S)
+#define I2C_SCL_PD_EN_V  0x00000001
+#define I2C_SCL_PD_EN_S  6
+
+/* I2C_SCL_RST_SLV_NUM : R/W; bitpos: [5:1]; default: 0;
+ * Configure the pulses of SCL generated in I2C master mode. Valid when
+ * I2C_SCL_RST_SLV_EN is 1.
+ */
+
+#define I2C_SCL_RST_SLV_NUM    0x0000001f
+#define I2C_SCL_RST_SLV_NUM_M  (I2C_SCL_RST_SLV_NUM_V << I2C_SCL_RST_SLV_NUM_S)
+#define I2C_SCL_RST_SLV_NUM_V  0x0000001f
+#define I2C_SCL_RST_SLV_NUM_S  1
+
+/* I2C_SCL_RST_SLV_EN : R/W; bitpos: [0]; default: 0;
+ * When I2C master is IDLE, set this bit to send out SCL pulses. The number
+ * of pulses equals to I2C_SCL_RST_SLV_NUM[4:0].
+ */
+
+#define I2C_SCL_RST_SLV_EN    (BIT(0))
+#define I2C_SCL_RST_SLV_EN_M  (I2C_SCL_RST_SLV_EN_V << I2C_SCL_RST_SLV_EN_S)
+#define I2C_SCL_RST_SLV_EN_V  0x00000001
+#define I2C_SCL_RST_SLV_EN_S  0
+
+/* I2C_SCL_STRETCH_CONF_REG register
+ * Set SCL stretch of I2C slave
+ */
+
+#define I2C_SCL_STRETCH_CONF_REG(i) (REG_I2C_BASE(i) + 0xa4)
+
+/* I2C_SLAVE_SCL_STRETCH_CLR : WO; bitpos: [11]; default: 0;
+ * Set this bit to clear the I2C slave SCL stretch function.
+ */
+
+#define I2C_SLAVE_SCL_STRETCH_CLR    (BIT(11))
+#define I2C_SLAVE_SCL_STRETCH_CLR_M  (I2C_SLAVE_SCL_STRETCH_CLR_V << I2C_SLAVE_SCL_STRETCH_CLR_S)
+#define I2C_SLAVE_SCL_STRETCH_CLR_V  0x00000001
+#define I2C_SLAVE_SCL_STRETCH_CLR_S  11
+
+/* I2C_SLAVE_SCL_STRETCH_EN : R/W; bitpos: [10]; default: 0;
+ * The enable bit for slave SCL stretch function. 1: Enable. 0: Disable. The
+ * SCL output line will be stretched low when I2C_SLAVE_SCL_STRETCH_EN is 1
+ * and stretch event happens. The stretch cause can be seen in
+ * I2C_STRETCH_CAUSE.
+ */
+
+#define I2C_SLAVE_SCL_STRETCH_EN    (BIT(10))
+#define I2C_SLAVE_SCL_STRETCH_EN_M  (I2C_SLAVE_SCL_STRETCH_EN_V << I2C_SLAVE_SCL_STRETCH_EN_S)
+#define I2C_SLAVE_SCL_STRETCH_EN_V  0x00000001
+#define I2C_SLAVE_SCL_STRETCH_EN_S  10
+
+/* I2C_STRETCH_PROTECT_NUM : R/W; bitpos: [9:0]; default: 0;
+ * Configure the period of I2C slave stretching SCL line.
+ */
+
+#define I2C_STRETCH_PROTECT_NUM    0x000003ff
+#define I2C_STRETCH_PROTECT_NUM_M  (I2C_STRETCH_PROTECT_NUM_V << I2C_STRETCH_PROTECT_NUM_S)
+#define I2C_STRETCH_PROTECT_NUM_V  0x000003ff
+#define I2C_STRETCH_PROTECT_NUM_S  0
+
+/* I2C_DATE_REG register
+ * Version control register
+ */
+
+#define I2C_DATE_REG(i) (REG_I2C_BASE(i) + 0xf8)
+
+/* I2C_DATE : R/W; bitpos: [31:0]; default: 419766272;
+ * This is the the version control register.
+ */
+
+#define I2C_DATE    0xffffffff
+#define I2C_DATE_M  (I2C_DATE_V << I2C_DATE_S)
+#define I2C_DATE_V  0xffffffff
+#define I2C_DATE_S  0
+
+#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_I2C_H */
diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h
index 4850a3a128..9276d98d7a 100644
--- a/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h
+++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_soc.h
@@ -190,7 +190,7 @@
 
 /* Helper to place a value in a field */
 
-#define VALUE_TO_FIELD(_value, _field) ((_value << (_field##_S)) & (_field##_M))
+#define VALUE_TO_FIELD(_value, _field) (((_value) << (_field##_S)) & (_field##_M))
 
 /* Periheral Clock */
 
diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_system.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_system.h
index 884298bc19..60351db7ad 100644
--- a/arch/xtensa/src/esp32s2/hardware/esp32s2_system.h
+++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_system.h
@@ -80,9 +80,9 @@
  * This field is used to force on clock gate of internal SRAM.
  */
 
-#define SYSTEM_SRAM_FO    0x003FFFFF
+#define SYSTEM_SRAM_FO    0x003fffff
 #define SYSTEM_SRAM_FO_M  (SYSTEM_SRAM_FO_V << SYSTEM_SRAM_FO_S)
-#define SYSTEM_SRAM_FO_V  0x003FFFFF
+#define SYSTEM_SRAM_FO_V  0x003fffff
 #define SYSTEM_SRAM_FO_S  0
 
 /* SYSTEM_SRAM_CTRL_1_REG register
@@ -95,9 +95,9 @@
  * This field is used to power down internal SRAM.
  */
 
-#define SYSTEM_SRAM_FORCE_PD    0x003FFFFF
+#define SYSTEM_SRAM_FORCE_PD    0x003fffff
 #define SYSTEM_SRAM_FORCE_PD_M  (SYSTEM_SRAM_FORCE_PD_V << SYSTEM_SRAM_FORCE_PD_S)
-#define SYSTEM_SRAM_FORCE_PD_V  0x003FFFFF
+#define SYSTEM_SRAM_FORCE_PD_V  0x003fffff
 #define SYSTEM_SRAM_FORCE_PD_S  0
 
 /* SYSTEM_CPU_PERI_CLK_EN_REG register
@@ -135,16 +135,15 @@
  */
 
 #define SYSTEM_CPU_PER_CONF_REG (DR_REG_SYSTEM_BASE + 0x18)
-#define DPORT_CPU_PER_CONF_REG  (DR_REG_SYSTEM_BASE + 0x018) /* old name */
 
 /* SYSTEM_CPU_WAITI_DELAY_NUM : R/W; bitpos: [7:4]; default: 0;
  * Sets the number of delay cycles to enter CPU wait mode after a WAITI
  * instruction.
  */
 
-#define SYSTEM_CPU_WAITI_DELAY_NUM    0x0000000F
+#define SYSTEM_CPU_WAITI_DELAY_NUM    0x0000000f
 #define SYSTEM_CPU_WAITI_DELAY_NUM_M  (SYSTEM_CPU_WAITI_DELAY_NUM_V << SYSTEM_CPU_WAITI_DELAY_NUM_S)
-#define SYSTEM_CPU_WAITI_DELAY_NUM_V  0x0000000F
+#define SYSTEM_CPU_WAITI_DELAY_NUM_V  0x0000000f
 #define SYSTEM_CPU_WAITI_DELAY_NUM_S  4
 
 /* SYSTEM_CPU_WAIT_MODE_FORCE_ON : R/W; bitpos: [3]; default: 1;
@@ -188,9 +187,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_0_S  0
 
 /* SYSTEM_JTAG_CTRL_1_REG register
@@ -205,9 +204,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_1_S  0
 
 /* SYSTEM_JTAG_CTRL_2_REG register
@@ -222,9 +221,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_2_S  0
 
 /* SYSTEM_JTAG_CTRL_3_REG register
@@ -239,9 +238,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_3_S  0
 
 /* SYSTEM_JTAG_CTRL_4_REG register
@@ -256,9 +255,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_4_S  0
 
 /* SYSTEM_JTAG_CTRL_5_REG register
@@ -273,9 +272,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_5_S  0
 
 /* SYSTEM_JTAG_CTRL_6_REG register
@@ -290,9 +289,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_6_S  0
 
 /* SYSTEM_JTAG_CTRL_7_REG register
@@ -307,9 +306,9 @@
  * temporary disable of eFuse to JTAG.
  */
 
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7    0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7    0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7_M  (SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7_V << SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7_S)
-#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7_V  0xFFFFFFFF
+#define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7_V  0xffffffff
 #define SYSTEM_CANCEL_EFUSE_DISABLE_JTAG_TEMPORARY_7_S  0
 
 /* SYSTEM_MEM_PD_MASK_REG register
@@ -1043,12 +1042,12 @@
 #define SYSTEM_LPCK_DIV_INT_REG (DR_REG_SYSTEM_BASE + 0x50)
 
 /* SYSTEM_LPCK_DIV_NUM : R/W; bitpos: [11:0]; default: 255;
- * This register is used to set the integer number of divider.
+ * This field is used to set the integer number of the divider value.
  */
 
-#define SYSTEM_LPCK_DIV_NUM    0x00000FFF
+#define SYSTEM_LPCK_DIV_NUM    0x00000fff
 #define SYSTEM_LPCK_DIV_NUM_M  (SYSTEM_LPCK_DIV_NUM_V << SYSTEM_LPCK_DIV_NUM_S)
-#define SYSTEM_LPCK_DIV_NUM_V  0x00000FFF
+#define SYSTEM_LPCK_DIV_NUM_V  0x00000fff
 #define SYSTEM_LPCK_DIV_NUM_S  0
 
 /* SYSTEM_BT_LPCK_DIV_FRAC_REG register
@@ -1313,18 +1312,18 @@
  * address.
  */
 
-#define SYSTEM_RTC_MEM_CRC_LEN    0x000007FF
+#define SYSTEM_RTC_MEM_CRC_LEN    0x000007ff
 #define SYSTEM_RTC_MEM_CRC_LEN_M  (SYSTEM_RTC_MEM_CRC_LEN_V << SYSTEM_RTC_MEM_CRC_LEN_S)
-#define SYSTEM_RTC_MEM_CRC_LEN_V  0x000007FF
+#define SYSTEM_RTC_MEM_CRC_LEN_V  0x000007ff
 #define SYSTEM_RTC_MEM_CRC_LEN_S  20
 
 /* SYSTEM_RTC_MEM_CRC_ADDR : R/W; bitpos: [19:9]; default: 0;
  * This field is used to set address of RTC memory for CRC.
  */
 
-#define SYSTEM_RTC_MEM_CRC_ADDR    0x000007FF
+#define SYSTEM_RTC_MEM_CRC_ADDR    0x000007ff
 #define SYSTEM_RTC_MEM_CRC_ADDR_M  (SYSTEM_RTC_MEM_CRC_ADDR_V << SYSTEM_RTC_MEM_CRC_ADDR_S)
-#define SYSTEM_RTC_MEM_CRC_ADDR_V  0x000007FF
+#define SYSTEM_RTC_MEM_CRC_ADDR_V  0x000007ff
 #define SYSTEM_RTC_MEM_CRC_ADDR_S  9
 
 /* SYSTEM_RTC_MEM_CRC_START : R/W; bitpos: [8]; default: 0;
@@ -1346,9 +1345,9 @@
  * This field stores the CRC result of RTC memory.
  */
 
-#define SYSTEM_RTC_MEM_CRC_RES    0xFFFFFFFF
+#define SYSTEM_RTC_MEM_CRC_RES    0xffffffff
 #define SYSTEM_RTC_MEM_CRC_RES_M  (SYSTEM_RTC_MEM_CRC_RES_V << SYSTEM_RTC_MEM_CRC_RES_S)
-#define SYSTEM_RTC_MEM_CRC_RES_V  0xFFFFFFFF
+#define SYSTEM_RTC_MEM_CRC_RES_V  0xffffffff
 #define SYSTEM_RTC_MEM_CRC_RES_S  0
 
 /* SYSTEM_Redundant_ECO_Ctrl_REG register
@@ -1400,9 +1399,9 @@
  * This field is used to power up internal SRAM.
  */
 
-#define SYSTEM_SRAM_FORCE_PU    0x003FFFFF
+#define SYSTEM_SRAM_FORCE_PU    0x003fffff
 #define SYSTEM_SRAM_FORCE_PU_M  (SYSTEM_SRAM_FORCE_PU_V << SYSTEM_SRAM_FORCE_PU_S)
-#define SYSTEM_SRAM_FORCE_PU_V  0x003FFFFF
+#define SYSTEM_SRAM_FORCE_PU_V  0x003fffff
 #define SYSTEM_SRAM_FORCE_PU_S  0
 
 /* SYSTEM_SYSCLK_CONF_REG register
@@ -1424,9 +1423,9 @@
  * This field is used to read XTAL frequency in MHz.
  */
 
-#define SYSTEM_CLK_XTAL_FREQ    0x0000007F
+#define SYSTEM_CLK_XTAL_FREQ    0x0000007f
 #define SYSTEM_CLK_XTAL_FREQ_M  (SYSTEM_CLK_XTAL_FREQ_V << SYSTEM_CLK_XTAL_FREQ_S)
-#define SYSTEM_CLK_XTAL_FREQ_V  0x0000007F
+#define SYSTEM_CLK_XTAL_FREQ_V  0x0000007f
 #define SYSTEM_CLK_XTAL_FREQ_S  12
 
 /* SYSTEM_SOC_CLK_SEL : R/W; bitpos: [11:10]; default: 0;
@@ -1442,24 +1441,24 @@
  * This field is used to set the count of prescaler of XTAL\_CLK.
  */
 
-#define SYSTEM_PRE_DIV_CNT    0x000003FF
+#define SYSTEM_PRE_DIV_CNT    0x000003ff
 #define SYSTEM_PRE_DIV_CNT_M  (SYSTEM_PRE_DIV_CNT_V << SYSTEM_PRE_DIV_CNT_S)
-#define SYSTEM_PRE_DIV_CNT_V  0x000003FF
+#define SYSTEM_PRE_DIV_CNT_V  0x000003ff
 #define SYSTEM_PRE_DIV_CNT_S  0
 
-/* SYSTEM_REG_DATE_REG register
+/* SYSTEM_DATE_REG register
  * Version control register
  */
 
-#define SYSTEM_REG_DATE_REG (DR_REG_SYSTEM_BASE + 0xffc)
+#define SYSTEM_DATE_REG (DR_REG_SYSTEM_BASE + 0xffc)
 
-/* SYSTEM_SYSTEM_REG_DATE : R/W; bitpos: [27:0]; default: 26247200;
- * This is the date version register.
+/* SYSTEM_DATE : R/W; bitpos: [27:0]; default: 26247200;
+ * Version control register.
  */
 
-#define SYSTEM_SYSTEM_REG_DATE    0x0FFFFFFF
-#define SYSTEM_SYSTEM_REG_DATE_M  (SYSTEM_SYSTEM_REG_DATE_V << SYSTEM_SYSTEM_REG_DATE_S)
-#define SYSTEM_SYSTEM_REG_DATE_V  0x0FFFFFFF
-#define SYSTEM_SYSTEM_REG_DATE_S  0
+#define SYSTEM_DATE    0x0fffffff
+#define SYSTEM_DATE_M  (SYSTEM_DATE_V << SYSTEM_DATE_S)
+#define SYSTEM_DATE_V  0x0fffffff
+#define SYSTEM_DATE_S  0
 
 #endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_SYSTEM_H */


[incubator-nuttx] 03/03: esp32s2-saola-1: Add support for BMP180 pressure sensor

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 43685aefc8fda38b892e5467ea8ddde295ffac44
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Wed Jun 15 16:17:10 2022 -0300

    esp32s2-saola-1: Add support for BMP180 pressure sensor
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 .../xtensa/esp32s2/esp32s2-saola-1/src/Make.defs   |  4 ++
 .../esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h  | 19 ++++++
 .../esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.c   | 75 ++++++++++++++++++++++
 .../esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c  | 15 +++++
 4 files changed, 113 insertions(+)

diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs b/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs
index 43ce38abba..cb7977835d 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs
@@ -45,6 +45,10 @@ ifeq ($(CONFIG_I2C_DRIVER),y)
 CSRCS += esp32s2_board_i2c.c
 endif
 
+ifeq ($(CONFIG_SENSORS_BMP180),y)
+CSRCS += esp32s2_bmp180.c
+endif
+
 SCRIPTIN = $(SCRIPTDIR)$(DELIM)esp32s2.template.ld
 SCRIPTOUT = $(SCRIPTDIR)$(DELIM)esp32s2_out.ld
 
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h
index 89f5263a28..b2a1a455b9 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h
@@ -133,5 +133,24 @@ int board_oneshot_init(int timer, uint16_t resolution);
 int board_i2c_init(void);
 #endif
 
+/****************************************************************************
+ * Name: board_bmp180_initialize
+ *
+ * Description:
+ *   Initialize and register the BMP180 Pressure Sensor driver.
+ *
+ * Input Parameters:
+ *   devno - The device number, used to build the device path as /dev/pressN
+ *   busno - The I2C bus number
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SENSORS_BMP180
+int board_bmp180_initialize(int devno, int busno);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_XTENSA_ESP32S2_ESP32S2_SAOLA_1_SRC_ESP32S2_SAOLA_1_H */
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.c b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.c
new file mode 100644
index 0000000000..08eed07862
--- /dev/null
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.c
@@ -0,0 +1,75 @@
+/****************************************************************************
+ * boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bmp180.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 <nuttx/arch.h>
+#include <nuttx/i2c/i2c_master.h>
+#include <nuttx/sensors/bmp180.h>
+
+#include "esp32s2_i2c.h"
+#include "esp32s2-saola-1.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_bmp180_initialize
+ *
+ * Description:
+ *   Initialize and register the BMP180 Pressure Sensor driver.
+ *
+ * Input Parameters:
+ *   devno - The device number, used to build the device path as /dev/pressN
+ *   busno - The I2C bus number
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_bmp180_initialize(int devno, int busno)
+{
+  struct i2c_master_s *i2c;
+  char devpath[12];
+
+  /* Initialize BMP180 */
+
+  i2c = esp32s2_i2cbus_initialize(busno);
+  if (i2c == NULL)
+    {
+      return -ENODEV;
+    }
+
+  /* Register the barometer sensor */
+
+  (void)snprintf(devpath, sizeof(devpath), "/dev/press%d", devno);
+
+  return bmp180_register(devpath, i2c);
+}
+
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c
index 7835f1bf40..d8607faaa9 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c
@@ -50,6 +50,10 @@
 #  include "esp32s2_tim_lowerhalf.h"
 #endif
 
+#ifdef CONFIG_ESP32S2_I2C
+#  include "esp32s2_i2c.h"
+#endif
+
 #ifdef CONFIG_ESP32S2_RT_TIMER
 #  include "esp32s2_rt_timer.h"
 #endif
@@ -202,6 +206,17 @@ int esp32s2_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_SENSORS_BMP180
+  /* Try to register BMP180 device in I2C0 */
+
+  ret = board_bmp180_initialize(0, ESP32S2_I2C0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "Failed to initialize BMP180 driver for I2C0: %d\n", ret);
+    }
+#endif
+
   /* If we got here then perhaps not all initialization was successful, but
    * at least enough succeeded to bring-up NSH with perhaps reduced
    * capabilities.


[incubator-nuttx] 02/03: esp32s2-saola-1: Add support for I2C chardev driver

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 01b3ddd22f50ee865009d0eb0f624fb7e1b1a6d0
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Wed Jun 15 15:49:35 2022 -0300

    esp32s2-saola-1: Add support for I2C chardev driver
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 .../esp32s2/esp32s2-saola-1/configs/i2c/defconfig  | 60 ++++++++++++++
 .../xtensa/esp32s2/esp32s2-saola-1/src/Make.defs   |  4 +
 .../esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h  | 16 ++++
 .../esp32s2-saola-1/src/esp32s2_board_i2c.c        | 93 ++++++++++++++++++++++
 .../esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c  | 10 +++
 5 files changed, 183 insertions(+)

diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/i2c/defconfig b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/i2c/defconfig
new file mode 100644
index 0000000000..66de620ab0
--- /dev/null
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/i2c/defconfig
@@ -0,0 +1,60 @@
+#
+# 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_ARCH_LEDS is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s2-saola-1"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S2_SAOLA_1=y
+CONFIG_ARCH_CHIP="esp32s2"
+CONFIG_ARCH_CHIP_ESP32S2=y
+CONFIG_ARCH_CHIP_ESP32S2WROVER=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_ERROR=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_I2C=y
+CONFIG_DEBUG_I2C_ERROR=y
+CONFIG_DEBUG_I2C_INFO=y
+CONFIG_DEBUG_I2C_WARN=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_WARN=y
+CONFIG_ESP32S2_I2C0=y
+CONFIG_ESP32S2_I2C1=y
+CONFIG_ESP32S2_UART0=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_I2CTOOL_DEFFREQ=100000
+CONFIG_I2CTOOL_MAXBUS=1
+CONFIG_I2C_RESET=y
+CONFIG_I2C_TRACE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=28
+CONFIG_START_MONTH=6
+CONFIG_START_YEAR=2022
+CONFIG_SYSTEM_I2CTOOL=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs b/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs
index 23737b3157..43ce38abba 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/Make.defs
@@ -41,6 +41,10 @@ ifeq ($(CONFIG_ONESHOT),y)
 CSRCS += esp32s2_oneshot.c
 endif
 
+ifeq ($(CONFIG_I2C_DRIVER),y)
+CSRCS += esp32s2_board_i2c.c
+endif
+
 SCRIPTIN = $(SCRIPTDIR)$(DELIM)esp32s2.template.ld
 SCRIPTOUT = $(SCRIPTDIR)$(DELIM)esp32s2_out.ld
 
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h
index 35bb4e25bc..89f5263a28 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2-saola-1.h
@@ -117,5 +117,21 @@ int esp32s2_gpio_init(void);
 int board_oneshot_init(int timer, uint16_t resolution);
 #endif
 
+/****************************************************************************
+ * Name: board_i2c_init
+ *
+ * Description:
+ *   Configure the I2C driver.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; A negated errno value is returned
+ *   to indicate the nature of any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_DRIVER
+int board_i2c_init(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_XTENSA_ESP32S2_ESP32S2_SAOLA_1_SRC_ESP32S2_SAOLA_1_H */
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_board_i2c.c b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_board_i2c.c
new file mode 100644
index 0000000000..8b6f4f73c6
--- /dev/null
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_board_i2c.c
@@ -0,0 +1,93 @@
+/****************************************************************************
+ * boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_board_i2c.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 <errno.h>
+#include <sys/types.h>
+
+#include <nuttx/i2c/i2c_master.h>
+
+#include "esp32s2_i2c.h"
+#include "esp32s2-saola-1.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+static int i2c_driver_init(int bus)
+{
+  struct i2c_master_s *i2c;
+  int ret;
+
+  i2c = esp32s2_i2cbus_initialize(bus);
+  if (i2c == NULL)
+    {
+      i2cerr("Failed to get I2C%d interface\n", bus);
+      return -ENODEV;
+    }
+
+  ret = i2c_register(i2c, bus);
+  if (ret < 0)
+    {
+      i2cerr("Failed to register I2C%d driver: %d\n", bus, ret);
+      esp32s2_i2cbus_uninitialize(i2c);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: board_i2c_init
+ *
+ * Description:
+ *   Configure the I2C driver.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; A negated errno value is returned
+ *   to indicate the nature of any failure.
+ *
+ ****************************************************************************/
+
+int board_i2c_init(void)
+{
+  int ret = OK;
+
+#ifdef CONFIG_ESP32S2_I2C0
+  ret = i2c_driver_init(ESP32S2_I2C0);
+  if (ret != OK)
+    {
+      goto done;
+    }
+#endif
+
+#ifdef CONFIG_ESP32S2_I2C1
+  ret = i2c_driver_init(ESP32S2_I2C1);
+#endif
+
+done:
+  return ret;
+}
+
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c
index 198ca5c767..7835f1bf40 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c
@@ -192,6 +192,16 @@ int esp32s2_bringup(void)
 
 #endif /* CONFIG_ONESHOT */
 
+#ifdef CONFIG_I2C_DRIVER
+  /* Configure I2C peripheral interfaces */
+
+  ret = board_i2c_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize I2C driver: %d\n", ret);
+    }
+#endif
+
   /* If we got here then perhaps not all initialization was successful, but
    * at least enough succeeded to bring-up NSH with perhaps reduced
    * capabilities.