diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 33f3026db7..4cf7ae8541 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -14,6 +14,7 @@ choice config ARCH_CHIP_ESP32S3WROOM1 bool "ESP32-S3-WROOM-1" select ESP32S3_FLASH_4M + select ARCH_HAVE_I2CRESET ---help--- Generic module with an embedded ESP32-S3. @@ -21,12 +22,14 @@ config ARCH_CHIP_ESP32S3WROOM2 bool "ESP32-S3-WROOM-2" select ESP32S3_FLASH_16M select ESP32S3_PSRAM_8M + select ARCH_HAVE_I2CRESET ---help--- Generic module with an embedded ESP32-S3. config ARCH_CHIP_ESP32S3MINI1 bool "ESP32-S3-MINI-1" select ESP32S3_FLASH_8M + select ARCH_HAVE_I2CRESET ---help--- Generic module with an embedded ESP32-S3. @@ -306,6 +309,10 @@ config ESP32S3_TIMER bool default n +config ESP32S3_I2C + bool + default n + config ESP32S3_SPI bool default n @@ -351,11 +358,23 @@ config ESP32S3_UART2 select UART2_SERIALDRIVER select ARCH_HAVE_SERIAL_TERMIOS +config ESP32S3_I2C0 + bool "I2C 0" + default n + select ESP32S3_I2C + select I2C + +config ESP32S3_I2C1 + bool "I2C 1" + default n + select ESP32S3_I2C + select I2C + config ESP32S3_USBSERIAL - bool "USB-Serial Driver" - default n - select OTHER_UART_SERIALDRIVER - select ARCH_HAVE_SERIAL_TERMIOS + bool "USB-Serial Driver" + default n + select OTHER_UART_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS config ESP32S3_TIMER0 bool "54-bit Timer 0 (Group 0 Timer 0)" @@ -484,7 +503,7 @@ config ESP32S3_SPIRAM_RODATA default n ---help--- If enabled, rodata in flash will be copied into SPIRAM. - If ESP32S3_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS is also enabled, + If ESP32S3_SPIRAM_FETCH_INSTRUCTIONS is also enabled, you can run the instruction when erasing or programming the flash. @@ -688,6 +707,47 @@ endif # ESP32S3_UART2 endmenu # UART Configuration +menu "I2C Configuration" + depends on ESP32S3_I2C + +if ESP32S3_I2C0 + +config ESP32S3_I2C0_SCLPIN + int "I2C0 SCL Pin" + default 2 + range 0 48 + +config ESP32S3_I2C0_SDAPIN + int "I2C0 SDA Pin" + default 1 + range 0 48 + +endif # ESP32S3_I2C0 + +if ESP32S3_I2C1 + +config ESP32S3_I2C1_SCLPIN + int "I2C1 SCL Pin" + default 5 + range 0 48 + +config ESP32S3_I2C1_SDAPIN + int "I2C1 SDA Pin" + default 4 + range 0 48 + +endif # ESP32S3_I2C1 + +config ESP32S3_I2CTIMEOSEC + int "Timeout seconds" + default 0 + +config ESP32S3_I2CTIMEOMS + int "Timeout milliseconds" + default 500 + +endmenu # I2C Configuration + menu "Timer/Counter Configuration" depends on ESP32S3_TIMER diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index 482b91346d..e66eff5ae9 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -125,6 +125,10 @@ ifeq ($(CONFIG_ESP32S3_RT_TIMER),y) CHIP_CSRCS += esp32s3_rt_timer.c endif +ifeq ($(CONFIG_ESP32S3_I2C),y) +CHIP_CSRCS += esp32s3_i2c.c +endif + ifeq ($(CONFIG_ESP32S3_SPI),y) CHIP_CSRCS += esp32s3_spi.c endif diff --git a/arch/xtensa/src/esp32s3/esp32s3_i2c.c b/arch/xtensa/src/esp32s3/esp32s3_i2c.c new file mode 100644 index 0000000000..20b5c1bcce --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_i2c.c @@ -0,0 +1,1740 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_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 + +#ifdef CONFIG_ESP32S3_I2C + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "esp32s3_gpio.h" +#include "esp32s3_i2c.h" +#include "esp32s3_irq.h" + +#include "xtensa.h" +#include "hardware/esp32s3_gpio_sigmap.h" +#include "hardware/esp32s3_i2c.h" +#include "hardware/esp32s3_soc.h" +#include "hardware/esp32s3_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 ESP32S3_I2CTIMEOTICKS \ + (SEC2TICK(CONFIG_ESP32S3_I2CTIMEOSEC) + MSEC2TICK(CONFIG_ESP32S3_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 + +/* 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 esp32s3_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 = 6, /* I2C restart command */ + I2C_CMD_WRITE = 1, /* I2C write command */ + I2C_CMD_READ = 3, /* I2C read command */ + I2C_CMD_STOP = 2, /* I2C stop command */ + I2C_CMD_END = 4 /* I2C end command */ +}; + +#ifdef CONFIG_I2C_TRACE + +/* Trace events */ + +enum esp32s3_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 esp32s3_trace_s +{ + uint32_t status; /* I2C 32-bit SR status */ + uint32_t count; /* Interrupt count when status change */ + enum esp32s3_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 esp32s3_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 esp32s3_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + + uint32_t id; /* I2C instance */ + + /* Port configuration */ + + const struct esp32s3_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 */ + uint8_t cpu; /* CPU ID */ +#endif + + /* I2C work state (see enum esp32s3_i2cstate_e) */ + + volatile enum esp32s3_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 */ + + spinlock_t lock; /* Device specific lock */ + +#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 esp32s3_trace_s trace[CONFIG_I2C_NTRACE]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void i2c_init_clock(struct esp32s3_i2c_priv_s *priv, + uint32_t clock); +static void i2c_init(struct esp32s3_i2c_priv_s *priv); +static void i2c_deinit(struct esp32s3_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 esp32s3_i2c_priv_s *priv, + uint32_t status); +static void i2c_sem_init(struct esp32s3_i2c_priv_s *priv); +static void i2c_sem_destroy(struct esp32s3_i2c_priv_s *priv); +static void i2c_sem_post(struct esp32s3_i2c_priv_s *priv); +static int i2c_sem_wait(struct esp32s3_i2c_priv_s *priv); +#ifndef CONFIG_I2C_POLLED +static int i2c_sem_waitdone(struct esp32s3_i2c_priv_s *priv); +#endif +#ifdef CONFIG_I2C_POLLED +static int i2c_polling_waitdone(struct esp32s3_i2c_priv_s *priv); +#endif +static void i2c_clear_bus(struct esp32s3_i2c_priv_s *priv); +static void i2c_reset_fsmc(struct esp32s3_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 esp32s3_i2c_priv_s *priv); +static void i2c_tracenew(struct esp32s3_i2c_priv_s *priv, uint32_t status); +static void i2c_traceevent(struct esp32s3_i2c_priv_s *priv, + enum esp32s3_trace_e event, + uint32_t parm, + uint32_t status); +static void i2c_tracedump(struct esp32s3_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* I2C interface */ + +static const struct i2c_ops_s g_esp32s3_i2c_ops = +{ + .transfer = i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = i2c_reset +#endif +}; + +/* I2C device structures */ + +#ifdef CONFIG_ESP32S3_I2C0 +static const struct esp32s3_i2c_config_s g_esp32s3_i2c0_config = +{ + .clk_freq = I2C_CLK_FREQ_DEF, + .scl_pin = CONFIG_ESP32S3_I2C0_SCLPIN, + .sda_pin = CONFIG_ESP32S3_I2C0_SDAPIN, +#ifndef CONFIG_I2C_POLLED + .periph = ESP32S3_PERIPH_I2C_EXT0, + .irq = ESP32S3_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 esp32s3_i2c_priv_s g_esp32s3_i2c0_priv = +{ + .ops = &g_esp32s3_i2c_ops, + .id = ESP32S3_I2C0, + .config = &g_esp32s3_i2c0_config, + .refs = 0, + .i2cstate = I2CSTATE_IDLE, + .msgv = NULL, + .msgid = 0, + .bytes = 0, + .ready_read = false +}; +#endif /* CONFIG_ESP32S3_I2C0 */ + +#ifdef CONFIG_ESP32S3_I2C1 +static const struct esp32s3_i2c_config_s g_esp32s3_i2c1_config = +{ + .clk_freq = I2C_CLK_FREQ_DEF, + .scl_pin = CONFIG_ESP32S3_I2C1_SCLPIN, + .sda_pin = CONFIG_ESP32S3_I2C1_SDAPIN, +#ifndef CONFIG_I2C_POLLED + .periph = ESP32S3_PERIPH_I2C_EXT1, + .irq = ESP32S3_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 esp32s3_i2c_priv_s g_esp32s3_i2c1_priv = +{ + .ops = &g_esp32s3_i2c_ops, + .id = ESP32S3_I2C1, + .config = &g_esp32s3_i2c1_config, + .refs = 0, + .i2cstate = I2CSTATE_IDLE, + .msgv = NULL, + .msgid = 0, + .bytes = 0, + .ready_read = false +}; +#endif /* CONFIG_ESP32S3_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 esp32s3_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 esp32s3_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 esp32s3_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 esp32s3_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), I2C_DATA_REG(priv->id)); + } + else + { + putreg32(I2C_READADDR8(msg->addr), I2C_DATA_REG(priv->id)); + } + + /* Enable I2C master TX interrupt */ + + i2c_intr_enable(priv); + + /* Update I2C configuration */ + + modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_CONF_UPGATE); + + /* 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 esp32s3_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], I2C_DATA_REG(priv->id)); + } + + priv->bytes += n; + + /* Enable I2C master TX interrupt */ + + i2c_intr_enable(priv); + + /* Update I2C configuration */ + + modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_CONF_UPGATE); + + /* 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 esp32s3_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(I2C_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 esp32s3_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); + + /* Update I2C configuration */ + + modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_CONF_UPGATE); + + /* 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 esp32s3_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); + + /* Update I2C configuration */ + + modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_CONF_UPGATE); + + /* 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 esp32s3_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 = XTAL_CLK_FREQ; + uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1; + uint32_t sclk_freq = source_clk / clkm_div; + uint32_t half_cycle = sclk_freq / bus_freq / 2; + + modifyreg32(I2C_CLK_CONF_REG(priv->id), I2C_SCLK_DIV_NUM_M, + VALUE_TO_FIELD((clkm_div - 1), I2C_SCLK_DIV_NUM)); + + /* According to the Technical Reference Manual, the following timings must + * be subtracted by 1. + * Moreover, the frequency calculation also shows that we must subtract 3 + * to the total SCL. + */ + + scl_low = half_cycle; + putreg32(scl_low - 1 - 2, I2C_SCL_LOW_PERIOD_REG(priv->id)); + + /* By default, scl_wait_high must be less than scl_high. + * A time compensation is needed for when the bus frequency is higher + * than 50K. + */ + + scl_high = (bus_freq <= 50000) ? half_cycle : + (half_cycle / 5 * 4 + 4); + scl_wait_high = half_cycle - scl_high; + + reg_value = VALUE_TO_FIELD(scl_high - 1 - 1, I2C_SCL_HIGH_PERIOD); + reg_value |= VALUE_TO_FIELD(scl_wait_high - 1 - 1, + I2C_SCL_WAIT_HIGH_PERIOD); + putreg32(reg_value, I2C_SCL_HIGH_PERIOD_REG(priv->id)); + + sda_hold = half_cycle / 2; + putreg32(sda_hold - 1, I2C_SDA_HOLD_REG(priv->id)); + + /* scl_wait_high < sda_sample <= scl_high */ + + sda_sample = half_cycle / 2; + putreg32(sda_sample - 1, I2C_SDA_SAMPLE_REG(priv->id)); + + setup = half_cycle; + putreg32(setup - 1, I2C_SCL_RSTART_SETUP_REG(priv->id)); + putreg32(setup - 1, I2C_SCL_STOP_SETUP_REG(priv->id)); + + hold = half_cycle; + putreg32(hold - 1, I2C_SCL_START_HOLD_REG(priv->id)); + putreg32(hold - 1, I2C_SCL_STOP_HOLD_REG(priv->id)); + + /* By default, we set the timeout value to about 10 bus cycles + * log(20*half_cycle)/log(2) = log(half_cycle)/log(2) + log(20)/log(2) + */ + + timeout = sizeof(half_cycle) * 8; + timeout -= __builtin_clz(5 * half_cycle); + timeout += 2; + + reg_value = I2C_TIME_OUT_EN; + reg_value |= VALUE_TO_FIELD(timeout, I2C_TIME_OUT_VALUE); + putreg32(reg_value, I2C_TO_REG(priv->id)); + + 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 esp32s3_i2c_priv_s *priv) +{ + const struct esp32s3_i2c_config_s *config = priv->config; + + esp32s3_gpiowrite(config->scl_pin, 1); + esp32s3_configgpio(config->scl_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN); + esp32s3_gpio_matrix_out(config->scl_pin, config->scl_outsig, 0, 0); + esp32s3_gpio_matrix_in(config->scl_pin, config->scl_insig, 0); + + esp32s3_gpiowrite(config->sda_pin, 1); + esp32s3_configgpio(config->sda_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN); + esp32s3_gpio_matrix_out(config->sda_pin, config->sda_outsig, 0, 0); + esp32s3_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 | I2C_SDA_FILTER_EN | + VALUE_TO_FIELD(I2C_FILTER_CYC_NUM_DEF, I2C_SCL_FILTER_THRES) | + VALUE_TO_FIELD(I2C_FILTER_CYC_NUM_DEF, I2C_SDA_FILTER_THRES), + I2C_FILTER_CFG_REG(priv->id)); + + /* Set I2C source clock */ + + modifyreg32(I2C_CLK_CONF_REG(priv->id), I2C_SCLK_SEL, 0); + + /* Configure I2C bus frequency */ + + i2c_init_clock(priv, config->clk_freq); + + /* Update I2C configuration */ + + modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_CONF_UPGATE); +} + +/**************************************************************************** + * Name: i2c_deinit + * + * Description: + * Disable I2C hardware. + * + * Parameters: + * priv - Pointer to the internal driver state structure. + * + ****************************************************************************/ + +static void i2c_deinit(struct esp32s3_i2c_priv_s *priv) +{ + const struct esp32s3_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 esp32s3_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 esp32s3_i2c_priv_s *priv) +{ + /* Wait on ISR semaphore */ + + return nxsem_tickwait_uninterruptible(&priv->sem_isr, + ESP32S3_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 esp32s3_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 esp32s3_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 esp32s3_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 esp32s3_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 esp32s3_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 esp32s3_i2c_priv_s *priv = (struct esp32s3_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 esp32s3_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_CTR_REG(priv->id), 0, I2C_CONF_UPGATE); + + 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 esp32s3_i2c_priv_s *priv = (struct esp32s3_i2c_priv_s *)dev; + + DEBUGASSERT(dev != NULL); + DEBUGASSERT(priv->refs > 0); + + flags = spin_lock_irqsave(&priv->lock); + + i2c_reset_fsmc(priv); + + /* Clear bus */ + + i2c_clear_bus(priv); + + priv->i2cstate = I2CSTATE_IDLE; + priv->msgid = 0; + priv->bytes = 0; + priv->ready_read = false; + + spin_unlock_irqrestore(&priv->lock, 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 esp32s3_i2c_priv_s *priv) +{ + struct esp32s3_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 esp32s3_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 esp32s3_i2c_priv_s *priv, uint32_t status) +{ + struct esp32s3_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 esp32s3_i2c_priv_s *priv, + enum esp32s3_trace_e event, + uint32_t parm, + uint32_t status) +{ + /* Check for new trace setup */ + + i2c_tracenew(priv, status); + + if (event != I2CEVENT_NONE) + { + struct esp32s3_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 esp32s3_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 esp32s3_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 esp32s3_i2c_priv_s *priv = (struct esp32s3_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 esp32s3_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: esp32s3_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 *esp32s3_i2cbus_initialize(int port) +{ + irqstate_t flags; + struct esp32s3_i2c_priv_s *priv; +#ifndef CONFIG_I2C_POLLED + const struct esp32s3_i2c_config_s *config; + int ret; +#endif + + switch (port) + { +#ifdef CONFIG_ESP32S3_I2C0 + case ESP32S3_I2C0: + priv = &g_esp32s3_i2c0_priv; + break; +#endif +#ifdef CONFIG_ESP32S3_I2C1 + case ESP32S3_I2C1: + priv = &g_esp32s3_i2c1_priv; + break; +#endif + default: + return NULL; + } + + flags = spin_lock_irqsave(&priv->lock); + + if (priv->refs++ != 0) + { + spin_unlock_irqrestore(&priv->lock, 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->cpu = up_cpu_index(); + priv->cpuint = esp32s3_setup_irq(priv->cpu, config->periph, + 1, ESP32S3_CPUINT_LEVEL); + if (priv->cpuint < 0) + { + /* Failed to allocate a CPU interrupt of this type */ + + spin_unlock_irqrestore(&priv->lock, flags); + + return NULL; + } + + ret = irq_attach(config->irq, i2c_irq, priv); + if (ret != OK) + { + esp32s3_teardown_irq(priv->cpu, config->periph, priv->cpuint); + + spin_unlock_irqrestore(&priv->lock, flags); + + return NULL; + } + + up_enable_irq(config->irq); +#endif + + i2c_sem_init(priv); + + i2c_init(priv); + + spin_unlock_irqrestore(&priv->lock, flags); + + return (struct i2c_master_s *)priv; +} + +/**************************************************************************** + * Name: esp32s3_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port and power down the device. + * + * Parameters: + * dev - Device structure as returned by + * esp32s3_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 esp32s3_i2cbus_uninitialize(struct i2c_master_s *dev) +{ + irqstate_t flags; + struct esp32s3_i2c_priv_s *priv = (struct esp32s3_i2c_priv_s *)dev; + + DEBUGASSERT(dev != NULL); + + if (priv->refs == 0) + { + return ERROR; + } + + flags = spin_lock_irqsave(&priv->lock); + + if (--priv->refs) + { + spin_unlock_irqrestore(&priv->lock, flags); + return OK; + } + + spin_unlock_irqrestore(&priv->lock, flags); + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->irq); + esp32s3_teardown_irq(priv->cpu, priv->config->periph, priv->cpuint); +#endif + + i2c_deinit(priv); + + i2c_sem_destroy(priv); + + return OK; +} + +#endif /* CONFIG_ESP32S3_I2C */ diff --git a/arch/xtensa/src/esp32s3/esp32s3_i2c.h b/arch/xtensa/src/esp32s3/esp32s3_i2c.h new file mode 100644 index 0000000000..3787b07ccf --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_i2c.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_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_ESP32S3_ESP32S3_I2C_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_ESP32S3_I2C0 +# define ESP32S3_I2C0 0 +#endif + +#ifdef CONFIG_ESP32S3_I2C1 +# define ESP32S3_I2C1 1 +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_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 *esp32s3_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: esp32s3_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameters: + * Device structure as returned by the esp32s3_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int esp32s3_i2cbus_uninitialize(struct i2c_master_s *dev); + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_I2C_H */ diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_i2c.h b/arch/xtensa/src/esp32s3/hardware/esp32s3_i2c.h new file mode 100644 index 0000000000..ca64fc1bb4 --- /dev/null +++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_i2c.h @@ -0,0 +1,1817 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/hardware/esp32s3_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_ESP32S3_HARDWARE_ESP32S3_I2C_H +#define __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "esp32s3_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: [8: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 0x000001ff +#define I2C_SCL_LOW_PERIOD_M (I2C_SCL_LOW_PERIOD_V << I2C_SCL_LOW_PERIOD_S) +#define I2C_SCL_LOW_PERIOD_V 0x000001ff +#define I2C_SCL_LOW_PERIOD_S 0 + +/* I2C_CTR_REG register + * Transmission setting + */ + +#define I2C_CTR_REG(i) (REG_I2C_BASE(i) + 0x4) + +/* I2C_ADDR_BROADCASTING_EN : R/W; bitpos: [14]; default: 0; + * This is the enable bit to support the 7bit general call function. + */ + +#define I2C_ADDR_BROADCASTING_EN (BIT(14)) +#define I2C_ADDR_BROADCASTING_EN_M (I2C_ADDR_BROADCASTING_EN_V << I2C_ADDR_BROADCASTING_EN_S) +#define I2C_ADDR_BROADCASTING_EN_V 0x00000001 +#define I2C_ADDR_BROADCASTING_EN_S 14 + +/* I2C_ADDR_10BIT_RW_CHECK_EN : R/W; bitpos: [13]; default: 0; + * This is the enable bit to check if the r/w bit of 10bit addressing + * consists with I2C protocol + */ + +#define I2C_ADDR_10BIT_RW_CHECK_EN (BIT(13)) +#define I2C_ADDR_10BIT_RW_CHECK_EN_M (I2C_ADDR_10BIT_RW_CHECK_EN_V << I2C_ADDR_10BIT_RW_CHECK_EN_S) +#define I2C_ADDR_10BIT_RW_CHECK_EN_V 0x00000001 +#define I2C_ADDR_10BIT_RW_CHECK_EN_S 13 + +/* I2C_SLV_TX_AUTO_START_EN : R/W; bitpos: [12]; default: 0; + * This is the enable bit for slave to send data automatically + */ + +#define I2C_SLV_TX_AUTO_START_EN (BIT(12)) +#define I2C_SLV_TX_AUTO_START_EN_M (I2C_SLV_TX_AUTO_START_EN_V << I2C_SLV_TX_AUTO_START_EN_S) +#define I2C_SLV_TX_AUTO_START_EN_V 0x00000001 +#define I2C_SLV_TX_AUTO_START_EN_S 12 + +/* I2C_CONF_UPGATE : WT; bitpos: [11]; default: 0; + * synchronization bit + */ + +#define I2C_CONF_UPGATE (BIT(11)) +#define I2C_CONF_UPGATE_M (I2C_CONF_UPGATE_V << I2C_CONF_UPGATE_S) +#define I2C_CONF_UPGATE_V 0x00000001 +#define I2C_CONF_UPGATE_S 11 + +/* I2C_FSM_RST : WT; bitpos: [10]; default: 0; + * This register is used to reset the scl FMS. + */ + +#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 arbitration_lost. + */ + +#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 : WT; bitpos: [5]; default: 0; + * Set this bit to start sending the data in txfifo. + */ + +#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: 3; + * 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_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_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: [5]; default: 0; + * This is the enable bit for time out control. + */ + +#define I2C_TIME_OUT_EN (BIT(5)) +#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 5 + +/* I2C_TIME_OUT_VALUE : R/W; bitpos: [4:0]; default: 16; + * This register is used to configure the timeout for receiving a data bit + * in APB + * clock cycles. + */ + +#define I2C_TIME_OUT_VALUE 0x0000001f +#define I2C_TIME_OUT_VALUE_M (I2C_TIME_OUT_VALUE_V << I2C_TIME_OUT_VALUE_S) +#define I2C_TIME_OUT_VALUE_V 0x0000001f +#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_TXFIFO_WADDR : RO; bitpos: [19:15]; default: 0; + * This is the offset address of APB bus writing to txfifo. + */ + +#define I2C_TXFIFO_WADDR 0x0000001f +#define I2C_TXFIFO_WADDR_M (I2C_TXFIFO_WADDR_V << I2C_TXFIFO_WADDR_S) +#define I2C_TXFIFO_WADDR_V 0x0000001f +#define I2C_TXFIFO_WADDR_S 15 + +/* I2C_TXFIFO_RADDR : RO; bitpos: [14:10]; default: 0; + * This is the offset address of i2c module reading from txfifo. + */ + +#define I2C_TXFIFO_RADDR 0x0000001f +#define I2C_TXFIFO_RADDR_M (I2C_TXFIFO_RADDR_V << I2C_TXFIFO_RADDR_S) +#define I2C_TXFIFO_RADDR_V 0x0000001f +#define I2C_TXFIFO_RADDR_S 10 + +/* I2C_RXFIFO_WADDR : RO; bitpos: [9:5]; default: 0; + * This is the offset address of i2c module receiving data and writing to + * rxfifo. + */ + +#define I2C_RXFIFO_WADDR 0x0000001f +#define I2C_RXFIFO_WADDR_M (I2C_RXFIFO_WADDR_V << I2C_RXFIFO_WADDR_S) +#define I2C_RXFIFO_WADDR_V 0x0000001f +#define I2C_RXFIFO_WADDR_S 5 + +/* I2C_RXFIFO_RADDR : RO; bitpos: [4:0]; default: 0; + * This is the offset address of the APB reading from rxfifo + */ + +#define I2C_RXFIFO_RADDR 0x0000001f +#define I2C_RXFIFO_RADDR_M (I2C_RXFIFO_RADDR_V << I2C_RXFIFO_RADDR_S) +#define I2C_RXFIFO_RADDR_V 0x0000001f +#define I2C_RXFIFO_RADDR_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: [14]; default: 1; + * The control enable bit of FIFO pointer in non-fifo access 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(14)) +#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 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 nonfifo access. + */ + +#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 nonfifo access mode. When + * reg_reg_fifo_prt_en is 1 and tx FIFO counter is smaller than + * reg_txfifo_wm_thrhd[4:0], reg_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 nonfifo access mode. When + * reg_reg_fifo_prt_en is 1 and rx FIFO counter is bigger than + * reg_rxfifo_wm_thrhd[4:0], reg_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_GENERAL_CALL_INT_RAW : R/SS/WTC; bitpos: [17]; default: 0; + * The raw interrupt bit for I2C_GENARAL_CALL_INT interrupt. + */ + +#define I2C_GENERAL_CALL_INT_RAW (BIT(17)) +#define I2C_GENERAL_CALL_INT_RAW_M (I2C_GENERAL_CALL_INT_RAW_V << I2C_GENERAL_CALL_INT_RAW_S) +#define I2C_GENERAL_CALL_INT_RAW_V 0x00000001 +#define I2C_GENERAL_CALL_INT_RAW_S 17 + +/* I2C_SLAVE_STRETCH_INT_RAW : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; 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 : R/SS/WTC; bitpos: [1]; default: 1; + * 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 : R/SS/WTC; 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_GENERAL_CALL_INT_CLR : WT; bitpos: [17]; default: 0; + * Set this bit for I2C_GENARAL_CALL_INT interrupt. + */ + +#define I2C_GENERAL_CALL_INT_CLR (BIT(17)) +#define I2C_GENERAL_CALL_INT_CLR_M (I2C_GENERAL_CALL_INT_CLR_V << I2C_GENERAL_CALL_INT_CLR_S) +#define I2C_GENERAL_CALL_INT_CLR_V 0x00000001 +#define I2C_GENERAL_CALL_INT_CLR_S 17 + +/* I2C_SLAVE_STRETCH_INT_CLR : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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 : WT; 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_GENERAL_CALL_INT_ENA : R/W; bitpos: [17]; default: 0; + * The interrupt enable bit for I2C_GENARAL_CALL_INT interrupt. + */ + +#define I2C_GENERAL_CALL_INT_ENA (BIT(17)) +#define I2C_GENERAL_CALL_INT_ENA_M (I2C_GENERAL_CALL_INT_ENA_V << I2C_GENERAL_CALL_INT_ENA_S) +#define I2C_GENERAL_CALL_INT_ENA_V 0x00000001 +#define I2C_GENERAL_CALL_INT_ENA_S 17 + +/* I2C_SLAVE_STRETCH_INT_ENA : R/W; bitpos: [16]; default: 0; + * The interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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 interrupt enable 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_GENERAL_CALL_INT_ST : RO; bitpos: [17]; default: 0; + * The masked interrupt status bit for I2C_GENARAL_CALL_INT interrupt. + */ + +#define I2C_GENERAL_CALL_INT_ST (BIT(17)) +#define I2C_GENERAL_CALL_INT_ST_M (I2C_GENERAL_CALL_INT_ST_V << I2C_GENERAL_CALL_INT_ST_S) +#define I2C_GENERAL_CALL_INT_ST_V 0x00000001 +#define I2C_GENERAL_CALL_INT_ST_S 17 + +/* 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: [8:0]; default: 0; + * This register is used to configure the time to hold the data after the + * negative + * edge of SCL, in I2C module clock cycles. + */ + +#define I2C_SDA_HOLD_TIME 0x000001ff +#define I2C_SDA_HOLD_TIME_M (I2C_SDA_HOLD_TIME_V << I2C_SDA_HOLD_TIME_S) +#define I2C_SDA_HOLD_TIME_V 0x000001ff +#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: [8:0]; default: 0; + * This register is used to configure for how long SDA is sampled, in I2C + * module clock cycles. + */ + +#define I2C_SDA_SAMPLE_TIME 0x000001ff +#define I2C_SDA_SAMPLE_TIME_M (I2C_SDA_SAMPLE_TIME_V << I2C_SDA_SAMPLE_TIME_S) +#define I2C_SDA_SAMPLE_TIME_V 0x000001ff +#define I2C_SDA_SAMPLE_TIME_S 0 + +/* I2C_SCL_HIGH_PERIOD_REG register + * Configures the high level width of SCL + */ + +#define I2C_SCL_HIGH_PERIOD_REG(i) (REG_I2C_BASE(i) + 0x38) + +/* I2C_SCL_WAIT_HIGH_PERIOD : R/W; bitpos: [15:9]; default: 0; + * This register is used to configure for the SCL_FSM's waiting period for + * SCL high level in master mode, in I2C module clock cycles. + */ + +#define I2C_SCL_WAIT_HIGH_PERIOD 0x0000007f +#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 0x0000007f +#define I2C_SCL_WAIT_HIGH_PERIOD_S 9 + +/* I2C_SCL_HIGH_PERIOD : R/W; bitpos: [8: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 0x000001ff +#define I2C_SCL_HIGH_PERIOD_M (I2C_SCL_HIGH_PERIOD_V << I2C_SCL_HIGH_PERIOD_S) +#define I2C_SCL_HIGH_PERIOD_V 0x000001ff +#define I2C_SCL_HIGH_PERIOD_S 0 + +/* I2C_SCL_START_HOLD_REG register + * Configures the delay between the SDA and SCL negative edge for a start + * condition + */ + +#define I2C_SCL_START_HOLD_REG(i) (REG_I2C_BASE(i) + 0x40) + +/* I2C_SCL_START_HOLD_TIME : R/W; bitpos: [8:0]; default: 8; + * This register is used to configure the time between the negative edge + * of SDA and the negative edge of SCL for a START condition, in I2C module + * clock cycles. + */ + +#define I2C_SCL_START_HOLD_TIME 0x000001ff +#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 0x000001ff +#define I2C_SCL_START_HOLD_TIME_S 0 + +/* I2C_SCL_RSTART_SETUP_REG register + * Configures the delay 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: [8:0]; default: 8; + * This register is used to configure the time 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 0x000001ff +#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 0x000001ff +#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: [8:0]; default: 8; + * This register is used to configure the delay after the STOP condition, + * in I2C module clock cycles. + */ + +#define I2C_SCL_STOP_HOLD_TIME 0x000001ff +#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 0x000001ff +#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: [8:0]; default: 8; + * 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 0x000001ff +#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 0x000001ff +#define I2C_SCL_STOP_SETUP_TIME_S 0 + +/* I2C_FILTER_CFG_REG register + * SCL and SDA filter configuration register + */ + +#define I2C_FILTER_CFG_REG(i) (REG_I2C_BASE(i) + 0x50) + +/* I2C_SDA_FILTER_EN : R/W; bitpos: [9]; default: 1; + * This is the filter enable bit for SDA. + */ + +#define I2C_SDA_FILTER_EN (BIT(9)) +#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 9 + +/* I2C_SCL_FILTER_EN : R/W; bitpos: [8]; default: 1; + * This is the filter enable bit for SCL. + */ + +#define I2C_SCL_FILTER_EN (BIT(8)) +#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 8 + +/* I2C_SDA_FILTER_THRES : R/W; bitpos: [7:4]; 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 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_CLK_CONF_REG register + * I2C CLK configuration register + */ + +#define I2C_CLK_CONF_REG(i) (REG_I2C_BASE(i) + 0x54) + +/* I2C_SCLK_ACTIVE : R/W; bitpos: [21]; default: 1; + * The clock switch for i2c module + */ + +#define I2C_SCLK_ACTIVE (BIT(21)) +#define I2C_SCLK_ACTIVE_M (I2C_SCLK_ACTIVE_V << I2C_SCLK_ACTIVE_S) +#define I2C_SCLK_ACTIVE_V 0x00000001 +#define I2C_SCLK_ACTIVE_S 21 + +/* I2C_SCLK_SEL : R/W; bitpos: [20]; default: 0; + * The clock selection for i2c module:0-XTAL;1-CLK_8MHz. + */ + +#define I2C_SCLK_SEL (BIT(20)) +#define I2C_SCLK_SEL_M (I2C_SCLK_SEL_V << I2C_SCLK_SEL_S) +#define I2C_SCLK_SEL_V 0x00000001 +#define I2C_SCLK_SEL_S 20 + +/* I2C_SCLK_DIV_B : R/W; bitpos: [19:14]; default: 0; + * the denominator of the fractional part of the fractional divisor for i2c + * module + */ + +#define I2C_SCLK_DIV_B 0x0000003f +#define I2C_SCLK_DIV_B_M (I2C_SCLK_DIV_B_V << I2C_SCLK_DIV_B_S) +#define I2C_SCLK_DIV_B_V 0x0000003f +#define I2C_SCLK_DIV_B_S 14 + +/* I2C_SCLK_DIV_A : R/W; bitpos: [13:8]; default: 0; + * the numerator of the fractional part of the fractional divisor for i2c + * module + */ + +#define I2C_SCLK_DIV_A 0x0000003f +#define I2C_SCLK_DIV_A_M (I2C_SCLK_DIV_A_V << I2C_SCLK_DIV_A_S) +#define I2C_SCLK_DIV_A_V 0x0000003f +#define I2C_SCLK_DIV_A_S 8 + +/* I2C_SCLK_DIV_NUM : R/W; bitpos: [7:0]; default: 0; + * the integral part of the fractional divisor for i2c module + */ + +#define I2C_SCLK_DIV_NUM 0x000000ff +#define I2C_SCLK_DIV_NUM_M (I2C_SCLK_DIV_NUM_V << I2C_SCLK_DIV_NUM_S) +#define I2C_SCLK_DIV_NUM_V 0x000000ff +#define I2C_SCLK_DIV_NUM_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/SS; 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/SS; 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/SS; 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/SS; 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/SS; 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/SS; 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/SS; 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/SS; 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_SCL_ST_TIME_OUT_REG register + * SCL status time out register + */ + +#define I2C_SCL_ST_TIME_OUT_REG(i) (REG_I2C_BASE(i) + 0x78) + +/* I2C_SCL_ST_TO_I2C : R/W; bitpos: [4:0]; default: 16; + * The threshold value of SCL_FSM state unchanged period. It should be o + * more than 23 + */ + +#define I2C_SCL_ST_TO_I2C 0x0000001f +#define I2C_SCL_ST_TO_I2C_M (I2C_SCL_ST_TO_I2C_V << I2C_SCL_ST_TO_I2C_S) +#define I2C_SCL_ST_TO_I2C_V 0x0000001f +#define I2C_SCL_ST_TO_I2C_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) + 0x7c) + +/* I2C_SCL_MAIN_ST_TO_I2C : R/W; bitpos: [4:0]; default: 16; + * The threshold value of SCL_MAIN_FSM state unchanged period.nIt should be + * o more than 23 + */ + +#define I2C_SCL_MAIN_ST_TO_I2C 0x0000001f +#define I2C_SCL_MAIN_ST_TO_I2C_M (I2C_SCL_MAIN_ST_TO_I2C_V << I2C_SCL_MAIN_ST_TO_I2C_S) +#define I2C_SCL_MAIN_ST_TO_I2C_V 0x0000001f +#define I2C_SCL_MAIN_ST_TO_I2C_S 0 + +/* I2C_SCL_SP_CONF_REG register + * Power configuration register + */ + +#define I2C_SCL_SP_CONF_REG(i) (REG_I2C_BASE(i) + 0x80) + +/* 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 reg_sda_force_out and reg_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 reg_scl_force_out and reg_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 + * reg_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/SC; bitpos: [0]; default: 0; + * When I2C master is IDLE, set this bit to send out SCL pulses. The number + * of pulses equals to reg_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) + 0x84) + +/* I2C_SLAVE_BYTE_ACK_LVL : R/W; bitpos: [13]; default: 0; + * Set the ACK level when slave controlling ACK level function enables. + */ + +#define I2C_SLAVE_BYTE_ACK_LVL (BIT(13)) +#define I2C_SLAVE_BYTE_ACK_LVL_M (I2C_SLAVE_BYTE_ACK_LVL_V << I2C_SLAVE_BYTE_ACK_LVL_S) +#define I2C_SLAVE_BYTE_ACK_LVL_V 0x00000001 +#define I2C_SLAVE_BYTE_ACK_LVL_S 13 + +/* I2C_SLAVE_BYTE_ACK_CTL_EN : R/W; bitpos: [12]; default: 0; + * The enable bit for slave to control ACK level function. + */ + +#define I2C_SLAVE_BYTE_ACK_CTL_EN (BIT(12)) +#define I2C_SLAVE_BYTE_ACK_CTL_EN_M (I2C_SLAVE_BYTE_ACK_CTL_EN_V << I2C_SLAVE_BYTE_ACK_CTL_EN_S) +#define I2C_SLAVE_BYTE_ACK_CTL_EN_V 0x00000001 +#define I2C_SLAVE_BYTE_ACK_CTL_EN_S 12 + +/* I2C_SLAVE_SCL_STRETCH_CLR : WT; 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 reg_slave_scl_stretch_en is 1 + * and stretch event happens. The stretch cause can be seen in + * reg_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 register + */ + +#define I2C_DATE_REG(i) (REG_I2C_BASE(i) + 0xf8) + +/* I2C_DATE : R/W; bitpos: [31:0]; default: 537330177; + * This is the the version 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 + +/* I2C_TXFIFO_START_ADDR_REG register + * I2C TXFIFO base address register + */ + +#define I2C_TXFIFO_START_ADDR_REG(i) (REG_I2C_BASE(i) + 0x100) + +/* I2C_TXFIFO_START_ADDR : RO; bitpos: [31:0]; default: 0; + * This is the I2C txfifo first address. + */ + +#define I2C_TXFIFO_START_ADDR 0xffffffff +#define I2C_TXFIFO_START_ADDR_M (I2C_TXFIFO_START_ADDR_V << I2C_TXFIFO_START_ADDR_S) +#define I2C_TXFIFO_START_ADDR_V 0xffffffff +#define I2C_TXFIFO_START_ADDR_S 0 + +/* I2C_RXFIFO_START_ADDR_REG register + * I2C RXFIFO base address register + */ + +#define I2C_RXFIFO_START_ADDR_REG(i) (REG_I2C_BASE(i) + 0x180) + +/* I2C_RXFIFO_START_ADDR : RO; bitpos: [31:0]; default: 0; + * This is the I2C rxfifo first address. + */ + +#define I2C_RXFIFO_START_ADDR 0xffffffff +#define I2C_RXFIFO_START_ADDR_M (I2C_RXFIFO_START_ADDR_V << I2C_RXFIFO_START_ADDR_S) +#define I2C_RXFIFO_START_ADDR_V 0xffffffff +#define I2C_RXFIFO_START_ADDR_S 0 + +#endif /* __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_I2C_H */ diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h b/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h index 45183f122a..5959aabf59 100644 --- a/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h +++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_soc.h @@ -258,7 +258,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)) /* Peripheral Clock */