diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index 9bdd71b5d7..544d653676 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -61,39 +61,48 @@ const float DC_GAIN_OX03C10 = 7.32; const float DC_GAIN_ON_GREY_AR0231= 0.2; const float DC_GAIN_OFF_GREY_AR0231 = 0.3; -const float DC_GAIN_ON_GREY_OX03C10= 0.3; -const float DC_GAIN_OFF_GREY_OX03C10 = 0.375; +const float DC_GAIN_ON_GREY_OX03C10= 0.25; +const float DC_GAIN_OFF_GREY_OX03C10 = 0.35; -const int DC_GAIN_MIN_WEIGHT = 0; +const int DC_GAIN_MIN_WEIGHT_AR0231 = 0; const int DC_GAIN_MAX_WEIGHT_AR0231 = 1; +const int DC_GAIN_MIN_WEIGHT_OX03C10 = 16; const int DC_GAIN_MAX_WEIGHT_OX03C10 = 32; +const float TARGET_GREY_FACTOR_AR0231 = 1.0; +const float TARGET_GREY_FACTOR_OX03C10 = 0.02; + const float sensor_analog_gains_AR0231[] = { 1.0/8.0, 2.0/8.0, 2.0/7.0, 3.0/7.0, // 0, 1, 2, 3 3.0/6.0, 4.0/6.0, 4.0/5.0, 5.0/5.0, // 4, 5, 6, 7 5.0/4.0, 6.0/4.0, 6.0/3.0, 7.0/3.0, // 8, 9, 10, 11 7.0/2.0, 8.0/2.0, 8.0/1.0}; // 12, 13, 14, 15 = bypass -// similar gain curve to AR const float sensor_analog_gains_OX03C10[] = { - 1.0, 1.25, 1.3125, 1.5625, - 1.6875, 2.0, 2.25, 2.625, - 3.125, 3.625, 4.5, 5.0, - 7.25, 8.5, 12.0, 15.5}; + 1.0, 1.125, 1.25, 1.3125, 1.5625, + 1.6875, 2.0, 2.25, 2.625, 3.125, + 3.625, 4.0, 4.5, 5.0, 5.5, + 6.0, 6.5, 7.0, 7.5, 8.0, + 8.5, 9.0, 9.5, 10.0, 10.5, + 11.0, 11.5, 12.0, 12.5, 13.0, + 13.5, 14.0, 14.5, 15.0, 15.5}; const uint32_t ox03c10_analog_gains_reg[] = { - 0x100, 0x140, 0x150, 0x190, - 0x1B0, 0x200, 0x240, 0x2A0, - 0x320, 0x3A0, 0x480, 0x500, - 0x740, 0x880, 0xC00, 0xF80}; + 0x100, 0x120, 0x140, 0x150, 0x190, + 0x1B0, 0x200, 0x240, 0x2A0, 0x320, + 0x3A0, 0x400, 0x480, 0x500, 0x580, + 0x600, 0x680, 0x700, 0x780, 0x800, + 0x880, 0x900, 0x980, 0xA00, 0xA80, + 0xB00, 0xB80, 0xC00, 0xC80, 0xD00, + 0xD80, 0xE00, 0xE80, 0xF00, 0xF80}; const int ANALOG_GAIN_MIN_IDX_AR0231 = 0x1; // 0.25x const int ANALOG_GAIN_REC_IDX_AR0231 = 0x6; // 0.8x const int ANALOG_GAIN_MAX_IDX_AR0231 = 0xD; // 4.0x const int ANALOG_GAIN_MIN_IDX_OX03C10 = 0x0; -const int ANALOG_GAIN_REC_IDX_OX03C10 = 0x5; // 2x -const int ANALOG_GAIN_MAX_IDX_OX03C10 = 0xF; +const int ANALOG_GAIN_REC_IDX_OX03C10 = 0x6; // 2x +const int ANALOG_GAIN_MAX_IDX_OX03C10 = 0x22; const int EXPOSURE_TIME_MIN_AR0231 = 2; // with HDR, fastest ss const int EXPOSURE_TIME_MAX_AR0231 = 0x0855; // with HDR, slowest ss, 40ms @@ -517,6 +526,7 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) { void CameraState::camera_set_parameters() { if (camera_id == CAMERA_ID_AR0231) { dc_gain_factor = DC_GAIN_AR0231; + dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_AR0231; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_AR0231; dc_gain_on_grey = DC_GAIN_ON_GREY_AR0231; dc_gain_off_grey = DC_GAIN_OFF_GREY_AR0231; @@ -529,8 +539,10 @@ void CameraState::camera_set_parameters() { sensor_analog_gains[i] = sensor_analog_gains_AR0231[i]; } min_ev = exposure_time_min * sensor_analog_gains[analog_gain_min_idx]; + target_grey_factor = TARGET_GREY_FACTOR_AR0231; } else if (camera_id == CAMERA_ID_OX03C10) { dc_gain_factor = DC_GAIN_OX03C10; + dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_OX03C10; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_OX03C10; dc_gain_on_grey = DC_GAIN_ON_GREY_OX03C10; dc_gain_off_grey = DC_GAIN_OFF_GREY_OX03C10; @@ -543,6 +555,7 @@ void CameraState::camera_set_parameters() { sensor_analog_gains[i] = sensor_analog_gains_OX03C10[i]; } min_ev = (exposure_time_min + VS_TIME_MIN_OX03C10) * sensor_analog_gains[analog_gain_min_idx]; + target_grey_factor = TARGET_GREY_FACTOR_OX03C10; } else { assert(false); } @@ -551,7 +564,7 @@ void CameraState::camera_set_parameters() { target_grey_fraction = 0.3; dc_gain_enabled = false; - dc_gain_weight = DC_GAIN_MIN_WEIGHT; + dc_gain_weight = dc_gain_min_weight; gain_idx = analog_gain_rec_idx; exposure_time = 5; cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight) * sensor_analog_gains[gain_idx] * exposure_time; @@ -1037,7 +1050,7 @@ void CameraState::set_camera_exposure(float grey_frac) { const float cur_ev_ = cur_ev[buf.cur_frame_data.frame_id % 3]; // Scale target grey between 0.1 and 0.4 depending on lighting conditions - float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + cur_ev_) / log2(6000.0), 0.1, 0.4); + float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + target_grey_factor*cur_ev_) / log2(6000.0), 0.1, 0.4); float target_grey = (1.0 - k_grey) * target_grey_fraction + k_grey * new_target_grey; float desired_ev = std::clamp(cur_ev_ * target_grey / grey_frac, min_ev, max_ev); @@ -1053,14 +1066,14 @@ void CameraState::set_camera_exposure(float grey_frac) { bool enable_dc_gain = dc_gain_enabled; if (!enable_dc_gain && target_grey < dc_gain_on_grey) { enable_dc_gain = true; - dc_gain_weight = DC_GAIN_MIN_WEIGHT; + dc_gain_weight = dc_gain_min_weight; } else if (enable_dc_gain && target_grey > dc_gain_off_grey) { enable_dc_gain = false; dc_gain_weight = dc_gain_max_weight; } if (enable_dc_gain && dc_gain_weight < dc_gain_max_weight) {dc_gain_weight += 1;} - if (!enable_dc_gain && dc_gain_weight > DC_GAIN_MIN_WEIGHT) {dc_gain_weight -= 1;} + if (!enable_dc_gain && dc_gain_weight > dc_gain_min_weight) {dc_gain_weight -= 1;} std::string gain_bytes, time_bytes; if (env_ctrl_exp_from_params) { @@ -1145,10 +1158,12 @@ void CameraState::set_camera_exposure(float grey_frac) { // t_HCG + t_LCG + t_VS on LPD, t_SPD on SPD uint32_t hcg_time = std::max((dc_gain_weight * exposure_time / dc_gain_max_weight), 0); uint32_t lcg_time = std::max(((dc_gain_max_weight - dc_gain_weight) * exposure_time / dc_gain_max_weight), 0); - uint32_t spd_time = std::max(hcg_time / 16, (uint32_t)exposure_time_min); - uint32_t vs_time = std::min(std::max(hcg_time / 64, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); + // uint32_t spd_time = std::max(hcg_time / 16, (uint32_t)exposure_time_min); + uint32_t vs_time = std::min(std::max((uint32_t)exposure_time / 128, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); + uint32_t spd_time = vs_time; uint32_t real_gain = ox03c10_analog_gains_reg[new_g]; + uint32_t min_gain = ox03c10_analog_gains_reg[0]; struct i2c_random_wr_payload exp_reg_array[] = { {0x3501, hcg_time>>8}, {0x3502, hcg_time&0xFF}, @@ -1157,9 +1172,9 @@ void CameraState::set_camera_exposure(float grey_frac) { {0x35c1, vs_time>>8}, {0x35c2, vs_time&0xFF}, {0x3508, real_gain>>8}, {0x3509, real_gain&0xFF}, - {0x3588, real_gain>>8}, {0x3589, real_gain&0xFF}, - {0x3548, real_gain>>8}, {0x3549, real_gain&0xFF}, - {0x35c8, real_gain>>8}, {0x35c9, real_gain&0xFF}, + {0x3588, min_gain>>8}, {0x3589, min_gain&0xFF}, + {0x3548, min_gain>>8}, {0x3549, min_gain&0xFF}, + {0x35c8, min_gain>>8}, {0x35c9, min_gain&0xFF}, }; sensors_i2c(exp_reg_array, sizeof(exp_reg_array)/sizeof(struct i2c_random_wr_payload), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false); } diff --git a/system/camerad/cameras/camera_qcom2.h b/system/camerad/cameras/camera_qcom2.h index 1b792e7e96..5023c82458 100644 --- a/system/camerad/cameras/camera_qcom2.h +++ b/system/camerad/cameras/camera_qcom2.h @@ -31,11 +31,12 @@ public: int exposure_time_max; float dc_gain_factor; + int dc_gain_min_weight; int dc_gain_max_weight; float dc_gain_on_grey; float dc_gain_off_grey; - float sensor_analog_gains[16]; + float sensor_analog_gains[35]; int analog_gain_min_idx; int analog_gain_max_idx; int analog_gain_rec_idx; @@ -45,6 +46,7 @@ public: float measured_grey_fraction; float target_grey_fraction; + float target_grey_factor; unique_fd sensor_fd; unique_fd csiphy_fd; diff --git a/system/camerad/cameras/sensor2_i2c.h b/system/camerad/cameras/sensor2_i2c.h index 9df99552e1..209e2d76d2 100644 --- a/system/camerad/cameras/sensor2_i2c.h +++ b/system/camerad/cameras/sensor2_i2c.h @@ -129,13 +129,13 @@ struct i2c_random_wr_payload init_array_ox03c10[] = { {0x350a, 0x04}, {0x350b, 0x00}, {0x350c, 0x00}, // hcg digital gain {0x3586, 0x40}, {0x3587, 0x00}, // lcg fine exposure - {0x358a, 0x04}, {0x358b, 0x00}, {0x358c, 0x00}, // lcg digital gain + {0x358a, 0x01}, {0x358b, 0x00}, {0x358c, 0x00}, // lcg digital gain {0x3546, 0x20}, {0x3547, 0x00}, // spd fine exposure - {0x354a, 0x04}, {0x354b, 0x00}, {0x354c, 0x00}, // spd digital gain + {0x354a, 0x01}, {0x354b, 0x00}, {0x354c, 0x00}, // spd digital gain {0x35c6, 0xb0}, {0x35c7, 0x00}, // vs fine exposure - {0x35ca, 0x04}, {0x35cb, 0x00}, {0x35cc, 0x00}, // vs digital gain + {0x35ca, 0x01}, {0x35cb, 0x00}, {0x35cc, 0x00}, // vs digital gain // also RSVD {0x3600, 0x8f}, {0x3605, 0x16}, {0x3609, 0xf0}, {0x360a, 0x01},