eldritch_shield

Crates.ioeldritch_shield
lib.rseldritch_shield
version0.2.4
created_at2025-10-05 20:23:11.012957+00
updated_at2025-11-12 02:58:25.562677+00
descriptionCrate for interfacing with the Blackmagic 3G-SDI Shield for Arduino
homepage
repositoryhttps://github.com/ekshore/eldritchwire
max_upload_size
id1869405
size23,204
Caleb Ekstrand (ekshore)

documentation

https://docs.rs/eldritch_shield

README

🛡️ eldritch_shield

Eldritch Shield is a Rust library for interfacing with the Blackmagic Design 3G-SDI Shield for Arduino over I²C.
It provides a safe, high-level API for controlling and querying the shield’s peripheral functions, while remaining agnostic of the underlying I²C transport implementation.

Designed to integrate cleanly with eldritchwire or any existing I²C client.


✨ Features

  • 🧩 Transport-agnostic: works with any I²C client — linux-embedded-hal or rppal, custom hardware clients, or mocks for testing.
  • 🧠 Strongly typed API: interact with camera control and SDI features using well-defined Rust types.
  • ⚙️ Blackmagic-specific: implements the protocol for the Blackmagic 3G-SDI Shield for Arduino.
  • 🧪 Test-friendly: easy to mock the transport layer for integration testing.

🚀 Example

use eldritch_shield::{EldritchShield, traits::I2cTransport};
use linux_embedded_hal::I2cdev;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create your own I²C client or use one from embedded-hal
    let i2c = I2cdev::new("/dev/i2c-1")?;
    
    // The Blackmagic Shield’s I²C address (adjust as needed)
    let mut shield = EldritchShield::new(i2c, 0x3B);

    // Initialize the device
    shield.init()?;

    // Read status
    let status = shield.read_status()?;
    println!("Shield status: 0x{status:02X}");

    // Set a configuration mode
    shield.set_mode(0x01)?;

    Ok(())
}

🧱 Architecture

eldritch_shield/
├── src/
│   ├── lib.rs          # Crate entry point
│   ├── traits.rs       # I²C transport abstraction
│   ├── shield.rs       # High-level Blackmagic-specific logic
│   ├── registers.rs    # Register constants
│   └── errors.rs       # Unified error type
  • I2cTransport trait: abstracts read/write operations, allowing pluggable backends.
  • EldritchShield struct: encapsulates all shield functionality.
  • PeripheralError: unifies I²C transport and device-specific errors.

🔌 Transport Abstraction

Eldritch Shield doesn’t implement its own I²C driver. Instead, it defines a small trait you can implement for any backend:

pub trait I2cTransport {
    type Error;

    fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error>;
    fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error>;

    fn write_read(
        &mut self,
        addr: u8,
        bytes: &[u8],
        buffer: &mut [u8],
    ) -> Result<(), Self::Error> {
        self.write(addr, bytes)?;
        self.read(addr, buffer)
    }
}

Implement this for your own I²C layer, and you’re ready to go.


🧩 Integration with eldritchwire

eldritchwire handles Blackmagic SDI camera control protocol parsing and serialization. eldritch_shield handles the physical I²C link to the 3G-SDI Shield.

Together, they form a full control pipeline:

Camera Control  ⇄  eldritchwire  ⇄  eldritch_shield  ⇄  I²C Transport  ⇄  SDI Shield  ⇄  Camera

📦 Installation

Add to your Cargo.toml:

[dependencies]
eldritch_shield = "0.1"

🛠️ Development

Build

cargo build

Test

cargo test

Lint & Format

cargo fmt
cargo clippy

🧰 Future Plans

  • Implement support for non-default I2C addressing for rppal transport
  • Add async support via embedded-hal-async
  • Provide helper methods for camera control commands
  • Integrate better with eldritchwire message types
  • Support multi-shield configurations

📖 References


Eldritch Shielda conduit between Rust and the arcane depths of Blackmagic hardware.

Commit count: 70

cargo fmt