sensors: Fix gain calculation math accuracy.

This commit is contained in:
Kwabena W. Agyeman 2023-09-26 16:56:38 -07:00
parent 53d69d3473
commit 74ff2d28f4
11 changed files with 68 additions and 67 deletions

View File

@ -518,6 +518,7 @@ endif
ifeq ($(OMV_ENABLE_UVC), 1)
UVC = uvc
# UVC object files
UVC_OBJ += $(BUILD)/$(MICROPY_DIR)/lib/libm/math.o
UVC_OBJ += $(wildcard $(BUILD)/$(UVC_DIR)/src/*.o)
UVC_OBJ += $(wildcard $(BUILD)/$(HAL_DIR)/src/*.o)
UVC_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/,\

View File

@ -342,13 +342,13 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
int ret = 0;
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
gain_db = IM_MAX(IM_MIN(gain_db, 24.0f), 0.0f);
int gain = fast_ceilf(fast_log2(fast_expf((gain_db / 20.0f) * fast_log(10.0f))));
int gain = fast_ceilf(logf(expf((gain_db / 20.0f) * M_LN10)) / M_LN2);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, 0); // Must disable AE
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, ANALOG_GAIN, ((gain & 0x7) << 4));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, GRP_PARAM_HOLD, 0x01);
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
gain_db_ceiling = IM_MAX(IM_MIN(gain_db_ceiling, 24.0f), 0.0f);
int gain = fast_ceilf(fast_log2(fast_expf((gain_db_ceiling / 20.0f) * fast_log(10.0f))));
int gain = fast_ceilf(logf(expf((gain_db_ceiling / 20.0f) * M_LN10) / M_LN2));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, MAX_AGAIN_FULL, (gain & 0x7));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, MAX_AGAIN_BIN2, (gain & 0x7));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, 1);
@ -361,7 +361,7 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
if (omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, ANALOG_GAIN, &gain) != 0) {
return -1;
}
*gain_db = fast_floorf(fast_log(1 << (gain >> 4)) / fast_log(10.0f) * 20.0f);
*gain_db = fast_floorf(log10f(1 << (gain >> 4)) * 20.0f);
return 0;
}

View File

@ -537,12 +537,12 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
int ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, &ae_ctrl);
if (!enable && (!isnanf(gain_db)) && (!isinff(gain_db))) {
gain_db = IM_MAX(IM_MIN(gain_db, 24.0f), 0.0f);
uint8_t gain = fast_ceilf(fast_log2(fast_expf((gain_db / 20.0f) * fast_log(10.0f))));
uint8_t gain = fast_ceilf(logf(expf((gain_db / 20.0f) * M_LN10)) / M_LN2);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, (ae_ctrl & 0xFE));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, ANALOG_GAIN, ((gain & 0x7) << 4));
} else if (enable && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
gain_db_ceiling = IM_MAX(IM_MIN(gain_db_ceiling, 24.0f), 0.0f);
uint8_t gain = fast_ceilf(fast_log2(fast_expf((gain_db_ceiling / 20.0f) * fast_log(10.0f))));
uint8_t gain = fast_ceilf(logf(expf((gain_db_ceiling / 20.0f) * M_LN10)) / M_LN2);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, MAX_AGAIN, (gain & 0x07));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, (ae_ctrl | 0x01));
}
@ -555,7 +555,7 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
if (omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, ANALOG_GAIN, &gain) != 0) {
return -1;
}
*gain_db = fast_floorf(fast_log(1 << (gain >> 4)) / fast_log(10.0f) * 20.0f);
*gain_db = fast_floorf(log10f(1 << (gain >> 4)) * 20.0f);
return 0;
}

View File

@ -785,7 +785,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
}
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.f) * fast_log(10.f)) * 32.f, 0xffff), 0x0000);
int gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10) * 32.0f, 0xffff), 0x0000);
if (omv_i2c_writew2(&sensor->i2c_bus, sensor->slv_addr, MT9M114_REG_UVC_GAIN_CONTROL, gain) != 0) {
return -1;
@ -802,7 +802,7 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
return -1;
}
*gain_db = 20.f * (fast_log(gain / 32.f) / fast_log(10.f));
*gain_db = 20.0f * log10f(gain / 32.0f);
return 0;
}

View File

@ -266,7 +266,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
}
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db / 20.0f) * fast_log(10.0f)) * 16.0f), 64), 16);
int gain = IM_MAX(IM_MIN(fast_roundf(expf((gain_db / 20.0f) * M_LN10) * 16.0f), 64), 16);
ret |= omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, &reg);
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, (reg & 0xFF80) | gain);
@ -276,7 +276,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0X4_ANALOG_GAIN_B, (reg & 0xFF80) | gain);
}
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db_ceiling / 20.0f) * fast_log(10.0f)) * 16.0f), 64), 16);
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(expf((gain_db_ceiling / 20.0f) * M_LN10) * 16.0f), 64), 16);
int max_gain = (is_mt9v0x4(sensor)) ? MT9V0X4_MAX_GAIN : MT9V0X2_MAX_GAIN;
ret |= omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, max_gain, &reg);
@ -299,7 +299,7 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
ret |= omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, analog_gain, &gain);
}
*gain_db = 20.0 * (fast_log((gain & 0x7F) / 16.0f) / fast_log(10.0f));
*gain_db = 20.0f * log10f((gain & 0x7F) / 16.0f);
return ret;
}

View File

@ -586,20 +586,20 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM8, (reg & (~COM8_AGC_EN)) | ((enable != 0) ? COM8_AGC_EN : 0));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 1.0);
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 32.0f), 1.0f);
int gain_temp = fast_roundf(fast_log2(IM_MAX(gain / 2.0, 1.0)));
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0xF >> (4 - gain_temp);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0f) * 16.0f), 15);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 128.0f), 2.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM9, &reg);
ret |=
omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM9,
(reg & 0x1F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 5));
(reg & 0x1F) | ((fast_ceilf(logf(gain_ceiling) / M_LN2) - 1) << 5));
}
return ret;
@ -625,8 +625,8 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
// DISABLED
int hi_gain = 1 << (((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1));
float lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0);
*gain_db = 20.0 * (fast_log(hi_gain * lo_gain) / fast_log(10.0));
float lo_gain = 1.0f + (((gain >> 0) & 0xF) / 16.0f);
*gain_db = 20.0f * log10f(hi_gain * lo_gain);
return ret;
}

View File

@ -1079,13 +1079,13 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_MANUAL, (reg & 0xFD) | ((enable == 0) << 1));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)) * 16.0, 1023), 0);
int gain = IM_MAX(IM_MIN(fast_roundf(expf((gain_db / 20.0f) * M_LN10) * 16.0f), 1023), 0);
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_H, &reg);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_H, (reg & 0xFC) | (gain >> 8));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_L, gain);
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
int gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)) * 16.0, 1023), 0);
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(expf((gain_db_ceiling / 20.0f) * M_LN10) * 16.0f), 1023), 0);
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_GAIN_CEILING_H, &reg);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_GAIN_CEILING_H, (reg & 0xFC) | (gain_ceiling >> 8));
@ -1101,7 +1101,7 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
int ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_H, &gainh);
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_L, &gainl);
*gain_db = 20.0 * (fast_log((((gainh & 0x3) << 8) | gainl) / 16.0) / fast_log(10.0));
*gain_db = 20.0f * log10f((((gainh & 0x3) << 8) | gainl) / 16.0f);
return ret;
}
@ -1209,9 +1209,9 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
int r_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((r_gain_db / 20.0) * fast_log(10.0))), 4095), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((g_gain_db / 20.0) * fast_log(10.0))), 4095), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((b_gain_db / 20.0) * fast_log(10.0))), 4095), 0);
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10)), 4095), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10)), 4095), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10)), 4095), 0);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AWB_R_GAIN_H, r_gain >> 8);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AWB_R_GAIN_L, r_gain);
@ -1234,9 +1234,9 @@ static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db,
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AWB_B_GAIN_H, &blueh);
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AWB_B_GAIN_L, &bluel);
*r_gain_db = 20.0 * (fast_log(((redh & 0xF) << 8) | redl) / fast_log(10.0));
*g_gain_db = 20.0 * (fast_log(((greenh & 0xF) << 8) | greenl) / fast_log(10.0));
*b_gain_db = 20.0 * (fast_log(((blueh & 0xF) << 8) | bluel) / fast_log(10.0));
*r_gain_db = 20.0f * log10f(((redh & 0xF) << 8) | redl);
*g_gain_db = 20.0f * log10f(((greenh & 0xF) << 8) | greenl);
*b_gain_db = 20.0f * log10f(((blueh & 0xF) << 8) | bluel);
return ret;
}

View File

@ -381,24 +381,24 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG13, (reg & 0xFB) | ((enable != 0) << 2));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 128.0), 1.0);
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 128.0f), 1.0f);
int gain_temp = fast_roundf(fast_log2(IM_MAX(gain / 2.0, 1.0)));
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0x3F >> (6 - gain_temp);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0f) * 16.0f), 15);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG15, &reg);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG15, (reg & 0xFC) | (gain_hi >> 4));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 128.0f), 2.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG14, &reg);
ret |=
omv_i2c_writeb(&sensor->i2c_bus,
sensor->slv_addr,
REG14,
(reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
(reg & 0x8F) | ((fast_ceilf(logf(gain_ceiling) / M_LN2) - 1) << 4));
}
return ret;
@ -415,8 +415,8 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
(((reg15 >>
1) & 1) +
((reg15 >> 0) & 1) + ((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1));
float lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0);
*gain_db = 20.0 * (fast_log(hi_gain * lo_gain) / fast_log(10.0));
float lo_gain = 1.0f + (((gain >> 0) & 0xF) / 16.0f);
*gain_db = 20.0f * log10f(hi_gain * lo_gain);
return ret;
}
@ -509,9 +509,9 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
int r_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((r_gain_db / 20.0) * fast_log(10.0))), 255), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((g_gain_db / 20.0) * fast_log(10.0))), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((b_gain_db / 20.0) * fast_log(10.0))), 255), 0);
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10)), 255), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10)), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10)), 255), 0);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, BGAIN, b_gain);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, RGAIN, r_gain);
@ -529,9 +529,9 @@ static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db,
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, RGAIN, &red);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, GGAIN, &green);
*r_gain_db = 20.0 * (fast_log(red) / fast_log(10.0));
*g_gain_db = 20.0 * (fast_log(green) / fast_log(10.0));
*b_gain_db = 20.0 * (fast_log(blue) / fast_log(10.0));
*r_gain_db = 20.0f * log10f(red);
*g_gain_db = 20.0f * log10f(green);
*b_gain_db = 20.0f * log10f(blue);
return ret;
}

View File

@ -348,20 +348,20 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM8, COM8_SET_AGC(reg, (enable != 0)));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 1.0);
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 32.0f), 1.0f);
int gain_temp = fast_roundf(fast_log2(IM_MAX(gain / 2.0, 1.0)));
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0xF >> (4 - gain_temp);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0f) * 16.0f), 15);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 32.0), 2.0);
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 32.0f), 2.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM9, &reg);
ret |=
omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM9,
(reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
(reg & 0x8F) | ((fast_ceilf(logf(gain_ceiling) / M_LN2) - 1) << 4));
}
return ret;
@ -386,8 +386,8 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
// DISABLED
int hi_gain = 1 << (((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1));
float lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0);
*gain_db = 20.0 * (fast_log(hi_gain * lo_gain) / fast_log(10.0));
float lo_gain = 1.0f + (((gain >> 0) & 0xF) / 16.0f);
*gain_db = 20.0f * log10f(hi_gain * lo_gain);
return ret;
}
@ -501,11 +501,11 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, AWB_CTRL1, &reg);
float gain_div = (reg & 0x2) ? 64.0 : 128.0;
float gain_div = (reg & 0x2) ? 64.0f : 128.0f;
int r_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((r_gain_db / 20.0) * fast_log(10.0)) * gain_div), 255), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((g_gain_db / 20.0) * fast_log(10.0)) * gain_div), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((b_gain_db / 20.0) * fast_log(10.0)) * gain_div), 255), 0);
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10) * gain_div), 255), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10) * gain_div), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10) * gain_div), 255), 0);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, BLUE, b_gain);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, RED, r_gain);
@ -536,11 +536,11 @@ static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db,
// DISABLED
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, AWB_CTRL1, &reg);
float gain_div = (reg & 0x2) ? 64.0 : 128.0;
float gain_div = (reg & 0x2) ? 64.0f : 128.0f;
*r_gain_db = 20.0 * (fast_log(red / gain_div) / fast_log(10.0));
*g_gain_db = 20.0 * (fast_log(green / gain_div) / fast_log(10.0));
*b_gain_db = 20.0 * (fast_log(blue / gain_div) / fast_log(10.0));
*r_gain_db = 20.0f * log10f(red / gain_div);
*g_gain_db = 20.0f * log10f(green / gain_div);
*b_gain_db = 20.0f * log10f(blue / gain_div);
return ret;
}

View File

@ -331,22 +331,22 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
(reg & (~REG_COM8_AGC)) | ((enable != 0) ? REG_COM8_AGC : 0));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinf(gain_db))) {
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 128.0), 1.0);
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 128.0f), 1.0f);
int gain_temp = fast_roundf(fast_log2(IM_MAX(gain / 2.0, 1.0)));
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0x3F >> (6 - gain_temp);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15);
int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0f) * 16.0f), 15);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_GAIN, ((gain_hi & 0x0F) << 4) | (gain_lo << 0));
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG_VREF, &reg);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinf(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 128.0f), 2.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG_COM9, &reg);
ret |=
omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_COM9,
(reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
(reg & 0x8F) | ((fast_ceilf(logf(gain_ceiling) / M_LN2) - 1) << 4));
}
return ret;
@ -376,8 +376,8 @@ static int get_gain_db(sensor_t *sensor, float *gain_db) {
(((gain >>
9) & 1) +
((gain >> 8) & 1) + ((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1));
float lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0);
*gain_db = 20.0 * (fast_log(hi_gain * lo_gain) / fast_log(10.0));
float lo_gain = 1.0f + (((gain >> 0) & 0xF) / 16.0f);
*gain_db = 20.0f * log10f(hi_gain * lo_gain);
return ret;
}
@ -486,8 +486,8 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
int r_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((r_gain_db / 20.0) * fast_log(10.0)) * 128.0), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((b_gain_db / 20.0) * fast_log(10.0)) * 128.0), 255), 0);
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10) * 128.0f), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10) * 128.0f), 255), 0);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_BLUE, b_gain);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_RED, r_gain);
@ -515,8 +515,8 @@ static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db,
// }
// DISABLED
*r_gain_db = 20.0 * (fast_log(red / 128.0) / fast_log(10.0));
*b_gain_db = 20.0 * (fast_log(blue / 128.0) / fast_log(10.0));
*r_gain_db = 20.0f * log10f(red / 128.0f);
*b_gain_db = 20.0f * log10f(blue / 128.0f);
return ret;
}

View File

@ -314,7 +314,7 @@ static void auto_exposure(sensor_t *sensor) {
gain_target = 8;
}
//gain_target = IM_MIN(IM_MAX(fast_ceilf(GEP_target/expo_target), R_AE_MinGain), R_AE_MaxGain);
gain_db = 20 * (fast_log((float) gain_target) / fast_log(10.0));
gain_db = 20 * log10f((float) gain_target);
expo_target = IM_MIN(IM_MAX(fast_roundf(GEP_target / gain_target), R_AE_MinExpoTime), R_AE_MaxExpoTime);
#ifdef DEBUG_AE
printf("Gain Target: %ld (%d DB (x1000))\n", gain_target, (int) (gain_db * 1000));