#i2c-bus #i2c #adafruit #seesaw #shared-bus

nightly no-std adafruit-seesaw

适用于与运行Seesaw固件的设备通信的平台无关实现

16次发布

0.6.1 2024年1月30日
0.5.3 2023年11月3日
0.5.1 2023年7月21日
0.5.0 2022年12月21日
0.0.3 2022年7月13日

#5 in #i2c-bus

Download history 5/week @ 2024-04-02 1/week @ 2024-05-28 3/week @ 2024-06-04 5/week @ 2024-06-11 95/week @ 2024-07-02

每月95次下载

MIT/Apache

275KB
895

Adafruit Seesaw Logo

crates.io page docs.rs

用于与实现Adafruit Seesaw固件的设备通信的平台无关驱动程序。有关固件信息,请参阅Seesaw指南

简介

该库遵循shared-bus库的模式,以便多个设备可以连接并进行通信,而无需拥有I2C总线。

与Seesaw设备通信需要实现I2C特性和来自embedded-halDelay的总线。

#![no_std]上下文中使用

如果您在单个线程内与设备通信,请使用使用RefCellBus包装器来允许多个Seesaw设备共享总线的SeesawRefCell类型结构。

// Setup on an STM32F405
let cp = cortex_m::Peripherals::take().unwrap();
let clocks = dp.RCC.constrain().cfgr.freeze();
let delay = cp.SYST.delay(&clocks);
let i2c = I2c::new(dp.I2C1, (scl, sda), 400.kHz(), &clocks);
let seesaw = SeesawRefCell::new(delay, i2c);
let mut neokeys = NeoKey1x4::new_with_default_addr(seesaw.acquire_driver())
    .init()
    .expect("Failed to start NeoKey1x4");

跨多个线程使用

这需要启用std功能标志。

对于多线程用途,请使用将总线包装在std Mutex中的SeesawStdMutex类型结构。

在ESP32-S3上使用多线程Seesaw的示例用法

use adafruit_seesaw::{devices::RotaryEncoder, prelude::*, SeesawStdMutex};
use esp_idf_hal::{
    self,
    delay::Delay,
    gpio::PinDriver,
    i2c::{I2cConfig, I2cDriver},
    peripherals::Peripherals,
    prelude::*,
};
use std::time::Duration;

fn main() -> Result<(), anyhow::Error> {
    esp_idf_hal::sys::link_patches();
    esp_idf_svc::log::EspLogger::initialize_default();

    // System
    let peripherals = Peripherals::take().unwrap();
    let mut i2c_power = PinDriver::output(peripherals.pins.gpio7).unwrap();
    i2c_power.set_low()?;
    std::thread::sleep(Duration::from_millis(333));

    // I2C
    let (sda, scl) = (peripherals.pins.gpio3, peripherals.pins.gpio4);
    let config = I2cConfig::new().baudrate(400.kHz().into());
    let i2c = I2cDriver::new(peripherals.i2c0, sda, scl, &config)?;
    i2c_power.set_high()?;
    std::thread::sleep(Duration::from_millis(333));

    let seesaw: &'static _ = {
        use once_cell::sync::OnceCell;
        static MANAGER: OnceCell<SeesawStdMutex<(Delay, I2cDriver<'_>)>> =
            OnceCell::new();

        match MANAGER.set(SeesawStdMutex::new(Delay::new_default(), i2c)) {
            Ok(_) => MANAGER.get(),
            Err(_) => None,
        }
    }
    .unwrap();

    let _encoder =
        RotaryEncoder::new_with_default_addr(seesaw.acquire_driver())
            .init()
            .expect("Failed to start rotary encoder.");

    loop {
        // Do stuff with rotary encoder
    }
}

创建设备

所有设备都实现了SeesawDevice特性和相同的构造函数,以及大量其他设备特定信息。

产品值 所有SeesawDevice上的常量方法 注意
默认地址 设备::default_addr()
硬件ID 设备::hardware_id() 此值取决于设备的宿主MCU
产品ID 设备::product_id() 您可以使用此值访问adafruit.com上的产品页面。

让我们通过上面创建的 seesaw 管理器来与NeoKey1x4 进行通信。

使用默认地址

let neokeys = NeoKey1x4::new_with_default_addr(seesaw.acquire_driver());

使用自定义地址

let neokeys = NeoKey1x4::new(0x00, seesaw.acquire_driver());

初始化设备

实现 SeesawDevice 的设备也实现了 SeesawDeviceInit,这定义了一个设备特定的 init 函数来设置设备的硬件功能。目的是运行一组合理的默认值,这样你就不必自己记住去做。

let neokeys = NeoKey1x4::new_with_default_addr(seesaw.acquire_driver())
    .init()
    .expect("Failed to initialize NeoKey1x4");

例如,我们的 Neokey1x4init 函数执行以下操作

  • 重置设备
  • 读取并验证设备硬件ID
  • 启用设备上的 NeoPixel
  • 启用设备上的按钮

调用 init 是可选的,但如果没有它,你必须自己处理初始化。

创建自己的设备

到目前为止,这个库只实现了几个 Seesaw 设备(即我目前拥有的那些)。你可以使用 seesaw_device! 宏来定义自己的设备。

假设你有一个未来的 Adafruit Neokey 类似的设备,该设备有 6 个按钮和 6 个 NeoPixel。

seesaw_device! {
    name: Neokey2x3,
    hardware_id: HardwareId::_,
    product_id: _,
    default_addr: _,
    modules: [
        GpioModule,
        NeopixelModule { num_leds: 6, pin: _ },
    ]
}

你可能想做的最后一件事是实现 SeesawDeviceInit 特性来处理设备初始化

impl<D: Driver> SeesawDeviceInit<D> for Neokey2x3<D> {
    fn init(mut self) -> Result<Self, Self::Error> {
        self.reset_and_verify_seesaw()
            .and_then(|_| self.enable_neopixel())
            .and_then(|_| self.enable_button_pins())
            .map(|_| self)
    }
}

现在你可以像使用任何其他设备一样使用新设备

let neokeys = NeoKey2x3::new_with_default_addr(seesaw.acquire_driver())
    .init()
    .expect("Failed to initialize NeoKey1x4");

实现进度

Seesaw 模块 已实现
ADC
EEPROM ⬜️
编码器
GPIO
键盘 ⬜️ 待定
NeoPixel
Sercom0 ⬜️
频谱 ⬜️
状态
定时器
触摸 ⬜️
设备 产品ID MCU 已实现
ArcadeButton1x4 5296 ATTiny8x7
NeoKey1x4 4980 SAMD09
NeoSlider 5295 ATTiny8x7
NeoTrellis 3954 SAMD09 ⬜️ 待定
旋转编码器 4991 SAMD09

其他任务

  • ⬜️ 请求 Adafruit 提供一份使用 Seesaw 固件的产品列表
  • ⬜️ 为 CI 设置 github actions

许可协议

adafruit-seesaw 依据以下任一许可协议授权

任选其一。


与 Adafruit 无关联,也不受其官方支持。

依赖项