ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_lsm6dso.c File Reference

ST LSM6DSO 6-DoF IMU driver – implementation. More...

#include "ra8_lsm6dso.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_lsm6dso.c:

Go to the source code of this file.

Enumerations

enum  ra8_lsm6dso_burst_bytes_t : uint32_t {
  k_lsm6dso_xyz_burst_bytes = 6U ,
  k_lsm6dso_temp_burst_bytes = 2U ,
  k_lsm6dso_fifo_status_bytes = 2U
}
 Layout constants used by burst-read helpers. More...
enum  ra8_lsm6dso_endian_idx_t : uint8_t {
  k_lsm6dso_idx_low = 0U ,
  k_lsm6dso_idx_high = 1U
}
 Two's-complement byte combination – 0..1 indices. More...
enum  ra8_lsm6dso_xyz_off_t : uint8_t {
  k_lsm6dso_xyz_off_x_l = 0U ,
  k_lsm6dso_xyz_off_x_h = 1U ,
  k_lsm6dso_xyz_off_y_l = 2U ,
  k_lsm6dso_xyz_off_y_h = 3U ,
  k_lsm6dso_xyz_off_z_l = 4U ,
  k_lsm6dso_xyz_off_z_h = 5U
}
 XYZ sample byte offsets within the 6-byte burst. More...
enum  ra8_lsm6dso_shift_t : uint8_t {
  k_lsm6dso_shift_odr = 4U ,
  k_lsm6dso_shift_fs_xl = 2U ,
  k_lsm6dso_shift_fs_g = 2U ,
  k_lsm6dso_shift_fs_125 = 1U
}
 CTRL1_XL / CTRL2_G field positions (DS12140 sec 9.12 / 9.13). More...
enum  ra8_lsm6dso_mask_t : uint8_t {
  k_lsm6dso_mask_odr = 0xF0U ,
  k_lsm6dso_mask_fs_xl = 0x0CU ,
  k_lsm6dso_mask_fs_g = 0x0CU ,
  k_lsm6dso_mask_fs_125 = 0x02U ,
  k_lsm6dso_mask_fs_g_full = 0x0EU ,
  k_lsm6dso_mask_nibble = 0x0FU ,
  k_lsm6dso_mask_byte = 0xFFU
}
enum  ra8_lsm6dso_temp_const_t : int32_t {
  k_lsm6dso_temp_offset_centi_c = 2500 ,
  k_lsm6dso_temp_scale_num = 100 ,
  k_lsm6dso_temp_scale_den = 256
}
 Temperature conversion constants per DS12140 sec 9.27. More...
enum  ra8_lsm6dso_cap_t : uint8_t {
  k_lsm6dso_xl_fs_max = (uint8_t)k_lsm6dso_g_fs_2000dps ,
  k_lsm6dso_xl_fs_cap = (uint8_t)k_lsm6dso_xl_fs_8g ,
  k_lsm6dso_g_fs_cap = (uint8_t)k_lsm6dso_g_fs_2000dps ,
  k_lsm6dso_odr_cap = (uint8_t)k_lsm6dso_odr_6660hz
}
 Enum upper bounds used by RA8_CHECK_RANGE_TAG. More...

Functions

static uint8_t internal_lsm6dso_g_fs_bits (ra8_lsm6dso_g_fs_t fs)
 Compose the FS_G + FS_125 sub-field of CTRL2_G for the requested gyro full-scale code.
static ra8_err_t internal_lsm6dso_write_byte (ra8_lsm6dso_t *dev, uint8_t reg, uint8_t val)
 Write a single byte to reg via the bound transport.
static ra8_err_t internal_lsm6dso_read_byte (ra8_lsm6dso_t *dev, uint8_t reg, uint8_t *out)
 Read a single byte from reg via the bound transport.
static ra8_err_t internal_lsm6dso_rmw_odr (ra8_lsm6dso_t *dev, uint8_t reg, uint8_t odr_bits)
 Read-modify-write the ODR nibble [7:4] of a CTRL register.
ra8_err_t ra8_lsm6dso_init (ra8_lsm6dso_t *out_dev, const ra8_lsm6dso_bus_t *bus)
 Bind a transport to a driver instance.
ra8_err_t ra8_lsm6dso_who_am_i (ra8_lsm6dso_t *dev, uint8_t *out_id)
 Read the WHO_AM_I register.
ra8_err_t ra8_lsm6dso_set_accel_range (ra8_lsm6dso_t *dev, ra8_lsm6dso_xl_fs_t fs)
 Program the accelerometer full-scale range.
ra8_err_t ra8_lsm6dso_set_gyro_range (ra8_lsm6dso_t *dev, ra8_lsm6dso_g_fs_t fs)
 Program the gyroscope full-scale range.
ra8_err_t ra8_lsm6dso_set_odr (ra8_lsm6dso_t *dev, ra8_lsm6dso_odr_t odr)
 Program the Output Data Rate for both the accelerometer and the gyroscope.
static ra8_err_t internal_lsm6dso_read_xyz (ra8_lsm6dso_t *dev, uint8_t reg, ra8_lsm6dso_xyz_t *out)
 Common XYZ burst-read used by both read_accel and read_gyro.
ra8_err_t ra8_lsm6dso_read_accel (ra8_lsm6dso_t *dev, ra8_lsm6dso_xyz_t *out)
 Read one accelerometer sample (raw 16-bit two's-complement).
ra8_err_t ra8_lsm6dso_read_gyro (ra8_lsm6dso_t *dev, ra8_lsm6dso_xyz_t *out)
 Read one gyroscope sample (raw 16-bit two's-complement).
ra8_err_t ra8_lsm6dso_read_temp (ra8_lsm6dso_t *dev, int32_t *out_centi_c)
 Read the on-die temperature in centi-degrees Celsius.
static ra8_err_t internal_lsm6dso_read_fifo_depth (ra8_lsm6dso_t *dev, uint32_t *out_n)
 Read the live FIFO word count (DIFF_FIFO[9:0]).
static ra8_err_t internal_lsm6dso_burst_fifo (ra8_lsm6dso_t *dev, uint8_t *out_buf, uint32_t n_words)
 Burst-read n_words 7-byte FIFO records from FIFO_DATA_OUT_TAG.
static ra8_err_t internal_lsm6dso_fifo_check_args (const ra8_lsm6dso_t *dev, const uint8_t *out_buf, uint32_t max_words, const uint32_t *out_words)
 Validate the inputs to ra8_lsm6dso_read_xl_gyro_fifo.
ra8_err_t ra8_lsm6dso_read_xl_gyro_fifo (ra8_lsm6dso_t *dev, uint8_t *out_buf, uint32_t max_words, uint32_t *out_words)
 Drain up to max_samples paired XL+G samples from the embedded FIFO.

Variables

static const char *const s_lsm6dso_tag = "lsm6dso"
 Tag for ra8_log_error / ra8_log_info lines from this TU.

Detailed Description

ST LSM6DSO 6-DoF IMU driver – implementation.

Tag
[Ring 4 / Service] {World: NS}

Polling, transport-agnostic implementation. All register-level citations point at LSM6DSO DS12140 Rev 4 (Sept 2019). The transport is supplied by the caller (Dependency Inversion) so this TU does not link against ra8_i3c_i2c or ra8_spi.

Algorithm style throughout this file:

  1. Validate dev / bus / output pointer.
  2. Verify dev->initialized.
  3. Validate the enum argument is in range (config setters only).
  4. Issue read / read-modify-write / write via the transport.
  5. Update dev->*_code cache only on success.

Each public function carries at least two precondition checks and two postcondition statements to satisfy NASA P10 Rule 5.

Since
0.1.0

Definition in file ra8_lsm6dso.c.

Enumeration Type Documentation

◆ ra8_lsm6dso_burst_bytes_t

enum ra8_lsm6dso_burst_bytes_t : uint32_t

Layout constants used by burst-read helpers.

Enumerator
k_lsm6dso_xyz_burst_bytes 

3 axes * 2 bytes (DS12140 sec 9.29 / 9.35).

k_lsm6dso_temp_burst_bytes 

OUT_TEMP_L + OUT_TEMP_H (DS12140 sec 9.27).

k_lsm6dso_fifo_status_bytes 

FIFO_STATUS1 + FIFO_STATUS2 (DS12140 sec 9.44).

Definition at line 47 of file ra8_lsm6dso.c.

◆ ra8_lsm6dso_cap_t

enum ra8_lsm6dso_cap_t : uint8_t

Enum upper bounds used by RA8_CHECK_RANGE_TAG.

Enumerator
k_lsm6dso_xl_fs_max 

shared cap value 0x04.

k_lsm6dso_xl_fs_cap 

Highest XL FS code.

k_lsm6dso_g_fs_cap 

Highest G FS code.

k_lsm6dso_odr_cap 

Highest ODR code.

Definition at line 95 of file ra8_lsm6dso.c.

◆ ra8_lsm6dso_endian_idx_t

enum ra8_lsm6dso_endian_idx_t : uint8_t

Two's-complement byte combination – 0..1 indices.

Enumerator
k_lsm6dso_idx_low 

Little-endian low byte.

k_lsm6dso_idx_high 

Little-endian high byte.

Definition at line 54 of file ra8_lsm6dso.c.

◆ ra8_lsm6dso_mask_t

enum ra8_lsm6dso_mask_t : uint8_t
Enumerator
k_lsm6dso_mask_odr 

Bits [7:4]: ODR field.

k_lsm6dso_mask_fs_xl 

Bits [3:2]: FS_XL field.

k_lsm6dso_mask_fs_g 

Bits [3:2]: FS_G field.

k_lsm6dso_mask_fs_125 

Bit [1]: FS_125 select.

k_lsm6dso_mask_fs_g_full 

FS_G + FS_125 combined.

k_lsm6dso_mask_nibble 

Low nibble (used for FIFO len high).

k_lsm6dso_mask_byte 

Full byte mask.

Definition at line 77 of file ra8_lsm6dso.c.

◆ ra8_lsm6dso_shift_t

enum ra8_lsm6dso_shift_t : uint8_t

CTRL1_XL / CTRL2_G field positions (DS12140 sec 9.12 / 9.13).

Enumerator
k_lsm6dso_shift_odr 

ODR_xL[3:0] / ODR_G[3:0] occupy bits [7:4].

k_lsm6dso_shift_fs_xl 

FS_XL[1:0] occupies bits [3:2].

k_lsm6dso_shift_fs_g 

FS_G[1:0] occupies bits [3:2].

k_lsm6dso_shift_fs_125 

FS_125 select bit occupies bit [1].

Definition at line 70 of file ra8_lsm6dso.c.

◆ ra8_lsm6dso_temp_const_t

enum ra8_lsm6dso_temp_const_t : int32_t

Temperature conversion constants per DS12140 sec 9.27.

Enumerator
k_lsm6dso_temp_offset_centi_c 

+25 C zero offset, scaled x100.

k_lsm6dso_temp_scale_num 

Numerator for centi-C convert.

k_lsm6dso_temp_scale_den 

Denominator for centi-C convert.

Definition at line 88 of file ra8_lsm6dso.c.

◆ ra8_lsm6dso_xyz_off_t

enum ra8_lsm6dso_xyz_off_t : uint8_t

XYZ sample byte offsets within the 6-byte burst.

Enumerator
k_lsm6dso_xyz_off_x_l 

Lsm6dso xyz off x l.

k_lsm6dso_xyz_off_x_h 

Lsm6dso xyz off x h.

k_lsm6dso_xyz_off_y_l 

Lsm6dso xyz off y l.

k_lsm6dso_xyz_off_y_h 

Lsm6dso xyz off y h.

k_lsm6dso_xyz_off_z_l 

Lsm6dso xyz off z l.

k_lsm6dso_xyz_off_z_h 

Lsm6dso xyz off z h.

Definition at line 60 of file ra8_lsm6dso.c.

Function Documentation

◆ internal_lsm6dso_burst_fifo()

ra8_err_t internal_lsm6dso_burst_fifo ( ra8_lsm6dso_t * dev,
uint8_t * out_buf,
uint32_t n_words )
static

Burst-read n_words 7-byte FIFO records from FIFO_DATA_OUT_TAG.

Per DS12140 sec 9.60 FIFO_DATA_OUT_TAG (78h) the FIFO data registers auto-increment across the 7-byte word (1 TAG + 6 sample bytes). We issue a single bus burst so the IIC/SPI controller can stream the entire window without per-byte START/STOP overhead.

Parameters
[in]devDriver instance (already validated by caller).
[out]out_bufDestination buffer (must be >= n_words * 7).
[in]n_wordsNumber of 7-byte words to fetch (must be > 0).
Returns
Transport error code; k_ra8_ok on success.
Return values
k_ra8_okout_buf populated with n_words * 7 bytes.
otherForwarded from dev->bus.read_regs.
Precondition
dev was bound by ra8_lsm6dso_init and is initialized.
out_buf has capacity for n_words * 7 bytes and n_words > 0.
Postcondition
On success the buffer holds n_words consecutive FIFO records.
On failure the buffer contents are unspecified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 532 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::bus, ra8_lsm6dso_bus_t::ctx, k_lsm6dso_fifo_bytes_word, k_lsm6dso_reg_fifo_data_out, and ra8_lsm6dso_bus_t::read_regs.

Referenced by ra8_lsm6dso_read_xl_gyro_fifo().

◆ internal_lsm6dso_fifo_check_args()

ra8_err_t internal_lsm6dso_fifo_check_args ( const ra8_lsm6dso_t * dev,
const uint8_t * out_buf,
uint32_t max_words,
const uint32_t * out_words )
static

Validate the inputs to ra8_lsm6dso_read_xl_gyro_fifo.

Returns the same error codes as the public entry point would on each individual check, but lives in its own function so the public entry stays within the NASA P10 Rule 4 statement budget. Behaviour matches the public API one-to-one: NULL pointer -> k_ra8_err_null_ptr, not initialized -> k_ra8_err_not_initialized, zero max_words -> k_ra8_err_invalid_arg.

Parameters
[in]devDriver instance.
[in]out_bufCaller buffer.
[in]max_wordsCaller's word cap.
[in]out_wordsCaller's output count pointer.
Returns
k_ra8_ok if all preconditions hold, otherwise the matching error code.
Return values
k_ra8_okAll preconditions satisfied.
k_ra8_err_null_ptrAny of dev / out_buf / out_words is NULL.
k_ra8_err_not_initializeddev->initialized is false.
k_ra8_err_invalid_argmax_words is zero.
Precondition
Caller must not have validated dev / out_buf / out_words previously – this helper is the single validation gate.
dev is either NULL or points at storage owned by the caller.
Postcondition
No state is mutated by this helper.
On failure the returned code matches the first failing check.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 574 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::initialized, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by ra8_lsm6dso_read_xl_gyro_fifo().

◆ internal_lsm6dso_g_fs_bits()

uint8_t internal_lsm6dso_g_fs_bits ( ra8_lsm6dso_g_fs_t fs)
static

Compose the FS_G + FS_125 sub-field of CTRL2_G for the requested gyro full-scale code.

Per DS12140 sec 9.13 "CTRL2_G (11h)":

  • FS_125 (bit 1) = 1 selects the +-125 dps narrow scale; the FS_G[1:0] field is then a don't-care.
  • For FS_G code in {250, 500, 1000, 2000} dps FS_125 must be cleared and FS_G[1:0] takes the value from ra8_lsm6dso_g_fs_t minus the +-125 dps slot (i.e. k_lsm6dso_g_fs_250dps maps to FS_G = 0, ..._500dps to FS_G = 1, etc).

The return value is the 3-bit sub-field [3:1] of CTRL2_G, pre-shifted into place. The caller masks in the ODR nibble.

Parameters
[in]fsGyro full-scale code.
Returns
3-bit sub-field [3:1] of CTRL2_G, pre-shifted.
Return values
0x02FS_125 path (fs == k_lsm6dso_g_fs_125dps).
otherEncoded FS_G[1:0] field for the wider scales.
Precondition
fs is one of the k_lsm6dso_g_fs_* enum values.
Caller has already range-checked fs via RA8_CHECK_RANGE_TAG.
Postcondition
Return value occupies only bits [3:1] of a CTRL2_G byte.
ODR nibble [7:4] of the result is zero (caller OR's it in).
Note
Pure function; no MMIO or transport access.
Since
0.1.0

Definition at line 138 of file ra8_lsm6dso.c.

References k_lsm6dso_g_fs_125dps, k_lsm6dso_g_fs_250dps, k_lsm6dso_shift_fs_125, and k_lsm6dso_shift_fs_g.

Referenced by ra8_lsm6dso_set_gyro_range().

◆ internal_lsm6dso_read_byte()

ra8_err_t internal_lsm6dso_read_byte ( ra8_lsm6dso_t * dev,
uint8_t reg,
uint8_t * out )
static

Read a single byte from reg via the bound transport.

Thin wrapper around dev->bus.read_regs that pins the byte count to 1. All real validation lives in the public entry that invokes this helper.

Parameters
[in]devDriver instance (already validated).
[in]regRegister address.
[out]outReceives the byte on success.
Returns
Transport error code.
Return values
k_ra8_ok*out populated.
otherForwarded from dev->bus.read_regs; *out unchanged.
Precondition
dev is non-NULL.
out points at writable storage.
Postcondition
On success *out carries the register byte.
On failure *out is left untouched.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 206 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::bus, ra8_lsm6dso_bus_t::ctx, and ra8_lsm6dso_bus_t::read_regs.

Referenced by internal_lsm6dso_rmw_odr(), ra8_lsm6dso_set_accel_range(), ra8_lsm6dso_set_gyro_range(), and ra8_lsm6dso_who_am_i().

◆ internal_lsm6dso_read_fifo_depth()

ra8_err_t internal_lsm6dso_read_fifo_depth ( ra8_lsm6dso_t * dev,
uint32_t * out_n )
static

Read the live FIFO word count (DIFF_FIFO[9:0]).

Reads FIFO_STATUS1 + FIFO_STATUS2 (DS12140 sec 9.44 / 9.45) and extracts the 10-bit DIFF_FIFO field into a 32-bit count. The low 8 bits live in FIFO_STATUS1, the upper 2 bits live in the low nibble of FIFO_STATUS2.

Parameters
[in]devDriver instance (already validated by caller).
[out]out_nReceives the live FIFO word count on success.
Returns
Transport error code; k_ra8_ok on success.
Return values
k_ra8_ok*out_n populated with the DIFF_FIFO count.
otherForwarded from dev->bus.read_regs; *out_n unchanged.
Precondition
dev was bound by ra8_lsm6dso_init and is initialized.
out_n points at writable storage.
Postcondition
On success *out_n is in the range [0, 1023] (10-bit field).
On failure *out_n is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 491 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::bus, ra8_lsm6dso_bus_t::ctx, k_lsm6dso_fifo_status_bytes, k_lsm6dso_idx_high, k_lsm6dso_idx_low, k_lsm6dso_mask_nibble, k_lsm6dso_reg_fifo_status1, k_ra8_ok, and ra8_lsm6dso_bus_t::read_regs.

Referenced by ra8_lsm6dso_read_xl_gyro_fifo().

◆ internal_lsm6dso_read_xyz()

ra8_err_t internal_lsm6dso_read_xyz ( ra8_lsm6dso_t * dev,
uint8_t reg,
ra8_lsm6dso_xyz_t * out )
static

Common XYZ burst-read used by both read_accel and read_gyro.

Issues a single 6-byte burst at reg (auto-incrementing across X/Y/Z low+high bytes per DS12140 sec 9.29 .. 9.40) and packs the little-endian two's-complement bytes into the caller's ra8_lsm6dso_xyz_t struct.

Parameters
[in]devDriver instance (validated).
[in]regFirst register address (OUTX_L_A / OUTX_L_G).
[out]out3-axis raw sample.
Returns
Transport error code; out is left untouched on failure.
Return values
k_ra8_ok*out populated with the latest sample.
otherForwarded from dev->bus.read_regs.
Precondition
dev was bound by ra8_lsm6dso_init and is initialized.
out points at writable ra8_lsm6dso_xyz_t storage.
Postcondition
On success *out is fully overwritten.
On failure *out is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 403 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::bus, ra8_lsm6dso_bus_t::ctx, k_lsm6dso_xyz_burst_bytes, k_lsm6dso_xyz_off_x_h, k_lsm6dso_xyz_off_x_l, k_lsm6dso_xyz_off_y_h, k_lsm6dso_xyz_off_y_l, k_lsm6dso_xyz_off_z_h, k_lsm6dso_xyz_off_z_l, k_ra8_ok, ra8_lsm6dso_bus_t::read_regs, ra8_lsm6dso_xyz_t::x, ra8_lsm6dso_xyz_t::y, and ra8_lsm6dso_xyz_t::z.

Referenced by ra8_lsm6dso_read_accel(), and ra8_lsm6dso_read_gyro().

◆ internal_lsm6dso_rmw_odr()

ra8_err_t internal_lsm6dso_rmw_odr ( ra8_lsm6dso_t * dev,
uint8_t reg,
uint8_t odr_bits )
static

Read-modify-write the ODR nibble [7:4] of a CTRL register.

Used to share the ODR write path between CTRL1_XL (DS12140 sec 9.12) and CTRL2_G (DS12140 sec 9.13) – both registers place the ODR field in bits [7:4] with the rest of the byte reserved for the per-axis full-scale select. This helper reads the current register value, masks off the existing ODR nibble, OR's in the new ODR bits, and writes the merged byte back.

Parameters
[in]devDriver instance (already validated by caller).
[in]regCTRL register address (CTRL1_XL or CTRL2_G).
[in]odr_bitsNew ODR field, pre-shifted into bits [7:4].
Returns
Transport error code; k_ra8_ok on success.
Return values
k_ra8_okRegister byte updated.
otherForwarded from the read or write transport call.
Precondition
dev is non-NULL and previously bound by ra8_lsm6dso_init.
odr_bits has bits [3:0] clear (caller pre-shifted into [7:4]).
Postcondition
On success bits [7:4] of reg match odr_bits.
On failure reg is left untouched (read fault) or partially written (write fault); dev state is unchanged either way.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 240 of file ra8_lsm6dso.c.

References internal_lsm6dso_read_byte(), internal_lsm6dso_write_byte(), k_lsm6dso_mask_odr, and k_ra8_ok.

Referenced by ra8_lsm6dso_set_odr().

◆ internal_lsm6dso_write_byte()

ra8_err_t internal_lsm6dso_write_byte ( ra8_lsm6dso_t * dev,
uint8_t reg,
uint8_t val )
static

Write a single byte to reg via the bound transport.

Thin wrapper around dev->bus.write_regs that pins the byte count to 1 and stages the value on the caller's stack so the transport can DMA from it. All real validation lives in the public entry that invokes this helper.

Parameters
[in]devDriver instance (already validated by caller).
[in]regRegister address.
[in]valByte to write.
Returns
Transport error code.
Return values
k_ra8_okByte written.
otherForwarded from dev->bus.write_regs.
Precondition
dev is non-NULL.
dev->bus.write_regs is non-NULL.
Postcondition
No driver state is mutated.
val storage on the caller's stack is still valid post-return.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 176 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::bus, ra8_lsm6dso_bus_t::ctx, and ra8_lsm6dso_bus_t::write_regs.

Referenced by internal_lsm6dso_rmw_odr(), ra8_lsm6dso_set_accel_range(), and ra8_lsm6dso_set_gyro_range().

◆ ra8_lsm6dso_init()

ra8_err_t ra8_lsm6dso_init ( ra8_lsm6dso_t * out_dev,
const ra8_lsm6dso_bus_t * bus )
nodiscard

Bind a transport to a driver instance.

Copies the supplied bus interface into out_dev and marks the instance initialised. Does not touch the wire – the caller is expected to follow this with ra8_lsm6dso_who_am_i (sanity check) and then ra8_lsm6dso_set_* calls to configure the part.

Parameters
[out]out_devDriver state, populated on success.
[in]busTransport interface (must have non-NULL read_regs and write_regs).
Returns
ra8_err_t Error code.
Return values
k_ra8_okDriver state initialized.
k_ra8_err_null_ptrout_dev or bus is NULL, or one of the callbacks in bus is NULL.
Precondition
out_dev points at writable storage.
bus->read_regs and bus->write_regs are non-NULL.
Postcondition
On success out_dev->initialized == true.
On success the transport is captured by value; the caller may release *bus after this returns.
Note
Not thread-safe. Call once per driver instance from init context.
Since
0.1.0

Definition at line 256 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::accel_fs_code, ra8_lsm6dso_t::bus, ra8_lsm6dso_t::gyro_fs_code, ra8_lsm6dso_t::initialized, k_lsm6dso_g_fs_250dps, k_lsm6dso_odr_off, k_lsm6dso_xl_fs_2g, k_ra8_ok, ra8_lsm6dso_t::odr_code, RA8_CHECK_NULL_PTR, ra8_lsm6dso_bus_t::read_regs, s_lsm6dso_tag, and ra8_lsm6dso_bus_t::write_regs.

Referenced by main().

◆ ra8_lsm6dso_read_accel()

ra8_err_t ra8_lsm6dso_read_accel ( ra8_lsm6dso_t * dev,
ra8_lsm6dso_xyz_t * out )
nodiscard

Read one accelerometer sample (raw 16-bit two's-complement).

Burst-reads 6 bytes starting at OUTX_L_A (0x28) into a 3x16 sample (DS12140 sec 9.35 .. 9.40). The LSM6DSO is little-endian so the bytes are combined as (high << 8) | low.

Parameters
[in]devDriver instance.
[out]out3-axis raw sample.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSample read.
k_ra8_err_null_ptrdev or out is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
Caller has previously enabled the XL with ra8_lsm6dso_set_odr.
Postcondition
On success *out carries the latest XL sample.
On failure *out is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 422 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::initialized, internal_lsm6dso_read_xyz(), k_lsm6dso_reg_outx_l_a, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by imu_demo_sample_and_emit().

◆ ra8_lsm6dso_read_gyro()

ra8_err_t ra8_lsm6dso_read_gyro ( ra8_lsm6dso_t * dev,
ra8_lsm6dso_xyz_t * out )
nodiscard

Read one gyroscope sample (raw 16-bit two's-complement).

Burst-reads 6 bytes starting at OUTX_L_G (0x22) into a 3x16 sample (DS12140 sec 9.29 .. 9.34). The LSM6DSO is little-endian so the bytes are combined as (high << 8) | low.

Parameters
[in]devDriver instance.
[out]out3-axis raw sample.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSample read.
k_ra8_err_null_ptrdev or out is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
Caller has previously enabled the G with ra8_lsm6dso_set_odr.
Postcondition
On success *out carries the latest G sample.
On failure *out is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 431 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::initialized, internal_lsm6dso_read_xyz(), k_lsm6dso_reg_outx_l_g, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by imu_demo_sample_and_emit().

◆ ra8_lsm6dso_read_temp()

ra8_err_t ra8_lsm6dso_read_temp ( ra8_lsm6dso_t * dev,
int32_t * out_centi_c )
nodiscard

Read the on-die temperature in centi-degrees Celsius.

Reads the 16-bit two's-complement OUT_TEMP register pair (0x20..0x21, DS12140 sec 9.27 / 9.28) and converts to centi-degrees Celsius using the datasheet formula T[C] = (raw / 256) + 25. Multiplied by 100 to stay in integer arithmetic the formula becomes out_centi_c = (raw * 100) / 256 + 2500, which is what the driver implements.

Parameters
[in]devDriver instance.
[out]out_centi_cReceives the temperature in centi-deg C.
Returns
ra8_err_t Error code.
Return values
k_ra8_okTemperature read.
k_ra8_err_null_ptrdev or out_centi_c is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
out_centi_c points at writable storage.
Postcondition
On success *out_centi_c carries centi-degC.
On failure *out_centi_c is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 440 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::bus, ra8_lsm6dso_bus_t::ctx, ra8_lsm6dso_t::initialized, k_lsm6dso_idx_high, k_lsm6dso_idx_low, k_lsm6dso_reg_out_temp_l, k_lsm6dso_temp_burst_bytes, k_lsm6dso_temp_offset_centi_c, k_lsm6dso_temp_scale_den, k_lsm6dso_temp_scale_num, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, ra8_lsm6dso_bus_t::read_regs, and s_lsm6dso_tag.

Referenced by imu_demo_sample_and_emit().

◆ ra8_lsm6dso_read_xl_gyro_fifo()

ra8_err_t ra8_lsm6dso_read_xl_gyro_fifo ( ra8_lsm6dso_t * dev,
uint8_t * out_buf,
uint32_t max_words,
uint32_t * out_words )
nodiscard

Drain up to max_samples paired XL+G samples from the embedded FIFO.

Polls FIFO_STATUS1/2 (DS12140 sec 9.44 / 9.45) for the live sample count, then issues a burst read of FIFO_DATA_OUT_TAG (0x78, DS12140 sec 9.60 .. 9.66) for each available 7-byte FIFO word. The tag byte identifies the source (XL vs G) per Table 167 "Tag codes"; this helper returns whatever the FIFO happens to hold and lets the caller demux.

Parameters
[in]devDriver instance.
[out]out_bufDestination buffer; receives raw FIFO words laid out as [tag][b0 b1 b2 b3 b4 b5] repeated.
[in]max_wordsMaximum FIFO words the caller can store (capacity of out_buf in bytes is max_words * k_lsm6dso_fifo_bytes_word).
[out]out_wordsNumber of FIFO words actually read into out_buf.
Returns
ra8_err_t Error code.
Return values
k_ra8_okFIFO drained (possibly to zero words).
k_ra8_err_null_ptrAny of the pointers is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_invalid_argmax_words == 0.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
The FIFO has been enabled by the caller (FIFO_CTRL1..4).
Postcondition
On success *out_words <= max_words.
On failure *out_words is set to 0.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 590 of file ra8_lsm6dso.c.

References internal_lsm6dso_burst_fifo(), internal_lsm6dso_fifo_check_args(), internal_lsm6dso_read_fifo_depth(), and k_ra8_ok.

◆ ra8_lsm6dso_set_accel_range()

ra8_err_t ra8_lsm6dso_set_accel_range ( ra8_lsm6dso_t * dev,
ra8_lsm6dso_xl_fs_t fs )
nodiscard

Program the accelerometer full-scale range.

Read-modify-writes the FS_XL field in CTRL1_XL (DS12140 sec 9.12). The ODR_XL nibble is preserved by reading the current value first.

Parameters
[in,out]devDriver instance.
[in]fsRange code (one of k_lsm6dso_xl_fs_*).
Returns
ra8_err_t Error code.
Return values
k_ra8_okRange programmed.
k_ra8_err_null_ptrdev is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_invalid_argfs out of range.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
fs is one of the accel full-scale enum values.
Postcondition
On success dev->accel_fs_code == fs.
On failure dev->accel_fs_code is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 291 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::accel_fs_code, ra8_lsm6dso_t::initialized, internal_lsm6dso_read_byte(), internal_lsm6dso_write_byte(), k_lsm6dso_mask_fs_xl, k_lsm6dso_reg_ctrl1_xl, k_lsm6dso_shift_fs_xl, k_lsm6dso_xl_fs_cap, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by imu_demo_configure().

◆ ra8_lsm6dso_set_gyro_range()

ra8_err_t ra8_lsm6dso_set_gyro_range ( ra8_lsm6dso_t * dev,
ra8_lsm6dso_g_fs_t fs )
nodiscard

Program the gyroscope full-scale range.

Read-modify-writes the FS_G[1:0] and FS_125 fields in CTRL2_G (DS12140 sec 9.13). The ODR_G nibble is preserved by reading the current value first.

Parameters
[in,out]devDriver instance.
[in]fsRange code (one of k_lsm6dso_g_fs_*).
Returns
ra8_err_t Error code.
Return values
k_ra8_okRange programmed.
k_ra8_err_null_ptrdev is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_invalid_argfs out of range.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
fs is one of the gyro full-scale enum values.
Postcondition
On success dev->gyro_fs_code == fs.
On failure dev->gyro_fs_code is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 318 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::gyro_fs_code, ra8_lsm6dso_t::initialized, internal_lsm6dso_g_fs_bits(), internal_lsm6dso_read_byte(), internal_lsm6dso_write_byte(), k_lsm6dso_g_fs_cap, k_lsm6dso_mask_fs_g_full, k_lsm6dso_reg_ctrl2_g, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by imu_demo_configure().

◆ ra8_lsm6dso_set_odr()

ra8_err_t ra8_lsm6dso_set_odr ( ra8_lsm6dso_t * dev,
ra8_lsm6dso_odr_t odr )
nodiscard

Program the Output Data Rate for both the accelerometer and the gyroscope.

Writes odr into the ODR_XL field of CTRL1_XL and the ODR_G field of CTRL2_G. The full-scale nibble of each register is preserved by reading the current value first. The two blocks share an ODR scale (DS12140 sec 5.3 "Output data rate and bandwidth selection") so one parameter covers both.

Parameters
[in,out]devDriver instance.
[in]odrODR code (one of k_lsm6dso_odr_*).
Returns
ra8_err_t Error code.
Return values
k_ra8_okODR programmed for XL and G.
k_ra8_err_null_ptrdev is NULL.
k_ra8_err_invalid_statedev not initialized.
k_ra8_err_invalid_argodr out of range.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
odr is one of the ODR enum values.
Postcondition
On success dev->odr_code == odr.
On failure dev->odr_code is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 344 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::initialized, internal_lsm6dso_rmw_odr(), k_lsm6dso_mask_nibble, k_lsm6dso_odr_cap, k_lsm6dso_reg_ctrl1_xl, k_lsm6dso_reg_ctrl2_g, k_lsm6dso_shift_odr, k_ra8_err_invalid_arg, k_ra8_ok, ra8_lsm6dso_t::odr_code, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by imu_demo_configure().

◆ ra8_lsm6dso_who_am_i()

ra8_err_t ra8_lsm6dso_who_am_i ( ra8_lsm6dso_t * dev,
uint8_t * out_id )
nodiscard

Read the WHO_AM_I register.

Reads register 0x0F and returns the raw byte. On a healthy LSM6DSO this is 0x6C (k_lsm6dso_who_am_i_value); any other value means the wrong part is wired or the bus is mis-addressed.

Parameters
[in]devDriver instance.
[out]out_idReceives the WHO_AM_I byte.
Returns
ra8_err_t Error code.
Return values
k_ra8_ok*out_id populated.
k_ra8_err_null_ptrdev or out_id is NULL.
k_ra8_err_invalid_statedev has not been initialized.
k_ra8_err_nackTransport reported a NACK.
Precondition
ra8_lsm6dso_init returned k_ra8_ok for dev.
out_id points at writable storage.
Postcondition
On success *out_id carries the device-ID byte.
On failure *out_id is unmodified.
Note
Not thread-safe per-instance.
Since
0.1.0

Definition at line 276 of file ra8_lsm6dso.c.

References ra8_lsm6dso_t::initialized, internal_lsm6dso_read_byte(), k_lsm6dso_reg_who_am_i, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, and s_lsm6dso_tag.

Referenced by imu_demo_check_who_am_i().

Variable Documentation

◆ s_lsm6dso_tag

const char* const s_lsm6dso_tag = "lsm6dso"
static