stk8ba58 1.0.2

Driver for the Sensortek STK8BA58 3-axis MEMS Accelerometer
Documentation
//! Driver for the Sensortek STK8BA58 3-axis MEMS Accelerometer
//!
//! Implements the [`Accelerometer` trait](https://docs.rs/accelerometer/latest/accelerometer/trait.Accelerometer.html)
//! from the `accelerometer` crate.
//!
//! # How to use
//! ## Reading the acceleration:
//! ```no_run
//! use stk8ba58::Stk8ba58;
//! use accelerometer::{vector::I16x3, Accelerometer};
//!
//! // i2c is an I2C bus you have previously initialized with your HAL
//! let mut accelerometer = Stk8ba58::new(i2c);
//!
//! let acceleration = accelerometer.accel_norm().unwrap();
//! let x_component = acceleration.x;
//! let y_component = acceleration.y;
//! let z_component = acceleration.z;
//! ```
//!
//! ## Setting register flags:
//! ```no_run
//! use stk8ba58::{
//!     registers::{Write, INTEN1},
//!     Stk8ba58,
//! };
//!
//! // i2c is an I2C bus you have previously initialized with your HAL
//! let mut accelerometer = Stk8ba58::new(i2c);
//!
//! // Enable slope interrupt for the X and Y axis.
//! let flags = INTEN1::SLP_EN_X | INTEN1::SLP_EN_Y;
//! accelerometer.set_flags(flags).unwrap();
//! ```
//!
//! ## Reading set values:
//! ```no_run
//! use stk8ba58::{
//!     registers::{Read, SleepDuration},
//!     Stk8ba58,
//! };
//!
//! // i2c is an I2C bus you have previously initialized with your HAL
//! let mut accelerometer = Stk8ba58::new(i2c);
//!
//! let sleep_duration = accelerometer.sleep_duration().unwrap();
//! if sleep_duration == SleepDuration::Ms10 {
//!     // Accelerometer is configured to have a 10ms sleep phase.
//! }
//! ```
#![doc(html_logo_url = "https://gitlab.com/slusheea/stk8ba58/-/raw/main/images/chip.svg")]
#![no_std]
use core::fmt::Debug;

use accelerometer_hal::error::Error;
use embedded_hal::i2c::I2c;

pub mod registers;
use registers::{RangeSel, Register};

mod accelerometer;

/// Software representation of the STK8BA58.
///
/// Create it with [`Stk8ba58::new()`] or check out the [examples](https://gitlab.com/slusheea/stk8ba58/-/tree/main/examples)
pub struct Stk8ba58<I2C> {
    i2c: I2C,
    range: RangeSel,
}

impl<I2C, E> Stk8ba58<I2C>
where
    I2C: I2c<Error = E>,
    E: Debug,
{
    /// STK8BA53 I2C address
    pub const ADDRESS: u8 = 0x18;

    /// Default STK8BA53 chip ID
    pub const CHIP_ID: u8 = 0x87;

    /// Create a new STK8BA58 from the I2C
    ///
    /// Usage:
    /// ```no_run
    /// // Your HAL's I2C object
    /// let i2c = I2C::i2c1(
    ///     pac.I2C1,
    ///     sda_pin,
    ///     scl_pin,
    ///     400.kHz(),
    ///     &mut pac.RESETS,
    ///     &clocks.system_clock,
    /// );
    ///
    /// let accelerometer = Stk8ba58::new(i2c);
    /// ```
    pub fn new(i2c: I2C) -> Self {
        Self {
            i2c,
            range: RangeSel::default(),
        }
    }

    /// Write to the given register
    ///
    /// # Errors
    ///  - Any I²C errors will cause the function to fail.
    fn write_register(&mut self, register: Register, value: u8) -> Result<(), Error<E>> {
        debug_assert!(!register.read_only(), "can't write to read-only register");
        self.i2c.write(Self::ADDRESS, &[register.addr(), value])?;
        Ok(())
    }

    /// Write to a given register, then read the result
    ///
    /// # Errors
    ///  - Any I²C errors will cause the function to fail.
    fn read_register(&mut self, register: Register, buffer: &mut [u8]) -> Result<(), E> {
        self.i2c
            .write_read(Self::ADDRESS, &[register.addr()], buffer)
    }
}