User Tools


Controlling the camera is done via writing “registers” - think of them as address locations. There are generally 4 ways to interface with the camera from a host:

  1. standard UVC - this one is automagically supported by any UVC 1.1 compliant OS, which in the year 2017 would be “any modern OS”. This interface covers the universally standardized controls for USB Video Class
  2. FX3 Host Vendor Command Interface - this interfaces with the Cypress's FX3 and is the primary FX3 API
  3. FPGA I²C Access - a “window” into a host of additional commands that are performed on FPGA, this is highly dependent on the FPGA model used and camera's generation and is not exactly intended for direct use outside of developing FX3 APIs and during development cycle of GUI implementation. The FPGA register maps are defined on this page
  4. (Gen 3 and Gen 4) direct I²C access via Cypress's FX3 interface, using control port 0x20. This allows access to all sensor's registers (at your own risk!). For more information search the web for documentation on the sensor in your camera (as of October 2017 that would be OmniVision 10823 sensor). Gen5 is using a sensor via an SLVS-EC interface which doesn't provide direct I²C access so one should use FX3 API (or, better yet - rely on SUB2r-lib for all your camera control needs)

If you are set on writing your own UI and don't want to be bothered too much with figuring out how to communicate with the camera you have an option of using the SUB2r-lib library (which should be your preference anyways).

More details

SUB2r camera is built on a Cypress FX3 chipset that facilitates the Super-Speed USB 3.0+ communication between the device and a host system. Every component of the camera, be it an FPGA or an image sensor, receives user commands via that Cypress FX3.

On Windows the device is registered with a GUID {36FC9E60-C465-11CF-8056-444553540000} and if you are not planning on using the SUB2r-lib for your development - that would be the GUID to search for to properly connect to the command channel.

Here's a sample code that shows how to send commands to both the FX3 Host (defined on this page) and to access FPGA's mapped registers. The code lacks error checking (for clarity) and this should go without saying that if you copy-paste it into your code you must add error handling :)

// set a new auto-functions' update interval to 2x the default
// just issue the command directly to FX3's vendor request interface
void setAUInterval(){
    S2R::FX3 fx3;;
    fx3.vrCmd(S2R::FX3::af_au_period, S2R::FX3::write, 6000, 0);
// run DPC calibration - also just a straight-up vendor request command to FX3
void runDPC(UCHAR _threshold = 240){
    S2R::FX3 fx3;;
    fx3.vrCmd(S2R::FX3::calibrate_dpc, S2R::FX3::write, _threshold, 0);
// increase LED's green brightness by 25%
// utilize the FPGA's I²C bridge
void lightUpTheGreen(){
    using Cmd = S2R::FX3::Fx3Cmd;
    using OpType = S2R::FX3::VrCmdOpType;
    S2R::FX3 fx3;;
    uint8_t        buf[1]{0};
    // LED green is mapped to register 0x0A ONLY for Gen3 and Gen4, won't work for Gen5
    const uint16_t clrChannel{0x0A};
    fx3.vrCmd(Cmd::i2c_bridge_fpga, OpType::read, 0, clrChannel, buf, 1);
    buf[0] += buf[0] / 4;  // yes, this can totally overflow
    fx3.vrCmd(Cmd::i2c_bridge_fpga, OpType::write, buf[0], clrChannel);

Firmware Version Info

This applies to both FX3 and FPGA firmware version info data structures.

Bit layout

The bits are laid out in 4 sequential bytes as follows:

3 2 1 0
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
buildNo[12:5] buildNo[4:0] releaseType productId hwCfgId vendorId

Firmware version info C/C++-struct

Both FX3 and FPGA version structures are as follows (little-endian memory layout):

struct FwVersion{
    unsigned vendorId    : 3;
    unsigned hwCfgId     : 5;
    unsigned productId   : 8;
    unsigned releaseType : 3;
    unsigned buildNo     : 13;
// [0, 3] = [hhhh'hvvv, pppp'pppp, bbbb'brrr, BBBB'BBBB]
static_assert(sizeof(FwVersion) == 4);

For example the following sequence of bytes:

[0,3] = 0x0A 0x06 0x08 0x00

corresponds to:

vendor id  = 2
H/W config = 1
product    = 6
build type = 0
build#     = 1

and in little-endian memory layout is equivalent to a uint32_t value of 0x0008`060A

FX3 Version Info

The version id is also encoded into the firmware image file name as:

Code Value
Vendor ID
Hardware ID
1FX3 Gen1
Product ID
1reserved for Gen 1 camera, a.k.a. “Moon landing”
2reserved for Gen 2 camera, a.k.a. “Piggy”
3Gen 3 camera (Alpha), a.k.a. “Frankie” (from Frankenstein's Monster)
4Gen 3 camera, Production
5Gen 4 camera, a.k.a. “Vitreledonella”
6Gen 5 camera, either “Square One” or “Studio”

FPGA Version Info

The version id is also encoded into the firmware image file name as:


Vendor ID that represents a vendor of the main computation unit

Code Value
Vendor ID1)
1Xilinx (AMD)
2Altera (Intel)
Hardware ID for VendorId 1 (Xylinx)
1Artix-7 100T
2Artix-7 200T
3Artix UltraScale+ XCAU25P
Hardware ID for VendorId 2 (Altera)
1Cyclone 10 GX
Product ID
3Gen 3 camera (Alpha), a.k.a. “Frankie”
4Gen 3 camera, Production
5Gen 4 camera, a.k.a. “Vitreledonella”
6Gen 5 camera, prosumer grade “Square One”
7Gen 5 camera, professional grade “Studio”

Shared parts of the Version Info

Both types of Version Infor (FX3 and FPGA) share the same codes for defining build type and build number:

Code Value
Release type
0Private build: Private build for debugging and similar purposes
1Alpha: feature-incomplete early development cycle “somewhat stable” build
2Beta: feature-complete, but not very stable build (lots of bugs)
3Evaluation: Tech preview
4Release candidate: feature complete and stable
5Release: general availability
6Backport: backport of a feature from next gen camera
7Emergency bug fix: a critical post-release bugfix
Build number
#13 bits of a build number (the range is 1..8191). Increments on each build

Previous iterations had different bit layout for the Version Info, see details here: Firmware Versioning Evolution

FPGA config status - SPI codes

These are the status bits that indicate the FPGA programming (reconfiguring) process:

Bit name Description
15 Program SwitchWord OK
14 Verify OK Verification succeeded
13 Program OK Programming completed successfully
12 Erase OK SPI erase was successful
11 Erase SwitchWord OK
10 Check ID OK
9 Initialize OK
8 Config started Config operation has started
7 CRC error
6 Timeout error
5 Program error Error while programming the SPI
4 Erase error Encountered an error while erasing SPI
3 IdCode error
2 Config error Configuration operation errored out
1 Config done Configuration operation is complete
0 Config not busySet to 1 while the config is not busy
represents a vendor of the main computation unit

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also, you acknowledge that you have read and understand our Privacy Policy. If you do not agree, please leave the website.

More information