Initialize sensor
Let's initialize the sensor. For this, we first create an I2C interface using the embassy-nrf and BSP crates. Once the I2C interface is instantiated, we pass it to the Lsm303agr driver to initialize the sensor.
Add the necessary imports:
#![allow(unused)] fn main() { use embassy_nrf::{self as hal, twim::Twim}; use hal::twim; use lsm303agr::Lsm303agr; }
Two Wire Interface in Master mode (TWIM)
We initialize the I2C-compatible TWIM driver provided by the embassy-nrf crate. This peripheral allows the nRF processor to act as an I2C master and communicate with devices like the LSM303AGR sensor.
We will create a Twim instance, which requires the I2C peripheral (TWISPI0), the interrupt handler (Irqs), the I2C pins (SDA and SCL), and configuration (which we will leave it to default).
#![allow(unused)] fn main() { static RAM_BUFFER: ConstStaticCell<[u8; 16]> = ConstStaticCell::new([0; 16]); let twim_config = twim::Config::default(); let twim0 = Twim::new( board.twispi0, Irqs, board.i2c_int_sda, // Internal I2C SDA, GPIO Pin: P0_08 board.i2c_int_scl, // Internal I2C SCL, GPIO Pin:P0_08 twim_config, RAM_BUFFER.take(), ); }
The last parameter is a RAM buffer that the TWIM driver uses when sending data. If the data is stored in flash memory (like fixed byte arrays written in your code), it cannot be sent directly over I2C. The driver first copies it into RAM using this buffer. We use ConstStaticCell to safely create the buffer in RAM, and .take() gives us safe access to it. A 16-byte buffer is usually enough for common I2C tasks like talking to sensors. If the RAM buffer is too small to hold the data being sent, the TWIM driver will panic and return a RAMBufferTooSmall error.
Lsm303agr Driver
Once the TWIM is initialized, we can pass it to the Lsm303agr::new_with_i2c function, which creates a new instance of the sensor driver using the provided I2C interface.
#![allow(unused)] fn main() { let mut sensor = Lsm303agr::new_with_i2c(twim0); }