mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
I2C: Refactor i2c hal and ll
This commit is contained in:
parent
5e47c7ce13
commit
31b88a4c88
@ -34,8 +34,6 @@
|
||||
#include "clk_ctrl_os.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static const char *I2C_TAG = "i2c";
|
||||
|
||||
/* DRAM_ATTR is required to avoid I2C array placed in flash, due to accessed from ISR */
|
||||
@ -376,8 +374,8 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_
|
||||
}
|
||||
i2c_hw_enable(i2c_num);
|
||||
//Disable I2C interrupt.
|
||||
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);
|
||||
i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
//hook isr handler
|
||||
ret = esp_intr_alloc(i2c_periph_signal[i2c_num].irq, intr_alloc_flags,
|
||||
i2c_isr_handler_default, p_i2c_obj[i2c_num],
|
||||
@ -386,7 +384,7 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_
|
||||
#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));
|
||||
i2c_ll_slave_enable_rx_it(i2c_context[i2c_num].hal.dev);
|
||||
}
|
||||
#endif // SOC_I2C_SUPPORT_SLAVE
|
||||
return ESP_OK;
|
||||
@ -443,7 +441,7 @@ esp_err_t i2c_driver_delete(i2c_port_t i2c_num)
|
||||
ESP_RETURN_ON_FALSE(p_i2c_obj[i2c_num] != NULL, ESP_FAIL, I2C_TAG, I2C_DRIVER_ERR_STR);
|
||||
|
||||
i2c_obj_t *p_i2c = p_i2c_obj[i2c_num];
|
||||
i2c_hal_disable_intr_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK);
|
||||
i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
esp_intr_free(p_i2c->intr_handle);
|
||||
p_i2c->intr_handle = NULL;
|
||||
|
||||
@ -500,7 +498,7 @@ esp_err_t i2c_reset_tx_fifo(i2c_port_t i2c_num)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_txfifo_rst(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_txfifo_rst(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -509,7 +507,7 @@ esp_err_t i2c_reset_rx_fifo(i2c_port_t i2c_num)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_rxfifo_rst(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_rxfifo_rst(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -522,7 +520,7 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg)
|
||||
// On C3 and S3 targets, the I2C may trigger a spurious interrupt,
|
||||
// in order to detect these false positive, check the I2C's hardware interrupt mask
|
||||
uint32_t int_mask;
|
||||
i2c_hal_get_intsts_mask(&(i2c_context[i2c_num].hal), &int_mask);
|
||||
i2c_ll_get_intr_mask(i2c_context[i2c_num].hal.dev, &int_mask);
|
||||
if (int_mask == 0) {
|
||||
return;
|
||||
}
|
||||
@ -561,25 +559,25 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg)
|
||||
}
|
||||
#if SOC_I2C_SUPPORT_SLAVE
|
||||
else {
|
||||
i2c_hal_slave_handle_event(&(i2c_context[i2c_num].hal), &evt_type);
|
||||
i2c_ll_slave_get_event(i2c_context[i2c_num].hal.dev, &evt_type);
|
||||
if (evt_type == I2C_INTR_EVENT_TRANS_DONE || evt_type == I2C_INTR_EVENT_RXFIFO_FULL) {
|
||||
uint32_t rx_fifo_cnt;
|
||||
i2c_hal_get_rxfifo_cnt(&(i2c_context[i2c_num].hal), &rx_fifo_cnt);
|
||||
i2c_hal_read_rxfifo(&(i2c_context[i2c_num].hal), p_i2c->data_buf, rx_fifo_cnt);
|
||||
i2c_ll_get_rxfifo_cnt(i2c_context[i2c_num].hal.dev, &rx_fifo_cnt);
|
||||
i2c_ll_read_rxfifo(i2c_context[i2c_num].hal.dev, p_i2c->data_buf, rx_fifo_cnt);
|
||||
xRingbufferSendFromISR(p_i2c->rx_ring_buf, p_i2c->data_buf, rx_fifo_cnt, &HPTaskAwoken);
|
||||
i2c_hal_slave_clr_rx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, int_mask);
|
||||
} else if (evt_type == I2C_INTR_EVENT_TXFIFO_EMPTY) {
|
||||
uint32_t tx_fifo_rem;
|
||||
i2c_hal_get_txfifo_cnt(&(i2c_context[i2c_num].hal), &tx_fifo_rem);
|
||||
i2c_ll_get_txfifo_len(i2c_context[i2c_num].hal.dev, &tx_fifo_rem);
|
||||
size_t size = 0;
|
||||
uint8_t *data = (uint8_t *) xRingbufferReceiveUpToFromISR(p_i2c->tx_ring_buf, &size, tx_fifo_rem);
|
||||
if (data) {
|
||||
i2c_hal_write_txfifo(&(i2c_context[i2c_num].hal), data, size);
|
||||
i2c_ll_write_txfifo(i2c_context[i2c_num].hal.dev, data, size);
|
||||
vRingbufferReturnItemFromISR(p_i2c->tx_ring_buf, data, &HPTaskAwoken);
|
||||
} else {
|
||||
i2c_hal_disable_slave_tx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_slave_disable_tx_it(i2c_context[i2c_num].hal.dev);
|
||||
}
|
||||
i2c_hal_slave_clr_tx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, int_mask);
|
||||
}
|
||||
}
|
||||
#endif // SOC_I2C_SUPPORT_SLAVE
|
||||
@ -595,8 +593,8 @@ esp_err_t i2c_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode,
|
||||
ESP_RETURN_ON_FALSE(tx_trans_mode < I2C_DATA_MODE_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TRANS_MODE_ERR_STR);
|
||||
ESP_RETURN_ON_FALSE(rx_trans_mode < I2C_DATA_MODE_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TRANS_MODE_ERR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_data_mode(&(i2c_context[i2c_num].hal), tx_trans_mode, rx_trans_mode);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_data_mode(i2c_context[i2c_num].hal.dev, tx_trans_mode, rx_trans_mode);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -604,7 +602,7 @@ esp_err_t i2c_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode,
|
||||
esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode, i2c_trans_mode_t *rx_trans_mode)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
i2c_hal_get_data_mode(&(i2c_context[i2c_num].hal), tx_trans_mode, rx_trans_mode);
|
||||
i2c_ll_get_data_mode(i2c_context[i2c_num].hal.dev, tx_trans_mode, rx_trans_mode);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -642,7 +640,7 @@ static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
|
||||
gpio_set_level(sda_io, 1); // STOP, SDA low -> high while SCL is HIGH
|
||||
i2c_set_pin(i2c_num, sda_io, scl_io, 1, 1, I2C_MODE_MASTER);
|
||||
#else
|
||||
i2c_hal_master_clr_bus(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_master_clr_bus(i2c_context[i2c_num].hal.dev);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -656,36 +654,24 @@ static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num)
|
||||
// A workaround for avoiding cause timeout issue when using
|
||||
// hardware reset.
|
||||
#if !SOC_I2C_SUPPORT_HW_FSM_RST
|
||||
int scl_low_period, scl_high_period, scl_wait_high_period;
|
||||
int scl_start_hold, scl_rstart_setup;
|
||||
int scl_stop_hold, scl_stop_setup;
|
||||
int sda_hold, sda_sample;
|
||||
int timeout;
|
||||
i2c_hal_timing_config_t timing_config;
|
||||
uint8_t filter_cfg;
|
||||
|
||||
i2c_hal_get_scl_clk_timing(&(i2c_context[i2c_num].hal), &scl_high_period, &scl_low_period, &scl_wait_high_period);
|
||||
i2c_hal_get_start_timing(&(i2c_context[i2c_num].hal), &scl_rstart_setup, &scl_start_hold);
|
||||
i2c_hal_get_stop_timing(&(i2c_context[i2c_num].hal), &scl_stop_setup, &scl_stop_hold);
|
||||
i2c_hal_get_sda_timing(&(i2c_context[i2c_num].hal), &sda_sample, &sda_hold);
|
||||
i2c_hal_get_tout(&(i2c_context[i2c_num].hal), &timeout);
|
||||
i2c_hal_get_filter(&(i2c_context[i2c_num].hal), &filter_cfg);
|
||||
i2c_hal_get_timing_config(&i2c_context[i2c_num].hal, &timing_config);
|
||||
i2c_ll_get_filter(i2c_context[i2c_num].hal.dev, &filter_cfg);
|
||||
|
||||
//to reset the I2C hw module, we need re-enable the hw
|
||||
i2c_hw_disable(i2c_num);
|
||||
i2c_master_clear_bus(i2c_num);
|
||||
i2c_hw_enable(i2c_num);
|
||||
|
||||
i2c_hal_master_init(&(i2c_context[i2c_num].hal), i2c_num);
|
||||
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);
|
||||
i2c_hal_set_scl_clk_timing(&(i2c_context[i2c_num].hal), scl_high_period, scl_low_period, scl_wait_high_period);
|
||||
i2c_hal_set_start_timing(&(i2c_context[i2c_num].hal), scl_rstart_setup, scl_start_hold);
|
||||
i2c_hal_set_stop_timing(&(i2c_context[i2c_num].hal), scl_stop_setup, scl_stop_hold);
|
||||
i2c_hal_set_sda_timing(&(i2c_context[i2c_num].hal), sda_sample, sda_hold);
|
||||
i2c_hal_set_tout(&(i2c_context[i2c_num].hal), timeout);
|
||||
i2c_hal_set_filter(&(i2c_context[i2c_num].hal), filter_cfg);
|
||||
i2c_hal_master_init(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
i2c_hal_set_timing_config(&i2c_context[i2c_num].hal, &timing_config);
|
||||
i2c_ll_set_filter(i2c_context[i2c_num].hal.dev, filter_cfg);
|
||||
#else
|
||||
i2c_hal_master_fsm_rst(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_master_fsm_rst(i2c_context[i2c_num].hal.dev);
|
||||
i2c_master_clear_bus(i2c_num);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
@ -769,28 +755,29 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf)
|
||||
}
|
||||
i2c_hw_enable(i2c_num);
|
||||
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);
|
||||
i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, 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);
|
||||
i2c_hal_set_slave_addr(&(i2c_context[i2c_num].hal), i2c_conf->slave.slave_addr, i2c_conf->slave.addr_10bit_en);
|
||||
i2c_hal_set_rxfifo_full_thr(&(i2c_context[i2c_num].hal), I2C_FIFO_FULL_THRESH_VAL);
|
||||
i2c_hal_set_txfifo_empty_thr(&(i2c_context[i2c_num].hal), I2C_FIFO_EMPTY_THRESH_VAL);
|
||||
i2c_hal_slave_init(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_slave_tx_auto_start_en(i2c_context[i2c_num].hal.dev, true);
|
||||
i2c_ll_set_source_clk(i2c_context[i2c_num].hal.dev, src_clk);
|
||||
i2c_ll_set_slave_addr(i2c_context[i2c_num].hal.dev, i2c_conf->slave.slave_addr, i2c_conf->slave.addr_10bit_en);
|
||||
i2c_ll_set_rxfifo_full_thr(i2c_context[i2c_num].hal.dev, I2C_FIFO_FULL_THRESH_VAL);
|
||||
i2c_ll_set_txfifo_empty_thr(i2c_context[i2c_num].hal.dev, I2C_FIFO_EMPTY_THRESH_VAL);
|
||||
//set timing for data
|
||||
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));
|
||||
i2c_ll_set_sda_timing(i2c_context[i2c_num].hal.dev, I2C_SLAVE_SDA_SAMPLE_DEFAULT, I2C_SLAVE_SDA_HOLD_DEFAULT);
|
||||
i2c_ll_set_tout(i2c_context[i2c_num].hal.dev, I2C_SLAVE_TIMEOUT_DEFAULT);
|
||||
i2c_ll_slave_enable_rx_it(i2c_context[i2c_num].hal.dev);
|
||||
} else
|
||||
#endif // SOC_I2C_SUPPORT_SLAVE
|
||||
{
|
||||
i2c_hal_master_init(&(i2c_context[i2c_num].hal), i2c_num);
|
||||
i2c_hal_master_init(&(i2c_context[i2c_num].hal));
|
||||
//Default, we enable hardware filter
|
||||
i2c_hal_set_filter(&(i2c_context[i2c_num].hal), I2C_FILTER_CYC_NUM_DEF);
|
||||
i2c_ll_set_filter(i2c_context[i2c_num].hal.dev, I2C_FILTER_CYC_NUM_DEF);
|
||||
i2c_hal_set_bus_timing(&(i2c_context[i2c_num].hal), i2c_conf->master.clk_speed, src_clk, s_get_src_clk_freq(src_clk));
|
||||
}
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -802,8 +789,8 @@ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period)
|
||||
ESP_RETURN_ON_FALSE((low_period <= I2C_SCL_LOW_PERIOD_V) && (low_period > 0), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TIMING_VAL_ERR_STR);
|
||||
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_scl_timing(&(i2c_context[i2c_num].hal), high_period, low_period);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_scl_timing(i2c_context[i2c_num].hal.dev, high_period, low_period);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -812,7 +799,7 @@ esp_err_t i2c_get_period(i2c_port_t i2c_num, int *high_period, int *low_period)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX && high_period != NULL && low_period != NULL, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_get_scl_timing(&(i2c_context[i2c_num].hal), high_period, low_period);
|
||||
i2c_ll_get_scl_timing(i2c_context[i2c_num].hal.dev, high_period, low_period);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -822,8 +809,8 @@ esp_err_t i2c_filter_enable(i2c_port_t i2c_num, uint8_t cyc_num)
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_i2c_obj[i2c_num] != NULL, ESP_FAIL, I2C_TAG, I2C_DRIVER_ERR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_filter(&(i2c_context[i2c_num].hal), cyc_num);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_filter(i2c_context[i2c_num].hal.dev, cyc_num);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -832,8 +819,8 @@ esp_err_t i2c_filter_disable(i2c_port_t i2c_num)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_filter(&(i2c_context[i2c_num].hal), 0);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_filter(i2c_context[i2c_num].hal.dev, 0);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -845,8 +832,8 @@ esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time
|
||||
ESP_RETURN_ON_FALSE((setup_time <= I2C_SCL_RSTART_SETUP_TIME_V) && (setup_time > 0), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TIMING_VAL_ERR_STR);
|
||||
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_start_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_start_timing(i2c_context[i2c_num].hal.dev, setup_time, hold_time);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -855,7 +842,7 @@ esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int *setup_time, int *hold_ti
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX && setup_time != NULL && hold_time != NULL, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_get_start_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time);
|
||||
i2c_ll_get_start_timing(i2c_context[i2c_num].hal.dev, setup_time, hold_time);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -867,8 +854,8 @@ esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time)
|
||||
ESP_RETURN_ON_FALSE((hold_time <= I2C_SCL_STOP_HOLD_TIME_V) && (hold_time > 0), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TIMING_VAL_ERR_STR);
|
||||
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_stop_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_stop_timing(i2c_context[i2c_num].hal.dev, setup_time, hold_time);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -877,7 +864,7 @@ esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int *setup_time, int *hold_tim
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX && setup_time != NULL && hold_time != NULL, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_get_stop_timing(&(i2c_context[i2c_num].hal), setup_time, hold_time);
|
||||
i2c_ll_get_stop_timing(i2c_context[i2c_num].hal.dev, setup_time, hold_time);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -889,8 +876,8 @@ esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time
|
||||
ESP_RETURN_ON_FALSE((hold_time <= I2C_SDA_HOLD_TIME_V) && (hold_time > 0), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TIMING_VAL_ERR_STR);
|
||||
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_sda_timing(&(i2c_context[i2c_num].hal), sample_time, hold_time);
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_set_sda_timing(i2c_context[i2c_num].hal.dev, sample_time, hold_time);
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -899,7 +886,7 @@ esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int *sample_time, int *hold_ti
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX && sample_time != NULL && hold_time != NULL, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_get_sda_timing(&(i2c_context[i2c_num].hal), sample_time, hold_time);
|
||||
i2c_ll_get_sda_timing(i2c_context[i2c_num].hal.dev, sample_time, hold_time);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -910,7 +897,7 @@ esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout)
|
||||
ESP_RETURN_ON_FALSE((timeout <= I2C_LL_MAX_TIMEOUT) && (timeout > 0), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_TIMING_VAL_ERR_STR);
|
||||
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_set_tout(&(i2c_context[i2c_num].hal), timeout);
|
||||
i2c_ll_set_tout(i2c_context[i2c_num].hal.dev, timeout);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -918,7 +905,7 @@ esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout)
|
||||
esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int *timeout)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX && timeout != NULL, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
|
||||
i2c_hal_get_tout(&(i2c_context[i2c_num].hal), timeout);
|
||||
i2c_ll_get_tout(i2c_context[i2c_num].hal.dev, timeout);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -1363,7 +1350,7 @@ static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num, portBASE_T
|
||||
i2c_cmd_evt_t evt = { 0 };
|
||||
if (p_i2c->cmd_link.head != NULL && p_i2c->status == I2C_STATUS_READ) {
|
||||
i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
|
||||
i2c_hal_read_rxfifo(&(i2c_context[i2c_num].hal), cmd->data + cmd->bytes_used, p_i2c->rx_cnt);
|
||||
i2c_ll_read_rxfifo(i2c_context[i2c_num].hal.dev, cmd->data + cmd->bytes_used, p_i2c->rx_cnt);
|
||||
/* rx_cnt bytes have just been read, increment the number of bytes used from the buffer */
|
||||
cmd->bytes_used += p_i2c->rx_cnt;
|
||||
|
||||
@ -1425,10 +1412,10 @@ static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num, portBASE_T
|
||||
write_pr = (uint8_t*) &cmd->data_byte;
|
||||
}
|
||||
hw_cmd.byte_num = fifo_fill;
|
||||
i2c_hal_write_txfifo(&(i2c_context[i2c_num].hal), write_pr, fifo_fill);
|
||||
i2c_hal_write_cmd_reg(&(i2c_context[i2c_num].hal), hw_cmd, p_i2c->cmd_idx);
|
||||
i2c_hal_write_cmd_reg(&(i2c_context[i2c_num].hal), hw_end_cmd, p_i2c->cmd_idx + 1);
|
||||
i2c_hal_enable_master_tx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_write_txfifo(i2c_context[i2c_num].hal.dev, write_pr, fifo_fill);
|
||||
i2c_ll_write_cmd_reg(i2c_context[i2c_num].hal.dev, hw_cmd, p_i2c->cmd_idx);
|
||||
i2c_ll_write_cmd_reg(i2c_context[i2c_num].hal.dev, hw_end_cmd, p_i2c->cmd_idx + 1);
|
||||
i2c_ll_master_enable_tx_it(i2c_context[i2c_num].hal.dev);
|
||||
p_i2c->cmd_idx = 0;
|
||||
if (i2c_cmd_is_single_byte(cmd) || cmd->total_bytes == cmd->bytes_used) {
|
||||
p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
|
||||
@ -1443,13 +1430,13 @@ static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num, portBASE_T
|
||||
fifo_fill = MIN(remaining_bytes, SOC_I2C_FIFO_LEN);
|
||||
p_i2c->rx_cnt = fifo_fill;
|
||||
hw_cmd.byte_num = fifo_fill;
|
||||
i2c_hal_write_cmd_reg(&(i2c_context[i2c_num].hal), hw_cmd, p_i2c->cmd_idx);
|
||||
i2c_hal_write_cmd_reg(&(i2c_context[i2c_num].hal), hw_end_cmd, p_i2c->cmd_idx + 1);
|
||||
i2c_hal_enable_master_rx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_write_cmd_reg(i2c_context[i2c_num].hal.dev, hw_cmd, p_i2c->cmd_idx);
|
||||
i2c_ll_write_cmd_reg(i2c_context[i2c_num].hal.dev, hw_end_cmd, p_i2c->cmd_idx + 1);
|
||||
i2c_ll_master_enable_rx_it(i2c_context[i2c_num].hal.dev);
|
||||
p_i2c->status = I2C_STATUS_READ;
|
||||
break;
|
||||
} else {
|
||||
i2c_hal_write_cmd_reg(&(i2c_context[i2c_num].hal), hw_cmd, p_i2c->cmd_idx);
|
||||
i2c_ll_write_cmd_reg(i2c_context[i2c_num].hal.dev, hw_cmd, p_i2c->cmd_idx);
|
||||
}
|
||||
p_i2c->cmd_idx++;
|
||||
p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
|
||||
@ -1458,8 +1445,8 @@ static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num, portBASE_T
|
||||
break;
|
||||
}
|
||||
}
|
||||
i2c_hal_update_config(&(i2c_context[i2c_num].hal));
|
||||
i2c_hal_trans_start(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_update(i2c_context[i2c_num].hal.dev);
|
||||
i2c_ll_trans_start(i2c_context[i2c_num].hal.dev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1513,7 +1500,7 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
|
||||
#endif
|
||||
xQueueReset(p_i2c->cmd_evt_queue);
|
||||
if (p_i2c->status == I2C_STATUS_TIMEOUT
|
||||
|| i2c_hal_is_bus_busy(&(i2c_context[i2c_num].hal))) {
|
||||
|| i2c_ll_is_bus_busy(i2c_context[i2c_num].hal.dev)) {
|
||||
i2c_hw_fsm_reset(i2c_num);
|
||||
clear_bus_cnt[i2c_num] = 0;
|
||||
}
|
||||
@ -1534,8 +1521,8 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
|
||||
i2c_reset_rx_fifo(i2c_num);
|
||||
// These two interrupts some times can not be cleared when the FSM gets stuck.
|
||||
// so we disable them when these two interrupt occurs and re-enable them here.
|
||||
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);
|
||||
i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK);
|
||||
//start send commands, at most 32 bytes one time, isr handler will process the remaining commands.
|
||||
i2c_master_cmd_begin_static(i2c_num, NULL);
|
||||
|
||||
@ -1616,7 +1603,7 @@ int i2c_slave_write_buffer(i2c_port_t i2c_num, const uint8_t *data, int size, Ti
|
||||
cnt = 0;
|
||||
} else {
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_enable_slave_tx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_slave_enable_tx_it(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
cnt = size;
|
||||
}
|
||||
@ -1640,7 +1627,7 @@ int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t *data, size_t max_size, Ti
|
||||
TickType_t ticks_rem = ticks_to_wait;
|
||||
TickType_t ticks_end = xTaskGetTickCount() + ticks_to_wait;
|
||||
I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
i2c_hal_enable_slave_rx_it(&(i2c_context[i2c_num].hal));
|
||||
i2c_ll_slave_enable_rx_it(i2c_context[i2c_num].hal.dev);
|
||||
I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock));
|
||||
while (size_rem && ticks_rem <= ticks_to_wait) {
|
||||
uint8_t *pdata = (uint8_t *) xRingbufferReceiveUpTo(p_i2c->rx_ring_buf, &size, ticks_to_wait, size_rem);
|
||||
|
@ -8,18 +8,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/i2c_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C hardware cmd register fields.
|
||||
*/
|
||||
@ -36,33 +36,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} i2c_hw_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_clk_cal_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 0 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
@ -70,20 +43,25 @@ typedef struct {
|
||||
#define I2C_LL_CMD_STOP 3 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#define I2C_LL_MASTER_TX_INT (I2C_ACK_ERR_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_EMPTY_INT_ENA_M)
|
||||
// I2C slave RX interrupt bitmap
|
||||
#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
#define I2C_LL_MASTER_EVENT_INTR (I2C_ACK_ERR_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)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_FULL_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_EMPTY_INT_ENA_M)
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@ -94,7 +72,7 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal)
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t half_cycle = source_clk / bus_freq / 2;
|
||||
clk_cal->scl_low = half_cycle;
|
||||
@ -114,7 +92,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg)
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
/* SCL period. According to the TRM, we should always subtract 1 to SCL low period */
|
||||
assert(bus_cfg->scl_low > 0);
|
||||
@ -199,7 +177,8 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int lo
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@ -225,6 +204,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
@ -237,9 +217,10 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
return hw->int_status.val;
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -413,17 +394,6 @@ static inline void i2c_ll_get_sda_timing(i2c_dev_t *hw, int *sda_sample, int *sd
|
||||
*sda_sample = hw->sda_sample.time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the I2C hardware version
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return The I2C hardware version
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the I2C bus is busy
|
||||
@ -437,18 +407,6 @@ static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw)
|
||||
return hw->status_reg.bus_busy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if I2C is master mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return True if I2C is master mode, else false will be returned
|
||||
*/
|
||||
static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->ctr.ms_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the rxFIFO readable length
|
||||
*
|
||||
@ -456,9 +414,10 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return hw->status_reg.rx_fifo_cnt;
|
||||
*length = hw->status_reg.rx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -468,9 +427,10 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return SOC_I2C_FIFO_LEN - hw->status_reg.tx_fifo_cnt;
|
||||
*length = SOC_I2C_FIFO_LEN - hw->status_reg.tx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -480,9 +440,9 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
return hw->timeout.tout;
|
||||
*timeout = hw->timeout.tout;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -551,7 +511,8 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint32_t fifo_addr = (hw == &I2C0) ? 0x6001301c : 0x6002701c;
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -568,6 +529,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -604,155 +566,9 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
return hw->sda_filter_cfg.thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master TX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master RX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_RX_INT;
|
||||
*filter_conf = hw->sda_filter_cfg.thres;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -795,54 +611,6 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
;//Not support on ESP32
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master 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_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.ack_err) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_empty) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_full) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C master
|
||||
*
|
||||
@ -890,22 +658,60 @@ static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
* @brief Set whether slave should auto start, or only start with start signal from master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
* @param wait_high_period The I2C SCL wait rising edge period.
|
||||
*
|
||||
* @return None.
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period)
|
||||
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
(void)wait_high_period;
|
||||
hw->scl_low_period.period = low_period;
|
||||
hw->scl_high_period.period = high_period;
|
||||
;// ESP32 do not support
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#define I2C_LL_MASTER_TX_INT (I2C_ACK_ERR_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_EMPTY_INT_ENA_M)
|
||||
// I2C slave RX interrupt bitmap
|
||||
#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
|
||||
#define I2C_LL_INTR_MASK (0xffff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Get I2C SCL timing configuration
|
||||
*
|
||||
@ -922,6 +728,186 @@ static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, in
|
||||
*low_period = hw->scl_low_period.period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
* @param wait_high_period The I2C SCL wait rising edge period.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period)
|
||||
{
|
||||
(void)wait_high_period;
|
||||
hw->scl_low_period.period = low_period;
|
||||
hw->scl_high_period.period = high_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C slave interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_empty) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_full) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.ack_err) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the I2C hardware version
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return The I2C hardware version
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->date;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/soc_caps.h"
|
||||
@ -16,13 +17,12 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C hardware cmd register fields.
|
||||
*/
|
||||
@ -39,35 +39,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} i2c_hw_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t clkm_div; /*!< I2C core clock devider */
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t scl_wait_high; /*!< I2C scl wait_high period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_clk_cal_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 6 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
@ -75,18 +46,24 @@ typedef struct {
|
||||
#define I2C_LL_CMD_STOP 2 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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)
|
||||
// delay time after rtc_clk swiching on
|
||||
#define DELAY_RTC_CLK_SWITCH (5)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_VALUE
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
#define I2C_LL_MASTER_EVENT_INTR (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)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@ -100,7 +77,7 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal)
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
|
||||
uint32_t sclk_freq = source_clk / clkm_div;
|
||||
@ -129,6 +106,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.conf_upgate = 1;
|
||||
@ -142,7 +120,7 @@ static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg)
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1);
|
||||
/* According to the Technical Reference Manual, the following timings must be subtracted by 1.
|
||||
@ -216,7 +194,8 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int lo
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@ -242,6 +221,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
@ -254,9 +234,10 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
return hw->int_status.val;
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,9 +439,10 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return hw->sr.rxfifo_cnt;
|
||||
*length = hw->sr.rxfifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -470,9 +452,10 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt;
|
||||
*length = SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -482,9 +465,9 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
return hw->to.time_out_value;
|
||||
*timeout = hw->to.time_out_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -553,7 +536,8 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for (int i = 0; i< len; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]);
|
||||
@ -569,6 +553,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -605,83 +590,9 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
return hw->filter_cfg.scl_filter_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master TX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master RX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_RX_INT;
|
||||
*filter_conf = hw->filter_cfg.scl_filter_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -693,6 +604,7 @@ static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
*/
|
||||
static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw)
|
||||
{
|
||||
// fsm_rst is a self cleared bit.
|
||||
hw->ctr.fsm_rst = 1;
|
||||
}
|
||||
|
||||
@ -731,32 +643,6 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
hw->clk_conf.sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master 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_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
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 Init I2C master
|
||||
*
|
||||
@ -775,6 +661,48 @@ static inline void i2c_ll_master_init(i2c_dev_t *hw)
|
||||
hw->ctr.val = ctrl_reg.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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)
|
||||
// delay time after rtc_clk swiching on
|
||||
#define DELAY_RTC_CLK_SWITCH (5)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_VALUE
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
@ -808,6 +736,84 @@ static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, in
|
||||
*low_period = hw->scl_low_period.scl_low_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
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 Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdbool.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/soc_caps.h"
|
||||
@ -16,12 +17,12 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C hardware cmd register fields.
|
||||
@ -39,35 +40,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} i2c_hw_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t clkm_div; /*!< I2C core clock devider */
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t scl_wait_high; /*!< I2C scl wait_high period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_clk_cal_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 6 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
@ -75,22 +47,25 @@ typedef struct {
|
||||
#define I2C_LL_CMD_STOP 2 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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)
|
||||
// delay time after rtc_clk swiching on
|
||||
#define DELAY_RTC_CLK_SWITCH (5)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
#define I2C_LL_MASTER_EVENT_INTR (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)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@ -104,7 +79,7 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal)
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
|
||||
uint32_t sclk_freq = source_clk / clkm_div;
|
||||
@ -133,6 +108,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.conf_upgate = 1;
|
||||
@ -146,7 +122,7 @@ static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg)
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1);
|
||||
/* According to the Technical Reference Manual, the following timings must be subtracted by 1.
|
||||
@ -220,7 +196,8 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int lo
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@ -246,6 +223,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
@ -258,9 +236,10 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
return hw->int_status.val;
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -477,9 +456,10 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return hw->sr.rx_fifo_cnt;
|
||||
*length = hw->sr.rx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,9 +469,10 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return SOC_I2C_FIFO_LEN - hw->sr.tx_fifo_cnt;
|
||||
*length = SOC_I2C_FIFO_LEN - hw->sr.tx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -501,9 +482,9 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
return hw->timeout.time_out_value;
|
||||
*timeout = hw->timeout.time_out_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -572,7 +553,8 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for (int i = 0; i< len; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->fifo_data, data, ptr[i]);
|
||||
@ -588,6 +570,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -624,156 +607,12 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
return hw->filter_cfg.scl_thres;
|
||||
*filter_conf = hw->filter_cfg.scl_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master TX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master RX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reste I2C master FSM. When the master FSM is stuck, call this function to reset the FSM
|
||||
@ -784,6 +623,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)
|
||||
{
|
||||
// fsm_rst is a self cleared bit.
|
||||
hw->ctr.fsm_rst = 1;
|
||||
}
|
||||
|
||||
@ -822,53 +662,7 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
hw->clk_conf.sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master 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_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C master
|
||||
@ -902,10 +696,64 @@ static inline void i2c_ll_slave_init(i2c_dev_t *hw)
|
||||
ctrl_reg.sda_force_out = 1;
|
||||
ctrl_reg.scl_force_out = 1;
|
||||
hw->ctr.val = ctrl_reg.val;
|
||||
hw->ctr.slv_tx_auto_start_en = 1;
|
||||
hw->fifo_conf.fifo_addr_cfg_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set whether slave should auto start, or only start with start signal from master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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 max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
|
||||
#define I2C_LL_INTR_MASK (0xffff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
@ -939,6 +787,157 @@ static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, in
|
||||
*low_period = hw->scl_low_period.period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out||int_sts.scl_st_to||int_sts.scl_main_st_to) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdbool.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/soc_caps.h"
|
||||
@ -16,15 +17,14 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C hardware cmd register filed.
|
||||
* @brief I2C hardware cmd register fields.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
@ -39,35 +39,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} i2c_hw_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t clkm_div; /*!< I2C core clock devider */
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t scl_wait_high; /*!< I2C scl wait_high period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_clk_cal_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 6 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
@ -75,22 +46,26 @@ typedef struct {
|
||||
#define I2C_LL_CMD_STOP 2 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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)
|
||||
// delay time after rtc_clk swiching on
|
||||
#define DELAY_RTC_CLK_SWITCH (5)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
#define I2C_LL_MASTER_EVENT_INTR (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_SCL_ST_TO_INT_ENA)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@ -104,7 +79,7 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal)
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
|
||||
uint32_t sclk_freq = source_clk / clkm_div;
|
||||
@ -133,6 +108,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.conf_upgate = 1;
|
||||
@ -146,7 +122,7 @@ static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg)
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1);
|
||||
/* According to the Technical Reference Manual, the following timings must be subtracted by 1.
|
||||
@ -220,7 +196,8 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int lo
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@ -246,6 +223,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
@ -258,9 +236,10 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
return hw->int_status.val;
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -477,9 +456,10 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return hw->sr.rx_fifo_cnt;
|
||||
*length = hw->sr.rx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,9 +469,10 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return SOC_I2C_FIFO_LEN - hw->sr.tx_fifo_cnt;
|
||||
*length = SOC_I2C_FIFO_LEN - hw->sr.tx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -501,9 +482,9 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
return hw->timeout.time_out_value;
|
||||
*timeout = hw->timeout.time_out_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -572,7 +553,8 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for (int i = 0; i< len; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->fifo_data, data, ptr[i]);
|
||||
@ -588,6 +570,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -624,155 +607,9 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
return hw->filter_cfg.scl_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master TX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master RX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_RX_INT;
|
||||
*filter_conf = hw->filter_cfg.scl_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -800,9 +637,12 @@ static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw)
|
||||
{
|
||||
hw->scl_sp_conf.scl_rst_slv_num = 9;
|
||||
hw->scl_sp_conf.scl_rst_slv_en = 0;
|
||||
hw->ctr.conf_upgate = 1;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -819,54 +659,6 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
hw->clk_conf.sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master 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_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C master
|
||||
*
|
||||
@ -899,10 +691,64 @@ static inline void i2c_ll_slave_init(i2c_dev_t *hw)
|
||||
ctrl_reg.sda_force_out = 1;
|
||||
ctrl_reg.scl_force_out = 1;
|
||||
hw->ctr.val = ctrl_reg.val;
|
||||
hw->ctr.slv_tx_auto_start_en = 1;
|
||||
hw->fifo_conf.fifo_addr_cfg_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set whether slave should auto start, or only start with start signal from master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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 max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
|
||||
#define I2C_LL_INTR_MASK (0xffff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
@ -936,6 +782,156 @@ static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, in
|
||||
*low_period = hw->scl_low_period.period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,16 +7,18 @@
|
||||
// The LL layer for I2C register operations
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/i2c_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x1ffff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
|
||||
/**
|
||||
* @brief I2C hardware cmd register fields.
|
||||
@ -34,34 +36,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} i2c_hw_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t scl_wait_high; /*!< I2C scl wait_high period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_clk_cal_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 0 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
@ -69,20 +43,26 @@ typedef struct {
|
||||
#define I2C_LL_CMD_STOP 3 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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 max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
#define I2C_LL_MASTER_EVENT_INTR (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)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
*
|
||||
@ -92,7 +72,7 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal)
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t half_cycle = source_clk / bus_freq / 2;
|
||||
//SCL
|
||||
@ -117,7 +97,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg)
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
//scl period
|
||||
hw->scl_low_period.period = bus_cfg->scl_low - 1;
|
||||
@ -185,7 +165,8 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int lo
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@ -211,6 +192,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
@ -223,9 +205,10 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
return hw->int_status.val;
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -443,9 +426,10 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return hw->status_reg.rx_fifo_cnt;
|
||||
*length = hw->status_reg.rx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -455,9 +439,10 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return SOC_I2C_FIFO_LEN - hw->status_reg.tx_fifo_cnt;
|
||||
*length = SOC_I2C_FIFO_LEN - hw->status_reg.tx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -467,9 +452,9 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
return hw->timeout.tout;
|
||||
*timeout = hw->timeout.tout;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -538,7 +523,8 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint32_t fifo_addr = (hw == &I2C0) ? 0x6001301c : 0x6002701c;
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -555,6 +541,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint32_t fifo_addr = (hw == &I2C0) ? 0x6001301c : 0x6002701c;
|
||||
@ -592,155 +579,9 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
return hw->sda_filter_cfg.thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master TX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master RX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_RX_INT;
|
||||
*filter_conf = hw->sda_filter_cfg.thres;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -786,53 +627,6 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
hw->ctr.ref_always_on = (src_clk == I2C_CLK_SRC_REF_TICK) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master 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_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C master
|
||||
@ -893,11 +687,67 @@ static inline void i2c_ll_slave_init(i2c_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
{
|
||||
;// ESP32S2 do not support
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set whether slave should auto start, or only start with start signal from master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
;// ESP32-S2 do not support
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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 max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x1ffff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
@ -931,6 +781,157 @@ static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, in
|
||||
*low_period = hw->scl_low_period.period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*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
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -8,18 +8,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdbool.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/i2c_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
/**
|
||||
* @brief I2C hardware cmd register fields.
|
||||
*/
|
||||
@ -36,35 +37,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} i2c_hw_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t clkm_div; /*!< I2C core clock divider */
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t scl_wait_high; /*!< I2C scl wait_high period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_clk_cal_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 6 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
@ -72,20 +44,24 @@ typedef struct {
|
||||
#define I2C_LL_CMD_STOP 2 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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 max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_VALUE_V
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
#define I2C_LL_MASTER_EVENT_INTR (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)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@ -99,7 +75,7 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_clk_cal_t *clk_cal)
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
|
||||
uint32_t sclk_freq = source_clk / clkm_div;
|
||||
@ -128,6 +104,7 @@ static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.conf_upgate = 1;
|
||||
@ -141,7 +118,7 @@ static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_clk_cal_t *bus_cfg)
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1);
|
||||
/* According to the Technical Reference Manual, the following timings must be subtracted by 1.
|
||||
@ -208,23 +185,6 @@ static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int high_period, int low
|
||||
hw->scl_high_period.scl_wait_high_period = high_period - high_period_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
* @param wait_high_period The I2C SCL wait rising edge period.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period)
|
||||
{
|
||||
hw->scl_low_period.scl_low_period = low_period;
|
||||
hw->scl_high_period.scl_high_period = high_period;
|
||||
hw->scl_high_period.scl_wait_high_period = wait_high_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C interrupt status
|
||||
*
|
||||
@ -233,7 +193,8 @@ static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_clr_intsts_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
@ -259,6 +220,7 @@ static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
@ -271,9 +233,10 @@ static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
return hw->int_status.val;
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -493,9 +456,10 @@ static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return hw->sr.rxfifo_cnt;
|
||||
*length = hw->sr.rxfifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -505,9 +469,10 @@ static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
return SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt;
|
||||
*length = SOC_I2C_FIFO_LEN - hw->sr.txfifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -517,9 +482,9 @@ static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
return hw->to.time_out_value;
|
||||
*timeout = hw->to.time_out_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -579,22 +544,6 @@ static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *l
|
||||
*low_period = hw->scl_low_period.scl_low_period + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C SCL timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period Pointer to accept the SCL high period
|
||||
* @param low_period Pointer to accept the SCL low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, int *low_period, int *wait_high_period)
|
||||
{
|
||||
*high_period = hw->scl_high_period.scl_high_period;
|
||||
*wait_high_period = hw->scl_high_period.scl_wait_high_period;
|
||||
*low_period = hw->scl_low_period.scl_low_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the I2C hardware txFIFO
|
||||
*
|
||||
@ -604,7 +553,8 @@ static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, in
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for (int i = 0; i< len; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]);
|
||||
@ -620,6 +570,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
@ -656,155 +607,9 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
return hw->filter_cfg.scl_filter_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = ~0;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master TX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C master RX interrupt status register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_clr.val = I2C_LL_SLAVE_RX_INT;
|
||||
*filter_conf = hw->filter_cfg.scl_filter_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -832,9 +637,8 @@ static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw)
|
||||
{
|
||||
hw->scl_sp_conf.scl_rst_slv_num = 9;
|
||||
hw->scl_sp_conf.scl_rst_slv_en = 0;
|
||||
hw->ctr.conf_upgate = 1;
|
||||
hw->scl_sp_conf.scl_rst_slv_en = 1;
|
||||
hw->ctr.conf_upgate = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -850,54 +654,6 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
hw->clk_conf.sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master 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_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) 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)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.txfifo_wm_int_st) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete_int_st) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rxfifo_wm_int_st) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C master
|
||||
*
|
||||
@ -930,10 +686,247 @@ static inline void i2c_ll_slave_init(i2c_dev_t *hw)
|
||||
ctrl_reg.sda_force_out = 1;
|
||||
ctrl_reg.scl_force_out = 1;
|
||||
hw->ctr.val = ctrl_reg.val;
|
||||
hw->ctr.slv_tx_auto_start_en = 1;
|
||||
hw->fifo_conf.fifo_addr_cfg_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set whether slave should auto start, or only start with start signal from master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
|
||||
// Get the I2C hardware FIFO address
|
||||
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
|
||||
// I2C master TX interrupt bitmap
|
||||
#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 max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_VALUE_V
|
||||
|
||||
#define I2C_LL_INTR_MASK (0x3fff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Get I2C SCL timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period Pointer to accept the SCL high period
|
||||
* @param low_period Pointer to accept the SCL low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, int *low_period, int *wait_high_period)
|
||||
{
|
||||
*high_period = hw->scl_high_period.scl_high_period;
|
||||
*wait_high_period = hw->scl_high_period.scl_wait_high_period;
|
||||
*low_period = hw->scl_low_period.scl_low_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
* @param wait_high_period The I2C SCL wait rising edge period.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period)
|
||||
{
|
||||
hw->scl_low_period.scl_low_period = low_period;
|
||||
hw->scl_high_period.scl_high_period = high_period;
|
||||
hw->scl_high_period.scl_wait_high_period = wait_high_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) 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
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.txfifo_wm_int_st) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete_int_st) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rxfifo_wm_int_st) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= 0x2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -5,154 +5,12 @@
|
||||
*/
|
||||
|
||||
#include "hal/i2c_hal.h"
|
||||
|
||||
void i2c_hal_txfifo_rst(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_txfifo_rst(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_rxfifo_rst(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_rxfifo_rst(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_set_data_mode(i2c_hal_context_t *hal, i2c_trans_mode_t tx_mode, i2c_trans_mode_t rx_mode)
|
||||
{
|
||||
i2c_ll_set_data_mode(hal->dev, tx_mode, rx_mode);
|
||||
}
|
||||
|
||||
void i2c_hal_get_data_mode(i2c_hal_context_t *hal, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode)
|
||||
{
|
||||
i2c_ll_get_data_mode(hal->dev, tx_mode, rx_mode);
|
||||
}
|
||||
|
||||
void i2c_hal_set_filter(i2c_hal_context_t *hal, uint8_t filter_num)
|
||||
{
|
||||
i2c_ll_set_filter(hal->dev, filter_num);
|
||||
}
|
||||
|
||||
void i2c_hal_get_filter(i2c_hal_context_t *hal, uint8_t *filter_num)
|
||||
{
|
||||
*filter_num = i2c_ll_get_filter(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_set_scl_timing(i2c_hal_context_t *hal, int hight_period, int low_period)
|
||||
{
|
||||
i2c_ll_set_scl_timing(hal->dev, hight_period, low_period);
|
||||
}
|
||||
|
||||
void i2c_hal_clr_intsts_mask(i2c_hal_context_t *hal, uint32_t mask)
|
||||
{
|
||||
i2c_ll_clr_intsts_mask(hal->dev, mask);
|
||||
}
|
||||
|
||||
void i2c_hal_enable_intr_mask(i2c_hal_context_t *hal, uint32_t mask)
|
||||
{
|
||||
i2c_ll_enable_intr_mask(hal->dev, mask);
|
||||
}
|
||||
|
||||
void i2c_hal_disable_intr_mask(i2c_hal_context_t *hal, uint32_t mask)
|
||||
{
|
||||
i2c_ll_disable_intr_mask(hal->dev, mask);
|
||||
}
|
||||
|
||||
void i2c_hal_get_intsts_mask(i2c_hal_context_t *hal, uint32_t *mask)
|
||||
{
|
||||
*mask = i2c_ll_get_intsts_mask(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_set_fifo_mode(i2c_hal_context_t *hal, bool fifo_mode_en)
|
||||
{
|
||||
i2c_ll_set_fifo_mode(hal->dev, fifo_mode_en);
|
||||
}
|
||||
|
||||
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_stop_timing(i2c_hal_context_t *hal, int stop_setup, int stop_hold)
|
||||
{
|
||||
i2c_ll_set_stop_timing(hal->dev, stop_setup, stop_hold);
|
||||
}
|
||||
|
||||
void i2c_hal_set_start_timing(i2c_hal_context_t *hal, int start_setup, int start_hold)
|
||||
{
|
||||
i2c_ll_set_start_timing(hal->dev, start_setup, start_hold);
|
||||
}
|
||||
|
||||
void i2c_hal_set_sda_timing(i2c_hal_context_t *hal, int sda_sample, int sda_hold)
|
||||
{
|
||||
i2c_ll_set_sda_timing(hal->dev, sda_sample, sda_hold);
|
||||
}
|
||||
|
||||
void i2c_hal_set_txfifo_empty_thr(i2c_hal_context_t *hal, uint8_t empty_thr)
|
||||
{
|
||||
i2c_ll_set_txfifo_empty_thr(hal->dev, empty_thr);
|
||||
}
|
||||
|
||||
void i2c_hal_set_rxfifo_full_thr(i2c_hal_context_t *hal, uint8_t full_thr)
|
||||
{
|
||||
i2c_ll_set_rxfifo_full_thr(hal->dev, full_thr);
|
||||
}
|
||||
|
||||
bool i2c_hal_is_bus_busy(i2c_hal_context_t *hal)
|
||||
{
|
||||
return i2c_ll_is_bus_busy(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_get_sda_timing(i2c_hal_context_t *hal, int *sample_time, int *hold_time)
|
||||
{
|
||||
i2c_ll_get_sda_timing(hal->dev, sample_time, hold_time);
|
||||
}
|
||||
|
||||
void i2c_hal_get_tout(i2c_hal_context_t *hal, int *tout_val)
|
||||
{
|
||||
*tout_val = i2c_ll_get_tout(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_get_start_timing(i2c_hal_context_t *hal, int *setup_time, int *hold_time)
|
||||
{
|
||||
i2c_ll_get_start_timing(hal->dev, setup_time, hold_time);
|
||||
}
|
||||
|
||||
void i2c_hal_get_stop_timing(i2c_hal_context_t *hal, int *setup_time, int *hold_time)
|
||||
{
|
||||
i2c_ll_get_stop_timing(hal->dev, setup_time, hold_time);
|
||||
}
|
||||
|
||||
void i2c_hal_get_scl_timing(i2c_hal_context_t *hal, int *high_period, int *low_period)
|
||||
{
|
||||
i2c_ll_get_scl_timing(hal->dev, high_period, low_period);
|
||||
}
|
||||
|
||||
bool i2c_hal_is_master_mode(i2c_hal_context_t *hal)
|
||||
{
|
||||
return i2c_ll_is_master_mode(hal->dev);
|
||||
}
|
||||
#include "hal/i2c_ll.h"
|
||||
#include "hal/i2c_types.h"
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void i2c_hal_enable_slave_rx_it(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_slave_enable_rx_it(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_disable_slave_rx_it(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_slave_disable_rx_it(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_slave_init(i2c_hal_context_t *hal, i2c_port_t i2c_num)
|
||||
void i2c_hal_slave_init(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_slave_init(hal->dev);
|
||||
//Use fifo mode
|
||||
@ -168,24 +26,18 @@ void i2c_hal_slave_init(i2c_hal_context_t *hal, i2c_port_t i2c_num)
|
||||
void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq)
|
||||
{
|
||||
i2c_ll_set_source_clk(hal->dev, src_clk);
|
||||
i2c_clk_cal_t clk_cal = {0};
|
||||
i2c_hal_clk_config_t clk_cal = {0};
|
||||
i2c_ll_cal_bus_clk(source_freq, scl_freq, &clk_cal);
|
||||
i2c_ll_set_bus_timing(hal->dev, &clk_cal);
|
||||
}
|
||||
|
||||
void i2c_hal_master_clr_bus(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_master_clr_bus(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_master_fsm_rst(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_master_fsm_rst(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_master_init(i2c_hal_context_t *hal, i2c_port_t i2c_num)
|
||||
void i2c_hal_master_init(i2c_hal_context_t *hal)
|
||||
{
|
||||
hal->version = i2c_ll_get_hw_version(hal->dev);
|
||||
i2c_ll_master_init(hal->dev);
|
||||
//Use fifo mode
|
||||
i2c_ll_set_fifo_mode(hal->dev, true);
|
||||
@ -195,3 +47,32 @@ void i2c_hal_master_init(i2c_hal_context_t *hal, i2c_port_t i2c_num)
|
||||
i2c_ll_txfifo_rst(hal->dev);
|
||||
i2c_ll_rxfifo_rst(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port)
|
||||
{
|
||||
hal->dev = I2C_LL_GET_HW(i2c_port);
|
||||
}
|
||||
|
||||
void i2c_hal_master_trans_start(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_update(hal->dev);
|
||||
i2c_ll_trans_start(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_get_timing_config(i2c_hal_context_t *hal, i2c_hal_timing_config_t *timing_config)
|
||||
{
|
||||
i2c_ll_get_scl_clk_timing(hal->dev, &timing_config->high_period, &timing_config->low_period, &timing_config->wait_high_period);
|
||||
i2c_ll_get_start_timing(hal->dev, &timing_config->rstart_setup, &timing_config->start_hold);
|
||||
i2c_ll_get_stop_timing(hal->dev, &timing_config->stop_setup, &timing_config->stop_hold);
|
||||
i2c_ll_get_sda_timing(hal->dev, &timing_config->sda_sample, &timing_config->sda_hold);
|
||||
i2c_ll_get_tout(hal->dev, &timing_config->timeout);
|
||||
}
|
||||
|
||||
void i2c_hal_set_timing_config(i2c_hal_context_t *hal, i2c_hal_timing_config_t *timing_config)
|
||||
{
|
||||
i2c_ll_set_scl_clk_timing(hal->dev, timing_config->high_period, timing_config->low_period, timing_config->wait_high_period);
|
||||
i2c_ll_set_start_timing(hal->dev, timing_config->rstart_setup, timing_config->start_hold);
|
||||
i2c_ll_set_stop_timing(hal->dev, timing_config->stop_setup, timing_config->stop_hold);
|
||||
i2c_ll_set_sda_timing(hal->dev, timing_config->sda_sample, timing_config->sda_hold);
|
||||
i2c_ll_set_tout(hal->dev, timing_config->timeout);
|
||||
}
|
||||
|
@ -6,57 +6,41 @@
|
||||
|
||||
#include "hal/i2c_hal.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void i2c_hal_master_handle_tx_event(i2c_hal_context_t *hal, i2c_intr_event_t *event)
|
||||
{
|
||||
if (i2c_ll_get_intsts_mask(hal->dev) != 0) {
|
||||
uint32_t intr_status = 0;
|
||||
i2c_ll_get_intr_mask(hal->dev, &intr_status);
|
||||
if (intr_status != 0) {
|
||||
// If intr status is 0, no need to handle it.
|
||||
i2c_ll_master_get_event(hal->dev, event);
|
||||
if ((*event < I2C_INTR_EVENT_END_DET) ||
|
||||
(*event == I2C_INTR_EVENT_TRANS_DONE)) {
|
||||
i2c_ll_master_disable_tx_it(hal->dev);
|
||||
i2c_ll_master_clr_tx_it(hal->dev);
|
||||
i2c_ll_clear_intr_mask(hal->dev, intr_status);
|
||||
} else if (*event == I2C_INTR_EVENT_END_DET) {
|
||||
i2c_ll_master_clr_tx_it(hal->dev);
|
||||
i2c_ll_clear_intr_mask(hal->dev, intr_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *event)
|
||||
{
|
||||
if (i2c_ll_get_intsts_mask(hal->dev) != 0) {
|
||||
uint32_t intr_status = 0;
|
||||
i2c_ll_get_intr_mask(hal->dev, &intr_status);
|
||||
if (intr_status != 0) {
|
||||
i2c_ll_master_get_event(hal->dev, event);
|
||||
if ((*event < I2C_INTR_EVENT_END_DET) ||
|
||||
(*event == I2C_INTR_EVENT_TRANS_DONE)) {
|
||||
i2c_ll_master_disable_rx_it(hal->dev);
|
||||
i2c_ll_master_clr_rx_it(hal->dev);
|
||||
i2c_ll_clear_intr_mask(hal->dev, intr_status);
|
||||
} else if (*event == I2C_INTR_EVENT_END_DET) {
|
||||
i2c_ll_master_clr_rx_it(hal->dev);
|
||||
i2c_ll_clear_intr_mask(hal->dev, intr_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
void i2c_hal_disable_slave_tx_it(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_slave_disable_tx_it(hal->dev);
|
||||
}
|
||||
#endif // SOC_I2C_SUPPORT_SLAVE
|
||||
|
||||
void i2c_hal_update_config(i2c_hal_context_t *hal)
|
||||
{
|
||||
i2c_ll_update(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_get_rxfifo_cnt(i2c_hal_context_t *hal, uint32_t *len)
|
||||
{
|
||||
*len = i2c_ll_get_rxfifo_cnt(hal->dev);
|
||||
}
|
||||
|
||||
void i2c_hal_get_txfifo_cnt(i2c_hal_context_t *hal, uint32_t *len)
|
||||
{
|
||||
*len = i2c_ll_get_txfifo_len(hal->dev);
|
||||
}
|
||||
|
@ -13,95 +13,22 @@
|
||||
// The HAL layer for I2C
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/i2c_ll.h"
|
||||
#include "hal/i2c_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief I2C hal Context definition
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_dev_t *dev;
|
||||
uint32_t version;
|
||||
} i2c_hal_context_t;
|
||||
|
||||
/**
|
||||
* @brief Write the I2C rxfifo with the given length
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param wr_data Pointer to data buffer
|
||||
* @param wr_size Amount of data needs write
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_write_txfifo(hal,wr_data,wr_size) i2c_ll_write_txfifo((hal)->dev,wr_data,wr_size)
|
||||
|
||||
/**
|
||||
* @brief Read the I2C rxfifo with the given length
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param buf Pointer to data buffer
|
||||
* @param rd_size Amount of data needs read
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_read_rxfifo(hal,buf,rd_size) i2c_ll_read_rxfifo((hal)->dev,buf,rd_size)
|
||||
|
||||
/**
|
||||
* @brief Write I2C cmd register
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param cmd I2C hardware command
|
||||
* @param cmd_idx The index of the command register, should be less than 16
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_write_cmd_reg(hal,cmd, cmd_idx) i2c_ll_write_cmd_reg((hal)->dev,cmd,cmd_idx)
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C to triger a transaction
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_trans_start(hal) i2c_ll_trans_start((hal)->dev)
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_enable_master_rx_it(hal) i2c_ll_master_enable_rx_it((hal)->dev)
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#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
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_slave_clr_tx_it(hal) i2c_ll_slave_clr_tx_it((hal)->dev)
|
||||
|
||||
/**
|
||||
* @brief Clear I2C slave RX interrupt
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_slave_clr_rx_it(hal) i2c_ll_slave_clr_rx_it((hal)->dev)
|
||||
|
||||
/**
|
||||
* @brief Init the I2C slave.
|
||||
@ -111,100 +38,10 @@ typedef struct {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_slave_init(i2c_hal_context_t *hal, i2c_port_t i2c_num);
|
||||
void i2c_hal_slave_init(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* the expected SCL frequency.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param src_clk Source clock to use choosen from `i2c_clock_source_t` type
|
||||
*/
|
||||
#define i2c_hal_set_source_clk(hal, src_clk) i2c_ll_set_source_clk((hal)->dev, src_clk)
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
* @param wait_high_period The I2C SCL wait rising edge period.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
#define i2c_hal_set_scl_clk_timing(hal, high_period, low_period, wait_high_period) i2c_ll_set_scl_clk_timing((hal)->dev, high_period, low_period, wait_high_period)
|
||||
|
||||
/**
|
||||
* @brief Get I2C SCL timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period Pointer to accept the SCL high period
|
||||
* @param low_period Pointer to accept the SCL low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define i2c_hal_get_scl_clk_timing(hal, high_period, low_period, wait_high_period) i2c_ll_get_scl_clk_timing((hal)->dev, high_period, low_period, wait_high_period)
|
||||
|
||||
/**
|
||||
* @brief Init the I2C master.
|
||||
*
|
||||
@ -213,273 +50,7 @@ void i2c_hal_slave_handle_event(i2c_hal_context_t *hal, i2c_intr_event_t *event)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_master_init(i2c_hal_context_t *hal, i2c_port_t i2c_num);
|
||||
|
||||
/**
|
||||
* @brief Reset the I2C hw txfifo
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_txfifo_rst(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Reset the I2C hw rxfifo
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_rxfifo_rst(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C data MSB bit shifted first or LSB bit shifted first.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param tx_mode Data format of TX
|
||||
* @param rx_mode Data format of RX
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_data_mode(i2c_hal_context_t *hal, i2c_trans_mode_t tx_mode, i2c_trans_mode_t rx_mode);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C hardware filter function.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param filter_num If the glitch period on the line is less than this value(in APB cycle), it will be filtered out
|
||||
* If `filter_num == 0`, the filter will be disabled
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_filter(i2c_hal_context_t *hal, uint8_t filter_num);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C hardware filter configuration
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param filter_num Pointer to accept the hardware filter configuration
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_filter(i2c_hal_context_t *hal, uint8_t *filter_num);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C SCL timing
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param hight_period SCL high period
|
||||
* @param low_period SCL low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_scl_timing(i2c_hal_context_t *hal, int hight_period, int low_period);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C master SCL frequency
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param src_clk The I2C Source clock frequency
|
||||
* @param scl_freq The SCL frequency to be set
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_scl_freq(i2c_hal_context_t *hal, uint32_t src_clk, uint32_t scl_freq);
|
||||
|
||||
/**
|
||||
* @brief Clear the I2C interrupt status with the given mask
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param mask The interrupt bitmap needs to be clearned
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_clr_intsts_mask(i2c_hal_context_t *hal, uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Enable the I2C interrupt with the given mask
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param mask The interrupt bitmap needs to be enabled
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_enable_intr_mask(i2c_hal_context_t *hal, uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Disable the I2C interrupt with the given mask
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param mask The interrupt bitmap needs to be disabled
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_disable_intr_mask(i2c_hal_context_t *hal, uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C memory access mode, FIFO mode or none FIFO mode
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param fifo_mode_en Set true to enable FIFO access mode, else set it false
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_fifo_mode(i2c_hal_context_t *hal, bool fifo_mode_en);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C timeout value
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param tout_val the timeout value to be set
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_tout(i2c_hal_context_t *hal, int tout_val);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C time out configuration
|
||||
*
|
||||
* @param tout_val Pointer to accept the timeout configuration
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_tout(i2c_hal_context_t *hal, int *tout_val);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C stop timing
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param stop_setup The stop condition setup period (in APB cycle)
|
||||
* @param stop_hold The stop condition hold period (in APB cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_stop_timing(i2c_hal_context_t *hal, int stop_setup, int stop_hold);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C start timing
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param start_setup The start condition setup period (in APB cycle)
|
||||
* @param start_hold The start condition hold period (in APB cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_start_timing(i2c_hal_context_t *hal, int start_setup, int start_hold);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C sda sample timing
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param sda_sample The SDA sample time (in APB cycle)
|
||||
* @param sda_hold The SDA hold time (in APB cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_sda_timing(i2c_hal_context_t *hal, int sda_sample, int sda_hold);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C txfifo empty threshold value
|
||||
*
|
||||
* @param hal Context of the HAL layer.
|
||||
* @param empty_thr TxFIFO empty threshold value
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_txfifo_empty_thr(i2c_hal_context_t *hal, uint8_t empty_thr);
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C rxfifo full threshold value
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param full_thr RxFIFO full threshold value
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_set_rxfifo_full_thr(i2c_hal_context_t *hal, uint8_t full_thr);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C interrupt status
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param mask Pointer to accept the interrupt status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_intsts_mask(i2c_hal_context_t *hal, uint32_t *mask);
|
||||
|
||||
/**
|
||||
* @brief Check if the I2C bus is busy
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return True if the bus is busy, otherwise, fale will be returned
|
||||
*/
|
||||
bool i2c_hal_is_bus_busy(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C sda sample timing configuration
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param sample_time Pointer to accept the SDA sample time
|
||||
* @param hold_time Pointer to accept the SDA hold time
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_sda_timing(i2c_hal_context_t *hal, int *sample_time, int *hold_time);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C stop timing configuration
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param setup_time Pointer to accept the stop condition setup period
|
||||
* @param hold_time Pointer to accept the stop condition hold period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_stop_timing(i2c_hal_context_t *hal, int *setup_time, int *hold_time);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C scl timing configuration
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param high_period Pointer to accept the scl high period
|
||||
* @param low_period Pointer to accept the scl low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_scl_timing(i2c_hal_context_t *hal, int *high_period, int *low_period);
|
||||
|
||||
/**
|
||||
* @brief Get the I2C start timing configuration
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param setup_time Pointer to accept the start condition setup period
|
||||
* @param hold_time Pointer to accept the start condition hold period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_start_timing(i2c_hal_context_t *hal, int *setup_time, int *hold_time);
|
||||
|
||||
/**
|
||||
* @brief Check if the I2C is master mode
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return True if in master mode, otherwise, false will be returned
|
||||
*/
|
||||
bool i2c_hal_is_master_mode(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Get the rxFIFO readable length
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param len Pointer to accept the rxFIFO readable length
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_rxfifo_cnt(i2c_hal_context_t *hal, uint32_t *len);
|
||||
void i2c_hal_master_init(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Set I2C bus timing with the given frequency
|
||||
@ -493,27 +64,6 @@ void i2c_hal_get_rxfifo_cnt(i2c_hal_context_t *hal, uint32_t *len);
|
||||
*/
|
||||
void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq);
|
||||
|
||||
/**
|
||||
* @brief Get I2C txFIFO writeable length
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param len Pointer to accept the txFIFO writeable length
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_txfifo_cnt(i2c_hal_context_t *hal, uint32_t *len);
|
||||
|
||||
/**
|
||||
* @brief Check if the I2C is master mode
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param tx_mode Pointer to accept the TX data mode
|
||||
* @param rx_mode Pointer to accept the RX data mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_get_data_mode(i2c_hal_context_t *hal, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode);
|
||||
|
||||
/**
|
||||
* @brief I2C hardware FSM reset
|
||||
*
|
||||
@ -523,15 +73,6 @@ void i2c_hal_get_data_mode(i2c_hal_context_t *hal, i2c_trans_mode_t *tx_mode, i2
|
||||
*/
|
||||
void i2c_hal_master_fsm_rst(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief @brief Clear I2C bus
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void i2c_hal_master_clr_bus(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief I2C master handle tx interrupt event
|
||||
*
|
||||
@ -553,11 +94,36 @@ 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 Synchronize I2C status
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*
|
||||
* @return None
|
||||
* @brief Init I2C hal layer
|
||||
*
|
||||
* @param hal Context of the HAL
|
||||
* @param i2c_port I2C port number.
|
||||
*/
|
||||
void i2c_hal_update_config(i2c_hal_context_t *hal);
|
||||
void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port);
|
||||
|
||||
/**
|
||||
* @brief Start I2C master transaction
|
||||
*
|
||||
* @param hal Context of the HAL
|
||||
*/
|
||||
void i2c_hal_master_trans_start(i2c_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Get timing configuration
|
||||
*
|
||||
* @param hal Context of the HAL
|
||||
* @param timing_config Pointer to timing config structure.
|
||||
*/
|
||||
void i2c_hal_get_timing_config(i2c_hal_context_t *hal, i2c_hal_timing_config_t *timing_config);
|
||||
|
||||
/**
|
||||
* @brief Set timing configuration
|
||||
*
|
||||
* @param hal Context of the HAL
|
||||
* @param timing_config Timing config structure.
|
||||
*/
|
||||
void i2c_hal_set_timing_config(i2c_hal_context_t *hal, i2c_hal_timing_config_t *timing_config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -26,6 +26,21 @@ typedef enum {
|
||||
I2C_NUM_MAX, /*!< I2C port max */
|
||||
} i2c_port_t;
|
||||
|
||||
/**
|
||||
* @brief Data structure for calculating I2C bus timing.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t clkm_div; /*!< I2C core clock devider */
|
||||
uint16_t scl_low; /*!< I2C scl low period */
|
||||
uint16_t scl_high; /*!< I2C scl hight period */
|
||||
uint16_t scl_wait_high; /*!< I2C scl wait_high period */
|
||||
uint16_t sda_hold; /*!< I2C scl low period */
|
||||
uint16_t sda_sample; /*!< I2C sda sample time */
|
||||
uint16_t setup; /*!< I2C start and stop condition setup period */
|
||||
uint16_t hold; /*!< I2C start and stop condition hold period */
|
||||
uint16_t tout; /*!< I2C bus timeout period */
|
||||
} i2c_hal_clk_config_t;
|
||||
|
||||
typedef enum{
|
||||
#if SOC_I2C_SUPPORT_SLAVE
|
||||
I2C_MODE_SLAVE = 0, /*!< I2C slave mode */
|
||||
@ -58,6 +73,23 @@ typedef enum {
|
||||
I2C_MASTER_ACK_MAX,
|
||||
} i2c_ack_type_t;
|
||||
|
||||
/**
|
||||
* @brief Timing configuration structure. Used for I2C reset internally.
|
||||
*/
|
||||
typedef struct {
|
||||
int high_period; /*!< high_period time */
|
||||
int low_period; /*!< low_period time */
|
||||
int wait_high_period; /*!< wait_high_period time */
|
||||
int rstart_setup; /*!< restart setup */
|
||||
int start_hold; /*!< start hold time */
|
||||
int stop_setup; /*!< stop setup */
|
||||
int stop_hold; /*!< stop hold time */
|
||||
int sda_sample; /*!< high_period time */
|
||||
int sda_hold; /*!< sda hold time */
|
||||
int timeout; /*!< timeout value */
|
||||
} i2c_hal_timing_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief I2C group clock source
|
||||
*/
|
||||
|
@ -241,7 +241,7 @@ config SOC_I2C_NUM
|
||||
|
||||
config SOC_I2C_FIFO_LEN
|
||||
int
|
||||
default 32
|
||||
default 16
|
||||
|
||||
config SOC_I2C_SUPPORT_HW_CLR_BUS
|
||||
bool
|
||||
|
@ -124,7 +124,7 @@
|
||||
// ESP32-C2 has 1 I2C
|
||||
#define SOC_I2C_NUM (1U)
|
||||
|
||||
#define SOC_I2C_FIFO_LEN (32) /*!< I2C hardware FIFO depth */
|
||||
#define SOC_I2C_FIFO_LEN (16) /*!< I2C hardware FIFO depth */
|
||||
|
||||
// FSM_RST only resets the FSM, not using it. So SOC_I2C_SUPPORT_HW_FSM_RST not defined.
|
||||
#define SOC_I2C_SUPPORT_HW_CLR_BUS (1)
|
||||
|
Loading…
Reference in New Issue
Block a user