====== 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 [[https://www.intel.com/content/www/us/en/docs/programmable/683091/22-3/introduction-to-the-interface-specifications.html|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 FIXME:
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 [[code#firmware_version_info|Firmware Version Info]]| |
|''0x5000'0004''|:!: FPGA status| 4 |R/O|see Notes for more details\\ \\ ''31:16'' [[code:code#FPGA config status - SPI codes|SPI codes]]\\ ''15:8'' FPGA core temperature\\ ''7:2'' reserved\\ ''1'' HDMI connected\\ ''0'' SFP+ active|The bytes of the FPGA status register are allocated according to the little-endian memory layout of the following C-style declaration((For details on ''spi_config_status'' see [[code:code#FPGA config status - SPI codes|SPI codes]])):\\
struct FpgaStatus{
struct State{
// SFP+ module is present, has signal, and reports no fault
bool sfp_active:1;
// HDMI sink is connected and detected through HPD
bool hdmi_connected:1;
uint8_t reserved:6;
} state;
uint8_t core_temperature;
uint16_t spi_config_status;
};|
===== FPGA operation mode =====
^ FPGA operation mode((Set the operation mode of the FPGA (e.g. switch into firmware programming) and enable/disable individual media output channels and specific transformation blocks)) ^^^^^^
^Address ^Name ^Bytes ^Access ^Bit mapping ^Notes ^
|''0x5000'0008''|:!: FPGA operation mode| 4 |R/W|''31:26'' reserved| |
|:::|:::|:::|:::|:!: ''25'' CCM| enable Color Correction Matrix transformation block |
|:::|:::|:::|:::|:!: ''24'' Gamma| enable UVC Gamma transformation block |
|:::|:::|:::|:::| ''23'' reserved| |
|:::|:::|:::|:::|:!: ''22:21'' debayer strategy|**De-mosaicing strategy** directs the use of a specific implementation of color reconstruction:\\ ''0'' - use "branchless 5x5", like the one [[https://www.ipol.im/pub/art/2011/g_mhcd/article.pdf|described in here]]\\ ''1'' - use "branching 5x5", for example the one [[http://www.siliconimaging.com/RGB%20Bayer.htm|described here]]\\ ''2'', ''3'' - reserved|
|:::|:::|:::|:::| ''20:17'' reserved| |
|:::|:::|:::|:::|:!: ''16'' headphones audio| enable audio output via headphone jack |
|:::|:::|:::|:::|:!: ''15'' HDMI audio| enable HDMI audio output |
|:::|:::|:::|:::|:!: ''14'' SDI audio| enable SDI audio output |
|:::|:::|:::|:::|:!: ''13'' SFP+ audio| enable SFP+ audio output |
|:::|:::|:::|:::|:!: ''12'' UAC output| enable UAC output |
|:::|:::|:::|:::|:!: ''11'' HDMI video| enable HDMI video output |
|:::|:::|:::|:::|:!: ''10'' SDI video| 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|
===== Color gains =====
Each color channel gets adjusted before being processed by de-bayer. The adjustment is of the form
\[
C_{out} = [(C_{in} - {black \space level})] \times Mult + Add \\
\text{where the result of} \space
[(C_{in} - {black \space level})] \space
\text{is 0 if negative}
\]
Additive and black level adjustments are 12 bit unsigned integers in range \([0..4095]\). Multiplicative adjustments are fixed-point format numbers with first 3 bits for integer part and the rest 13 bits for fractional, i.e. ''Q3.13'' format.
^ Color gain adjustments, pre-debayer ^^^^^
^Address ^Name ^Type ^Access ^Notes ^
|''0x5000'0100''|Additive gain Red| uint16_t |R/W|value to add to Red component. Default is \(1200\)|
|''0x5000'0104''|Additive gain Green (red)| uint16_t |R/W|value to add to Green component in red row. Default is \(1200\)|
|''0x5000'0108''|Additive gain Green (blue)| uint16_t |R/W|value to add to Green component in blue row. Default is \(1200\)|
|''0x5000'010C''|Additive gain Blue| uint16_t |R/W|value to add to Blue component. Default is \(1200\)|
|''0x5000'0110''|:!: Multiplicative gain Red| Q3.13 |R/W|Multiplicative adjustment to apply to Red channel|
|''0x5000'0114''|:!: Multiplicative gain Green (red)| Q3.13 |R/W|Multiplicative adjustment to apply to Green channel in red row|
|''0x5000'0118''|:!: Multiplicative gain Green (blue)| Q3.13 |R/W|Multiplicative adjustment to apply to Green channel in blue row|
|''0x5000'011C''|:!: Multiplicative gain Blue| Q3.13 |R/W|Multiplicative adjustment to apply to Blue channel|
|''0x5000'0120''|:!: Black level Red| uint16_t |R/W|Value to subtract from initial Red component before applying multiplicative adjustment|
|''0x5000'0124''|:!: Black level Green (red)| uint16_t |R/W|Value to subtract from initial Green component in red row before applying multiplicative adjustment|
|''0x5000'0128''|:!: Black level Green (blue)| uint16_t |R/W|Value to subtract from initial Green component in blue row before applying multiplicative adjustment|
|''0x5000'012C''|:!: Black level Blue| uint16_t |R/W|Value to subtract from initial Blue component before applying multiplicative adjustment|
===== RGGB gamma LUTs =====
^ RGGB gamma LUTs ^^^^^
FX3 (or Nios) is responsible for populating the 4x4K LUTs for FPGA to use for RGGB gamma correction.
^Address ^Name ^Type ^Access ^Notes ^
|''0x5000'0138''|:!: RGGB gamma LUT control| uint32_t |R/W||
|''0x5000'013C''|:!: RGGB gamma LUT data| uint32_t |R/W||
===== AWB =====
^ Auto White-Balance adjustments, post-debayer ^^^^^
^Address ^Name ^Type ^Access ^Notes ^
|''0x5000'0200''|:!: AWB Red adjustment| uint16_t |R/W|value to add to Red component. Default is \(0\)|
|''0x5000'0204''|:!: AWB Green adjustment| uint16_t |R/W|value to add to Green component. Default is \(0\)|
|''0x5000'0208''|:!: AWB Blue adjustment| uint16_t |R/W|value to add to Blue component. Default is \(0\)|
===== ISP adjustments =====
^ Standard image adjustments ^^^^^^^
^Address ^Name ^Bytes ^Access ^Range ^Range description ^Neutral value ^
|''0x5000'0300''|:!: Brightness| 2 |R/W|\([-1024..1023]\) |\(-1024\) makes the image very dark\\ \(1023\) makes the image very bright |\(0\) |
|''0x5000'0304''|:!: Contrast| 2 |R/W|\([1..2047]\) |\(1\) turns image into grayscale\\ \(2047\) makes all pixels either black or white |\(1023\) |
|''0x5000'0308''|:!: Saturation| 2 |R/W|\([0..900]\) |\([0\%..900\%]\) or grayscale to 9x |\(100\) |
|''0x5000'030C''|:!: Sharpness| 1 |R/W|\([0..255]\) | |\(0\) |
|''0x5000'0310''|:!: Gamma| 1 |R/W|\([0..15]\) | the values \([0..15]\) map into range from \(1.0\) to \(2.5\) with a \(0.1\) increment step |\(0\) |
|''0x5000'0314''|:!: Hue| 2 |R/W|\([-8192..8191]\) |\([-180°..180°)\) |\(0\) |
===== DPC =====
^ Defective pixel cancellation ^^^^^
^Address ^Name ^Bytes ^Access ^Notes ^
|''0x5000'0400''|:!: DPC Threshold| 2 |R/W| Only consider a pixel to be defective if its value is over the specified threshold |
|''0x5000'0404''|:!: 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'0480''|:!: 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'0484''|:!: Y average| 2 |R/O|Average "brightness" value|
===== Color Correction Matrix (a.k.a. CCM or CMX) =====
See [[isp:ccm|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 (a.k.a. ''Q7.9''), 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 ^
|''0x5000'0500''|:!: CCM_00| 2 |R/W|\(CCM_{00}\)|
|''0x5000'0504''|:!: CCM_01| 2 |R/W|\(CCM_{01}\)|
|''0x5000'0508''|:!: CCM_02| 2 |R/W|\(CCM_{02}\)|
|''0x5000'050C''|:!: CCM_10| 2 |R/W|\(CCM_{10}\)|
|''0x5000'0510''|:!: CCM_11| 2 |R/W|\(CCM_{11}\)|
|''0x5000'0514''|:!: CCM_12| 2 |R/W|\(CCM_{12}\)|
|''0x5000'0518''|:!: CCM_20| 2 |R/W|\(CCM_{20}\)|
|''0x5000'051C''|:!: CCM_21| 2 |R/W|\(CCM_{21}\)|
|''0x5000'0520''|:!: CCM_22| 2 |R/W|\(CCM_{22}\)|
===== Exposure stats =====
Exposure stats are being accumulated each frame by summing up \(R+G+B\) values of every pixel in the specified window
^ Image's exposure stats ^^^^^
^Address ^Name ^Bytes ^Access ^Notes ^
|''0x5000'0530''|exposure_xy_win1| 4 |R/W|''31:16'' - X coordinate\\ ''15:0'' - Y coordinate|
|''0x5000'0534''|exposure_xy_win2| 4 |R/W|''31:16'' - X coordinate\\ ''15:0'' - Y coordinate|
|''0x5000'0538''|exposure_sum| 4 |R/O|Sum of all pixel’s magnitude within window|
|''0x5000'053C''|over_exposed_sum| 4 |R/O|Number of over exposed pixels (those with \(R+G+B > 12000\))|
===== White balance stats =====
WB stats are being accumulated each frame by summing up \(R, G, B\) channel values of every pixel in the specified window
^ Image's exposure stats ^^^^^
^Address ^Name ^Bytes ^Access ^Notes ^
|''0x5000'0540''|wb_xy_win1| 4 |R/W|''31:16'' - X coordinate\\ ''15:0'' - Y coordinate|
|''0x5000'0544''|wb_xy_win2| 4 |R/W|''31:16'' - X coordinate\\ ''15:0'' - Y coordinate|
|''0x5000'0548''|R_sum| 4 |R/O|Sum of all pixel’s \(R\) values within window|
|''0x5000'054C''|G_sum| 4 |R/O|Sum of all pixel’s \(G\) values within window|
|''0x5000'0550''|B_sum| 4 |R/O|Sum of all pixel’s \(B\) values within window|
|''0x5000'0554''|R_sat_count| 4 |R/O|Number of pixel within window where \(R\) values are saturated (those with \(R > 4000\))|
|''0x5000'0558''|G_sat_count| 4 |R/O|Number of pixel within window where \(G\) values are saturated (those with \(G > 4000\))|
|''0x5000'055C''|B_sat_count| 4 |R/O|Number of pixel within window where \(B\) values are saturated (those with \(B > 4000\))|
===== Color grading =====
FIXME Move all that out into its very own big block of address space FIXME
^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\\ - 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 and pixel bit depth|''0x5000'0700''|R/W|''31:16'' - reserved\\ :!: ''15:12'' - UVC\\ :!: ''11:8'' - FPS code for SDI, SFP+, SDI|Bit depth for all video formats is set in register ''0x5000'0708''\\ UVC video formats:\\ :!:''0'' - "RAW" greyscale pre-debayer pixels\\ :!:''1'' - 4:4:4 RGB\\ :!:''2'' - (res) packed YCbCr 4:4:4\\ :!:''3'' - packed YCbCr 4:2:2\\ :!:''4'' - (res) packed YCbCr 4:2:0\\ :!:''5'' - (res) planar YCbCr 4:4:4\\ :!:''6'' - (res) planar YCbCr 4:2:2\\ :!:''7'' - planar YCbCr 4:2:0\\ :!:''8-15'' - (res) MJPEG, MPEG-x/H.26x, etc\\ \\ SDI/HDMI and SFP+ video output formats/FPS are always in unison. See [[code:fx3_hvci_and_fpga_i_c_commands#sdi_fps|SDI FPS]] table below for codes. SDI output is always in a packed (not planar) YUV 4:2:2 format|
|:::|:::|:::|:!: ''7:6'' - HDMI\\ :!: ''5:4'' - SDI\\ :!: ''3:2'' - SFP+\\ :!: ''1:0'' - UVC|Pixel bit values:\\ ''0'' => 8\\ ''1'' => 10\\ ''2'' => 12\\ ''3'' => 14\\ Not all values are valid, for example SDI and SFP+ both do not support ''8''-bit output and UVC currently **only** supports ''8''-bit color depth|
|:!: Video output geometry|''0x5000'0708''|R/W|:!: ''31:16'' - uint16_t horizontal\\ :!: ''15:0'' - uint16_t vetical|Horizontal x vertical resolution, in pixels|
==== FOURCC formats (for UVC) ====
^ UVC's FOURCC codes((A combination of pixel bit depth and video format used for UVC is mapped into standard FOURCC codes as summarized in the following table)) ^^^^^^
^\(_{bit-depth} \backslash ^{video-format}\) ^''0'' (RAW) ^''1'' (RGB) ^''2'' (packed YUV 4:4:4((ordering is UYV))) ^''3'' (packed YUV 4:2:2((macropixel byte ordering: Y0U0Y1V0))) ^''7'' (planar YUV 4:2:0((chroma plane is a interleaved set of U/V samples))) ^
^''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) |:!: Y10((need to register with MS)) (16bpp((not 10)))|:!: BI_BITFIELDS (48bpp) |:!: Y410 (32bpp((includes 2 bit alpha at [31:30]))) |:!: Y210 (32bpp)\\ YUVP?/Y42T (24bpp?)|:!: P010 (32bpp) |
^''2'' (12 bit) |:!: BYR2 (16pbb((not 12)))|:!: BI_BITFIELDS (48bpp) |:!: Y412((need to register with MS)) (40bpp((or 36?))) |:!: Y212((need to register with MS)) (32bpp((or 24?))) |:!: P012((need to register with MS)) (32bpp((or 24, or 18?))) |
^''3'' (14 bit) |:!: Y16((yes, 16, not 14)) (16bpp((not 14)))|:!: BI_BITFIELDS (48bpp) |:!: Y414((need to register with MS)) (48bpp((or 42?))) |:!: Y214((need to register with MS)) (32bpp((or 28?))) |:!: P014((need to register with MS)) (32bpp((or 21?))) |
==== SDI FPS and pixel clock ====
^ SDI FPS and pixel clock((FPS+resolution pair dictates an SDI pixel clock choice)) ^^^^
^ \(_{code (FPS)} \backslash ^{resolution}\) ^ 1920x1080 ^ 3840x2160 ^ 7680x4320 ^
| ''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 | |
==== Video pipeline setup ====
^Name ^Address ^Access ^Bit mapping ^Notes ^
|:!: Initial scaler setup|''0x5000'0800''|R/W|''31:4'' - reserved\\ :!: ''3:2'' - scale divisor\\ :!: ''1:0'' - filter mode|The initial scaler is the first post-debayer pipeline stage. Horizontal and vertical scaling always use the same divisor, preserving the input aspect ratio.\\ \\ Scale divisor values:\\ ''0'' - 1:1 (pass-through)\\ ''1'' - 2:1 (output width and height are each half of the input)\\ ''2-3'' - reserved\\ \\ Filter mode values:\\ ''0'' - nearest (select the top-left pixel from each source region)\\ ''1'' - box average\\ ''2-3'' - reserved for future filters\\ \\ The filter mode is ignored in 1:1 pass-through mode. This register must only be changed while the video pipeline is fully stopped.|
|:!: UVC scaler output geometry|''0x5000'0804''|R/W|:!: ''31:16'' - uint16_t horizontal\\ :!: ''15:0'' - uint16_t vertical|Requested UVC scaler output resolution, in pixels. The input geometry is derived internally from the output of the initial scaler and is not independently configurable.\\ \\ Setting the output geometry equal to the input geometry selects 1:1 pass-through. Initially, only downscaling is supported. The requested width and height must be non-zero and must not exceed the input geometry. Packed YCbCr 4:2:2 output requires an even horizontal resolution. This register must only be changed while UVC output is stopped.|
|:!: UVC scaler control|''0x5000'0808''|R/W|''31:2'' - reserved\\ :!: ''1:0'' - filter mode|Filter mode values:\\ ''0'' - nearest\\ ''1'' - box average\\ ''2-3'' - reserved for future filters\\ \\ Horizontal and vertical sampling ratios are derived internally from the initial scaler output geometry and requested UVC output geometry. This register must only be changed while UVC output is stopped.|
===== 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//
FIXME Move out into its own large address block FIXME
==== 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'' reserved\\ ''0'' 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''
==== mFTS lens access ====
^ mFT lense access ^^^^^
^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(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 set ''goto 5''
- If read command, check ''input_fifo_data_count'' in ''mft_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 the ''input_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