In triggered mode, ina237_sample_fetch() called
ina237_trigg_one_shot_request() which only writes to the ADC_CONFIG
register to start a one-shot conversion, then returned immediately
without waiting for the conversion to complete.
This violates the sensor API contract: after sensor_sample_fetch()
returns, the data must be ready to read via sensor_channel_get().
Fix by polling the DIAG_ALRT register until the CNVRF (Conversion
Ready Flag, bit 1) is set before calling ina2xx_sample_fetch() to
read the converted data.
Fixes#98547
Signed-off-by: Md Shofiqul Islam <shofiqtest@gmail.com>
The accel and gyro full-scale setters passed the raw field encoding
(0-3 / 0-7) as the value to a register update whose mask is the
FS_SEL field at bits 7:5, so the masked value was always 0 and the
part stayed at +/-16 g and +/-2000 dps while software scaled for the
requested range. Wrap the value in FIELD_PREP and widen the masks to
the 3-bit field the datasheet defines.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The accelerometer sensitivity shift was hardcoded to 10, which matches
neither the selected full-scale range nor the part's 16-bit output
(2048 LSB/g at +/-16 g, i.e. a shift of 11), making every reading twice
too large. Derive the shift from the selected range and write the
full-scale selection into the correct bit field so the two agree.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The fractional part was computed with an unsigned modulo while the
integer part used signed division, so for negative raw values the two
halves used different quotients and the result was one full unit too
high. Compute the value in signed micro-units and let
sensor_value_from_micro() split it consistently.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The pressure trigger setup passed ~int_mask to
inv_icp201xx_set_press_notification_config(), whose argument bits are
cleared from the whole INT_MASK register, so the stray bits set by the
bitwise NOT also un-masked the FIFO watermark, overflow and underflow
sources. Restrict the inverted mask to the two pressure bits.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
icp201xx_trigger_set() returned -1 without releasing the driver mutex
when called with a NULL handler, deadlocking every other driver entry
point. Unregistering now clears the requested trigger's handler,
re-arms the interrupt if another trigger is still registered, unlocks
and returns 0.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
Add a bus emulator for the BMM350 so the driver can be exercised on
native_sim without hardware. It models the register file, the two dummy
bytes returned ahead of every I2C read, the soft-reset and OTP-read
handshake, and the PMU magnetic-reset / forced-mode status sequence, and
implements the emul_sensor backend (set_channel / get_sample_range) for
the magnetometer and die-temperature channels.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
Report the on-die temperature via SENSOR_CHAN_DIE_TEMP. The classic API
returns it from channel_get() as a sensor_value, and the RTIO decoder
path gains a matching channel: encode tags the frame with a temperature
bit (widening the encoded channel mask to four bits), get_size_info and
decode emit it as a q31 sample, and streamed data-ready frames now carry
temperature alongside the magnetic axes. The value is reported at 0.01
degC resolution.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
The temperature was converted and compensated at 1 degC resolution, which
also truncated the 25.49 degC offset to 25 and fed only whole-degree
temperature into the magnetic TCO/TCS compensation. Carry the temperature
in centi-degC (0.01 degC) instead: apply the full 25.49 degC offset and
fold the extra factor of 100 into the TCO/TCS stages so the magnetic
compensation uses the full-resolution temperature, matching the Bosch
SensorAPI reference. The stored temperature is now in centi-degC.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
A failed pad drive-strength write in bmm350_init_chip() returned directly
instead of going through the err_poweroff path, leaving the device in an
indeterminate power state unlike every other init failure. Use the common
error path so the part is returned to suspend mode.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
set_powermode() issued the PMU command write and then slept and returned
without inspecting the write result, and bmm350_init_chip() ignored the
return value of the soft-reset command write entirely. Propagate a failed
PMU write instead of sleeping on it, and abort init (returning the part
to suspend) if the soft-reset write fails.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
bmm350_trigger_set() always wrote the full interrupt configuration,
including the data-ready enable, even when called with a NULL handler.
The Zephyr trigger API uses a NULL handler to request "disable", so
there was previously no way to turn the trigger off. Clear the
data-ready and interrupt-output enables when the handler is NULL.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
bmm350_decoder_compensate_raw_data() performed the fixed-point
compensation in int32. The cross-axis stage multiplies the per-axis
value by BMM350_MAG_COMP_COEFF_SCALING (1000) twice, which overflows
int32 once the field exceeds roughly 2 mT (reachable during self-test
excitation or saturation), corrupting the result. Use int64
intermediates for the working values and cast back to int32 only for
the final stored readings.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
bmm350_submit_one_shot() and the streaming event handler acquired the
completion-callback RTIO SQE with rtio_sqe_acquire() but used it
without checking for NULL. If the SQE pool is exhausted the acquire
returns NULL and rtio_sqe_prep_callback_no_cqe() then dereferences it.
Check the result, drop any partially-prepared SQEs and fail the
submission with -ENOMEM, matching how the preceding read SQE is already
handled.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
Add bmm350_self_test() to the driver's public header, following the
Bosch BMM350 SensorAPI self-test sequence: re-initialise the TMR sensor
(suspend, flux-guide reset, fast bit reset, fast-forced mode) with
per-step PMU command status verification, then measure the response to
a positive and negative excitation on the X and Y axes.
The excited-axis response is read uncompensated and converted to
micro-Tesla using the default sensitivity coefficients, matching the
SensorAPI read_out_raw_data(); OTP compensation is intentionally not
applied since the test evaluates the differential response. Results
(per-axis responses and deltas) are reported through a
bmm350_self_test_result struct, and the prior power mode is restored on
return. Judging the deltas against the datasheet self-test limit is
left to the caller.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
The BMM350 driver only supported I2C. Extend the existing RTIO bus
abstraction to also drive the sensor over I3C, following the same
multi-bus pattern used by the bmp581 driver.
A new BMM350_BUS_TYPE_I3C bus type is selected per devicetree instance
based on the bus the node sits on. The RTIO register read/write helpers
set the I3C stop/restart iodev flags, and bus readiness is checked via
the I3C controller device. Register access, triggering and one-shot/
streaming all flow through the existing bus_io vtable unchanged.
Add a bosch,bmm350-i3c.yaml binding that reuses the common properties,
make the I2C/I3C Kconfig selects conditional on the instance bus, and
add an I3C node to the sensor build_all test.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
The FIFO temperature is a signed quantity (8-bit at 2.07 LSB/degC in
standard packets, 16-bit at 132.48 LSB/degC in hires packets, both
offset at 25 degC), but the decoder read the bytes as unsigned, so any
temperature below 25 degC decoded as a large bogus positive value and
could trip the whole-degrees range assert. Cast to the signed width
before converting.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The sensor streams sample registers MSB-first, so assembling the value
as (MSB << 8) | LSB already yields a CPU-order value. Wrapping it in
sys_le16_to_cpu() byte-swapped every sample on big-endian targets; use
sys_get_be16() instead.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The streaming header unconditionally reported fifo_count as the FIFO
watermark, even on the flush paths (SENSOR_STREAM_DATA_NOP/DROP or
FIFO_FULL trigger) where only a header-sized buffer is allocated and
no FIFO payload is read, causing the decoder to walk past the end of
the buffer. Set fifo_count to 0 unless the watermark trigger requested
the data to be included, matching the read performed in the FIFO event
handler.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The one-shot decoder read edata->readings directly, ignoring the
axis_align remap that icm4268x_encode stores in the header and that
both the FIFO decoder and the sync channel_get path apply. Index and
sign the accel/gyro readings through header->axis_align so async
one-shot reads match the other data paths.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
icm4268x_safely_configure() overwrote the primary configure error
with the rollback result, so a failed reconfigure followed by a
successful rollback returned 0 to callers such as attr_set even
though the requested configuration was never applied. Keep the
original error and only log a rollback failure.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The FIFO temperature was packed by OR-ing a FIELD_PREP'd whole part
with a fraction term computed via unsigned GENMASK64 arithmetic. For
negative temperatures both pieces are negative, so the unsigned divide
produced garbage and bitwise OR cannot perform the required signed
add. Compute the q31 value with signed 64-bit arithmetic instead.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The non-hires FIFO decode path masked with BIT(16), which can never
be set in a 16-bit sample, so negative accel/gyro values were never
sign-extended and decoded as large positive values. Use BIT(15) to
match the 20-bit hires path's BIT(19) idiom.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
icm566xx_attr_set() ignored the return value of the accel/gyro config
helpers and always returned 0, and those helpers discarded the status of
every HAL setter, so unsupported attributes and bus failures were
reported as success. Also fix icm566xx_init() to check the accel LPF
call instead of re-testing the previous gyro LPF result.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
On ICM56686 builds the one-shot decoder routed SENSOR_CHAN_DIE_TEMP
through get_raw_reading_by_position(), which only handles the six
accel/gyro positions and returned -EINVAL as if it were a sample.
Read the 16-bit temperature straight from the payload instead.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
Setting SENSOR_ATTR_FULL_SCALE only reprogrammed the accel/gyro FSR
register while the cached full-scale values used to convert raw samples
kept the devicetree settings, silently scaling every reading by the
wrong factor. Update the cached values on a successful FSR change, and
stamp encoded frames from the driver data instead of the fixed config.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The ODR register enums decrease as frequency increases, so comparing
the requested ODR with >= ODR_12_5_HZ picked low-noise mode for the
slowest rates and low-power mode for the fastest ones. Invert both the
accel and gyro comparisons so LN is selected for rates of 12.5 Hz and
above, and LP for the slower LP-only rates.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
ICM566XX_DT_GYRO_ODR_12_5 was defined as 1 instead of 12, which is
neither a valid hardware ODR encoding nor an accepted value of the
gyro-odr binding enum, and it made the low-noise branch of
ICM566XX_VALID_GYRO_ODR unsatisfiable so every LN devicetree failed
its BUILD_ASSERT. Also relax the ODR range checks to inclusive
comparisons so the documented 400 Hz LP and 12.5 Hz LN rates are
accepted, matching icm45686.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The gyroscope sensitivity values are encoded as LSB per dps scaled by
1000, but the rad/s conversion multiplied the raw value by 10000,
making every gyro reading ten times too large for all full-scale
settings. Use a multiplier of 1000 to match the sensitivity scaling.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
Add DEVICE_DT_INST_GET_COMMA helper macro to include/zephyr/device.h to
easily get a device pointer followed by a comma when expanding
devicetree foreach iterators like DT_INST_FOREACH_STATUS_OKAY.
Update drivers, soc, subsys, and tests to use the common definition.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Assisted-by: Antigravity:gemini-1.5-pro
The `__ASSERT_UNREACHABLE` macro is a PRIVATE helper macro used in the
implementation of the actual `__ASSERT` macros. It should not be used
except by the `__assert.h` header itself; in fact, the macro is never
defined if assertions are not enabled.
Replace this private macro's usage in the aforementioned driver with
`__ASSERT_NO_MSG(0)` which will trigger a proper assertion panic if
reached, which seemed to be the intent here.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
The MPU6050 die-temperature conversion used a 36.00 degC offset, but
the InvenSense register map specifies TEMP_OUT/340 + 36.53 degC, making
every reading 0.53 degC too low. Use 36530000 microdegrees instead.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The PMU command emulation kept only the field being written and
cleared every other sensor's PMU state instead of the opposite.
Invert the mask so the read-modify-write preserves unrelated fields.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
bmi160_pm() ignored the return values of bmi160_resume() and
bmi160_suspend(), reporting success to the PM subsystem even when the
underlying PMU register writes failed. Capture and return them.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
(slope_th_ums2 - 1) * 512 was computed in 32-bit arithmetic and wraps
for thresholds above ~0.855 g, which the range check explicitly allows
on the 2g range and up. Widen to 64-bit before multiplying, and reject
negative and zero threshold inputs which would underflow the
subtraction.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The 10-bit gyro offset is assembled from the 2 MSBs in OFFSET_EN and an
8-bit LSB byte read into an int8_t array. Integer promotion
sign-extended LSB values >= 0x80, flooding the upper bits and making
the explicit 10-bit sign extension that follows a no-op. Treat the LSB
as unsigned when assembling the raw value.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The cached temperature word overlaid the first gyro/accel sample in
union bmi160_sample, so fetching SENSOR_CHAN_DIE_TEMP clobbered the
cached X-axis raw sample, and a SENSOR_CHAN_ALL fetch overwrote the
temperature with gyro X data that channel_get then converted to a
bogus temperature. Store the temperature in its own struct bmi160_data
field.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The raw temperature register is a signed two's-complement value with
0x0000 = 23 degrees C, but it was multiplied as unsigned, so any die
temperature below 23 C was reported as roughly +23..+151 C. Cast the
sample to int16_t and use signed arithmetic throughout.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
Per the datasheet, reading the status register does not release the
latched ALERT pin, and the flags themselves only clear once the alert
condition is gone. Re-arming an edge interrupt on a still-asserted pin
therefore lost all further alerts permanently. Use a level interrupt,
as the tmp11x and tmp007 drivers do, so a still-pending alert re-runs
the handler and a stale latch at init recovers.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
tmp451_attr_set() programmed the remote-diode offset registers for
SENSOR_ATTR_OFFSET regardless of the requested channel, so setting an
offset on SENSOR_CHAN_AMBIENT_TEMP silently shifted die temperature
readings instead. Return -ENOTSUP unless the channel is
SENSOR_CHAN_DIE_TEMP or SENSOR_CHAN_ALL.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
Add a driver for the Plantower PMSA003I laser particulate matter sensor.
The sensor exposes PM1.0/PM2.5/PM10 mass concentrations (both CF=1
standard particle and atmospheric environment) and 0.3/0.5/1.0/2.5/5.0/10
um particle counts over I2C, read as a 32-byte fixed frame from register
0x00 with a start-byte, frame-length and checksum validation.
The optional reset and set pins are internally pulled up on the sensor,
so they are handled only when wired in the devicetree.
Signed-off-by: JaeHwan Jin <jaehwan.jin@rakwireless.com>
Group the Plantower PMS7003 driver under a dedicated plantower/ vendor
directory, matching the per-vendor layout used elsewhere in
drivers/sensor. No functional change.
Signed-off-by: JaeHwan Jin <jaehwan.jin@rakwireless.com>
The macro IS_TIM_32B_COUNTER_INSTANCE doesn't exist on STM32L0 and WB0.
These series don't have any 32 bits counter.
Add an ifdef to make the driver compatible with these series.
Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
The shub humidity converters stored the whole relative humidity scaled
by 1e6 in val2 instead of only the fractional part, so consumers using
val1 + val2/1000000 saw roughly double the actual reading. Use
sensor_value_from_float() to split the value correctly.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The drain loop exited only once every STATUS_REG data-ready bit was
clear, but those bits are cleared as a side effect of a registered
handler reading the output registers, so a source with no handler (e.g.
temperature) spun the loop forever. Qualify the exit condition by
handler presence and cap the number of iterations in both variants.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
lsm6dso_enable_tilt_int() assigned only the tilt bit of an
uninitialised lsm6dso_emb_sens_t, and lsm6dso_embedded_sens_set()
writes all six bits into EMB_FUNC_EN_A/B, so stack residue could
enable the pedometer, significant motion or FSM engines. Read the
current state first and modify only the tilt bit.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The SENSOR_CHAN_MTCH9010_OUT_STATE fetch path called gpio_pin_get_dt()
unconditionally, dereferencing a NULL port when the optional
output-gpios property is absent (e.g. UART-only configurations). Return
-ENOTSUP in that case, mirroring the guard used by the other fetch path.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
config->sleep_time holds the devicetree enum index used as the UART
command argument, but the fetch timeout math treated it as seconds, so
any sleep period of 4 s or more timed out early. Store the period in
seconds separately and widen the timeout values to uint32_t, since
256 s no longer fits in uint16_t once converted to milliseconds.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
The decode entry guard rejected any buffer whose first character was
not a digit, so DELTA-only packets carrying a negative delta (e.g.
"-99\n\r") always failed with -EINVAL. Allow a leading minus sign; the
per-format range checks still reject negative measurements.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5