| Crates.io | tca9534-driver-rs |
| lib.rs | tca9534-driver-rs |
| version | 0.1.0 |
| created_at | 2025-07-10 09:15:35.230452+00 |
| updated_at | 2025-07-10 09:15:35.230452+00 |
| description | A platform-independent driver for the TCA9534 I2C IO expander |
| homepage | |
| repository | https://github.com/Adancurusul/tca9534-driver-rs |
| max_upload_size | |
| id | 1746063 |
| size | 54,732 |
A platform-independent Rust driver for the TCA9534 I2C IO expander, with optional embedded-hal integration.
no_std Compatible: Perfect for embedded systems┌─────────────────────────────────────┐
│ User Code Layer │
├─────────────────────────────────────┤
│ Convenience Constructors │ <- embedded-hal optional
│ (new_with_default_address) │
├─────────────────────────────────────┤
│ TCA9534 Driver Core │ <- Always available
├─────────────────────────────────────┤
│ Transport Traits │ <- Always available
│ (SyncTransport/AsyncTransport) │
├─────────────────────────────────────┤
│ Transport Implementation Layer │ <- embedded-hal optional
└─────────────────────────────────────┘
Core Principle: Driver core and transport traits are always available, embedded-hal integration is optional
full-async): Complete async functionality with embedded-hal integrationdefault-features = false): Zero dependencies, custom transport onlyembedded-hal): Synchronous operations with embedded-hal I2C traitsasync + embedded-hal-async): Async/await support with embedded-hal integrationThe TCA9534 is an 8-bit I2C IO expander that provides:
[dependencies]
# Default - includes full async support (async + embedded-hal + embedded-hal-async)
tca9534 = "0.1"
# Minimal - no external dependencies, sync only
tca9534 = { version = "0.1", default-features = false }
# Sync with embedded-hal support only
tca9534 = { version = "0.1", default-features = false, features = ["embedded-hal"] }
# Async only (no embedded-hal)
tca9534 = { version = "0.1", default-features = false, features = ["async"] }
# Custom combinations
tca9534 = { version = "0.1", default-features = false, features = ["async", "embedded-hal"] }
# With defmt logging support
tca9534 = { version = "0.1", features = ["defmt"] }
async - Enables async/await support for TCA9534Asyncembedded-hal - Enables embedded-hal v1.0 I2C trait integrationembedded-hal-async - Enables embedded-hal-async I2C trait integrationfull-async - Combines async + embedded-hal + embedded-hal-async (included in default)defmt - Enables defmt logging supportDefault features: ["full-async"] - provides complete async functionality out of the box.
Note: For sync-only usage, disable default features in your Cargo.toml:
tca9534 = { version = "0.1", default-features = false, features = ["embedded-hal"] }
use tca9534::{TCA9534Sync, PinConfig, PinLevel, addresses};
// Initialize I2C bus (platform specific)
let i2c = setup_i2c(); // Your I2C initialization code
// Create TCA9534 driver with address 0x20
let mut tca9534 = TCA9534Sync::new(i2c, addresses::ADDR_000);
// Or use default address constructor
let mut tca9534 = TCA9534Sync::new_with_default_address(i2c);
//Or use transport which implements SyncTransport
let transport = MyI2c::new(your_own_i2c);
let mut tca9534 = TCA9534Sync::new(transport, addresses::ADDR_000);
// Initialize the device
tca9534.init()?;
// Configure pin 0 as output, others as input
tca9534.set_pin_config(0, PinConfig::Output)?;
for pin in 1..8 {
tca9534.set_pin_config(pin, PinConfig::Input)?;
}
// Set pin 0 to high
tca9534.set_pin_output(0, PinLevel::High)?;
// Read pin 1 input
let pin1_level = tca9534.read_pin_input(1)?;
// Toggle pin 0
tca9534.toggle_pin_output(0)?;
Note: For zero dependencies, use minimal mode:
tca9534 = { version = "0.1", default-features = false }
use tca9534::{TCA9534Sync, PinConfig, PinLevel, addresses, SyncTransport};
// Implement your own transport
struct MyI2cTransport {
// Your I2C implementation
}
impl SyncTransport for MyI2cTransport {
type Error = MyError;
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
// Your I2C write implementation
}
fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Self::Error> {
// Your I2C read implementation
}
fn write_read(&mut self, addr: u8, wr_bytes: &[u8], rd_bytes: &mut [u8]) -> Result<(), Self::Error> {
// Your I2C write_read implementation
}
}
// Use with custom transport
let transport = MyI2cTransport::new();
let mut tca9534 = TCA9534Sync::new(transport, addresses::ADDR_000);
Note: Async support is enabled by default with full-async feature.
use tca9534::{TCA9534Async, PinConfig, PinLevel, addresses};
// Initialize async I2C bus (platform specific)
let i2c = setup_async_i2c(); // Your async I2C initialization code
// Create TCA9534 driver
let mut tca9534 = TCA9534Async::new(i2c, addresses::ADDR_000);
// Initialize the device
tca9534.init().await?;
// Configure and use pins
tca9534.set_pin_config(0, PinConfig::Output).await?;
tca9534.set_pin_output(0, PinLevel::High).await?;
let input_level = tca9534.read_pin_input(1).await?;
// Configure all pins at once (1=input, 0=output)
tca9534.set_port_config(0b11110000)?; // Pins 0-3 output, 4-7 input
// Set all output pins at once
tca9534.write_output_port(0b00001111)?; // Set pins 0-3 high
// Read all input pins at once
let input_state = tca9534.read_input_port()?;
new(transport, address) - Create new driver instanceinit() - Initialize device with default settingsset_pin_config(pin, config) - Configure pin as input or outputset_pin_output(pin, level) - Set output pin high or lowread_pin_input(pin) - Read input pin leveltoggle_pin_output(pin) - Toggle output pin stateset_port_config(config) - Configure all pins at oncewrite_output_port(value) - Set all output pins at onceread_input_port() - Read all input pins at onceread_output_port() - Read current output register valueset_pin_polarity(pin, polarity) - Set input polarity (normal/inverted)set_port_polarity(polarity) - Set polarity for all pinsaddress() / set_address(addr) - Get/set I2C address| Register | Address | Description |
|---|---|---|
| Input Port | 0x00 | Read input pin levels |
| Output Port | 0x01 | Set output pin levels |
| Polarity Inversion | 0x02 | Configure input polarity |
| Configuration | 0x03 | Configure pin directions |
The TCA9534 supports 8 different I2C addresses based on the A2, A1, A0 pins:
| A2 | A1 | A0 | Address | Constant |
|---|---|---|---|---|
| 0 | 0 | 0 | 0x20 | addresses::ADDR_000 |
| 0 | 0 | 1 | 0x21 | addresses::ADDR_001 |
| 0 | 1 | 0 | 0x22 | addresses::ADDR_010 |
| 0 | 1 | 1 | 0x23 | addresses::ADDR_011 |
| 1 | 0 | 0 | 0x24 | addresses::ADDR_100 |
| 1 | 0 | 1 | 0x25 | addresses::ADDR_101 |
| 1 | 1 | 0 | 0x26 | addresses::ADDR_110 |
| 1 | 1 | 1 | 0x27 | addresses::ADDR_111 |
The driver provides minimal error handling focused on essential validation:
InvalidPin - Pin number out of range (must be 0-7)I2cError(E) - Underlying I2C transport errorAdditional error types can be added as needed for your specific use case.
This driver works with any platform that implements the embedded-hal I2C traits:
stm32hal family crates)esp-hal)rp2040-hal)arduino-hal)linux-embedded-hal)You can use this driver on any platform by implementing the SyncTransport or AsyncTransport traits for your I2C implementation.
embedded-hal - Enable embedded-hal I2C trait integrationembedded-hal-async - Enable embedded-hal async I2C trait integrationasync - Enable async/await support (requires async transport)defmt - Enable defmt logging supportSee the examples/ directory for complete examples:
basic_usage - Complete example using STM32G431 with embassy-rsContributions are welcome! Please feel free to submit a Pull Request.
Licensed under either of
at your option.