Skip to content

drivers: sensor: rm3100: fix I2C addressing and streaming SQE handling - #117395

Open
bperseghetti wants to merge 3 commits into
zephyrproject-rtos:mainfrom
CogniPilot:pr-deps-rm3100-i2c-streaming
Open

drivers: sensor: rm3100: fix I2C addressing and streaming SQE handling#117395
bperseghetti wants to merge 3 commits into
zephyrproject-rtos:mainfrom
CogniPilot:pr-deps-rm3100-i2c-streaming

Conversation

@bperseghetti

@bperseghetti bperseghetti commented Aug 26, 2026

Copy link
Copy Markdown
Member

Three fixes to the RM3100 driver:

  • Only set the SPI read bit on SPI transfers. On I2C the read bit addressed a nonexistent register, so every bus read of a real register returned zero and measurements were unusable on I2C deployments.

  • Encode a fixed channel spec when streaming. In a streaming read configuration the channels and triggers share a union, so reading cfg->channels reinterprets trigger data. The device produces one magnetic field sample type, so the streaming path now encodes the fixed magnetometer channel spec directly.

  • Acquire the bus SQEs for the streaming read chain as a single array. The bus RTIO context is shared across reads, and the previous per-SQE acquire fell back to a drop-all on shortage, which could free an SQE still in flight from another chain and corrupt the pool. Acquiring the chain atomically rolls back only its own SQEs on shortage.

The one-shot read path still acquires its SQEs individually. That path cannot corrupt another chain the same way, and unifying it is left as a follow-up.

Validated on NXP MCXN947 hardware with the magnetometer streaming over I2C.

The bus read helpers unconditionally OR the SPI read-address flag into
the register address. On I2C the register address must be sent raw:
with the flag set every read addresses a nonexistent register and
returns zeros, so the sensor appears dead on I2C buses.

Gate the flag on the RTIO bus type so I2C transfers send the plain
register address while SPI behavior is unchanged.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
In a streaming read-config the channels union member holds the trigger
array, so the encoded channel mask was computed from reinterpreted
trigger data and came out 0, making every streamed frame fail decode
with -ENODATA. A data-ready event always carries all three axes, so
encode a fixed MAGN_XYZ channel spec in the stream path.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
…load

The RM3100 streaming read acquires five bus SQEs one at a time and, on a
short pool, calls rtio_sqe_drop_all() to clean up. rtio_sqe_drop_all frees
every SQE queued on the shared bus RTIO context, including SQEs still in
flight from another read chain, returning an in-use SQE to the pool. A
later allocation then hands out that SQE with a corrupted back-pointer and
the completion path dereferences it, hard-faulting in the RTIO executor
(observed on I2C RM3100 hardware as a bus fault in the sensor work queue
after "Failed to acquire RTIO SQEs").

Acquire the five SQEs of a chain as one array with rtio_sqe_acquire_array,
which pushes nothing until all five are held and rolls its own back on
shortage, so a partial acquire can no longer orphan or double-free an SQE.
The incomplete NULL check that omitted the two status SQEs is retired with
it. Double the bus context pool from 8 to 16 so a five-SQE chain does not
run the pool short under streaming load.

The one-shot read path still acquires its SQEs individually and returns
early on shortage without preparing them. That is a lower-pressure path
outside the streaming scope of this change and is left to a follow-up.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants