From d78429eb8e3222d094ee8048e53c229117e18916 Mon Sep 17 00:00:00 2001 From: SCZeiDan <53632180+SCZeiDan@users.noreply.github.com> Date: Sun, 5 May 2024 00:51:27 +0800 Subject: [PATCH] =?UTF-8?q?[stm32]=20i2c=20hard=20driver=20fixup=EF=BC=9A?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A1=AC=E4=BB=B6I2C=E4=BC=A0=E8=BE=93?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E7=AD=89=E5=BE=85=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 在使用硬件 I2C 驱动进行音频模块 WM8978 配置时,发现连续 rt_i2c_transfer 进行 I2C 传输时发现,连续多次调用 rt_i2c_transfer 会出现丢包现象;溯源发现是每次使用 rt_i2c_transfer 传输2字节,传输频率过高导致底层 HAL_I2C_Master_Seq_Transmit_DMA 报错 HAL_BUSY; 现象: rt_completion_wait超时等待完成之后,I2C仍处于HAL_I2C_STATE_BUSY_TX状态,且后续第二次运行至HAL_I2C_Master_Seq_Transmit_DMA时会直接返回HAL_BUSY,从而直接 goto out; 退出而不会再次进行超时等待; * drv_hard_i2c.c: 修复325行缺失'}'语法错误;更改HAL_I2C_xx_Transimt_xx调用中目标设备地址值;i2c_hard_config.h: 添加STM32F系列芯片xx_DMA_CONFIG宏定义; * 回溯I2C设备地址传参处(msg->addr<<1)修改; * fixup: 增加硬件I2C传输延时,解决连续传输导致HAL_BUSY状态; --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.c index 08ac464592..405644a36d 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.c @@ -177,7 +177,7 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus, LOG_D("xfer msgs[%d] addr=0x%2x buf=0x%x len= 0x%x flags= 0x%x", i, msg->addr, msg->buf, msg->len, msg->flags); next_msg = &msgs[i + 1]; next_flag = next_msg->flags; - timeout = msg->len/TRANS_TIMEOUT_PERSEC + 1; + timeout = msg->len/TRANS_TIMEOUT_PERSEC + 5; if (next_flag & RT_I2C_NO_START) { if ((next_flag & RT_I2C_RD) == (msg->flags & RT_I2C_RD)) @@ -250,7 +250,7 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus, } /* last msg */ msg = &msgs[i]; - timeout = msg->len/TRANS_TIMEOUT_PERSEC+1; + timeout = msg->len/TRANS_TIMEOUT_PERSEC + 5; if (msg->flags & RT_I2C_NO_STOP) mode = I2C_LAST_FRAME_NO_STOP; else