====== 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'' DPC done\\ ''0'' 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 ''spi_config_status'' see [[code:code#FPGA config status - SPI codes|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;
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|''0x32''|R/W|:!: ''7:4'' - UVC\\ :!: ''3: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 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|
|:!: Video output pixel bit depth|''0x33''|R/W|:!: ''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|
==== 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 | |
===== 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