====== FX3/FPGA API spec ====== This page describes FX3 API for Frankie (gen3), Rex (gen4), Square1 and Studio (gen5) products. For gen4 and earlier API see [[code:fx3_fpga_api_spec_rex|FX3/FPGA API spec up to REX]]. ====== FX3 API Reference ====== The following tables provide information on how to access the camera's functionality for ''FX3 Host Vendor Command Interface''. The address space is split into smaller chunks, grouped by common functionality: ===== 0x00-0x9F ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0x00''-''0x9F''| | | | | |Think of this as "system address space"| ===== Global controls ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Bootloader check|''0xA0''| | |R/W| | |Check if a bootloader is running, the result is in the command's status code (success/failure interpreted as ''true''/''false'')| |MS OS Descr.|''0xA1''|bits [\(3:0\)] - see notes | |R/O|\(174\)|MS OS Platform Descriptor|For details on the structure and valid parameters' values refer to Microsoft's documentation for [[https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-os-2-0-descriptors-specification|Microsoft OS 2.0 Descriptors Specification]]\\ The \(4\) LSB of the ''wIndex'' field are the descriptor's index. Valid values are:\\ \(7\) - MS OS 2.0 descriptor\\ \(8\) - MS OS 2.0 set alternative enumeration (currently not supported)| |:!: Run DPC calibration|''0xA2''| |DPC Threshold|W/O| | |Start the dynamic DPC calibration with the given DPC Threshold in range [\(0..4095\)]| |Reserved|''0xA3''| | | | | | | ===== I²C access ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: FPGA I²C Bridge|''0xA4''|FPGA register offset|FPGA data (write)|R/W|\(0\) or \(1\)|[\(7:0\)] - FPGA data| **DEPRECATED in Gen5+** - use the ''Generic I²C access'' instead\\ **Up to Gen4** - FPGA write returns 0 byte buffer, FPGA read returns 1 byte buffer. Read/write is requested via control endpoint's direction attribute being set to ''DIR_FROM_DEVICE''/''DIR_TO_DEVICE''.\\ For details on individual commands refer to [[fpga_registers_map|FPGA I²C bridge]]| |:!: Sensor I²C bridge (\(8\)-bit configuration registers)|''0xA5''| [\(15:0\)] - sensor ''register'' address | ''mask'' and ''data'' (if writing) - see Notes column for details |R/W|\(0\) or \(1\)| [\(7:0\)] - sensor register's data | ''register'' - a \(16\) bit register address\\ ''mask'' - an \(8\)-bit MSB that specifies which bits to affect during a write operation - only the bits that are set in ''mask'' will be affected by bits in ''data''. Setting ''mask'' to \(0\) ultimately turns a write operation into a read one as no bits are getting modified\\ ''data'' - an \(8\)-bit LSB that specifies the new data to write into sensor's register. The write only affects the bits that are set in ''mask''\\ Read operation returns an \(8\)-bit register's value\\ Read/write is requested via control endpoint's direction attribute being set to ''DIR_FROM_DEVICE''/''DIR_TO_DEVICE''.\\ For details on each sensor's register's function refer to the sensor's specification | |:!: Generic I²C access|''0xA6''|[\(15:8\)] \(8\)-bit I²C bus address\\ [\(7:6\)] [[#Generic I²C command selector|command selector]]\\ [\(5:3\)] [[#Generic I²C width selector|data width selector]]\\ [''2:0''] [[#Generic I²C width selector|address width selector]]|[\(7:0\)] - number of data elements to read/write|R/W| | |single/bulk read/write to/from an arbitrary device on I²C bus, supports \(8\), \(16\), \(32\) bit addressing and same for data OR poll for status or get result of a bulk I2C operation, see [[#Generic I²C access details|next section]] for details| ==== Generic I²C access details ==== This versatile API allows single/bulk access to an arbitrary device on I²C and supports 8, 16, 32-bit addressing and data. Single (non-bulk) access is always an immediate, non-cached execution while bulk access is always cached. For bulk operations the result is queried/polled until it is acquired or has failed. === Generic I²C command selector === ^Code ^Name ^Description ^ | \(0\) | read |This command issues an immediate read on I²C if a single address is requested or batches up the reads for a background task otherwise. Use `status` to know when it is ok to retrieve data via a call to `get results`| | \(1\) | write |same as `read`, but for I²C writes| | \(2\) | status |Call this repeatedly while the return code is `still in progress` (code \(0x80\)), until it returns either a `success` (code \(0\)) or any of the `fail` codes, at which point call the `results`| | \(3\) | results |Once the `read` operation completes successfully, this call will retrieve the read data| === Status codes === ^Code ^Description ^ | ''0x00'' |operation completed with no errors| | ''0x01'' |I²C subsystem is not initialized| | ''0x02'' |invalid I²C bus address - must be an \(8\)-bit kind, so last bit has to be a \(0\)| | ''0x03'' |I²C operation failed| | ''0x10'' |too many elements to process| | ''0x11'' |invalid (reserved) width value for address| | ''0x12'' |invalid (reserved) width value for data| | ''0x13'' |mismatch between number of elements specified in request (in ''wValue'''s LSB) and buffer (based on ''wLength'' and address+data width)| | ''0x20'' |cache buffer overflow (did you forget to poll for successful completion before issuing a new command? Or is there another application trying to utilize this same API in parallel?)| === Generic I²C width selector === ^Value ^Width (bits) ^ | \(0\) | \(8\) | | \(1\) | \(16\) | | \(2\) | \(32\) | ===== Video mode select ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: Video Mode Select|''0xA7''| | |R/W| 1 |\(7:2\) - Reserved\\ \(1\) - HDR mode\\ \(0\) - RAW mode |\(1\) - chose between HDR(\(1\)) or linear (\(0\)) sensor mode\\ \(0\) - select RAW mode (\(1\)) or Processed Video (\(0\)) for video pipeline\\ **N.B.** "Raw mode" has been moved here from ''0xA5'' in FX3 version \(46\)| ===== Sysinfo ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: Sysinfo|''0xA8''|data structure version:\\ \(1\) - deprecated\\ \(2\) - supported version | bitmask of additional checks to perform:\\ :!: \(0\) - reinit FPGA and/or sensor if needed\\ \(1\)-\(7\): reserved |R/O|\(54\)| struct SysInfoV2 |Get various internal system info on the guts of the RTOS and the firmware running on FX3, as well as overall configuration and health check results. Returned bytes:\\ **Version 2**: [[SysInfoV2]] | |Reserved|''0xA9''| | | | | | | ===== Versioning and reprogramming ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Notes ^ |Erase SPI Flash|''0xAA''| | |W/O| |Any write to this location invalidates the FX3 SPI Flash and causes the FX3 to reset itself to a bootloader mode for reprogramming| |FX3 version|''0xAB''| | |R/O| \(4\) |Get detailed version information of the FX3, for more details refer to [[#FX3 Version Info]]| |:!: FPGA version|''0xAC''| | |R/O| \(4\) |Get detailed version information of the FPGA, for more details refer to [[#FPGA Version Info]]| |:!: FPGA config. ctrl.|''0xAD''| | |W/O| |Any write to this location will put the FPGA into configuration mode| |:!: FPGA config. status - SPI codes|''0xAE''| | |R/O| \(2\) |Retrieve detailed status of the FPGA configuration operation. See [[#FPGA config status - SPI codes|below]] for details| |SPI Flash write enable|''0xAF''| | |W/O| |Reconfigure the FX3 IOMatrix to disable GPIF and enable SPI to be re-written| ==== FPGA config status - SPI codes ==== ^ Bit position^ 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 busy|Set to \(1\) while the config is not busy| ===== FPS control ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: FPS|''0xB0''| | |R/W|\(4\)|float32 FPS|FPS value is in IEEE float32 format, x86 LE| ===== Bulk color grading ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: Bulk color grading|''0xB1''|[\(15:8\)] - table\\ [\(7:0\)] - starting index|[\(15:8\)] - version\\ [\(7:0\)] - count|R/W|\(count * 2\)| |Currently only version \(1\) is supported.\\ The //table// is a value from this list:\\ ''000'' - Hue vs. Hue (\(14\) bits)\\ ''001'' - Hue vs. Saturation (\(12\) bits)\\ ''010'' - Lightness vs. Saturation (\(12\) bits)\\ ''011'' - Saturation vs. Saturation (\(12\) bits)((scheduled for later))\\ ''100'' - Lightness vs. Lightness (\(12\) bits)\\ ''101'' - Hue vs. Lightness (\(12\) bits)((scheduled for later))\\ ''110-111'' - reserved\\ //Starting index// is a \(0\)-based offset of the first written/read color grading value\\ //Version// is currently \(1\)\\ //Count// - how many entries to write/read\\ The buffer is exchanged in data phase of the USB control request (both IN/OUT)| ===== 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. ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: Color correction matrix|''0xB2''| ''0'' | ''0x0303'' |R/W|32|packed C-array float[3][3]|That data buffer could also be defined as float[9] or as byte* for the same exact memory layout on LE systems| ===== 0xB3-0xB7 ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0xB3''| | | | |Reserved|''0xB4''| | | | |Reserved|''0xB5''| | | | |Reserved|''0xB6''| | | | |Reserved|''0xB7''| | | | ===== FPGA stats ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: FPGA stats|''0xB8''|statistics type|\(0\)|R/O|see notes|see notes|Read out various stats from FPGA, see [[#FPGA stats' details|table below]] for details| ==== FPGA stats' details === ^Name ^Value ^Return type ^Notes ^ | :!: Sensor FPS | ''0x01'' | float | IEEE float32 format, x86 LE number derived from FPGA's video pipeline observed time between first pixel output of two consecutive video frames | ===== 0xB9 ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0xB9''| | | | ===== SDI control ===== ^ Name ^ Offset ^ wIndex ^ wValue ^ Access type ^ Byte length ^ Return buffer bits ^ Notes ^ |:!: SDI control| ''0xBA'' | \(0\) | \(1\) | R/W | \(1\) |\(0\) - SDI on/off | SDI control, for now only on/off with the default video mode of 1080p@60fps 10bit YUV ''4:2:0'' packed | ===== 0xBB-0xBF ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0xBB''| | | | |Reserved|''0xBC''| | | | |Reserved|''0xBD''| | | | |Reserved|''0xBE''| | | | |Reserved|''0xBF''| | | | ===== SPI flash management ===== The SPI flash memory (either \(128\)MB or \(256\)MB) is partitioned into \(65\)KB sectors, each comprised of \(256\) pages. Each page is \(256\) bytes long. ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |SPI command byte|''0xC0''|[\(7:0\)] command byte|\(0\)|R/W| |execute SPI command with no address| |SPI command with 24-bit address|''0xC1''|[\(15:8\)] bits [\(23:16\)] of the address\\ [\(7:0\)] command byte|[\(15:0\)] LSW of the address|R/W| |execute SPI command with a \(24\)-bit address| |SPI flash write page|''0xC2''|[\(15:0\)] page address| |W/O|\(256\)| |write a page of SPI flash (same command as Cypress' examples). The flash page size is fixed to \(256\) bytes| |SPI flash read page|''0xC3''|[\(15:0\)] page address| |R/O|\(256\)|page's content|read a page of SPI flash (same command as Cypress' examples). The flash page size is fixed to \(256\) bytes| |SPI flash sector erase/poll|''0xC4''|[\(7:0\)] - sector|\(0\) - poll\\ \(1\) - erase |R/W| | |either erase a SPI flash sector, or poll SPI busy status (same command as Cypress' examples)\\ \\ sector's byte address is computed by multiplying //wIndex// by \(65536\)\\ \\ For Erase SPI flash sector function:\\ - //wValue// = ''0x0001''\\ - //wIndex// = SPI flash sector address\\ - //wLength// = ''0x0000''\\ No data phase associated with this command\\ \\ For Check SPI busy status function:\\ - //wValue// = ''0x0000''\\ - //wIndex// = ''0x0000''\\ - //wLength// = ''0x0001''\\ Data phase indicates flash busy status:\\ - ''0x00'' means SPI flash has finished write/erase operation\\ - non-zero value means that SPI flash is still busy processing previous write/erase command.| |SPI flash cmd 24|''0xC5''|[\(7:0\)] command byte\\ [\(15:8\)] address's bits [\(23:16\)]|[\(15:0\)] address's bits [\(15:0\)]|R/W| | |Run an arbitrary SPI flash command byte| |Reserved|''0xC6''| | | | | | | |Reserved|''0xC7''| | | | | | | ===== 0xC8-0xCF ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0xC8''| | | | | | | |Reserved|''0xC9''| | | | | | | |Reserved|''0xCA''| | | | | | | |Reserved|''0xCB''| | | | | | | |Reserved|''0xCC''| | | | | | | |Reserved|''0xCD''| | | | | | | |Reserved|''0xCE''| | | | | | | |Reserved|''0xCF''| | | | | | | ===== Auto exposure configuration ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: AE Setpoint|''0xD0''| |AE Setpoint|R/W|\(0\) or \(2\) |[\(11:0\)] value|Target Auto Exposure Luminance Setpoint \([0..4095]\)\\ Default: \(2500\)\\ This controls the "average luminance" of the whole frame that we are trying to achieve. The higher the value the brighter the result is going to be| |Reserved|''0xD1''| | | | | | | |Reserved|''0xD2''| | | | | | | |Reserved|''0xD3''| | | | | | | |Reserved|''0xD4''| | | | | | | |Reserved|''0xD5''| | | | | | | |Reserved|''0xD6''| | | | | | | |Reserved|''0xD7''| | | | | | | ===== Auto white balance configuration ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: AWB Setpoint|''0xD8''| |AWB Setpoint|R/W|\(0\) or \(2\) |[\(11:0\)] value|Auto White Balance G Gain Setpoint \([0..4095]\)\\ Default \(2048\)\\ The pinned value for Green Gain that is used as the basis for the rest of the white balance adjustments. Only change this value if you need to make your picture brighter and you have exhausted both the Exposure and the Global Gain options| |Reserved|''0xDC''| | | | | | | |Reserved|''0xDD''| | | | | | | |Reserved|''0xDE''| | | | | | | ===== Auto-functions' timing ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Auto Update Period|''0xDF''| |Auto Update Period|R/W|\(0\) or \(2\) |[\(15:0\)] value|Auto Update Period \([0..65535]\))\\ Default \(17\)\\ Determines how long we wait before trying to apply a new update for both exposure and white balance (when auto functions are enabled), as well as other up-keep operations, like pushing data over I²C bus.\\ This is an asynchronous update rate.\\ That value is approximately in milliseconds| ===== FX3 reset ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |FX3 reset|''0xE0''| | |W/O| | |Cypress vendor command to soft reset FX3| ===== Camera peripherals ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Notes ^ | LED | ''0xE1'' | See [[#LED function selector]] | \(0\) | R/W | \(24\) bits per RGB triplet | Mode selector values are described in [[#LED function selector]] | | Fan control and monitoring | ''0xE2'' | See [[#Fan control and monitoring function selector]] | depends on selected function | R/W | \(1\) or \(2\) | This API is available in gen4 v.114 and gen5 v.1\\ \\ For function selector values refer to [[#Fan control and monitoring function selector]] | | Temperature sensor(s)|''0xE3''| See [[#Temperature sensor monitoring function selector]] | depends on selected function | R/O | \(1\) | This API is available in gen4 v.114 and gen5 v.1\\ \\ For function selector values refer to [[#Temperature sensor monitoring function selector]] below | |mFT|''0xE4''| see Notes | see Notes | R/W | varies | This API requires gen5 v.1\\ For reads:\\ wValue is the number of data bytes to read from the last mFT command's response or a ''0'' to get the status, defined as follows:\\ struct MftStatus final{ bool ready : 1; // LSB bool cmd_done : 1; bool in_fifo_empty : 1; bool in_fifo_full : 1; bool crc_error : 1; bool to_error : 1; uint8_t res0 : 2; uint8_t res1; uint8_t in_fifo_data_count; uint8_t res2; // MSB }; For writes:\\ - wIndex MSB: command type\\ - wIndex LSB: command code\\ - wValue MSB: param1\\ - wValue LSB: param2 | |Reserved|''0xE5''| | | | |Reserved|''0xE6''| | | | |Reserved|''0xE7''| | | | |Reserved|''0xE8''| | | | ====== LED function selector ====== ^Function ^Value ^Byte length^ Notes ^ | Unified LED color | \(0\) | \(3\) | For both gen4 and gen5 this allows to get/set the single \(24\)-bit RGB triplet for LED pixel(s) color. When reading from multi-pixel setup the value of the first pixel is returned | | Left-side LED color | \(1\) | \(3\) | Gen5 has two sides for pixels, this allows to get/set the color of the left group. When reading the value of the first pixel in a group is returned | | Right-side LED color | \(2\) | \(3\) | Gen5 has two sides for pixels, this allows to get/set the color of the right group. When reading the value of the first pixel in a group is returned | | \(8\)-pixel LED mode | \(3\) | \(24\) | Gen5 comes with a total of 8 LED pixels, individually controllable with this API. The command always operates (gets/sets) the full array of \(8\) \(3\)-byte RGB pixels | ====== Fan control and monitoring function selector ====== ^Function ^Value ^Type ^Byte length^ Notes ^ | FPGA-controlled fan on/off | \(0\) | boolean | \(1\) | Gen4 (including the REX model) is equipped with a fan that is controlled by FPGA | | EMC2101's fan speed | \(1\) | uint8_t | fan speed | The speed's value is in range \([0..100]\%\) though keep in mind that at very low speeds the fan may stop spinning | | EMC2101's fan RPM reading | \(2\) | uint16_t | RPM, R/O access | This reading is based on internal tachometer's clock ticks' count | ====== Temperature sensor monitoring function selector ====== ^Function ^Constant ^Value ^Byte length^ Notes ^ | EMC2101's internal temperature sensor | ''0'' | ''int8_t'' | ''1'' | A signed temperature reading in °C | ===== 0xE9-0xEF ===== |Reserved|''0xE9''| | | | |Reserved|''0xEA''| | | | |Reserved|''0xEB''| | | | |Reserved|''0xEC''| | | | |Reserved|''0xED''| | | | |Reserved|''0xEE''| | | | |Reserved|''0xEF''| | | | ===== 0xF0-0xF9 ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0xF0''| | | | |Reserved|''0xF1''| | | | |Reserved|''0xF2''| | | | |Reserved|''0xF3''| | | | |Reserved|''0xF4''| | | | |Reserved|''0xF5''| | | | |Reserved|''0xF6''| | | | |Reserved|''0xF7''| | | | |Reserved|''0xF8''| | | | |Reserved|''0xF9''| | | | ===== [Debug] Get raw descriptor ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Get raw descriptor|''0xFA''|[[#Get raw descriptor commands|command]]|[[#Get raw descriptor structure types|struct to get]]|R/O|varies by command (see below)|struct's byte buffer|This APi is mostly used for debugging purposes and provides "direct" access to USB descriptors| ==== Get raw descriptor commands ==== ^Cmd (wIndex) ^Meaning ^ |\(0\)|get a \(2\)-byte descriptive text label's length (not including the C-style null-terminator)| |\(1\)|get descriptive text label (up to \(4096\) bytes **without** a C-style null-terminator)| |\(2\)|get a \(2\)-byte size of the structure in bytes| |\(3\)|get structure's byte buffer| ==== Get raw descriptor structure types ==== As of FX3 version ''58'' the following internal structures are supported: ^wValue ^ Details ^ |\(0\)|reserved (unused)| |\(1\)|USB device descriptor HS| |\(2\)|USB device descriptor SS| |\(3\)|USB Device Qualifier descriptor| |\(4\)|USB BOS (Binary Object Store) descriptor| |\(5\)|MS OS Platform Capability descriptor version 2.0| |\(6\)|Full-Speed (2.0) USB Configuration descriptor| |\(7\)|High-Speed (2.0) USB Configuration descriptor| |\(8\)|Super-Speed (3.0) USB Configuration descriptor| ===== OS runtime info ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |:!: OS runtime info|''0xFB''|see below|see below|R/O|see below|see below|Query for OS internal info. A type of query is specified in ''wValue'' field and, along with other fields, is described in the table below| ^wValue ^wIndex ^Description ^ | :!: \(0\) | | get number of user trheads | | :!: \(1\) | \(0\)-based thread's index |get info on the thread, see [[OsThreadInfo_v60|struct OsThreadInfo]] for details| ===== 0xFC-0xFF - Reserved for debug APIs ===== ^Name ^Offset ^wIndex ^wValue ^Access type ^Byte length ^Return buffer bits ^Notes ^ |Reserved|''0xFC''| | | | | | | |Reserved|''0xFD''| | | | | | | |Reserved|''0xFE''| | | | | | | |Reserved|''0xFF''| | | | | | |