6 releases
| 0.2.4 | Nov 12, 2025 |
|---|---|
| 0.2.3 | Nov 12, 2025 |
| 0.2.2 | Oct 20, 2025 |
| 0.1.0 | Oct 5, 2025 |
#848 in Hardware support
23KB
434 lines
🛡️ 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-halorrppal, 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
I2cTransporttrait: abstracts read/write operations, allowing pluggable backends.EldritchShieldstruct: 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
eldritchwiremessage types - Support multi-shield configurations
📖 References
- Blackmagic Design 3G-SDI Shield Developer Manual (PDF)
- Blackmagic Camera Control Protocol
- Eldritchwire crate (Camera Control Protocol)
Eldritch Shield — a conduit between Rust and the arcane depths of Blackmagic hardware.
Dependencies
~87KB