15 changed files with 2894 additions and 1 deletions
@ -0,0 +1,453 @@
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* |
||||
* HM0360 driver. |
||||
* |
||||
*/ |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "sccb.h" |
||||
#include "xclk.h" |
||||
#include "hm0360.h" |
||||
#include "hm0360_regs.h" |
||||
#include "hm0360_settings.h" |
||||
#include "freertos/FreeRTOS.h" |
||||
#include "freertos/task.h" |
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) |
||||
#include "esp32-hal-log.h" |
||||
#else |
||||
#include "esp_log.h" |
||||
static const char *TAG = "HM0360"; |
||||
#endif |
||||
|
||||
// #define REG_DEBUG_ON
|
||||
|
||||
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); |
||||
|
||||
static int read_reg(uint8_t slv_addr, const uint16_t reg) |
||||
{ |
||||
int ret = SCCB_Read16(slv_addr, reg); |
||||
#ifdef REG_DEBUG_ON |
||||
if (ret < 0) { |
||||
ESP_LOGE(TAG, "READ REG 0x%04x FAILED: %d", reg, ret); |
||||
} |
||||
#endif |
||||
return ret; |
||||
} |
||||
|
||||
static int check_reg_mask(uint8_t slv_addr, uint16_t reg, uint8_t mask) |
||||
{ |
||||
return (read_reg(slv_addr, reg) & mask) == mask; |
||||
} |
||||
|
||||
static int read_reg16(uint8_t slv_addr, const uint16_t reg) |
||||
{ |
||||
int ret = 0, ret2 = 0; |
||||
|
||||
ret = read_reg(slv_addr, reg); |
||||
if (ret >= 0) { |
||||
ret = (ret & 0xFF) << 8; |
||||
ret2 = read_reg(slv_addr, reg + 1); |
||||
if (ret2 < 0) { |
||||
ret = ret2; |
||||
} else { |
||||
ret |= ret2 & 0xFF; |
||||
} |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int write_reg(uint8_t slv_addr, const uint16_t reg, uint8_t value) |
||||
{ |
||||
int ret = 0; |
||||
#ifndef REG_DEBUG_ON |
||||
ret = SCCB_Write16(slv_addr, reg, value); |
||||
#else |
||||
int old_value = read_reg(slv_addr, reg); |
||||
if (old_value < 0) { |
||||
return old_value; |
||||
} |
||||
|
||||
if ((uint8_t)old_value != value) { |
||||
ESP_LOGD(TAG, "NEW REG 0x%04x: 0x%02x to 0x%02x", reg, (uint8_t)old_value, value); |
||||
ret = SCCB_Write16(slv_addr, reg, value); |
||||
} else { |
||||
ESP_LOGD(TAG, "OLD REG 0x%04x: 0x%02x", reg, (uint8_t)old_value); |
||||
ret = SCCB_Write16(slv_addr, reg, value); // maybe not?
|
||||
} |
||||
if (ret < 0) { |
||||
ESP_LOGE(TAG, "WRITE REG 0x%04x FAILED: %d", reg, ret); |
||||
} |
||||
#endif |
||||
return ret; |
||||
} |
||||
|
||||
static int set_reg_bits(uint8_t slv_addr, uint16_t reg, uint8_t offset, uint8_t mask, uint8_t value) |
||||
{ |
||||
int ret = 0; |
||||
uint8_t c_value, new_value; |
||||
|
||||
ret = read_reg(slv_addr, reg); |
||||
if (ret < 0) { |
||||
return ret; |
||||
} |
||||
|
||||
c_value = ret; |
||||
new_value = (c_value & ~(mask << offset)) | ((value & mask) << offset); |
||||
ret = write_reg(slv_addr, reg, new_value); |
||||
return ret; |
||||
} |
||||
|
||||
static int write_regs(uint8_t slv_addr, const uint16_t (*regs)[2]) |
||||
{ |
||||
int i = 0, ret = 0; |
||||
|
||||
while (!ret && regs[i][0] != REGLIST_TAIL) { |
||||
if (regs[i][0] == REG_DLY) { |
||||
vTaskDelay(regs[i][1] / portTICK_PERIOD_MS); |
||||
} else { |
||||
ret = write_reg(slv_addr, regs[i][0], regs[i][1]); |
||||
} |
||||
i++; |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int write_reg16(uint8_t slv_addr, const uint16_t reg, uint16_t value) |
||||
{ |
||||
if (write_reg(slv_addr, reg, value >> 8) || write_reg(slv_addr, reg + 1, value)) { |
||||
return -1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static int write_addr_reg(uint8_t slv_addr, const uint16_t reg, uint16_t x_value, uint16_t y_value) |
||||
{ |
||||
if (write_reg16(slv_addr, reg, x_value) || write_reg16(slv_addr, reg + 2, y_value)) { |
||||
return -1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
#define write_reg_bits(slv_addr, reg, mask, enable) set_reg_bits(slv_addr, reg, 0, mask, (enable) ? (mask) : 0) |
||||
|
||||
static int reset(sensor_t *sensor) |
||||
{ |
||||
vTaskDelay(100 / portTICK_PERIOD_MS); |
||||
int ret = 0; |
||||
|
||||
// Software Reset: clear all registers and reset them to their default values
|
||||
ret = write_reg(sensor->slv_addr, SW_RESET, 0x00); |
||||
if (ret) { |
||||
ESP_LOGE(TAG, "Software Reset FAILED!"); |
||||
return ret; |
||||
} |
||||
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS); |
||||
ret = write_regs(sensor->slv_addr, sensor_default_regs); |
||||
if (ret == 0) { |
||||
ESP_LOGD(TAG, "Camera defaults loaded"); |
||||
vTaskDelay(100 / portTICK_PERIOD_MS); |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) |
||||
{ |
||||
int ret = 0; |
||||
sensor->pixformat = pixformat; |
||||
|
||||
switch (pixformat) { |
||||
case PIXFORMAT_GRAYSCALE: |
||||
break; |
||||
default: |
||||
ESP_LOGE(TAG, "Only support GRAYSCALE"); |
||||
return -1; |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
sensor->status.framesize = framesize; |
||||
ret = write_regs(sensor->slv_addr, sensor_default_regs); |
||||
|
||||
if (framesize == FRAMESIZE_QQVGA) { |
||||
ESP_LOGI(TAG, "Set FRAMESIZE_QQVGA"); |
||||
ret |= write_regs(sensor->slv_addr, sensor_framesize_QQVGA); |
||||
ret |= set_reg_bits(sensor->slv_addr, 0x3024, 0, 0x01, 1); |
||||
} else if (framesize == FRAMESIZE_QVGA) { |
||||
ESP_LOGI(TAG, "Set FRAMESIZE_QVGA"); |
||||
ret |= write_regs(sensor->slv_addr, sensor_framesize_QVGA); |
||||
ret |= set_reg_bits(sensor->slv_addr, 0x3024, 0, 0x01, 1); |
||||
} else if (framesize == FRAMESIZE_VGA) { |
||||
ESP_LOGI(TAG, "Set FRAMESIZE_VGA"); |
||||
ret |= set_reg_bits(sensor->slv_addr, 0x3024, 0, 0x01, 0); |
||||
} else { |
||||
ESP_LOGI(TAG, "Dont suppost this size, Set FRAMESIZE_VGA"); |
||||
ret |= set_reg_bits(sensor->slv_addr, 0x3024, 0, 0x01, 0); |
||||
} |
||||
|
||||
if (ret == 0) { |
||||
_set_pll(sensor, 0, 0, 0, 0, 0, 0, 0, 0); |
||||
ret |= write_reg(sensor->slv_addr, 0x0104, 0x01); |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable) |
||||
{ |
||||
if (set_reg_bits(sensor->slv_addr, 0x0101, 0, 0x01, enable)) { |
||||
return -1; |
||||
} |
||||
|
||||
ESP_LOGD(TAG, "Set h-mirror to: %d", enable); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable) |
||||
{ |
||||
if (set_reg_bits(sensor->slv_addr, 0x0101, 1, 0x01, enable)) { |
||||
return -1; |
||||
} |
||||
|
||||
ESP_LOGD(TAG, "Set v-flip to: %d", enable); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int set_colorbar(sensor_t *sensor, int enable) |
||||
{ |
||||
if (set_reg_bits(sensor->slv_addr, 0x0601, 0, 0x01, enable)) { |
||||
return -1; |
||||
} |
||||
|
||||
ESP_LOGD(TAG, "Set color-bar to: %d", enable); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int set_exposure_ctrl(sensor_t *sensor, int enable) |
||||
{ |
||||
if (set_reg_bits(sensor->slv_addr, 0x2000, 0, 0x01, enable)) { |
||||
return -1; |
||||
} |
||||
|
||||
ESP_LOGD(TAG, "Set exposure to: %d", enable); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int set_brightness(sensor_t *sensor, int level) |
||||
{ |
||||
uint8_t ae_mean; |
||||
|
||||
switch (level) { |
||||
case 0: |
||||
ae_mean = 60; |
||||
break; |
||||
case 1: |
||||
ae_mean = 80; |
||||
break; |
||||
case 2: |
||||
ae_mean = 100; |
||||
break; |
||||
case 3: |
||||
ae_mean = 127; |
||||
break; |
||||
default: |
||||
ae_mean = 80; |
||||
} |
||||
|
||||
return write_reg(sensor->slv_addr, AE_TARGET_MEAN, ae_mean); |
||||
} |
||||
|
||||
static int get_reg(sensor_t *sensor, int reg, int mask) |
||||
{ |
||||
int ret = 0, ret2 = 0; |
||||
|
||||
if (mask > 0xFF) { |
||||
ret = read_reg16(sensor->slv_addr, reg); |
||||
if (ret >= 0 && mask > 0xFFFF) { |
||||
ret2 = read_reg(sensor->slv_addr, reg + 2); |
||||
if (ret2 >= 0) { |
||||
ret = (ret << 8) | ret2; |
||||
} else { |
||||
ret = ret2; |
||||
} |
||||
} |
||||
} else { |
||||
ret = read_reg(sensor->slv_addr, reg); |
||||
} |
||||
|
||||
if (ret > 0) { |
||||
ret &= mask; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int set_reg(sensor_t *sensor, int reg, int mask, int value) |
||||
{ |
||||
int ret = 0, ret2 = 0; |
||||
|
||||
if (mask > 0xFF) { |
||||
ret = read_reg16(sensor->slv_addr, reg); |
||||
if (ret >= 0 && mask > 0xFFFF) { |
||||
ret2 = read_reg(sensor->slv_addr, reg + 2); |
||||
if (ret2 >= 0) { |
||||
ret = (ret << 8) | ret2; |
||||
} else { |
||||
ret = ret2; |
||||
} |
||||
} |
||||
} else { |
||||
ret = read_reg(sensor->slv_addr, reg); |
||||
} |
||||
|
||||
if (ret < 0) { |
||||
return ret; |
||||
} |
||||
|
||||
value = (ret & ~mask) | (value & mask); |
||||
if (mask > 0xFFFF) { |
||||
ret = write_reg16(sensor->slv_addr, reg, value >> 8); |
||||
if (ret >= 0) { |
||||
ret = write_reg(sensor->slv_addr, reg + 2, value & 0xFF); |
||||
} |
||||
} else if (mask > 0xFF) { |
||||
ret = write_reg16(sensor->slv_addr, reg, value); |
||||
} else { |
||||
ret = write_reg(sensor->slv_addr, reg, value); |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
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); |
||||
if (ret == 0) { |
||||
ESP_LOGD(TAG, "Set xclk to %d", xclk); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
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) |
||||
{ |
||||
uint8_t value = 0; |
||||
uint8_t pll_cfg = 0; |
||||
|
||||
if (sensor->xclk_freq_hz <= 6000000) { |
||||
value = 0x03; |
||||
} else if (sensor->xclk_freq_hz <= 12000000) { |
||||
value = 0x02; |
||||
} else if (sensor->xclk_freq_hz <= 18000000) { |
||||
value = 0x01; |
||||
} else { // max is 48000000
|
||||
value = 0x00; |
||||
} |
||||
|
||||
pll_cfg = read_reg(sensor->slv_addr, PLL1CFG); |
||||
return write_reg(sensor->slv_addr, PLL1CFG, (pll_cfg & 0xFC) | value); |
||||
} |
||||
|
||||
static int set_dummy(sensor_t *sensor, int val) |
||||
{ |
||||
ESP_LOGW(TAG, "Unsupported"); |
||||
return -1; |
||||
} |
||||
|
||||
static int set_gainceiling_dummy(sensor_t *sensor, gainceiling_t val) |
||||
{ |
||||
ESP_LOGW(TAG, "Unsupported"); |
||||
return -1; |
||||
} |
||||
|
||||
static int init_status(sensor_t *sensor) |
||||
{ |
||||
(void) write_addr_reg; |
||||
|
||||
sensor->status.brightness = 0; |
||||
sensor->status.contrast = 0; |
||||
sensor->status.saturation = 0; |
||||
sensor->status.sharpness = 0; |
||||
sensor->status.denoise = 0; |
||||
sensor->status.ae_level = 0; |
||||
sensor->status.awb = 0; |
||||
sensor->status.aec = 0; |
||||
sensor->status.hmirror = check_reg_mask(sensor->slv_addr, 0x101, 0x01); |
||||
sensor->status.vflip = check_reg_mask(sensor->slv_addr, 0x101, 0x02); |
||||
sensor->status.lenc = 0; |
||||
sensor->status.awb_gain = 0; |
||||
sensor->status.agc_gain = 0; |
||||
sensor->status.aec_value = 0; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int hm0360_detect(int slv_addr, sensor_id_t *id) |
||||
{ |
||||
if (HM1055_SCCB_ADDR == slv_addr) { |
||||
uint8_t h = SCCB_Read16(slv_addr, MODEL_ID_H); |
||||
uint8_t l = SCCB_Read16(slv_addr, MODEL_ID_L); |
||||
uint16_t PID = (h << 8) | l; |
||||
if (HM0360_PID == PID) { |
||||
id->PID = PID; |
||||
id->VER = SCCB_Read16(slv_addr, SILICON_REV); |
||||
return PID; |
||||
} else { |
||||
ESP_LOGD(TAG, "Mismatch PID=0x%x", PID); |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
int hm0360_init(sensor_t *sensor) |
||||
{ |
||||
sensor->reset = reset; |
||||
sensor->set_pixformat = set_pixformat; |
||||
sensor->set_framesize = set_framesize; |
||||
sensor->set_contrast = set_dummy; |
||||
sensor->set_brightness = set_brightness; |
||||
sensor->set_saturation = set_dummy; |
||||
sensor->set_sharpness = set_dummy; |
||||
sensor->set_gainceiling = set_gainceiling_dummy; |
||||
sensor->set_quality = set_dummy; |
||||
sensor->set_colorbar = set_colorbar; |
||||
sensor->set_gain_ctrl = set_dummy; |
||||
sensor->set_exposure_ctrl = set_exposure_ctrl; |
||||
sensor->set_whitebal = set_dummy; |
||||
sensor->set_hmirror = set_hmirror; |
||||
sensor->set_vflip = set_vflip; |
||||
sensor->init_status = init_status; |
||||
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_agc_gain = set_dummy; |
||||
sensor->set_raw_gma = set_dummy; |
||||
sensor->set_lenc = set_dummy; |
||||
sensor->set_denoise = set_dummy; |
||||
|
||||
sensor->get_reg = get_reg; |
||||
sensor->set_reg = set_reg; |
||||
sensor->set_res_raw = NULL; |
||||
sensor->set_pll = _set_pll; |
||||
sensor->set_xclk = set_xclk; |
||||
return 0; |
||||
} |
@ -0,0 +1,829 @@
@@ -0,0 +1,829 @@
|
||||
/*
|
||||
* |
||||
* HM1055 driver. |
||||
* |
||||
*/ |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "sccb.h" |
||||
#include "xclk.h" |
||||
#include "hm1055.h" |
||||
#include "hm1055_regs.h" |
||||
#include "hm1055_settings.h" |
||||
#include "freertos/FreeRTOS.h" |
||||
#include "freertos/task.h" |
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) |
||||
#include "esp32-hal-log.h" |
||||
#else |
||||
#include "esp_log.h" |
||||
static const char *TAG = "HM1055"; |
||||
#endif |
||||
|
||||
// #define REG_DEBUG_ON
|
||||
|
||||
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); |
||||
|
||||
static int read_reg(uint8_t slv_addr, const uint16_t reg) |
||||
{ |
||||
int ret = SCCB_Read16(slv_addr, reg); |
||||
#ifdef REG_DEBUG_ON |
||||
if (ret < 0) |
||||
{ |
||||
ESP_LOGE(TAG, "READ REG 0x%04x FAILED: %d", reg, ret); |
||||
} |
||||
#endif |
||||
return ret; |
||||
} |
||||
|
||||
static int check_reg_mask(uint8_t slv_addr, uint16_t reg, uint8_t mask) |
||||
{ |
||||
return (read_reg(slv_addr, reg) & mask) == mask; |
||||
} |
||||
|
||||
static int read_reg16(uint8_t slv_addr, const uint16_t reg) |
||||
{ |
||||
int ret = 0, ret2 = 0; |
||||
ret = read_reg(slv_addr, reg); |
||||
if (ret >= 0) |
||||
{ |
||||
ret = (ret & 0xFF) << 8; |
||||
ret2 = read_reg(slv_addr, reg + 1); |
||||
if (ret2 < 0) |
||||
{ |
||||
ret = ret2; |
||||
} |
||||
else |
||||
{ |
||||
ret |= ret2 & 0xFF; |
||||
} |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int write_reg(uint8_t slv_addr, const uint16_t reg, uint8_t value) |
||||
{ |
||||
int ret = 0; |
||||
#ifndef REG_DEBUG_ON |
||||
ret = SCCB_Write16(slv_addr, reg, value); |
||||
#else |
||||
int old_value = read_reg(slv_addr, reg); |
||||
if (old_value < 0) |
||||
{ |
||||
return old_value; |
||||
} |
||||
if ((uint8_t)old_value != value) |
||||
{ |
||||
ESP_LOGD(TAG, "NEW REG 0x%04x: 0x%02x to 0x%02x", reg, (uint8_t)old_value, value); |
||||
ret = SCCB_Write16(slv_addr, reg, value); |
||||
} |
||||
else |
||||
{ |
||||
ESP_LOGD(TAG, "OLD REG 0x%04x: 0x%02x", reg, (uint8_t)old_value); |
||||
ret = SCCB_Write16(slv_addr, reg, value); // maybe not?
|
||||
} |
||||
if (ret < 0) |
||||
{ |
||||
ESP_LOGE(TAG, "WRITE REG 0x%04x FAILED: %d", reg, ret); |
||||
} |
||||
#endif |
||||
return ret; |
||||
} |
||||
|
||||
static int set_reg_bits(uint8_t slv_addr, uint16_t reg, uint8_t offset, uint8_t mask, uint8_t value) |
||||
{ |
||||
int ret = 0; |
||||
uint8_t c_value, new_value; |
||||
ret = read_reg(slv_addr, reg); |
||||
if (ret < 0) |
||||
{ |
||||
return ret; |
||||
} |
||||
c_value = ret; |
||||
new_value = (c_value & ~(mask << offset)) | ((value & mask) << offset); |
||||
ret = write_reg(slv_addr, reg, new_value); |
||||
return ret; |
||||
} |
||||
|
||||
static int write_regs(uint8_t slv_addr, const uint16_t (*regs)[2]) |
||||
{ |
||||
int i = 0, ret = 0; |
||||
while (!ret && regs[i][0] != REGLIST_TAIL) |
||||
{ |
||||
if (regs[i][0] == REG_DLY) |
||||
{ |
||||
vTaskDelay(regs[i][1] / portTICK_PERIOD_MS); |
||||
} |
||||
else |
||||
{ |
||||
ret = write_reg(slv_addr, regs[i][0], regs[i][1]); |
||||
} |
||||
i++; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int write_reg16(uint8_t slv_addr, const uint16_t reg, uint16_t value) |
||||
{ |
||||
if (write_reg(slv_addr, reg, value >> 8) || write_reg(slv_addr, reg + 1, value)) |
||||
{ |
||||
return -1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static int write_addr_reg(uint8_t slv_addr, const uint16_t reg, uint16_t x_value, uint16_t y_value) |
||||
{ |
||||
if (write_reg16(slv_addr, reg, x_value) || write_reg16(slv_addr, reg + 2, y_value)) |
||||
{ |
||||
return -1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
#define write_reg_bits(slv_addr, reg, mask, enable) set_reg_bits(slv_addr, reg, 0, mask, (enable) ? (mask) : 0) |
||||
|
||||
static int set_ae_level(sensor_t *sensor, int level); |
||||
|
||||
static int reset(sensor_t *sensor) |
||||
{ |
||||
vTaskDelay(100 / portTICK_PERIOD_MS); |
||||
int ret = 0; |
||||
// Software Reset: clear all registers and reset them to their default values
|
||||
ret = write_reg(sensor->slv_addr, SFTRST, 0x55); |
||||
if (ret) |
||||
{ |
||||
ESP_LOGE(TAG, "Software Reset FAILED!"); |
||||
return ret; |
||||
} |
||||
vTaskDelay(100 / portTICK_PERIOD_MS); |
||||
ret = write_regs(sensor->slv_addr, sensor_default_regs); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Camera defaults loaded"); |
||||
vTaskDelay(100 / portTICK_PERIOD_MS); |
||||
set_ae_level(sensor, 0); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
switch (pixformat) |
||||
{ |
||||
case PIXFORMAT_RAW: |
||||
ret = write_reg(sensor->slv_addr, PORTCTRL, 0x20); |
||||
break; |
||||
case PIXFORMAT_YUV422: |
||||
ret = write_reg(sensor->slv_addr, PORTCTRL, 0x30); |
||||
break; |
||||
case PIXFORMAT_RGB565: |
||||
case PIXFORMAT_RGB888: |
||||
ret = write_reg(sensor->slv_addr, PORTCTRL, 0x40); |
||||
break; |
||||
case PIXFORMAT_RGB555: |
||||
ret = write_reg(sensor->slv_addr, PORTCTRL, 0x50); |
||||
break; |
||||
case PIXFORMAT_RGB444: |
||||
ret = write_reg(sensor->slv_addr, PORTCTRL, 0x60); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
if (ret == 0) |
||||
{ |
||||
sensor->pixformat = pixformat; |
||||
ESP_LOGD(TAG, "Set pixformat: %d", pixformat); |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
sensor->status.framesize = framesize; |
||||
ESP_LOGD(TAG, "Set framesize: %d", framesize); |
||||
ret = write_regs(sensor->slv_addr, sensor_default_regs); |
||||
if (framesize == FRAMESIZE_QQVGA) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_QQVGA"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_QQVGA); |
||||
} |
||||
else if (framesize == FRAMESIZE_QCIF) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_QCIF"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_QCIF); |
||||
} |
||||
else if (framesize == FRAMESIZE_240X240) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_240X240"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_240X240); |
||||
} |
||||
else if (framesize == FRAMESIZE_QVGA) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_QVGA"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_QVGA); |
||||
} |
||||
else if (framesize == FRAMESIZE_CIF) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_CIF"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_CIF); |
||||
} |
||||
else if (framesize == FRAMESIZE_VGA) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_VGA"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_VGA); |
||||
} |
||||
else if (framesize == FRAMESIZE_SVGA) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_SVGA"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_SVGA); |
||||
} |
||||
else if (framesize == FRAMESIZE_HD) |
||||
{ |
||||
ESP_LOGD(TAG, "Set FRAMESIZE_HD"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_HD); |
||||
ret = _set_pll(sensor, 0, 288, 1, 0, 0, 0, 1, 16); |
||||
} |
||||
else |
||||
{ |
||||
ESP_LOGD(TAG, "Dont suppost this size, Set FRAMESIZE_VGA"); |
||||
ret = write_regs(sensor->slv_addr, sensor_framesize_VGA); |
||||
} |
||||
|
||||
if (ret == 0) |
||||
{ |
||||
ret = write_reg(sensor->slv_addr, CMU, 0x01) || write_reg(sensor->slv_addr, TGRDCFG, 0x01); |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg_bits(sensor->slv_addr, RDCFG, 0x02, enable); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set hmirror to: %d", enable); |
||||
sensor->status.hmirror = enable; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg_bits(sensor->slv_addr, RDCFG, 0x01, enable); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set vflip to: %d", enable); |
||||
sensor->status.vflip = enable; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int set_quality(sensor_t *sensor, int qs) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static int set_colorbar(sensor_t *sensor, int enable) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static int set_gain_ctrl(sensor_t *sensor, int enable) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static int set_exposure_ctrl(sensor_t *sensor, int enable) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
ret = write_reg_bits(sensor->slv_addr, AEWBCFG, 0x01, enable); |
||||
|
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set aec to: %d", enable); |
||||
sensor->status.aec = enable; |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int set_whitebal(sensor_t *sensor, int enable) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
ret = write_reg_bits(sensor->slv_addr, AEWBCFG, 0x02, enable); |
||||
|
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set awb to: %d", enable); |
||||
sensor->status.awb = enable; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
// Gamma enable
|
||||
static int set_raw_gma_dsp(sensor_t *sensor, int enable) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg_bits(sensor->slv_addr, ISPCTRL1, 0x04, enable); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set raw_gma to: %d", enable); |
||||
sensor->status.raw_gma = enable; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static int set_lenc_dsp(sensor_t *sensor, int enable) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg_bits(sensor->slv_addr, ISPCTRL3, 0x40, enable); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set lenc to: %d", enable); |
||||
sensor->status.lenc = enable; |
||||
} |
||||
return -1; |
||||
} |
||||
// real gain
|
||||
static int set_agc_gain(sensor_t *sensor, int gain) |
||||
{ |
||||
int ret = 0; |
||||
if (gain < 0 || gain > 7) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
ret = write_reg(sensor->slv_addr, AGAIN, gain); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set gain to: %d", gain); |
||||
sensor->status.agc_gain = gain; |
||||
} |
||||
return 0; |
||||
} |
||||
static int set_aec_value(sensor_t *sensor, int value) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg(sensor->slv_addr, AETARGM, value); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set aec_value to: %d", value); |
||||
sensor->status.aec_value = value; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int set_ae_level(sensor_t *sensor, int level) |
||||
{ |
||||
int ret = 0; |
||||
if (level < -5 || level > 5) |
||||
{ |
||||
return -1; |
||||
} |
||||
uint8_t target_level = ((level + 5) * 10) + 5; |
||||
uint8_t upper = target_level * 27 / 25; |
||||
uint8_t lower = target_level * 23 / 25; |
||||
|
||||
ret = write_reg(sensor->slv_addr, AETARGU, upper) || write_reg(sensor->slv_addr, AETARGL, lower); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set ae_level to: %d", level); |
||||
sensor->status.ae_level = level; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static int set_brightness(sensor_t *sensor, int level) |
||||
{ |
||||
int ret = 0; |
||||
uint8_t ispctrl5 = read_reg(sensor->slv_addr, ISPCTRL5); |
||||
uint8_t brightness = 0; |
||||
|
||||
switch (level) |
||||
{ |
||||
case 3: |
||||
brightness = 0xFF; |
||||
break; |
||||
|
||||
case 2: |
||||
brightness = 0xBA; |
||||
break; |
||||
|
||||
case 1: |
||||
brightness = 0x96; |
||||
break; |
||||
|
||||
case 0: |
||||
brightness = 0x72; |
||||
break; |
||||
|
||||
case -1: |
||||
brightness = 0x48; |
||||
break; |
||||
|
||||
case -2: |
||||
brightness = 0x24; |
||||
break; |
||||
|
||||
case -3: |
||||
brightness = 0x00; |
||||
break; |
||||
|
||||
default: // 0
|
||||
break; |
||||
} |
||||
|
||||
ispctrl5 |= 0x40; // enable brightness
|
||||
ret = write_reg(sensor->slv_addr, ISPCTRL5, ispctrl5); |
||||
ret = write_reg(sensor->slv_addr, BRIGHT, brightness); |
||||
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; |
||||
uint8_t ispctrl5 = read_reg(sensor->slv_addr, ISPCTRL5); |
||||
|
||||
ispctrl5 |= 0x80; // enable contrast
|
||||
ret = write_reg(sensor->slv_addr, ISPCTRL5, ispctrl5); |
||||
ret = write_reg(sensor->slv_addr, ACONTQ, (level * 0x20) & 0xFF); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set contrast to: %d", level); |
||||
sensor->status.contrast = level; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int set_saturation(sensor_t *sensor, int level) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg(sensor->slv_addr, SAT, (level * 0x20) + 0x4A); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set saturation to: %d", level); |
||||
sensor->status.saturation = level; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int get_sharpness(sensor_t *sensor) |
||||
{ |
||||
int ret = 0; |
||||
int level = 0; |
||||
ret = read_reg(sensor->slv_addr, EDGE); |
||||
|
||||
level = (ret - 0x60) / 0x20; |
||||
ESP_LOGD(TAG, "Get sharpness: %d", level); |
||||
|
||||
return level; |
||||
} |
||||
static int set_sharpness(sensor_t *sensor, int level) |
||||
{ |
||||
int ret = 0; |
||||
ret = write_reg(sensor->slv_addr, EDGE, (level * 0x20) + 0x60); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set sharpness to: %d", level); |
||||
sensor->status.sharpness = level; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int get_denoise(sensor_t *sensor) |
||||
{ |
||||
int ret = 0; |
||||
int level = 0; |
||||
ret = read_reg(sensor->slv_addr, YDN); |
||||
|
||||
level = (ret - 0x07) / 2; |
||||
ESP_LOGD(TAG, "Get denoise: %d", level); |
||||
|
||||
return level; |
||||
} |
||||
static int set_denoise(sensor_t *sensor, int level) |
||||
{ |
||||
int ret = 0; |
||||
uint8_t ispctrl5 = read_reg(sensor->slv_addr, ISPCTRL5); |
||||
|
||||
ispctrl5 |= 0x20; // enable denoise
|
||||
ret = write_reg(sensor->slv_addr, ISPCTRL5, ispctrl5); |
||||
ret = write_reg(sensor->slv_addr, YDN, (level * 2) + 0x07); |
||||
|
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set denoise to: %d", level); |
||||
sensor->status.denoise = level; |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int get_reg(sensor_t *sensor, int reg, int mask) |
||||
{ |
||||
int ret = 0, ret2 = 0; |
||||
if (mask > 0xFF) |
||||
{ |
||||
ret = read_reg16(sensor->slv_addr, reg); |
||||
if (ret >= 0 && mask > 0xFFFF) |
||||
{ |
||||
ret2 = read_reg(sensor->slv_addr, reg + 2); |
||||
if (ret2 >= 0) |
||||
{ |
||||
ret = (ret << 8) | ret2; |
||||
} |
||||
else |
||||
{ |
||||
ret = ret2; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
ret = read_reg(sensor->slv_addr, reg); |
||||
} |
||||
if (ret > 0) |
||||
{ |
||||
ret &= mask; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int set_reg(sensor_t *sensor, int reg, int mask, int value) |
||||
{ |
||||
int ret = 0, ret2 = 0; |
||||
if (mask > 0xFF) |
||||
{ |
||||
ret = read_reg16(sensor->slv_addr, reg); |
||||
if (ret >= 0 && mask > 0xFFFF) |
||||
{ |
||||
ret2 = read_reg(sensor->slv_addr, reg + 2); |
||||
if (ret2 >= 0) |
||||
{ |
||||
ret = (ret << 8) | ret2; |
||||
} |
||||
else |
||||
{ |
||||
ret = ret2; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
ret = read_reg(sensor->slv_addr, reg); |
||||
} |
||||
if (ret < 0) |
||||
{ |
||||
return ret; |
||||
} |
||||
value = (ret & ~mask) | (value & mask); |
||||
if (mask > 0xFFFF) |
||||
{ |
||||
ret = write_reg16(sensor->slv_addr, reg, value >> 8); |
||||
if (ret >= 0) |
||||
{ |
||||
ret = write_reg(sensor->slv_addr, reg + 2, value & 0xFF); |
||||
} |
||||
} |
||||
else if (mask > 0xFF) |
||||
{ |
||||
ret = write_reg16(sensor->slv_addr, reg, value); |
||||
} |
||||
else |
||||
{ |
||||
ret = write_reg(sensor->slv_addr, reg, value); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
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 0; |
||||
} |
||||
|
||||
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) |
||||
{ |
||||
int ret = 0; |
||||
uint8_t ckcfg1 = 0; |
||||
uint8_t ckcfg2 = 0; |
||||
uint8_t ckcfg3 = 0; |
||||
uint8_t pll2 = 0; |
||||
|
||||
if (sensor->xclk_freq_hz <= 6000000) |
||||
{ |
||||
ckcfg2 = 0x00; |
||||
} |
||||
else if (sensor->xclk_freq_hz <= 12000000) |
||||
{ |
||||
ckcfg2 = 0x20; |
||||
} |
||||
else if (sensor->xclk_freq_hz <= 18000000) |
||||
{ |
||||
ckcfg2 = 0x40; |
||||
} |
||||
else if (sensor->xclk_freq_hz <= 24000000) |
||||
{ |
||||
ckcfg2 = 0x60; |
||||
} |
||||
else if (sensor->xclk_freq_hz <= 30000000) |
||||
{ |
||||
ckcfg2 = 0x80; |
||||
} |
||||
else if (sensor->xclk_freq_hz <= 36000000) |
||||
{ |
||||
ckcfg2 = 0xA0; |
||||
} |
||||
else if (sensor->xclk_freq_hz <= 42000000) |
||||
{ |
||||
ckcfg2 = 0xC0; |
||||
} |
||||
else |
||||
{ // max is 48000000
|
||||
ckcfg2 = 0xE0; |
||||
} |
||||
|
||||
if (bypass == 0) |
||||
{ |
||||
switch (multiplier) |
||||
{ |
||||
case 204: |
||||
ckcfg2 |= 10; |
||||
break; |
||||
case 216: |
||||
ckcfg2 |= 11; |
||||
break; |
||||
case 228: |
||||
ckcfg2 |= 0x12; |
||||
break; |
||||
case 240: |
||||
ckcfg2 |= 0x13; |
||||
break; |
||||
case 288: |
||||
ckcfg2 |= 0x17; |
||||
break; |
||||
case 300: |
||||
ckcfg2 |= 0x18; |
||||
break; |
||||
case 312: |
||||
ckcfg2 |= 0x19; |
||||
break; |
||||
case 324: |
||||
ckcfg2 |= 0x1A; |
||||
break; |
||||
case 336: |
||||
ckcfg2 |= 0x1B; |
||||
break; |
||||
case 348: |
||||
ckcfg2 |= 0x1C; |
||||
break; |
||||
case 360: |
||||
ckcfg2 |= 0x1D; |
||||
break; |
||||
default: |
||||
ckcfg2 |= 0x17; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (pclk_manual > 0) |
||||
{ |
||||
if (pclk_div > 128) |
||||
{ |
||||
pclk_div = 128; |
||||
} |
||||
if (pclk_div < 1) |
||||
{ |
||||
pclk_div = 1; |
||||
} |
||||
ckcfg1 |= (pclk_div - 1); |
||||
} |
||||
|
||||
if (root_2x > 0) |
||||
{ |
||||
ckcfg3 = 0x00; |
||||
} |
||||
else |
||||
{ |
||||
ckcfg3 = 0x01; |
||||
} |
||||
|
||||
ESP_LOGD(TAG, "ckcfg1 = 0x%02x, ckcfg2 = 0x%02x, ckcfg3 = 0x%02x, pll2 = 0x%02x", ckcfg1, ckcfg2, ckcfg3, pll2); |
||||
ret = write_reg(sensor->slv_addr, CKCFG1, ckcfg1); |
||||
ret = write_reg(sensor->slv_addr, CKCFG2, ckcfg2); |
||||
ret = write_reg(sensor->slv_addr, CKCFG3, ckcfg3); |
||||
ret = write_reg(sensor->slv_addr, PLL2, pll2); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
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); |
||||
if (ret == 0) |
||||
{ |
||||
ESP_LOGD(TAG, "Set xclk to %d", xclk); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static int init_status(sensor_t *sensor) |
||||
{ |
||||
(void) write_addr_reg; |
||||
|
||||
sensor->status.brightness = 0; |
||||
sensor->status.contrast = 0; |
||||
sensor->status.saturation = 0; |
||||
sensor->status.sharpness = get_sharpness(sensor); |
||||
sensor->status.denoise = get_denoise(sensor); |
||||
sensor->status.ae_level = 0; |
||||
sensor->status.awb = check_reg_mask(sensor->slv_addr, AEWBCFG, 0x02); |
||||
sensor->status.agc = true; |
||||
sensor->status.aec = check_reg_mask(sensor->slv_addr, AEWBCFG, 0x04); |
||||
sensor->status.hmirror = check_reg_mask(sensor->slv_addr, RDCFG, 0x02); |
||||
sensor->status.vflip = check_reg_mask(sensor->slv_addr, RDCFG, 0x01); |
||||
sensor->status.lenc = check_reg_mask(sensor->slv_addr, ISPCTRL3, 0x40); |
||||
sensor->status.awb_gain = read_reg(sensor->slv_addr, DGAIN); |
||||
sensor->status.agc_gain = read_reg(sensor->slv_addr, AGAIN); |
||||
sensor->status.aec_value = read_reg(sensor->slv_addr, AETARGM); |
||||
return 0; |
||||
} |
||||
|
||||
int hm1055_detect(int slv_addr, sensor_id_t *id) |
||||
{ |
||||
if (HM1055_SCCB_ADDR == slv_addr) |
||||
{ |
||||
uint8_t h = SCCB_Read16(slv_addr, IDH); |
||||
uint8_t l = SCCB_Read16(slv_addr, IDL); |
||||
uint16_t PID = (h << 8) | l; |
||||
if (HM1055_PID == PID) |
||||
{ |
||||
id->PID = PID; |
||||
return PID; |
||||
} |
||||
else |
||||
{ |
||||
ESP_LOGD(TAG, "Mismatch PID=0x%x", PID); |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
int hm1055_init(sensor_t *sensor) |
||||
{ |
||||
sensor->reset = reset; |
||||
sensor->set_pixformat = set_pixformat; |
||||
sensor->set_framesize = set_framesize; |
||||
sensor->set_contrast = set_contrast; |
||||
sensor->set_brightness = set_brightness; |
||||
sensor->set_saturation = set_saturation; |
||||
sensor->set_sharpness = set_sharpness; |
||||
sensor->set_gainceiling = NULL; |
||||
sensor->set_quality = set_quality; |
||||
sensor->set_colorbar = set_colorbar; |
||||
sensor->set_gain_ctrl = set_gain_ctrl; |
||||
sensor->set_exposure_ctrl = set_exposure_ctrl; |
||||
sensor->set_whitebal = set_whitebal; |
||||
sensor->set_hmirror = set_hmirror; |
||||
sensor->set_vflip = set_vflip; |
||||
sensor->init_status = init_status; |
||||
sensor->set_aec2 = NULL; |
||||
sensor->set_aec_value = set_aec_value; |
||||
sensor->set_special_effect = NULL; |
||||
sensor->set_wb_mode = NULL; |
||||
sensor->set_ae_level = set_ae_level; |
||||
sensor->set_dcw = NULL; |
||||
sensor->set_bpc = NULL; |
||||
sensor->set_wpc = NULL; |
||||
sensor->set_agc_gain = set_agc_gain; |
||||
sensor->set_raw_gma = set_raw_gma_dsp; |
||||
sensor->set_lenc = set_lenc_dsp; |
||||
sensor->set_denoise = set_denoise; |
||||
|
||||
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; |
||||
return 0; |
||||
} |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* HM0360 driver. |
||||
*/ |
||||
#ifndef __HM0360_H__ |
||||
#define __HM0360_H__ |
||||
#include "sensor.h" |
||||
/**
|
||||
* @brief Detect sensor pid |
||||
* |
||||
* @param slv_addr SCCB address |
||||
* @param id Detection result |
||||
* @return |
||||
* 0: Can't detect this sensor |
||||
* Nonzero: This sensor has been detected |
||||
*/ |
||||
int hm0360_detect(int slv_addr, sensor_id_t *id); |
||||
|
||||
/**
|
||||
* @brief initialize sensor function pointers |
||||
* |
||||
* @param sensor pointer of sensor |
||||
* @return |
||||
* Always 0 |
||||
*/ |
||||
int hm0360_init(sensor_t *sensor); |
||||
|
||||
#endif // __HM1055_H__
|
@ -0,0 +1,150 @@
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* HM1055 register definitions. |
||||
*/ |
||||
#ifndef __REG_REGS_H__ |
||||
#define __REG_REGS_H__ |
||||
|
||||
// Sensor ID
|
||||
#define MODEL_ID_H 0x0000 |
||||
#define MODEL_ID_L 0x0001 |
||||
#define SILICON_REV 0x0002 |
||||
#define FRAME_COUNT_H 0x0005 |
||||
#define FRAME_COUNT_L 0x0006 |
||||
#define PIXEL_ODERDER 0x0007 |
||||
|
||||
// Snesor mode control
|
||||
#define MODEL_SELECT 0x0100 |
||||
#define IMAGE_ORIENTATION 0x0101 |
||||
#define EMBEDDED_LINE_EN 0x0102 |
||||
#define SW_RESET 0x0103 |
||||
#define COMMAND_UPDATE 0x0104 |
||||
|
||||
// Sensor exposure gain control
|
||||
#define INTEGRATION_H 0x0202 |
||||
#define INTEGRATION_L 0x0203 |
||||
#define ANALOG_GAIN 0x0205 |
||||
#define DIGITAL_GAIN_H 0x020E |
||||
#define DIGITAL_GAIN_L 0x020F |
||||
|
||||
// clock control
|
||||
#define PLL1CFG 0x0300 |
||||
#define PLL2CFG 0x0301 |
||||
#define PLL3CFG 0x0302 |
||||
|
||||
// frame timming control
|
||||
#define FRAME_LENGTH_LINES_H 0x0340 |
||||
#define FRAME_LENGTH_LINES_L 0x0341 |
||||
#define LINE_LENGTH_PCK_H 0x0342 |
||||
#define LINE_LENGTH_PCK_L 0x0343 |
||||
|
||||
// monochrome programming
|
||||
#define MONO_MODE 0x0370 |
||||
#define MONO_MODE_ISP 0x0371 |
||||
#define MONO_MODE_SEL 0x0372 |
||||
|
||||
// sub-sampling / binning control
|
||||
#define H_SUB 0x0380 |
||||
#define V_SUB 0x0381 |
||||
#define BINNING_MODE 0x0382 |
||||
|
||||
// test pattern control
|
||||
#define TEST_PATTERN_MODE 0x0601 |
||||
#define TEST_DATA_BLUE_H 0x0602 |
||||
#define TEST_DATA_BLUE_L 0x0603 |
||||
#define TEST_DATA_GB_H 0x0604 |
||||
#define TEST_DATA_GB_L 0x0605 |
||||
#define TEST_DATA_GR_H 0x0605 |
||||
#define TEST_DATA_GR_L 0x0606 |
||||
#define TEST_DATA_RED_H 0x0608 |
||||
#define TEST_DATA_RED_L 0x0609 |
||||
|
||||
// black level control
|
||||
#define BLC_TGT 0x1004 |
||||
#define BLC2_TGT 0x1009 |
||||
|
||||
// monochrome programming
|
||||
#define MONO_CTRL 0x100A |
||||
|
||||
// VSYNC / HSYNC / pixel shift
|
||||
#define OPFM_CTRL 0x1014 |
||||
|
||||
// Tone mapping registers
|
||||
#define CMPRS_CTRL 0x102F |
||||
#define CMPRS_01 0x1030 |
||||
#define CMPRS_02 0x1031 |
||||
#define CMPRS_03 0x1032 |
||||
#define CMPRS_04 0x1033 |
||||
#define CMPRS_05 0x1034 |
||||
#define CMPRS_06 0x1035 |
||||
#define CMPRS_07 0x1036 |
||||
#define CMPRS_08 0x1037 |
||||
#define CMPRS_09 0x1038 |
||||
#define CMPRS_10 0x1039 |
||||
#define CMPRS_11 0x103A |
||||
#define CMPRS_12 0x103B |
||||
#define CMPRS_13 0x103C |
||||
#define CMPRS_14 0x103D |
||||
#define CMPRS_15 0x103E |
||||
#define CMPRS_16 0x103F |
||||
|
||||
// automatic exposure programming
|
||||
#define AE_CTRL 0x2000 |
||||
#define AE_CTRL1 0x2001 |
||||
#define CNT_ORG_H_H 0x2002 |
||||
#define CNT_ORG_H_L 0x2003 |
||||
#define CNT_ORG_V_H 0x2004 |
||||
#define CNT_ORG_V_L 0x2005 |
||||
#define CNT_ST_H_H 0x2006 |
||||
#define CNT_ST_H_L 0x2007 |
||||
#define CNT_ST_V_H 0x2008 |
||||
#define CNT_ST_V_L 0x2009 |
||||
#define CTRL_PG_SKIPCNT 0x200A |
||||
#define BV_WIN_WEIGHT_EN 0x200D |
||||
#define MAX_INTG_H 0x2029 |
||||
#define MAX_INTG_L 0x202A |
||||
#define MAX_AGAIN 0x202B |
||||
#define MAX_DGAIN_H 0x202C |
||||
#define MAX_DGAIN_L 0x202D |
||||
#define MIN_INTG 0x202E |
||||
#define MIN_AGAIN 0x202F |
||||
#define MIN_DGAIN 0x2030 |
||||
#define T_DAMPING 0x2031 |
||||
#define N_DAMPING 0x2032 |
||||
#define ALC_TH 0x2033 |
||||
#define AE_TARGET_MEAN 0x2034 |
||||
#define AE_MIN_MEAN 0x2035 |
||||
#define AE_TARGET_ZONE 0x2036 |
||||
#define CONVERGE_IN_TH 0x2037 |
||||
#define CONVERGE_OUT_TH 0x2038 |
||||
|
||||
// Interrupt control
|
||||
#define PULSE_MODE 0x2061 |
||||
#define PULSE_TH_H 0x2062 |
||||
#define PULSE_TH_L 0x2063 |
||||
#define INT_INDIC 0x2064 |
||||
#define INT_CLEAR 0x2065 |
||||
|
||||
// Motion detection control
|
||||
#define MD_CTRL 0x2080 |
||||
#define ROI_START_END_V 0x2081 |
||||
#define ROI_START_END_H 0x2082 |
||||
#define MD_TH_MIN 0x2083 |
||||
#define MD_TH_STR_L 0x2084 |
||||
#define MD_TH_STR_H 0x2085 |
||||
#define MD_LIGHT_COEF 0x2099 |
||||
#define MD_BLOCK_NUM_TH 0x209B |
||||
#define MD_LATENCY 0x209C |
||||
#define MD_LATENCY_TH 0x209D |
||||
#define MD_CTRL1 0x209E |
||||
|
||||
// Context switch control registers
|
||||
#define PMU_CFG_3 0x3024 |
||||
#define PMU_CFG_4 0x3025 |
||||
|
||||
// Operation mode control
|
||||
#define WIN_MODE 0x3030 |
||||
|
||||
// IO and clock control
|
||||
#define PAD_REGISTER_07 0x3112 |
||||
|
||||
#endif //__REG_REGS_H__
|
@ -0,0 +1,549 @@
@@ -0,0 +1,549 @@
|
||||
|
||||
#include <stdint.h> |
||||
|
||||
#define REG_DLY 0xffff |
||||
#define REGLIST_TAIL 0x0000 |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_default_regs[][2] = { |
||||
{0x0103, 0x00}, |
||||
{REG_DLY, 100}, |
||||
{0x3035, 0x01}, |
||||
{0x3126, 0x03}, |
||||
{0x3128, 0x57}, |
||||
{0x3142, 0x9F}, |
||||
{0x311C, 0x10}, |
||||
{0x3115, 0x42}, |
||||
{0x3116, 0x10}, |
||||
{0x3117, 0x0A}, |
||||
{0x310B, 0x10}, |
||||
{0x3031, 0x01}, |
||||
{0x312E, 0x00}, |
||||
{0x30D7, 0x00}, |
||||
{0x30DC, 0x00}, |
||||
{0x30E1, 0x00}, |
||||
{0x30E6, 0x00}, |
||||
{0x30EB, 0x00}, |
||||
{0x30F0, 0x00}, |
||||
{0x30F5, 0x00}, |
||||
{0x30FA, 0x00}, |
||||
{0x30FF, 0x00}, |
||||
{0x3104, 0x00}, |
||||
{0x30D8, 0xA7}, |
||||
{0x30DD, 0x27}, |
||||
{0x30E2, 0x27}, |
||||
{0x30E7, 0x27}, |
||||
{0x30EC, 0x27}, |
||||
{0x30F1, 0xA7}, |
||||
{0x30F6, 0x27}, |
||||
{0x30FB, 0x27}, |
||||
{0x3100, 0x27}, |
||||
{0x3105, 0x27}, |
||||
{0x30D9, 0x00}, // 220215
|
||||
{0x30DE, 0x05}, |
||||
{0x30E3, 0x05}, |
||||
{0x30E8, 0x05}, |
||||
{0x30ED, 0x05}, |
||||
{0x30F2, 0x00}, // 220215
|
||||
{0x30F7, 0x05}, |
||||
{0x30FC, 0x05}, |
||||
{0x3101, 0x05}, |
||||
{0x3106, 0x05}, |
||||
{0x30C4, 0x10}, |
||||
{0x30C5, 0x01}, |
||||
{0x30C6, 0x2F}, // 220215
|
||||
{0x30CB, 0xFF}, |
||||
{0x30CC, 0xFF}, |
||||
{0x30CD, 0x7F}, |
||||
{0x30CE, 0x7F}, |
||||
{0x30D3, 0x01}, |
||||
{0x30D4, 0xFF}, |
||||
{0x311F, 0x0E}, |
||||
{0x3120, 0x0D}, |
||||
{0x3121, 0x0F}, |
||||
{0x3122, 0x00}, |
||||
{0x3147, 0x18}, |
||||
{0x314B, 0x01}, |
||||
{0x3149, 0x28}, |
||||
{0x3150, 0x50}, |
||||
{0x3152, 0x00}, |
||||
{0x3156, 0x2C}, |
||||
{0x3163, 0x1F}, |
||||
{0x3165, 0x7F}, |
||||
{0x312B, 0x41}, |
||||
{0x3113, 0xA0}, |
||||
{0x3114, 0x67}, |
||||
{0x317D, 0x02}, |
||||
{0x3160, 0x1F}, |
||||
{0x318C, 0x00}, |
||||
{0x315C, 0xE0}, |
||||
{0x311E, 0x0F}, |
||||
{0x30D5, 0x00}, |
||||
{0x30DA, 0x01}, |
||||
{0x30DF, 0x07}, |
||||
{0x30E4, 0x47}, |
||||
{0x30E9, 0x87}, |
||||
{0x30FD, 0x47}, |
||||
{0x3102, 0x87}, |
||||
{0x311D, 0x06}, |
||||
{0x3141, 0x2A}, |
||||
{0x315A, 0x0A}, |
||||
{0x30D6, 0x40}, |
||||
{0x30DB, 0x40}, |
||||
{0x30E0, 0x40}, |
||||
{0x30E5, 0x30}, |
||||
{0x30EA, 0x30}, |
||||
{0x30EF, 0x40}, |
||||
{0x30F4, 0x40}, |
||||
{0x30F9, 0x40}, |
||||
{0x30FE, 0x30}, |
||||
{0x3103, 0x30}, |
||||
{0x3164, 0x7F}, |
||||
{0x282A, 0x0F}, |
||||
{0x282E, 0x2F}, |
||||
{0x282B, 0x08}, |
||||
{0x312A, 0x11}, |
||||
{0x1000, 0x43}, |
||||
{0x1001, 0x80}, |
||||
{0x0350, 0xE0}, |
||||
{0x101D, 0xCF}, |
||||
{0x1021, 0x5D}, |
||||
|
||||
// setA VGA
|
||||
{0x3500, 0x74}, |
||||
{0x3501, 0x0A}, |
||||
{0x3502, 0x77}, |
||||
{0x3503, 0x04}, |
||||
{0x3504, 0x14}, |
||||
{0x3505, 0x03}, |
||||
{0x3506, 0x00}, |
||||
{0x3507, 0x00}, |
||||
{0x3508, 0x00}, |
||||
{0x3509, 0x00}, |
||||
{0x350A, 0xFF}, |
||||
{0x350B, 0x00}, |
||||
{0x350D, 0x01}, |
||||
{0x350C, 0x00}, |
||||
{0x350F, 0x00}, |
||||
{0x3510, 0x01}, |
||||
{0x3513, 0x00}, |
||||
{0x351C, 0x00}, |
||||
{0x3514, 0x00}, |
||||
{0x3515, 0x01}, |
||||
{0x3516, 0x00}, |
||||
{0x3517, 0x02}, |
||||
{0x3518, 0x00}, |
||||
{0x3519, 0x7F}, |
||||
{0x351A, 0x00}, |
||||
{0x351B, 0x5F}, |
||||
{0x351D, 0x04}, |
||||
{0x351E, 0x10}, |
||||
{0x352A, 0x01}, |
||||
{0x352B, 0x04}, |
||||
{0x352C, 0x01}, |
||||
{0x352D, 0x38}, |
||||
{0x354B, 0x21}, |
||||
{0x354C, 0x01}, |
||||
{0x354D, 0xE0}, |
||||
{0x354E, 0xF0}, |
||||
{0x354F, 0x10}, |
||||
{0x3550, 0x10}, |
||||
{0x3551, 0x10}, |
||||
{0x3552, 0x20}, |
||||
{0x3553, 0x10}, |
||||
{0x3554, 0x01}, |
||||
{0x3555, 0x06}, |
||||
{0x3556, 0x0C}, |
||||
{0x3557, 0x12}, |
||||
{0x3558, 0x1C}, |
||||
{0x3559, 0x30}, |
||||
{0x3549, 0x04}, |
||||
{0x354A, 0x35}, |
||||
|
||||
// setB QVGA
|
||||
{0x355A, 0x74}, |
||||
{0x355B, 0x0A}, |
||||
{0x355C, 0x77}, |
||||
{0x355D, 0x04}, |
||||
{0x355E, 0x14}, |
||||
{0x355F, 0x03}, |
||||
{0x3560, 0x00}, |
||||
{0x3561, 0x01}, |
||||
{0x3562, 0x01}, |
||||
{0x3563, 0x00}, |
||||
{0x3564, 0xFF}, |
||||
{0x3565, 0x00}, |
||||
{0x3567, 0x01}, |
||||
{0x3566, 0x00}, |
||||
{0x3569, 0x00}, |
||||
{0x356A, 0x01}, |
||||
{0x356D, 0x00}, |
||||
{0x3576, 0x00}, |
||||
{0x356E, 0x00}, |
||||
{0x356F, 0x01}, |
||||
{0x3570, 0x00}, |
||||
{0x3571, 0x02}, |
||||
{0x3572, 0x00}, |
||||
{0x3573, 0x3F}, |
||||
{0x3574, 0x00}, |
||||
{0x3575, 0x2F}, |
||||
{0x3577, 0x04}, |
||||
{0x3578, 0x10}, |
||||
{0x3584, 0x01}, |
||||
{0x3585, 0x04}, |
||||
{0x3586, 0x01}, |
||||
{0x3587, 0x38}, |
||||
{0x3588, 0x02}, |
||||
{0x3589, 0x12}, |
||||
{0x358A, 0x04}, |
||||
{0x358B, 0x24}, |
||||
{0x358C, 0x06}, |
||||
{0x358D, 0x36}, |
||||
{0x35A5, 0x21}, |
||||
{0x35A6, 0x01}, |
||||
{0x35A7, 0xE0}, |
||||
{0x35A8, 0xF0}, |
||||
{0x35A9, 0x10}, |
||||
{0x35AA, 0x10}, |
||||
{0x35AB, 0x10}, |
||||
{0x35AC, 0x20}, |
||||
{0x35AD, 0x10}, |
||||
{0x35AE, 0x01}, |
||||
{0x35AF, 0x06}, |
||||
{0x35B0, 0x0C}, |
||||
{0x35B1, 0x12}, |
||||
{0x35B2, 0x1C}, |
||||
{0x35B3, 0x30}, |
||||
{0x35A3, 0x02}, |
||||
{0x35A4, 0x03}, |
||||
|
||||
// AE_tuning
|
||||
{0x3512, 0x3F}, |
||||
{0x351F, 0x04}, |
||||
{0x3520, 0x03}, |
||||
{0x3521, 0x00}, |
||||
{0x3523, 0x60}, |
||||
{0x3524, 0x08}, |
||||
{0x3525, 0x19}, |
||||
{0x3526, 0x08}, |
||||
{0x3527, 0x10}, |
||||
{0x356C, 0x3F}, |
||||
{0x3579, 0x04}, |
||||
{0x357A, 0x03}, |
||||
{0x357B, 0x00}, |
||||
{0x357D, 0x60}, |
||||
{0x357E, 0x08}, |
||||
{0x357F, 0x19}, |
||||
{0x3580, 0x08}, |
||||
{0x3581, 0x10}, |
||||
{0x2048, 0x00}, |
||||
{0x2049, 0x10}, |
||||
{0x204A, 0x40}, |
||||
{0x204E, 0x00}, |
||||
{0x204F, 0x38}, |
||||
{0x2050, 0xE0}, |
||||
{0x204B, 0x00}, |
||||
{0x204C, 0x08}, |
||||
{0x204D, 0x20}, |
||||
{0x2051, 0x00}, |
||||
{0x2052, 0x1C}, |
||||
{0x2053, 0x70}, |
||||
{0x2054, 0x00}, |
||||
{0x2055, 0x1A}, |
||||
{0x2056, 0xC0}, |
||||
{0x2057, 0x00}, |
||||
{0x2058, 0x06}, |
||||
{0x2059, 0xB0}, |
||||
|
||||
// MD tuning
|
||||
{0x2080, 0x41}, |
||||
{0x2083, 0x01}, |
||||
{0x208D, 0x02}, |
||||
{0x208E, 0x08}, |
||||
{0x208F, 0x0D}, |
||||
{0x2090, 0x14}, |
||||
{0x2091, 0x1D}, |
||||
{0x2092, 0x30}, |
||||
{0x2093, 0x08}, |
||||
{0x2094, 0x0A}, |
||||
{0x2095, 0x0F}, |
||||
{0x2096, 0x14}, |
||||
{0x2097, 0x18}, |
||||
{0x2098, 0x20}, |
||||
{0x2099, 0x10}, |
||||
{0x209A, 0x00}, |
||||
{0x209B, 0x01}, |
||||
{0x209C, 0x01}, |
||||
{0x209D, 0x11}, |
||||
{0x209E, 0x06}, |
||||
|
||||
// Tone mapping
|
||||
{0x1030, 0x04}, |
||||
{0x1031, 0x08}, |
||||
{0x1032, 0x10}, |
||||
{0x1033, 0x18}, |
||||
{0x1034, 0x20}, |
||||
{0x1035, 0x28}, |
||||
{0x1036, 0x30}, |
||||
{0x1037, 0x38}, |
||||
{0x1038, 0x40}, |
||||
{0x1039, 0x50}, |
||||
{0x103A, 0x60}, |
||||
{0x103B, 0x70}, |
||||
{0x103C, 0x80}, |
||||
{0x103D, 0xA0}, |
||||
{0x103E, 0xC0}, |
||||
{0x103F, 0xE0}, |
||||
|
||||
// RESERVED
|
||||
{0x35B4, 0x74}, |
||||
{0x35B5, 0x0A}, |
||||
{0x35B6, 0x77}, |
||||
{0x35B7, 0x00}, |
||||
{0x35B8, 0x94}, |
||||
{0x35B9, 0x03}, |
||||
{0x35BA, 0x00}, |
||||
{0x35BB, 0x03}, |
||||
{0x35BD, 0x00}, |
||||
{0x35BE, 0xFF}, |
||||
{0x35BF, 0x00}, |
||||
{0x35C1, 0x01}, |
||||
{0x35C0, 0x01}, |
||||
{0x35C3, 0x00}, |
||||
{0x35C4, 0x00}, |
||||
{0x35C6, 0x3F}, |
||||
{0x35C7, 0x00}, |
||||
{0x35D0, 0x00}, |
||||
{0x35D3, 0x04}, |
||||
{0x35D7, 0x18}, |
||||
{0x35D8, 0x01}, |
||||
{0x35D9, 0x20}, |
||||
{0x35DA, 0x08}, |
||||
{0x35DB, 0x14}, |
||||
{0x35DC, 0x70}, |
||||
{0x35C8, 0x00}, |
||||
{0x35C9, 0x01}, |
||||
{0x35CA, 0x00}, |
||||
{0x35CB, 0x02}, |
||||
{0x35CC, 0x00}, |
||||
{0x35CD, 0x0F}, |
||||
{0x35CE, 0x00}, |
||||
{0x35CF, 0x0B}, |
||||
{0x35DE, 0x00}, |
||||
{0x35DF, 0x01}, |
||||
{0x35FD, 0x00}, |
||||
{0x35FE, 0x5E}, |
||||
|
||||
// RESERVED
|
||||
{0x3024, 0x00}, |
||||
{0x3025, 0x12}, |
||||
{0x3026, 0x03}, |
||||
{0x3027, 0x81}, |
||||
{0x3028, 0x01}, |
||||
{0x3029, 0x00}, |
||||
{0x302A, 0x30}, |
||||
|
||||
// Interrupt
|
||||
{0x2061, 0x00}, |
||||
{0x2062, 0x00}, |
||||
{0x2063, 0xC8}, |
||||
|
||||
// Parallel I/F
|
||||
{0x1014, 0x00}, |
||||
{0x102F, 0x08}, |
||||
{0x309E, 0x05}, |
||||
{0x309F, 0x02}, |
||||
{0x30A0, 0x02}, |
||||
{0x30A1, 0x00}, |
||||
{0x30A2, 0x08}, |
||||
{0x30A3, 0x00}, |
||||
{0x30A4, 0x20}, |
||||
{0x30A5, 0x04}, |
||||
{0x30A6, 0x02}, |
||||
{0x30A7, 0x02}, |
||||
{0x30A8, 0x01}, |
||||
{0x30B0, 0x03}, |
||||
{0x3112, 0x04}, |
||||
{0x311A, 0x30}, //31:bypass internal ldo 30:internal LDO
|
||||
|
||||
// MIPI
|
||||
{0x2800, 0x00}, |
||||
|
||||
// Enable BPC}
|
||||
{0x0370, 0x00}, |
||||
{0x0371, 0x00}, |
||||
{0x0372, 0x01}, |
||||
{0x100A, 0x05}, |
||||
{0x2590, 0x01}, |
||||
{0x0104, 0x01}, |
||||
{0x0100, 0x01}, |
||||
|
||||
{REGLIST_TAIL, 0x00}, // tail
|
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_VGA[][2] = { |
||||
{0x0006, 0x10}, |
||||
{0x000D, 0x00}, |
||||
{0x000E, 0x00}, |
||||
{0x0122, 0xEB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0XC1}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0xC1}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x03}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x82}, |
||||
{0x05E7, 0x02}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xE3}, |
||||
{0x05EB, 0x01}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_QVGA[][2] = { |
||||
{0x355A, 0x74}, // vt_sys_d
|
||||
{0x355B, 0x0A}, // op_sys_d
|
||||
{0x355C, 0x77}, // mclk_div_d
|
||||
{0x355D, 0x01}, |
||||
{0x355E, 0x1C}, |
||||
{0x355F, 0x03}, |
||||
{0x3560, 0x00}, |
||||
{0x3561, 0x01}, |
||||
{0x3562, 0x01}, |
||||
{0x3563, 0x00}, |
||||
{0x3564, 0xFF}, |
||||
{0x3565, 0x00}, |
||||
{0x3567, 0x01}, |
||||
{0x3566, 0x00}, |
||||
{0x3569, 0x00}, |
||||
{0x356A, 0x01}, |
||||
{0x356C, 0x7F}, |
||||
{0x356D, 0x00}, |
||||
{0x3576, 0x00}, |
||||
{0x3579, 0x03}, // Max Again
|
||||
{0x356E, 0x00}, // AE cnt org H HB
|
||||
{0x356F, 0x01}, // AE cnt org H LB
|
||||
{0x3570, 0x00}, // AE cnt org V HB
|
||||
{0x3571, 0x02}, // AE cnt org V LB
|
||||
{0x3572, 0x00}, // AE cnt st H HB
|
||||
{0x3573, 0x3F}, // AE cnt st H LB
|
||||
{0x3574, 0x00}, // AE cnt st V HB
|
||||
{0x3575, 0x2F}, // AE cnt st V LB
|
||||
{0x3577, 0x04}, |
||||
{0x3578, 0x24}, |
||||
{0x3584, 0x01}, |
||||
{0x3585, 0x04}, |
||||
{0x3586, 0x01}, |
||||
{0x3587, 0x38}, |
||||
{0x3588, 0x02}, // FR stage 1 H
|
||||
{0x3589, 0x12}, // FR stage 1 L
|
||||
{0x358A, 0x04}, // FR stage 2 H
|
||||
{0x358B, 0x24}, // FR stage 2 L
|
||||
{0x358C, 0x06}, // FR stage 3 H
|
||||
{0x358D, 0x36}, // FR stage 3 L
|
||||
{0x35A5, 0x21}, // [7:1]MD_light_coef [0] MD enable
|
||||
{0x35A6, 0x01}, // MD_block_num_th
|
||||
{0x35A7, 0xE0}, // [7:4]md_roi_end_v [3:0]md_roi_start_v
|
||||
{0x35A8, 0xF0}, // [7:4]md_roi_end_h [3:0]md_roi_start_h
|
||||
{0x35A9, 0x10}, // [6:0] md_th_str_HCG
|
||||
{0x35AA, 0x10}, // [5:0] md_th_str_LCG
|
||||
{0x35AB, 0x10}, // [5:0] md_th_str_HDR
|
||||
{0x35AC, 0x20}, // md_flick_skip_th_adj_N
|
||||
{0x35AD, 0x10}, // md_flick_skip_th_adj_P
|
||||
{0x35AE, 0x01}, |
||||
{0x35AF, 0x06}, |
||||
{0x35B0, 0x0C}, |
||||
{0x35B1, 0x12}, |
||||
{0x35BC, 0x1C}, |
||||
{0x35B3, 0x30}, |
||||
{0x35A3, 0x02}, // full trigger H
|
||||
{0x35A4, 0x03}, // full trigger L
|
||||
|
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_240X240[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0XBE}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0xBE}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x62}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x51}, |
||||
{0x05E7, 0x01}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xF3}, |
||||
{0x05EB, 0x00}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_QQVGA[][2] = { |
||||
{0x355A, 0x74}, // vt_sys_d
|
||||
{0x355B, 0x0A}, // op_sys_d
|
||||
{0x355C, 0x77}, // mclk_div_d
|
||||
{0x355D, 0x00}, |
||||
{0x355E, 0x8E}, |
||||
{0x355F, 0x03}, |
||||
{0x3560, 0x00}, |
||||
{0x3561, 0x02}, |
||||
{0x3562, 0x02}, |
||||
{0x3563, 0x00}, |
||||
{0x3564, 0xFF}, |
||||
{0x3565, 0x00}, |
||||
{0x3567, 0x01}, |
||||
{0x3566, 0x00}, |
||||
{0x3569, 0x00}, |
||||
{0x356A, 0x01}, |
||||
{0x356C, 0x7F}, |
||||
{0x356D, 0x00}, |
||||
{0x3576, 0x00}, |
||||
{0x3579, 0x03}, // Max Again
|
||||
{0x356E, 0x00}, // AE cnt org H HB
|
||||
{0x356F, 0x01}, // AE cnt org H LB
|
||||
{0x3570, 0x00}, // AE cnt org V HB
|
||||
{0x3571, 0x02}, // AE cnt org V LB
|
||||
{0x3572, 0x00}, // AE cnt st H HB
|
||||
{0x3573, 0x1F}, // AE cnt st H LB
|
||||
{0x3574, 0x00}, // AE cnt st V HB
|
||||
{0x3575, 0x17}, // AE cnt st V LB
|
||||
{0x3577, 0x04}, |
||||
{0x3578, 0x24}, |
||||
{0x3584, 0x01}, |
||||
{0x3585, 0x04}, |
||||
{0x3586, 0x01}, |
||||
{0x3587, 0x38}, |
||||
{0x3588, 0x02}, // FR stage 1 H
|
||||
{0x3589, 0x12}, // FR stage 1 L
|
||||
{0x358A, 0x04}, // FR stage 2 H
|
||||
{0x358B, 0x24}, // FR stage 2 L
|
||||
{0x358C, 0x06}, // FR stage 3 H
|
||||
{0x358D, 0x36}, // FR stage 3 L
|
||||
{0x35A5, 0x21}, // [7:1]MD_light_coef [0] MD enable
|
||||
{0x35A6, 0x01}, // MD_block_num_th
|
||||
{0x35A7, 0xD0}, // [7:4]md_roi_end_v [3:0]md_roi_start_v
|
||||
{0x35A8, 0xF0}, // [7:4]md_roi_end_h [3:0]md_roi_start_h
|
||||
{0x35A9, 0x10}, // [6:0] md_th_str_HCG
|
||||
{0x35AA, 0x10}, // [5:0] md_th_str_LCG
|
||||
{0x35AB, 0x10}, // [5:0] md_th_str_HDR
|
||||
{0x35AC, 0x20}, // md_flick_skip_th_adj_N
|
||||
{0x35AD, 0x10}, // md_flick_skip_th_adj_P
|
||||
{0x35AE, 0x01}, |
||||
{0x35AF, 0x06}, |
||||
{0x35B0, 0x0C}, |
||||
{0x35B1, 0x12}, |
||||
{0x35B2, 0x1C}, |
||||
{0x35B3, 0x30}, |
||||
{0x35A3, 0x00}, // full trigger H
|
||||
{0x35A4, 0xEA}, // full trigger L
|
||||
|
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* HM1055 driver. |
||||
*/ |
||||
#ifndef __HM1055_H__ |
||||
#define __HM1055_H__ |
||||
#include "sensor.h" |
||||
/**
|
||||
* @brief Detect sensor pid |
||||
* |
||||
* @param slv_addr SCCB address |
||||
* @param id Detection result |
||||
* @return |
||||
* 0: Can't detect this sensor |
||||
* Nonzero: This sensor has been detected |
||||
*/ |
||||
int hm1055_detect(int slv_addr, sensor_id_t *id); |
||||
|
||||
/**
|
||||
* @brief initialize sensor function pointers |
||||
* |
||||
* @param sensor pointer of sensor |
||||
* @return |
||||
* Always 0 |
||||
*/ |
||||
int hm1055_init(sensor_t *sensor); |
||||
|
||||
#endif // __HM1055_H__
|
@ -0,0 +1,120 @@
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* HM1055 register definitions. |
||||
*/ |
||||
#ifndef __REG_REGS_H__ |
||||
#define __REG_REGS_H__ |
||||
|
||||
// Imager Configuration
|
||||
#define CMU 0x0000 |
||||
#define IDH 0x0001 |
||||
#define IDL 0x0002 |
||||
#define VID 0x0003 |
||||
#define PWDCTRL 0x0004 |
||||
#define TGRDCFG 0x0005 |
||||
#define RDCFG 0x0006 |
||||
#define VREAD 0x000D |
||||
#define HREAD 0x000E |
||||
#define IMG_CFG 0x000F |
||||
|
||||
// Imager Operation
|
||||
#define BLNKRH 0x0010 |
||||
#define BLNKRL 0x0011 |
||||
#define BLNKCCLK 0x0012 |
||||
#define BLNKC 0x0013 |
||||
#define INTGH 0x0015 |
||||
#define INTGL 0x0016 |
||||
#define AGAIN 0x0018 |
||||
#define DGAIN 0x001D |
||||
|
||||
// IO and Clock Configuration Setting
|
||||
#define OPRTCFG 0x0020 |
||||
#define SFTRST 0x0022 // any value to reset
|
||||
#define IOCTRLH 0x0023 |
||||
#define IOCTRLL 0x0024 |
||||
#define CKCFG1 0x0025 |
||||
#define CKCFG2 0x0026 |
||||
#define PORTCTRL 0x0027 |
||||
#define TESTIMG 0x0028 |
||||
#define CCIR656 0x0029 |
||||
#define PLL1 0x002A |
||||
#define CKCFG3 0x002B |
||||
#define PLL2 0x002C |
||||
|
||||
// Black Level Target
|
||||
#define BLCTGT 0x0040 |
||||
#define BLCTGT2 0x0053 |
||||
|
||||
// Vertical Arbitrary Window Configuration
|
||||
#define VAWINSTARTH 0x0078 |
||||
#define VAWINSTARTL 0x0079 |
||||
#define VAWINENDH 0x007A |
||||
#define VAWINENDL 0x007B |
||||
|
||||
// Image Signal Processing Control
|
||||
#define CMU_AE 0x0100 |
||||
#define CMU_AWB 0x0101 |
||||
#define ISPID 0x0105 |
||||
#define ISPCTRL1 0x0120 |
||||
#define ISPCTRL2 0x0121 |
||||
#define ISPCTRL3 0x0122 |
||||
#define ISPCTRL4 0x0124 |
||||
#define ISPCTRL5 0x0125 |
||||
#define ISPCTRL6 0x0126 |
||||
|
||||
// RAW Noise Filter Control
|
||||
#define RAWNF 0x01E4 |
||||
#define ARAWNF 0x01E5 |
||||
#define ARAWNFODEL 0x01E6 |
||||
|
||||
// Automatic Exposure Control Registers
|
||||
#define AEWBCFG 0x0380 |
||||
#define AETARGU 0x0381 |
||||
#define AETARGL 0x0382 |
||||
#define AETARGM 0x0383 |
||||
|
||||
// Saturation and Hue Control
|
||||
#define SAT 0x0480 |
||||
#define ASAT 0x0481 |
||||
#define ASATODEL 0x0482 |
||||
#define HUESIN 0x0486 |
||||
#define HUECOS 0x0487 |
||||
#define SCENE 0x0488 |
||||
|
||||
// Contrast and Brightness Control
|
||||
#define CONTM 0x04B0 |
||||
#define ACONTM 0x04B1 |
||||
#define CONTQ 0x04B3 |
||||
#define ACONTQ 0x04B4 |
||||
#define CONTN 0x04B6 |
||||
#define CONTP 0x04B9 |
||||
#define CONTGAIN 0x04BC |
||||
#define YMEAN 0x04BD |
||||
#define BRIGHT 0x04C0 |
||||
|
||||
// Y Denoise Control
|
||||
#define YDN 0x0580 |
||||
#define AYDN 0x0581 |
||||
#define AYDNODEL 0x0582 |
||||
|
||||
// Sharpness Control
|
||||
#define EDGE 0x05A1 |
||||
|
||||
// Fade to Black Control
|
||||
#define F2BMEAN 0x05D0 |
||||
#define F2BRANGE 0x05D1 |
||||
|
||||
// Digital Window Control
|
||||
#define YUVSCXL 0x05E0 |
||||
#define YUVSCXH 0x05E1 |
||||
#define YUVSCYL 0x05E2 |
||||
#define YUVSCYH 0x05E3 |
||||
#define WINXSTL 0x05E4 |
||||
#define WINXSTH 0x05E5 |
||||
#define WINXEDL 0x05E6 |
||||
#define WINXEDH 0x05E7 |
||||
#define WINYSTL 0x05E8 |
||||
#define WINYSTH 0x05E9 |
||||
#define WINYEDL 0x05EA |
||||
#define WINYEDH 0x05EB |
||||
|
||||
#endif //__REG_REGS_H__
|
@ -0,0 +1,697 @@
@@ -0,0 +1,697 @@
|
||||
|
||||
#include <stdint.h> |
||||
|
||||
#define REG_DLY 0xffff |
||||
#define REGLIST_TAIL 0xffff |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_default_regs[][2] = { |
||||
{0x0022, 0x00}, // RESET
|
||||
{0x0026, 0x77}, // 24MHz MCLK, 72MHz PCLK
|
||||
{0x002A, 0x44}, // Modified by Wilson
|
||||
{0x002B, 0x02}, |
||||
{0x002C, 0x00}, // Turn off DCC
|
||||
{0x0025, 0x00}, // PLL on
|
||||
{0x0020, 0x08}, |
||||
{0x0027, 0x40}, // FPGA 24 data format
|
||||
{0x0028, 0xC0}, //
|
||||
{0x0004, 0x10}, //
|
||||
{0x0006, 0x00}, // Modified by Brandon. No Flip
|
||||
{0x0012, 0x0F}, |
||||
{0x0044, 0x04}, |
||||
{0x004A, 0x2A}, |
||||
{0x004B, 0x72}, |
||||
{0x004E, 0x30}, |
||||
{0x0070, 0x2A}, |
||||
{0x0071, 0x57}, |
||||
{0x0072, 0x55}, |
||||
{0x0073, 0x30}, |
||||
{0x0077, 0x04}, |
||||
{0x0080, 0xC2}, |
||||
{0x0082, 0xA2}, |
||||
{0x0083, 0xF0}, |
||||
{0x0085, 0x11}, // Set ADC power to 100% and Increase Comparator power and reduce ADC swing range(4/19, K.Kim)
|
||||
{0x0086, 0x22}, |
||||
{0x0087, 0x08}, |
||||
{0x0088, 0x6e}, // Temperature config 0x80[7:5]:76C, Minimize CTIA & PGA power and set VCMI to 200mV(4/19, K.Kim)
|
||||
{0x0089, 0x2A}, |
||||
{0x008A, 0x2F}, // Set BLC power to 50%(4/19, K.Kim)
|
||||
{0x008D, 0x20}, |
||||
{0x008f, 0x77}, |
||||
{0x0090, 0x01}, |
||||
{0x0091, 0x02}, |
||||
{0x0092, 0x03}, |
||||
{0x0093, 0x04}, |
||||
{0x0094, 0x14}, |
||||
{0x0095, 0x09}, |
||||
{0x0096, 0x0A}, |
||||
{0x0097, 0x0B}, |
||||
{0x0098, 0x0C}, |
||||
{0x0099, 0x04}, |
||||
{0x009A, 0x14}, |
||||
{0x009B, 0x34}, |
||||
{0x00A0, 0x00}, |
||||
{0x00A1, 0x00}, |
||||
{0x0B3B, 0x0B}, |
||||
{0x0040, 0x0A}, // BLC Phase1
|
||||
{0x0053, 0x0A}, // BLC Phase2
|
||||
{0x0120, 0x36}, // 36:50Hz, 37:60Hz
|
||||
{0x0121, 0x80}, |
||||
{0x0122, 0xEB}, // 122[3] is temperature_control_bit2
|
||||
{0x0123, 0xCC}, // 123[3:0]maskTH
|
||||
{0x0124, 0xDE}, |
||||
{0x0125, 0xDF}, |
||||
{0x0126, 0x70}, |
||||
{0x0128, 0x1F}, |
||||
{0x0129, 0x8F}, |
||||
{0x0132, 0xF8}, |
||||
{0x011F, 0x08}, // BPC COLD PIXEL ENABLE if 11F[0] = 1 then on else 0 off
|
||||
{0x0144, 0x04}, // Hot pixel ratio
|
||||
{0x0145, 0x00}, // Hot pixel ratio alpha
|
||||
{0x0146, 0x20}, // Vertical Line TH
|
||||
{0x0147, 0x20}, // Vertical Line TH alpha
|
||||
{0x0148, 0x14}, // HD_2line_BPC_TH
|
||||
{0x0149, 0x14}, // HD_2line_BPC_TH alpha
|
||||
{0x0156, 0x0C}, // BPC RATIO FOR COLD PIXEL
|
||||
{0x0157, 0x0C}, // BPC RATIO FOR COLD PIXEL
|
||||
{0x0158, 0x0A}, // 2 LINE BPC RATIO
|
||||
{0x0159, 0x0A}, // 2 LINE BPC RATIO
|
||||
{0x015A, 0x03}, // BPC RATIO FOR COLD PIXEL
|
||||
{0x015B, 0x40}, // Corner TH
|
||||
{0x015C, 0x21}, // Corner TH alpha
|
||||
{0x015E, 0x0F}, // Debug_mode
|
||||
{0x0168, 0xC8}, // BPC T1
|
||||
{0x0169, 0xC8}, // BPC T1 ALPHA
|
||||
{0x016A, 0x96}, // BPC T2
|
||||
{0x016B, 0x96}, // BPC T2 ALPHA
|
||||
{0x016C, 0x64}, // BPC T3
|
||||
{0x016D, 0x64}, // BPC T3 ALPHA
|
||||
{0x016E, 0x32}, // BPC T4
|
||||
{0x016F, 0x32}, // BPC T4 ALPHA
|
||||
{0x01EF, 0xF1}, // BPC Control Byte
|
||||
{0x0131, 0x44}, //[6] DS_EN, [5] VOFF, [4] EDGEON, [3] SBPI_MODE, [2] RAW_SAHRPNESS_EN, [1]G1G2B_EN
|
||||
{0x014C, 0x60}, // VSUB
|
||||
{0x014D, 0x24}, // VSUB ALPHA0
|
||||
{0x015D, 0x90}, //[7] TG_en// [6:0]:min Tgain
|
||||
{0x01D8, 0x40}, // NOISE TH
|
||||
{0x01D9, 0x20}, // NL_V1
|
||||
{0x01DA, 0x23}, // NL_V2
|
||||
{0x0150, 0x05}, // NL_INC1
|
||||
{0x0155, 0x07}, // NL_INC2
|
||||
{0x0178, 0x10}, // EVDIV
|
||||
{0x017A, 0x10}, // EVDIVD
|
||||
{0x01BA, 0x10}, // EVSUB
|
||||
{0x0176, 0x00}, // EDGE2W
|
||||
{0x0179, 0x10}, // EVDIV ALPHA0
|
||||
{0x017B, 0x10}, // EVDIVD ALPHA0
|
||||
{0x01BB, 0x10}, // EVSUB ALPHA0
|
||||
{0x0177, 0x00}, // EDGE2W ALPHA0
|
||||
{0x01E7, 0x20}, // TLTH1
|
||||
{0x01E8, 0x30}, // TLTH2
|
||||
{0x01E9, 0x50}, // TLTH3
|
||||
{0x01E4, 0x18}, // BD STRENGTH
|
||||
{0x01E5, 0x20}, // BD STRENGTH ALPHA0
|
||||
{0x01E6, 0x04}, // BD STRENGTH OUTDOOR
|
||||
{0x0210, 0x21}, // STD
|
||||
{0x0211, 0x0A}, // STD ALPHA0
|
||||
{0x0212, 0x21}, // STD OUTDOOR
|
||||
{0x01DB, 0x04}, // G1G2 STRENGTH
|
||||
{0x01DC, 0x14}, // SBPI_OFFSET
|
||||
{0x0151, 0x08}, |
||||
{0x01F2, 0x18}, |
||||
{0x01F8, 0x3C}, |
||||
{0x01FE, 0x24}, |
||||
{0x0213, 0x03}, // BPC_Control_BYTE_2 // BPC_line_edge_th 3rd bpc
|
||||
{0x0214, 0x03}, // BPC_Control_BYTE_3 // 3rd bpc strength[4:0] , [7:5] is for 2line bpc temp_control_bit
|
||||
{0x0215, 0x10}, // BPC_Control_BYTE_4 // 1st bpc strength[4:0]
|
||||
{0x0216, 0x08}, // BPC_Control_BYTE_5 // 1st br pulse strength[4:0]
|
||||
{0x0217, 0x05}, // BPC_Control_BYTE_6 // 1st gbgr pulse strengh[4:0]
|
||||
{0x0218, 0xB8}, |
||||
{0x0219, 0x01}, |
||||
{0x021A, 0xB8}, |
||||
{0x021B, 0x01}, |
||||
{0x021C, 0xB8}, |
||||
{0x021D, 0x01}, |
||||
{0x021E, 0xB8}, |
||||
{0x021F, 0x01}, |
||||
{0x0220, 0xF1}, |
||||
{0x0221, 0x5D}, |
||||
{0x0222, 0x0A}, |
||||
{0x0223, 0x80}, |
||||
{0x0224, 0x50}, |
||||
{0x0225, 0x09}, |
||||
{0x0226, 0x80}, |
||||
{0x022A, 0x56}, |
||||
{0x022B, 0x13}, |
||||
{0x022C, 0x80}, |
||||
{0x022D, 0x11}, |
||||
{0x022E, 0x08}, |
||||
{0x022F, 0x11}, |
||||
{0x0230, 0x08}, |
||||
{0x0233, 0x11}, |
||||
{0x0234, 0x08}, |
||||
{0x0235, 0x88}, |
||||
{0x0236, 0x02}, |
||||
{0x0237, 0x88}, |
||||
{0x0238, 0x02}, |
||||
{0x023B, 0x88}, |
||||
{0x023C, 0x02}, |
||||
{0x023D, 0x68}, |
||||
{0x023E, 0x01}, |
||||
{0x023F, 0x68}, |
||||
{0x0240, 0x01}, |
||||
{0x0243, 0x68}, |
||||
{0x0244, 0x01}, |
||||
{0x0251, 0x0F}, |
||||
{0x0252, 0x00}, |
||||
{0x0260, 0x00}, |
||||
{0x0261, 0x4A}, |
||||
{0x0262, 0x2C}, |
||||
{0x0263, 0x68}, |
||||
{0x0264, 0x40}, |
||||
{0x0265, 0x2C}, |
||||
{0x0266, 0x6A}, |
||||
{0x026A, 0x40}, |
||||
{0x026B, 0x30}, |
||||
{0x026C, 0x66}, |
||||
{0x0278, 0x98}, |
||||
{0x0279, 0x20}, |
||||
{0x027A, 0x80}, |
||||
{0x027B, 0x73}, |
||||
{0x027C, 0x08}, |
||||
{0x027D, 0x80}, |
||||
{0x0280, 0x0D}, |
||||
{0x0282, 0x1A}, |
||||
{0x0284, 0x30}, |
||||
{0x0286, 0x53}, |
||||
{0x0288, 0x62}, |
||||
{0x028a, 0x6E}, |
||||
{0x028c, 0x7A}, |
||||
{0x028e, 0x83}, |
||||
{0x0290, 0x8B}, |
||||
{0x0292, 0x92}, |
||||
{0x0294, 0x9D}, |
||||
{0x0296, 0xA8}, |
||||
{0x0298, 0xBC}, |
||||
{0x029a, 0xCF}, |
||||
{0x029c, 0xE2}, |
||||
{0x029e, 0x2A}, |
||||
{0x02A0, 0x02}, |
||||
{0x02C0, 0x7D}, // CCM N
|
||||
{0x02C1, 0x01}, |
||||
{0x02C2, 0x7C}, |
||||
{0x02C3, 0x04}, |
||||
{0x02C4, 0x01}, |
||||
{0x02C5, 0x04}, |
||||
{0x02C6, 0x3E}, |
||||
{0x02C7, 0x04}, |
||||
{0x02C8, 0x90}, |
||||
{0x02C9, 0x01}, |
||||
{0x02CA, 0x52}, |
||||
{0x02CB, 0x04}, |
||||
{0x02CC, 0x04}, |
||||
{0x02CD, 0x04}, |
||||
{0x02CE, 0xA9}, |
||||
{0x02CF, 0x04}, |
||||
{0x02D0, 0xAD}, |
||||
{0x02D1, 0x01}, |
||||
{0x0302, 0x00}, |
||||
{0x0303, 0x00}, |
||||
{0x0304, 0x00}, |
||||
{0x02e0, 0x04}, // CCM by Alpha
|
||||
{0x02F0, 0x4E}, // CCM A
|
||||
{0x02F1, 0x04}, |
||||
{0x02F2, 0xB1}, |
||||
{0x02F3, 0x00}, |
||||
{0x02F4, 0x63}, |
||||
{0x02F5, 0x04}, |
||||
{0x02F6, 0x28}, |
||||
{0x02F7, 0x04}, |
||||
{0x02F8, 0x29}, |
||||
{0x02F9, 0x04}, |
||||
{0x02FA, 0x51}, |
||||
{0x02FB, 0x00}, |
||||
{0x02FC, 0x64}, |
||||
{0x02FD, 0x04}, |
||||
{0x02FE, 0x6B}, |
||||
{0x02FF, 0x04}, |
||||
{0x0300, 0xCF}, |
||||
{0x0301, 0x00}, |
||||
{0x0305, 0x08}, |
||||
{0x0306, 0x40}, |
||||
{0x0307, 0x00}, |
||||
{0x032D, 0x70}, |
||||
{0x032E, 0x01}, |
||||
{0x032F, 0x00}, |
||||
{0x0330, 0x01}, |
||||
{0x0331, 0x70}, |
||||
{0x0332, 0x01}, |
||||
{0x0333, 0x82}, // AWB channel offset
|
||||
{0x0334, 0x82}, |
||||
{0x0335, 0x86}, |
||||
{0x0340, 0x30}, // AWB
|
||||
{0x0341, 0x44}, |
||||
{0x0342, 0x4A}, |
||||
{0x0343, 0x3C}, // CT1
|
||||
{0x0344, 0x83}, //
|
||||
{0x0345, 0x4D}, // CT2
|
||||
{0x0346, 0x75}, //
|
||||
{0x0347, 0x56}, // CT3
|
||||
{0x0348, 0x68}, //
|
||||
{0x0349, 0x5E}, // CT4
|
||||
{0x034A, 0x5C}, //
|
||||
{0x034B, 0x65}, // CT5
|
||||
{0x034C, 0x52}, //
|
||||
{0x0350, 0x88}, |
||||
{0x0352, 0x18}, |
||||
{0x0354, 0x80}, |
||||
{0x0355, 0x50}, |
||||
{0x0356, 0x88}, |
||||
{0x0357, 0xE0}, |
||||
{0x0358, 0x00}, |
||||
{0x035A, 0x00}, |
||||
{0x035B, 0xAC}, |
||||
{0x0360, 0x02}, |
||||
{0x0361, 0x18}, |
||||
{0x0362, 0x50}, |
||||
{0x0363, 0x6C}, |
||||
{0x0364, 0x00}, |
||||
{0x0365, 0xF0}, |
||||
{0x0366, 0x08}, |
||||
{0x036A, 0x10}, |
||||
{0x036B, 0x18}, |
||||
{0x036E, 0x10}, |
||||
{0x0370, 0x10}, |
||||
{0x0371, 0x18}, |
||||
{0x0372, 0x0C}, |
||||
{0x0373, 0x38}, |
||||
{0x0374, 0x3A}, |
||||
{0x0375, 0x12}, |
||||
{0x0376, 0x20}, |
||||
{0x0380, 0xFF}, |
||||
{0x0381, 0x44}, |
||||
{0x0382, 0x34}, |
||||
{0x038A, 0x80}, |
||||
{0x038B, 0x0A}, |
||||
{0x038C, 0xC1}, |
||||
{0x038E, 0x3C}, |
||||
{0x038F, 0x09}, |
||||
{0x0390, 0xE0}, |
||||
{0x0391, 0x01}, |
||||
{0x0392, 0x03}, |
||||
{0x0393, 0x80}, |
||||
{0x0395, 0x22}, |
||||
{0x0398, 0x02}, // AE Frame Control
|
||||
{0x0399, 0xF0}, |
||||
{0x039A, 0x03}, |
||||
{0x039B, 0xAC}, |
||||
{0x039C, 0x04}, |
||||
{0x039D, 0x68}, |
||||
{0x039E, 0x05}, |
||||
{0x039F, 0xE0}, |
||||
{0x03A0, 0x07}, |
||||
{0x03A1, 0x58}, |
||||
{0x03A2, 0x08}, |
||||
{0x03A3, 0xD0}, |
||||
{0x03A4, 0x0B}, |
||||
{0x03A5, 0xC0}, |
||||
{0x03A6, 0x18}, |
||||
{0x03A7, 0x1C}, |
||||
{0x03A8, 0x20}, |
||||
{0x03A9, 0x24}, |
||||
{0x03AA, 0x28}, |
||||
{0x03AB, 0x30}, |
||||
{0x03AC, 0x24}, |
||||
{0x03AD, 0x21}, |
||||
{0x03AE, 0x1C}, |
||||
{0x03AF, 0x18}, |
||||
{0x03B0, 0x17}, |
||||
{0x03B1, 0x13}, |
||||
{0x03B7, 0x64}, // AEAWB Windowing Step for 7x7
|
||||
{0x03B8, 0x00}, |
||||
{0x03B9, 0xB4}, |
||||
{0x03BA, 0x00}, |
||||
{0x03bb, 0xff}, // WinWeight 7x7
|
||||
{0x03bc, 0xff}, |
||||
{0x03bd, 0xff}, |
||||
{0x03be, 0xff}, |
||||
{0x03bf, 0xff}, |
||||
{0x03c0, 0xff}, |
||||
{0x03c1, 0x01}, |
||||
{0x03e0, 0x04}, |
||||
{0x03e1, 0x11}, |
||||
{0x03e2, 0x01}, |
||||
{0x03e3, 0x04}, |
||||
{0x03e4, 0x10}, |
||||
{0x03e5, 0x21}, |
||||
{0x03e6, 0x11}, |
||||
{0x03e7, 0x00}, |
||||
{0x03e8, 0x11}, |
||||
{0x03e9, 0x32}, |
||||
{0x03ea, 0x12}, |
||||
{0x03eb, 0x01}, |
||||
{0x03ec, 0x21}, |
||||
{0x03ed, 0x33}, |
||||
{0x03ee, 0x23}, |
||||
{0x03ef, 0x01}, |
||||
{0x03f0, 0x11}, |
||||
{0x03f1, 0x32}, |
||||
{0x03f2, 0x12}, |
||||
{0x03f3, 0x01}, |
||||
{0x03f4, 0x10}, |
||||
{0x03f5, 0x21}, |
||||
{0x03f6, 0x11}, |
||||
{0x03f7, 0x00}, |
||||
{0x03f8, 0x04}, |
||||
{0x03f9, 0x11}, |
||||
{0x03fa, 0x01}, |
||||
{0x03fb, 0x04}, |
||||
{0x03DC, 0x47}, // SubWinAE setting, min_dark_cnt=7, exit_dark_cnt=4
|
||||
{0x03DD, 0x5A}, // AEbl_th=70%
|
||||
{0x03DE, 0x41}, // enable SubWinAE, bottom 3x5, DM_tol=12.5%
|
||||
{0x03DF, 0x53}, // limit_ratio=65%
|
||||
{0x0420, 0x82}, // Digital Gain offset
|
||||
{0x0421, 0x00}, |
||||
{0x0422, 0x00}, |
||||
{0x0423, 0x88}, |
||||
{0x0430, 0x08}, // ABLC
|
||||
{0x0431, 0x30}, |
||||
{0x0432, 0x0c}, |
||||
{0x0433, 0x04}, // 0A
|
||||
{0x0435, 0x08}, // 10
|
||||
{0x0450, 0xFF}, // Alpha
|
||||
{0x0451, 0xD0}, |
||||
{0x0452, 0xB8}, |
||||
{0x0453, 0x88}, |
||||
{0x0454, 0x00}, |
||||
{0x0458, 0x80}, |
||||
{0x0459, 0x03}, |
||||
{0x045A, 0x00}, |
||||
{0x045B, 0x50}, |
||||
{0x045C, 0x00}, |
||||
{0x045D, 0x90}, |
||||
{0x0465, 0x02}, |
||||
{0x0466, 0x14}, |
||||
{0x047A, 0x00}, // ELOFFNRB
|
||||
{0x047B, 0x00}, // ELOFFNRY
|
||||
{0x047C, 0x04}, |
||||
{0x047D, 0x50}, |
||||
{0x047E, 0x04}, |
||||
{0x047F, 0x90}, |
||||
{0x0480, 0x58}, |
||||
{0x0481, 0x06}, |
||||
{0x0482, 0x08}, // Sat outdoor
|
||||
{0x04B0, 0x50}, // Contrast
|
||||
{0x04B6, 0x30}, |
||||
{0x04B9, 0x10}, |
||||
{0x04B3, 0x00}, |
||||
{0x04B1, 0x85}, |
||||
{0x04B4, 0x00}, |
||||
{0x0540, 0x00}, //
|
||||
{0x0541, 0xBC}, // 60Hz Flicker
|
||||
{0x0542, 0x00}, //
|
||||
{0x0543, 0xE1}, // 50Hz Flicker
|
||||
{0x0580, 0x04}, // BLUR WEIGHT
|
||||
{0x0581, 0x0F}, // BLUR WEIGHT ALPHA0
|
||||
{0x0582, 0x04}, // BLUR WEIGHT OUTDOOR
|
||||
{0x05A1, 0x0A}, // SHARPNESS STRENGTH
|
||||
{0x05A2, 0x21}, //[6:4] SHARP_ORE_NEG, [1:0] FIL SELECTION
|
||||
{0x05A3, 0x84}, //[7]EA_EN, [6] EE_CENTER, [3:0] EDGEDIV
|
||||
{0x05A4, 0x24}, // SHARP_ORE
|
||||
{0x05A5, 0xFF}, // ORE_MAX
|
||||
{0x05A6, 0x00}, // ORE_LOW
|
||||
{0x05A7, 0x24}, // OUGB_HOT
|
||||
{0x05A8, 0x24}, // OUGB_COLD
|
||||
{0x05A9, 0x02}, // EDGE RANGE
|
||||
{0x05B1, 0x24}, // EDGE SUB
|
||||
{0x05B2, 0x0C}, //[3] Y_ADJC, [2]CMODE
|
||||
{0x05B4, 0x1F}, // FIX WEIGHT
|
||||
{0x05AE, 0x75}, // OAR START
|
||||
{0x05AF, 0x78}, //[7:5]OAR STEP, [4:0]OAR DECSTR
|
||||
{0x05B6, 0x00}, // SHARPNESS STRENGTH ALPHA0
|
||||
{0x05B7, 0x10}, // SHARP_ORE ALPHA0
|
||||
{0x05BF, 0x20}, // EDGESUB ALPHA0
|
||||
{0x05C1, 0x06}, // SHARPNESS STRENGTH OUTDOOR
|
||||
{0x05C2, 0x18}, // SHARP ORE OUTDOOR
|
||||
{0x05C7, 0x00}, // TFBPI
|
||||
{0x05CC, 0x04}, // Raw sharpness strength
|
||||
{0x05CD, 0x00}, // Raw sharpness strength ALPHA0
|
||||
{0x05CE, 0x03}, // Raw sharpness strength outdoor
|
||||
{0x05E4, 0x08}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x07}, |
||||
{0x05E7, 0x05}, |
||||
{0x05E8, 0x08}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xD7}, |
||||
{0x05EB, 0x02}, |
||||
{0x0660, 0x00}, |
||||
{0x0661, 0x16}, |
||||
{0x0662, 0x07}, |
||||
{0x0663, 0xf1}, |
||||
{0x0664, 0x07}, |
||||
{0x0665, 0xde}, |
||||
{0x0666, 0x07}, |
||||
{0x0667, 0xe7}, |
||||
{0x0668, 0x00}, |
||||
{0x0669, 0x35}, |
||||
{0x066a, 0x07}, |
||||
{0x066b, 0xf9}, |
||||
{0x066c, 0x07}, |
||||
{0x066d, 0xb7}, |
||||
{0x066e, 0x00}, |
||||
{0x066f, 0x27}, |
||||
{0x0670, 0x07}, |
||||
{0x0671, 0xf3}, |
||||
{0x0672, 0x07}, |
||||
{0x0673, 0xc5}, |
||||
{0x0674, 0x07}, |
||||
{0x0675, 0xee}, |
||||
{0x0676, 0x00}, |
||||
{0x0677, 0x16}, |
||||
{0x0678, 0x01}, |
||||
{0x0679, 0x80}, |
||||
{0x067a, 0x00}, |
||||
{0x067b, 0x85}, |
||||
{0x067c, 0x07}, |
||||
{0x067d, 0xe1}, |
||||
{0x067e, 0x07}, |
||||
{0x067f, 0xf5}, |
||||
{0x0680, 0x07}, |
||||
{0x0681, 0xb9}, |
||||
{0x0682, 0x00}, |
||||
{0x0683, 0x31}, |
||||
{0x0684, 0x07}, |
||||
{0x0685, 0xe6}, |
||||
{0x0686, 0x07}, |
||||
{0x0687, 0xd3}, |
||||
{0x0688, 0x00}, |
||||
{0x0689, 0x18}, |
||||
{0x068a, 0x07}, |
||||
{0x068b, 0xfa}, |
||||
{0x068c, 0x07}, |
||||
{0x068d, 0xd2}, |
||||
{0x068e, 0x00}, |
||||
{0x068f, 0x08}, |
||||
{0x0690, 0x00}, |
||||
{0x0691, 0x02}, |
||||
{0xAFD0, 0x03}, // Auto Flicker detection off
|
||||
{0xAFD3, 0x18}, |
||||
{0xAFD4, 0x04}, |
||||
{0xAFD5, 0xB8}, // auto flicker samp time 3188
|
||||
{0xAFD6, 0x02}, |
||||
{0xAFD7, 0x44}, |
||||
{0xAFD8, 0x02}, |
||||
|
||||
// QVGA
|
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0XBE}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0xBE}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x3A}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x79}, |
||||
{0x05E7, 0x01}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xF3}, |
||||
{0x05EB, 0x00}, |
||||
|
||||
{0x0000, 0x01}, |
||||
{0x0100, 0x01}, |
||||
{0x0101, 0x01}, |
||||
{REGLIST_TAIL, 0x00}, // tail
|
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_HD[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x00}, |
||||
{0x000E, 0x00}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xDF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E4, 0x08}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x07}, |
||||
{0x05E7, 0x05}, |
||||
{0x05E8, 0x08}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xD7}, |
||||
{0x05EB, 0x02}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_SVGA[][2] = { |
||||
{0x0006, 0x10}, |
||||
{0x000D, 0x00}, |
||||
{0x000E, 0x00}, |
||||
{0x0122, 0xEB}, |
||||
{0x0125, 0xDF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E4, 0x58}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x77}, |
||||
{0x05E7, 0x03}, |
||||
{0x05E8, 0x42}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0x99}, |
||||
{0x05EB, 0x02}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_VGA[][2] = { |
||||
{0x0006, 0x10}, |
||||
{0x000D, 0x00}, |
||||
{0x000E, 0x00}, |
||||
{0x0122, 0xEB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0XC1}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0xC1}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x03}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x82}, |
||||
{0x05E7, 0x02}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xE3}, |
||||
{0x05EB, 0x01}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_CIF[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x72}, |
||||
{0x05E0, 0XC0}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0x8F}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x11}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0xA0}, |
||||
{0x05E7, 0x01}, |
||||
{0x05E8, 0x08}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0x2F}, |
||||
{0x05EB, 0x01}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_QVGA[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0XBE}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0xBE}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x3A}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x79}, |
||||
{0x05E7, 0x01}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xF3}, |
||||
{0x05EB, 0x00}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_QCIF[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x72}, |
||||
{0x05E0, 0X52}, |
||||
{0x05E1, 0x01}, |
||||
{0x05E2, 0x38}, |
||||
{0x05E3, 0x01}, |
||||
{0x05E4, 0x22}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0xD1}, |
||||
{0x05E7, 0x00}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0x93}, |
||||
{0x05EB, 0x00}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_240X240[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0XBE}, |
||||
{0x05E1, 0x00}, |
||||
{0x05E2, 0xBE}, |
||||
{0x05E3, 0x00}, |
||||
{0x05E4, 0x62}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0x51}, |
||||
{0x05E7, 0x01}, |
||||
{0x05E8, 0x04}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0xF3}, |
||||
{0x05EB, 0x00}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
||||
|
||||
static const DRAM_ATTR uint16_t sensor_framesize_QQVGA[][2] = { |
||||
{0x0006, 0x00}, |
||||
{0x000D, 0x01}, |
||||
{0x000E, 0x11}, |
||||
{0x0122, 0xFB}, |
||||
{0x0125, 0xFF}, |
||||
{0x0126, 0x70}, |
||||
{0x05E0, 0X78}, |
||||
{0x05E1, 0x01}, |
||||
{0x05E2, 0x78}, |
||||
{0x05E3, 0x01}, |
||||
{0x05E4, 0x1E}, |
||||
{0x05E5, 0x00}, |
||||
{0x05E6, 0xBD}, |
||||
{0x05E7, 0x00}, |
||||
{0x05E8, 0x03}, |
||||
{0x05E9, 0x00}, |
||||
{0x05EA, 0x7A}, |
||||
{0x05EB, 0x00}, |
||||
{REGLIST_TAIL, 0x00}, |
||||
}; |
Loading…
Reference in new issue