GMSL#
GMSL Overview#
Gigabit Multimedia Serial Link (GMSL) is the predominant camera connectivity technology for automotive platforms and is increasingly adopted in robotics. A typical GMSL camera topology places one deserializer on the SoC side and one or more camera modules on the remote end of each link. Each camera module contains a serializer, a sensor, and optional components such as an EEPROM or PMIC. A high-speed GMSL link connects each module to the deserializer.
SoC ── [ Deserializer ] ──GMSL── [ Serializer | Sensor | EEPROM | ... ]
──GMSL── [ Serializer | Sensor | EEPROM | ... ]
──GMSL── [ Serializer | Sensor | EEPROM | ... ]
UDDF represents this topology with five driver types:
Driver Type |
DDI Interface |
Role |
|---|---|---|
Deserializer |
|
Controls the deserializer chip attached to the SoC. |
Camera module |
|
Controls all hardware elements on a single camera module. |
Serializer (sub-component) |
|
Exposed through |
Deserializer power |
|
Manages power for the deserializer. |
Module power |
|
Manages power independently for each camera module. |
The following sections describe each driver type in detail.
Deserializer Drivers#
A deserializer driver controls a GMSL deserializer chip such as the MAXIM 96712. It implements the IGmslDeserializer interface, which extends the standard driver lifecycle described in UDDF Driver Model with the following GMSL-specific methods:
Method |
Description |
|---|---|
|
Performs per-link initialization after |
|
Finalizes per-link initialization after the camera module has been probed and initialized. At this point, links to other camera modules can also be enabled. |
|
Enables or disables an individual GMSL link. The framework calls this to isolate a single link before programming its serializer. |
|
Verifies that the links identified by |
|
Probes the deserializer hardware. When |
Every deserializer entrypoint receives a DeserializerContext. This context provides hwAccess for hardware communication, driverServices for logging, and configuration structures (basicConfig, initConfig). Because the context is passed into every call, your driver does not need to cache any of these handles.
Camera Module Drivers#
A camera module driver controls all hardware elements that are physically part of a camera module. Common components include the following:
Serializer
Camera sensor
EEPROM
PMIC
IR illuminator
IMU
Only the serializer and camera sensor are required. The driver implements the IGmslModuleControl interface, which extends the standard lifecycle with the following GMSL-specific methods:
Method |
Description |
|---|---|
|
Performs hardware authentication for the camera module. |
|
Notifies the driver that the module is about to be powered off. The driver should prepare the hardware for a loss of power. |
|
Notifies the driver that the module has just been powered on. The driver can restore hardware state or perform post-power checks. |
Every camera module entrypoint receives a GmslModuleContext. Like the deserializer context, it provides hwAccess for hardware communication, driverServices for logging, and a config structure with module-specific settings (link index, CSI port, frame sync mode, sensor info). There is no need to cache these handles.
Module Sub-Components#
A camera module driver exposes its internal components through the IModuleComponentAccess interface. UDDF consumers retrieve sub-components by type and index, then use interface_cast<> to obtain the specific interface for that component.
The standard component types are defined in ModuleComponentTypes.hpp:
MODULE_COMPONENT_SENSOR— camera sensor.MODULE_COMPONENT_SERIALIZER— GMSL serializer.MODULE_COMPONENT_EEPROM— EEPROM (optional).
The following example retrieves the serializer component from a module driver:
auto* compAccess = interface_cast<IModuleComponentAccess>(moduleDriver);
auto* serializer = interface_cast<IGmslSerializer>(
compAccess->GetComponent(MODULE_COMPONENT_SERIALIZER, 0));
The IGmslSerializer interface provides methods that the framework calls during the serdes initialization sequence:
SerInit(context)— initializes the serializer and sets up I2C address translations fromcontext.config.addressTranslations.SerPrepareForModuleInit(context)— performs any remaining initialization before the rest of the camera module is probed and initialized.SerFinalizeInit(context)— completes serializer initialization after all module elements are initialized.
For the complete ordering of these calls, refer to Serdes Initialization Sequence.
Power Drivers#
UDDF defines two driver types for GMSL power control.
IGmslDeserializerPowerControl controls the power rail for the deserializer. Key methods:
EnablePower(context)/DisablePower(context)— Turn deserializer power on or off.ConfigureDriver(context, i2cDevices, gpioPins)— Declare I2C and GPIO resources.
The GmslDeserializerPowerControlContext provides hwAccess, driverServices, and a config structure containing busNumber and an optional gpioPinIndex.
IGmslModulePowerControl controls power independently for each camera module attached to a single deserializer. Key methods:
EnableModulePower(context, index)/DisableModulePower(context, index)— Control power for a single module by index.EnableModulePowerMask(context, mask)/DisableModulePowerMask(context, mask)— Control power for multiple modules using a bitmask.
The GmslModulePowerControlContext provides hwAccess, driverServices, and a config structure containing the i2cAddress of the power control device.
Note
Power drivers are optional. Some hardware designs do not include programmable power control, or the power control is handled outside the UDDF layer.
Serdes Initialization Sequence#
After both the deserializer and camera module are powered on and the deserializer itself is initialized, the following per-link sequence establishes the serdes connection:
IGmslDeserializer::ControlLink()enables the link to the target serializer and disables links to all other serializers.IGmslSerializer::SerInit()initializes the serializer. This includes setting up virtual-to-physical I2C address translations as specified bycontext.config.addressTranslations.IGmslDeserializer::InitWithSerializer()gives the deserializer driver a chance to perform per-link operations such as GPIO port forwarding or diagnostic tests. The serializer driver is available atcontext.initConfig.serializers[linkIndex].IGmslSerializer::SerPrepareForModuleInit()performs any remaining initialization or checks before the rest of the camera module is probed and initialized.The camera module is probed and initialized through calls to
IGmslModuleControl::ProbeHardware()andIGmslModuleControl::Init().IGmslDeserializer::FinalizeInitWithSerializer()finalizes the link. At this point, links to other camera modules can also be enabled.IGmslSerializer::SerFinalizeInit()completes serializer initialization.
Some elements in this sequence can be implemented as no-ops for particular hardware, especially when safety mechanisms are not in use.
I2C Addressing#
Physical Address Remapping#
In PyHSL, an I2CDevice object is created with a single I2C address, which is normally the physical address for the device. However, in some cases the runtime address differs from the compile-time address that was used in PyHSL. For example, the address of a power loadswitch can vary across different boards.
Rather than generating different HSL sequences for each address, you can use the optional hslI2cAddress field in the driver I2C device table. When present, hslI2cAddress specifies the address that was used in PyHSL, while i2cAddress specifies the actual runtime address. The camera HAL translates the PyHSL sequences to match the correct address.
Virtual Address Translation#
Many serializers support I2C address translation so that multiple camera modules with devices at the same physical address can be separately programmed using unique virtual addresses. UDDF supports virtual addressing by providing a table of address translations to IGmslSerializer methods. Virtual addresses are assigned by the camera HAL, not by driver code. By default, all I2C operations go through virtual address translation.
Bypassing Virtual Address Translation#
In some cases – primarily during serializer initialization – the driver must bypass virtual address translation and use the physical address directly. This is necessary because the serializer must be programmed before virtual address translation is configured.
You can bypass virtual translation across all three I2C access patterns using the I2CAddressMode enum (from CDITypes.hpp):
Static HSL (PyHSL) — Use the no_virtual_address flag:
phys = I2CDevice(ADDR, no_virtual_address=True)
virt = I2CDevice(ADDR)
Raw ReadI2C — Pass I2CAddressMode::Physical:
hwAccess->ReadI2C(addr, offset, len, buf, I2CAddressMode::Physical);
Dynamic HSL — Select the builder by mode:
auto* p = seq.i2cBuilder(addr, I2CAddressMode::Physical);
auto* v = seq.i2cBuilder(addr); // default: Virtual
Both the ReadI2C and i2cBuilder parameters default to I2CAddressMode::Virtual, which preserves existing behavior. You need to specify the mode explicitly only when bypassing virtual translation.