@@ -116,31 +116,287 @@ static inline void i2c_log_error(struct gd32_i2c *i2c_dev)
116116 if (i2c_dev -> errs & I2C_GD32_ERR_BUSY ) LOG_E ("I2C bus is busy" );
117117}
118118
119+ static inline void gd32_i2c_xfer_read (struct gd32_i2c * i2c_obj )
120+ {
121+ const struct gd32_i2c_config * cfg = i2c_obj -> config ;
122+
123+ i2c_obj -> current -> len -- ;
124+ * i2c_obj -> current -> buf = I2C_DATA (cfg -> i2c_periph );
125+ i2c_obj -> current -> buf ++ ;
119126
120- static inline void i2c_xfer_read (struct gd32_i2c * i2c_obj )
127+ /* 如果当前 msg 读完,但总传输长度 > 0,则切换到下一个 msg */
128+ if ((i2c_obj -> xfer_len > 0U ) && (i2c_obj -> current -> len == 0U ))
129+ {
130+ i2c_obj -> current ++ ;
131+ }
132+ }
133+
134+ /**
135+ * @brief 将当前消息缓冲区的一个字节写入 I2C_DATA 寄存器
136+ */
137+ static inline void gd32_i2c_xfer_write (struct gd32_i2c * i2c_obj )
121138{
122-
139+ const struct gd32_i2c_config * cfg = i2c_obj -> config ;
140+
141+ i2c_obj -> current -> len -- ;
142+ I2C_DATA (cfg -> i2c_periph ) = * i2c_obj -> current -> buf ;
143+ i2c_obj -> current -> buf ++ ;
144+
145+ /* 如果当前 msg 写完,但总传输长度 > 0,则切换到下一个 msg */
146+ if ((i2c_obj -> xfer_len > 0U ) && (i2c_obj -> current -> len == 0U ))
147+ {
148+ i2c_obj -> current ++ ;
149+ }
123150}
124151
125- static inline void i2c_xfer_write (struct gd32_i2c * i2c_obj )
152+ /**
153+ * @brief 处理 TBE (发送缓冲区为空) 事件
154+ */
155+ static void gd32_i2c_handle_tbe (struct gd32_i2c * i2c_obj )
126156{
127-
157+ const struct gd32_i2c_config * cfg = i2c_obj -> config ;
158+
159+ if (i2c_obj -> xfer_len > 0U )
160+ {
161+ i2c_obj -> xfer_len -- ;
162+ if (i2c_obj -> xfer_len == 0U )
163+ {
164+ /* 这是最后一个要发送的数据,关闭缓冲区中断,等待 BTC 中断来确认发送完成 */
165+ I2C_CTL1 (cfg -> i2c_periph ) &= ~I2C_CTL1_BUFIE ;
166+ }
167+ gd32_i2c_xfer_write (i2c_obj );
168+ }
169+ else
170+ {
171+ /* 所有数据都已发送,且 BTC 事件触发了此函数 */
172+ /* 产生 STOP 信号并唤醒等待的线程 */
173+ I2C_CTL0 (cfg -> i2c_periph ) |= I2C_CTL0_STOP ;
174+ rt_completion_done (& i2c_obj -> sync_sem );
175+ }
128176}
129177
130- static void gd32_i2c_event_handler (struct gd32_i2c * i2c_obj )
178+ /**
179+ * @brief 处理 RBNE (接收缓冲区非空) 事件
180+ */
181+ static void gd32_i2c_handle_rbne (struct gd32_i2c * i2c_obj )
131182{
132-
183+ const struct gd32_i2c_config * cfg = i2c_obj -> config ;
184+
185+ switch (i2c_obj -> xfer_len )
186+ {
187+ case 0 :
188+ /* 不应该发生,但如果发生了,直接唤醒线程 */
189+ rt_completion_done (& i2c_obj -> sync_sem );
190+ break ;
191+ case 1 :
192+ /* 如果总共只读1个字节,在这里读取并唤醒线程 */
193+ i2c_obj -> xfer_len -- ;
194+ gd32_i2c_xfer_read (i2c_obj );
195+ rt_completion_done (& i2c_obj -> sync_sem );
196+ break ;
197+ case 2 :
198+ case 3 :
199+ /*
200+ * 如果总读取长度为2,或总长度>3且剩下3个字节时,
201+ * 关闭缓冲区中断,等待 BTC 中断来处理最后几个字节的特殊读取序列。
202+ */
203+ I2C_CTL1 (cfg -> i2c_periph ) &= ~I2C_CTL1_BUFIE ;
204+ break ;
205+ default :
206+ /* 正常情况,直接读取数据 */
207+ i2c_obj -> xfer_len -- ;
208+ gd32_i2c_xfer_read (i2c_obj );
209+ break ;
210+ }
133211}
134212
135- // Error interrupt handler
136- static void gd32_i2c_error_handler (struct gd32_i2c * i2c_obj )
213+ /**
214+ * @brief 处理 BTC (字节传输完成) 事件
215+ */
216+ static void gd32_i2c_handle_btc (struct gd32_i2c * i2c_obj )
137217{
138-
218+ const struct gd32_i2c_config * cfg = i2c_obj -> config ;
219+
220+ if (i2c_obj -> current -> flags & RT_I2C_RD )
221+ {
222+ /* 读模式下的 BTC */
223+ switch (i2c_obj -> xfer_len )
224+ {
225+ case 2 :
226+ /* 在读取最后两个字节之前,必须产生 STOP 信号 */
227+ I2C_CTL0 (cfg -> i2c_periph ) |= I2C_CTL0_STOP ;
228+ /* 读取最后两个字节 */
229+ i2c_obj -> xfer_len -= 2 ;
230+ gd32_i2c_xfer_read (i2c_obj );
231+ gd32_i2c_xfer_read (i2c_obj );
232+ /* 唤醒线程 */
233+ rt_completion_done (& i2c_obj -> sync_sem );
234+ break ;
235+ case 3 :
236+ /* 清除 ACKEN 位,这样在收到下一个字节后会回复 NACK */
237+ I2C_CTL0 (cfg -> i2c_periph ) &= ~I2C_CTL0_ACKEN ;
238+ /* 读取倒数第3个字节 */
239+ i2c_obj -> xfer_len -- ;
240+ gd32_i2c_xfer_read (i2c_obj );
241+ /* 等待下一个 BTC 来处理最后两个字节 */
242+ break ;
243+ default :
244+ /* 其他情况(不应该发生),按 RBNE 处理 */
245+ gd32_i2c_handle_rbne (i2c_obj );
246+ break ;
247+ }
248+ }
249+ else
250+ {
251+ /* 写模式下的 BTC 表示最后一个字节已发送完成,可以发 STOP */
252+ gd32_i2c_handle_tbe (i2c_obj );
253+ }
139254}
140255
141- static rt_err_t i2c_xfer_begin (struct gd32_i2c * i2c_obj )
256+ /**
257+ * @brief 处理 ADDSEND (地址已发送) 事件
258+ */
259+ static void gd32_i2c_handle_addsend (struct gd32_i2c * i2c_obj )
142260{
143-
261+ const struct gd32_i2c_config * cfg = i2c_obj -> config ;
262+
263+ /* 对于1字节读取,在地址发送后就要准备发送 NACK */
264+ if ((i2c_obj -> current -> flags & RT_I2C_RD ) && (i2c_obj -> xfer_len <= 1U ))
265+ {
266+ I2C_CTL0 (cfg -> i2c_periph ) &= ~I2C_CTL0_ACKEN ;
267+ }
268+
269+ /* 清除 ADDSEND 标志位 (通过读取 STAT0 和 STAT1) */
270+ (void )I2C_STAT0 (cfg -> i2c_periph );
271+ (void )I2C_STAT1 (cfg -> i2c_periph );
272+
273+ /* 处理10位地址读操作的 RESTART */
274+ if (i2c_obj -> is_restart )
275+ {
276+ i2c_obj -> is_restart = RT_FALSE ;
277+ i2c_obj -> current -> flags |= RT_I2C_RD ; // 恢复读标志
278+ /* 产生 RESTART 信号 */
279+ I2C_CTL0 (cfg -> i2c_periph ) |= I2C_CTL0_START ;
280+ return ; /* 提前返回,等待下一个 SBSEND 事件 */
281+ }
282+
283+ /* 对于1字节读取,在地址发送后就要准备发送 STOP */
284+ if ((i2c_obj -> current -> flags & RT_I2C_RD ) && (i2c_obj -> xfer_len == 1U ))
285+ {
286+ I2C_CTL0 (cfg -> i2c_periph ) |= I2C_CTL0_STOP ;
287+ }
288+ }
289+
290+ static void gd32_i2c_event_handler (struct gd32_i2c * i2c_obj )
291+ {
292+ const struct gd32_i2c_config * cfg ;
293+ uint32_t stat0 ;
294+
295+ RT_ASSERT (i2c_obj != RT_NULL );
296+ cfg = i2c_obj -> config ;
297+
298+ stat0 = I2C_STAT0 (cfg -> i2c_periph );
299+
300+ /*
301+ * 状态位检查的顺序至关重要,必须与 Zephyr 驱动保持一致,
302+ * 以正确处理各种复杂的传输序列。
303+ */
304+ if (stat0 & I2C_STAT0_SBSEND )
305+ {
306+ /* 起始位已发送,下一步是发送从机地址 */
307+ if (i2c_obj -> current -> flags & RT_I2C_RD )
308+ {
309+ I2C_DATA (cfg -> i2c_periph ) = (i2c_obj -> addr1 << 1 ) | 1 ;
310+ }
311+ else
312+ {
313+ I2C_DATA (cfg -> i2c_periph ) = (i2c_obj -> addr1 << 1 ) | 0 ;
314+ }
315+ }
316+ else if (stat0 & I2C_STAT0_ADD10SEND )
317+ {
318+ /* 10位地址的第一个字节已发送,现在发送第二个字节 */
319+ I2C_DATA (cfg -> i2c_periph ) = i2c_obj -> addr2 ;
320+ }
321+ else if (stat0 & I2C_STAT0_ADDSEND )
322+ {
323+ /* 从机地址已发送且收到 ACK */
324+ gd32_i2c_handle_addsend (i2c_obj );
325+ }
326+ /*
327+ * 必须先检查 BTC,因为 BTC 是 TBE 和 RBNE 的超集。
328+ * 在某些序列中(如读操作的结尾),硬件会同时置位 BTC 和 RBNE,
329+ * 此时必须由 BTC 的逻辑来处理。
330+ */
331+ else if (stat0 & I2C_STAT0_BTC )
332+ {
333+ /* 字节传输完成 */
334+ gd32_i2c_handle_btc (i2c_obj );
335+ }
336+ else if (stat0 & I2C_STAT0_RBNE )
337+ {
338+ /* 接收缓冲区非空 */
339+ gd32_i2c_handle_rbne (i2c_obj );
340+ }
341+ else if (stat0 & I2C_STAT0_TBE )
342+ {
343+ /* 发送缓冲区为空 */
344+ gd32_i2c_handle_tbe (i2c_obj );
345+ }
346+ }
347+
348+ void gd32_i2c_error_handler (struct gd32_i2c * i2c_obj )
349+ {
350+ const struct gd32_i2c_config * cfg ;
351+ uint32_t stat0 ;
352+
353+ RT_ASSERT (i2c_obj != RT_NULL );
354+ cfg = i2c_obj -> config ;
355+
356+ /* 读取状态寄存器以检查错误标志 */
357+ stat0 = I2C_STAT0 (cfg -> i2c_periph );
358+
359+ /* 1. 检查总线错误 (BERR) */
360+ if (stat0 & I2C_STAT0_BERR )
361+ {
362+ /* 清除 BERR 标志位 (通过写0) */
363+ I2C_STAT0 (cfg -> i2c_periph ) &= ~I2C_STAT0_BERR ;
364+ /* 在运行时对象中记录错误类型 */
365+ i2c_obj -> errs |= I2C_GD32_ERR_BERR ;
366+ }
367+
368+ /* 2. 检查仲裁丢失 (LOSTARB) */
369+ if (stat0 & I2C_STAT0_LOSTARB )
370+ {
371+ /* 清除 LOSTARB 标志位 */
372+ I2C_STAT0 (cfg -> i2c_periph ) &= ~I2C_STAT0_LOSTARB ;
373+ i2c_obj -> errs |= I2C_GD32_ERR_LARB ;
374+ }
375+
376+ /* 3. 检查应答失败 (AERR) */
377+ if (stat0 & I2C_STAT0_AERR )
378+ {
379+ /* 清除 AERR 标志位 */
380+ I2C_STAT0 (cfg -> i2c_periph ) &= ~I2C_STAT0_AERR ;
381+ i2c_obj -> errs |= I2C_GD32_ERR_AERR ;
382+ }
383+
384+ /* 4. 如果记录到了任何错误 */
385+ if (i2c_obj -> errs != 0 )
386+ {
387+ /*
388+ * 发生错误后,硬件可能处于不确定状态。
389+ * 发送一个 STOP 信号是让总线恢复到已知空闲状态的最佳方式。
390+ */
391+ I2C_CTL0 (cfg -> i2c_periph ) |= I2C_CTL0_STOP ;
392+
393+ /*
394+ * 唤醒在 master_xfer 中等待的线程。
395+ * master_xfer 函数会检查 i2c_obj->errs,发现非零后,
396+ * 就会记录错误日志并向上层返回错误码。
397+ */
398+ rt_completion_done (& i2c_obj -> sync_sem );
399+ }
144400}
145401
146402static rt_ssize_t gd32_i2c_master_xfer (struct rt_i2c_bus_device * bus , struct rt_i2c_msg msgs [], rt_uint32_t num )
0 commit comments