Why do you need synchronizing
There are applications of the cameras when precise frame rate is required as there are some applications when several cameras need to have their frames locked - acquired at exactly the same time or with controlled delays between them. It is important for stereo imaging or other multi-camera setups. The following method applies to the Model 353 cameras with 10338 sensor front ends that use Micron 5MPix sensors that allow synchronizing in so called "snapshot" mode.
Snapshot vs. continuous mode with ERS
Most of the CMOS image sensors (including those used in Elphel Model 353 cameras) use so-called Electronic Rolling Shutter (ERS) mode of image acquisition where there are two running "pointers" in the sensor - first erases pixels, second reads out the pixel values accumulated since the first pointer passed. Those pointers scan all the pixels, row by row with the constant delay between them. That delay defines the exposure time and can be as short as a single scan line (about 1/30,000 of a second for the 5MPix sensors), but it happens at different times for different scan lines - the difference between the top and the bottom ones is about 1/15 of a second (that may lead to significant distortions of the fast moving objects (or the camera itself).
Normally such sensors run continuously and the vertical gap between frames can be very small - smaller than the exposure time, because while erase pointer moves across next frame, readout pointer scans the current one, and without significant vertical blanking (gap between frames) the exposure time can be as long as the frame readout time. In some sensors (including the ones used in 10338 sensor front end) it is possible to erase all pixels at once, but end of exposure is always defined by the pixel readout moment, so global erase is only useful with additional mechanical shutter (not available in model 353 cameras) or a special case of the flash light illumination. In most cases to achieve identical exposure for all pixels we have to erase with the rolling pointer.
So what kind of synchronization is possible with the ERS mode? It is possible to start the erase pointer running at arbitrary moment, wait exposure time and then start reading out the frame. Because sensor "does not know" when the trigger will arrive overlapping of the exposure and readout (as in continuous ERS mode) is not possible and the minimal frame period (reverse of the frame rate) is defined is equal to the frame readout time (i.e. 1/15 sec for a full frame of the 5MPix sensor used) plus required exposure time.
External connections on 10353
Camera CPU board 10353 has a high density 30-pin extension board connector J2. Among others it has 12 contacts ts connected directly to the FPGA for general purpose input/output, with appropriate FPGA code any of them can be used as differential pairs. Current FPGA code (v. 3533012, software v.22.214.171.124 ) has all of them defined as single-ended.
These pins (GPIO[11:0]) can be used in several ways. Most basic is direct software control by writing to FPGA registers (and reading one).
Direct software control of GPIO signals
Currently it is possible to read/write FPGA registers with fpcf application using telnet or serial console or phpshell, it will be possible to do that directly from the PHP scripts:
fpcf -r ''<register_address>'' # read FPGA register fpcf -w ''<register_address> <register_data>'' # write data to FPGA register
You should remember that most of the registers (defined in x353.h) are write only, trying to read them will return something different. The fpcf implementation uses ioctl to access those registers that can not return negative values so the MSB is lost.
Regardless of the other settings it is always possible to read all the 12 signals through 12 low bits of the FPGA register 0x70 (higher bits may have non-zero values and should be disregarded here). You may try it with
fpcf -r 70
The result is actual logic level on the pins, "1" for high level (near 3.3V) and "0" for low level (near zero volts), so if the signal is defined as output and set to output "1" it will read "1", unless it is "shorted" to ground or to the output that provides higher current (both are not good as they draw excessive current and can lead to permanent damage of the FPGA).
You may control individually each of the 12 signals by "tri-stating" (Z) it (turning off output, making this pin an input), driving output "0"(0) or driving output "1"(1). It is possible to organize "wired-OR" by connecting several outputs together (usually from different cameras) and connecting them to ground through a resistor. Then alternating outputs between "Z" and "1" (no "0" as "1" and "0" connected together will cause harmful "short circuit") the signal level (that any of the devices can read back) will be "1" if any of the outputs is "1" and "0" if all are "Z". Similarly it is possible to make a "wire-AND" by connecting ("pulling up") the signal with a resistor to power supply rail (3.3V) and alternating outputs between "0" and "Z".
Control of the outputs is achieved by writing a pair of bits for each output pin to register 0x70. Each bit pair is defined as following:
|0||No change to this output state|
|1||Set output to "0" (drive to ground)|
|2||Set output to "1" (drive to +3.3V)|
|3||Set output to "Z" ("tristate", disconnect)|
The value "0" is needed for convenience - it is write only register and it is not possible to read the current output setting w/o storing that information elsewhere, setting currently unused bits to 0 allows program to modify only selected signals w/o modifying the others.
|0..1||Output control for GPIO|
|2..3||Output control for GPIO|
|4..5||Output control for GPIO|
|6..7||Output control for GPIO|
|8..9||Output control for GPIO|
|10..11||Output control for GPIO|
|12..13||Output control for GPIO|
|14..15||Output control for GPIO|
|16..17||Output control for GPIO|
|18..19||Output control for GPIO|
|20..21||Output control for GPIO|
|22..23||Output control for GPIO|
|24..25||Enable GPIO software control (enabled at poweup)|
|26..27||Enable GPIO control from internal FPGA source A (camsync module) - (disabled at poweup)|
|28..29||Enable GPIO control from internal FPGA source B (reserved) - (disabled at poweup)|
|30..31||Enable GPIO control from internal FPGA source C (reserved) - (disabled at poweup)|
Bits 24..31 control source for the GPIO pins (outputs) - it can be software write to FPGA register 0x70 described here or one of 3 other data sources inside FPGA. Data source A is used for camsync module described here, 2 others are reserved for future applications. The data sources have different priorities, so (C higher than B higher than A higher than software), so if several sources are enabled and try to drive the same output, the one with higher priority takes control.
Each of these higher bit pairs control the data source in the following way:
|0,1||No change to this data sourcce status|
|2||Disable this data source|
|3||Enable this data source|
Examples of the direct software control of GPIO signals
fpcf -w 70 ffffff # disable all 12 outputs fpcf -w 70 9 # set GPIO to drive "1", set GPIO to drive "0", don't change other bits fpcf -w 70 c000000 # enable data source A (camsync)
Module camsync.v implements the following functions:
- Generation of a a single or repetitive trigger output;
- Routing of the trigger output to selected GPIO pins
- Routing of the trigger output to the same camera sensor without usage of the GPIO pins;
- Generating input trigger condition by monitoring all GPIO pins and comparing their selected subset to the specified value
- Filtering out the "noise" on the input trigger signal
- Delaying input trigger signal by a specified number of clock pulses
- Generating trigger signal to the sensor
- routing sensor trigger and trigger delay signals to GPIO and GPIO respectively if "test mode" is selected.
to be continued ...--Andrey.filippov 03:36, 21 October 2007 (CDT)