> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/holoscan/sensor-bridge-e2e-latency-tool/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/holoscan/sensor-bridge-e2e-latency-tool/_mcp/server.

# Sequencer Configuration

The heart of the HSB Native Latency Tool lies in its precise sequencer configuration, which synchronizes LED triggers with camera frame events at the hardware level. Different camera sensor types require different timing strategies due to their distinct capture mechanisms.

The HSB Native Latency Tool provides complete example implementations for each sensor type, demonstrating the specific timing adjustments and GPIO control sequences required for accurate latency measurement.

The HSB Native Latency Tool includes two example applications in the `examples/` directory:

* **`e2e_imx274_latency.py`** - Rolling shutter camera implementation (IMX274)
* **`e2e_vb1940_latency.py`** - Global shutter camera implementation (VB1940)

Each implementation showcases the hardware sequencer programming, event handling, and timing synchronization specific to that sensor type, providing a complete reference for implementing latency measurement with your own camera sensors.

## Rolling Shutter Sequencer Setup

The HSB Native Latency Tool uses hardware sequencers to precisely control GPIO events synchronized to camera frame timing. The following code demonstrates how to configure the sequencer for rolling shutter cameras.

### Event Sequencer Implementation

The code snippets below are from the rolling shutter application `e2e_imx274_latency.py`.

```python
def setup_sequencer(self):
    # GPIO register addresses
    GPIO_DIRECTION_REG_BASE = 0x0000002C
    # GPIO module control registers
    GPIO_DELAYED_IO_OUTPUT_REG = 0x70000014
    GPIO_MODULE_CLEAR_REG = 0x7000080C
    GPIO_MODULE_ENABLE_REG = 0x700008F0
    GPIO_DELAY_REG = 0x70000804
    GPIO_DELAYED_SET_REG = 0x70000814

    self._hololink.write_uint32(
        GPIO_DELAYED_IO_OUTPUT_REG, 0x00000100
    )  # Enable DELAYED_IO output on GPIO

    # GPIO Pin 0 will be set HIGH on Frame Start event
    sequencer = self._hololink.sif0_frame_start_sequencer()
    sequencer.write_uint32(GPIO_MODULE_CLEAR_REG, 0x1)  # Clear all
    sequencer.write_uint32(
        GPIO_MODULE_ENABLE_REG, 0x1
    )  # To enable the whole module
    sequencer.write_uint32(GPIO_DELAY_REG, 0x0)  # 0ms delay
    sequencer.write_uint32(GPIO_DELAYED_SET_REG, 0x1)  # Delayed set
    sequencer.write_uint32(GPIO_DIRECTION_REG_BASE, 0x2)  # Set pin 1 as Input
    sequencer.enable()

    # Setting up sequencer to retrieve timestamp on LED_TRIGGER aka GPIO0
    sequencer = self._hololink.gpio0_sequencer()
    sequencer.enable()

    # When the PD_ACTIVE aka GPIO1 goes HIGH, timestamp is retrieved to calculate end to end measurements.
    # Also LED_TRIGGER aka GPIO0 is set to LOW to ACK that PD_ACTIVE went HIGH.
    sequencer = self._hololink.gpio1_sequencer()
    sequencer.write_uint32(
        GPIO_MODULE_ENABLE_REG, 0x1
    )  # To enable the whole module
    sequencer.write_uint32(GPIO_MODULE_CLEAR_REG, 0x1)  # To clear all
    sequencer.enable()
```

### Key Configuration Parameters

* **`GPIO_DELAYED_IO_OUTPUT_REG` (`0x70000014`)** - Enables DELAYED\_IO output on the GPIO pin
* **`GPIO_MODULE_CLEAR_REG` (`0x7000080C`)** - Clears all previous sequencer states
* **`GPIO_MODULE_ENABLE_REG` (`0x700008F0`)** - Enables the sequencer module
* **`GPIO_DELAY_REG` (`0x70000804`)** - Sets the LED trigger delay (0 for rolling shutter; set to `sensor_readout_time` for global shutter)
* **`GPIO_DELAYED_SET_REG` (`0x70000814`)** - Enables delayed set functionality

### Event Acknowledgment for Continuous Measurement

To enable continuous latency measurements, events must be acknowledged after each measurement cycle. The following `MultiEventAcknowledgmentOperator` class is implemented in both applications `e2e_imx274_latency.py` and `e2e_vb1940_latency.py`:

```python
class MultiEventAcknowledgmentOperator(holoscan.core.Operator):
    """
    Operator that acknowledges events after a specified frame count.
    """

    def __init__(self, fragment, hololink, frame_threshold=50, *args, **kwargs):
        super().__init__(fragment, *args, **kwargs)
        self._hololink = hololink
        self._frame_threshold = frame_threshold
        self._frame_count = 0

    def setup(self, spec):
        spec.input("input")
        spec.output("output")

    def compute(self, op_input, op_output, context):
        in_message = op_input.receive("input")

        self._frame_count += 1

        if self._frame_count >= self._frame_threshold:
            logging.info(f"Acknowledging events after {self._frame_count} frames")
            self._hololink.write_uint32(0x0000020C, 0xFFFFFFFF)  # Set flag
            self._hololink.write_uint32(0x0000020C, 0x0)  # Clear flag
            # Reset frame counter for next acknowledgment cycle
            self._frame_count = 0

        op_output.emit(in_message, "output")
```

### Sequencer Operation Flow

1. **Frame Start Detection** - HSB FPGA detects camera frame start signal
2. **Immediate LED Trigger** - GPIO pin 0 set high with 0ms delay (rolling shutter)
3. **Event Processing** - LED\_TRIGGER and PD\_ACTIVE events are processed
4. **Frame Counting** - MultiEventAcknowledgmentOperator tracks frame count
5. **Event Acknowledgment** - After N frames, events are acknowledged for next cycle
6. **Cycle Repeat** - Process repeats for continuous measurement

## Global Shutter Modifications

For global shutter cameras (like VB1940), the sequencer configuration in `e2e_vb1940_latency.py` modifies the delay parameter to account for sensor readout time:

```python
# Global shutter configuration
sequencer.write_uint32(GPIO_DELAY_REG, sensor_readout_time)  # Add readout time delay
```

Where `sensor_readout_time` is the specific readout time for your sensor mode.

## Run Latency Tool app

Once your HSB system is operational, run the app using:

```bash
# Navigate to latency measurement examples
# for IMX274
python3 examples/e2e_imx274_latency.py --fullscreen
# for VB1940
python3 examples/e2e_vb1940_latency.py --fullscreen
```