mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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
This commit is contained in:
commit
cc1d89ebba
@ -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"
|
||||
#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)
|
||||
#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,8 +684,10 @@ 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. */
|
||||
@ -675,8 +695,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf)
|
||||
#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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 |
|
||||
|
@ -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 |
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 )
|
||||
|
||||
|
@ -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
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,20 +20,29 @@ 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
|
||||
|
||||
.. 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)
|
||||
|
||||
.. 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
|
||||
@ -49,13 +58,16 @@ 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**
|
||||
|
||||
.. only:: SOC_I2C_SUPPORT_SLAVE
|
||||
|
||||
- (Slave only) Configure the following
|
||||
|
||||
* Whether to enable **10 bit address mode**
|
||||
@ -78,6 +90,8 @@ Configuration example (master):
|
||||
// .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
|
||||
};
|
||||
|
||||
.. only:: SOC_I2C_SUPPORT_SLAVE
|
||||
|
||||
Configuration example (slave):
|
||||
|
||||
.. code-block:: c
|
||||
@ -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`
|
||||
- {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,6 +296,8 @@ 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);
|
||||
|
||||
|
||||
.. only:: SOC_I2C_SUPPORT_SLAVE
|
||||
|
||||
.. _i2c-api-slave-mode:
|
||||
|
||||
Communication as Slave
|
||||
@ -297,6 +317,9 @@ The API provides the following functions for slaves
|
||||
|
||||
A code example showing how to use these functions can be found in :example:`peripherals/i2c`.
|
||||
|
||||
.. _i2c-api-interrupt-handling:
|
||||
|
||||
.. only:: not SOC_I2C_SUPPORT_SLAVE
|
||||
|
||||
.. _i2c-api-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
|
||||
|
@ -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"}
|
||||
|
||||
概述
|
||||
---------
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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().
|
||||
|
@ -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
|
||||
|
@ -65,13 +65,13 @@ 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 |
|
||||
| ------------------------------------------- | ------ | ------ |
|
||||
| ESP32-C3/ESP32-C2/ESP32-H2 I2C Master(Slave)| GPIO5 | GPIO6 |
|
||||
| BH1750 Sensor | SDA | SCL |
|
||||
|
||||
- master:
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
#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());
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user