fix(i2c): sync robust hardware transactions

This commit is contained in:
2026-09-15 19:16:53 +08:00
parent dccce6967c
commit 8872b5ae57
2 changed files with 571 additions and 1032 deletions
+69 -10
View File
@@ -25,6 +25,11 @@
#define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */ #define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */
#define I2C_MASTER_ADDRESS 0x00U /* Master address (not used) */ #define I2C_MASTER_ADDRESS 0x00U /* Master address (not used) */
/* Optional delay between the sub-address write phase and repeated START. */
#ifndef I2C_READ_RESTART_DELAY_MS
#define I2C_READ_RESTART_DELAY_MS 0U
#endif
/* Legacy compatibility */ /* Legacy compatibility */
#define I2C_OK 1 #define I2C_OK 1
#define I2C_FAIL 0 #define I2C_FAIL 0
@@ -91,29 +96,33 @@ void i2c_scan(void);
#endif #endif
/*! /*!
\brief write 16-bit data to I2C device \brief write two data bytes using an 8-bit register address
\param[in] slave_addr: 7-bit slave address \param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address (16-bit, high byte first) \param[in] reg_addr: 8-bit register address
\param[in] data: pointer to 2-byte data array \param[in] data: pointer to 2-byte data array
\param[out] none \param[out] none
\retval i2c_result_t \retval i2c_result_t
\note legacy compatibility wrapper; "16bits" describes data length,
not register-address width
*/ */
i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]); i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
/*! /*!
\brief read 16-bit data from I2C device \brief read two data bytes using an 8-bit register address
\param[in] slave_addr: 7-bit slave address \param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address \param[in] reg_addr: 8-bit register address
\param[out] data: pointer to 2-byte data buffer \param[out] data: pointer to 2-byte data buffer
\retval i2c_result_t \retval i2c_result_t
\note legacy compatibility wrapper; "16bits" describes data length,
not register-address width
*/ */
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
/* Generic read/write functions with configurable length */ /* Legacy generic APIs: register address is sent as two bytes, MSB first. */
/*! /*!
\brief write data to I2C device with configurable length \brief write data using a 16-bit register address
\param[in] slave_addr: slave device address (7-bit) \param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address \param[in] reg_addr: 16-bit register address (MSB first on the bus)
\param[in] data: pointer to data buffer \param[in] data: pointer to data buffer
\param[in] length: number of bytes to write (1-255) \param[in] length: number of bytes to write (1-255)
\param[out] none \param[out] none
@@ -122,7 +131,7 @@ i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data
i2c_result_t i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length); i2c_result_t i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length);
/*! /*!
\brief read data from I2C device with configurable length \brief read data using a 16-bit register address
\param[in] slave_addr: slave device address (7-bit) \param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address (16-bit, high byte first) \param[in] reg_addr: register address (16-bit, high byte first)
\param[out] data: pointer to data buffer \param[out] data: pointer to data buffer
@@ -131,6 +140,51 @@ i2c_result_t i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uin
*/ */
i2c_result_t i2c_read(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length); i2c_result_t i2c_read(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length);
/* Explicit register-address-width APIs. */
/*!
\brief write data using an 8-bit register address
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: 8-bit register address
\param[in] data: pointer to data buffer
\param[in] length: number of bytes to write (1-255)
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_write_reg8(uint8_t slave_addr, uint8_t reg_addr,
const uint8_t *data, uint8_t length);
/*!
\brief read data using an 8-bit register address
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: 8-bit register address
\param[out] data: pointer to data buffer
\param[in] length: number of bytes to read (1-255)
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_read_reg8(uint8_t slave_addr, uint8_t reg_addr,
uint8_t *data, uint8_t length);
/*!
\brief write data using a 16-bit register address
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: 16-bit register address (MSB first on the bus)
\param[in] data: pointer to data buffer
\param[in] length: number of bytes to write (1-255)
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_write_reg16(uint8_t slave_addr, uint16_t reg_addr,
const uint8_t *data, uint8_t length);
/*!
\brief read data using a 16-bit register address
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: 16-bit register address (MSB first on the bus)
\param[out] data: pointer to data buffer
\param[in] length: number of bytes to read (1-255)
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_read_reg16(uint8_t slave_addr, uint16_t reg_addr,
uint8_t *data, uint8_t length);
/* Pure read response without sub-address phase (for commands that already sent read request parameters) */ /* Pure read response without sub-address phase (for commands that already sent read request parameters) */
/*! /*!
\brief read data from I2C device without register/sub-address phase \brief read data from I2C device without register/sub-address phase
@@ -141,7 +195,13 @@ i2c_result_t i2c_read(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint
*/ */
i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length); i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length);
#if DEBUG_VERBOSE == CFG_ENABLE /*!
\brief probe one 7-bit address (ACK only, no data phase)
\param[in] slave_addr: slave device address (7-bit)
\retval bool: true when the address was acknowledged
*/
bool i2c_probe_ack(uint8_t slave_addr);
/*! /*!
\brief get status string for debugging \brief get status string for debugging
\param[in] status: i2c_result_t value \param[in] status: i2c_result_t value
@@ -149,6 +209,5 @@ i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length);
\retval const char* status string \retval const char* status string
*/ */
const char* i2c_get_status_string(i2c_result_t status); const char* i2c_get_status_string(i2c_result_t status);
#endif
#endif //I2C_H #endif //I2C_H
+502 -1022
View File
File diff suppressed because it is too large Load Diff