rp2040-hal中Spi<Enabled, D, DS>如何实现FullDuplex以调用传输函数?
我定义了如下TMC429结构体,其成员spi为rp2040-hal中的Spi<Enabled, D, DS>类型:
pub struct TMC429<D, CS, const DS: u8> where D: SpiDevice, CS: OutputPin, CS::Error: core::fmt::Debug { spi: Spi<Enabled, D, DS>, chip_select: CS, motors: [MotorConfig; 3] }
但我无法调用read/write/transfer函数,因为这些方法未针对Spi<Enabled, SpiDevice, const DS>实现。我知道SPI类型需要实现FullDuplex trait,而该trait在rp2040-hal的宏中实现,请问如何让我的spi成员具备FullDuplex trait以使用传输函数?
添加
FullDuplextrait约束到泛型参数D
在结构体的where从句中,给D加上FullDuplextrait的约束,并指定数据宽度(比如u8,需匹配实际传输需求),同时约束其Error类型可调试。修改后的结构体定义:pub struct TMC429<D, CS, const DS: u8> where D: SpiDevice + FullDuplex<u8>, D::Error: core::fmt::Debug, CS: OutputPin, CS::Error: core::fmt::Debug { spi: Spi<Enabled, D, DS>, chip_select: CS, motors: [MotorConfig; 3] }确认D类型的合法性
rp2040-hal中,Spi0、Spi1这类SPI外设实例,在通过spi.configure(...)完成启用配置后,会通过内部宏自动实现FullDuplextrait。只要你初始化Spi<Enabled, D, DS>时使用的是rp2040-hal提供的合法SPI外设,这个约束就能满足。在结构体方法中调用传输函数
现在可以在TMC429的实现块中直接调用spi的read/write/transfer方法,示例:impl<D, CS, const DS: u8> TMC429<D, CS, DS> where D: SpiDevice + FullDuplex<u8>, D::Error: core::fmt::Debug, CS: OutputPin, CS::Error: core::fmt::Debug { pub fn transfer(&mut self, data: &mut [u8]) -> Result<(), D::Error> { self.chip_select.set_low().unwrap(); let result = self.spi.transfer(data); self.chip_select.set_high().unwrap(); result } }可选:绑定通用SPI trait
若想提升代码通用性,可直接绑定embedded_hal::spi::FullDuplex(rp2040-hal的FullDuplex是对该trait的实现),后续更换HAL库时修改成本更低。
内容的提问来源于stack exchange,提问作者elhe

