diff --git a/src/omv/mt9v034.c b/src/omv/mt9v034.c index 4c69ed80a..30bb46f25 100644 --- a/src/omv/mt9v034.c +++ b/src/omv/mt9v034.c @@ -210,12 +210,12 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain ret |= cambus_writew(sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, (reg & (~MT9V034_AGC_ENABLE)) | ((enable != 0) ? MT9V034_AGC_ENABLE : 0)); - if ((enable == 0) && (gain_db >= 0)) { + if ((enable == 0) && (!isnanf(gain_db))) { int gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db / 20.0) * fast_log(10.0)) * 16.0), 127), 0); ret |= cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, ®); ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, (reg & 0xFF80) | gain); - } else if ((enable != 0) && (gain_db_ceiling >= 0)) { + } else if ((enable != 0) && (!isnanf(gain_db_ceiling))) { int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)) * 16.0), 127), 16); ret |= cambus_readw(sensor->slv_addr, MT9V034_MAX_GAIN, ®); @@ -273,7 +273,12 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us) return ret; } -static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain) +static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db) +{ + return 0; +} + +static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db) { return 0; } @@ -329,6 +334,7 @@ int mt9v034_init(sensor_t *sensor) sensor->set_auto_exposure = set_auto_exposure; 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_hmirror = set_hmirror; sensor->set_vflip = set_vflip; sensor->set_special_effect = set_special_effect; diff --git a/src/omv/ov2640.c b/src/omv/ov2640.c index 31c75d757..e187f6634 100644 --- a/src/omv/ov2640.c +++ b/src/omv/ov2640.c @@ -610,7 +610,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain ret |= cambus_readb(sensor->slv_addr, COM8, ®); ret |= cambus_writeb(sensor->slv_addr, COM8, (reg & (~COM8_AGC_EN)) | ((enable != 0) ? COM8_AGC_EN : 0)); - if ((enable == 0) && (gain_db >= 0)) { + if ((enable == 0) && (!isnanf(gain_db))) { float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 0.0); int gain_hi = 15; @@ -624,7 +624,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain } ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0)); - } else if ((enable != 0) && (gain_db_ceiling >= 0)) { + } else if ((enable != 0) && (!isnanf(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); ret |= cambus_readb(sensor->slv_addr, COM9, ®); @@ -756,22 +756,40 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us) return ret; } -static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain) +static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db) { uint8_t reg; - /* Switch to SENSOR register bank */ - int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); - - /* Update CTRL1 */ + int ret = cambus_readb(sensor->slv_addr, BANK_SEL, ®); + ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg & (~BANK_SEL_SENSOR)); ret |= cambus_readb(sensor->slv_addr, CTRL1, ®); + ret |= cambus_writeb(sensor->slv_addr, CTRL1, (reg & (~CTRL1_AWB)) | ((enable != 0) ? CTRL1_AWB : 0)); - if (enable) { - reg |= CTRL1_AWB; - } else { - reg &= ~CTRL1_AWB; + if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))) { } - return cambus_writeb(sensor->slv_addr, CTRL1, reg) | ret; + return ret; +} + +static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db) +{ + uint8_t reg; + int ret = cambus_readb(sensor->slv_addr, BANK_SEL, ®); + ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg & (~BANK_SEL_SENSOR)); + ret |= cambus_readb(sensor->slv_addr, CTRL1, ®); + + // DISABLED + // if (reg & CTRL1_AWB) { + // ret |= cambus_writeb(sensor->slv_addr, CTRL1, reg & (~CTRL1_AWB)); + // } + // DISABLED + + // DISABLED + // if (reg & CTRL1_AWB) { + // ret |= cambus_writeb(sensor->slv_addr, CTRL1, reg | CTRL1_AWB); + // } + // DISABLED + + return ret; } static int set_hmirror(sensor_t *sensor, int enable) @@ -829,6 +847,7 @@ int ov2640_init(sensor_t *sensor) sensor->set_auto_exposure = set_auto_exposure; 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_hmirror = set_hmirror; sensor->set_vflip = set_vflip; diff --git a/src/omv/ov7725.c b/src/omv/ov7725.c index f7de59f5d..b9ac902f2 100644 --- a/src/omv/ov7725.c +++ b/src/omv/ov7725.c @@ -358,7 +358,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain int ret = cambus_readb(sensor->slv_addr, COM8, ®); ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, (enable != 0))); - if ((enable == 0) && (gain_db >= 0)) { + if ((enable == 0) && (!isnanf(gain_db))) { float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 0.0); int gain_hi = 15; @@ -372,7 +372,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain } ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0)); - } else if ((enable != 0) && (gain_db_ceiling >= 0)) { + } else if ((enable != 0) && (!isnanf(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); ret |= cambus_readb(sensor->slv_addr, COM9, ®); @@ -491,24 +491,59 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us) return ret; } -static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain) +static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db) { uint8_t reg; int ret = cambus_readb(sensor->slv_addr, COM8, ®); - // Set AWB on/off - reg = COM8_SET_AWB(reg, enable); - ret |= cambus_writeb(sensor->slv_addr, COM8, reg); + ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AWB(reg, (enable != 0))); - if (enable == 0 && r_gain >= 0 && g_gain >=0 && b_gain >=0) { - // Set value manually. + if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))) { + ret |= cambus_readb(sensor->slv_addr, AWB_CTRL1, ®); + float gain_div = (reg & 0x2) ? 64.0 : 128.0; + + 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); + + ret |= cambus_writeb(sensor->slv_addr, BLUE, b_gain); ret |= cambus_writeb(sensor->slv_addr, RED, r_gain); ret |= cambus_writeb(sensor->slv_addr, GREEN, g_gain); - ret |= cambus_writeb(sensor->slv_addr, BLUE, b_gain); } return ret; } +static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db) +{ + uint8_t reg, blue, red, green; + int ret = cambus_readb(sensor->slv_addr, COM8, ®); + + // DISABLED + // if (reg & COM8_AWB_EN) { + // ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AWB(reg, 0)); + // } + // DISABLED + + ret |= cambus_readb(sensor->slv_addr, BLUE, &blue); + ret |= cambus_readb(sensor->slv_addr, RED, &red); + ret |= cambus_readb(sensor->slv_addr, GREEN, &green); + + // DISABLED + // if (reg & COM8_AWB_EN) { + // ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AWB(reg, 1)); + // } + // DISABLED + + ret |= cambus_readb(sensor->slv_addr, AWB_CTRL1, ®); + float gain_div = (reg & 0x2) ? 64.0 : 128.0; + + *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)); + + return ret; +} + static int set_hmirror(sensor_t *sensor, int enable) { uint8_t reg; @@ -578,6 +613,7 @@ int ov7725_init(sensor_t *sensor) sensor->set_auto_exposure = set_auto_exposure; 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_hmirror = set_hmirror; sensor->set_vflip = set_vflip; sensor->set_special_effect = set_special_effect; diff --git a/src/omv/ov9650.c b/src/omv/ov9650.c index c5ddc22f6..18f762615 100644 --- a/src/omv/ov9650.c +++ b/src/omv/ov9650.c @@ -334,7 +334,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®); ret |= cambus_writeb(sensor->slv_addr, REG_COM8, (reg & (~REG_COM8_AGC)) | ((enable != 0) ? REG_COM8_AGC : 0)); - if ((enable == 0) && (gain_db >= 0)) { + if ((enable == 0) && (!isnanf(gain_db))) { float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 128.0), 0.0); int gain_hi = 63; @@ -350,7 +350,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain ret |= cambus_writeb(sensor->slv_addr, REG_GAIN, ((gain_hi & 0x0F) << 4) | (gain_lo << 0)); ret |= cambus_readb(sensor->slv_addr, REG_VREF, ®); ret |= cambus_writeb(sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F)); - } else if ((enable != 0) && (gain_db_ceiling >= 0)) { + } else if ((enable != 0) && (!isnanf(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); ret |= cambus_readb(sensor->slv_addr, REG_COM9, ®); @@ -459,15 +459,47 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us) return ret; } -static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain) +static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db) { - uint8_t val; - cambus_readb(sensor->slv_addr, REG_COM8, &val); + uint8_t reg; + int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®); + ret |= cambus_writeb(sensor->slv_addr, REG_COM8, (reg & (~REG_COM8_AWB)) | ((enable != 0) ? REG_COM8_AWB : 0)); - cambus_writeb(sensor->slv_addr, REG_COM8, - enable ? (val | REG_COM8_AWB) : (val & ~REG_COM8_AWB)); + if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(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); - return 0; + ret |= cambus_writeb(sensor->slv_addr, REG_BLUE, b_gain); + ret |= cambus_writeb(sensor->slv_addr, REG_RED, r_gain); + } + + return ret; +} + +static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db) +{ + uint8_t reg, blue, red; + int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®); + + // DISABLED + // if (reg & REG_COM8_AWB) { + // ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AWB)); + // } + // DISABLED + + ret |= cambus_readb(sensor->slv_addr, REG_BLUE, &blue); + ret |= cambus_readb(sensor->slv_addr, REG_RED, &red); + + // DISABLED + // if (reg & REG_COM8_AWB) { + // ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AWB); + // } + // 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)); + + return ret; } static int set_hmirror(sensor_t *sensor, int enable) @@ -503,6 +535,7 @@ int ov9650_init(sensor_t *sensor) sensor->set_auto_exposure = set_auto_exposure; 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_hmirror = set_hmirror; sensor->set_vflip = set_vflip; diff --git a/src/omv/py/py_helper.c b/src/omv/py/py_helper.c index 6c1705182..6e84ea633 100644 --- a/src/omv/py/py_helper.c +++ b/src/omv/py/py_helper.c @@ -41,6 +41,19 @@ void py_helper_lookup_int_array(mp_map_t *kw_args, mp_obj_t kw, int *x, int size } } +void py_helper_lookup_float_array(mp_map_t *kw_args, mp_obj_t kw, float *x, int size) +{ + mp_map_elem_t *kw_array = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP); + + if (kw_array != NULL) { + mp_obj_t *arg_array; + mp_obj_get_array_fixed_n(kw_array->value, size, &arg_array); + for (int i=0; i