1 个不稳定版本
0.1.0 | 2020年1月27日 |
---|
#1170 in 嵌入式开发
14KB
68 行
i2c_hung_fix
尝试使用 embedded-hal 的特性,在非正常重置后解除 I2C 总线的挂起状态。
I2C 标准的一个缺点是,如果主设备在从设备读取数据的过程中断电或崩溃,从设备会保持数据线处于低电平,因为它正在等待完成向主设备发送数据。
如果数据线保持低电平,初始化主设备上的 I2C 将会失败,因为从设备不会响应启动程序。这通常被称为挂起总线。
我实现了这个功能,因为在我的设备开发与调试过程中,设备重编程时 I2C 总线经常挂起,但这是一个在生产硬件中人们需要缓解的已知问题。
模拟器件(Analog Devices)有一篇应用笔记描述了这个问题和两种解决方案:[实现 I2C 重置](https://www.analog.com/media/en/technical-documentation/application-notes/54305147357414AN686_0.pdf)
如果硬件设计可以添加硬件,允许主设备给从设备断电是最佳方案;但在许多情况下,软件解决方案也有效。
这个 crate 实现了挂起总线的软件解决方案。它简单地给 SCL 时钟线计时,直到从设备释放 SDA 数据线。
在每次启动时运行挂起修复是合理的;如果总线没有挂起,它将在单个 I2C 时钟周期后退出。
示例
本示例使用 stm32f1xx-hal
let mut rcc = device.RCC.constrain();
let mut flash = device.FLASH.constrain();
let mut gpiob = device.GPIOB.split(&mut rcc.apb2);
let mut scl = gpiob.pb10.into_push_pull_ouput();
let sda = gpiob.pb11;
let clocks = rcc.cfgr.freeze(&mut flash.acr);
let mut delay = Delay::new(core.SYST, clocks);
try_unhang_i2c(&mut scl, &sda, &mut delay, 4_000_000, RECOMMENDED_MAX_CLOCK_CYCLES)
.expect("I2C bus is still hung after try_unhang_i2c");
许可证
免费开源软件,根据 MIT 许可证和 Apache 许可证 2.0 的条款分发。
依赖项
~71KB