/* 假板子的控制面 —— 只有宿主机测试与 sim/ 自己会包含它,应用代码一律不许包含。 (包含了就编不过:ESP 目标根本不编译 sim/。) ⚠️ 模拟器是用来证明**代码逻辑**对的,不是用来证明**设计**对的。 电压、余量、时序裕量的结论全部来自设计文档的计算与首板实测。见计划 §4.2。 */ #ifndef SIM_HAL_H #define SIM_HAL_H #include #include #include "hal_gpio.h" #include "hal_i2c.h" #include "hal_pwm.h" #include "hal_time.h" #ifdef __cplusplus extern "C" { #endif /* 四路 sim 全部恢复出厂:器件表清空、引脚未配置、PWM 未配置、时钟归零、 init 标志清掉。每个测试的 setUp() 里调它。 */ void sim_hal_reset(void); /* ---------------- I²C ---------------- */ #define SIM_I2C_MAX_DEV 16 #define SIM_I2C_REGS 256 #define SIM_I2C_LOG_BYTES 8 typedef struct { uint8_t addr; uint8_t reg_width; /* 1 或 2 字节。2 字节按**大端**——INA226 / DAC63204 / LM75 都是 */ bool present; /* false = 器件失联(A15 降级矩阵用),事务一律 NAK */ int nak_left; /* >0:接下来 n 次事务 NAK 后自动恢复;<0:一直 NAK;0:正常 */ uint16_t regs[SIM_I2C_REGS]; uint8_t ptr; /* 器件内部的寄存器指针,跨事务保持(真器件就是这个行为) */ uint32_t n_write; /* 事务计数,可用来断言「驱动真的访问过它 / 没多访问」 */ uint32_t n_read; uint8_t last_write[SIM_I2C_LOG_BYTES]; /* 最后一次写进去的原始字节 */ uint8_t last_write_len; } sim_i2c_dev_t; /* 往假总线上挂一个器件。地址重复或超出 16 个会 abort(测试写错了,不该悄悄过)。 */ sim_i2c_dev_t *sim_i2c_add(uint8_t addr, uint8_t reg_width); sim_i2c_dev_t *sim_i2c_dev(uint8_t addr); /* 没挂就返回 NULL */ /* 预置 / 回读寄存器。地址没挂过会 abort。 */ void sim_i2c_set_reg(uint8_t addr, uint8_t reg, uint16_t val); uint16_t sim_i2c_get_reg(uint8_t addr, uint8_t reg); /* 故障注入。count>0:接下来 count 次事务 NAK;count<0:一直 NAK;0:清除。 */ void sim_i2c_inject_nak(uint8_t addr, int count); void sim_i2c_set_present(uint8_t addr, bool present); /* ---------------- GPIO ---------------- */ #define SIM_GPIO_PINS 48 /* ESP32-S3 的 GPIO 编号上限 */ /* 外部世界把某个**输入**脚拉成 level。对输出脚调用会 abort(那是总线打架)。 */ void sim_gpio_drive(int pin, int level); /* 该脚当前电平:输出脚 = 固件驱动的值,输入脚 = 外部驱动的值。没配过返回 -1。 */ int sim_gpio_level(int pin); /* 被 hal_gpio_write() 写成功过几次。断言「改 CH1 没动 CH2~5」用得上(A5)。 */ uint32_t sim_gpio_writes(int pin); /* ---------------- PWM ---------------- */ int sim_pwm_pin(int ch); /* 未配置返回 -1 */ uint32_t sim_pwm_freq(int ch); /* 未配置返回 0 */ int sim_pwm_permille(int ch); /* 未配置返回 -1 */ /* ---------------- 时钟 ---------------- */ void sim_time_set_us(uint64_t us); void sim_time_advance_us(uint64_t us); void sim_time_advance_ms(uint32_t ms); uint32_t sim_time_delay_calls(void); /* hal_time_delay_ms() 被调了几次 */ #ifdef __cplusplus } #endif #endif /* SIM_HAL_H */