Skip to content

Commit 5558216

Browse files
committed
fix
1 parent 562b69e commit 5558216

File tree

1 file changed

+80
-30
lines changed

1 file changed

+80
-30
lines changed

bsp/gd32/arm/libraries/gd32_drivers/drv_hw_i2c.c

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,25 @@ static void gd32_i2c_irq_handler(struct gd32_i2c *i2c_obj)
7777
}
7878
else if (stat0 & I2C_STAT0_ADDSEND)
7979
{
80-
(void)stat1; // Clear ADDSEND
81-
if ((i2c_obj->msg->flags & RT_I2C_RD) && (i2c_obj->msg->len == 1))
80+
/* 清除 ADDSEND 标志 */
81+
(void)stat1;
82+
83+
if (i2c_obj->msg->flags & RT_I2C_RD) /* Master Receiver */
8284
{
83-
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
85+
if (i2c_obj->msg->len == 1)
86+
{
87+
// N=1: 清除ACK位, 然后立即发送STOP
88+
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
89+
if (!(i2c_obj->msg->flags & RT_I2C_NO_STOP))
90+
{
91+
i2c_stop_on_bus(i2c_periph);
92+
}
93+
}
94+
else if (i2c_obj->msg->len == 2)
95+
{
96+
// N=2: 在ADDSEND之后, 必须立即清除ACK位
97+
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
98+
}
8499
}
85100
}
86101
else if ((stat1 & I2C_STAT1_MASTER) && (stat1 & I2C_STAT1_TR)) /* Master Transmitter */
@@ -112,50 +127,85 @@ static void gd32_i2c_irq_handler(struct gd32_i2c *i2c_obj)
112127
}
113128
}
114129
}
115-
else if ((stat1 & I2C_STAT1_MASTER) && !(stat1 & I2C_STAT1_TR)) /* Master Receiver */
130+
else if ((stat1 & I2C_STAT1_MASTER) && !(stat1 & I2C_STAT1_TR)) /* Master Receiver */
116131
{
117-
if ((stat0 & I2C_STAT0_BTC) && (i2c_obj->msg->len > 2))
132+
/*
133+
* 关键点: 必须优先处理 BTC,因为 BTC 标志是 TBE/RBNE 的超集。
134+
* 在接收的最后阶段,BTC 和 RBNE 可能会同时置位。
135+
*/
136+
137+
if (stat0 & I2C_STAT0_BTC)
118138
{
119-
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
120-
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
121-
if (!(i2c_obj->msg->flags & RT_I2C_NO_STOP))
139+
/*
140+
* BTC 表示字节传输完成。在接收模式下,这通常用于处理传输的最后几个字节。
141+
* 这是处理 N=2 和 N>3 场景下最后阶段的地方。
142+
*/
143+
if (i2c_obj->msg->len == 2) // N=2 的特殊情况
122144
{
123-
i2c_stop_on_bus(i2c_periph);
145+
// 1. 发送STOP信号
146+
if (!(i2c_obj->msg->flags & RT_I2C_NO_STOP))
147+
{
148+
i2c_stop_on_bus(i2c_periph);
149+
}
150+
// 2. 连续读取两个字节
151+
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
152+
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
153+
154+
// 3. 结束传输
155+
i2c_interrupt_disable(i2c_periph, I2C_INT_EV);
156+
i2c_interrupt_disable(i2c_periph, I2C_INT_ERR);
157+
i2c_interrupt_disable(i2c_periph, I2C_INT_BUF);
158+
159+
i2c_obj->result = RT_EOK;
160+
rt_completion_done(&i2c_obj->completion);
161+
}
162+
else // N > 2 场景下的最后阶段 (接收最后两个字节)
163+
{
164+
i2c_interrupt_disable(i2c_periph, I2C_INT_BUF); // 关闭缓冲区中断
165+
166+
// 1. 禁用ACK
167+
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
168+
// 2. 读取倒数第二个字节
169+
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
170+
// 3. 发送STOP信号
171+
if (!(i2c_obj->msg->flags & RT_I2C_NO_STOP))
172+
{
173+
i2c_stop_on_bus(i2c_periph);
174+
}
175+
// 4. 读取最后一个字节
176+
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
177+
178+
// 5. 结束传输
179+
i2c_interrupt_disable(i2c_periph, I2C_INT_EV | I2C_INT_ERR);
180+
i2c_obj->result = RT_EOK;
181+
rt_completion_done(&i2c_obj->completion);
124182
}
125-
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
126-
i2c_interrupt_disable(i2c_periph, I2C_INT_ERR);
127-
i2c_interrupt_disable(i2c_periph, I2C_INT_EV);
128-
i2c_interrupt_disable(i2c_periph, I2C_INT_BUF);
129-
i2c_obj->result = RT_EOK;
130-
rt_completion_done(&i2c_obj->completion);
131183
}
132184
else if (stat0 & I2C_STAT0_RBNE)
133185
{
134186
if ((i2c_obj->msg->len > 2) && (i2c_obj->count == i2c_obj->msg->len - 3))
135187
{
188+
/* 剩下最后3个字节时,等待BTC来处理,不再响应RBNE */
136189
i2c_interrupt_disable(i2c_periph, I2C_INT_BUF);
137190
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
138191
}
139-
else
192+
else // 处理 N=1 和 N>3 场景下的普通字节
140193
{
141-
if (i2c_obj->count < i2c_obj->msg->len)
142-
{
143-
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
144-
}
194+
i2c_obj->msg->buf[i2c_obj->count++] = i2c_data_receive(i2c_periph);
195+
145196
if (i2c_obj->count == i2c_obj->msg->len)
146197
{
147-
if (i2c_obj->msg->len <= 2)
198+
// 仅用于 N=1 的场景
199+
if (!(i2c_obj->msg->flags & RT_I2C_NO_STOP))
148200
{
149-
if (!(i2c_obj->msg->flags & RT_I2C_NO_STOP))
150-
{
151-
i2c_stop_on_bus(i2c_periph);
152-
}
153-
i2c_interrupt_disable(i2c_periph, I2C_INT_ERR);
154-
i2c_interrupt_disable(i2c_periph, I2C_INT_EV);
155-
i2c_interrupt_disable(i2c_periph, I2C_INT_BUF);
156-
i2c_obj->result = RT_EOK;
157-
rt_completion_done(&i2c_obj->completion);
201+
i2c_stop_on_bus(i2c_periph); // 注意: 对于N=1, STOP应在ADDSEND后就发送
158202
}
203+
i2c_interrupt_disable(i2c_periph, I2C_INT_EV);
204+
i2c_interrupt_disable(i2c_periph, I2C_INT_ERR);
205+
i2c_interrupt_disable(i2c_periph, I2C_INT_BUF);
206+
207+
i2c_obj->result = RT_EOK;
208+
rt_completion_done(&i2c_obj->completion);
159209
}
160210
}
161211
}

0 commit comments

Comments
 (0)