mirror of
https://github.com/espressif/esp32-camera.git
synced 2025-07-03 15:36:49 +08:00
Add support for HM0360
This commit is contained in:
@ -43,6 +43,7 @@ if(IDF_TARGET STREQUAL "esp32" OR IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET ST
|
||||
sensors/sc031gs.c
|
||||
sensors/mega_ccm.c
|
||||
sensors/hm1055.c
|
||||
sensors/hm0360.c
|
||||
)
|
||||
|
||||
list(APPEND priv_include_dirs
|
||||
|
7
Kconfig
7
Kconfig
@ -124,6 +124,13 @@ menu "Camera configuration"
|
||||
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
|
||||
|
@ -75,6 +75,9 @@
|
||||
#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)
|
||||
#include "esp32-hal-log.h"
|
||||
@ -155,6 +158,9 @@ static const sensor_func_t g_sensors[] = {
|
||||
#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)
|
||||
|
@ -33,6 +33,7 @@ typedef enum {
|
||||
SC031GS_PID = 0x0031,
|
||||
MEGA_CCM_PID =0x039E,
|
||||
HM1055_PID = 0x0955,
|
||||
HM0360_PID = 0x0360
|
||||
} camera_pid_t;
|
||||
|
||||
typedef enum {
|
||||
@ -52,6 +53,7 @@ typedef enum {
|
||||
CAMERA_SC031GS,
|
||||
CAMERA_MEGA_CCM,
|
||||
CAMERA_HM1055,
|
||||
CAMERA_HM0360,
|
||||
CAMERA_MODEL_MAX,
|
||||
CAMERA_NONE,
|
||||
} camera_model_t;
|
||||
@ -73,6 +75,7 @@ typedef enum {
|
||||
SC031GS_SCCB_ADDR = 0x30,
|
||||
MEGA_CCM_SCCB_ADDR = 0x1F, // 0x3E >> 1
|
||||
HM1055_SCCB_ADDR = 0x24,
|
||||
HM0360_SCCB_ADDR = 0x12,
|
||||
} camera_sccb_addr_t;
|
||||
|
||||
typedef enum {
|
||||
@ -85,6 +88,7 @@ typedef enum {
|
||||
PIXFORMAT_RAW, // RAW
|
||||
PIXFORMAT_RGB444, // 3BP2P/RGB444
|
||||
PIXFORMAT_RGB555, // 3BP2P/RGB555
|
||||
PIXFORMAT_RAW8, // RAW 8-bit
|
||||
} pixformat_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -19,6 +19,7 @@ const camera_sensor_info_t camera_sensor[CAMERA_MODEL_MAX] = {
|
||||
{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_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] = {
|
||||
|
410
sensors/hm0360.c
Executable file
410
sensors/hm0360.c
Executable file
@ -0,0 +1,410 @@
|
||||
/*
|
||||
*
|
||||
* 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 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, 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);
|
||||
set_ae_level(sensor, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
|
||||
{
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable)
|
||||
{
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable)
|
||||
{
|
||||
int ret = 0;
|
||||
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;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// real gain
|
||||
static int set_agc_gain(sensor_t *sensor, int gain)
|
||||
{
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
static int set_aec_value(sensor_t *sensor, int value)
|
||||
{
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_ae_level(sensor_t *sensor, int level)
|
||||
{
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_brightness(sensor_t *sensor, int level)
|
||||
{
|
||||
int ret = 0;
|
||||
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_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)
|
||||
{
|
||||
sensor->status.brightness = 0;
|
||||
sensor->status.contrast = 0;
|
||||
sensor->status.saturation = 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 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 = NULL;
|
||||
sensor->set_brightness = set_brightness;
|
||||
sensor->set_saturation = NULL;
|
||||
sensor->set_sharpness = NULL;
|
||||
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 = NULL;
|
||||
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 = NULL;
|
||||
sensor->set_lenc = NULL;
|
||||
sensor->set_denoise = NULL;
|
||||
|
||||
sensor->get_reg = get_reg;
|
||||
sensor->set_reg = set_reg;
|
||||
sensor->set_res_raw = set_res_raw;
|
||||
sensor->set_pll = NULL;
|
||||
sensor->set_xclk = set_xclk;
|
||||
return 0;
|
||||
}
|
27
sensors/private_include/hm0360.h
Executable file
27
sensors/private_include/hm0360.h
Executable file
@ -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__
|
86
sensors/private_include/hm0360_regs.h
Executable file
86
sensors/private_include/hm0360_regs.h
Executable file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 INTERGRATION_H 0x0202
|
||||
#define INTERGRATION_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_MONIDE_SEL 0x0372
|
||||
|
||||
// sub-sampling / binning control
|
||||
#define H_SUB 0x0380
|
||||
#define V_SUB 0x0381
|
||||
#define BINNING 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
|
||||
|
||||
// automatic exposure programming
|
||||
#define AE_CTRL 0x2000
|
||||
#define AE_CTRL2 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
|
||||
|
||||
|
||||
#endif //__REG_REGS_H__
|
509
sensors/private_include/hm0360_settings.h
Executable file
509
sensors/private_include/hm0360_settings.h
Executable file
@ -0,0 +1,509 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define REG_DLY 0xffff
|
||||
#define REGLIST_TAIL 0xffff
|
||||
|
||||
static const DRAM_ATTR uint16_t sensor_default_regs[][2] = {
|
||||
{0x0103, 0x00},
|
||||
// 0xffff,0xc0,
|
||||
{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, 0x05},
|
||||
{0x30DE, 0x05},
|
||||
{0x30E3, 0x05},
|
||||
{0x30E8, 0x05},
|
||||
{0x30ED, 0x05},
|
||||
{0x30F2, 0x05},
|
||||
{0x30F7, 0x05},
|
||||
{0x30FC, 0x05},
|
||||
{0x3101, 0x05},
|
||||
{0x3106, 0x05},
|
||||
{0x30C4, 0x10},
|
||||
{0x30C5, 0x01},
|
||||
{0x30C6, 0xBF},
|
||||
{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, 0x18},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{0x1030, 0x09},
|
||||
{0x1031, 0x12},
|
||||
{0x1032, 0x23},
|
||||
{0x1033, 0x31},
|
||||
{0x1034, 0x3E},
|
||||
{0x1035, 0x4B},
|
||||
{0x1036, 0x56},
|
||||
{0x1037, 0x5E},
|
||||
{0x1038, 0x65},
|
||||
{0x1039, 0x72},
|
||||
{0x103A, 0x7F},
|
||||
{0x103B, 0x8C},
|
||||
{0x103C, 0x98},
|
||||
{0x103D, 0xB2},
|
||||
{0x103E, 0xCC},
|
||||
{0x103F, 0xE6},
|
||||
{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},
|
||||
{0x3024, 0x00},
|
||||
{0x3025, 0x12},
|
||||
{0x3026, 0x03},
|
||||
{0x3027, 0x81},
|
||||
{0x3028, 0x01},
|
||||
{0x3029, 0x00},
|
||||
{0x302A, 0x30},
|
||||
{0x2061, 0x00},
|
||||
{0x2062, 0x00},
|
||||
{0x2063, 0xC8},
|
||||
{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},
|
||||
{0x2800, 0x00},
|
||||
{0x0370, 0x00},
|
||||
{0x0371, 0x00},
|
||||
{0x0372, 0x01},
|
||||
{0x100A, 0x05},
|
||||
{0x2590, 0x01},
|
||||
{0x0104, 0x01},
|
||||
{0x0100, 0x01},
|
||||
// 0xFFFF,0xC0,
|
||||
{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_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},
|
||||
};
|
@ -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)
|
||||
{
|
||||
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
|
||||
} else {
|
||||
cam->in_bytes_per_pixel = 2; // camera sends YU/YV
|
||||
|
Reference in New Issue
Block a user