-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from madeleyneVaca/mavaca/io_exp_min_support
Min support for PCAL6416A
- Loading branch information
Showing
8 changed files
with
299 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
[package] | ||
name = "pcal6416a" | ||
version = "0.1.0" | ||
repository = "https://github.com/pop-project/pcal6416a" | ||
license = "MIT" | ||
description = "Platform-agnostic Rust driver for the Texas Instruments BQ25773 battery charge controller." | ||
readme = "README.md" | ||
keywords = ["pcal6416a", "NXP", "IO Expander", "i2c", "driver", "embedded-hal-driver"] | ||
categories = ["embedded", "hardware-support", "no-std"] | ||
documentation = "https://docs.rs/pcal6416a" | ||
include = [ | ||
"/**/*.rs", | ||
"/Cargo.toml", | ||
"/README.md", | ||
"/LICENSE", | ||
"/device.yaml", | ||
] | ||
edition = "2021" | ||
|
||
[dependencies] | ||
device-driver = { version = "=1.0.0-rc.1", default-features = false, features = ["yaml"] } | ||
defmt = { version = "0.3", optional = true } | ||
embedded-hal = "1.0.0" | ||
embedded-hal-async = "1.0.0" | ||
|
||
[lints.rust] | ||
unsafe_code = "forbid" | ||
missing_docs = "deny" | ||
|
||
|
||
[lints.clippy] | ||
correctness = "forbid" | ||
suspicious = "forbid" | ||
perf = "forbid" | ||
style = "forbid" | ||
pedantic = "deny" | ||
|
||
[features] | ||
defmt-03 = ["dep:defmt", "device-driver/defmt-03"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,19 @@ | ||
# embedded-rust-template | ||
Template repository for Embedded Rust development | ||
# PCAL6416A Rust Device Driver | ||
|
||
A `#[no_std]` platform-agnostic driver for the [PCAL6416A](https://www.nxp.com/docs/en/data-sheet/PCAL6416A.pdf) IO Expander | ||
|
||
## MSRV | ||
|
||
Currently, rust `1.81` and up is supported. | ||
|
||
## License | ||
|
||
Licensed under the terms of the [MIT license](http://opensource.org/licenses/MIT). | ||
|
||
## Contribution | ||
|
||
Unless you explicitly state otherwise, any contribution submitted for | ||
inclusion in the work by you shall be licensed under the terms of the | ||
MIT license. | ||
|
||
License: MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#![allow(missing_docs)] | ||
fn main() { | ||
println!("cargo:rebuild-if-changed=device.yaml"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
config: | ||
register_address_type: u8 | ||
default_byte_order: LE | ||
default_bit_order: LSB0 | ||
defmt_feature: defmt-03 | ||
|
||
OUTPUT_PORT0: | ||
type: register | ||
address: 0x02 | ||
size_bits: 8 | ||
reset_value: 0xFF | ||
fields: | ||
O0_0: | ||
base: bool | ||
start: 0 | ||
description: Output Port 0 Pin 0. Host writes this bit to set the desired logic output level. | ||
O0_1: | ||
base: bool | ||
start: 1 | ||
description: Output Port 0 Pin 1. Host writes this bit to set the desired logic output level. | ||
O0_2: | ||
base: bool | ||
start: 2 | ||
description: Output Port 0 Pin 2. Host writes this bit to set the desired logic output level. | ||
O0_3: | ||
base: bool | ||
start: 3 | ||
description: Output Port 0 Pin 3. Host writes this bit to set the desired logic output level. | ||
O0_4: | ||
base: bool | ||
start: 4 | ||
description: Output Port 0 Pin 4. Host writes this bit to set the desired logic output level. | ||
O0_5: | ||
base: bool | ||
start: 5 | ||
description: Output Port 0 Pin 5. Host writes this bit to set the desired logic output level. | ||
O0_6: | ||
base: bool | ||
start: 6 | ||
description: Output Port 0 Pin 6. Host writes this bit to set the desired logic output level. | ||
O0_7: | ||
base: bool | ||
start: 7 | ||
description: Output Port 0 Pin 7. Host writes this bit to set the desired logic output level. | ||
|
||
OUTPUT_PORT1: | ||
type: register | ||
address: 0x03 | ||
size_bits: 8 | ||
reset_value: 0xFF | ||
fields: | ||
O1_0: | ||
base: bool | ||
start: 0 | ||
description: Output Port 1 Pin 0. Host writes this bit to set the desired logic output level. | ||
O1_1: | ||
base: bool | ||
start: 1 | ||
description: Output Port 1 Pin 1. Host writes this bit to set the desired logic output level. | ||
O1_2: | ||
base: bool | ||
start: 2 | ||
description: Output Port 1 Pin 2. Host writes this bit to set the desired logic output level. | ||
O1_3: | ||
base: bool | ||
start: 3 | ||
description: Output Port 1 Pin 3. Host writes this bit to set the desired logic output level. | ||
O1_4: | ||
base: bool | ||
start: 4 | ||
description: Output Port 1 Pin 4. Host writes this bit to set the desired logic output level. | ||
O1_5: | ||
base: bool | ||
start: 5 | ||
description: Output Port 1 Pin 5. Host writes this bit to set the desired logic output level. | ||
O1_6: | ||
base: bool | ||
start: 6 | ||
description: Output Port 1 Pin 6. Host writes this bit to set the desired logic output level. | ||
O1_7: | ||
base: bool | ||
start: 7 | ||
description: Output Port 1 Pin 7. Host writes this bit to set the desired logic output level. | ||
|
||
CONFIG_PORT0: | ||
type: register | ||
address: 0x06 | ||
size_bits: 8 | ||
reset_value: 0xFF | ||
fields: | ||
C0_0: | ||
base: bool | ||
start: 0 | ||
description: Config Port 0 Pin 0. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_1: | ||
base: bool | ||
start: 1 | ||
description: Config Port 0 Pin 1. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_2: | ||
base: bool | ||
start: 2 | ||
description: Config Port 0 Pin 2. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_3: | ||
base: bool | ||
start: 3 | ||
description: Config Port 0 Pin 3. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_4: | ||
base: bool | ||
start: 4 | ||
description: Config Port 0 Pin 4. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_5: | ||
base: bool | ||
start: 5 | ||
description: Config Port 0 Pin 5. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_6: | ||
base: bool | ||
start: 6 | ||
description: Config Port 0 Pin 6. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C0_7: | ||
base: bool | ||
start: 7 | ||
description: Config Port 0 Pin 7. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
CONFIG_PORT1: | ||
type: register | ||
address: 0x07 | ||
size_bits: 8 | ||
reset_value: 0xFF | ||
fields: | ||
C1_0: | ||
base: bool | ||
start: 0 | ||
description: Config Port 1 Pin 0. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_1: | ||
base: bool | ||
start: 1 | ||
description: Config Port 1 Pin 1. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_2: | ||
base: bool | ||
start: 2 | ||
description: Config Port 1 Pin 2. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_3: | ||
base: bool | ||
start: 3 | ||
description: Config Port 1 Pin 3. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_4: | ||
base: bool | ||
start: 4 | ||
description: Config Port 1 Pin 4. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_5: | ||
base: bool | ||
start: 5 | ||
description: Config Port 1 Pin 5. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_6: | ||
base: bool | ||
start: 6 | ||
description: Config Port 1 Pin 6. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. | ||
C1_7: | ||
base: bool | ||
start: 7 | ||
description: Config Port 1 Pin 7. Host clears this bit to set the pin as an output. Bit is set by default and configures the pin as an input. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
//! This is a platform-agnostic Rust driver for the NXP PCAL6416A IO Expander | ||
//! based on the [`embedded-hal`] traits. | ||
//! | ||
//! [`embedded-hal`]: https://docs.rs/embedded-hal | ||
//! | ||
//! For further details of the device architecture and operation, please refer | ||
//! to the official [`Datasheet`]. | ||
//! | ||
//! [`Datasheet`]: https://www.nxp.com/docs/en/data-sheet/PCAL6416A.pdf | ||
#![doc = include_str!("../README.md")] | ||
#![no_std] | ||
#![allow(missing_docs)] | ||
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] | ||
pub enum Pcal6416aError<E> { | ||
/// I2C bus error | ||
I2c(E), | ||
} | ||
const IOEXP_ADDR: u8 = 0x20; | ||
const LARGEST_REG_SIZE_BYTES: usize = 2; | ||
|
||
pub struct Pcal6416aDevice<I2c: embedded_hal_async::i2c::I2c> { | ||
pub i2cbus: I2c, | ||
} | ||
|
||
device_driver::create_device!( | ||
device_name: Device, | ||
manifest: "device.yaml" | ||
); | ||
|
||
impl<I2c: embedded_hal_async::i2c::I2c> device_driver::AsyncRegisterInterface for Pcal6416aDevice<I2c> { | ||
type Error = Pcal6416aError<I2c::Error>; | ||
type AddressType = u8; | ||
|
||
async fn write_register( | ||
&mut self, | ||
address: Self::AddressType, | ||
_size_bits: u32, | ||
data: &[u8], | ||
) -> Result<(), Self::Error> { | ||
assert!((data.len() <= LARGEST_REG_SIZE_BYTES), "Register size too big"); | ||
|
||
// Add one byte for register address | ||
let mut buf = [0u8; 1 + LARGEST_REG_SIZE_BYTES]; | ||
buf[0] = address; | ||
buf[1..=data.len()].copy_from_slice(data); | ||
|
||
// Because the pcal6416a has a mix of 1 byte and 2 byte registers that can be written to, | ||
// we pass in a slice of the appropriate size so we do not accidentally write to the register at | ||
// address + 1 when writing to a 1 byte register | ||
self.i2cbus | ||
.write(IOEXP_ADDR, &buf[..=data.len()]) | ||
.await | ||
.map_err(Pcal6416aError::I2c) | ||
} | ||
|
||
async fn read_register( | ||
&mut self, | ||
address: Self::AddressType, | ||
_size_bits: u32, | ||
data: &mut [u8], | ||
) -> Result<(), Self::Error> { | ||
self.i2cbus | ||
.write_read(IOEXP_ADDR, &[address], data) | ||
.await | ||
.map_err(Pcal6416aError::I2c) | ||
} | ||
} |