2026-09-16 完成、当时未提交,这里补提交(原样,不含 09-27 上板的修改)。 - 器件层 / 拓扑层整体从 R1 换到 R2:TCA9548A 分通道、五路同址 INA226 0x40 + 输入侧 0x43、 刀片 PCA9555(VBUS_EN 挪到 P0.4)、CH224A 只读驱动、风扇闭环 t_thermal - 新增 i2cbus(mux 原子事务)、slot(刀片 I/O 门面)、host/qtest.sh - 74HC595 链退役(代码与测试保留) - 判据阈值与时间常量未动;19 个 ctest 全绿,idf.py build 通过 Co-Authored-By: Claude Opus 5.5 <[email protected]>
76 行
2.1 KiB
C
76 行
2.1 KiB
C
/* TCA9548A 驱动。只经 hal_i2c_*,不碰任何平台头文件。契约见 tca9548a.h。 */
|
|
#include "tca9548a.h"
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "hal_i2c.h"
|
|
|
|
bool tca9548a_addr_ok(void)
|
|
{
|
|
/* 同一条主干上的其它器件。撞上任何一个都是硬件表被改坏了。
|
|
⚠️ 0x40 / 0x20 **不在**这张表里:它们在 mux 的支路上,与主干不冲突 ——
|
|
这正是 D8 的全部意义。 */
|
|
static const uint8_t others[] = { 0x43, 0x4A, 0x4B };
|
|
|
|
if (TCA9548A_ADDR > 0x7f) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < sizeof(others); i++) {
|
|
if (others[i] == TCA9548A_ADDR) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
hal_err_t tca9548a_select(uint8_t addr, int ch)
|
|
{
|
|
if (ch < TCA9548A_CH_NONE || ch >= TCA9548A_CH_COUNT) {
|
|
return HAL_ERR_ARG;
|
|
}
|
|
/* 一个字节,**没有寄存器指针**(文件头第 1 条)。 */
|
|
const uint8_t mask = (ch == TCA9548A_CH_NONE) ? 0u : (uint8_t)(1u << ch);
|
|
return hal_i2c_write(addr, &mask, 1);
|
|
}
|
|
|
|
hal_err_t tca9548a_read_mask(uint8_t addr, uint8_t *mask)
|
|
{
|
|
if (mask == NULL) {
|
|
return HAL_ERR_ARG;
|
|
}
|
|
return hal_i2c_read(addr, mask, 1);
|
|
}
|
|
|
|
hal_err_t tca9548a_probe(uint8_t addr)
|
|
{
|
|
hal_err_t err = tca9548a_select(addr, TCA9548A_CH_NONE);
|
|
if (err != HAL_OK) {
|
|
return err;
|
|
}
|
|
uint8_t mask = 0xFF;
|
|
err = tca9548a_read_mask(addr, &mask);
|
|
if (err != HAL_OK) {
|
|
return err;
|
|
}
|
|
/* 刚被写成全关的器件读回来必须是 0。不是的话要么这地址上蹲着别的东西,
|
|
要么写根本没生效 —— 后者在真板上是「所有刀片都读不到」,
|
|
而这里能在启动自检时就叫出来。 */
|
|
return (mask == 0) ? HAL_OK : HAL_ERR_BUS;
|
|
}
|
|
|
|
int tca9548a_mask_to_ch(uint8_t mask)
|
|
{
|
|
if (mask == 0) {
|
|
return TCA9548A_CH_NONE;
|
|
}
|
|
if ((mask & (uint8_t)(mask - 1u)) != 0) {
|
|
return -2; /* 多于一位:见文件头第 2 条 */
|
|
}
|
|
for (int ch = 0; ch < TCA9548A_CH_COUNT; ch++) {
|
|
if (mask == (uint8_t)(1u << ch)) {
|
|
return ch;
|
|
}
|
|
}
|
|
return -2; /* 到不了 */
|
|
}
|