From af931850f4a32566f51403758c3a49032327225c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 3 Jun 2020 22:54:57 +0300 Subject: [PATCH] Some 7725 fixes --- driver/camera.c | 14 +-- driver/sccb.c | 2 +- sensors/ov7725.c | 310 ++++++++++++++++++++++++++++++++++++----------- 3 files changed, 249 insertions(+), 77 deletions(-) diff --git a/driver/camera.c b/driver/camera.c index d2ac7a3..c6b09ad 100755 --- a/driver/camera.c +++ b/driver/camera.c @@ -1307,20 +1307,20 @@ esp_err_t esp_camera_init(const camera_config_t* config) goto fail; } if (camera_model == CAMERA_OV7725) { - ESP_LOGD(TAG, "Detected OV7725 camera"); + ESP_LOGI(TAG, "Detected OV7725 camera"); if(config->pixel_format == PIXFORMAT_JPEG) { ESP_LOGE(TAG, "Camera does not support JPEG"); err = ESP_ERR_CAMERA_NOT_SUPPORTED; goto fail; } } else if (camera_model == CAMERA_OV2640) { - ESP_LOGD(TAG, "Detected OV2640 camera"); + ESP_LOGI(TAG, "Detected OV2640 camera"); } else if (camera_model == CAMERA_OV3660) { - ESP_LOGD(TAG, "Detected OV3660 camera"); + ESP_LOGI(TAG, "Detected OV3660 camera"); } else if (camera_model == CAMERA_OV5640) { - ESP_LOGD(TAG, "Detected OV5640 camera"); + ESP_LOGI(TAG, "Detected OV5640 camera"); } else { - ESP_LOGE(TAG, "Camera not supported"); + ESP_LOGI(TAG, "Camera not supported"); err = ESP_ERR_CAMERA_NOT_SUPPORTED; goto fail; } @@ -1425,7 +1425,7 @@ sensor_t * esp_camera_sensor_get() esp_err_t esp_camera_save_to_nvs(const char *key) { -#ifdef ESP_IDF_VERSION_MAJOR +#if ESP_IDF_VERSION_MAJOR > 3 nvs_handle_t handle; #else nvs_handle handle; @@ -1453,7 +1453,7 @@ esp_err_t esp_camera_save_to_nvs(const char *key) esp_err_t esp_camera_load_from_nvs(const char *key) { -#ifdef ESP_IDF_VERSION_MAJOR +#if ESP_IDF_VERSION_MAJOR > 3 nvs_handle_t handle; #else nvs_handle handle; diff --git a/driver/sccb.c b/driver/sccb.c index 30e725c..d2f5fb9 100755 --- a/driver/sccb.c +++ b/driver/sccb.c @@ -26,7 +26,7 @@ static const char* TAG = "sccb"; #ifdef CONFIG_SCCB_HARDWARE_I2C #include "driver/i2c.h" -#define SCCB_FREQ 200000 /*!< I2C master frequency*/ +#define SCCB_FREQ 100000 /*!< I2C master frequency*/ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ diff --git a/sensors/ov7725.c b/sensors/ov7725.c index b4e6710..228906f 100755 --- a/sensors/ov7725.c +++ b/sensors/ov7725.c @@ -121,6 +121,51 @@ static const uint8_t default_regs[][2] = { {0x00, 0x00}, }; +static int get_reg(sensor_t *sensor, int reg, int mask) +{ + int ret = SCCB_Read(sensor->slv_addr, reg & 0xFF); + if(ret > 0){ + ret &= mask; + } + return ret; +} + +static int set_reg(sensor_t *sensor, int reg, int mask, int value) +{ + int ret = 0; + ret = SCCB_Read(sensor->slv_addr, reg & 0xFF); + if(ret < 0){ + return ret; + } + value = (ret & ~mask) | (value & mask); + ret = SCCB_Write(sensor->slv_addr, reg & 0xFF, value); + return ret; +} + +static int set_reg_bits(sensor_t *sensor, uint8_t reg, uint8_t offset, uint8_t length, uint8_t value) +{ + int ret = 0; + ret = SCCB_Read(sensor->slv_addr, reg); + if(ret < 0){ + return ret; + } + uint8_t mask = ((1 << length) - 1) << offset; + value = (ret & ~mask) | ((value << offset) & mask); + ret = SCCB_Write(sensor->slv_addr, reg & 0xFF, value); + return ret; +} + +static int get_reg_bits(sensor_t *sensor, uint8_t reg, uint8_t offset, uint8_t length) +{ + int ret = 0; + ret = SCCB_Read(sensor->slv_addr, reg); + if(ret < 0){ + return ret; + } + uint8_t mask = ((1 << length) - 1) << offset; + return (ret & mask) >> offset; +} + static int reset(sensor_t *sensor) { @@ -251,82 +296,208 @@ static int set_colorbar(sensor_t *sensor, int enable) static int set_whitebal(sensor_t *sensor, int enable) { - // Read register COM8 - uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); - - sensor->status.awb = enable; - // Set white bal on/off - reg = COM8_SET_AWB(reg, enable); - - // Write back register COM8 - return SCCB_Write(sensor->slv_addr, COM8, reg); + if(set_reg_bits(sensor, COM8, 1, 1, enable) >= 0){ + sensor->status.awb = !!enable; + } + return sensor->status.awb; } static int set_gain_ctrl(sensor_t *sensor, int enable) { - sensor->status.agc = enable; - // Read register COM8 - uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); - - // Set white bal on/off - reg = COM8_SET_AGC(reg, enable); - - // Write back register COM8 - return SCCB_Write(sensor->slv_addr, COM8, reg); + if(set_reg_bits(sensor, COM8, 2, 1, enable) >= 0){ + sensor->status.agc = !!enable; + } + return sensor->status.agc; } static int set_exposure_ctrl(sensor_t *sensor, int enable) { - sensor->status.aec = enable; - // Read register COM8 - uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); - - // Set white bal on/off - reg = COM8_SET_AEC(reg, enable); - - // Write back register COM8 - return SCCB_Write(sensor->slv_addr, COM8, reg); + if(set_reg_bits(sensor, COM8, 0, 1, enable) >= 0){ + sensor->status.aec = !!enable; + } + return sensor->status.aec; } static int set_hmirror(sensor_t *sensor, int enable) { - sensor->status.hmirror = 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); + if(set_reg_bits(sensor, COM3, 6, 1, enable) >= 0){ + sensor->status.hmirror = !!enable; + } + return sensor->status.hmirror; } static int set_vflip(sensor_t *sensor, int enable) { - sensor->status.vflip = enable; - // Read register COM3 - uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); + if(set_reg_bits(sensor, COM3, 7, 1, enable) >= 0){ + sensor->status.vflip = !!enable; + } + return sensor->status.vflip; +} - // Set mirror on/off - reg = COM3_SET_FLIP(reg, enable); +static int set_dcw_dsp(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, 0x65, 2, 1, !enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set dcw to: %d", enable); + sensor->status.dcw = enable; + } + return ret; +} - // Write back register COM3 - return SCCB_Write(sensor->slv_addr, COM3, reg); +static int set_aec2(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, COM8, 7, 1, enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set aec2 to: %d", enable); + sensor->status.aec2 = enable; + } + return ret; +} + +static int set_bpc_dsp(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, 0x64, 1, 1, enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set bpc to: %d", enable); + sensor->status.bpc = enable; + } + return ret; +} + +static int set_wpc_dsp(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, 0x64, 0, 1, enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set wpc to: %d", enable); + sensor->status.wpc = enable; + } + return ret; +} + +static int set_raw_gma_dsp(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, 0x64, 2, 1, enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set raw_gma to: %d", enable); + sensor->status.raw_gma = enable; + } + return ret; +} + +static int set_lenc_dsp(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, LC_CTR, 0, 1, enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set lenc to: %d", enable); + sensor->status.lenc = enable; + } + return ret; +} + +//real gain +static int set_agc_gain(sensor_t *sensor, int gain) +{ + int ret = 0; + ret = set_reg_bits(sensor, COM9, 4, 3, gain % 5); + if (ret == 0) { + ESP_LOGD(TAG, "Set gain to: %d", gain); + sensor->status.agc_gain = gain; + } + return ret; +} + +static int set_aec_value(sensor_t *sensor, int value) +{ + int ret = 0; + ret = SCCB_Write(sensor->slv_addr, AEC, value & 0xff) | SCCB_Write(sensor->slv_addr, AECH, value >> 8); + if (ret == 0) { + ESP_LOGD(TAG, "Set aec_value to: %d", value); + sensor->status.aec_value = value; + } + return ret; +} + +static int set_awb_gain_dsp(sensor_t *sensor, int enable) +{ + int ret = 0; + ret = set_reg_bits(sensor, 0x63, 7, 1, enable); + if (ret == 0) { + ESP_LOGD(TAG, "Set awb_gain to: %d", enable); + sensor->status.awb_gain = enable; + } + return ret; +} + +static int set_brightness(sensor_t *sensor, int level) +{ + int ret = 0; + ret = SCCB_Write(sensor->slv_addr, 0x9B, level); + if (ret == 0) { + ESP_LOGD(TAG, "Set brightness to: %d", level); + sensor->status.brightness = level; + } + return ret; +} + +static int set_contrast(sensor_t *sensor, int level) +{ + int ret = 0; + ret = SCCB_Write(sensor->slv_addr, 0x9C, level); + if (ret == 0) { + ESP_LOGD(TAG, "Set contrast to: %d", level); + sensor->status.contrast = level; + } + return ret; } static int init_status(sensor_t *sensor) { - sensor->status.awb = 0;//get_reg_bits(sensor, BANK_DSP, CTRL1, 3, 1); - sensor->status.aec = 0; - sensor->status.agc = 0; - sensor->status.hmirror = 0; - sensor->status.vflip = 0; - sensor->status.colorbar = 0; + sensor->status.brightness = SCCB_Read(sensor->slv_addr, 0x9B); + sensor->status.contrast = SCCB_Read(sensor->slv_addr, 0x9C); + sensor->status.saturation = 0; + sensor->status.ae_level = 0; + sensor->status.special_effect = get_reg_bits(sensor, 0x64, 5, 1); + sensor->status.wb_mode = get_reg_bits(sensor, 0x6B, 7, 1); + sensor->status.agc_gain = get_reg_bits(sensor, COM9, 4, 3); + sensor->status.aec_value = SCCB_Read(sensor->slv_addr, AEC) | (SCCB_Read(sensor->slv_addr, AECH) << 8); + sensor->status.gainceiling = SCCB_Read(sensor->slv_addr, 0x00); + sensor->status.awb = get_reg_bits(sensor, COM8, 1, 1); + sensor->status.awb_gain = get_reg_bits(sensor, 0x63, 7, 1); + sensor->status.aec = get_reg_bits(sensor, COM8, 0, 1); + sensor->status.aec2 = get_reg_bits(sensor, COM8, 7, 1); + sensor->status.agc = get_reg_bits(sensor, COM8, 2, 1); + sensor->status.bpc = get_reg_bits(sensor, 0x64, 1, 1); + sensor->status.wpc = get_reg_bits(sensor, 0x64, 0, 1); + sensor->status.raw_gma = get_reg_bits(sensor, 0x64, 2, 1); + sensor->status.lenc = get_reg_bits(sensor, LC_CTR, 0, 1); + sensor->status.hmirror = get_reg_bits(sensor, COM3, 6, 1); + sensor->status.vflip = get_reg_bits(sensor, COM3, 7, 1); + sensor->status.dcw = get_reg_bits(sensor, 0x65, 2, 1); + sensor->status.colorbar = get_reg_bits(sensor, COM3, 0, 1); + sensor->status.sharpness = get_reg_bits(sensor, EDGE0, 0, 5); + sensor->status.denoise = SCCB_Read(sensor->slv_addr, 0x8E); return 0; } static int set_dummy(sensor_t *sensor, int val){ return -1; } static int set_gainceiling_dummy(sensor_t *sensor, gainceiling_t val){ return -1; } +static int set_res_raw(sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning){return -1;} +static int _set_pll(sensor_t *sensor, int bypass, int multiplier, int sys_div, int root_2x, int pre_div, int seld5, int pclk_manual, int pclk_div){return -1;} + +esp_err_t xclk_timer_conf(int ledc_timer, int xclk_freq_hz); +static int set_xclk(sensor_t *sensor, int timer, int xclk) +{ + int ret = 0; + sensor->xclk_freq_hz = xclk * 1000000U; + ret = xclk_timer_conf(timer, sensor->xclk_freq_hz); + return ret; +} int ov7725_init(sensor_t *sensor) { @@ -342,34 +513,35 @@ int ov7725_init(sensor_t *sensor) sensor->set_hmirror = set_hmirror; sensor->set_vflip = set_vflip; + sensor->set_brightness = set_brightness; + sensor->set_contrast = set_contrast; + sensor->set_aec2 = set_aec2; + sensor->set_aec_value = set_aec_value; + sensor->set_awb_gain = set_awb_gain_dsp; + sensor->set_agc_gain = set_agc_gain; + sensor->set_dcw = set_dcw_dsp; + sensor->set_bpc = set_bpc_dsp; + sensor->set_wpc = set_wpc_dsp; + sensor->set_raw_gma = set_raw_gma_dsp; + sensor->set_lenc = set_lenc_dsp; + //not supported - sensor->set_brightness= set_dummy; sensor->set_saturation= set_dummy; + sensor->set_sharpness = set_dummy; + sensor->set_denoise = set_dummy; sensor->set_quality = set_dummy; - sensor->set_gainceiling = set_gainceiling_dummy; - sensor->set_gain_ctrl = set_dummy; - sensor->set_exposure_ctrl = set_dummy; - sensor->set_hmirror = set_dummy; - sensor->set_vflip = set_dummy; - sensor->set_whitebal = set_dummy; - sensor->set_aec2 = set_dummy; - sensor->set_aec_value = set_dummy; sensor->set_special_effect = set_dummy; sensor->set_wb_mode = set_dummy; sensor->set_ae_level = set_dummy; - sensor->set_dcw = set_dummy; - sensor->set_bpc = set_dummy; - sensor->set_wpc = set_dummy; - sensor->set_awb_gain = set_dummy; - sensor->set_agc_gain = set_dummy; - sensor->set_raw_gma = set_dummy; - sensor->set_lenc = set_dummy; - sensor->set_sharpness = set_dummy; - sensor->set_denoise = set_dummy; - - + sensor->set_gainceiling = set_gainceiling_dummy; + sensor->get_reg = get_reg; + sensor->set_reg = set_reg; + sensor->set_res_raw = set_res_raw; + sensor->set_pll = _set_pll; + sensor->set_xclk = set_xclk; + // Retrieve sensor's signature sensor->id.MIDH = SCCB_Read(sensor->slv_addr, REG_MIDH); sensor->id.MIDL = SCCB_Read(sensor->slv_addr, REG_MIDL);