/* I²C 主机事务。板上挂着 6 片 INA226 + 2 片 DAC63204 + PCA9555(+ 载板 LM75), 见设计文档 §8.2 的地址表。 刻意只抽象「事务」这一层:不暴露 start/stop/ack,也不暴露时钟延展 —— 驱动层需要的全部就是「往这个地址写这几个字节 / 从这个地址读这几个字节」。 */ #ifndef HAL_I2C_H #define HAL_I2C_H #include #include #include "hal_err.h" #ifdef __cplusplus extern "C" { #endif typedef struct { int sda_gpio; int scl_gpio; uint32_t freq_hz; /* 0 = 用默认 400 kHz */ } hal_i2c_cfg_t; /* 幂等:重复调用直接返回 HAL_OK,不会重建总线。 sim 实现忽略 cfg 的内容,但仍然要求先 init —— 让「忘了 init」在宿主机上就暴露。 */ hal_err_t hal_i2c_init(const hal_i2c_cfg_t *cfg); /* 地址一律是 7 位(0x00~0x7F),不含读写位。 */ hal_err_t hal_i2c_write(uint8_t addr, const uint8_t *data, size_t len); hal_err_t hal_i2c_read(uint8_t addr, uint8_t *data, size_t len); /* 写后重复起始再读 —— INA226 / LM75 / PCA9555 读寄存器都是这个形状。 拆成 write + read 两次事务在多主机总线上会被插进来,所以单列一个接口。 */ hal_err_t hal_i2c_write_read(uint8_t addr, const uint8_t *wr, size_t wr_len, uint8_t *rd, size_t rd_len); /* 只发地址看有没有 ACK。需求 §12.1 步 2「I²C 扫到 10 个器件」用它。 */ hal_err_t hal_i2c_probe(uint8_t addr); #ifdef __cplusplus } #endif #endif /* HAL_I2C_H */