Skip to content

Commit

Permalink
add I2C autodetect feature
Browse files Browse the repository at this point in the history
Added a new function which simply scans all possible I2C addresses
for the device to determine the `SlaveAddr`.
  • Loading branch information
robamu committed Jun 24, 2024
1 parent 030919b commit 6436747
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,49 @@ pub struct Lis2dh12<I2C> {
fs: FullScale,
}

/// Errors returned from the [detect_i2c_addr]
#[derive(Debug)]
pub enum AddrDetectionError<I2cError: Debug> {
/// Other I2C error trying to detect a device address.
I2c(I2cError),
/// Invalid device ID read from device.
InvalidDeviceId,
}

impl<I2cError: Debug> From<I2cError> for AddrDetectionError<I2cError> {
fn from(value: I2cError) -> Self {
AddrDetectionError::I2c(value)
}
}

/// This function tries to detect the I2C address of the device by scanning all possible I2C
/// addresses.
pub fn detect_i2c_addr<I2C: I2c>(
i2c: &mut I2C,
) -> Result<SlaveAddr, AddrDetectionError<I2C::Error>> {
let mut buf = [0u8];
let write_buf = &[reg::Register::WHO_AM_I.addr()];
match i2c.write_read(reg::I2C_SAD | 0b1, write_buf, &mut buf) {
Ok(_) => {
if buf[0] == reg::DEVICE_ID {
return Ok(SlaveAddr::Alternative(true));
}
Err(AddrDetectionError::InvalidDeviceId)
}
Err(_) => {
let result = i2c.write_read(reg::I2C_SAD, write_buf, &mut buf);
if result.is_ok() {
if buf[0] == reg::DEVICE_ID {
return Ok(SlaveAddr::Default);
} else {
return Err(AddrDetectionError::InvalidDeviceId);
}
}
Err(result.unwrap_err().into())
}
}
}

/// Interrupt setting and status
pub struct Int<'a, REG, I2C> {
dev: &'a mut Lis2dh12<I2C>,
Expand Down

0 comments on commit 6436747

Please sign in to comment.