From e05aeb04a30778698b05dcef838ddabe3c4b86c8 Mon Sep 17 00:00:00 2001 From: dchvs Date: Wed, 3 Mar 2021 19:57:53 -0600 Subject: [PATCH 1/4] Fix gain & exposure range on DTB --- .../tegra186-tx2-spiri-camera.dtsi | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/hardware/nvidia-spiri/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-tx2-spiri-camera.dtsi b/hardware/nvidia-spiri/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-tx2-spiri-camera.dtsi index 0f5b0f2..8543957 100644 --- a/hardware/nvidia-spiri/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-tx2-spiri-camera.dtsi +++ b/hardware/nvidia-spiri/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-tx2-spiri-camera.dtsi @@ -98,26 +98,25 @@ i2c8 = "/i2c@31e0000"; inherent_gain = "1"; pix_clk_hz = "74250000"; - gain_factor = "1"; + gain_factor = "3125"; framerate_factor = "1000000"; exposure_factor = "1000000"; - min_gain_val = "4"; - max_gain_val = "6476"; + min_gain_val = "100000"; + max_gain_val = "797000"; step_gain_val = "1"; - default_gain = "100"; + default_gain = "100000"; min_hdr_ratio = "1"; max_hdr_ratio = "1"; min_framerate = "2000000"; max_framerate = "60000000"; step_framerate = "1"; - default_framerate = "6000000"; // 60.0 fps + default_framerate = "60000000"; // 60.0 fps - min_exp_time = "23"; // us - max_exp_time = "14933"; // us + min_exp_time = "500"; // us + max_exp_time = "16000"; // us step_exp_time = "1"; - default_exp_time = "10000"; // us - + default_exp_time = "8000"; // us }; ports { #address-cells = <0x1>; @@ -186,25 +185,25 @@ i2c8 = "/i2c@31e0000"; inherent_gain = "1"; pix_clk_hz = "74250000"; - gain_factor = "1"; + gain_factor = "3125"; framerate_factor = "1000000"; exposure_factor = "1000000"; - min_gain_val = "4"; - max_gain_val = "6476"; + min_gain_val = "100000"; + max_gain_val = "797000"; step_gain_val = "1"; - default_gain = "100"; + default_gain = "100000"; min_hdr_ratio = "1"; max_hdr_ratio = "1"; min_framerate = "2000000"; max_framerate = "60000000"; step_framerate = "1"; - default_framerate = "6000000"; // 60.0 fps + default_framerate = "60000000"; // 60.0 fps - min_exp_time = "23"; // us - max_exp_time = "14933"; // us + min_exp_time = "500"; // us + max_exp_time = "16000"; // us step_exp_time = "1"; - default_exp_time = "10000"; // us + default_exp_time = "8000"; // us }; ports { #address-cells = <0x1>; From 897f1f78c152039213437d063a7a855b16c38cfd Mon Sep 17 00:00:00 2001 From: dchvs Date: Thu, 4 Mar 2021 00:34:39 -0600 Subject: [PATCH 2/4] documentation: Update README with AE --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e8689c..19dc4b2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ gst-launch-1.0 nvarguscamerasrc sensor-id=0 aelock=true awblock=true ! 'video/x- ### UDP Streaming Test #### Sender Endpoint ``` -gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)30/1' ! omxh264enc control-rate=2 bitrate=8000000 ! 'video/x-h264, stream-format=(string)byte-stream' ! h264parse ! rtph264pay mtu=1400 ! udpsink host=$HOST_IP port=5000 sync=false async=false +gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)60/1' ! omxh264enc control-rate=2 bitrate=8000000 ! 'video/x-h264, stream-format=(string)byte-stream' ! h264parse ! rtph264pay mtu=1400 ! udpsink host=$HOST_IP port=5000 sync=false async=false ``` #### Receiver Endpoint @@ -71,11 +71,58 @@ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=RG12 - #### Slave ``` -v4l2-ctl -d /dev/video01 --set-fmt-video=width=1280,height=720,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap +v4l2-ctl -d /dev/video1 --set-fmt-video=width=1280,height=720,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap +``` + +### AE Synchronized +First run the master pipeline and then the slave pipeline: + +#### Master Pipeline +``` +gst-launch-1.0 nvarguscamerasrc sensor-id=1 ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)60/1' ! fakesink +``` + +#### Slave Pipeline +``` +gst-launch-1.0 nvarguscamerasrc sensor-id=0 aelock=true awblock=true ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)60/1' ! fakesink +``` + +### Run script +``` +./script_to_control_gain_exposure.sh & ``` ## Appends +#### Auto Exposure + +The AE controls realays in the feedback provided by the Driver's camera sensor to the nvarguscamerasrc libraries, +and the custom DTSIs with the sensor parameters definitions. +As the AE has interdependency with the digital gain. This gain it's and operation on the Driver, and follows this setup: + +```bash + /* + * Digital gain equation: + * + * RANGE: 1x, 7.97x + * GAIN: VAL / STEPS; + * STEPS: 1/32 + * + * SCALE FACTOR = 100.000 + * + * min_gain_val = 100.000 + * max_gain_val = 797.000 + * step_gain_val = 3125 + */ + + MT9M021 sensor datasheet: + * MT9M021 Developer Guide +``` + +Where, the min_gain_val, max_gain_val, step_gain_val are part of the cameras' DTSI (tegra186-tx2-spiri-camera.dtsi) fixed parameters +as per the datasheet. The step_gain_val consists of the steps (1/32 for the register) scaled to a value that makes this fraction become an significant +in integer. + #### Kernel Changes The Driver for the MT9M021 cameras consists on the following structure, that adds the DTB and Kernel sources, along with its Makefiles that lead its portability to a Kernel source. From 4c34506a6a6a391828975564ec4c9406f933bec5 Mon Sep 17 00:00:00 2001 From: dchvs Date: Thu, 4 Mar 2021 00:36:20 -0600 Subject: [PATCH 3/4] Fix gain equation on Driver --- .../nvidia-spiri/drivers/media/i2c/mt9m021.c | 99 ++++++++++--------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/kernel/nvidia-spiri/drivers/media/i2c/mt9m021.c b/kernel/nvidia-spiri/drivers/media/i2c/mt9m021.c index e34291e..33e57c8 100644 --- a/kernel/nvidia-spiri/drivers/media/i2c/mt9m021.c +++ b/kernel/nvidia-spiri/drivers/media/i2c/mt9m021.c @@ -135,8 +135,8 @@ #define MT9M021_ANALOG_GAIN_SHIFT 4 #define MT9M021_ANALOG_GAIN_MASK 0x0030 -#define MT9M021_GLOBAL_GAIN_MIN 4 -#define MT9M021_GLOBAL_GAIN_MAX 6476 +#define MT9M021_GLOBAL_GAIN_MIN 100 +#define MT9M021_GLOBAL_GAIN_MAX 797 #define MT9M021_GLOBAL_GAIN_DEF 100 #define MT9M021_COARSE_INT_TIME_MIN 0x0001 @@ -396,54 +396,59 @@ static int mt9m021_set_gain(struct tegracam_device *tc_dev, s64 val) { struct camera_common_data *s_data = tc_dev->s_data; struct device *dev = tc_dev->dev; - int err = 0; - u16 gain_mul; - u16 reg16 = 0; - u8 integer, fraction; + int err = 0; + u16 gain_mul; + u16 reg16 = 0; + u64 gain = 0; dev_dbg(dev, "Setting Gain to: %lld", val); - if (val >= MT9M021_GAIN_8X_FIXED) { - integer = val / MT9M021_GAIN_8X_FIXED; - fraction = ((val / 8) % 100) * 32 / 100; - gain_mul = MT9M021_GAIN_8X; - } else if (val >= MT9M021_GAIN_4X_FIXED) { - integer = val / MT9M021_GAIN_4X_FIXED; - fraction = ((val / 4) % 100) * 32 / 100; - gain_mul = MT9M021_GAIN_4X; - } else if (val >= MT9M021_GAIN_2X_FIXED) { - integer = val / MT9M021_GAIN_2X_FIXED; - fraction = ((val / 2) % 100) * 32 / 100; - gain_mul = MT9M021_GAIN_2X; - } else { - integer = val / MT9M021_GAIN_1X_FIXED; - fraction = (val % 100) * 32 / 100; - gain_mul = MT9M021_GAIN_1X; - } + if (val >= MT9M021_GAIN_8X_FIXED) { + gain_mul = MT9M021_GAIN_8X; + } else if (val >= MT9M021_GAIN_4X_FIXED) { + gain_mul = MT9M021_GAIN_4X; + } else if (val >= MT9M021_GAIN_2X_FIXED) { + gain_mul = MT9M021_GAIN_2X; + } else { + gain_mul = MT9M021_GAIN_1X; + } - /* Update analog gain multiplier */ - err = mt9m021_read_reg16(s_data, MT9M021_DIGITAL_TEST, ®16); - if (err) - goto exit; - reg16 = - (reg16 & ~MT9M021_ANALOG_GAIN_MASK) | - ((gain_mul << MT9M021_ANALOG_GAIN_SHIFT) & - MT9M021_ANALOG_GAIN_MASK); - err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16); - msleep(10); - if (err) - goto exit; + /* + * Digital gain equation: + * + * RANGE: 1x, 7.97x + * GAIN: VAL / STEPS; + * STEPS: 1/32 + * + * SCALE FACTOR = 100.000 + * + * min_gain_val = 100.000 + * max_gain_val = 797.000 + * step_gain_val = 3125 + */ + gain = val / 3125; + + /* Update analog gain multiplier */ + err = mt9m021_read_reg16(s_data, MT9M021_DIGITAL_TEST, ®16); + if (err) + goto exit; + reg16 = + (reg16 & ~MT9M021_ANALOG_GAIN_MASK) | + ((gain_mul << MT9M021_ANALOG_GAIN_SHIFT) & + MT9M021_ANALOG_GAIN_MASK); + err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16); + msleep(10); + if (err) + goto exit; /* Update global gain */ err = - mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN, - (integer << 5) | fraction); - msleep(10); + mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN, gain); + msleep(10); if (err) goto exit; err = - mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN_CB, - (integer << 5) | fraction); + mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN_CB, gain); if (err) goto exit; @@ -507,7 +512,7 @@ static int mt9m021_set_coarse_time(struct mt9m021 *priv, s64 val) dev_dbg(dev, "Setting Coarse Time to: %lld", val); - err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME, val); + err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME, val); if (err) return err; err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME_CB, val); @@ -524,16 +529,16 @@ static int mt9m021_set_exposure(struct tegracam_device *tc_dev, s64 val) struct mt9m021 *priv = (struct mt9m021 *)tc_dev->priv; struct device *dev = tc_dev->dev; const struct sensor_mode_properties *mode = - &s_data->sensor_props.sensor_modes[s_data->mode]; + &s_data->sensor_props.sensor_modes[s_data->mode]; u64 coarse_time; int err = 0; - dev_dbg(dev, "Setting Exposure Time to: %lld", val); + dev_dbg(dev, "Setting Exposure Time to : %lld", val); - /* Calculate coarse-time */ - coarse_time = mode->signal_properties.pixel_clock.val * - val / mode->image_properties.line_length / - mode->control_properties.exposure_factor; + coarse_time = + val * mode->signal_properties.pixel_clock.val / + mode->image_properties.line_length / + mode->control_properties.exposure_factor; err = mt9m021_set_coarse_time(priv, coarse_time); if (err) From c26468be0299f9618ec40895f1c3c8251c56cbac Mon Sep 17 00:00:00 2001 From: dchvs Date: Thu, 4 Mar 2021 06:22:22 -0600 Subject: [PATCH 4/4] Add script to control AE on sensor-id=0 --- script_to_control_gain_exposure.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100755 script_to_control_gain_exposure.sh diff --git a/script_to_control_gain_exposure.sh b/script_to_control_gain_exposure.sh new file mode 100755 index 0000000..29cc4ad --- /dev/null +++ b/script_to_control_gain_exposure.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +initial_gain=0 +initial_exposure_time=0 + +while true; do sleep 0.5; + # Read center camera controls + echo `v4l2-ctl -d /dev/video1 --get-ctrl=gain --get-ctrl=exposure` > controls + awk '{print $2}' controls > get_control + actual_gain=`cat get_control` + awk '{print $4}' controls > get_control + actual_exposure_time=`cat get_control` + + # Print controls + #echo -e "\n**Center Camera Controls**" + #cat controls + # Remove temp files + rm controls get_control + # Set R/L camera controls manually + if [ $actual_gain -ne $initial_gain ]; then + v4l2-ctl -d /dev/video0 --set-ctrl=gain=$actual_gain + fi + if [ $actual_exposure_time -ne $initial_exposure_time ]; then + v4l2-ctl -d /dev/video0 --set-ctrl=exposure=$actual_exposure_time + fi + # Define new initial value + initial_gain=$actual_gain + initial_exposure_time=$actual_exposure_time +done