mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-23 17:24:44 +00:00
Merge branch 'feature/i2c_master_new_driver' into 'master'
I2C: Add new i2c master impl APIs and i2c eeprom example See merge request espressif/esp-idf!23592
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -27,13 +28,13 @@ extern "C" {
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t byte_num: 8,
|
||||
ack_en: 1,
|
||||
ack_exp: 1,
|
||||
ack_val: 1,
|
||||
op_code: 3,
|
||||
reserved14: 17,
|
||||
done: 1;
|
||||
uint32_t byte_num: 8, /*!< Specifies the length of data (in bytes) to be read or written */
|
||||
ack_en: 1, /*!< Used to enable the I2C controller during a write operation to check whether ACK */
|
||||
ack_exp: 1, /*!< Used to configure the level of the ACK bit expected by the I2C controller during a write operation */
|
||||
ack_val: 1, /*!< Used to configure the level of the ACK bit sent by the I2C controller during a read operation */
|
||||
op_code: 3, /*!< Indicates the command */
|
||||
reserved14: 17, /*!< Reserved bits */
|
||||
done: 1; /*!< Indicates that a command has been executed */
|
||||
};
|
||||
uint32_t val;
|
||||
} i2c_ll_hw_cmd_t;
|
||||
@@ -46,25 +47,32 @@ typedef union {
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
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;
|
||||
I2C_LL_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_LL_INTR_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;
|
||||
|
||||
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;
|
||||
I2C_LL_STRETCH_REASON_MASTER_START = 0,
|
||||
I2C_LL_STRETCH_REASON_TX_EMPTY = 1,
|
||||
I2C_LL_STRETCH_REASON_RX_FULL = 2,
|
||||
} i2c_ll_stretch_cause_t;
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == I2C_NUM_0) ? (&I2C0) : (&LP_I2C))
|
||||
#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)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M|I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M | I2C_SLAVE_ADDR_UNMATCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M | I2C_SLAVE_ADDR_UNMATCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_TX_EVENT_INTR (I2C_TXFIFO_WM_INT_ENA_M | I2C_SLAVE_ADDR_UNMATCH_INT_ENA_M)
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
@@ -78,7 +86,7 @@ typedef enum {
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
static inline void i2c_ll_master_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;
|
||||
@@ -125,7 +133,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_hal_clk_config_t *bus_cfg)
|
||||
static inline void i2c_ll_master_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_num, bus_cfg->clkm_div - 1);
|
||||
|
||||
@@ -153,6 +161,20 @@ static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bu
|
||||
hw->to.time_out_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set fractional divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param div_a The denominator of the frequency divider factor of the i2c function clock
|
||||
* @param div_b The numerator of the frequency divider factor of the i2c function clock.
|
||||
*/
|
||||
static inline void i2c_ll_master_set_fractional_divider(i2c_dev_t *hw, uint8_t div_a, uint8_t div_b)
|
||||
{
|
||||
/* Set div_a and div_b to 0, as it's not necessary to use them */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_a, div_a);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2c_sclk_conf, i2c_sclk_div_b, div_b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset I2C txFIFO
|
||||
*
|
||||
@@ -160,6 +182,7 @@ static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bu
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw)
|
||||
{
|
||||
hw->fifo_conf.tx_fifo_rst = 1;
|
||||
@@ -173,28 +196,13 @@ static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_rxfifo_rst(i2c_dev_t *hw)
|
||||
{
|
||||
hw->fifo_conf.rx_fifo_rst = 1;
|
||||
hw->fifo_conf.rx_fifo_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param hight_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)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int low_period)
|
||||
{
|
||||
hw->scl_low_period.scl_low_period = low_period - 1;
|
||||
hw->scl_high_period.scl_high_period = hight_period - 10;
|
||||
hw->scl_high_period.scl_wait_high_period = hight_period - hw->scl_high_period.scl_high_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C interrupt status
|
||||
*
|
||||
@@ -217,6 +225,7 @@ static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val |= mask;
|
||||
@@ -257,7 +266,7 @@ static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en)
|
||||
static inline void i2c_ll_slave_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en)
|
||||
{
|
||||
hw->fifo_conf.nonfifo_en = fifo_mode_en ? 0 : 1;
|
||||
}
|
||||
@@ -275,6 +284,19 @@ static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout)
|
||||
hw->to.time_out_value = tout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C slave broadcasting mode.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param broadcast_en Set true to enable broadcast, else, set it false
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_en)
|
||||
{
|
||||
hw->ctr.addr_broadcasting_en = broadcast_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C slave address
|
||||
*
|
||||
@@ -286,8 +308,15 @@ static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout)
|
||||
*/
|
||||
static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, bool addr_10bit_en)
|
||||
{
|
||||
hw->slave_addr.slave_addr = slave_addr;
|
||||
hw->slave_addr.addr_10bit_en = addr_10bit_en;
|
||||
if (addr_10bit_en) {
|
||||
uint8_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;
|
||||
} else {
|
||||
hw->slave_addr.slave_addr = slave_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,7 +329,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_ll_hw_cmd_t cmd, int cmd_idx)
|
||||
static inline void i2c_ll_master_write_cmd_reg(i2c_dev_t *hw, i2c_ll_hw_cmd_t cmd, int cmd_idx)
|
||||
{
|
||||
hw->command[cmd_idx].val = cmd.val;
|
||||
}
|
||||
@@ -314,7 +343,7 @@ static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_ll_hw_cmd_t cmd, int
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int start_hold)
|
||||
static inline void i2c_ll_master_set_start_timing(i2c_dev_t *hw, int start_setup, int start_hold)
|
||||
{
|
||||
hw->scl_rstart_setup.scl_rstart_setup_time = start_setup;
|
||||
hw->scl_start_hold.scl_start_hold_time = start_hold - 1;
|
||||
@@ -329,7 +358,7 @@ static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int s
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_stop_timing(i2c_dev_t *hw, int stop_setup, int stop_hold)
|
||||
static inline void i2c_ll_master_set_stop_timing(i2c_dev_t *hw, int stop_setup, int stop_hold)
|
||||
{
|
||||
hw->scl_stop_setup.scl_stop_setup_time = stop_setup;
|
||||
hw->scl_stop_hold.scl_stop_hold_time = stop_hold;
|
||||
@@ -391,21 +420,6 @@ static inline void i2c_ll_set_data_mode(i2c_dev_t *hw, i2c_trans_mode_t tx_mode,
|
||||
hw->ctr.rx_lsb_first = rx_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the I2C data mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param tx_mode Pointer to accept the received bytes mode
|
||||
* @param rx_mode Pointer to accept the sended bytes mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode)
|
||||
{
|
||||
*tx_mode = hw->ctr.tx_lsb_first;
|
||||
*rx_mode = hw->ctr.rx_lsb_first;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C sda timing configuration
|
||||
*
|
||||
@@ -440,6 +454,7 @@ static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw)
|
||||
*
|
||||
* @return True if I2C state machine is busy, else false will be returned
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->sr.bus_busy;
|
||||
@@ -503,7 +518,7 @@ static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_trans_start(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_master_trans_start(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.trans_start = 1;
|
||||
}
|
||||
@@ -538,21 +553,6 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h
|
||||
*hold_time = hw->scl_stop_hold.scl_stop_hold_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_timing(i2c_dev_t *hw, int *high_period, int *low_period)
|
||||
{
|
||||
*high_period = hw->scl_high_period.scl_high_period + hw->scl_high_period.scl_wait_high_period;
|
||||
*low_period = hw->scl_low_period.scl_low_period + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the I2C hardware txFIFO
|
||||
*
|
||||
@@ -587,6 +587,56 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the I2C hardware txFIFO
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param ram_offset Offset value of I2C RAM.
|
||||
* @param ptr Pointer to data buffer
|
||||
* @param len Amount of data needs to be writen
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr;
|
||||
for (int i = 0; i < len; i++) {
|
||||
fifo_addr[i + ram_offset] = ptr[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the I2C hardware ram
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param ram_offset Offset value of I2C RAM.
|
||||
* @param ptr Pointer to data buffer
|
||||
* @param len Amount of data needs read
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
ptr[i] = fifo_addr[i + ram_offset];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get access to I2C RAM address directly
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param addr_wr_en Enable I2C ram address read and write
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_enable_mem_access_nonfifo(i2c_dev_t *hw, bool addr_wr_en)
|
||||
{
|
||||
hw->fifo_conf.fifo_addr_cfg_en = addr_wr_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C hardware filter
|
||||
*
|
||||
@@ -596,7 +646,7 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
static inline void i2c_ll_master_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
{
|
||||
if (filter_num > 0) {
|
||||
hw->filter_cfg.scl_filter_thres = filter_num;
|
||||
@@ -616,7 +666,7 @@ static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
static inline void i2c_ll_master_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
*filter_conf = hw->filter_cfg.scl_filter_thres;
|
||||
}
|
||||
@@ -641,12 +691,13 @@ static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw)
|
||||
* Note: The master cannot detect if deadlock happens, but when the scl_st_to interrupt is generated, a deadlock may occur.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slave_pulses When I2C master is IDLE, the number of pulses will be sent out.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw)
|
||||
static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw, uint32_t slave_pulses)
|
||||
{
|
||||
hw->scl_sp_conf.scl_rst_slv_num = 9;
|
||||
hw->scl_sp_conf.scl_rst_slv_num = slave_pulses;
|
||||
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,
|
||||
@@ -758,6 +809,28 @@ static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable I2C slave clock stretch.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param enable true: Enable, false: Disable.
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_scl_stretch(i2c_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->scl_stretch_conf.slave_scl_stretch_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C clock stretch status
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_clear_stretch(i2c_dev_t *dev)
|
||||
{
|
||||
dev->scl_stretch_conf.slave_scl_stretch_clr = 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////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)//////////////////////////////
|
||||
@@ -975,6 +1048,52 @@ static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw)
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param hight_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)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int low_period)
|
||||
{
|
||||
hw->scl_low_period.scl_low_period = low_period - 1;
|
||||
hw->scl_high_period.scl_high_period = hight_period - 10;
|
||||
hw->scl_high_period.scl_wait_high_period = hight_period - hw->scl_high_period.scl_high_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the I2C data mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param tx_mode Pointer to accept the received bytes mode
|
||||
* @param rx_mode Pointer to accept the sended bytes mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode)
|
||||
{
|
||||
*tx_mode = hw->ctr.tx_lsb_first;
|
||||
*rx_mode = hw->ctr.rx_lsb_first;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_timing(i2c_dev_t *hw, int *high_period, int *low_period)
|
||||
{
|
||||
*high_period = hw->scl_high_period.scl_high_period + hw->scl_high_period.scl_wait_high_period;
|
||||
*low_period = hw->scl_low_period.scl_low_period + 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user