Browse Source

Merge pull request #707 from Lesords/feat/hm1055

feat: add camera drivers for hm0360 and hm1055
pull/759/head
Me No Dev 1 week ago committed by GitHub
parent
commit
5fe2266536
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      CMakeLists.txt
  2. 16
      Kconfig
  3. 2
      README.md
  4. 12
      driver/esp_camera.c
  5. 7
      driver/include/sensor.h
  6. 2
      driver/sensor.c
  7. 453
      sensors/hm0360.c
  8. 829
      sensors/hm1055.c
  9. 27
      sensors/private_include/hm0360.h
  10. 150
      sensors/private_include/hm0360_regs.h
  11. 549
      sensors/private_include/hm0360_settings.h
  12. 27
      sensors/private_include/hm1055.h
  13. 120
      sensors/private_include/hm1055_regs.h
  14. 697
      sensors/private_include/hm1055_settings.h
  15. 2
      target/esp32s3/ll_cam.c

2
CMakeLists.txt

@ -41,6 +41,8 @@ if(IDF_TARGET STREQUAL "esp32" OR IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET ST
sensors/sc030iot.c sensors/sc030iot.c
sensors/sc031gs.c sensors/sc031gs.c
sensors/mega_ccm.c sensors/mega_ccm.c
sensors/hm1055.c
sensors/hm0360.c
) )
list(APPEND priv_include_dirs list(APPEND priv_include_dirs

16
Kconfig

@ -117,6 +117,22 @@ menu "Camera configuration"
Enable this option if you want to use the SC031GS. Enable this option if you want to use the SC031GS.
Disable this option to save memory. Disable this option to save memory.
config HM1055_SUPPORT
bool "Support HM1055 VGA"
default y
help
Enable this option if you want to use the HM1055.
Disable this option to save memory.
config HM0360_SUPPORT
bool "Support HM0360 VGA"
default y
help
Enable this option if you want to use the HM0360.
Disable this option to save memory.
config SCCB_I2C_PORT
config MEGA_CCM_SUPPORT config MEGA_CCM_SUPPORT
bool "Support MEGA CCM 5MP" bool "Support MEGA CCM 5MP"
default y default y

2
README.md

@ -29,6 +29,8 @@ This repository hosts ESP32 series Soc compatible driver for image sensors. Addi
| SC101IOT| 1280 x 720 | color | YUV/YCbCr422<br/>Raw RGB | 1/4.2" | | SC101IOT| 1280 x 720 | color | YUV/YCbCr422<br/>Raw RGB | 1/4.2" |
| SC030IOT| 640 x 480 | color | YUV/YCbCr422<br/>RAW Bayer | 1/6.5" | | SC030IOT| 640 x 480 | color | YUV/YCbCr422<br/>RAW Bayer | 1/6.5" |
| SC031GS | 640 x 480 | monochrome | RAW MONO<br/>Grayscale | 1/6" | | SC031GS | 640 x 480 | monochrome | RAW MONO<br/>Grayscale | 1/6" |
| HM0360 | 656 x 496 | monochrome | RAW MONO<br/>Grayscale | 1/6" |
| HM1055 | 1280 x 720 | color | 8/10-bit Raw<br/>YUV/YCbCr422<br/>RGB565/555/444 | 1/6" |
## Important to Remember ## Important to Remember

12
driver/esp_camera.c

@ -72,6 +72,12 @@
#if CONFIG_MEGA_CCM_SUPPORT #if CONFIG_MEGA_CCM_SUPPORT
#include "mega_ccm.h" #include "mega_ccm.h"
#endif #endif
#if CONFIG_HM1055_SUPPORT
#include "hm1055.h"
#endif
#if CONFIG_HM0360_SUPPORT
#include "hm0360.h"
#endif
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h" #include "esp32-hal-log.h"
@ -149,6 +155,12 @@ static const sensor_func_t g_sensors[] = {
#if CONFIG_MEGA_CCM_SUPPORT #if CONFIG_MEGA_CCM_SUPPORT
{mega_ccm_detect, mega_ccm_init}, {mega_ccm_detect, mega_ccm_init},
#endif #endif
#if CONFIG_HM1055_SUPPORT
{hm1055_detect, hm1055_init},
#endif
#if CONFIG_HM0360_SUPPORT
{hm0360_detect, hm0360_init},
#endif
}; };
static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out_camera_model) static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out_camera_model)

7
driver/include/sensor.h

@ -32,6 +32,8 @@ typedef enum {
SC030IOT_PID = 0x9a46, SC030IOT_PID = 0x9a46,
SC031GS_PID = 0x0031, SC031GS_PID = 0x0031,
MEGA_CCM_PID =0x039E, MEGA_CCM_PID =0x039E,
HM1055_PID = 0x0955,
HM0360_PID = 0x0360
} camera_pid_t; } camera_pid_t;
typedef enum { typedef enum {
@ -50,6 +52,8 @@ typedef enum {
CAMERA_SC030IOT, CAMERA_SC030IOT,
CAMERA_SC031GS, CAMERA_SC031GS,
CAMERA_MEGA_CCM, CAMERA_MEGA_CCM,
CAMERA_HM1055,
CAMERA_HM0360,
CAMERA_MODEL_MAX, CAMERA_MODEL_MAX,
CAMERA_NONE, CAMERA_NONE,
} camera_model_t; } camera_model_t;
@ -70,6 +74,8 @@ typedef enum {
SC030IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1 SC030IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
SC031GS_SCCB_ADDR = 0x30, SC031GS_SCCB_ADDR = 0x30,
MEGA_CCM_SCCB_ADDR = 0x1F, // 0x3E >> 1 MEGA_CCM_SCCB_ADDR = 0x1F, // 0x3E >> 1
HM1055_SCCB_ADDR = 0x24,
HM0360_SCCB_ADDR = 0x12,
} camera_sccb_addr_t; } camera_sccb_addr_t;
typedef enum { typedef enum {
@ -82,6 +88,7 @@ typedef enum {
PIXFORMAT_RAW, // RAW PIXFORMAT_RAW, // RAW
PIXFORMAT_RGB444, // 3BP2P/RGB444 PIXFORMAT_RGB444, // 3BP2P/RGB444
PIXFORMAT_RGB555, // 3BP2P/RGB555 PIXFORMAT_RGB555, // 3BP2P/RGB555
PIXFORMAT_RAW8, // RAW 8-bit
} pixformat_t; } pixformat_t;
typedef enum { typedef enum {

2
driver/sensor.c

@ -18,6 +18,8 @@ const camera_sensor_info_t camera_sensor[CAMERA_MODEL_MAX] = {
{CAMERA_SC030IOT, "SC030IOT", SC030IOT_SCCB_ADDR, SC030IOT_PID, FRAMESIZE_VGA, false}, {CAMERA_SC030IOT, "SC030IOT", SC030IOT_SCCB_ADDR, SC030IOT_PID, FRAMESIZE_VGA, false},
{CAMERA_SC031GS, "SC031GS", SC031GS_SCCB_ADDR, SC031GS_PID, FRAMESIZE_VGA, false}, {CAMERA_SC031GS, "SC031GS", SC031GS_SCCB_ADDR, SC031GS_PID, FRAMESIZE_VGA, false},
{CAMERA_MEGA_CCM, "MEGA_CCM", MEGA_CCM_SCCB_ADDR, MEGA_CCM_PID, FRAMESIZE_5MP, true}, {CAMERA_MEGA_CCM, "MEGA_CCM", MEGA_CCM_SCCB_ADDR, MEGA_CCM_PID, FRAMESIZE_5MP, true},
{CAMERA_HM1055, "HM1055", HM1055_SCCB_ADDR, HM1055_PID, FRAMESIZE_HD, false},
{CAMERA_HM0360, "HM0360", HM0360_SCCB_ADDR, HM0360_PID, FRAMESIZE_VGA, false},
}; };
const resolution_info_t resolution[FRAMESIZE_INVALID] = { const resolution_info_t resolution[FRAMESIZE_INVALID] = {

453
sensors/hm0360.c

@ -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;
}

829
sensors/hm1055.c

@ -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;
}

27
sensors/private_include/hm0360.h

@ -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__

150
sensors/private_include/hm0360_regs.h

@ -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__

549
sensors/private_include/hm0360_settings.h

@ -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},
};

27
sensors/private_include/hm1055.h

@ -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__

120
sensors/private_include/hm1055_regs.h

@ -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__

697
sensors/private_include/hm1055_settings.h

@ -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},
};

2
target/esp32s3/ll_cam.c

@ -557,7 +557,7 @@ size_t IRAM_ATTR ll_cam_memcpy(cam_obj_t *cam, uint8_t *out, const uint8_t *in,
esp_err_t ll_cam_set_sample_mode(cam_obj_t *cam, pixformat_t pix_format, uint32_t xclk_freq_hz, uint16_t sensor_pid) esp_err_t ll_cam_set_sample_mode(cam_obj_t *cam, pixformat_t pix_format, uint32_t xclk_freq_hz, uint16_t sensor_pid)
{ {
if (pix_format == PIXFORMAT_GRAYSCALE) { if (pix_format == PIXFORMAT_GRAYSCALE) {
if (sensor_pid == OV3660_PID || sensor_pid == OV5640_PID || sensor_pid == NT99141_PID || sensor_pid == SC031GS_PID || sensor_pid == BF20A6_PID || sensor_pid == GC0308_PID) { if (sensor_pid == OV3660_PID || sensor_pid == OV5640_PID || sensor_pid == NT99141_PID || sensor_pid == SC031GS_PID || sensor_pid == BF20A6_PID || sensor_pid == GC0308_PID || sensor_pid == HM0360_PID) {
cam->in_bytes_per_pixel = 1; // camera sends Y8 cam->in_bytes_per_pixel = 1; // camera sends Y8
} else { } else {
cam->in_bytes_per_pixel = 2; // camera sends YU/YV cam->in_bytes_per_pixel = 2; // camera sends YU/YV

Loading…
Cancel
Save