Skip to content

media: i2c: ov9282: Arm FSIN wake last in external trigger setup - #7739

Merged
pelwell merged 1 commit into
raspberrypi:rpi-6.18.yfrom
Slynyr:ov9282-arm-fsin-last
Nov 6, 2026
Merged

pelwell merged 1 commit into
raspberrypi:rpi-6.18.yfrom
Slynyr:ov9282-arm-fsin-last

Conversation

@Slynyr

@Slynyr Slynyr commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

This moves the FSIN arm write to the end of the external trigger setup, which
fixes the sensor sometimes free-running instead of waiting for the trigger.

We run two OV9281s on a Pi 5 as a stereo pair, both triggered at 30 Hz from
an external microcontroller (trigger-mode=1). Every so often one of the two
cameras would ignore the trigger and free-run for the whole stream, while the
other locked fine. All the registers read back correctly afterwards, which
made it confusing to track down.

The cause seems to be the write order in ov9282_apply_trigger_config(). The
FSIN wake bit (0x3030 = 0x04) is set before the frame count, sleep period
and TIMING_23. Our trigger keeps pulsing while the driver configures the
sensor, so if an edge arrives after the arm write but before the rest, the
sensor wakes with those registers still at their defaults and stays
free-running until the next stream start. Arming last closes that window.

This might also be what @6by9 saw in #5349 ("the sensor keeps free-running").
The order goes back to the register list from the ArduCAM example in that
thread, which the trigger support in #6954 was based on. cc @omeredemen

To make sure it wasn't luck, we added an msleep(100) right after the point
where the current driver arms, so a few edges always land in the window. Then
we started both cameras over and over: a random delay before each start, a 4 s
capture, and a start counted as free-running if frames ever arrived faster
than the trigger.

arm write forced 100 ms delay camera starts free-running
first (current) yes 40 12
last (this patch) yes 40 0
first (current) no 80 0
last (this patch) no 80 0

Without the delay the window is only about 2 ms, so it's rare. We hit it in
normal use but couldn't reproduce it in the 80 undelayed starts. All 12 forced
failures were on the same camera, so an edge landing in the window doesn't
always do it. We don't know why one module is more sensitive than the other.

We also tried clearing bits 0-1 of SC_CTRL_23 (0x3023), which we first
thought was part of the problem. It didn't help on its own (7/40 with the
delay) and made no difference on top of the reorder, so it's not in this
patch.

Tested on 6.18.34 on a Pi 5. Happy to share the test scripts and raw data if
that's useful.

ov9282_apply_trigger_config() sets the FSIN wake bit in
LOW_POWER_MODE_CTRL (0x3030) before it writes NUM_FRAME_ON_TRIG, the
sleep period and TIMING_23 (no auto wake). FSIN comes from an external
source and is not gated while the driver is setting up, so an edge
that arrives after the arm write but before the rest of the sequence
wakes the sensor with those registers still at their power-on defaults.
When that happens the sensor can be left free-running at its internal
frame rate and ignore FSIN until the next stream start.

Write the arm bit last, once everything the wake path depends on is
already set. Nothing else changes.

On a stereo pair of OV9281 modules on a Raspberry Pi 5 (6.18.34),
triggered at 30 Hz, with an msleep(100) added just after the point
where the stock driver arms so that edges always land inside the
window:

  arm bit   free-running starts
  early     12/40
  last       0/40

Without the forced delay, neither ordering failed in 80 starts. The
natural window (arm write to end of setup) is about 2 ms with the
stock order.

Link: raspberrypi#5349
Fixes: 01732af ("media: i2c: ov9282: Add external FSIN trigger snapshot mode")
Signed-off-by: Filip Dumitru <filip.stefan.dumitru@gmail.com>

@6by9 6by9 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks sensible to me.

@pelwell
pelwell merged commit 31a3488 into raspberrypi:rpi-6.18.y Nov 6, 2026
11 of 12 checks passed
@pelwell

pelwell commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants