Critical Link MityCam SoC Firmware  1.0
Critical Link MityCam SoC Firmware
Adding GenICam Registers

Several of the supported camera control protocols take advantage of the GenICam control framework defined by emva.

The MityCAM-SDK includes a C++ object / framework for managing registers defined by the GenICam framework.

For best interoperability, registers defined for a camera should conform to the emva Standard Feature Naming Convention (SFNC) whenever possible. This will allow standard host applications to provide generic controls for many commonly used camera features.

Specifications for GenICAM (including SFNC, and several other useful reference documents) are available from the downloads link at emva.

NOTE: you will need to be comfortable reading and modifying XML as well as updating C++ software to perform these steps.

Overview of Steps to add a new Register to your Camera

  1. Update the XML file for your Camera
  2. Check if the register is already handled
  3. Determine which class will handle the register
  4. Implement the register handling logic
  5. Define the register to the SocCamera::tcRegisterFile class
  6. Register the Handling logic with the SocCamera::tcRegisterFile class

Update the XML file for your Camera

In the ARM/pages folder, edit the camera XML file you are publishing with your application. Users unfamiliar with the XML schema for GenICam defined cameras should refer to emva's GenICam.

Once you have updated the camera XML file, it is important to validate the XML to ensure that it meets the schema requirements and there are no syntax errors. In the ARM/pages folder, you can run the following command to check if the XML is compliant:

[linux-devkit]:~/mitycam_sdk/ARM> ./validate_xml.sh

Any errors indicated by the script should be addressed before continuing to the next steps.

Important Note: Currently, the GenICAM implementation requires all defined register to be of one endian type. For GigE cameras, XML must define all registers as Big Endian. For U3V cameras, XML must define all registers as Little Endian. Generally, this does not have significant impact on the handler implementation, as the marshalling is managed by the provided tcRegisterFile class.

Check if the register is already defined

The MityCAM-SDK includes support for GIGE boostrap regsiters and U3V ARBM and SIRM register sets.

In addition, the MityCAM-SDK includes software to manage / handle many registers defined by the SFNC. The table below includes the known register support at the time of this writing. Users are encouraged to review the /ARM/sw/camera_software/src/CommandInterface/RegisterFile.h to check if the feature they need may already be implemented. If it has, then you need to ensure that the XML file provides the register at the same address offset that is defined in the header file.

For common (often required) SFNC features, a default handler is included in the /ARM/sw/camera_software/src/CommandHandlers folder. The table below lists common XML registers with handler code, their addresses, and the associated command handler. Note: not all cameras must support these features. In the tcSensorBoard implementation, several interface calls may return a "Not Supported", and the XML file for such a camera should exclude unsupported features. Some defined Common registers include specific registers for sensor demonstrations. They are included for completeness, and their address space should be avoided.

GenICam Features In Common Code

Feature SFNC Section Address CommandHandler Comment
AcquisitionFramePeriod 0x3A000 SocCamera::tcFrameIntervalHandler see SocCamera::tcSensorBoard::setFrameInterval()
ExposureTime 5.7.4 0x3A004 SocCamera::tcExposureHandler see SocCamera::tcSensorBoard::setExposure()
Width 4.18 0x3A008 SocCamera::tcROIHandler see SocCamera::tcSensorBoard::setROI()
Height 4.19 0x3A00C SocCamera::tcROIHandler see SocCamera::tcSensorBoard::setROI()
OffsetX 4.20 0x3A010 SocCamera::tcROIHandler see SocCamera::tcSensorBoard::setROI()
OffsetY 4.21 0x3A014 SocCamera::tcROIHandler see SocCamera::tcSensorBoard::setROI()
AcquisitionStart 5.5.3 0x3A018 SocCamera::tcStartStopHandler see SocCamera::tcSensorBoard::start(), tcIOChannel::capture()
AcquisitionMode 5.5.2 0x3A01C SocCamera::tcStartStopHandler see SocCamera::tcSensorBoard::start(), tcIOChannel::capture()
PixelFormat 4.35 0x3A020 SocCamera::tcBPPModeHandler see SocCamera::tcSensorBoard::setColor()
PayloadSize 25.2.5 0x3A024 SocCamera::tcRegisterFile see SocCamera::tcSensorBoard::getrFrameSizeBytes()
BinningHorizontal 4.26 0x3A028 SocCamera::tcBinningHandler see SocCamera::tcSensorBoard::setHorizontalBin()
BinningVertical 4.28 0x3A02C SocCamera::tcBinningHandler see SocCamera::tcSensorBoard::setVerticalBin()
ReverseX 4.33 0x3A030 SocCamera::tcFlipXHandler see SocCamera::tcSensorBoard::setMirroring()
ReverseY 4.34 0x3A034 SocCamera::tcFlipXHandler see SocCamera::tcSensorBoard::setMirroring()
AcquisitionFrameCount 5.5.4 0x3A038 SocCamera::tcStartStopHandler see SocCamera::tcSensorBoard::start(), tcIOChannel::capture()
AcquisitionStop 5.5.4 0x3A03C SocCamera::tcStartStopHandler see SocCamera::tcSensorBoard::stop(), tcIOChannel::capture()
DecimationVertical 4.32 0x3A040 N/A Reserved for sensor decimation implementation (no common handler)
SensorTemperature N/A 0x3A044 SocCamera::tcTemperatureSensorHandler This is a legacy address. See SocCamera::tcSensorBoard::getTempCelsius()
BoardTemperature N/A 0x3A048 SocCamera::tcTemperatureSensorHandler This is a legacy address. See SocCamera::tcSensorBoard::getBoardTempCelsius()
EdgeDetectionEnable N/A 0x3A04C SocCamera::tcEdgeDetectionHandler For demonstration cameras only.
GainMode N/A 0x3A054 SocCamera::tcGainModeHandler Reserved for BAE 5T sensor architectures.
Calibrate N/A 0x3A058 SocCamera::tcCalibrationHandler Reserved for BAE 5T sensor architectures.
TestPattern 4.44 0x3A05C SocCamera::tcTestPatternHandler
ClockSpeed N/A 0x3A060 SocCamera::tcClockHandler Used to change sensor clock rates for Noise Improvement.
SqrtCompression N/A 0x3A060 SocCamera::tcSqrtHandler Used to compress 16 bit data to 12 bit data via custom function.
HotPixelCorrection N/A 0x3A068 N/A Flag to enable / disable median filtering
BadPixelEnable N/A 0x3A070 SocCamera::tcBadPixelHandler Must be instantiated by Sensor Object. Used to enable or disable bad pixel correction core, if available.
BadPixelMap N/A 0x3A074 SocCamera::tcBadPixelHandler Must be instantiated by Sensor Object. Used to force bad pixel map to be written into image stream (for debug).
VoltageSensorSelect N/A 0x3A078 SocCamera::tcVoltageSensorHandler tcSensorBoard must implement/derive from tcVoltageSensor interface (see Sensors/Interfaces/VoltageSensor.h)
VoltageSensorValue N/A 0x3A07C SocCamera::tcVoltageSensorHandler tcSensorBoard must implement/derive from tcVoltageSensor interface (see Sensors/Interfaces/VoltageSensor.h)
DeviceTemperatureSelector 3.60 0x3A080 SocCamera::tcTemperatureSensorHandler tcSensorBoard must implement/derive from tcTemperatureSensorHandler interface (see Sensors/Interfaces/VoltageSensor.h)
DeviceTemperature 3.61 0x3A084 SocCamera::tcTemperatureSensorHandler tcSensorBoard must implement/derive from tcTemperatureSensorHandler interface (see Sensors/Interfaces/VoltageSensor.h)
ExposureTimeSelector 5.7.3 0x3A08C SocCamera::tcExposureHandler Allows configuring second exposures for multi-exposure frames.
FreeRAM N/A 0x3A100 SocCamera::tcSensorBoard Size (bytes) of internal camera ring buffer.
LUTSelector TBD 0x3A300 N/A Reserved for sensor Look Up Table implementation (no common handler)
LUTEnable TBD 0x3A304 N/A Reserved for sensor Look Up Table implementation (no common handler)
LUTMaxIndex N/A 0x3A308 N/A Reserved for sensor Look Up Table implementation (no common handler)
LUTIndex TBD 0x3A30C N/A Reserved for sensor Look Up Table implementation (no common handler)
LUTMaxValue N/A 0x3A310 N/A Reserved for sensor Look Up Table implementation (no common handler)
LUTValue TBD 0x3A314 N/A Reserved for sensor Look Up Table implementation (no common handler)
GainSelector 6.2 0x3A400 SocCamera::tcGainHandler tcSensorBoard must implement/derive from tcGainControl interface (see Sensors/Interfaces/GainControl.h)
Gain 6.3 0x3A404 SocCamera::tcGainHandler tcSensorBoard must implement/derive from tcGainControl interface (see Sensors/Interfaces/GainControl.h)
GainAuto 6.4 0x3A408 N/A Reserved for sensor multi-Gain implementation (no common handler)
GainAutoBalance 6.5 0x3A40C N/A Reserved for sensor multi-Gain implementation (no common handler)
BlackLevelSelector 6.6 0x3A410 SocCamera::tcBlackLevelHandler tcSensorBoard must implement/derive from tcBlackLevelEstimator interface (see Sensors/Interfaces/BlackLevelEstimator.h)
BlackLevel 6.7 0x3A414 SocCamera::tcBlackLevelHandler tcSensorBoard must implement/derive from tcBlackLevelEstimator interface (see Sensors/Interfaces/BlackLevelEstimator.h)
BlackLevelAuto 6.9 0x3A418 SocCamera::tcBlackLevelHandler tcSensorBoard must implement/derive from tcBlackLevelEstimator interface (see Sensors/Interfaces/BlackLevelEstimator.h)
BlackLevelAutoBalance 6.9 0x3A41C SocCamera::tcBlackLevelHandler tcSensorBoard must implement/derive from tcBlackLevelEstimator interface (see Sensors/Interfaces/BlackLevelEstimator.h)
WhiteClipSelector 6.10 0x3A420 N/A Reserved for sensor white clip control implementation (no common handler)
WhiteClip 6.11 0x3A424 N/A Reserved for sensor white clip control implementation (no common handler)
BalanceRatioSelector 6.12 0x3A428 N/A Reserved for sensor white balance implementation (no common handler)
BalanceRatio 6.13 0x3A42C N/A Reserved for sensor white balance implementation (no common handler
BalanceWhiteAuto 6.14 0x3A430 N/A Reserved for sensor white balance implementation (no common handler
Gamma 6.15 0x3A434 N/A Reserved for sensor gamma correction implementation (no common handler
Bias N/A 0x3A410 N/A Custom register for BAE 5T architectures.
ColorTransformationSelector 8.2 0x3A500 N/A Reserved for sensor color transformation/correction implementation (no common handler)
ColorTransformationEnable 8.3 0x3A504 N/A Reserved for sensor color transformation/correction implementation (no common handler)
ColorTransformationValueSelector 8.4 0x3A508 N/A Reserved for sensor color transformation/correction implementation (no common handler)
ColorTransformationValue 8.5 0x3A508 N/A Reserved for sensor color transformation/correction implementation (no common handler)
TriggerSelector 5.6 0x3B000 SocCamera::tcTriggerHandler see SocCamera::tcSensorBoard::setTrigger()
TriggerMode 5.6 0x3B004 SocCamera::tcTriggerHandler see SocCamera::tcSensorBoard::setTrigger()
TriggerSource 5.6 0x3B008 SocCamera::tcTriggerHandler see SocCamera::tcSensorBoard::setTrigger()
TriggerActivation 5.6 0x3B00C SocCamera::tcTriggerHandler see SocCamera::tcSensorBoard::setTrigger()
LineSelector 9.2.2 0x3B100 SocCamera::tcDigitalIOHandler
LineMode 9.2.3 0x3B104 SocCamera::tcDigitalIOHandler see SocCamera::tcSensorBoard::setIODirection()
LineSource 9.2.7 0x3B10C SocCamera::tcDigitalIOHandler see SocCamera::tcSensorBoard::setIOValue()
UserOutputSelector 9.2.9 0x3B110 SocCamera::tcDigitalIOHandler
UserOutputValue 9.2.10 0x3B114 SocCamera::tcDigitalIOHandler see SocCamera::tcSensorBoard::setIOValue()
LineStatus 9.2.5 0x3B118 SocCamera::tcDigitalIOHandler see SocCamera::tcSensorBoard::getIOValue()
LineInverter 9.2.4 0x3B11C SocCamera::tcDigitalIOHandler see SocCamera::tcSensorBoard::setIOInverter()
IndicatorControl N/A 0x3B120 SocCamera::tcIndicatorHandler intended to disable any camera LEDs
FanControl N/A 0x3B124 SocCamera::tcFanHandler intended to disable any camera FANs
ColorCamera N/A 0x3B200 N/A intended to flag cameras with color filters
SensorRegAddr N/A 0x3C000 SocCamera::tcPokeHandler see SocCamera::tcSensorBoard::peek() Sensor Peek/Poke Address
SensorRegValue N/A 0x3C004 SocCamera::tcPeekHandler see SocCamera::tcSensorBoard::peek()/poke() Sensor Peek/Poke Value
SensorRegRead N/A 0x3C008 SocCamera::tcPokeHandler see SocCamera::tcSensorBoard::peek() Sensor Peek/Poke peek command
SensorRegWrite N/A 0x3C00C SocCamera::tcPokeHandler see SocCamera::tcSensorBoard::poke() Sensor Peek/Poke poke command
Sensor Specific Control N/A 0x3D000-0x3D200 N/A Reserved for additional simple registers
XML File Location N/A 0x44000-0x22FFFF Reserved for XML or XML zip file
SensorRegisterMap N/A 0x230000-0x23FFFF Reserved for direct memory mapping for sensor registers
DebugBufferSize N/A 0x300000 Number of bytes in debug buffer, if enabled
DebugRingBuffer N/A 0x301000-xxx
ManifestTableCount N/A 0x10000000
ManifestTableVersion N/A 0x10000008
ManifestTableType N/A 0x1000000C
ManifestTableReg N/A 0x10000020
ManifestTableSize N/A 0x10000028
ManifestTableSHA1 N/A 0x10000030
HDMI output control N/A 0x20000000-0x20000100 Reserved for MityCAM HDMI output control

Determine which class will handle the register

If you are defining a common register in the SFNC, it might make sense to create a general purpose handler in the CommandHandlers folder. This will allow reuse from camera to camera. If, however, the register you are adding is specific to your plugin implementation, then you can define and handle the register within the context of your plugin. The following paragraphs outline both approaches.

Adding re-usable register handlers

The original design of the camera application library utilized Command Handlers (located in ARM/camera_software/src/CommandHandlers) for handling text based commands from IO interfaces such as the command line, scripts, or the Camera Link UART interface for controlling sensors using the common SocCamera::tcSensorBoard method calls. Command Handlers are derived from the SocCamera::tcAbstractHandler base class. An example of handling text based commands is shown in the example sequence diagram below for updating exposure time.

Text Based Command Processing

As protocols supporting GenICam have been added, the SocCamera::tcAbstractHandler class was extended to register in with the tcRegisterFile class as a tcObserver in order for command handlers to detect and process changes to GenICam defined registers. This is accomplished by command handlers implementing the SocCamera::tcAbstractHandler::update() method and handling register accesses accordingly. An example of handling commands via GenICam register writes (in this case, from the AIA U3V protocol) is shown in the sequence diagram below.

GenICam Register Handling

If you choose to impelment a re-usable register handler, follow the steps listed below:

  1. Create and impelment a Handler Class that derives from the SocCamera::tcAbstractHandler
  2. Add the class source and header file to the Makefile.am in the ARM/camera_software/ folder and rerun the autotools process.
  3. Add construction of the handler in the appropriate location of tcCommandInterface::initialize_chain() or tcCommandInterface::initialize_channel_specific() methods.

Adding plugin specific register handlers

If the registers you are trying to handler are specific to only one sensor type, you may implement a localized (i.e., at the plugin level) handler instead of developing a re-usable handler as described in the previous section. You can implemenmt a local Command Handler derived from SocCamera::tcAbstractHandler and add it to the command chain as part of the SocCamera::tcSensorBoard::getCustomHandlers() method. Alternatively, any class can derive from the SocCamera::tcObserver, register in with the SocCamera::tcRegisterFile class via SocCamera::tcRegisterFile::registerObserver() method, and handle register updates using the implemented SocCamera::tcObserver::update() method.

Note: The SocCamera::tcSensorBoard class uses the same tcObserver pattern for handling notifications that new image data has arrived. If you choose to have your plugin implmentation of the SocCamera::tcSensorBoard class handle register modifications, you should check the value of the Register Update message pointer. If it is null, then the callback is from the tcIOChannel and should be handled by the SocCamera::tcSensorBoard::update() method. See the code example below.

void tcSensorBoardImpl::update(tsUpdate asMessage)
{
tcRegUpdateMsg* pmsg = static_cast<tcRegUpdateMsg*>(asMessage.mpMessage);
// this method can be called by the RAM streamer (tcPollingInterruptThread), in which
// case the asMessage.mpMessage is NULL. Pass this down to the base class handler.
if (pmsg == nullptr) {
// Call parent function even if we think we handled message
tcSensorBoard::update(asMessage);
return;
}
// otherwise this is a register update callback
switch (pmsg->m_address)
{
}
}

Define the register to the tcRegisterFile class

For common registers, 2 files must be edited. First reserve an address for the register(s) in the ARM/camera_software/src/CommandInterface/RegisterFile.h. The register should be defined with the following format and added in address order to the header file.

const uint32_t NEW_REGISTER_ADDR    = XML_REGS_OFFSET + 0x0000'ADDR;

Second, define the register type, access level, and default value by editing the CommandInterface/GenICamSharedRegs.h. Here there are macros used at compile time to create an initialization structure for the registers. The macros are of the form:

REGDEF_INT(NEW_REGISTER, ACCESS_MODE, DEFAULT_VALUE),
REGDEF_I64(NEW_REGISTER, ACCESS_MODE, DEFAULT_VALUE),
REGDEF_FLT(NEW_REGISTER, ACCESS_MODE, DEFAULT_VALUE),
REGDEF_STR(NEW_REGISTER, ACCESS_MODE, SIZE, DEFAULT_VALUE),
REGDEF_BUF(NEW_REGISTER, ACCESS_MODE, SIZE, DEFAULT_VALUE),

In the macros, "NEW_REGISTER" must match the base variable name of the register field added in the RegisterFile.h. ACCESS_MODE should be RO, WO, RW.

If you are not defining a common register and wish to leave all implementation details within the Sensor/Camera plugin code, you can dynamically add a register in your plugin initialization software. Simply reserve a clear location for your register(s) and use the SocCamera::tcRegisterFile::addRegister() method:

using namespace SocCamera;
tcMySensorBoard::init()
{
....
SocCamera::tcRegisterFile::tsRegDefinition regdef = {
.address = XML_REGS_OFFSET + 0x0000'ADDR,
.name = "CustomIntReg",
.size = 4,
.type = SocCamera::eeRegUint32,
.rdaccess = true,
.wraccess = true,
.numData.dfltnval = 0xDEADBEEF,
};
SocCamera::tcRegisterFile::getInstance()->addRegister(&regdef);
....
}