#register #i2c #spi #embedded-hal-driver #traits-structs

无std bit-byte-structs

用于与基于寄存器的外设接口的无总线特性和结构体

1个不稳定版本

0.0.3 2021年9月29日

#1397 in 嵌入式开发


icm20948中使用

MIT许可

24KB
291

位字节结构体

一个库,提供创建基于寄存器配置的设备无总线驱动程序的模板

此库通过提供特性和结构体来帮助创建外设库,从而减少模板代码。这些特性目前实现了嵌入式-hal库的I2C和SPI特性。

这是一个初步版本,还有一些粗糙的边缘。

文档

当前文档可以在https://pointswaves.gitlab.io/bit-byte-structures/bit_byte_structs/index.html找到

许可

此库目前使用MIT许可。

交互

请随时创建一个问题来报告问题,或在花费太多时间之前讨论新的PR。


lib.rs:

位字节结构体

针对寄存器银行式芯片的无总线代码

许多外设IC芯片通过一组寄存器进行配置。设置这些寄存器以使芯片按预期工作可能需要大量努力和代码。此库实现了所需的模板代码,因此特定设备的库不需要。

关于此库

此库提供了一个方便的接口特性和I2C和SPI的实现。然后,它使用该特性实现了一组表示由子、空或多个字节组成的数字的基本结构。

没有理由不能为其他总线实现。当前的实现基于嵌入式hal特性

提供的结构用于快速轻松地创建外设芯片的驱动程序,而不是帮助优化驱动程序的某些性能方面。

此库在很大程度上受到了Adafruits BusIO的启发,但没有任何知识产权或代码共享。

像其他上述库的用户一样,假设驱动程序作者可以使用此库与基本配置寄存器进行交互,但可能实现自己的函数来处理性能关键或不太标准的寄存器。

此库有几个关键目标:* 使创建驱动程序变得容易 * 不占用总线的永久所有权 * 不让作者轻易选择使用此库交互的寄存器 * 最小化结构体下游用户的模板代码。

在库中使用

此库帮助使用库的库移除模板代码。

这些示例仅作说明。我们正在努力获取可正常工作的示例。

use core::marker::PhantomData;
use bitbytestructs::bus::{Interface, InterfaceError};
use bitbytestructs::registers::{BitStruct, BitByteStructError};

pub struct PeripheralDevice<InterfaceThing: ?Sized, E> {
   phantom: PhantomData<InterfaceThing>,
   low_power_bit: BitStruct<dyn Interface<Error = InterfaceError<E>>>,
}

impl<I2C, E> PeripheralDevice<I2C, E>
where
    I2C: Read<Error = E> + Write<Error = E> + WriteRead<Error = E>,
{
    pub fn new() -> Result<Self, BitByteStructError<InterfaceError<E>>> {

       let low_power_bit =
           BitStruct::<dyn Interface<Error = InterfaceError<E>>>::new(0x23, 1, 5)?;


        Ok(ICMCommon::<I, E> {
            phantom: PhantomData,
            low_power_bit,
        })
    }

   /// Set low power mode
   pub fn set_low_power(
       &mut self,
       i2c_bus: &mut I2C,
   ) -> Result<(), BitByteStructError<InterfaceError<E>>> {
        let mut interface = bus::SPIPeripheral::<I2C, E>::new(spi_bus, cs);
        
        if low_power {
           self.low_power_bit.write(interface, 1)?;
        } else {
           self.low_power_bit.write(interface, 0)?;
        }
        Ok(())
    }
}

该库可用于在编写使用单一总线的外设库时减少模板代码,此外,它还可以用于辅助具有SPI和I2C的外设。

使用此类库的库

fn main() {
    let spi_mode = Mode {
        polarity: Polarity::IdleLow,
        phase: Phase::CaptureOnFirstTransition,
    };

    let mut spi = Spi::spi2(dp.SPI2, pins, spi_mode, 500.khz(), clocks, &mut rcc.apb1);

    let mut delay_obj = Delay::new(cp.SYST, clocks);
    let mut peripheral_A = PeripheralDevice::new(&mut spi, cs_a).unwrap();
    peripheral_A.init(&mut spi, &mut delay_obj).unwrap();

    let mut peripheral_B = PeripheralDevice::new(&mut spi, cs_b).unwrap();
    peripheral_B.init(&mut spi, &mut delay_obj).unwrap();

    loop {
        let results = peripheral_A.get_values_accel_gyro(&mut spi).unwrap();
        let (xa, ya, za, xg, yg, zg) =
            results;
        hprintln!(
            "results values from chip A {:?} {:?} {:?} {:?} {:?} {:?}",
            xa,
            ya,
            za,
            xg,
            yg,
            zg
        )
        .unwrap();
        let results = peripheral_B.get_values_accel_gyro(&mut spi).unwrap();
        let (xa, ya, za, xg, yg, zg) =
            results;
        hprintln!(
            "results values from chip B{:?} {:?} {:?} {:?} {:?} {:?}",
            xa,
            ya,
            za,
            xg,
            yg,
            zg
        )
        .unwrap();
        delay_obj.delay_ms(500 as u16);
    }
}

通过借用每项操作的总线,我们使用类型系统确保总线在由其他外设使用时不会被访问。

外设结构体可以包含创建子结构体的函数,该子结构体在返回总线之前保持总线状态,以便不同外设可以使用。

依赖关系

~200KB