This is an old revision of the document!
FPGA I²C bridge (registers' map)
The following tables provide information on how to access the camera's functionality for an FPGA I²C bridge.
Intel-based FPGA utilizes an Avalon interface bus to facilitate access to FPGA's “registers”. We have reserved addresses beginning with \(0x5000'0000\) for the FX3↔FPGA communication.
Note that one of the limitations of Avalon is that addressing is done on a 4-byte boundary.
Here's a sample code (skipping all error checking) that sets the LED to bright-yellow color :
S2R::FX3 dev; // auto-open device #0 using S2R::FX3; dev.vrCmd(FX3Cmd::i2c_bridge, VrCmdOpType::write, 255, 0x08); // red dev.vrCmd(FX3Cmd::i2c_bridge, VrCmdOpType::write, 255, 0x0A); // green dev.vrCmd(FX3Cmd::i2c_bridge, VrCmdOpType::write, 0, 0x0C); // blue
The address space is broken down into smaller chunks, grouped by common functionality:
FPGA basic status and controls
FPGA basic status and controls | |||||
---|---|---|---|---|---|
Address | Name | Bytes | Access | Bit mapping | Notes |
0x5000'0000 | FPGA Version | 4 | R/O | see Firmware Version Info | |
0x5000'0004 | FPGA status | 4 | R/O | see Notes for more details31:16 SPI codes15:8 FPGA core temperature7:2 reserved1 DPC done0 SFP active | The bytes of the FPGA status register are allocated according to the little-ending memory layout of the following C-style declaration. For details on SpiCodeStruct see SPI codes:struct FpgaStatus{ struct State{ // there is an active device in SFP+ cage bool sfp_active:1; // DPC calibration is completed bool dpc_done:1; // reading of the FPGA's internal temperature sensor in degrees of Fahrenheits uint8_t reserved:6; } state; uint8_t core_temperature; SpiCodeStruct config_status; }; |
FPGA operation mode
FPGA operation mode1) | |||||
---|---|---|---|---|---|
Address | Name | Bytes | Access | Bit mapping | Notes |
0x5000'0008 | FPGA operation mode | 4 | R/W | 31:20 reserved | |
19 CCM | enable Color Correction Matrix transformation block | ||||
18 Gamma | enable UVC Gamma transformation block | ||||
17:16 debayer strategy | De-mosaicing strategy directs the use of a specific implementation of color reconstruction:0 - use “branchless 5×5”, like the one described in here1 - use “branching 5×5”, for example the one described here2 , 3 - reserved |
||||
15 reserved | |||||
14 reserved (headphones) | |||||
13 reserved (UAC) | |||||
12 reserved | |||||
11 HDMI output | enable HDMI video output | ||||
10 SDI output | enable SDI video output | ||||
9 SFP+ video | enable SFP+ video output | ||||
8 UVC output | enable UVC output | ||||
7:3 reserved | |||||
2 calibrate DPC | Start DPC calibration process | ||||
1 enable DPC | enable DPC correction | ||||
0 FPGA config enable | if set to 1 , the GPIF becomes read only and waits for an FPGA update bitstream |
AWB
Auto White-Balance adjustments | ||||
---|---|---|---|---|
Address | Name | Bytes | Access | Notes |
0x5000'0100 | AWB Red adjustment | 2 | R/W | int16_t value to add to Red channel. Default is \(0\) |
0x5000'0104 | AWB Green adjustment | 2 | R/W | int16_t value to add to Green channel. Default is \(0\) |
0x5000'0108 | AWB Blue adjustment | 2 | R/W | int16_t value to add to Blue channel. Default is \(0\) |
0x5000'010C | AWB Red total | 4 | R/O | |
0x5000'0110 | AWB Green total | 4 | R/O | |
0x5000'0114 | AWB Blue total | 4 | R/O | |
0x5000'0118 | AWB count total | 4 | R/O | A count of pixels that were used to calculate the \(R/G/B\) totals |
0x5000'011C | AWB status | 1 | R/O | Status and flags pertaining to AWB.7:2 reserved1 - indicates whether a red overexposure is detected0 - set if there is a general overexposure detected |
Standard image adjustments
Standard image adjustments | ||||||
---|---|---|---|---|---|---|
Address | Name | Bytes | Access | Range | Range description | Neutral value |
0x5000'0200 | Brightness | 2 | R/W | \([-1024..1023]\) | \(-1024\) makes the image very dark \(1023\) makes the image very bright | \(0\) |
0x5000'0204 | Contrast | 2 | R/W | \([1..2047]\) | \(1\) turns image into grayscale \(2047\) makes all pixels either black or white | \(1023\) |
0x5000'0208 | Saturation | 2 | R/W | \([0..900]\) | \([0\%..900\%]\) or grayscale to 9x | \(100\) |
0x5000'020C | Sharpness | 1 | R/W | \([0..255]\) | \(0\) | |
0x5000'0210 | Gamma | 1 | R/W | \([0..15]\) | \(1\) | |
0x5000'0214 | Hue | 2 | R/W | \([-8192..8191]\) | \([-180°..180°)\) | \(0\) |
DPC
Defective pixel cancellation | ||||
---|---|---|---|---|
Address | Name | Bytes | Access | Notes |
0x5000'0300 | DPC Threshold | 2 | R/W | Only consider a pixel to be defective if its value is over the specified threshold |
0x5000'0304 | DPC count | 2 | R/O | Once the DPC calibration is done the 16-bit result is stored in here |
Image stats
General image stats | ||||
---|---|---|---|---|
Address | Name | Bytes | Access | Notes |
0x5000'0400 | FPS | 2 | R/O | 16-bit unsigned value representing number of 10μs units between frame start signals from the image sensor, e.g. a value of \(1000\) means it took 10ms between 2 frame start signals, which corresponds to 100FPS |
0x5000'0404 | Y average | 2 | R/O | Average “brightness” value |
Color Correction Matrix (a.k.a. CCM or CMX)
See Color correction matrix article in this Wiki's ISP section for more details. The 16-bit (MSB-LSB) value is defined as \(7+9\) bits, where MSB[7:1]
are the integer part and MSB[0]
LSB[7:0]
is the fractional part (effectively that value is 512 times larger than the original fractional part)
CMX | ||||
---|---|---|---|---|
Address | Name | Bytes | Access | Notes |
0x80 | CCM_00 | 2 | R/W | \(CCM_{00}\) |
0x84 | CCM_01 | 2 | R/W | \(CCM_{01}\) |
0x88 | CCM_02 | 2 | R/W | \(CCM_{02}\) |
0x8C | CCM_10 | 2 | R/W | \(CCM_{10}\) |
0x90 | CCM_11 | 2 | R/W | \(CCM_{11}\) |
0x94 | CCM_12 | 2 | R/W | \(CCM_{12}\) |
0x98 | CCM_20 | 2 | R/W | \(CCM_{20}\) |
0x9C | CCM_21 | 2 | R/W | \(CCM_{21}\) |
0xA0 | CCM_22 | 2 | R/W | \(CCM_{22}\) |
Color grading
Move all that out into its very own big block of address space
Name | Address | Access | Bit mapping | Notes |
---|---|---|---|---|
switch | 0x2E | W | 15:10 reserved | Controls what information is being read/written by accessing the register 0x002F |
9:7 table switch | 000 - Hue vs. Hue (14 bits)001 - Hue vs. Saturation (12 bits )010 - Lightness vs. Saturation (12 bits)011 - Saturation vs. Saturation (12 bits)100 - Lightness vs. Lightness (12 bits)101 - Hue vs. Lightness (12 bits)110-111 - reserved |
|||
6:1 index LSB | index into a page in the table | |||
0 access mode | 0 : “normal mode”, in which all the subsequent accesses to the register 0x002F are governed by the values in 0x002E 1 : “bulk access”, where after a read or write access to register 0x002F the “Index” value will auto-increment by one so that the next read/wrie will access the subsequent table slot |
|||
Value | 0x2F | R/W | 15:0 value | 16 bits of either signed or unsigned integer value - for a “Hue vs. Hue” table the 14 bits signed value is in range [-8192..+8192] which maps linearly into a Hue angle range -180°..+180° - for a “Hue vs. Saturation” table (as well as for similar tables LvS and SvS) the 12 bit unsigned value in range [0..+1280] maps linearly into a Saturation range [0%..1000%] where 100% is the neutral position and 0% produces a greyscale image- (until FPGA v.72) for a “Lightness vs. Lightness” table (as well as for similar table HvL) the 12 bit unsigned value in range [0..+4095] maps linearly into a Lightness absolute range [0..255] where 0 is pitch black and 255 is the maximum possible pixel luminosity value- (starting with FPGA v.73) for a “Lightness vs. Lightness” table (as well as for similar table HvL) the 13 bit signed value in range [-4096..+4095] maps linearly into a Lightness *relative* (adjustment) range [-256..255] where 0 is no adjustment to pixel luminosity value |
Media setup
Video output formats
Name | Address | Access | Bit mapping | Notes |
---|---|---|---|---|
Video output format | 0x32 | R/W | 7:4 - UVC3:0 - FPS code for SDI, SFP+, SDI | Bit depth for all video formats is set in register 0x49 UVC video formats: 0 - “RAW” greyscale pre-debayer pixels1 - 4:4:4 RGB2 - (res) packed YCbCr 4:4:43 - packed YCbCr 4:2:24 - (res) packed YCbCr 4:2:05 - (res) planar YCbCr 4:4:46 - (res) planar YCbCr 4:2:27 - planar YCbCr 4:2:08-15 - (res) MJPEG, MPEG-x/H.26x, etcSDI/HDMI and SFP+ video output formats/FPS are always in unison. See SDI FPS table below for codes. SDI output is always in a packed (not planar) YUV 4:2:2 format |
Video output pixel bit depth | 0x33 | R/W | 7:6 - HDMI5:4 - SDI3:2 - SFP+1:0 - UVC | Pixel bit depths \(d_p\) is calculated from a 2-bit value \(N\) as: \[d_p = (N+4)*2\] Not all values are valid, for example SDI and SFP+ both do not support 8 -bit output and UVC only supports 8 -bit color depth, at least for now |
Image sensor config
Name | Address | Access | Bit mapping | Notes |
---|---|---|---|---|
Image sensor configuration | 0x34 | R/W | 7:2 - res1:0 - de-mosaicing strategy | De-mosaicing strategy directs the use of a specific implementation of color reconstruction:3 , 2 - reserved1 - use “branching 5×5”, for example the one described here0 - use “branchless 5×5”, like the one described in here |
Reserved | 0x35-0x39 |
FOURCC formats (for UVC)
A combination of data in 0x0033[1:0]
(pixel bit depth) and 0x32[7:4]
(video format) used for UVC is mapped into standard FOURCC codes as summarized in the following table:
0x0033[1:0] \0x0032[7:4] | 0 (RAW) | 1 (RGB) | 2 (packed YUV 4:4:42)) | 3 (packed YUV 4:2:23)) | 7 (planar YUV 4:2:04)) |
---|---|---|---|---|---|
0 (8 bit) | BA81/BYR1/GREY/Y8/Y800 (8bpp) | BI_RGB/RGB (24bpp) | Y444/IYU2 (24bpp) | YUY2/YUYV (16 bpp) | NV12 (12bpp) |
1 (10 bit) | Y105) (16bpp6)) | BI_BITFIELDS (48bpp) | Y410 (32bpp7)) | Y210 (32bpp) YUVP?/Y42T (24bpp?) | P010 (32bpp) |
2 (12 bit) | BYR2 (16pbb8)) | BI_BITFIELDS (48bpp) | Y4129) (40bpp10)) | Y21211) (32bpp12)) | P01213) (32bpp14)) |
3 (14 bit) | Y1615) (16bpp16)) | BI_BITFIELDS (48bpp) | Y41417) (48bpp18)) | Y21419) (32bpp20)) | P01421) (32bpp22)) |
SDI FPS
FPS+resolution pair dictates an SDI pixel clock choice according to this table:
code (FPS) | 1920×1080 | 3840×2160 | 7680×4320 |
---|---|---|---|
0x01 (23.98) | 74.18 | 296.70 | |
0x02 (24) | 74.25 | 297 | 1188 |
0x04 (25) | 74.25 | 297 | |
0x05 (29.97) | 74.18 | 296.70 | |
0x06 (30) | 74.25 | 297 | 1188 |
0x08 (50) | 148.5 | 594 | |
0x09 (59.94) | 148.35 | 593.41 | |
0x0A (60) | 148.5 | 594 | |
0x0C (120) | 297 | 1188 |
Green Screen enhancer
“Green screen”, a.k.a. “Chroma Key” on-board optimization is designed to replace a range of colors with a single solid one
Move out into its own large address block
band #0
If enabled these setting take precedence over other 3 bands
Name | Address | Bytes | Access | Notes |
---|---|---|---|---|
CK control | 0x80 | 1 | R/W | 7:1 reserved0 enable/disable Chroma Key control |
CK saturation min | 0x81 | 1 | R/W | [0..255] to specify the minimum saturation threshold |
CK saturation max | 0x82 | 1 | R/W | [0..255] to specify the maximum saturation threshold |
CK luma min | 0x83 | 1 | R/W | [0..255] to specify the minimum brightness threshold |
CK luma max | 0x84 | 1 | R/W | [0..255] to specify the maximum brightness threshold |
CK hue | 0x85 | 2 | R/W | 14 bits of a signed hue value, its [-8K..+8K] range is mapped into [-180°..+180°] |
CK tolerance | 0x86 | 2 | R/W | 13 bits of an unsigned hue tolerance value, valid range is [0..8K], which is mapped into [0°..180°]. That value specifies how far to stretch the CK hue value both ways (symmetrically). If the CK tolerance is above 90° the covered color space is over 50% of values |
CK red | 0x87 | 2 | R/W | |
CK green | 0x88 | 2 | R/W | |
CK blue | 0x89 | 2 | R/W | |
Reserved | 0x8A-0x8F |
band #1
Color substitution (if enabled) takes place after the first band had a chance to process the pixels
The layout of the settings is identical to that of band #0 just shifted down by a paragraph and occupying address block 0x0090-0x009F
band #2
Color substitution (if enabled) takes place after the first and second bands had a chance to process the pixels
The layout of the settings is identical to that of band #0 just shifted down by 2 paragraphs and occupying address block 0x00A0-0x00AF
band #3
Color substitution (if enabled) takes place after other bands had a chance to process the pixels
The layout of the settings is identical to that of band #0 just shifted down by 3 paragraphs and occupying address block 0xB0-0xBF
mFT lense access
Need to totally rewrite
Address | Name | Bytes | Access | Notes |
---|---|---|---|---|
0x4805'0000 | MFT command | 4 | R/W | struct MftCmd final{ uint8_t param2, param1; uint8_t cmd_code; uint8_t cmd_type; }; static_assert(std::bit_cast<uint32_t>(MftCmd{1, 2, 3, 4}) == 0x04030201); |
0x4806'0000 | MFT control | 4 | R/W | struct MftCtrl final{ bool start : 1; // start command (type, code, param1, param2) bool pop_input_fifo : 1; // increments the read pointer on input FIFO uint8_t res0 : 5; bool reset : 1; // reset MFT block (must clear after set) uint8_t res1, res2, res3; }; |
0x4807'0000 | MFT status | 4 | R/O | struct MftStatus final{ bool ready : 1; // MFT lens ready (attached) bool cmd_done : 1; // command done (finished) bool in_fifo_empty : 1; // Input FIFO empty bool in_fifo_full : 1; // Input FIFO full bool crc_error : 1; // CRC error occurred bool to_error : 1; // MFT Bus timeout error occurred uint8_t res0 : 2; uint8_t res1; uint8_t in_fifo_data_count; // Input FIFO data count uint8_t res2; }; |
0x4808'0000 | MFT input FIFO data | 1 | R/O |
Micro Four Thirds System (mFT) defines a communication protocol in which the “body” (host) issues 4 bytes of data (command type, command code, and two 1-byte parameters) and gets a response of variable number of bytes, depending on the command (including a 0-length data response). See the mFT spec for each individual command's request/response.
FPGA acts as a two-way command repeater and in such capacity it expects a 4 byte command supplied to it as part of an I²C “write” operation and responds with the appropriate return data buffer to a subsequent “read” I²C operation on the same address.
MFT access protocol
Usage
The mb427 MFT block implements MFT protocol providing communication between the camera body and lens (lens accessories are not yet supported). The current hardware supports type A0,B0 and C0 commands.
Lens Attach
The hardware automatically senses the lens and will immediately attach to the lens. Firmware can tell if a lens is attached by checking the mft_status
bit 0 (ready). If set (1
), a lens has successfully attached to the body and is ready to accept a command.
Lens Detach
When a lens is removed, hardware automatically initiates the detach MFT sequence. When detached, mft_status
bit 0 (ready) will be clear (0
).
Executing an MFT command
- Check ready status. If ready
goto 2
- Load
mft_command
register - Set start bit in
mft_command
register - Check status bit 1 (
command_done
). If setgoto 5
- If read command, check
input_fifo_data_count
inmft_status
register (bits 23:16) - For each byte in fifo:
- Read
mft_rx_data_port
and save the data - Write
mft_control
bit 1 (pop_input_fifo
). This increments the FIFO address pointer and decrements theinput_fifo_data_count
- Clear
mft_control
bit 1 (pop_input_fifo
)
- For read commands, the last byte of data is a checksum. To verify the checksum, simply add all (N-1) bytes and compare the sum to last byte (N) returned
- Remember to use unsigned arithmetic
- Finally, clear start bit and
pop_input_fifo
bits in the control register