Merge branch 'feature/i2c_support_on_esp8684_esp32h2' into 'master'

i2c: support i2c on esp32c2 and esp32h2

Closes IDF-3918

See merge request espressif/esp-idf!16444
pull/8484/head
Kevin (Lao Kaiyao) 2022-02-28 13:59:02 +08:00
commit cc1d89ebba
44 zmienionych plików z 565 dodań i 670 usunięć

Wyświetl plik

@ -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 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. */
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

Wyświetl plik

@ -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;
@ -89,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)
* @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.
@ -418,6 +421,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 +454,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

Wyświetl plik

@ -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 /*!<Data buffer length for test buffer*/
#define RW_TEST_LENGTH 129 /*!<Data length for r/w test, any value from 0-DATA_LENGTH*/
@ -723,3 +724,5 @@ TEST_CASE("I2C SCL freq test (local test)", "[i2c][ignore]")
}
#endif // TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3)
#endif // SOC_I2C_SUPPORT_SLAVE

Wyświetl plik

@ -266,7 +266,7 @@ TEST_CASE("test slave send unaligned","[spi]")
/********************************************************************************
* Test By Master & Slave (2 boards)
*
* Master (C3, 8684, H2) && Slave (C3, 8684, H2):
* Master (C3, C2, H2) && Slave (C3, C2, H2):
* PIN | Master | Slave |
* ----| --------- | --------- |
* CS | 10 | 10 |

Wyświetl plik

@ -605,7 +605,7 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
/********************************************************************************
* Test By Master & Slave (2 boards)
*
* Master (C3, 8684, H2) && Slave (C3, 8684, H2):
* Master (C3, C2, H2) && Slave (C3, C2, H2):
* PIN | Master | Slave |
* ----| --------- | --------- |
* CS | 10 | 10 |

Wyświetl plik

@ -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

Wyświetl plik

@ -26,7 +26,7 @@
extern "C" {
#endif
//NOTE: These macros are changed on 8684 for build. MODIFY these when bringup flash.
//NOTE: These macros are changed on ESP32-C2 for build. MODIFY these when bringup flash.
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )

Wyświetl plik

@ -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); // TODO: IDF-4535
}
// 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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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)
{

Wyświetl plik

@ -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

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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;

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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;
@ -1060,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");

Wyświetl plik

@ -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 */

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -355,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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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"}
概述
---------

Wyświetl plik

@ -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
{

Wyświetl plik

@ -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

Wyświetl plik

@ -155,6 +155,7 @@ vector<uint8_t> 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<uint8_t> &bytes, chrono::milliseconds driver_timeout)
: I2CTransfer<void>(driver_timeout), bytes(bytes)

Wyświetl plik

@ -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().

Wyświetl plik

@ -54,8 +54,9 @@ struct MasterFixture {
vector<uint8_t> 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

Wyświetl plik

@ -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

Wyświetl plik

@ -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_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
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
default 0 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2
help
Port number for I2C Master device.
@ -32,6 +32,7 @@ menu "Example Configuration"
endmenu
menu "I2C Slave"
depends on SOC_I2C_NUM > 1
config I2C_SLAVE_SCL
int "SCL GPIO Num"
default 5

Wyświetl plik

@ -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,11 +30,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 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 */
#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 +48,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 +57,7 @@ static const char *TAG = "i2c-example";
SemaphoreHandle_t print_mux = NULL;
#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.
@ -101,6 +109,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 +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
#if SOC_I2C_NUM > 1
/**
* @brief i2c slave initialization
*/
@ -205,7 +214,7 @@ static void i2c_test_task(void *arg)
{
int ret;
uint32_t task_idx = (uint32_t)arg;
#if !CONFIG_IDF_TARGET_ESP32C3
#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);
@ -232,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
#if SOC_I2C_NUM > 1
for (i = 0; i < DATA_LENGTH; i++) {
data[i] = i;
}
@ -297,7 +306,7 @@ static void i2c_test_task(void *arg)
void app_main(void)
{
print_mux = xSemaphoreCreateMutex();
#if !CONFIG_IDF_TARGET_ESP32C3
#if SOC_I2C_NUM > 1
ESP_ERROR_CHECK(i2c_slave_init());
#endif
ESP_ERROR_CHECK(i2c_master_init());

Wyświetl plik

@ -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_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
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.

Wyświetl plik

@ -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: ** Theres 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=<Hz>] --sda=<gpio> --scl=<gpio>
@ -76,7 +78,7 @@ i2cconfig [--port=<0|1>] [--freq=<Hz>] --sda=<gpio> --scl=<gpio>
--sda=<gpio> Set the gpio for I2C SDA
--scl=<gpio> Set the gpio for I2C SCL
i2cdetect
i2cdetect
Scan I2C bus for devices
i2cget -c <chip_addr> [-r <register_addr>] [-l <length>]
@ -96,17 +98,17 @@ i2cdump -c <chip_addr> [-s <size>]
-c, --chip=<chip_addr> Specify the address of the chip on that bus
-s, --size=<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 <t>] [--io=<n>] [--io_level=<0|1>]
@ -124,7 +126,7 @@ light_sleep [-t <t>] [--io=<n>]... [--io_level=<0|1>]...
--io=<n> 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.

Wyświetl plik

@ -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

Wyświetl plik

@ -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,

1 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 1M,
6 storage, data, fat, , 1M, storage, data, fat, , 0x80000,

Wyświetl plik

@ -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

Wyświetl plik

@ -566,7 +566,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
@ -886,7 +885,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
@ -947,8 +945,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
@ -957,8 +953,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
@ -2261,10 +2255,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