feat(i2c_slave): Add new implementation and API for I2C slave

This commit is contained in:
Cao Sen Miao
2023-10-24 18:44:49 +08:00
parent ca32e5268b
commit 8d639492f2
27 changed files with 1046 additions and 141 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -48,18 +48,23 @@ typedef union {
#define I2C_LL_CMD_END 4 /*!<I2C end command */
typedef enum {
I2C_LL_INTR_TXFIFO_WM = (1 << 1),
I2C_LL_INTR_RXFIFO_WM = (1 << 0),
I2C_INTR_MST_TXFIFO_WM = (1 << 1),
I2C_INTR_MST_RXFIFO_WM = (1 << 0),
I2C_LL_INTR_NACK = (1 << 10),
I2C_LL_INTR_TIMEOUT = (1 << 8),
I2C_LL_INTR_MST_COMPLETE = (1 << 7),
I2C_LL_INTR_ARBITRATION = (1 << 5),
I2C_LL_INTR_END_DETECT = (1 << 3),
I2C_LL_INTR_ST_TO = (1 << 13),
I2C_LL_INTR_START = (1 << 15),
I2C_LL_INTR_STRETCH = (1 << 16),
I2C_LL_INTR_UNMATCH = (1 << 18),
} i2c_ll_intr_t;
} i2c_ll_master_intr_t;
typedef enum {
I2C_INTR_SLV_TXFIFO_WM = (1 << 1),
I2C_INTR_SLV_RXFIFO_WM = (1 << 0),
I2C_INTR_SLV_COMPLETE = (1 << 7),
I2C_INTR_START = (1 << 15),
I2C_INTR_STRETCH = (1 << 16),
} i2c_ll_slave_intr_t;
// Get the I2C hardware instance
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
@@ -288,6 +293,37 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e
hw->ctr.addr_broadcasting_en = broadcast_en;
}
/**
* @brief Get the cause of SCL clock stretching in slave mode
*
* @param hw Beginning address of the peripheral registers
* @param stretch_cause Pointer to stretch cause in the slave mode.
*
* @return None
*/
__attribute__((always_inline))
static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause)
{
switch (hw->sr.stretch_cause)
{
case 0:
*stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH;
break;
case 1:
*stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY;
break;
case 2:
*stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL;
break;
case 3:
*stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK;
break;
default:
HAL_ASSERT(false);
break;
}
}
/**
* @brief Configure I2C slave address
*
@@ -301,7 +337,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo
{
hw->slave_addr.addr_10bit_en = addr_10bit_en;
if (addr_10bit_en) {
uint8_t addr_14_7 = (slave_addr & 0xff) << 7;
uint16_t addr_14_7 = (slave_addr & 0xff) << 7;
uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78;
hw->slave_addr.slave_addr = addr_14_7 | addr_6_0;
hw->ctr.addr_10bit_rw_check_en = addr_10bit_en;
@@ -393,6 +429,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr)
*/
static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr)
{
hw->fifo_conf.fifo_prt_en = 1;
hw->fifo_conf.rxfifo_wm_thrhd = full_thr;
}