diff --git a/src/omv/ov2640.c b/src/omv/ov2640.c index 27d38f2e4..4cd829907 100644 --- a/src/omv/ov2640.c +++ b/src/omv/ov2640.c @@ -612,6 +612,69 @@ static int set_colorbar(sensor_t *sensor, int enable) return ret; } +static int set_whitebal(sensor_t *sensor, int enable) +{ + int ret=0; + uint8_t reg; + + /* Switch to SENSOR register bank */ + ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); + + /* Update COM7 */ + reg = SCCB_Read(sensor->slv_addr, CTRL1); + + if (enable) { + reg |= CTRL1_AWB; + } else { + reg &= ~CTRL1_AWB; + } + + ret |= SCCB_Write(sensor->slv_addr, CTRL1, reg); + return ret; +} + +static int set_hmirror(sensor_t *sensor, int enable) +{ + int ret=0; + uint8_t reg; + + /* Switch to SENSOR register bank */ + ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR); + + /* Update REG04 */ + reg = SCCB_Read(sensor->slv_addr, REG04); + + if (enable) { + reg |= REG04_HFLIP_IMG; + } else { + reg &= ~REG04_HFLIP_IMG; + } + + ret |= SCCB_Write(sensor->slv_addr, REG04, reg); + return ret; +} + +static int set_vflip(sensor_t *sensor, int enable) +{ + int ret=0; + uint8_t reg; + + /* Switch to SENSOR register bank */ + ret |= SCCB_Write(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR); + + /* Update REG04 */ + reg = SCCB_Read(sensor->slv_addr, REG04); + + if (enable) { + reg |= REG04_VFLIP_IMG; + } else { + reg &= ~REG04_VFLIP_IMG; + } + + ret |= SCCB_Write(sensor->slv_addr, REG04, reg); + return ret; +} + int ov2640_init(sensor_t *sensor) { /* set function pointers */ @@ -626,6 +689,9 @@ int ov2640_init(sensor_t *sensor) sensor->set_gainceiling = set_gainceiling; sensor->set_quality = set_quality; sensor->set_colorbar = set_colorbar; + sensor->set_whitebal = set_whitebal; + sensor->set_hmirror = set_hmirror; + sensor->set_vflip = set_vflip; // Set sensor flags SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 0); diff --git a/src/omv/ov2640_regs.h b/src/omv/ov2640_regs.h index 2d501e565..88730751b 100644 --- a/src/omv/ov2640_regs.h +++ b/src/omv/ov2640_regs.h @@ -187,6 +187,8 @@ #define COM9_AGC_GAIN_128x 0x06 /* AGC: 128x */ #define COM9_AGC_SET(x) (COM9_DEFAULT|(x<<5)) +#define CTRL1_AWB 0x08 /* Enable AWB */ + #define VV 0x26 #define VV_AGC_TH_SET(h,l) ((h<<4)|(l&0x0F)) diff --git a/src/omv/ov7725.c b/src/omv/ov7725.c index 1df0dc4b3..2f8a1dc2f 100644 --- a/src/omv/ov7725.c +++ b/src/omv/ov7725.c @@ -22,14 +22,14 @@ static const uint8_t default_regs[][2] = { {COM4, 0xC1}, /* PLL */ {CLKRC, 0x00}, - // VGA Window Size + // VGA Window Size {HSTART, 0x23}, {HSIZE, 0xA0}, {VSTART, 0x07}, {VSIZE, 0xF0}, {HREF, 0x00}, - // Scale down to QVGA Resoultion + // Scale down to QVGA Resoultion {HOUTSIZE, 0x50}, {VOUTSIZE, 0x78}, @@ -284,7 +284,7 @@ static int set_colorbar(sensor_t *sensor, int enable) // Read register COM3 uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); - // Set color bar on/off + // Set color bar on/off reg = COM3_SET_CBAR(reg, enable); // Set mirror on/off to pass self-tests @@ -294,6 +294,42 @@ static int set_colorbar(sensor_t *sensor, int enable) return SCCB_Write(sensor->slv_addr, COM3, reg); } +static int set_whitebal(sensor_t *sensor, int enable) +{ + // Read register COM8 + uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); + + // Set white bal on/off + reg = COM8_SET_AWB(reg, enable); + + // Write back register COM8 + return SCCB_Write(sensor->slv_addr, COM8, reg); +} + +static int set_hmirror(sensor_t *sensor, int enable) +{ + // Read register COM3 + uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); + + // Set mirror on/off + reg = COM3_SET_MIRROR(reg, enable); + + // Write back register COM3 + return SCCB_Write(sensor->slv_addr, COM3, reg); +} + +static int set_vflip(sensor_t *sensor, int enable) +{ + // Read register COM3 + uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); + + // Set mirror on/off + reg = COM3_SET_FLIP(reg, enable); + + // Write back register COM3 + return SCCB_Write(sensor->slv_addr, COM3, reg); +} + static int set_special_effect(sensor_t *sensor, sde_t sde) { int ret=0; @@ -327,6 +363,9 @@ int ov7725_init(sensor_t *sensor) sensor->set_exposure = set_exposure; sensor->set_gainceiling = set_gainceiling; sensor->set_colorbar = set_colorbar; + sensor->set_whitebal = set_whitebal; + sensor->set_hmirror = set_hmirror; + sensor->set_vflip = set_vflip; sensor->set_special_effect = set_special_effect; // Set sensor flags diff --git a/src/omv/ov7725_regs.h b/src/omv/ov7725_regs.h index af82c4fd8..3741a4c73 100644 --- a/src/omv/ov7725_regs.h +++ b/src/omv/ov7725_regs.h @@ -25,7 +25,7 @@ #define PID 0x0A /* Product ID Number MSB */ #define VER 0x0B /* Product ID Number LSB */ - + #define COM3 0x0C /* Common Control 3 */ #define COM3_VFLIP 0x80 /* Vertical flip image ON/OFF selection */ #define COM3_MIRROR 0x40 /* Horizontal mirror image ON/OFF selection */ @@ -37,6 +37,7 @@ #define COM3_COLOR_BAR 0x01 /* Sensor color bar test pattern output enable */ #define COM3_SET_CBAR(r, x) ((r&0xFE)|((x&1)<<0)) #define COM3_SET_MIRROR(r, x) ((r&0xBF)|((x&1)<<6)) +#define COM3_SET_FLIP(r, x) ((r&0x7F)|((x&1)<<7)) #define COM4 0x0D /* Common Control 4 */ #define COM4_PLL_BYPASS 0x00 /* Bypass PLL */ @@ -61,11 +62,11 @@ #define COM5_AEC_NO_LIMIT 0x01 /* No limit to AEC increase step */ #define COM6 0x0F /* Common Control 6 */ -#define COM6_AUTO_WINDOW 0x01 /* Auto window setting ON/OFF selection when format changes */ +#define COM6_AUTO_WINDOW 0x01 /* Auto window setting ON/OFF selection when format changes */ #define AEC 0x10 /* AEC[7:0] (see register AECH for AEC[15:8]) */ #define CLKRC 0x11 /* Internal Clock */ - + #define COM7 0x12 /* Common Control 7 */ #define COM7_RESET 0x80 /* SCCB Register Reset */ #define COM7_RES_VGA 0x00 /* Resolution VGA */ @@ -92,6 +93,7 @@ #define COM8_AGC_EN 0x04 /* AGC Enable */ #define COM8_AWB_EN 0x02 /* AWB Enable */ #define COM8_AEC_EN 0x01 /* AEC Enable */ +#define COM8_SET_AWB(r, x) ((r&0xFD)|((x&0x1)<<1)) #define COM9 0x14 /* Common Control 9 */ #define COM9_HISTO_AVG 0x80 /* Histogram or average based AEC/AGC selection */ @@ -178,7 +180,7 @@ #define LC_CTR_RGB_COMP_1 0x00 /* R, G, and B channel compensation coefficient is set by LC_COEF (0x49) */ #define LC_CTR_RGB_COMP_3 0x04 /* R, G, and B channel compensation coefficient is set by registers LC_COEFB (0x4B), LC_COEF (0x49), and LC_COEFR (0x4C), respectively */ -#define LC_CTR_EN 0x01 /* Lens correction enable */ +#define LC_CTR_EN 0x01 /* Lens correction enable */ #define LC_XC 0x47 /* X Coordinate of Lens Correction Center Relative to Array Center */ #define LC_YC 0x48 /* Y Coordinate of Lens Correction Center Relative to Array Center */ #define LC_COEF 0x49 /* Lens Correction Coefficient */ diff --git a/src/omv/ov9650.c b/src/omv/ov9650.c index 2bc03896c..5f638dbd1 100644 --- a/src/omv/ov9650.c +++ b/src/omv/ov9650.c @@ -343,6 +343,39 @@ static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling) return 0; } +static int set_whitebal(sensor_t *sensor, int enable) +{ + uint8_t val; + val = SCCB_Read(sensor->slv_addr, REG_COM8); + + SCCB_Write(sensor->slv_addr, REG_COM8, + enable ? (val | REG_COM8_AWB) : (val & ~REG_COM8_AWB)); + + return 0; +} + +static int set_hmirror(sensor_t *sensor, int enable) +{ + uint8_t val; + val = SCCB_Read(sensor->slv_addr, REG_MVFP); + + SCCB_Write(sensor->slv_addr, REG_MVFP, + enable ? (val | REG_MVFP_HMIRROR) : (val & ~REG_MVFP_HMIRROR)); + + return 0; +} + +static int set_vflip(sensor_t *sensor, int enable) +{ + uint8_t val; + val = SCCB_Read(sensor->slv_addr, REG_MVFP); + + SCCB_Write(sensor->slv_addr, REG_MVFP, + enable ? (val | REG_MVFP_VFLIP) : (val & ~REG_MVFP_VFLIP)); + + return 0; +} + int ov9650_init(sensor_t *sensor) { // Set function pointers @@ -353,6 +386,9 @@ int ov9650_init(sensor_t *sensor) sensor->set_brightness= set_brightness; sensor->set_exposure = set_exposure; sensor->set_gainceiling = set_gainceiling; + sensor->set_whitebal = set_whitebal; + sensor->set_hmirror = set_hmirror; + sensor->set_vflip = set_vflip; // Set sensor flags SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 1); diff --git a/src/omv/ov9650_regs.h b/src/omv/ov9650_regs.h index c11b472a7..27ac43bfe 100644 --- a/src/omv/ov9650_regs.h +++ b/src/omv/ov9650_regs.h @@ -120,4 +120,7 @@ #define REG_COM7_QVGA (1<<4) #define REG_COM7_CIF (1<<5) #define REG_COM7_VGA (1<<6) +#define REG_COM8_AWB (1<<1) +#define REG_MVFP_HMIRROR (1<<5) +#define REG_MVFP_VFLIP (1<<4) #endif //__REG_REGS_H__ diff --git a/src/omv/py/py_sensor.c b/src/omv/py/py_sensor.c index e83a9da13..3211f0442 100644 --- a/src/omv/py/py_sensor.c +++ b/src/omv/py/py_sensor.c @@ -159,6 +159,27 @@ static mp_obj_t py_sensor_set_colorbar(mp_obj_t enable) { return mp_const_true; } +static mp_obj_t py_sensor_set_whitebal(mp_obj_t enable) { + if (sensor_set_whitebal(mp_obj_is_true(enable)) != 0) { + return mp_const_false; + } + return mp_const_true; +} + +static mp_obj_t py_sensor_set_hmirror(mp_obj_t enable) { + if (sensor_set_hmirror(mp_obj_is_true(enable)) != 0) { + return mp_const_false; + } + return mp_const_true; +} + +static mp_obj_t py_sensor_set_vflip(mp_obj_t enable) { + if (sensor_set_vflip(mp_obj_is_true(enable)) != 0) { + return mp_const_false; + } + return mp_const_true; +} + static mp_obj_t py_sensor_set_special_effect(mp_obj_t sde) { if (sensor_set_special_effect(mp_obj_get_int(sde)) != 0) { return mp_const_false; @@ -230,6 +251,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_brightness_obj, py_sensor_se STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_saturation_obj, py_sensor_set_saturation); STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_quality_obj, py_sensor_set_quality); STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_colorbar_obj, py_sensor_set_colorbar); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_whitebal_obj, py_sensor_set_whitebal); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_hmirror_obj, py_sensor_set_hmirror); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_vflip_obj, py_sensor_set_vflip); STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_special_effect_obj, py_sensor_set_special_effect); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_sensor_set_image_filter_obj,1, py_sensor_set_image_filter); STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_sensor_write_reg_obj, py_sensor_write_reg); @@ -280,6 +304,9 @@ STATIC const mp_map_elem_t globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_set_saturation), (mp_obj_t)&py_sensor_set_saturation_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_set_quality), (mp_obj_t)&py_sensor_set_quality_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_set_colorbar), (mp_obj_t)&py_sensor_set_colorbar_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_whitebal), (mp_obj_t)&py_sensor_set_whitebal_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_hmirror), (mp_obj_t)&py_sensor_set_hmirror_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_vflip), (mp_obj_t)&py_sensor_set_vflip_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_image_filter), (mp_obj_t)&py_sensor_set_image_filter_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___write_reg), (mp_obj_t)&py_sensor_write_reg_obj }, diff --git a/src/omv/sensor.c b/src/omv/sensor.c index 57ca0fa85..dc57c5f5f 100644 --- a/src/omv/sensor.c +++ b/src/omv/sensor.c @@ -455,6 +455,39 @@ int sensor_set_colorbar(int enable) return 0; } +int sensor_set_whitebal(int enable) +{ + /* call the sensor specific function */ + if (sensor.set_whitebal == NULL + || sensor.set_whitebal(&sensor, enable) != 0) { + /* operation not supported */ + return -1; + } + return 0; +} + +int sensor_set_hmirror(int enable) +{ + /* call the sensor specific function */ + if (sensor.set_hmirror == NULL + || sensor.set_hmirror(&sensor, enable) != 0) { + /* operation not supported */ + return -1; + } + return 0; +} + +int sensor_set_vflip(int enable) +{ + /* call the sensor specific function */ + if (sensor.set_vflip == NULL + || sensor.set_vflip(&sensor, enable) != 0) { + /* operation not supported */ + return -1; + } + return 0; +} + int sensor_set_special_effect(sde_t sde) { if (sensor.sde == sde) { diff --git a/src/omv/sensor.h b/src/omv/sensor.h index 295e6fbbd..3e626433e 100644 --- a/src/omv/sensor.h +++ b/src/omv/sensor.h @@ -126,6 +126,9 @@ typedef struct _sensor { int (*set_gainceiling) (sensor_t *sensor, gainceiling_t gainceiling); int (*set_quality) (sensor_t *sensor, int quality); int (*set_colorbar) (sensor_t *sensor, int enable); + int (*set_whitebal) (sensor_t *sensor, int enable); + 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); } sensor_t; @@ -189,6 +192,15 @@ int sensor_set_quality(int qs); // Enable/disable the colorbar mode. int sensor_set_colorbar(int enable); +// Enable/disable the whitebal mode. +int sensor_set_whitebal(int enable); + +// Enable/disable the hmirror mode. +int sensor_set_hmirror(int enable); + +// Enable/disable the vflip mode. +int sensor_set_vflip(int enable); + // Set special digital effects (SDE). int sensor_set_special_effect(sde_t sde);