本帖最后由 小恩GG 于 2025-11-11 17:38 编辑
1. I3C 协议与 Hot-Join 简介
I3C(Improved Inter Integrated Circuit)是由 MIPI 联盟推出的新一代串行通信协议,旨在替代传统的 I2C 协议。相比 I2C,I3C 提供了更高的数据速率、更低的功耗以及更丰富的功能特性,如动态地址分配、In-Band Interrupt(IBI)、Hot-Join、节能模式等。
与传统的 I2C 协议不同,I3C 支持动态地址分配和更高效的事件通知机制。Hot-Join 是 I3C 的关键特性之一,适用于系统运行过程中新增传感器或外设的场景。控制器必须识别该 IBI 为 Hot-Join 类型,并决定是否接受该设备加入。
Hot-Join 是 I3C 协议中的一种机制,允许新的目标设备在总线运行过程中加入通信。目标设备通过拉低 SDA 线并发起 In-Band Interrupt (IBI) 请求,通知控制器其加入意图。
本文将详细介绍在 LPC55S36 平台上如何处理 I3C 协议中的 Hot-Join(热插拔)事件,包括控制器寄存器配置、协议流程解析、目标设备代码实现,以及逻辑分析仪截图辅助说明。
硬件环境: 开发板:LPC55S36 EVK 软件环境: IDE:MCUXpresso IDEv25.06.0 SDK:SDK Builder |MCUXpresso SDK Builder (nxp.com) 基础工程:lpcxpresso55s36_i3c_interrupt_b2b_transfer_master lpcxpresso55s36_i3c_interrupt_b2b_transfer_slave
2. I3C 协议中的 Hot-Join 流程图 根据i3c spec 中的hot join 流程图。 Hot-Join 流程概述 流程如下: 2.1. 总线空闲(Bus Idle) 总线处于空闲状态,目标设备检测到总线空闲后尝试发起 Hot-Join。 2.2. 发送 Hot-Join 请求 设备发出 START 条件,并发送 Hot-Join 地址(固定为 0x7E)。 RnW = 0(写操作),表示 Hot-Join 请求。 2.3. 主机响应 主机根据当前总线状态和策略,可能: 2.3.1 ACK:接受 Hot-Join。 主机发送 STOP,表示请求完成。 后续执行 DAA(Dynamic AddressAssignment) 流程,为新设备分配动态地址。 2.3.1 NACK:拒绝 Hot-Join(暂时不允许加入)。 设备会稍后重试。 3. 目标设备(Slave)Hot-Join 关键代码 - i3c_slave_config_t slaveConfig;
- I3C_SlaveGetDefaultConfig(&slaveConfig);
- slaveConfig.staticAddr = I3C_STATIC_ADDRESS;
- slaveConfig.vendorID = I3C_VENDOR_ID;
- slaveConfig.offline = false;
- I3C_SlaveInit(EXAMPLE_SLAVE, &slaveConfig, I3C_SLAVE_CLOCK_FREQUENCY);
- i3c_slave_handle_t slaveHandle;
- I3C_SlaveTransferCreateHandle(EXAMPLE_SLAVE, &slaveHandle, i3c_slave_callback, NULL);
- I3C_SlaveTransferNonBlocking(EXAMPLE_SLAVE, &slaveHandle, kI3C_SlaveAllEvents);
- I3C_SlaveRequestEvent(EXAMPLE_SLAVE, kI3C_SlaveEventHotJoinReq);
- g_requestSent = false;
- while (!g_requestSent)
- {
- }
复制代码
I3C_SlaveRequestEvent(EXAMPLE_SLAVE,kI3C_SlaveEventHotJoinReq); 为 目标设备的hot join 请求。 4. 主设备(master)Hot-Join 关键代码 在 LPC55S36 中,控制器通过配置 MCTRL 寄存器来处理 I3C 总线上的 Hot-Join 请求。整个流程分为两个阶段:监听阶段和响应阶段,确保控制器能够灵活应对目标设备的动态接入。
4.1 配置 MCTRL 寄存器,进入 AutoIBI +Manual 模式 - mctrlVal = I3C0->MCTRL;
- mctrlVal &= ~(I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_IBIRESP_MASK);
- mctrlVal |= I3C_MCTRL_REQUEST(kI3C_RequestAutoIbi) |
- I3C_MCTRL_IBIRESP(kI3C_IbiRespManual);
- I3C0->MCTRL = mctrlVal;
复制代码• kI3C_RequestAutoIbi:控制器进入自动监听模式,当目标设备拉低 SDA 发起 IBI(如 Hot-Join)时,控制器自动检测。 • kI3C_IbiRespManual:控制器在收到 IBI 后不立即响应,而是进入等待状态,由应用程序决定是否 ACK 或 NACK。 • 此阶段的配置是为了确保控制器能够捕捉到 Hot-Join 请求,并将处理权交给软件层。
4.2 轮询 MSTATUS 寄存器,等待 Hot-Join IBI 到来 - do {
- mstatusVal = I3C0->MSTATUS;
- } while (((mstatusVal & I3C_MSTATUS_NACKED_MASK) == I3C_MSTATUS_NACKED(1)) ||
- ((mstatusVal & I3C_MSTATUS_IBITYPE_MASK) != I3C_MSTATUS_IBITYPE(3)) ||
- ((mstatusVal & I3C_MSTATUS_SLVSTART_MASK) != I3C_MSTATUS_SLVSTART(1)) ||
- ((mstatusVal & I3C_MSTATUS_MCTRLDONE_MASK) != I3C_MSTATUS_MCTRLDONE(1)) ||
- ((mstatusVal & I3C_MSTATUS_COMPLETE_MASK) != I3C_MSTATUS_COMPLETE(1)) ||
- ((mstatusVal & I3C_MSTATUS_IBIWON_MASK) != I3C_MSTATUS_IBIWON(1)));
复制代码4.3 手动 ACK Hot-Join 请求 - mctrlVal &= ~(I3C_MCTRL_IBIRESP_MASK | I3C_MCTRL_REQUEST_MASK);
- mctrlVal |= I3C_MCTRL_IBIRESP(kI3C_IbiRespAck) |
- I3C_MCTRL_REQUEST(kI3C_RequestIbiAckNack);
- I3C0->MCTRL = mctrlVal;
复制代码• kI3C_RequestIbiAckNack:发起手动 ACK/NACK 请求。 • kI3C_IbiRespAck:明确表示接受该 Hot-Join 请求。
• 此阶段是对第一阶段的补充,完成对目标设备的响应。
4.4 发送 STOP - I3C_MasterEmitStop(I3C0, true);
复制代码4.5 执行 DAA(Dynamic AddressAssignment) 流程 - I3C_MasterProcessDAA(EXAMPLE_MASTER, addressList, 8);
复制代码
5. 逻辑分析仪截图 逻辑分析仪显示,目标设备发起Hot-Join, 主设备 成功ACK 并动态分配地址。
6. 总结 本文成功验证了在LPC55S36 平台,如何发起hot join请求,如何处理hot join请求。
|