From 7da023ceaea4b4d7e1ae92509ffcad62d154007b Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Tue, 4 Jan 2022 19:46:53 +0800 Subject: [PATCH 1/2] i2c: support esp32c2 --- components/driver/i2c.c | 61 +++- components/driver/include/driver/i2c.h | 6 +- .../include/esp32c3/rom/apb_backup_dma.h | 18 +- components/hal/esp32c2/include/hal/i2c_ll.h | 299 ++++++++---------- components/hal/esp32c2/rtc_cntl_hal.c | 15 + components/hal/i2c_hal.c | 50 ++- components/hal/i2c_hal_iram.c | 21 +- components/hal/include/hal/i2c_hal.h | 155 +++++---- components/hal/include/hal/i2c_types.h | 20 +- .../soc/esp32/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32/include/soc/soc_caps.h | 1 + .../soc/esp32c2/include/soc/i2c_struct.h | 193 +---------- components/soc/esp32c2/include/soc/soc_caps.h | 2 +- .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32h2/include/soc/soc_caps.h | 1 + .../esp32s2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32s2/include/soc/soc_caps.h | 1 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 28 ++ .../i2c/i2c_self_test/main/Kconfig.projbuild | 7 +- .../i2c/i2c_self_test/main/i2c_example_main.c | 24 +- .../i2c/i2c_simple/main/Kconfig.projbuild | 4 +- .../i2c/i2c_tools/partitions_example.csv | 2 +- tools/ci/check_copyright_ignore.txt | 4 - 25 files changed, 398 insertions(+), 531 deletions(-) diff --git a/components/driver/i2c.c b/components/driver/i2c.c index 22282a75df..878329a9fa 100644 --- a/components/driver/i2c.c +++ b/components/driver/i2c.c @@ -43,12 +43,14 @@ static const char *I2C_TAG = "i2c"; #define I2C_TIMING_VAL_ERR_STR "i2c timing value error" #define I2C_ADDR_ERROR_STR "i2c null address error" #define I2C_DRIVER_NOT_INSTALL_ERR_STR "i2c driver not installed" -#define I2C_SLAVE_BUFFER_LEN_ERR_STR "i2c buffer size too small for slave mode" +#if SOC_I2C_SUPPORT_SLAVE + #define I2C_SLAVE_BUFFER_LEN_ERR_STR "i2c buffer size too small for slave mode" + #define I2C_MODE_SLAVE_ERR_STR "Only allowed in slave mode" +#endif #define I2C_EVT_QUEUE_ERR_STR "i2c evt queue error" #define I2C_SEM_ERR_STR "i2c semaphore error" #define I2C_BUF_ERR_STR "i2c ringbuffer error" #define I2C_MASTER_MODE_ERR_STR "Only allowed in master mode" -#define I2C_MODE_SLAVE_ERR_STR "Only allowed in slave mode" #define I2C_CMD_MALLOC_ERR_STR "i2c command link malloc error" #define I2C_CMD_USER_ALLOC_ERR_STR "i2c command link allocation error: the buffer provided is too small." #define I2C_TRANS_MODE_ERR_STR "i2c trans mode error" @@ -70,9 +72,11 @@ static const char *I2C_TAG = "i2c"; #define I2C_CMD_EVT_ALIVE (0) #define I2C_CMD_EVT_DONE (1) #define I2C_EVT_QUEUE_LEN (1) -#define I2C_SLAVE_TIMEOUT_DEFAULT (32000) /* I2C slave timeout value, APB clock cycle number */ -#define I2C_SLAVE_SDA_SAMPLE_DEFAULT (10) /* I2C slave sample time after scl positive edge default value */ -#define I2C_SLAVE_SDA_HOLD_DEFAULT (10) /* I2C slave hold time after scl negative edge default value */ +#if SOC_I2C_SUPPORT_SLAVE + #define I2C_SLAVE_TIMEOUT_DEFAULT (32000) /* I2C slave timeout value, APB clock cycle number */ + #define I2C_SLAVE_SDA_SAMPLE_DEFAULT (10) /* I2C slave sample time after scl positive edge default value */ + #define I2C_SLAVE_SDA_HOLD_DEFAULT (10) /* I2C slave hold time after scl negative edge default value */ +#endif #define I2C_MASTER_TOUT_CNUM_DEFAULT (8) /* I2C master timeout cycle number of I2C clock, after which the timeout interrupt will be triggered */ #define I2C_ACKERR_CNT_MAX (10) #define I2C_FILTER_CYC_NUM_DEF (7) /* The number of apb cycles filtered by default*/ @@ -157,9 +161,10 @@ typedef struct { #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; #endif - +#if SOC_I2C_SUPPORT_SLAVE SemaphoreHandle_t slv_rx_mux; /*!< slave rx buffer mux */ SemaphoreHandle_t slv_tx_mux; /*!< slave tx buffer mux */ +#endif // SOC_I2C_SUPPORT_SLAVE size_t rx_buf_length; /*!< rx buffer length */ RingbufHandle_t rx_ring_buf; /*!< rx ringbuffer handler of slave mode */ size_t tx_buf_length; /*!< tx buffer length */ @@ -242,8 +247,10 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ int intr_alloc_flags) { ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR); +#if SOC_I2C_SUPPORT_SLAVE ESP_RETURN_ON_FALSE(mode == I2C_MODE_MASTER || ( slv_rx_buf_len > 100 || slv_tx_buf_len > 100 ), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SLAVE_BUFFER_LEN_ERR_STR); +#endif // SOC_I2C_SUPPORT_SLAVE esp_err_t ret = ESP_OK; if (p_i2c_obj[i2c_num] == NULL) { @@ -271,7 +278,7 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ #if CONFIG_SPIRAM_USE_MALLOC p_i2c->intr_alloc_flags = intr_alloc_flags; #endif - +#if SOC_I2C_SUPPORT_SLAVE if (mode == I2C_MODE_SLAVE) { //we only use ringbuffer for slave mode. if (slv_rx_buf_len > 0) { @@ -302,7 +309,9 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ ESP_LOGE(I2C_TAG, I2C_SEM_ERR_STR); goto err; } - } else { + } else +#endif // SOC_I2C_SUPPORT_SLAVE + { //semaphore to sync sending process, because we only have 32 bytes for hardware fifo. p_i2c->cmd_mux = xSemaphoreCreateMutex(); #ifdef CONFIG_PM_ENABLE @@ -353,10 +362,12 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ i2c_isr_handler_default, p_i2c_obj[i2c_num], &p_i2c_obj[i2c_num]->intr_handle); ESP_GOTO_ON_ERROR(ret, err, I2C_TAG, I2C_INTR_ALLOC_ERR_STR); +#if SOC_I2C_SUPPORT_SLAVE //Enable I2C slave rx interrupt if (mode == I2C_MODE_SLAVE) { i2c_hal_enable_slave_rx_it(&(i2c_context[i2c_num].hal)); } +#endif // SOC_I2C_SUPPORT_SLAVE return ESP_OK; err: @@ -379,12 +390,14 @@ err: if (p_i2c_obj[i2c_num]->cmd_mux) { vSemaphoreDelete(p_i2c_obj[i2c_num]->cmd_mux); } +#if SOC_I2C_SUPPORT_SALVE if (p_i2c_obj[i2c_num]->slv_rx_mux) { vSemaphoreDelete(p_i2c_obj[i2c_num]->slv_rx_mux); } if (p_i2c_obj[i2c_num]->slv_tx_mux) { vSemaphoreDelete(p_i2c_obj[i2c_num]->slv_tx_mux); } +#endif #ifdef CONFIG_PM_ENABLE if (p_i2c_obj[i2c_num]->pm_lock) { esp_pm_lock_delete(p_i2c_obj[i2c_num]->pm_lock); @@ -423,12 +436,14 @@ esp_err_t i2c_driver_delete(i2c_port_t i2c_num) vQueueDelete(p_i2c_obj[i2c_num]->cmd_evt_queue); p_i2c_obj[i2c_num]->cmd_evt_queue = NULL; } +#if SOC_I2C_SUPPORT_SLAVE if (p_i2c->slv_rx_mux) { vSemaphoreDelete(p_i2c->slv_rx_mux); } if (p_i2c->slv_tx_mux) { vSemaphoreDelete(p_i2c->slv_tx_mux); } +#endif if (p_i2c->rx_ring_buf) { vRingbufferDelete(p_i2c->rx_ring_buf); @@ -510,7 +525,9 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg) .type = I2C_CMD_EVT_ALIVE }; xQueueSendFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken); - } else { + } +#if SOC_I2C_SUPPORT_SLAVE + else { i2c_hal_slave_handle_event(&(i2c_context[i2c_num].hal), &evt_type); if (evt_type == I2C_INTR_EVENT_TRANS_DONE || evt_type == I2C_INTR_EVENT_RXFIFO_FULL) { uint32_t rx_fifo_cnt; @@ -532,6 +549,7 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg) i2c_hal_slave_clr_tx_it(&(i2c_context[i2c_num].hal)); } } +#endif // SOC_I2C_SUPPORT_SLAVE //We only need to check here if there is a high-priority task needs to be switched. if (HPTaskAwoken == pdTRUE) { portYIELD_FROM_ISR(); @@ -666,17 +684,20 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) if (i2c_conf->mode == I2C_MODE_MASTER) { src_clk = i2c_get_clk_src(i2c_conf->clk_flags, i2c_conf->master.clk_speed); ESP_RETURN_ON_FALSE(src_clk != I2C_SCLK_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_CLK_FLAG_ERR_STR); - } else { -#if CONFIG_IDF_TARGET_ESP32S2 + } +#if SOC_I2C_SUPPORT_SLAVE + else { + #if CONFIG_IDF_TARGET_ESP32S2 /* On ESP32-S2, APB clock shall always be used in slave mode as the * other one, I2C_SCLK_REF_TICK, is too slow, even for sampling a * 100KHz SCL. */ src_clk = I2C_SCLK_APB; -#else + #else src_clk = i2c_get_clk_src(i2c_conf->clk_flags, i2c_conf->slave.maximum_speed); ESP_RETURN_ON_FALSE(src_clk != I2C_SCLK_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_CLK_FLAG_ERR_STR); -#endif + #endif // CONFIG_IDF_TARGET_ESP32S2 } +#endif // SOC_I2C_SUPPORT_SLAVE ret = i2c_set_pin(i2c_num, i2c_conf->sda_io_num, i2c_conf->scl_io_num, i2c_conf->sda_pullup_en, i2c_conf->scl_pullup_en, i2c_conf->mode); @@ -687,6 +708,7 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_hal_disable_intr_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK); i2c_hal_clr_intsts_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK); +#if SOC_I2C_SUPPORT_SLAVE if (i2c_conf->mode == I2C_MODE_SLAVE) { //slave mode i2c_hal_slave_init(&(i2c_context[i2c_num].hal), i2c_num); i2c_hal_set_source_clk(&(i2c_context[i2c_num].hal), src_clk); @@ -697,7 +719,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) i2c_hal_set_sda_timing(&(i2c_context[i2c_num].hal), I2C_SLAVE_SDA_SAMPLE_DEFAULT, I2C_SLAVE_SDA_HOLD_DEFAULT); i2c_hal_set_tout(&(i2c_context[i2c_num].hal), I2C_SLAVE_TIMEOUT_DEFAULT); i2c_hal_enable_slave_rx_it(&(i2c_context[i2c_num].hal)); - } else { + } else +#endif // SOC_I2C_SUPPORT_SLAVE + { i2c_hal_master_init(&(i2c_context[i2c_num].hal), i2c_num); //Default, we enable hardware filter i2c_hal_set_filter(&(i2c_context[i2c_num].hal), I2C_FILTER_CYC_NUM_DEF); @@ -840,8 +864,10 @@ esp_err_t i2c_set_pin(i2c_port_t i2c_num, int sda_io_num, int scl_io_num, bool s ESP_RETURN_ON_FALSE(( i2c_num < I2C_NUM_MAX ), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR); ESP_RETURN_ON_FALSE(((sda_io_num < 0) || ((GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)))), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SDA_IO_ERR_STR); ESP_RETURN_ON_FALSE(scl_io_num < 0 || - (GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)) || - (GPIO_IS_VALID_GPIO(scl_io_num) && mode == I2C_MODE_SLAVE), +#if SOC_I2C_SUPPORT_SLAVE + (GPIO_IS_VALID_GPIO(scl_io_num) && mode == I2C_MODE_SLAVE) || +#endif // SOC_I2C_SUPPORT_SLAVE + (GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SCL_IO_ERR_STR); ESP_RETURN_ON_FALSE(sda_io_num < 0 || @@ -1499,7 +1525,7 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle, xSemaphoreGive(p_i2c->cmd_mux); return ret; } - +#if SOC_I2C_SUPPORT_SLAVE int i2c_slave_write_buffer(i2c_port_t i2c_num, const uint8_t *data, int size, TickType_t ticks_to_wait) { ESP_RETURN_ON_FALSE(( i2c_num < I2C_NUM_MAX ), ESP_FAIL, I2C_TAG, I2C_NUM_ERROR_STR); @@ -1563,3 +1589,4 @@ int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t *data, size_t max_size, Ti xSemaphoreGive(p_i2c->slv_rx_mux); return max_size - size_rem; } +#endif diff --git a/components/driver/include/driver/i2c.h b/components/driver/include/driver/i2c.h index 9eec372099..248c94af5a 100644 --- a/components/driver/include/driver/i2c.h +++ b/components/driver/include/driver/i2c.h @@ -75,11 +75,13 @@ typedef struct{ struct { uint32_t clk_speed; /*!< I2C clock frequency for master mode, (no higher than 1MHz for now) */ } master; /*!< I2C master config */ +#if SOC_I2C_SUPPORT_SLAVE struct { uint8_t addr_10bit_en; /*!< I2C 10bit address mode enable for slave mode */ uint16_t slave_addr; /*!< I2C address for slave mode */ uint32_t maximum_speed; /*!< I2C expected clock speed from SCL. */ } slave; /*!< I2C slave config */ +#endif // SOC_I2C_SUPPORT_SLAVE }; uint32_t clk_flags; /*!< Bitwise of ``I2C_SCLK_SRC_FLAG_**FOR_DFS**`` for clk source choice*/ } i2c_config_t; @@ -91,7 +93,7 @@ typedef void *i2c_cmd_handle_t; /*!< I2C command handle */ * @brief Install an I2C driver * * @param i2c_num I2C port number - * @param mode I2C mode (either master or slave) + * @param mode I2C mode (either master or slave). ESP8684 doesn't support i2c slave mode * @param slv_rx_buf_len Receiving buffer size. Only slave mode will use this value, it is ignored in master mode. * @param slv_tx_buf_len Sending buffer size. Only slave mode will use this value, it is ignored in master mode. * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. @@ -418,6 +420,7 @@ esp_err_t i2c_master_stop(i2c_cmd_handle_t cmd_handle); */ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle, TickType_t ticks_to_wait); +#if SOC_I2C_SUPPORT_SLAVE /** * @brief Write bytes to internal ringbuffer of the I2C slave data. When the TX fifo empty, the ISR will * fill the hardware FIFO with the internal ringbuffer's data. @@ -450,6 +453,7 @@ int i2c_slave_write_buffer(i2c_port_t i2c_num, const uint8_t *data, int size, Ti * - Others(>=0) The number of data bytes read from I2C slave buffer. */ int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t *data, size_t max_size, TickType_t ticks_to_wait); +#endif // SOC_I2C_SUPPORT_SLAVE /** * @brief Set I2C master clock period diff --git a/components/esp_rom/include/esp32c3/rom/apb_backup_dma.h b/components/esp_rom/include/esp32c3/rom/apb_backup_dma.h index d4e709b742..14948bbde1 100644 --- a/components/esp_rom/include/esp32c3/rom/apb_backup_dma.h +++ b/components/esp_rom/include/esp32c3/rom/apb_backup_dma.h @@ -1,16 +1,8 @@ -// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed 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. +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/hal/esp32c2/include/hal/i2c_ll.h b/components/hal/esp32c2/include/hal/i2c_ll.h index 4489dcff86..e779bd55af 100644 --- a/components/hal/esp32c2/include/hal/i2c_ll.h +++ b/components/hal/esp32c2/include/hal/i2c_ll.h @@ -7,8 +7,11 @@ // The LL layer for I2C register operations #pragma once + +#include "hal/misc.h" #include "soc/i2c_periph.h" #include "soc/soc_caps.h" +#include "soc/i2c_struct.h" #include "hal/i2c_types.h" #include "soc/rtc_cntl_reg.h" #include "esp_rom_sys.h" @@ -79,10 +82,6 @@ typedef struct { #define I2C_LL_MASTER_TX_INT (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M) // I2C master RX interrupt bitmap #define I2C_LL_MASTER_RX_INT (I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M) -// I2C slave TX interrupt bitmap -#define I2C_LL_SLAVE_TX_INT (I2C_TXFIFO_WM_INT_ENA_M) -// I2C slave RX interrupt bitmap -#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_WM_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M) // I2C source clock #define I2C_LL_CLK_SRC_FREQ(src_clk) (((src_clk) == I2C_SCLK_RTC) ? 20*1000*1000 : 40*1000*1000); // Another clock is XTAL clock // delay time after rtc_clk swiching on @@ -104,7 +103,24 @@ typedef struct { */ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal) { - abort(); //TODO: I2C support IDF-3918 + 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; + //SCL + clk_cal->clkm_div = clkm_div; + clk_cal->scl_low = half_cycle; + // default, scl_wait_high < scl_high + int scl_wait_high = (bus_freq <= 50000) ? 0 : (half_cycle / 8); // compensate the time when freq > 50K + clk_cal->scl_wait_high = scl_wait_high; + clk_cal->scl_high = half_cycle - scl_wait_high; + clk_cal->sda_hold = half_cycle / 4; + // scl_wait_high < sda_sample <= scl_high + clk_cal->sda_sample = half_cycle / 2; + clk_cal->setup = half_cycle; + clk_cal->hold = half_cycle; + //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) + clk_cal->tout = (int)(sizeof(half_cycle) * 8 - __builtin_clz(5 * half_cycle)) + 2; } /** @@ -116,7 +132,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2 */ static inline void i2c_ll_update(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->ctr.conf_upgate = 1; } /** @@ -129,7 +145,21 @@ static inline void i2c_ll_update(i2c_dev_t *hw) */ static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) { - abort(); //TODO: I2C support IDF-3918 + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1); + //scl period + hw->scl_low_period.scl_low_period = bus_cfg->scl_low - 1; + hw->scl_high_period.scl_high_period = bus_cfg->scl_high; + //sda sample + hw->sda_hold.sda_hold_time = bus_cfg->sda_hold; + hw->sda_sample.sda_sample_time = bus_cfg->sda_sample; + //setup + hw->scl_rstart_setup.scl_rstart_setup_time = bus_cfg->setup; + hw->scl_stop_setup.scl_stop_setup_time = bus_cfg->setup; + //hold + hw->scl_start_hold.scl_start_hold_time = bus_cfg->hold - 1; + hw->scl_stop_hold.scl_stop_hold_time = bus_cfg->hold; + hw->to.time_out_value = bus_cfg->tout; + hw->to.time_out_en = 1; } /** @@ -141,7 +171,8 @@ static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg) */ static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->fifo_conf.tx_fifo_rst = 1; + hw->fifo_conf.tx_fifo_rst = 0; } /** @@ -153,7 +184,8 @@ static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw) */ static inline void i2c_ll_rxfifo_rst(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->fifo_conf.rx_fifo_rst = 1; + hw->fifo_conf.rx_fifo_rst = 0; } /** @@ -167,7 +199,9 @@ static inline void i2c_ll_rxfifo_rst(i2c_dev_t *hw) */ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int low_period) { - abort(); //TODO: I2C support IDF-3918 + hw->scl_low_period.scl_low_period = low_period - 1; + hw->scl_high_period.scl_high_period = hight_period - 10; + hw->scl_high_period.scl_wait_high_period = hight_period - hw->scl_high_period.scl_high_period; } /** @@ -180,7 +214,7 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int lo */ static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask) { - abort(); //TODO: I2C support IDF-3918 + hw->int_clr.val = mask; } /** @@ -193,7 +227,7 @@ static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask) */ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask) { - abort(); //TODO: I2C support IDF-3918 + hw->int_ena.val |= mask; } /** @@ -206,7 +240,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask) */ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask) { - abort(); //TODO: I2C support IDF-3918 + hw->int_ena.val &= (~mask); } /** @@ -218,7 +252,7 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask) */ static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->int_status.val; } /** @@ -231,7 +265,7 @@ static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw) */ static inline void i2c_ll_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en) { - abort(); //TODO: I2C support IDF-3918 + hw->fifo_conf.nonfifo_en = fifo_mode_en ? 0 : 1; } /** @@ -244,21 +278,7 @@ static inline void i2c_ll_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en) */ static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout) { - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Configure I2C slave address - * - * @param hw Beginning address of the peripheral registers - * @param slave_addr I2C slave address needs to be set - * @param addr_10bit_en Set true to enable 10-bit slave address mode, set false to enable 7-bit address mode - * - * @return None - */ -static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, bool addr_10bit_en) -{ - abort(); //TODO: I2C support IDF-3918 + hw->to.time_out_value = tout; } /** @@ -272,7 +292,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo */ static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_hw_cmd_t cmd, int cmd_idx) { - abort(); //TODO: I2C support IDF-3918 + hw->command[cmd_idx].val = cmd.val; } /** @@ -286,7 +306,8 @@ static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_hw_cmd_t cmd, int cmd */ static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int start_hold) { - abort(); //TODO: I2C support IDF-3918 + hw->scl_rstart_setup.scl_rstart_setup_time = start_setup; + hw->scl_start_hold.scl_start_hold_time = start_hold - 1; } /** @@ -300,7 +321,8 @@ static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int s */ static inline void i2c_ll_set_stop_timing(i2c_dev_t *hw, int stop_setup, int stop_hold) { - abort(); //TODO: I2C support IDF-3918 + hw->scl_stop_setup.scl_stop_setup_time = stop_setup; + hw->scl_stop_hold.scl_stop_hold_time = stop_hold; } /** @@ -314,7 +336,8 @@ static inline void i2c_ll_set_stop_timing(i2c_dev_t *hw, int stop_setup, int sto */ static inline void i2c_ll_set_sda_timing(i2c_dev_t *hw, int sda_sample, int sda_hold) { - abort(); //TODO: I2C support IDF-3918 + hw->sda_hold.sda_hold_time = sda_hold; + hw->sda_sample.sda_sample_time = sda_sample; } /** @@ -327,7 +350,7 @@ static inline void i2c_ll_set_sda_timing(i2c_dev_t *hw, int sda_sample, int sda_ */ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) { - abort(); //TODO: I2C support IDF-3918 + hw->fifo_conf.txfifo_wm_thrhd = empty_thr; } /** @@ -340,7 +363,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { - abort(); //TODO: I2C support IDF-3918 + hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } /** @@ -354,7 +377,8 @@ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) */ static inline void i2c_ll_set_data_mode(i2c_dev_t *hw, i2c_trans_mode_t tx_mode, i2c_trans_mode_t rx_mode) { - abort(); //TODO: I2C support IDF-3918 + hw->ctr.tx_lsb_first = tx_mode; + hw->ctr.rx_lsb_first = rx_mode; } /** @@ -368,7 +392,8 @@ static inline void i2c_ll_set_data_mode(i2c_dev_t *hw, i2c_trans_mode_t tx_mode, */ static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode) { - abort(); //TODO: I2C support IDF-3918 + *tx_mode = hw->ctr.tx_lsb_first; + *rx_mode = hw->ctr.rx_lsb_first; } /** @@ -382,7 +407,8 @@ static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode */ static inline void i2c_ll_get_sda_timing(i2c_dev_t *hw, int *sda_sample, int *sda_hold) { - abort(); //TODO: I2C support IDF-3918 + *sda_hold = hw->sda_hold.sda_hold_time; + *sda_sample = hw->sda_sample.sda_sample_time; } /** @@ -394,7 +420,7 @@ static inline void i2c_ll_get_sda_timing(i2c_dev_t *hw, int *sda_sample, int *sd */ static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->date.date; } /** @@ -406,7 +432,7 @@ static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw) */ static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->sr.bus_busy; } /** @@ -418,7 +444,7 @@ static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw) */ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->ctr.ms_mode; } /** @@ -430,7 +456,7 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw) */ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->sr.rxfifo_cnt; } /** @@ -442,7 +468,7 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw) */ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt; } /** @@ -454,7 +480,7 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw) */ static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->to.time_out_value; } /** @@ -466,7 +492,7 @@ static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw) */ static inline void i2c_ll_trans_start(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->ctr.trans_start = 1; } /** @@ -480,7 +506,8 @@ static inline void i2c_ll_trans_start(i2c_dev_t *hw) */ static inline void i2c_ll_get_start_timing(i2c_dev_t *hw, int *setup_time, int *hold_time) { - abort(); //TODO: I2C support IDF-3918 + *setup_time = hw->scl_rstart_setup.scl_rstart_setup_time; + *hold_time = hw->scl_start_hold.scl_start_hold_time + 1; } /** @@ -494,7 +521,8 @@ static inline void i2c_ll_get_start_timing(i2c_dev_t *hw, int *setup_time, int * */ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *hold_time) { - abort(); //TODO: I2C support IDF-3918 + *setup_time = hw->scl_stop_setup.scl_stop_setup_time; + *hold_time = hw->scl_stop_hold.scl_stop_hold_time; } /** @@ -508,7 +536,8 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h */ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *low_period) { - abort(); //TODO: I2C support IDF-3918 + *high_period = hw->scl_high_period.scl_high_period + hw->scl_high_period.scl_wait_high_period; + *low_period = hw->scl_low_period.scl_low_period + 1; } /** @@ -522,7 +551,9 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l */ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - abort(); //TODO: I2C support IDF-3918 + for (int i = 0; i< len; i++) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); + } } /** @@ -536,7 +567,9 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) */ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - abort(); //TODO: I2C support IDF-3918 + for(int i = 0; i < len; i++) { + ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); + } } /** @@ -550,7 +583,15 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) */ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num) { - abort(); //TODO: I2C support IDF-3918 + if (filter_num > 0) { + hw->filter_cfg.scl_filter_thres = filter_num; + hw->filter_cfg.sda_filter_thres = filter_num; + hw->filter_cfg.scl_filter_en = 1; + hw->filter_cfg.sda_filter_en = 1; + } else { + hw->filter_cfg.scl_filter_en = 0; + hw->filter_cfg.sda_filter_en = 0; + } } /** @@ -562,7 +603,7 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num) */ static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + return hw->filter_cfg.scl_filter_thres; } /** @@ -574,7 +615,8 @@ static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw) */ static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->int_clr.val = ~0; + hw->int_ena.val = I2C_LL_MASTER_TX_INT; } /** @@ -586,7 +628,8 @@ static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw) */ static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->int_clr.val = ~0; + hw->int_ena.val = I2C_LL_MASTER_RX_INT; } /** @@ -598,7 +641,7 @@ static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw) */ static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT); } /** @@ -610,7 +653,7 @@ static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw) */ static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT); } /** @@ -622,7 +665,7 @@ static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw) */ static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->int_clr.val = I2C_LL_MASTER_TX_INT; } /** @@ -634,79 +677,7 @@ static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw) */ static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Enable I2C slave RX interrupt - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_enable_rx_it(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Disable I2C slave TX interrupt - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Disable I2C slave RX interrupt - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Clear I2C slave TX interrupt status register - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_clr_tx_it(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Clear I2C slave RX interrupt status register. - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_clr_rx_it(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 + hw->int_clr.val = I2C_LL_MASTER_RX_INT; } /** @@ -718,7 +689,7 @@ static inline void i2c_ll_slave_clr_rx_it(i2c_dev_t *hw) */ static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->ctr.fsm_rst = 1; } /** @@ -733,7 +704,13 @@ static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw) */ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 + hw->scl_sp_conf.scl_rst_slv_num = 9; + hw->scl_sp_conf.scl_rst_slv_en = 1; + hw->ctr.conf_upgate = 1; + // hardward will clear scl_rst_slv_en after sending SCL pulses, + // and we should set conf_upgate bit to synchronize register value. + while (hw->scl_sp_conf.scl_rst_slv_en); + hw->ctr.conf_upgate = 1; } /** @@ -746,7 +723,13 @@ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw) */ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_sclk_t src_clk) { - abort(); //TODO: I2C support IDF-3918 + // rtc_clk needs to switch on. + if (src_clk == I2C_SCLK_RTC) { + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); + esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); + } + // src_clk : (1) for RTC_CLK, (0) for XTAL + hw->clk_conf.sclk_sel = (src_clk == I2C_SCLK_RTC) ? 1 : 0; } /** @@ -759,20 +742,20 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_sclk_t src_clk) */ static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event) { - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Get I2C slave interrupt event - * - * @param hw Beginning address of the peripheral registers - * @param event Pointer to accept the interrupt event - * - * @return None - */ -static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event) -{ - abort(); //TODO: I2C support IDF-3918 + i2c_int_status_reg_t int_sts = hw->int_status; + if (int_sts.arbitration_lost_int_st) { + *event = I2C_INTR_EVENT_ARBIT_LOST; + } else if (int_sts.nack_int_st) { + *event = I2C_INTR_EVENT_NACK; + } else if (int_sts.time_out_int_st) { + *event = I2C_INTR_EVENT_TOUT; + } else if (int_sts.end_detect_int_st) { + *event = I2C_INTR_EVENT_END_DET; + } else if (int_sts.trans_complete_int_st) { + *event = I2C_INTR_EVENT_TRANS_DONE; + } else { + *event = I2C_INTR_EVENT_ERR; + } } /** @@ -784,19 +767,13 @@ static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event */ static inline void i2c_ll_master_init(i2c_dev_t *hw) { - abort(); //TODO: I2C support IDF-3918 -} - -/** - * @brief Init I2C slave - * - * @param hw Beginning address of the peripheral registers - * - * @return None - */ -static inline void i2c_ll_slave_init(i2c_dev_t *hw) -{ - abort(); //TODO: I2C support IDF-3918 + typeof(hw->ctr) ctrl_reg; + ctrl_reg.val = 0; + ctrl_reg.ms_mode = 1; + ctrl_reg.clk_en = 1; + ctrl_reg.sda_force_out = 1; + ctrl_reg.scl_force_out = 1; + hw->ctr.val = ctrl_reg.val; } #ifdef __cplusplus diff --git a/components/hal/esp32c2/rtc_cntl_hal.c b/components/hal/esp32c2/rtc_cntl_hal.c index 09121d3e62..7ee75a484d 100644 --- a/components/hal/esp32c2/rtc_cntl_hal.c +++ b/components/hal/esp32c2/rtc_cntl_hal.c @@ -10,6 +10,7 @@ #include "soc/lldesc.h" #include "hal/rtc_hal.h" #include "hal/assert.h" +#include "esp_attr.h" #define RTC_CNTL_HAL_LINK_BUF_SIZE_MIN (SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE) /* The minimum size of dma link buffer */ @@ -36,6 +37,7 @@ void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next) return (void *)plink; } +#if SOC_PM_SUPPORT_CPU_PD void rtc_cntl_hal_enable_cpu_retention(void *addr) { if (addr) { @@ -51,3 +53,16 @@ void rtc_cntl_hal_enable_cpu_retention(void *addr) rtc_cntl_ll_enable_cpu_retention((uint32_t)addr); } } + +void IRAM_ATTR rtc_cntl_hal_disable_cpu_retention(void *addr) +{ + rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr; + + if (addr) { + if (retent->cpu_pd_mem) { + rtc_cntl_ll_disable_cpu_retention(); + } + } +} + +#endif // SOC_PM_SUPPORT_CPU_PD diff --git a/components/hal/i2c_hal.c b/components/hal/i2c_hal.c index 2d975d8c99..1003c7ea50 100644 --- a/components/hal/i2c_hal.c +++ b/components/hal/i2c_hal.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed 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. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "hal/i2c_hal.h" @@ -79,11 +71,6 @@ void i2c_hal_set_tout(i2c_hal_context_t *hal, int tout_num) i2c_ll_set_tout(hal->dev, tout_num); } -void i2c_hal_set_slave_addr(i2c_hal_context_t *hal, uint16_t slave_addr, bool addr_10bit_en) -{ - i2c_ll_set_slave_addr(hal->dev, slave_addr, addr_10bit_en); -} - void i2c_hal_set_stop_timing(i2c_hal_context_t *hal, int stop_setup, int stop_hold) { i2c_ll_set_stop_timing(hal->dev, stop_setup, stop_hold); @@ -154,6 +141,12 @@ void i2c_hal_get_txfifo_cnt(i2c_hal_context_t *hal, uint32_t *len) *len = i2c_ll_get_txfifo_len(hal->dev); } +#if SOC_I2C_SUPPORT_SLAVE +void i2c_hal_set_slave_addr(i2c_hal_context_t *hal, uint16_t slave_addr, bool addr_10bit_en) +{ + i2c_ll_set_slave_addr(hal->dev, slave_addr, addr_10bit_en); +} + void i2c_hal_enable_slave_tx_it(i2c_hal_context_t *hal) { i2c_ll_slave_enable_tx_it(hal->dev); @@ -174,16 +167,6 @@ void i2c_hal_disable_slave_rx_it(i2c_hal_context_t *hal) i2c_ll_slave_disable_rx_it(hal->dev); } -void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_sclk_t src_clk) -{ - i2c_ll_set_source_clk(hal->dev, src_clk); - uint32_t sclk = I2C_LL_CLK_SRC_FREQ(src_clk); - i2c_clk_cal_t clk_cal = {0}; - uint32_t scl_hw_freq = (scl_freq == I2C_CLK_FREQ_MAX) ? (sclk / 20) : (uint32_t)scl_freq; // FREQ_MAX use the highest freq of the chosen clk. - i2c_ll_cal_bus_clk(sclk, scl_hw_freq, &clk_cal); - i2c_ll_set_bus_timing(hal->dev, &clk_cal); -} - void i2c_hal_slave_init(i2c_hal_context_t *hal, int i2c_num) { i2c_ll_slave_init(hal->dev); @@ -195,6 +178,17 @@ void i2c_hal_slave_init(i2c_hal_context_t *hal, int i2c_num) i2c_ll_txfifo_rst(hal->dev); i2c_ll_rxfifo_rst(hal->dev); } +#endif + +void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_sclk_t src_clk) +{ + i2c_ll_set_source_clk(hal->dev, src_clk); + uint32_t sclk = I2C_LL_CLK_SRC_FREQ(src_clk); + i2c_clk_cal_t clk_cal = {0}; + uint32_t scl_hw_freq = (scl_freq == I2C_CLK_FREQ_MAX) ? (sclk / 20) : (uint32_t)scl_freq; // FREQ_MAX use the highest freq of the chosen clk. + i2c_ll_cal_bus_clk(sclk, scl_hw_freq, &clk_cal); + i2c_ll_set_bus_timing(hal->dev, &clk_cal); +} void i2c_hal_master_clr_bus(i2c_hal_context_t *hal) { diff --git a/components/hal/i2c_hal_iram.c b/components/hal/i2c_hal_iram.c index f40d4a3a0b..a4d17740ea 100644 --- a/components/hal/i2c_hal_iram.c +++ b/components/hal/i2c_hal_iram.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed 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. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "hal/i2c_hal.h" @@ -42,8 +34,9 @@ void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *ev } } } - +#if SOC_I2C_SUPPORT_SLAVE void i2c_hal_slave_handle_event(i2c_hal_context_t *hal, i2c_intr_event_t *event) { i2c_ll_slave_get_event(hal->dev, event); } +#endif // SOC_I2C_SUPPORT_SLAVE diff --git a/components/hal/include/hal/i2c_hal.h b/components/hal/include/hal/i2c_hal.h index b255878cc4..dc0a5c0eba 100644 --- a/components/hal/include/hal/i2c_hal.h +++ b/components/hal/include/hal/i2c_hal.h @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed 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. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /******************************************************************************* * NOTICE @@ -92,6 +84,7 @@ typedef struct { */ #define i2c_hal_enable_master_tx_it(hal) i2c_ll_master_enable_tx_it((hal)->dev) +#if SOC_I2C_SUPPORT_SLAVE /** * @brief Clear I2C slave TX interrupt * @@ -110,6 +103,75 @@ typedef struct { */ #define i2c_hal_slave_clr_rx_it(hal) i2c_ll_slave_clr_rx_it((hal)->dev) +/** + * @brief Init the I2C slave. + * + * @param hal Context of the HAL layer + * @param i2c_num I2C port number + * + * @return None + */ +void i2c_hal_slave_init(i2c_hal_context_t *hal, i2c_port_t i2c_num); + +/** + * @brief Configure the I2C slave address + * + * @param hal Context of the HAL layer + * @param slave_addr Slave address + * @param addr_10bit_en Set true to enable 10-bit slave address mode, Set false to enable 7-bit address mode + * + * @return None + */ +void i2c_hal_set_slave_addr(i2c_hal_context_t *hal, uint16_t slave_addr, bool addr_10bit_en); + + +/** + * @brief Enable I2C slave TX interrupt + * + * @param hal Context of the HAL layer + * + * @return None + */ +void i2c_hal_enable_slave_tx_it(i2c_hal_context_t *hal); + +/** + * @brief Disable I2C slave TX interrupt + * + * @param hal Context of the HAL layer + * + * @return None + */ +void i2c_hal_disable_slave_tx_it(i2c_hal_context_t *hal); + +/** + * @brief Enable I2C slave RX interrupt + * + * @param hal Context of the HAL layer + * + * @return None + */ +void i2c_hal_enable_slave_rx_it(i2c_hal_context_t *hal); + +/** + * @brief Disable I2C slave RX interrupt + * + * @param hal Context of the HAL layer + * + * @return None + */ +void i2c_hal_disable_slave_rx_it(i2c_hal_context_t *hal); + +/** + * @brief I2C slave handle interrupt event + * + * @param hal Context of the HAL layer + * @param event Pointer to accept the interrupt event + * + * @return None + */ +void i2c_hal_slave_handle_event(i2c_hal_context_t *hal, i2c_intr_event_t *event); +#endif // SOC_I2C_SUPPORT_SLAVE + /** * @brief Set the source clock. This function is meant to be used in * slave mode, in order to select a source clock abe to handle @@ -130,16 +192,6 @@ typedef struct { */ void i2c_hal_master_init(i2c_hal_context_t *hal, i2c_port_t i2c_num); -/** - * @brief Init the I2C slave. - * - * @param hal Context of the HAL layer - * @param i2c_num I2C port number - * - * @return None - */ -void i2c_hal_slave_init(i2c_hal_context_t *hal, i2c_port_t i2c_num); - /** * @brief Reset the I2C hw txfifo * @@ -271,17 +323,6 @@ void i2c_hal_set_tout(i2c_hal_context_t *hal, int tout_val); */ void i2c_hal_get_tout(i2c_hal_context_t *hal, int *tout_val); -/** - * @brief Configure the I2C slave address - * - * @param hal Context of the HAL layer - * @param slave_addr Slave address - * @param addr_10bit_en Set true to enable 10-bit slave address mode, Set false to enable 7-bit address mode - * - * @return None - */ -void i2c_hal_set_slave_addr(i2c_hal_context_t *hal, uint16_t slave_addr, bool addr_10bit_en); - /** * @brief Configure the I2C stop timing * @@ -467,42 +508,6 @@ void i2c_hal_master_fsm_rst(i2c_hal_context_t *hal); */ void i2c_hal_master_clr_bus(i2c_hal_context_t *hal); -/** - * @brief Enable I2C slave TX interrupt - * - * @param hal Context of the HAL layer - * - * @return None - */ -void i2c_hal_enable_slave_tx_it(i2c_hal_context_t *hal); - -/** - * @brief Disable I2C slave TX interrupt - * - * @param hal Context of the HAL layer - * - * @return None - */ -void i2c_hal_disable_slave_tx_it(i2c_hal_context_t *hal); - -/** - * @brief Enable I2C slave RX interrupt - * - * @param hal Context of the HAL layer - * - * @return None - */ -void i2c_hal_enable_slave_rx_it(i2c_hal_context_t *hal); - -/** - * @brief Disable I2C slave RX interrupt - * - * @param hal Context of the HAL layer - * - * @return None - */ -void i2c_hal_disable_slave_rx_it(i2c_hal_context_t *hal); - /** * @brief I2C master handle tx interrupt event * @@ -523,16 +528,6 @@ void i2c_hal_master_handle_tx_event(i2c_hal_context_t *hal, i2c_intr_event_t *ev */ void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *event); -/** - * @brief I2C slave handle interrupt event - * - * @param hal Context of the HAL layer - * @param event Pointer to accept the interrupt event - * - * @return None - */ -void i2c_hal_slave_handle_event(i2c_hal_context_t *hal, i2c_intr_event_t *event); - /** * @brief Synchronize I2C status * diff --git a/components/hal/include/hal/i2c_types.h b/components/hal/include/hal/i2c_types.h index 12147c78b7..fba0bc9c70 100644 --- a/components/hal/include/hal/i2c_types.h +++ b/components/hal/include/hal/i2c_types.h @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed 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. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -28,7 +20,9 @@ extern "C" { typedef int i2c_port_t; typedef enum{ +#if SOC_I2C_SUPPORT_SLAVE I2C_MODE_SLAVE = 0, /*!< I2C slave mode */ +#endif I2C_MODE_MASTER, /*!< I2C master mode */ I2C_MODE_MAX, } i2c_mode_t; diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index e8167fa931..a2e570fb96 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -187,6 +187,10 @@ config SOC_I2C_FIFO_LEN int default 32 +config SOC_I2C_SUPPORT_SLAVE + bool + default y + config SOC_I2C_SUPPORT_APB bool default y diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 48fdaa66ff..fa58582e5e 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -154,6 +154,7 @@ #define SOC_I2C_NUM (2) #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ +#define SOC_I2C_SUPPORT_SLAVE (1) #define SOC_I2C_SUPPORT_APB (1) diff --git a/components/soc/esp32c2/include/soc/i2c_struct.h b/components/soc/esp32c2/include/soc/i2c_struct.h index d343277196..f0c22cb249 100644 --- a/components/soc/esp32c2/include/soc/i2c_struct.h +++ b/components/soc/esp32c2/include/soc/i2c_struct.h @@ -784,195 +784,29 @@ typedef union { /** Group: Command registers */ -/** Type of comd0 register - * I2C command register 0 +/** Type of comd register + * I2C command register 0~7 */ typedef union { struct { - /** command0 : R/W; bitpos: [13:0]; default: 0; - * This is the content of command 0. It consists of three parts: + /** command : R/W; bitpos: [13:0]; default: 0; + * This is the content of command. 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. */ - uint32_t command0:14; + uint32_t command:14; uint32_t reserved_14:17; - /** command0_done : R/W/SS; bitpos: [31]; default: 0; - * When command 0 is done in I2C Master mode, this bit changes to high + /** command_done : R/W/SS; bitpos: [31]; default: 0; + * When command is done in I2C Master mode, this bit changes to high * level. */ - uint32_t command0_done:1; + uint32_t command_done:1; }; uint32_t val; -} i2c_comd0_reg_t; - -/** Type of comd1 register - * I2C command register 1 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command1:14; - uint32_t reserved_14:17; - /** command1_done : R/W/SS; bitpos: [31]; default: 0; - * When command 1 is done in I2C Master mode, this bit changes to high - * level. - */ - uint32_t command1_done:1; - }; - uint32_t val; -} i2c_comd1_reg_t; - -/** Type of comd2 register - * I2C command register 2 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command2:14; - uint32_t reserved_14:17; - /** command2_done : R/W/SS; bitpos: [31]; default: 0; - * When command 2 is done in I2C Master mode, this bit changes to high - * Level. - */ - uint32_t command2_done:1; - }; - uint32_t val; -} i2c_comd2_reg_t; - -/** Type of comd3 register - * I2C command register 3 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command3:14; - uint32_t reserved_14:17; - /** command3_done : R/W/SS; bitpos: [31]; default: 0; - * When command 3 is done in I2C Master mode, this bit changes to high - * level. - */ - uint32_t command3_done:1; - }; - uint32_t val; -} i2c_comd3_reg_t; - -/** Type of comd4 register - * I2C command register 4 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command4:14; - uint32_t reserved_14:17; - /** command4_done : R/W/SS; bitpos: [31]; default: 0; - * When command 4 is done in I2C Master mode, this bit changes to high - * level. - */ - uint32_t command4_done:1; - }; - uint32_t val; -} i2c_comd4_reg_t; - -/** Type of comd5 register - * I2C command register 5 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command5:14; - uint32_t reserved_14:17; - /** command5_done : R/W/SS; bitpos: [31]; default: 0; - * When command 5 is done in I2C Master mode, this bit changes to high level. - */ - uint32_t command5_done:1; - }; - uint32_t val; -} i2c_comd5_reg_t; - -/** Type of comd6 register - * I2C command register 6 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command6:14; - uint32_t reserved_14:17; - /** command6_done : R/W/SS; bitpos: [31]; default: 0; - * When command 6 is done in I2C Master mode, this bit changes to high level. - */ - uint32_t command6_done:1; - }; - uint32_t val; -} i2c_comd6_reg_t; - -/** Type of comd7 register - * I2C command register 7 - */ -typedef union { - struct { - /** 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. - */ - uint32_t command7:14; - uint32_t reserved_14:17; - /** command7_done : R/W/SS; bitpos: [31]; default: 0; - * When command 7 is done in I2C Master mode, this bit changes to high level. - */ - uint32_t command7_done:1; - }; - uint32_t val; -} i2c_comd7_reg_t; - +} i2c_comd_reg_t; /** Group: Version register */ /** Type of date register @@ -1040,14 +874,7 @@ typedef struct { volatile i2c_scl_stop_setup_reg_t scl_stop_setup; volatile i2c_filter_cfg_reg_t filter_cfg; volatile i2c_clk_conf_reg_t clk_conf; - volatile i2c_comd0_reg_t comd0; - volatile i2c_comd1_reg_t comd1; - volatile i2c_comd2_reg_t comd2; - volatile i2c_comd3_reg_t comd3; - volatile i2c_comd4_reg_t comd4; - volatile i2c_comd5_reg_t comd5; - volatile i2c_comd6_reg_t comd6; - volatile i2c_comd7_reg_t comd7; + volatile i2c_comd_reg_t command[8]; volatile i2c_scl_st_time_out_reg_t scl_st_time_out; volatile i2c_scl_main_st_time_out_reg_t scl_main_st_time_out; volatile i2c_scl_sp_conf_reg_t scl_sp_conf; diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 6de911aa78..d07d769bd8 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -116,7 +116,7 @@ #define SOC_DEDIC_PERIPH_ALWAYS_ENABLE (1) /*!< The dedicated GPIO (a.k.a. fast GPIO) is featured by some customized CPU instructions, which is always enabled */ /*-------------------------- I2C CAPS ----------------------------------------*/ -// TODO IDF-3918 +// ESP32-C2 has 1 I2C #define SOC_I2C_NUM (1U) #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index c685d0048e..e393a511b7 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -275,6 +275,10 @@ config SOC_I2C_FIFO_LEN int default 32 +config SOC_I2C_SUPPORT_SLAVE + bool + default y + config SOC_I2C_SUPPORT_HW_FSM_RST bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 1616b63765..7f42c8cda4 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -145,6 +145,7 @@ #define SOC_I2C_NUM (1U) #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ +#define SOC_I2C_SUPPORT_SLAVE (1) #define SOC_I2C_SUPPORT_HW_FSM_RST (1) #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index c3b03428d0..20bb3eb969 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -255,6 +255,10 @@ config SOC_I2C_FIFO_LEN int default 32 +config SOC_I2C_SUPPORT_SLAVE + bool + default y + config SOC_I2C_SUPPORT_HW_FSM_RST bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 2b1a1d5bb7..4c5862d2bf 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -139,6 +139,7 @@ #define SOC_I2C_NUM (1U) #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ +#define SOC_I2C_SUPPORT_SLAVE (1) #define SOC_I2C_SUPPORT_HW_FSM_RST (1) #define SOC_I2C_SUPPORT_HW_CLR_BUS (1) diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 4974ffd1b7..94c1929055 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -267,6 +267,10 @@ config SOC_I2C_FIFO_LEN int default 32 +config SOC_I2C_SUPPORT_SLAVE + bool + default y + config SOC_I2C_SUPPORT_HW_FSM_RST bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index a5e6455b2d..9411514d28 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -145,6 +145,7 @@ #define SOC_I2C_NUM (2) #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ +#define SOC_I2C_SUPPORT_SLAVE (1) //ESP32-S2 support hardware FSM reset #define SOC_I2C_SUPPORT_HW_FSM_RST (1) diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index d786bcfe76..1cfcfaed1f 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -47,6 +47,34 @@ config SOC_GPIO_SUPPORT_SLP_SWITCH bool default y +config SOC_I2C_NUM + int + default 2 + +config SOC_I2C_FIFO_LEN + int + default 32 + +config SOC_I2C_SUPPORT_SLAVE + bool + default y + +config SOC_I2C_SUPPORT_HW_FSM_RST + bool + default y + +config SOC_I2C_SUPPORT_HW_CLR_BUS + bool + default y + +config SOC_I2C_SUPPORT_XTAL + bool + default y + +config SOC_I2C_SUPPORT_RTC + bool + default y + config SOC_LEDC_SUPPORT_XTAL_CLOCK bool default y diff --git a/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild b/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild index 2dccfd9e65..07933664a0 100644 --- a/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild +++ b/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild @@ -3,7 +3,7 @@ menu "Example Configuration" menu "I2C Master" config I2C_MASTER_SCL int "SCL GPIO Num" - default 6 if IDF_TARGET_ESP32C3 + default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 default 2 if IDF_TARGET_ESP32S3 default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 help @@ -11,7 +11,7 @@ menu "Example Configuration" config I2C_MASTER_SDA int "SDA GPIO Num" - default 5 if IDF_TARGET_ESP32C3 + default 5 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 default 1 if IDF_TARGET_ESP32S3 default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 help @@ -20,7 +20,7 @@ menu "Example Configuration" config I2C_MASTER_PORT_NUM int "Port Number" default 1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 - default 0 if IDF_TARGET_ESP32C3 + default 0 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 help Port number for I2C Master device. @@ -32,6 +32,7 @@ menu "Example Configuration" endmenu menu "I2C Slave" + depends on SOC_I2C_SUPPORT_SLAVE config I2C_SLAVE_SCL int "SCL GPIO Num" default 5 diff --git a/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c b/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c index b309efbee2..f5835cab8a 100644 --- a/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c +++ b/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c @@ -25,11 +25,14 @@ static const char *TAG = "i2c-example"; #define RW_TEST_LENGTH 128 /*!< Data length for r/w test, [0,DATA_LENGTH] */ #define DELAY_TIME_BETWEEN_ITEMS_MS 1000 /*!< delay time between different test items */ -#define I2C_SLAVE_SCL_IO CONFIG_I2C_SLAVE_SCL /*!< gpio number for i2c slave clock */ -#define I2C_SLAVE_SDA_IO CONFIG_I2C_SLAVE_SDA /*!< gpio number for i2c slave data */ -#define I2C_SLAVE_NUM I2C_NUMBER(CONFIG_I2C_SLAVE_PORT_NUM) /*!< I2C port number for slave dev */ -#define I2C_SLAVE_TX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave tx buffer size */ -#define I2C_SLAVE_RX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave rx buffer size */ +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) + #define I2C_SLAVE_SCL_IO CONFIG_I2C_SLAVE_SCL /*!< gpio number for i2c slave clock */ + #define I2C_SLAVE_SDA_IO CONFIG_I2C_SLAVE_SDA /*!< gpio number for i2c slave data */ + #define I2C_SLAVE_NUM I2C_NUMBER(CONFIG_I2C_SLAVE_PORT_NUM) /*!< I2C port number for slave dev */ + #define I2C_SLAVE_TX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave tx buffer size */ + #define I2C_SLAVE_RX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave rx buffer size */ + #define ESP_SLAVE_ADDR CONFIG_I2C_SLAVE_ADDRESS /*!< ESP32 slave address, you can set any 7bit value */ +#endif #define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< gpio number for I2C master data */ @@ -40,7 +43,6 @@ static const char *TAG = "i2c-example"; #define BH1750_SENSOR_ADDR CONFIG_BH1750_ADDR /*!< slave address for BH1750 sensor */ #define BH1750_CMD_START CONFIG_BH1750_OPMODE /*!< Operation mode */ -#define ESP_SLAVE_ADDR CONFIG_I2C_SLAVE_ADDRESS /*!< ESP32 slave address, you can set any 7bit value */ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ @@ -50,6 +52,7 @@ static const char *TAG = "i2c-example"; SemaphoreHandle_t print_mux = NULL; +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) /** * @brief test code to read esp-i2c-slave * We need to fill the buffer of esp slave device, then master can read them out. @@ -101,6 +104,7 @@ static esp_err_t __attribute__((unused)) i2c_master_write_slave(i2c_port_t i2c_n i2c_cmd_link_delete(cmd); return ret; } +#endif /** * @brief test code to operate on BH1750 sensor @@ -162,7 +166,7 @@ static esp_err_t i2c_master_init(void) return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } -#if !CONFIG_IDF_TARGET_ESP32C3 +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) /** * @brief i2c slave initialization */ @@ -205,7 +209,7 @@ static void i2c_test_task(void *arg) { int ret; uint32_t task_idx = (uint32_t)arg; -#if !CONFIG_IDF_TARGET_ESP32C3 +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) int i = 0; uint8_t *data = (uint8_t *)malloc(DATA_LENGTH); uint8_t *data_wr = (uint8_t *)malloc(DATA_LENGTH); @@ -232,7 +236,7 @@ static void i2c_test_task(void *arg) xSemaphoreGive(print_mux); vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_PERIOD_MS); //--------------------------------------------------- -#if !CONFIG_IDF_TARGET_ESP32C3 +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) for (i = 0; i < DATA_LENGTH; i++) { data[i] = i; } @@ -297,7 +301,7 @@ static void i2c_test_task(void *arg) void app_main(void) { print_mux = xSemaphoreCreateMutex(); -#if !CONFIG_IDF_TARGET_ESP32C3 +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) ESP_ERROR_CHECK(i2c_slave_init()); #endif ESP_ERROR_CHECK(i2c_master_init()); diff --git a/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild b/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild index dc9568c775..14f02e0d7e 100644 --- a/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild +++ b/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild @@ -2,14 +2,14 @@ menu "Example Configuration" config I2C_MASTER_SCL int "SCL GPIO Num" - default 6 if IDF_TARGET_ESP32C3 + default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 help GPIO number for I2C Master clock line. config I2C_MASTER_SDA int "SDA GPIO Num" - default 5 if IDF_TARGET_ESP32C3 + default 5 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 help GPIO number for I2C Master data line. diff --git a/examples/peripherals/i2c/i2c_tools/partitions_example.csv b/examples/peripherals/i2c/i2c_tools/partitions_example.csv index 1c79321a10..b6298ac549 100644 --- a/examples/peripherals/i2c/i2c_tools/partitions_example.csv +++ b/examples/peripherals/i2c/i2c_tools/partitions_example.csv @@ -3,4 +3,4 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, factory, app, factory, 0x10000, 1M, -storage, data, fat, , 1M, +storage, data, fat, , 0x80000, diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 432bea84f9..7cda0fc024 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -975,8 +975,6 @@ components/hal/esp32s3/include/hal/usb_ll.h components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h components/hal/esp32s3/interrupt_descriptor_table.c components/hal/gpio_hal.c -components/hal/i2c_hal.c -components/hal/i2c_hal_iram.c components/hal/include/hal/aes_hal.h components/hal/include/hal/aes_types.h components/hal/include/hal/brownout_hal.h @@ -985,8 +983,6 @@ components/hal/include/hal/dac_hal.h components/hal/include/hal/dac_types.h components/hal/include/hal/ds_hal.h components/hal/include/hal/esp_flash_err.h -components/hal/include/hal/i2c_hal.h -components/hal/include/hal/i2c_types.h components/hal/include/hal/interrupt_controller_hal.h components/hal/include/hal/interrupt_controller_types.h components/hal/include/hal/ledc_hal.h From cf353c505abf161b9633bd72aa8b3361ac219e41 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Tue, 4 Jan 2022 19:48:12 +0800 Subject: [PATCH 2/2] i2c: support esp32h2 --- components/driver/i2c.c | 2 +- components/driver/include/driver/i2c.h | 3 +- components/driver/test/test_i2c.c | 3 + components/driver/test/test_spi_slave.c | 2 +- components/driver/test/test_spi_slave_hd.c | 2 +- .../hal/esp32c2/include/hal/gpspi_flash_ll.h | 2 +- components/hal/esp32c2/include/hal/i2c_ll.h | 2 +- components/hal/esp32h2/include/hal/i2c_ll.h | 4 +- components/hal/esp32h2/rtc_cntl_hal.c | 33 +++--- components/hal/spi_flash_hal_iram.c | 2 +- .../soc/esp32c2/include/soc/i2c_struct.h | 1 - .../esp32s3/include/soc/Kconfig.soc_caps.in | 32 +----- components/soc/esp32s3/include/soc/soc_caps.h | 1 + docs/en/api-reference/peripherals/i2c.rst | 97 ++++++++++------ docs/zh_CN/api-reference/peripherals/i2c.rst | 2 +- .../host_test/fixtures/test_fixtures.hpp | 4 +- .../host_test/i2c/main/i2c_cxx_test.cpp | 2 + .../experimental_cpp_component/i2c_cxx.cpp | 2 + .../include/i2c_cxx.hpp | 4 +- .../test/test_i2c.cpp | 4 +- .../peripherals/i2c/i2c_self_test/README.md | 106 +++++++++--------- .../i2c/i2c_self_test/main/Kconfig.projbuild | 8 +- .../i2c/i2c_self_test/main/i2c_example_main.c | 17 ++- .../i2c/i2c_simple/main/Kconfig.projbuild | 4 +- examples/peripherals/i2c/i2c_tools/README.md | 40 +++---- .../i2c/i2c_tools/main/cmd_i2ctools.c | 7 +- .../i2c/i2c_tools/sdkconfig.defaults | 2 +- tools/ci/check_copyright_ignore.txt | 4 - 28 files changed, 210 insertions(+), 182 deletions(-) diff --git a/components/driver/i2c.c b/components/driver/i2c.c index 878329a9fa..e020cfbbb2 100644 --- a/components/driver/i2c.c +++ b/components/driver/i2c.c @@ -687,7 +687,7 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) } #if SOC_I2C_SUPPORT_SLAVE else { - #if CONFIG_IDF_TARGET_ESP32S2 + #if SOC_I2C_SUPPORT_REF_TICK /* On ESP32-S2, APB clock shall always be used in slave mode as the * other one, I2C_SCLK_REF_TICK, is too slow, even for sampling a * 100KHz SCL. */ diff --git a/components/driver/include/driver/i2c.h b/components/driver/include/driver/i2c.h index 248c94af5a..99974db424 100644 --- a/components/driver/include/driver/i2c.h +++ b/components/driver/include/driver/i2c.h @@ -91,9 +91,10 @@ typedef void *i2c_cmd_handle_t; /*!< I2C command handle */ /** * @brief Install an I2C driver + * @note Not all Espressif chips can support slave mode (e.g. ESP32C2) * * @param i2c_num I2C port number - * @param mode I2C mode (either master or slave). ESP8684 doesn't support i2c slave mode + * @param mode I2C mode (either master or slave). * @param slv_rx_buf_len Receiving buffer size. Only slave mode will use this value, it is ignored in master mode. * @param slv_tx_buf_len Sending buffer size. Only slave mode will use this value, it is ignored in master mode. * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. diff --git a/components/driver/test/test_i2c.c b/components/driver/test/test_i2c.c index 8b4ff403c0..fa601fc510 100644 --- a/components/driver/test/test_i2c.c +++ b/components/driver/test/test_i2c.c @@ -25,6 +25,7 @@ #include "hal/gpio_hal.h" #include "hal/uart_ll.h" +#if SOC_I2C_SUPPORT_SLAVE // i2c test can't work without slave #define DATA_LENGTH 512 /*!clk_conf.sclk_sel = (src_clk == I2C_SCLK_RTC) ? 1 : 0; diff --git a/components/hal/esp32h2/include/hal/i2c_ll.h b/components/hal/esp32h2/include/hal/i2c_ll.h index 2a86971151..d17327d7aa 100644 --- a/components/hal/esp32h2/include/hal/i2c_ll.h +++ b/components/hal/esp32h2/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -87,7 +87,7 @@ typedef struct { // I2C slave RX interrupt bitmap #define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_WM_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M) // I2C source clock -#define I2C_LL_CLK_SRC_FREQ(src_clk) (((src_clk) == I2C_SCLK_RTC) ? 20*1000*1000 : 40*1000*1000); // Another clock is XTAL clock +#define I2C_LL_CLK_SRC_FREQ(src_clk) (((src_clk) == I2C_SCLK_RTC) ? 8*1000*1000 : 32*1000*1000); // Another clock is XTAL clock // delay time after rtc_clk swiching on #define DELAY_RTC_CLK_SWITCH (5) // I2C max timeout value diff --git a/components/hal/esp32h2/rtc_cntl_hal.c b/components/hal/esp32h2/rtc_cntl_hal.c index 2fb14a5b2f..7ee75a484d 100644 --- a/components/hal/esp32h2/rtc_cntl_hal.c +++ b/components/hal/esp32h2/rtc_cntl_hal.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed 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. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // The HAL layer for RTC CNTL (common part) @@ -18,6 +10,7 @@ #include "soc/lldesc.h" #include "hal/rtc_hal.h" #include "hal/assert.h" +#include "esp_attr.h" #define RTC_CNTL_HAL_LINK_BUF_SIZE_MIN (SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE) /* The minimum size of dma link buffer */ @@ -44,6 +37,7 @@ void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next) return (void *)plink; } +#if SOC_PM_SUPPORT_CPU_PD void rtc_cntl_hal_enable_cpu_retention(void *addr) { if (addr) { @@ -59,3 +53,16 @@ void rtc_cntl_hal_enable_cpu_retention(void *addr) rtc_cntl_ll_enable_cpu_retention((uint32_t)addr); } } + +void IRAM_ATTR rtc_cntl_hal_disable_cpu_retention(void *addr) +{ + rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr; + + if (addr) { + if (retent->cpu_pd_mem) { + rtc_cntl_ll_disable_cpu_retention(); + } + } +} + +#endif // SOC_PM_SUPPORT_CPU_PD diff --git a/components/hal/spi_flash_hal_iram.c b/components/hal/spi_flash_hal_iram.c index 032875a162..cdf275538c 100644 --- a/components/hal/spi_flash_hal_iram.c +++ b/components/hal/spi_flash_hal_iram.c @@ -19,7 +19,7 @@ void spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t *host); // HAL for // - MEMSPI -// - SPI1~3 on ESP32/S2/S3/C3/H2/8684 +// - SPI1~3 on ESP32/S2/S3/C3/H2/C2 // The common part is in spi_flash_hal_common.inc void spi_flash_hal_erase_chip(spi_flash_host_inst_t *host) diff --git a/components/soc/esp32c2/include/soc/i2c_struct.h b/components/soc/esp32c2/include/soc/i2c_struct.h index f0c22cb249..a40ad248db 100644 --- a/components/soc/esp32c2/include/soc/i2c_struct.h +++ b/components/soc/esp32c2/include/soc/i2c_struct.h @@ -887,7 +887,6 @@ typedef struct { } i2c_dev_t; extern i2c_dev_t I2C0; -extern i2c_dev_t I2C1; #ifndef __cplusplus _Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 1cfcfaed1f..fdc0af1599 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -47,34 +47,6 @@ config SOC_GPIO_SUPPORT_SLP_SWITCH bool default y -config SOC_I2C_NUM - int - default 2 - -config SOC_I2C_FIFO_LEN - int - default 32 - -config SOC_I2C_SUPPORT_SLAVE - bool - default y - -config SOC_I2C_SUPPORT_HW_FSM_RST - bool - default y - -config SOC_I2C_SUPPORT_HW_CLR_BUS - bool - default y - -config SOC_I2C_SUPPORT_XTAL - bool - default y - -config SOC_I2C_SUPPORT_RTC - bool - default y - config SOC_LEDC_SUPPORT_XTAL_CLOCK bool default y @@ -383,6 +355,10 @@ config SOC_I2C_FIFO_LEN int default 32 +config SOC_I2C_SUPPORT_SLAVE + bool + default y + config SOC_I2C_SUPPORT_HW_FSM_RST bool default y diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 93fda42283..e5a1183595 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -128,6 +128,7 @@ #define SOC_I2C_NUM (2) #define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */ +#define SOC_I2C_SUPPORT_SLAVE (1) //ESP32-S3 support hardware FSM reset #define SOC_I2C_SUPPORT_HW_FSM_RST (1) diff --git a/docs/en/api-reference/peripherals/i2c.rst b/docs/en/api-reference/peripherals/i2c.rst index 7fb3e3246b..9de043e5a4 100644 --- a/docs/en/api-reference/peripherals/i2c.rst +++ b/docs/en/api-reference/peripherals/i2c.rst @@ -3,7 +3,7 @@ Inter-Integrated Circuit (I2C) :link_to_translation:`zh_CN:[中文]` -{IDF_TARGET_I2C_NUM:default="2", esp32c3="1", esp32h2="1", esp328684="1"} +{IDF_TARGET_I2C_NUM:default="2", esp32c3="1", esp32h2="1", esp32c2="1"} Overview -------- @@ -20,21 +20,30 @@ Driver Features I2C driver governs communications of devices over the I2C bus. The driver supports the following features: - Reading and writing bytes in Master mode -- Slave mode + +.. only:: SOC_I2C_SUPPORT_SLAVE + + - Slave mode + - Reading and writing to registers which are in turn read/written by the master Driver Usage ------------ +{IDF_TARGET_I2C_ROLE:default="master or slave", esp32c2="master"} + The following sections describe typical steps of configuring and operating the I2C driver: -1. :ref:`i2c-api-configure-driver` - set the initialization parameters (master or slave mode, GPIO pins for SDA and SCL, clock speed, etc.) -2. :ref:`i2c-api-install-driver`- activate the driver on one of the two I2C controllers as a master or slave -3. Depending on whether you configure the driver for a master or slave, choose the appropriate item +1. :ref:`i2c-api-configure-driver` - set the initialization parameters ({IDF_TARGET_I2C_ROLE} mode, GPIO pins for SDA and SCL, clock speed, etc.) +2. :ref:`i2c-api-install-driver`- activate the driver on one of the two I2C controllers as a {IDF_TARGET_I2C_ROLE} +3. Depending on whether you configure the driver for a {IDF_TARGET_I2C_ROLE}, choose the appropriate item - a) :ref:`i2c-api-master-mode` - handle communications (master) - b) :ref:`i2c-api-slave-mode` - respond to messages from the master (slave) + a) :ref:`i2c-api-master-mode` - handle communications (master) + + .. only:: SOC_I2C_SUPPORT_SLAVE + + b) :ref:`i2c-api-slave-mode` - respond to messages from the master (slave) 4. :ref:`i2c-api-interrupt-handling` - configure and service I2C interrupts 5. :ref:`i2c-api-customized-configuration` - adjust default I2C communication parameters (timings, bit order, etc.) @@ -49,17 +58,20 @@ Configuration To establish I2C communication, start by configuring the driver. This is done by setting the parameters of the structure :cpp:type:`i2c_config_t`: -- Set I2C **mode of operation** - slave or master from :cpp:type:`i2c_mode_t` +- Set I2C **mode of operation** - {IDF_TARGET_I2C_ROLE} from :cpp:type:`i2c_mode_t` - Configure **communication pins** - Assign GPIO pins for SDA and SCL signals - Set whether to enable {IDF_TARGET_NAME}'s internal pull-ups - (Master only) Set I2C **clock speed** -- (Slave only) Configure the following - * Whether to enable **10 bit address mode** - * Define **slave address** +.. only:: SOC_I2C_SUPPORT_SLAVE + + - (Slave only) Configure the following + + * Whether to enable **10 bit address mode** + * Define **slave address** After that, initialize the configuration for a given I2C port. For this, call the function :cpp:func:`i2c_param_config` and pass to it the port number and the structure :cpp:type:`i2c_config_t`. @@ -78,20 +90,22 @@ Configuration example (master): // .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */ }; -Configuration example (slave): +.. only:: SOC_I2C_SUPPORT_SLAVE -.. code-block:: c + Configuration example (slave): - int i2c_slave_port = I2C_SLAVE_NUM; - i2c_config_t conf_slave = { - .sda_io_num = I2C_SLAVE_SDA_IO, // select GPIO specific to your project - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_io_num = I2C_SLAVE_SCL_IO, // select GPIO specific to your project - .scl_pullup_en = GPIO_PULLUP_ENABLE, - .mode = I2C_MODE_SLAVE, - .slave.addr_10bit_en = 0, - .slave.slave_addr = ESP_SLAVE_ADDR, // address of your project - }; + .. code-block:: c + + int i2c_slave_port = I2C_SLAVE_NUM; + i2c_config_t conf_slave = { + .sda_io_num = I2C_SLAVE_SDA_IO, // select GPIO specific to your project + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_io_num = I2C_SLAVE_SCL_IO, // select GPIO specific to your project + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .mode = I2C_MODE_SLAVE, + .slave.addr_10bit_en = 0, + .slave.slave_addr = ESP_SLAVE_ADDR, // address of your project + }; At this stage, :cpp:func:`i2c_param_config` also sets a few other I2C configuration parameters to default values that are defined by the I2C specification. For more details on the values and how to modify them, see :ref:`i2c-api-customized-configuration`. @@ -200,8 +214,12 @@ Install Driver After the I2C driver is configured, install it by calling the function :cpp:func:`i2c_driver_install` with the following parameters: - Port number, one of the two port numbers from :cpp:type:`i2c_port_t` -- Master or slave, selected from :cpp:type:`i2c_mode_t` -- (Slave only) Size of buffers to allocate for sending and receiving data. As I2C is a master-centric bus, data can only go from the slave to the master at the master's request. Therefore, the slave will usually have a send buffer where the slave application writes data. The data remains in the send buffer to be read by the master at the master's own discretion. +- {IDF_TARGET_I2C_ROLE}, selected from :cpp:type:`i2c_mode_t` + +.. only:: SOC_I2C_SUPPORT_SLAVE + + - (Slave only) Size of buffers to allocate for sending and receiving data. As I2C is a master-centric bus, data can only go from the slave to the master at the master's request. Therefore, the slave will usually have a send buffer where the slave application writes data. The data remains in the send buffer to be read by the master at the master's own discretion. + - Flags for allocating the interrupt (see ESP_INTR_FLAG_* values in :component_file:`esp_hw_support/include/esp_intr_alloc.h`) .. _i2c-api-master-mode: @@ -278,27 +296,32 @@ Likewise, the command link to read from the slave looks as follows: i2c_master_write_byte(cmd, (ESP_SLAVE_ADDR << 1) | I2C_MASTER_READ, ACK_EN); -.. _i2c-api-slave-mode: +.. only:: SOC_I2C_SUPPORT_SLAVE -Communication as Slave -^^^^^^^^^^^^^^^^^^^^^^ + .. _i2c-api-slave-mode: -After installing the I2C driver, {IDF_TARGET_NAME} is ready to communicate with other I2C devices. + Communication as Slave + ^^^^^^^^^^^^^^^^^^^^^^ -The API provides the following functions for slaves + After installing the I2C driver, {IDF_TARGET_NAME} is ready to communicate with other I2C devices. -- :cpp:func:`i2c_slave_read_buffer` + The API provides the following functions for slaves - Whenever the master writes data to the slave, the slave will automatically store it in the receive buffer. This allows the slave application to call the function :cpp:func:`i2c_slave_read_buffer` at its own discretion. This function also has a parameter to specify block time if no data is in the receive buffer. This will allow the slave application to wait with a specified timeout for data to arrive to the buffer. + - :cpp:func:`i2c_slave_read_buffer` -- :cpp:func:`i2c_slave_write_buffer` + Whenever the master writes data to the slave, the slave will automatically store it in the receive buffer. This allows the slave application to call the function :cpp:func:`i2c_slave_read_buffer` at its own discretion. This function also has a parameter to specify block time if no data is in the receive buffer. This will allow the slave application to wait with a specified timeout for data to arrive to the buffer. - The send buffer is used to store all the data that the slave wants to send to the master in FIFO order. The data stays there until the master requests for it. The function :cpp:func:`i2c_slave_write_buffer` has a parameter to specify block time if the send buffer is full. This will allow the slave application to wait with a specified timeout for the adequate amount of space to become available in the send buffer. + - :cpp:func:`i2c_slave_write_buffer` -A code example showing how to use these functions can be found in :example:`peripherals/i2c`. + The send buffer is used to store all the data that the slave wants to send to the master in FIFO order. The data stays there until the master requests for it. The function :cpp:func:`i2c_slave_write_buffer` has a parameter to specify block time if the send buffer is full. This will allow the slave application to wait with a specified timeout for the adequate amount of space to become available in the send buffer. + A code example showing how to use these functions can be found in :example:`peripherals/i2c`. -.. _i2c-api-interrupt-handling: + .. _i2c-api-interrupt-handling: + +.. only:: not SOC_I2C_SUPPORT_SLAVE + + .. _i2c-api-interrupt-handling: Interrupt Handling ^^^^^^^^^^^^^^^^^^ @@ -369,7 +392,7 @@ Before calling :cpp:func:`i2c_driver_delete` to remove i2c driver, please make s Application Example ------------------- -I2C master and slave example: :example:`peripherals/i2c`. +I2C examples: :example:`peripherals/i2c`. API Reference diff --git a/docs/zh_CN/api-reference/peripherals/i2c.rst b/docs/zh_CN/api-reference/peripherals/i2c.rst index 502555df41..5c3b81b475 100644 --- a/docs/zh_CN/api-reference/peripherals/i2c.rst +++ b/docs/zh_CN/api-reference/peripherals/i2c.rst @@ -3,7 +3,7 @@ I2C 驱动程序 :link_to_translation:`en:[English]` -{IDF_TARGET_I2C_NUM:default="2", esp32c3="1", esp32h2="1", esp328684="1"} +{IDF_TARGET_I2C_NUM:default="2", esp32c3="1", esp32h2="1", esp32c2="1"} 概述 --------- diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp b/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp index 0d7d6597fe..484762c249 100644 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp +++ b/examples/cxx/experimental/experimental_cpp_component/host_test/fixtures/test_fixtures.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 * @@ -318,6 +318,7 @@ struct I2CMasterFix { i2c_port_t port; }; +#if CONFIG_SOC_I2C_SUPPORT_SLAVE struct I2CSlaveFix { I2CSlaveFix(CreateAnd flags, i2c_port_t port_arg = 0, size_t buffer_size = 64) : i2c_conf(), port(port_arg) { @@ -344,6 +345,7 @@ struct I2CSlaveFix { i2c_config_t i2c_conf; i2c_port_t port; }; +#endif // CONFIG_SOC_I2C_SUPPORT_SLAVE struct I2CCmdLinkFix { diff --git a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp index 3d7638e9d1..a3d2bcc085 100644 --- a/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp +++ b/examples/cxx/experimental/experimental_cpp_component/host_test/i2c/main/i2c_cxx_test.cpp @@ -376,6 +376,7 @@ TEST_CASE("I2CMaster syncronous transfer (read and write)") } } +#if SOC_I2C_SUPPORT_SLAVE TEST_CASE("I2CSlave parameter configuration fails") { CMockFixture fix; @@ -458,3 +459,4 @@ TEST_CASE("I2CSlave read calls driver functions correctly") CHECK(read_buffer[i] == WRITE_BUFFER[i]); } } +#endif // SOC_I2C_SUPPORT_SLAVE diff --git a/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp b/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp index c452f9dceb..e549aef15a 100644 --- a/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp +++ b/examples/cxx/experimental/experimental_cpp_component/i2c_cxx.cpp @@ -155,6 +155,7 @@ vector I2CMaster::sync_transfer(I2CAddress i2c_addr, return composed_transfer.do_transfer(i2c_num, i2c_addr)[0]; } +#if CONFIG_SOC_I2C_SUPPORT_SLAVE I2CSlave::I2CSlave(I2CNumber i2c_number, SCL_GPIO scl_gpio, SDA_GPIO sda_gpio, @@ -191,6 +192,7 @@ int I2CSlave::read_raw(uint8_t *buffer, size_t buffer_len, chrono::milliseconds { return i2c_slave_read_buffer(i2c_num.get_value(), buffer, buffer_len, (TickType_t) timeout.count() / portTICK_PERIOD_MS); } +#endif // CONFIG_SOC_I2C_SUPPORT_SLAVE I2CWrite::I2CWrite(const vector &bytes, chrono::milliseconds driver_timeout) : I2CTransfer(driver_timeout), bytes(bytes) diff --git a/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp index c497d3b566..8342a21965 100644 --- a/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp +++ b/examples/cxx/experimental/experimental_cpp_component/include/i2c_cxx.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -400,6 +400,7 @@ public: size_t read_n_bytes); }; +#if CONFIG_SOC_I2C_SUPPORT_SLAVE /** * @brief Responsible for initialization and de-initialization of an I2C slave peripheral. */ @@ -451,6 +452,7 @@ public: */ virtual int read_raw(uint8_t* buffer, size_t buffer_len, std::chrono::milliseconds timeout); }; +#endif // CONFIG_SOC_I2C_SUPPORT_SLAVE /** * Implementation for simple I2C writes, which can be executed by \c I2CMaster::transfer(). diff --git a/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp b/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp index da834d70c5..d64652d56a 100644 --- a/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp +++ b/examples/cxx/experimental/experimental_cpp_component/test/test_i2c.cpp @@ -54,8 +54,9 @@ struct MasterFixture { vector data; }; +#if SOC_I2C_SUPPORT_SALVE // TODO The I2C driver tests are disabled, so disable them here, too. Probably due to no runners. -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP8684) static void i2c_slave_read_raw_byte(void) { @@ -258,4 +259,5 @@ TEST_CASE_MULTIPLE_DEVICES("I2CMaster Composed transfer", "[cxx i2c][test_env=UT i2c_master_composed_trans, i2c_slave_composed_trans); #endif //TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) +#endif // SOC_I2C_SUPPORT_SALVE #endif // __cpp_exceptions diff --git a/examples/peripherals/i2c/i2c_self_test/README.md b/examples/peripherals/i2c/i2c_self_test/README.md index d9b3b440e6..38e3704434 100644 --- a/examples/peripherals/i2c/i2c_self_test/README.md +++ b/examples/peripherals/i2c/i2c_self_test/README.md @@ -65,14 +65,14 @@ To run this example, you should have one ESP development board (e.g. ESP32-WROVE **Note:** It is recommended to add external pull-up resistors for SDA/SCL pins to make the communication more stable, though the driver will enable internal pull-up resistors. -#### Pin Assignment(esp32c3): +#### Pin Assignment(esp32c3, esp32c2, esp32h2): **Note:** The following pin assignments are used by default, you can change these in the `menuconfig` . -| | SDA | SCL | -| ------------------------- | ------ | ------ | -| ESP32-C3 I2C Master(Slave)| GPIO5 | GPIO6 | -| BH1750 Sensor | SDA | SCL | +| | SDA | SCL | +| ------------------------------------------- | ------ | ------ | +| ESP32-C3/ESP32-C2/ESP32-H2 I2C Master(Slave)| GPIO5 | GPIO6 | +| BH1750 Sensor | SDA | SCL | - master: - GPIO5 is assigned to the data signal of the I2C master port @@ -121,70 +121,70 @@ sensor val: 386.67 [Lux] TASK[0] MASTER READ FROM SLAVE ******************* ====TASK[0] Slave buffer data ==== -00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f -10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f -20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f -30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f -40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f -50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f -60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f -70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f +60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f ====TASK[0] Master read ==== -00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f -10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f -20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f -30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f -40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f -50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f -60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f -70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f +60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f ******************* TASK[1] MASTER READ FROM SLAVE ******************* ====TASK[1] Slave buffer data ==== -00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f -10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f -20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f -30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f -40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f -50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f -60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f -70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f +60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f ====TASK[1] Master read ==== -00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f -10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f -20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f -30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f -40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f -50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f -60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f -70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f +60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f ******************* TASK[0] MASTER WRITE TO SLAVE ******************* ----TASK[0] Master write ---- -0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 -1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 -2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 -3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 -4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 -5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 -6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 -7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 +0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 +1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 +2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 +3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 +5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 +6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 +7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 ----TASK[0] Slave read: [128] bytes ---- -0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 -1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 -2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 -3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 -4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 -5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 -6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 -7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 +0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 +1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 +2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 +3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 +5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 +6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 +7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 ``` ## Troubleshooting diff --git a/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild b/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild index 07933664a0..7772ab1a71 100644 --- a/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild +++ b/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild @@ -3,7 +3,7 @@ menu "Example Configuration" menu "I2C Master" config I2C_MASTER_SCL int "SCL GPIO Num" - default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 + default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 default 2 if IDF_TARGET_ESP32S3 default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 help @@ -11,7 +11,7 @@ menu "Example Configuration" config I2C_MASTER_SDA int "SDA GPIO Num" - default 5 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 + default 5 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 default 1 if IDF_TARGET_ESP32S3 default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 help @@ -20,7 +20,7 @@ menu "Example Configuration" config I2C_MASTER_PORT_NUM int "Port Number" default 1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 - default 0 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 + default 0 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 help Port number for I2C Master device. @@ -32,7 +32,7 @@ menu "Example Configuration" endmenu menu "I2C Slave" - depends on SOC_I2C_SUPPORT_SLAVE + depends on SOC_I2C_NUM > 1 config I2C_SLAVE_SCL int "SCL GPIO Num" default 5 diff --git a/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c b/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c index f5835cab8a..184ccfcc35 100644 --- a/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c +++ b/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* i2c - Example For other examples please check: @@ -25,7 +30,7 @@ static const char *TAG = "i2c-example"; #define RW_TEST_LENGTH 128 /*!< Data length for r/w test, [0,DATA_LENGTH] */ #define DELAY_TIME_BETWEEN_ITEMS_MS 1000 /*!< delay time between different test items */ -#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) +#if SOC_I2C_NUM > 1 #define I2C_SLAVE_SCL_IO CONFIG_I2C_SLAVE_SCL /*!< gpio number for i2c slave clock */ #define I2C_SLAVE_SDA_IO CONFIG_I2C_SLAVE_SDA /*!< gpio number for i2c slave data */ #define I2C_SLAVE_NUM I2C_NUMBER(CONFIG_I2C_SLAVE_PORT_NUM) /*!< I2C port number for slave dev */ @@ -52,7 +57,7 @@ static const char *TAG = "i2c-example"; SemaphoreHandle_t print_mux = NULL; -#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) +#if SOC_I2C_NUM > 1 /** * @brief test code to read esp-i2c-slave * We need to fill the buffer of esp slave device, then master can read them out. @@ -166,7 +171,7 @@ static esp_err_t i2c_master_init(void) return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } -#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) +#if SOC_I2C_NUM > 1 /** * @brief i2c slave initialization */ @@ -209,7 +214,7 @@ static void i2c_test_task(void *arg) { int ret; uint32_t task_idx = (uint32_t)arg; -#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) +#if SOC_I2C_NUM > 1 int i = 0; uint8_t *data = (uint8_t *)malloc(DATA_LENGTH); uint8_t *data_wr = (uint8_t *)malloc(DATA_LENGTH); @@ -236,7 +241,7 @@ static void i2c_test_task(void *arg) xSemaphoreGive(print_mux); vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_PERIOD_MS); //--------------------------------------------------- -#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) +#if SOC_I2C_NUM > 1 for (i = 0; i < DATA_LENGTH; i++) { data[i] = i; } @@ -301,7 +306,7 @@ static void i2c_test_task(void *arg) void app_main(void) { print_mux = xSemaphoreCreateMutex(); -#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684) +#if SOC_I2C_NUM > 1 ESP_ERROR_CHECK(i2c_slave_init()); #endif ESP_ERROR_CHECK(i2c_master_init()); diff --git a/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild b/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild index 14f02e0d7e..ce85352b02 100644 --- a/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild +++ b/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild @@ -2,14 +2,14 @@ menu "Example Configuration" config I2C_MASTER_SCL int "SCL GPIO Num" - default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 + default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 help GPIO number for I2C Master clock line. config I2C_MASTER_SDA int "SDA GPIO Num" - default 5 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP8684 + default 5 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 help GPIO number for I2C Master data line. diff --git a/examples/peripherals/i2c/i2c_tools/README.md b/examples/peripherals/i2c/i2c_tools/README.md index 71176acfe2..9d70bb20bf 100644 --- a/examples/peripherals/i2c/i2c_tools/README.md +++ b/examples/peripherals/i2c/i2c_tools/README.md @@ -7,7 +7,7 @@ [I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) is a simple but very useful tool for developing I2C related applications, which is also famous in Linux platform. This example just implements some of basic features of [I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) based on [esp32 console component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html). As follows, this example supports five command-line tools: 1. `i2cconfig`: It will configure the I2C bus with specific GPIO number, port number and frequency. -2. `i2cdetect`: It will scan an I2C bus for devices and output a table with the list of detected devices on the bus. +2. `i2cdetect`: It will scan an I2C bus for devices and output a table with the list of detected devices on the bus. 3. `i2cget`: It will read registers visible through the I2C bus. 4. `i2cset`: It will set registers visible through the I2C bus. 5. `i2cdump`: It will examine registers visible through the I2C bus. @@ -30,6 +30,8 @@ To run this example, you should have any ESP32, ESP32-S and ESP32-C based develo | ESP32-S2 I2C Master | GPIO18 | GPIO19 | GND | GND | 3.3V | | ESP32-S3 I2C Master | GPIO1 | GPIO2 | GND | GND | 3.3V | | ESP32-C3 I2C Master | GPIO5 | GPIO6 | GND | GND | 3.3V | +| ESP32-C2 I2C Master | GPIO5 | GPIO6 | GND | GND | 3.3V | +| ESP32-H2 I2C Master | GPIO5 | GPIO6 | GND | GND | 3.3V | | Sensor | SDA | SCL | GND | WAK | VCC | **Note: ** There’s no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors itself. @@ -66,7 +68,7 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l ============================================================== i2c-tools> help -help +help Print the list of registered commands i2cconfig [--port=<0|1>] [--freq=] --sda= --scl= @@ -76,7 +78,7 @@ i2cconfig [--port=<0|1>] [--freq=] --sda= --scl= --sda= Set the gpio for I2C SDA --scl= Set the gpio for I2C SCL -i2cdetect +i2cdetect Scan I2C bus for devices i2cget -c [-r ] [-l ] @@ -96,17 +98,17 @@ i2cdump -c [-s ] -c, --chip= Specify the address of the chip on that bus -s, --size= Specify the size of each read -free +free Get the current size of free heap memory -heap +heap Get minimum size of free heap memory that was available during program execu tion -version +version Get version of chip and SDK -restart +restart Software reset of the chip deep_sleep [-t ] [--io=] [--io_level=<0|1>] @@ -124,7 +126,7 @@ light_sleep [-t ] [--io=]... [--io_level=<0|1>]... --io= If specified, wakeup using GPIO with given number --io_level=<0|1> GPIO level to trigger wakeup -tasks +tasks Get information about running tasks ``` @@ -143,14 +145,14 @@ esp32> i2cconfig --port=0 --sda=18 --scl=19 --freq=100000 ```bash esp32> i2cdetect 0 1 2 3 4 5 6 7 8 9 a b c d e f -00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -50: -- -- -- -- -- -- -- -- -- -- -- 5b -- -- -- -- -60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- -- 5b -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ``` * Here we found the address of CCS811 is 0x5b. @@ -159,7 +161,7 @@ esp32> i2cdetect ```bash esp32> i2cget -c 0x5b -r 0x00 -l 1 -0x10 +0x10 ``` * `-c` option to specify the address of I2C device (acquired from `i2cdetect` command). @@ -175,7 +177,7 @@ I (734717) cmd_i2ctools: Write OK esp32> i2cset -c 0x5b -r 0x01 0x10 I (1072047) cmd_i2ctools: Write OK esp32> i2cget -c 0x5b -r 0x00 -l 1 -0x98 +0x98 ``` * Here we change the mode from boot to application and set a proper measure mode (by writing 0x10 to register 0x01) @@ -185,7 +187,7 @@ esp32> i2cget -c 0x5b -r 0x00 -l 1 ```bash esp32> i2cget -c 0x5b -r 0x02 -l 8 -0x01 0xb0 0x00 0x04 0x98 0x00 0x19 0x8f +0x01 0xb0 0x00 0x04 0x98 0x00 0x19 0x8f ``` * The register 0x02 will output 8 bytes result, mainly including value of eCO~2~、TVOC and there raw value. So the value of eCO~2~ is 0x01b0 ppm and value of TVOC is 0x04 ppb. diff --git a/examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.c b/examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.c index 996a2975b1..551128228d 100644 --- a/examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.c +++ b/examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* cmd_i2ctools.c This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -26,7 +31,7 @@ static const char *TAG = "cmd_i2ctools"; #if CONFIG_IDF_TARGET_ESP32S3 static gpio_num_t i2c_gpio_sda = 1; static gpio_num_t i2c_gpio_scl = 2; -#elif CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP8684 static gpio_num_t i2c_gpio_sda = 5; static gpio_num_t i2c_gpio_scl = 6; #else diff --git a/examples/peripherals/i2c/i2c_tools/sdkconfig.defaults b/examples/peripherals/i2c/i2c_tools/sdkconfig.defaults index 2d3564c649..fc9a5ae743 100644 --- a/examples/peripherals/i2c/i2c_tools/sdkconfig.defaults +++ b/examples/peripherals/i2c/i2c_tools/sdkconfig.defaults @@ -14,4 +14,4 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv" CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 7cda0fc024..80f554a504 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -590,7 +590,6 @@ components/esp_rom/include/esp32/rom/tjpgd.h components/esp_rom/include/esp32/rom/uart.h components/esp_rom/include/esp32c2/rom/md5_hash.h components/esp_rom/include/esp32c3/rom/aes.h -components/esp_rom/include/esp32c3/rom/apb_backup_dma.h components/esp_rom/include/esp32c3/rom/bigint.h components/esp_rom/include/esp32c3/rom/cache.h components/esp_rom/include/esp32c3/rom/crc.h @@ -912,7 +911,6 @@ components/hal/esp32h2/include/hal/twai_ll.h components/hal/esp32h2/include/hal/uhci_ll.h components/hal/esp32h2/include/hal/uhci_types.h components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h -components/hal/esp32h2/rtc_cntl_hal.c components/hal/esp32s2/brownout_hal.c components/hal/esp32s2/cp_dma_hal.c components/hal/esp32s2/include/hal/adc_hal_conf.h @@ -2333,10 +2331,8 @@ examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/include/matrix_keyboard.h examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/src/matrix_keyboard.c examples/peripherals/gpio/matrix_keyboard/main/matrix_keyboard_example_main.c -examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c examples/peripherals/i2c/i2c_tools/example_test.py -examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.c examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.h examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c examples/peripherals/i2s/i2s_adc_dac/main/app_main.c