mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #1938 from kwagyeman/kwabena/sensor_full_control
sensors: Add full control.
This commit is contained in:
commit
9b5b2476c4
@ -0,0 +1,81 @@
|
||||
# Sensor Save and Restore Settings
|
||||
#
|
||||
# This example shows off how to save and then restore camera settings
|
||||
# after a sensor reset and/or powerdown.
|
||||
|
||||
import sensor
|
||||
import time
|
||||
|
||||
# Set pixel format to RGB565 (or GRAYSCALE)
|
||||
target_pixformat = sensor.RGB565
|
||||
|
||||
# Set frame size to QVGA (320x240)
|
||||
target_framesize = sensor.QVGA
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(target_pixformat)
|
||||
sensor.set_framesize(target_framesize)
|
||||
|
||||
# Delay 3 seconds to let the camera auto functions run and measure the fps.
|
||||
t = time.ticks_ms()
|
||||
clock = time.clock()
|
||||
fps = 0
|
||||
while time.ticks_diff(time.ticks_ms(), t) < 3000:
|
||||
clock.tick()
|
||||
sensor.snapshot()
|
||||
fps = clock.fps()
|
||||
|
||||
# The sensor should have time now to warm up and adjust to the current environment.
|
||||
# Grab the settings now before turning off the sensor.
|
||||
|
||||
gain = sensor.get_gain_db()
|
||||
exposure = sensor.get_exposure_us()
|
||||
rgb_gain = sensor.get_rgb_gain_db()
|
||||
|
||||
print("Gain == %f db" % gain)
|
||||
print("Exposure == %d us" % exposure)
|
||||
print("RGB Gain == %f db, %f db, %f db" % (rgb_gain[0], rgb_gain[1], rgb_gain[2]))
|
||||
|
||||
print("Powering Off Sensor")
|
||||
sensor.shutdown(True)
|
||||
time.sleep(2)
|
||||
|
||||
# Disable all settling time delays in the sensor driver code. Turning this off WILL result in
|
||||
# corrupted images appearing when modifying settings. However, now you can change sensor settings
|
||||
# in bulk quickly.
|
||||
sensor.disable_delays(True)
|
||||
|
||||
ts = time.ticks_ms()
|
||||
print("Powering On Sensor")
|
||||
sensor.shutdown(False)
|
||||
sensor.reset()
|
||||
|
||||
sensor.set_pixformat(target_pixformat)
|
||||
sensor.set_framesize(target_framesize)
|
||||
|
||||
sensor.set_auto_gain(False, gain_db=gain)
|
||||
sensor.set_auto_exposure(False, exposure_us=exposure)
|
||||
sensor.set_auto_whitebal(False, rgb_gain_db=rgb_gain)
|
||||
|
||||
# You need to delay before calling snapshot as the image coming out of the camera right now is
|
||||
# most likely to be very corrupt. The exact amount of time to delay below is application
|
||||
# dependent. However, you should probably wait for a frame.
|
||||
time.sleep(1.0 / fps)
|
||||
|
||||
print("Restore Delay %d ms" % (time.ticks_ms() - ts))
|
||||
|
||||
gain = sensor.get_gain_db()
|
||||
exposure = sensor.get_exposure_us()
|
||||
rgb_gain = sensor.get_rgb_gain_db()
|
||||
|
||||
print("Gain == %f db" % gain)
|
||||
print("Exposure == %d us" % exposure)
|
||||
print("RGB Gain == %f db, %f db, %f db" % (rgb_gain[0], rgb_gain[1], rgb_gain[2]))
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
# Image should look like it did before save and restore.
|
||||
while True:
|
||||
clock.tick()
|
||||
img = sensor.snapshot()
|
||||
# print(clock.fps())
|
||||
@ -141,6 +141,8 @@ typedef enum {
|
||||
IOCTL_PAUSE_AUTO_FOCUS,
|
||||
IOCTL_RESET_AUTO_FOCUS,
|
||||
IOCTL_WAIT_ON_AUTO_FOCUS,
|
||||
IOCTL_SET_NIGHT_MODE,
|
||||
IOCTL_GET_NIGHT_MODE,
|
||||
IOCTL_LEPTON_GET_WIDTH,
|
||||
IOCTL_LEPTON_GET_HEIGHT,
|
||||
IOCTL_LEPTON_GET_RADIOMETRY,
|
||||
@ -219,9 +221,11 @@ typedef struct _sensor {
|
||||
uint32_t yuv_swap : 1; // Byte-swap 2BPP YUV formats after capture.
|
||||
uint32_t bayer : 3; // Bayer/CFA pattern.
|
||||
uint32_t yuv_order : 1; // YUV/YVU order.
|
||||
uint32_t blc_size : 4; // Number of black level calibration registers.
|
||||
} hw_flags;
|
||||
|
||||
const uint16_t *color_palette; // Color palette used for color lookup.
|
||||
bool disable_delays; // Set to true to disable all sensor settling time delays.
|
||||
bool disable_full_flush; // Turn off default frame buffer flush policy when full.
|
||||
|
||||
vsync_cb_t vsync_callback; // VSYNC callback.
|
||||
@ -265,6 +269,8 @@ typedef struct _sensor {
|
||||
int (*get_exposure_us) (sensor_t *sensor, int *exposure_us);
|
||||
int (*set_auto_whitebal) (sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db);
|
||||
int (*get_rgb_gain_db) (sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db);
|
||||
int (*set_auto_blc) (sensor_t *sensor, int enable, int *regs);
|
||||
int (*get_blc_regs) (sensor_t *sensor, int *regs);
|
||||
int (*set_hmirror) (sensor_t *sensor, int enable);
|
||||
int (*set_vflip) (sensor_t *sensor, int enable);
|
||||
int (*set_special_effect) (sensor_t *sensor, sde_t sde);
|
||||
@ -378,6 +384,12 @@ int sensor_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float
|
||||
// Get the rgb gain values.
|
||||
int sensor_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db);
|
||||
|
||||
// Enable auto blc (black level calibration) or set from previous calibration.
|
||||
int sensor_set_auto_blc(int enable, int *regs);
|
||||
|
||||
// Get black level valibration register values.
|
||||
int sensor_get_blc_regs(int *regs);
|
||||
|
||||
// Enable/disable the hmirror mode.
|
||||
int sensor_set_hmirror(int enable);
|
||||
|
||||
|
||||
@ -583,7 +583,9 @@ __weak int sensor_set_pixformat(pixformat_t pixformat) {
|
||||
return SENSOR_ERROR_CTL_FAILED;
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(100); // wait for the camera to settle
|
||||
if (!sensor.disable_delays) {
|
||||
mp_hal_delay_ms(100); // wait for the camera to settle
|
||||
}
|
||||
|
||||
// Set pixel format
|
||||
sensor.pixformat = pixformat;
|
||||
@ -619,7 +621,9 @@ __weak int sensor_set_framesize(framesize_t framesize) {
|
||||
return SENSOR_ERROR_CTL_FAILED;
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(100); // wait for the camera to settle
|
||||
if (!sensor.disable_delays) {
|
||||
mp_hal_delay_ms(100); // wait for the camera to settle
|
||||
}
|
||||
|
||||
// Set framebuffer size
|
||||
sensor.framesize = framesize;
|
||||
@ -906,6 +910,34 @@ __weak int sensor_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_g
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak int sensor_set_auto_blc(int enable, int *regs) {
|
||||
// Check if the control is supported.
|
||||
if (sensor.set_auto_blc == NULL) {
|
||||
return SENSOR_ERROR_CTL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Call the sensor specific function.
|
||||
if (sensor.set_auto_blc(&sensor, enable, regs) != 0) {
|
||||
return SENSOR_ERROR_CTL_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak int sensor_get_blc_regs(int *regs) {
|
||||
// Check if the control is supported.
|
||||
if (sensor.get_blc_regs == NULL) {
|
||||
return SENSOR_ERROR_CTL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Call the sensor specific function.
|
||||
if (sensor.get_blc_regs(&sensor, regs) != 0) {
|
||||
return SENSOR_ERROR_CTL_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak int sensor_set_hmirror(int enable) {
|
||||
// Check if the value has changed.
|
||||
if (sensor.hmirror == ((bool) enable)) {
|
||||
@ -929,7 +961,9 @@ __weak int sensor_set_hmirror(int enable) {
|
||||
sensor.hmirror = enable;
|
||||
|
||||
// Wait for the camera to settle
|
||||
mp_hal_delay_ms(100);
|
||||
if (!sensor.disable_delays) {
|
||||
mp_hal_delay_ms(100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -961,7 +995,9 @@ __weak int sensor_set_vflip(int enable) {
|
||||
sensor.vflip = enable;
|
||||
|
||||
// Wait for the camera to settle
|
||||
mp_hal_delay_ms(100);
|
||||
if (!sensor.disable_delays) {
|
||||
mp_hal_delay_ms(100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -451,6 +451,48 @@ static mp_obj_t py_sensor_get_rgb_gain_db() {
|
||||
});
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_set_auto_blc(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_enable, ARG_regs };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_enable, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_regs, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
int enable = args[ARG_enable].u_int;
|
||||
int regs[sensor.hw_flags.blc_size];
|
||||
bool regs_present = args[ARG_regs].u_obj != mp_const_none;
|
||||
if (regs_present) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(args[ARG_regs].u_obj, sensor.hw_flags.blc_size, &arg_array);
|
||||
for (uint32_t i = 0; i < sensor.hw_flags.blc_size; i++) {
|
||||
regs[i] = mp_obj_get_int(arg_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int error = sensor_set_auto_blc(enable, regs_present ? regs : NULL);
|
||||
if (error != 0) {
|
||||
sensor_raise_error(error);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_get_blc_regs() {
|
||||
int regs[sensor.hw_flags.blc_size];
|
||||
int error = sensor_get_blc_regs(regs);
|
||||
if (error != 0) {
|
||||
sensor_raise_error(error);
|
||||
}
|
||||
|
||||
mp_obj_list_t *l = mp_obj_new_list(sensor.hw_flags.blc_size, NULL);
|
||||
for (uint32_t i = 0; i < sensor.hw_flags.blc_size; i++) {
|
||||
l->items[i] = mp_obj_new_int(regs[i]);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_set_hmirror(mp_obj_t enable) {
|
||||
int error = sensor_set_hmirror(mp_obj_is_true(enable));
|
||||
if (error != 0) {
|
||||
@ -522,6 +564,15 @@ static mp_obj_t py_sensor_get_framebuffers() {
|
||||
return mp_obj_new_int(framebuffer->n_buffers);
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_disable_delays(uint n_args, const mp_obj_t *args) {
|
||||
if (!n_args) {
|
||||
return mp_obj_new_bool(sensor.disable_delays);
|
||||
}
|
||||
|
||||
sensor.disable_delays = mp_obj_get_int(args[0]);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_disable_full_flush(uint n_args, const mp_obj_t *args) {
|
||||
if (!n_args) {
|
||||
return mp_obj_new_bool(sensor.disable_full_flush);
|
||||
@ -656,6 +707,22 @@ static mp_obj_t py_sensor_ioctl(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
#endif
|
||||
|
||||
case IOCTL_SET_NIGHT_MODE: {
|
||||
if (n_args >= 2) {
|
||||
error = sensor_ioctl(request, mp_obj_get_int(args[1]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_GET_NIGHT_MODE: {
|
||||
int enabled;
|
||||
error = sensor_ioctl(request, &enabled);
|
||||
if (error == 0) {
|
||||
ret_obj = mp_obj_new_bool(enabled);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_LEPTON_GET_WIDTH: {
|
||||
int width;
|
||||
error = sensor_ioctl(request, &width);
|
||||
@ -915,6 +982,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_sensor_set_auto_exposure_obj, 1, py_sensor_
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_exposure_us_obj, py_sensor_get_exposure_us);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_sensor_set_auto_whitebal_obj, 1, py_sensor_set_auto_whitebal);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_rgb_gain_db_obj, py_sensor_get_rgb_gain_db);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_sensor_set_auto_blc_obj, 1, py_sensor_set_auto_blc);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_blc_regs_obj, py_sensor_get_blc_regs);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_hmirror_obj, py_sensor_set_hmirror);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_hmirror_obj, py_sensor_get_hmirror);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_vflip_obj, py_sensor_set_vflip);
|
||||
@ -925,6 +994,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_auto_rotation_obj, py_sensor_se
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_auto_rotation_obj, py_sensor_get_auto_rotation);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_framebuffers_obj, py_sensor_set_framebuffers);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_framebuffers_obj, py_sensor_get_framebuffers);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_sensor_disable_delays_obj, 0, 1, py_sensor_disable_delays);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_sensor_disable_full_flush_obj, 0, 1, py_sensor_disable_full_flush);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_special_effect_obj, py_sensor_set_special_effect);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_sensor_set_lens_correction_obj, py_sensor_set_lens_correction);
|
||||
@ -1028,6 +1098,8 @@ STATIC const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_RESET_AUTO_FOCUS), MP_OBJ_NEW_SMALL_INT(IOCTL_RESET_AUTO_FOCUS)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_WAIT_ON_AUTO_FOCUS), MP_OBJ_NEW_SMALL_INT(IOCTL_WAIT_ON_AUTO_FOCUS)},
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_SET_NIGHT_MODE), MP_OBJ_NEW_SMALL_INT(IOCTL_SET_NIGHT_MODE)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_GET_NIGHT_MODE), MP_OBJ_NEW_SMALL_INT(IOCTL_GET_NIGHT_MODE)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_LEPTON_GET_WIDTH), MP_OBJ_NEW_SMALL_INT(IOCTL_LEPTON_GET_WIDTH)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_LEPTON_GET_HEIGHT), MP_OBJ_NEW_SMALL_INT(IOCTL_LEPTON_GET_HEIGHT)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_LEPTON_GET_RADIOMETRY), MP_OBJ_NEW_SMALL_INT(IOCTL_LEPTON_GET_RADIOMETRY)},
|
||||
@ -1091,6 +1163,8 @@ STATIC const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_exposure_us), (mp_obj_t) &py_sensor_get_exposure_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_auto_whitebal), (mp_obj_t) &py_sensor_set_auto_whitebal_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_rgb_gain_db), (mp_obj_t) &py_sensor_get_rgb_gain_db_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_auto_blc), (mp_obj_t) &py_sensor_set_auto_blc_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_blc_regs), (mp_obj_t) &py_sensor_get_blc_regs_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_hmirror), (mp_obj_t) &py_sensor_set_hmirror_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_hmirror), (mp_obj_t) &py_sensor_get_hmirror_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_vflip), (mp_obj_t) &py_sensor_set_vflip_obj },
|
||||
@ -1101,6 +1175,7 @@ STATIC const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_auto_rotation), (mp_obj_t) &py_sensor_get_auto_rotation_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_framebuffers), (mp_obj_t) &py_sensor_set_framebuffers_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_framebuffers), (mp_obj_t) &py_sensor_get_framebuffers_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_delays), (mp_obj_t) &py_sensor_disable_delays_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_full_flush), (mp_obj_t) &py_sensor_disable_full_flush_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_special_effect), (mp_obj_t) &py_sensor_set_special_effect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_lens_correction), (mp_obj_t) &py_sensor_set_lens_correction_obj },
|
||||
|
||||
@ -55,6 +55,8 @@ void sensor_init0() {
|
||||
omv_i2c_init(&sensor.i2c_bus, sensor.i2c_bus.id, sensor.i2c_bus.speed);
|
||||
}
|
||||
|
||||
sensor.disable_delays = false;
|
||||
|
||||
// Disable VSYNC IRQ and callback
|
||||
sensor_set_vsync_callback(NULL);
|
||||
|
||||
|
||||
@ -521,6 +521,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/,\
|
||||
|
||||
@ -102,6 +102,8 @@ void sensor_init0() {
|
||||
omv_i2c_init(&sensor.i2c_bus, sensor.i2c_bus.id, sensor.i2c_bus.speed);
|
||||
}
|
||||
|
||||
sensor.disable_delays = false;
|
||||
|
||||
// Disable VSYNC IRQ and callback
|
||||
sensor_set_vsync_callback(NULL);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -247,7 +247,9 @@ static int set_colorbar(sensor_t *sensor, int enable) {
|
||||
ret = omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ROW_NOISE_CORR_CONTROL, ®);
|
||||
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ROW_NOISE_CORR_CONTROL,
|
||||
(reg & (~mask)) | ((enable == 0) ? mask : 0));
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
if (!sensor->disable_delays) {
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -259,10 +261,12 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
int ret = omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE, ®);
|
||||
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE,
|
||||
(reg & (~agc_mask)) | ((enable != 0) ? agc_mask : 0));
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
if (!sensor->disable_delays) {
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
}
|
||||
|
||||
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, ®);
|
||||
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, (reg & 0xFF80) | gain);
|
||||
@ -272,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, ®);
|
||||
@ -295,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;
|
||||
}
|
||||
|
||||
@ -309,8 +313,9 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
|
||||
ret |= omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE, ®);
|
||||
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE,
|
||||
(reg & (~aec_mask)) | ((enable != 0) ? aec_mask : 0));
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
|
||||
if (!sensor->disable_delays) {
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
}
|
||||
int read_mode = context ? MT9V0X4_READ_MODE_B : MT9V0XX_READ_MODE;
|
||||
int window_width = context ? MT9V0X4_WINDOW_WIDTH_B : MT9V0XX_WINDOW_WIDTH;
|
||||
int horizontal_blanking = context ? MT9V0X4_HORIZONTAL_BLANKING_B : MT9V0XX_HORIZONTAL_BLANKING;
|
||||
@ -389,7 +394,9 @@ static int set_hmirror(sensor_t *sensor, int enable) {
|
||||
(read_mode & (~MT9V0XX_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V0XX_READ_MODE_COL_FLIP : 0));
|
||||
}
|
||||
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
if (!sensor->disable_delays) {
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -405,7 +412,9 @@ static int set_vflip(sensor_t *sensor, int enable) {
|
||||
(read_mode & (~MT9V0XX_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V0XX_READ_MODE_ROW_FLIP : 0));
|
||||
}
|
||||
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
if (!sensor->disable_delays) {
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -462,7 +471,9 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
|
||||
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL,
|
||||
(chip_control & (~MT9V0XX_CHIP_CONTROL_MODE_MASK))
|
||||
| ((enable != 0) ? MT9V0XX_CHIP_CONTROL_SNAP_MODE : MT9V0XX_CHIP_CONTROL_MASTER_MODE));
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
if (!sensor->disable_delays) {
|
||||
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IOCTL_GET_TRIGGERED_MODE: {
|
||||
|
||||
@ -359,7 +359,9 @@ static int reset(sensor_t *sensor) {
|
||||
}
|
||||
|
||||
// Delay 300 ms
|
||||
mp_hal_delay_ms(300);
|
||||
if (!sensor->disable_delays) {
|
||||
mp_hal_delay_ms(300);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -584,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, ®);
|
||||
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;
|
||||
@ -623,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;
|
||||
}
|
||||
|
||||
@ -705,7 +705,9 @@ static int reset(sensor_t *sensor) {
|
||||
#endif
|
||||
|
||||
// Delay 300 ms
|
||||
mp_hal_delay_ms(300);
|
||||
if (!sensor->disable_delays) {
|
||||
mp_hal_delay_ms(300);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1077,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, ®);
|
||||
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, ®);
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_GAIN_CEILING_H, (reg & 0xFC) | (gain_ceiling >> 8));
|
||||
@ -1099,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;
|
||||
}
|
||||
@ -1173,7 +1175,7 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
|
||||
}
|
||||
|
||||
static int get_exposure_us(sensor_t *sensor, int *exposure_us) {
|
||||
uint8_t spc0, spc1, spc2, spc3, sysrootdiv, aec_0, aec_1, aec_2, hts_h, hts_l;
|
||||
uint8_t spc0, spc1, spc2, spc3, sysrootdiv, aec_0, aec_1, aec_2, hts_h, hts_l, vts_h, vts_l;
|
||||
int ret = 0;
|
||||
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, SC_PLL_CONTRL0, &spc0);
|
||||
@ -1189,8 +1191,14 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us) {
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, TIMING_HTS_H, &hts_h);
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, TIMING_HTS_L, &hts_l);
|
||||
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, TIMING_VTS_H, &vts_h);
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, TIMING_VTS_L, &vts_l);
|
||||
|
||||
uint32_t aec = ((aec_0 << 16) | (aec_1 << 8) | aec_2) >> 4;
|
||||
uint16_t hts = (hts_h << 8) | hts_l;
|
||||
uint16_t vts = (vts_h << 8) | vts_l;
|
||||
|
||||
aec = IM_MIN(aec, vts);
|
||||
|
||||
int pclk_freq = calc_pclk_freq(spc0, spc1, spc2, spc3, sysrootdiv);
|
||||
int clocks_per_us = pclk_freq / 1000000;
|
||||
@ -1207,9 +1215,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);
|
||||
@ -1232,9 +1240,35 @@ 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;
|
||||
}
|
||||
|
||||
static int set_auto_blc(sensor_t *sensor, int enable, int *regs) {
|
||||
uint8_t reg;
|
||||
int ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, BLC_CTRL_00, ®);
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, BLC_CTRL_00, (reg & 0xFE) | (enable != 0));
|
||||
|
||||
if ((enable == 0) && (regs != NULL)) {
|
||||
for (uint32_t i = 0; i < sensor->hw_flags.blc_size; i++) {
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, BLACK_LEVEL_00_H + i, regs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_blc_regs(sensor_t *sensor, int *regs) {
|
||||
int ret = 0;
|
||||
|
||||
for (uint32_t i = 0; i < sensor->hw_flags.blc_size; i++) {
|
||||
uint8_t reg;
|
||||
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, BLACK_LEVEL_00_H + i, ®);
|
||||
regs[i] = reg;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1298,6 +1332,7 @@ static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||
|
||||
static int ioctl(sensor_t *sensor, int request, va_list ap) {
|
||||
int ret = 0;
|
||||
uint8_t reg;
|
||||
|
||||
switch (request) {
|
||||
case IOCTL_SET_READOUT_WINDOW: {
|
||||
@ -1343,7 +1378,6 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
|
||||
case IOCTL_WAIT_ON_AUTO_FOCUS: {
|
||||
mp_uint_t start_tick = mp_hal_ticks_ms(), delay_ms = va_arg(ap, uint32_t);
|
||||
for (;;) {
|
||||
uint8_t reg;
|
||||
ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AF_CMD_ACK, ®);
|
||||
if ((ret < 0) || (!reg)) {
|
||||
break;
|
||||
@ -1356,6 +1390,21 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case IOCTL_SET_NIGHT_MODE: {
|
||||
int enable = va_arg(ap, int);
|
||||
ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_CTRL_00, ®);
|
||||
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_CTRL_00,
|
||||
(reg & 0xFB) | ((enable != 0) << 2));
|
||||
break;
|
||||
}
|
||||
case IOCTL_GET_NIGHT_MODE: {
|
||||
int *enable = va_arg(ap, int *);
|
||||
ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_CTRL_00, ®);
|
||||
if (ret >= 0) {
|
||||
*enable = reg & 0x4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = -1;
|
||||
break;
|
||||
@ -1385,6 +1434,8 @@ int ov5640_init(sensor_t *sensor) {
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_auto_whitebal = set_auto_whitebal;
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_auto_blc = set_auto_blc;
|
||||
sensor->get_blc_regs = get_blc_regs;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->set_special_effect = set_special_effect;
|
||||
@ -1401,6 +1452,7 @@ int ov5640_init(sensor_t *sensor) {
|
||||
sensor->hw_flags.gs_bpp = 1;
|
||||
sensor->hw_flags.rgb_swap = 0;
|
||||
sensor->hw_flags.yuv_order = SENSOR_HW_FLAGS_YVU422;
|
||||
sensor->hw_flags.blc_size = 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -87,9 +87,25 @@
|
||||
#define TIMING_TC_REG_20 0x3820
|
||||
#define TIMING_TC_REG_21 0x3821
|
||||
|
||||
#define AEC_CTRL_00 0x3A00
|
||||
|
||||
#define AEC_GAIN_CEILING_H 0x3A18
|
||||
#define AEC_GAIN_CEILING_L 0x3A18
|
||||
|
||||
#define BLC_CTRL_00 0x4000
|
||||
|
||||
#define BLACK_LEVEL_00_H 0x402C
|
||||
#define BLACK_LEVEL_00_L 0x402D
|
||||
|
||||
#define BLACK_LEVEL_01_H 0x402E
|
||||
#define BLACK_LEVEL_01_L 0x402F
|
||||
|
||||
#define BLACK_LEVEL_10_H 0x4030
|
||||
#define BLACK_LEVEL_10_L 0x4031
|
||||
|
||||
#define BLACK_LEVEL_11_H 0x4032
|
||||
#define BLACK_LEVEL_11_L 0x4033
|
||||
|
||||
#define FORMAT_CONTROL 0x4300
|
||||
|
||||
#define VFIFO_HSIZE_H 0x4602
|
||||
|
||||
@ -336,7 +336,9 @@ static int reset(sensor_t *sensor) {
|
||||
}
|
||||
|
||||
// Delay 300 ms
|
||||
mp_hal_delay_ms(300);
|
||||
if (!sensor->disable_delays) {
|
||||
mp_hal_delay_ms(300);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -196,7 +196,9 @@ static int reset(sensor_t *sensor) {
|
||||
}
|
||||
|
||||
// Delay 300 ms
|
||||
mp_hal_delay_ms(300);
|
||||
if (!sensor->disable_delays) {
|
||||
mp_hal_delay_ms(300);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -379,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, ®);
|
||||
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, ®);
|
||||
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;
|
||||
@ -413,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;
|
||||
}
|
||||
@ -507,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);
|
||||
@ -527,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;
|
||||
}
|
||||
|
||||
@ -163,7 +163,9 @@ static int reset(sensor_t *sensor) {
|
||||
}
|
||||
|
||||
// Delay 300 ms
|
||||
mp_hal_delay_ms(300);
|
||||
if (!sensor->disable_delays) {
|
||||
mp_hal_delay_ms(300);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -346,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, ®);
|
||||
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;
|
||||
@ -384,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;
|
||||
}
|
||||
@ -499,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, ®);
|
||||
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);
|
||||
@ -534,11 +536,37 @@ 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, ®);
|
||||
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;
|
||||
}
|
||||
|
||||
static int set_auto_blc(sensor_t *sensor, int enable, int *regs) {
|
||||
uint8_t reg;
|
||||
int ret = omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM13, ®);
|
||||
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM13, COM13_SET_BLC(reg, (enable != 0)));
|
||||
|
||||
if ((enable == 0) && (regs != NULL)) {
|
||||
for (uint32_t i = 0; i < sensor->hw_flags.blc_size; i++) {
|
||||
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, ADOFF_B + i, regs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_blc_regs(sensor_t *sensor, int *regs) {
|
||||
int ret = 0;
|
||||
|
||||
for (uint32_t i = 0; i < sensor->hw_flags.blc_size; i++) {
|
||||
uint8_t reg;
|
||||
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, ADOFF_B + i, ®);
|
||||
regs[i] = reg;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -590,6 +618,38 @@ static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ioctl(sensor_t *sensor, int request, va_list ap) {
|
||||
int ret = 0;
|
||||
uint8_t reg;
|
||||
|
||||
switch (request) {
|
||||
case IOCTL_SET_NIGHT_MODE: {
|
||||
int enable = va_arg(ap, int);
|
||||
ret = omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM5, ®);
|
||||
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM5, COM5_SET_AFR(reg, (enable != 0)));
|
||||
if (enable == 0) {
|
||||
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, ADVFL, 0);
|
||||
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, ADVFH, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IOCTL_GET_NIGHT_MODE: {
|
||||
int *enable = va_arg(ap, int *);
|
||||
ret = omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM5, ®);
|
||||
if (ret >= 0) {
|
||||
*enable = reg & COM5_AFR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ov7725_init(sensor_t *sensor) {
|
||||
// Initialize sensor structure.
|
||||
sensor->reset = reset;
|
||||
@ -609,10 +669,13 @@ int ov7725_init(sensor_t *sensor) {
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_auto_whitebal = set_auto_whitebal;
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_auto_blc = set_auto_blc;
|
||||
sensor->get_blc_regs = get_blc_regs;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->set_special_effect = set_special_effect;
|
||||
sensor->set_lens_correction = set_lens_correction;
|
||||
sensor->ioctl = ioctl;
|
||||
|
||||
// Set sensor flags
|
||||
sensor->hw_flags.vsync = 1;
|
||||
@ -623,6 +686,7 @@ int ov7725_init(sensor_t *sensor) {
|
||||
sensor->hw_flags.gs_bpp = 2;
|
||||
sensor->hw_flags.rgb_swap = 1;
|
||||
sensor->hw_flags.yuv_order = SENSOR_HW_FLAGS_YVU422;
|
||||
sensor->hw_flags.blc_size = 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
#define COM5_AFR_8x 0x08 /* Add frame when AGC reaches 8x gain */
|
||||
#define COM5_AFR_16x 0x0c /* Add frame when AGC reaches 16x gain */
|
||||
#define COM5_AEC_NO_LIMIT 0x01 /* No limit to AEC increase step */
|
||||
#define COM5_SET_AFR(r, x) ((r & 0x7F) | ((x & 0x1) << 7))
|
||||
|
||||
#define COM6 0x0F /* Common Control 6 */
|
||||
#define COM6_AUTO_WINDOW 0x01 /* Auto window setting ON/OFF selection when format changes */
|
||||
@ -184,6 +185,7 @@
|
||||
#define COM13_ADC_EN 0x40 /* ADC channel BLC ON/OFF control */
|
||||
#define COM13_ANALOG_BLC 0x20 /* Analog processing channel BLC ON/OFF control */
|
||||
#define COM13_ABLC_GAIN_EN 0x04 /* ABLC gain trigger enable */
|
||||
#define COM13_SET_BLC(r, x) ((r & 0x7F) | ((x & 0x1) << 7))
|
||||
|
||||
#define COM14 0x3F /* Common Control 14 */
|
||||
#define COM15 0x40 /* Common Control 15 */
|
||||
|
||||
@ -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, ®);
|
||||
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, ®);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user