@@ -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