mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
sensors: Add support for HIMAX HM0360.
This commit is contained in:
parent
e3ba901270
commit
cc9ed3a477
@ -38,6 +38,7 @@ SRCS += $(addprefix sensors/, \
|
||||
mt9m114.c \
|
||||
lepton.c \
|
||||
hm01b0.c \
|
||||
hm0360.c \
|
||||
gc2145.c \
|
||||
paj6100.c \
|
||||
frogeye2020.c \
|
||||
|
||||
@ -66,6 +66,7 @@
|
||||
#define OMV_ENABLE_MT9V0XX (1)
|
||||
#define OMV_ENABLE_LEPTON (0)
|
||||
#define OMV_ENABLE_HM01B0 (1)
|
||||
#define OMV_ENABLE_HM0360 (1)
|
||||
#define OMV_ENABLE_GC2145 (0)
|
||||
|
||||
// Enable sensor features
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#define MT9V0XX_SLV_ADDR (0xB8)
|
||||
#define MT9M114_SLV_ADDR (0x90)
|
||||
#define LEPTON_SLV_ADDR (0x54)
|
||||
#define HM01B0_SLV_ADDR (0x48)
|
||||
#define HM0XX0_SLV_ADDR (0x48)
|
||||
#define GC2145_SLV_ADDR (0x78)
|
||||
#define FROGEYE2020_SLV_ADDR (0x6E)
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
#define LEPTON_3_0 (0x5430)
|
||||
#define LEPTON_3_5 (0x5435)
|
||||
#define HM01B0_ID (0xB0)
|
||||
#define HM0360_ID (0x60)
|
||||
#define GC2145_ID (0x21)
|
||||
#define PAJ6100_ID (0x6100)
|
||||
#define FROGEYE2020_ID (0x2020)
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "mt9m114.h"
|
||||
#include "lepton.h"
|
||||
#include "hm01b0.h"
|
||||
#include "hm0360.h"
|
||||
#include "paj6100.h"
|
||||
#include "frogeye2020.h"
|
||||
#include "gc2145.h"
|
||||
@ -273,11 +274,11 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed)
|
||||
break;
|
||||
#endif // (OMV_ENABLE_LEPTON == 1)
|
||||
|
||||
#if (OMV_ENABLE_HM01B0 == 1)
|
||||
case HM01B0_SLV_ADDR:
|
||||
#if (OMV_ENABLE_HM01B0 == 1) || (OMV_ENABLE_HM0360 == 1)
|
||||
case HM0XX0_SLV_ADDR:
|
||||
cambus_readb2(&sensor.bus, sensor.slv_addr, HIMAX_CHIP_ID, &sensor.chip_id);
|
||||
break;
|
||||
#endif //(OMV_ENABLE_HM01B0 == 1)
|
||||
#endif // (OMV_ENABLE_HM01B0 == 1) || (OMV_ENABLE_HM0360 == 1)
|
||||
|
||||
#if (OMV_ENABLE_GC2145 == 1)
|
||||
case GC2145_SLV_ADDR:
|
||||
@ -406,6 +407,15 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed)
|
||||
break;
|
||||
#endif //(OMV_ENABLE_HM01B0 == 1)
|
||||
|
||||
#if (OMV_ENABLE_HM0360 == 1)
|
||||
case HM0360_ID:
|
||||
if (sensor_set_xclk_frequency(HM0360_XCLK_FREQ) != 0) {
|
||||
return SENSOR_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
init_ret = hm0360_init(&sensor);
|
||||
break;
|
||||
#endif //(OMV_ENABLE_HM0360 == 1)
|
||||
|
||||
#if (OMV_ENABLE_GC2145 == 1)
|
||||
case GC2145_ID:
|
||||
if (sensor_set_xclk_frequency(GC2145_XCLK_FREQ) != 0) {
|
||||
|
||||
@ -160,6 +160,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
|
||||
mt9m114.o \
|
||||
lepton.o \
|
||||
hm01b0.o \
|
||||
hm0360.o \
|
||||
gc2145.o \
|
||||
paj6100.o \
|
||||
frogeye2020.o \
|
||||
@ -537,6 +538,7 @@ UVC_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
|
||||
mt9m114.o \
|
||||
lepton.o \
|
||||
hm01b0.o \
|
||||
hm0360.o \
|
||||
gc2145.o \
|
||||
paj6100.o \
|
||||
frogeye2020.o \
|
||||
|
||||
793
src/omv/sensors/hm0360.c
Normal file
793
src/omv/sensors/hm0360.c
Normal file
@ -0,0 +1,793 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2022 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* HM0360 driver.
|
||||
*/
|
||||
#include "omv_boardconfig.h"
|
||||
#if (OMV_ENABLE_HM0360 == 1)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cambus.h"
|
||||
#include "sensor.h"
|
||||
#include "hm0360.h"
|
||||
#include "hm0360_regs.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#define HIMAX_BOOT_RETRY (10)
|
||||
#define HIMAX_LINE_LEN_PCK_VGA 0x300
|
||||
#define HIMAX_FRAME_LENGTH_VGA 0x214
|
||||
|
||||
#define HIMAX_LINE_LEN_PCK_QVGA 0x178
|
||||
#define HIMAX_FRAME_LENGTH_QVGA 0x109
|
||||
|
||||
#define HIMAX_LINE_LEN_PCK_QQVGA 0x178
|
||||
#define HIMAX_FRAME_LENGTH_QQVGA 0x084
|
||||
|
||||
#define HIMAX_MD_ROI_VGA_W 40
|
||||
#define HIMAX_MD_ROI_VGA_H 30
|
||||
|
||||
#define HIMAX_MD_ROI_QVGA_W 20
|
||||
#define HIMAX_MD_ROI_QVGA_H 15
|
||||
|
||||
#define HIMAX_MD_ROI_QQVGA_W 10
|
||||
#define HIMAX_MD_ROI_QQVGA_H 8
|
||||
|
||||
static const uint16_t default_regs[][2] = {
|
||||
{SW_RESET, 0x00},
|
||||
{MONO_MODE, 0x00},
|
||||
{MONO_MODE_ISP, 0x01},
|
||||
{MONO_MODE_SEL, 0x01},
|
||||
|
||||
// BLC control
|
||||
{0x1000, 0x01},
|
||||
{0x1003, 0x04},
|
||||
{BLC_TGT, 0x04},
|
||||
{0x1007, 0x01},
|
||||
{0x1008, 0x04},
|
||||
{BLC2_TGT, 0x04},
|
||||
{MONO_CTRL, 0x01},
|
||||
|
||||
// Output format control
|
||||
{OPFM_CTRL, 0x0C},
|
||||
|
||||
// Reserved regs
|
||||
{0x101D, 0x00},
|
||||
{0x101E, 0x01},
|
||||
{0x101F, 0x00},
|
||||
{0x1020, 0x01},
|
||||
{0x1021, 0x00},
|
||||
|
||||
{CMPRS_CTRL, 0x00},
|
||||
{CMPRS_01, 0x09},
|
||||
{CMPRS_02, 0x12},
|
||||
{CMPRS_03, 0x23},
|
||||
{CMPRS_04, 0x31},
|
||||
{CMPRS_05, 0x3E},
|
||||
{CMPRS_06, 0x4B},
|
||||
{CMPRS_07, 0x56},
|
||||
{CMPRS_08, 0x5E},
|
||||
{CMPRS_09, 0x65},
|
||||
{CMPRS_10, 0x72},
|
||||
{CMPRS_11, 0x7F},
|
||||
{CMPRS_12, 0x8C},
|
||||
{CMPRS_13, 0x98},
|
||||
{CMPRS_14, 0xB2},
|
||||
{CMPRS_15, 0xCC},
|
||||
{CMPRS_16, 0xE6},
|
||||
|
||||
{0x3112, 0x00}, // PCLKO_polarity falling
|
||||
|
||||
{PLL1_CONFIG, 0x04}, // Core = MCLK/1 PCLKO = MCLK/2 REG = MCLK/1
|
||||
{PLL2_CONFIG, 0x0A}, // MIPI pre-dev (default)
|
||||
{PLL3_CONFIG, 0x77}, // PMU/MIPI pre-dev (default)
|
||||
|
||||
{PMU_CFG_3, 0x08}, // Disable context switching
|
||||
{PAD_REGISTER_07, 0x00}, // PCLKO_polarity falling
|
||||
|
||||
{AE_CTRL, 0x5F}, // Automatic Exposure (NOTE: Auto framerate enabled)
|
||||
{AE_CTRL1, 0x00},
|
||||
{T_DAMPING, 0x20}, // AE T damping factor
|
||||
{N_DAMPING, 0x00}, // AE N damping factor
|
||||
{AE_TARGET_MEAN, 0x64}, // AE target
|
||||
{AE_MIN_MEAN, 0x0A}, // AE min target mean
|
||||
{AE_TARGET_ZONE, 0x23}, // AE target zone
|
||||
{CONVERGE_IN_TH, 0x03}, // AE converge in threshold
|
||||
{CONVERGE_OUT_TH, 0x05}, // AE converge out threshold
|
||||
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_QVGA-4)>>8},
|
||||
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_QVGA-4)&0xFF},
|
||||
|
||||
{MAX_AGAIN, 0x04}, // Maximum analog gain
|
||||
{MAX_DGAIN_H, 0x03},
|
||||
{MAX_DGAIN_L, 0x3F},
|
||||
{INTEGRATION_H, 0x01},
|
||||
{INTEGRATION_L, 0x08},
|
||||
|
||||
{MD_CTRL, 0x6A},
|
||||
{MD_TH_MIN, 0x01},
|
||||
{MD_BLOCK_NUM_TH, 0x01},
|
||||
{MD_CTRL1, 0x06},
|
||||
{PULSE_MODE, 0x00}, // Interrupt in level mode.
|
||||
{ROI_START_END_V, 0xF0},
|
||||
{ROI_START_END_H, 0xF0},
|
||||
|
||||
{FRAME_LEN_LINES_H, HIMAX_FRAME_LENGTH_QVGA>>8},
|
||||
{FRAME_LEN_LINES_L, HIMAX_FRAME_LENGTH_QVGA&0xFF},
|
||||
{LINE_LEN_PCK_H, HIMAX_LINE_LEN_PCK_QVGA>>8},
|
||||
{LINE_LEN_PCK_L, HIMAX_LINE_LEN_PCK_QVGA&0xFF},
|
||||
{H_SUBSAMPLE, 0x01},
|
||||
{V_SUBSAMPLE, 0x01},
|
||||
{BINNING_MODE, 0x00},
|
||||
{WIN_MODE, 0x00},
|
||||
{IMG_ORIENTATION, 0x00},
|
||||
{COMMAND_UPDATE, 0x01},
|
||||
|
||||
/// SYNC function config.
|
||||
{0x3010, 0x00},
|
||||
{0x3013, 0x01},
|
||||
{0x3019, 0x00},
|
||||
{0x301A, 0x00},
|
||||
{0x301B, 0x20},
|
||||
{0x301C, 0xFF},
|
||||
|
||||
// PREMETER config.
|
||||
{0x3026, 0x03},
|
||||
{0x3027, 0x81},
|
||||
{0x3028, 0x01},
|
||||
{0x3029, 0x00},
|
||||
{0x302A, 0x30},
|
||||
{0x302E, 0x00},
|
||||
{0x302F, 0x00},
|
||||
|
||||
// Magic regs 🪄.
|
||||
{0x302B, 0x2A},
|
||||
{0x302C, 0x00},
|
||||
{0x302D, 0x03},
|
||||
{0x3031, 0x01},
|
||||
{0x3051, 0x00},
|
||||
{0x305C, 0x03},
|
||||
{0x3060, 0x00},
|
||||
{0x3061, 0xFA},
|
||||
{0x3062, 0xFF},
|
||||
{0x3063, 0xFF},
|
||||
{0x3064, 0xFF},
|
||||
{0x3065, 0xFF},
|
||||
{0x3066, 0xFF},
|
||||
{0x3067, 0xFF},
|
||||
{0x3068, 0xFF},
|
||||
{0x3069, 0xFF},
|
||||
{0x306A, 0xFF},
|
||||
{0x306B, 0xFF},
|
||||
{0x306C, 0xFF},
|
||||
{0x306D, 0xFF},
|
||||
{0x306E, 0xFF},
|
||||
{0x306F, 0xFF},
|
||||
{0x3070, 0xFF},
|
||||
{0x3071, 0xFF},
|
||||
{0x3072, 0xFF},
|
||||
{0x3073, 0xFF},
|
||||
{0x3074, 0xFF},
|
||||
{0x3075, 0xFF},
|
||||
{0x3076, 0xFF},
|
||||
{0x3077, 0xFF},
|
||||
{0x3078, 0xFF},
|
||||
{0x3079, 0xFF},
|
||||
{0x307A, 0xFF},
|
||||
{0x307B, 0xFF},
|
||||
{0x307C, 0xFF},
|
||||
{0x307D, 0xFF},
|
||||
{0x307E, 0xFF},
|
||||
{0x307F, 0xFF},
|
||||
{0x3080, 0x01},
|
||||
{0x3081, 0x01},
|
||||
{0x3082, 0x03},
|
||||
{0x3083, 0x20},
|
||||
{0x3084, 0x00},
|
||||
{0x3085, 0x20},
|
||||
{0x3086, 0x00},
|
||||
{0x3087, 0x20},
|
||||
{0x3088, 0x00},
|
||||
{0x3089, 0x04},
|
||||
{0x3094, 0x02},
|
||||
{0x3095, 0x02},
|
||||
{0x3096, 0x00},
|
||||
{0x3097, 0x02},
|
||||
{0x3098, 0x00},
|
||||
{0x3099, 0x02},
|
||||
{0x309E, 0x05},
|
||||
{0x309F, 0x02},
|
||||
{0x30A0, 0x02},
|
||||
{0x30A1, 0x00},
|
||||
{0x30A2, 0x08},
|
||||
{0x30A3, 0x00},
|
||||
{0x30A4, 0x20},
|
||||
{0x30A5, 0x04},
|
||||
{0x30A6, 0x02},
|
||||
{0x30A7, 0x02},
|
||||
{0x30A8, 0x01},
|
||||
{0x30A9, 0x00},
|
||||
{0x30AA, 0x02},
|
||||
{0x30AB, 0x34},
|
||||
{0x30B0, 0x03},
|
||||
{0x30C4, 0x10},
|
||||
{0x30C5, 0x01},
|
||||
{0x30C6, 0xBF},
|
||||
{0x30C7, 0x00},
|
||||
{0x30C8, 0x00},
|
||||
{0x30CB, 0xFF},
|
||||
{0x30CC, 0xFF},
|
||||
{0x30CD, 0x7F},
|
||||
{0x30CE, 0x7F},
|
||||
{0x30D3, 0x01},
|
||||
{0x30D4, 0xFF},
|
||||
{0x30D5, 0x00},
|
||||
{0x30D6, 0x40},
|
||||
{0x30D7, 0x00},
|
||||
{0x30D8, 0xA7},
|
||||
{0x30D9, 0x05},
|
||||
{0x30DA, 0x01},
|
||||
{0x30DB, 0x40},
|
||||
{0x30DC, 0x00},
|
||||
{0x30DD, 0x27},
|
||||
{0x30DE, 0x05},
|
||||
{0x30DF, 0x07},
|
||||
{0x30E0, 0x40},
|
||||
{0x30E1, 0x00},
|
||||
{0x30E2, 0x27},
|
||||
{0x30E3, 0x05},
|
||||
{0x30E4, 0x47},
|
||||
{0x30E5, 0x30},
|
||||
{0x30E6, 0x00},
|
||||
{0x30E7, 0x27},
|
||||
{0x30E8, 0x05},
|
||||
{0x30E9, 0x87},
|
||||
{0x30EA, 0x30},
|
||||
{0x30EB, 0x00},
|
||||
{0x30EC, 0x27},
|
||||
{0x30ED, 0x05},
|
||||
{0x30EE, 0x00},
|
||||
{0x30EF, 0x40},
|
||||
{0x30F0, 0x00},
|
||||
{0x30F1, 0xA7},
|
||||
{0x30F2, 0x05},
|
||||
{0x30F3, 0x01},
|
||||
{0x30F4, 0x40},
|
||||
{0x30F5, 0x00},
|
||||
{0x30F6, 0x27},
|
||||
{0x30F7, 0x05},
|
||||
{0x30F8, 0x07},
|
||||
{0x30F9, 0x40},
|
||||
{0x30FA, 0x00},
|
||||
{0x30FB, 0x27},
|
||||
{0x30FC, 0x05},
|
||||
{0x30FD, 0x47},
|
||||
{0x30FE, 0x30},
|
||||
{0x30FF, 0x00},
|
||||
{0x3100, 0x27},
|
||||
{0x3101, 0x05},
|
||||
{0x3102, 0x87},
|
||||
{0x3103, 0x30},
|
||||
{0x3104, 0x00},
|
||||
{0x3105, 0x27},
|
||||
{0x3106, 0x05},
|
||||
{0x310B, 0x10},
|
||||
{0x3113, 0xA0},
|
||||
{0x3114, 0x67},
|
||||
{0x3115, 0x42},
|
||||
{0x3116, 0x10},
|
||||
{0x3117, 0x0A},
|
||||
{0x3118, 0x3F},
|
||||
{0x311C, 0x10},
|
||||
{0x311D, 0x06},
|
||||
{0x311E, 0x0F},
|
||||
{0x311F, 0x0E},
|
||||
{0x3120, 0x0D},
|
||||
{0x3121, 0x0F},
|
||||
{0x3122, 0x00},
|
||||
{0x3123, 0x1D},
|
||||
{0x3126, 0x03},
|
||||
{0x3128, 0x57},
|
||||
{0x312A, 0x11},
|
||||
{0x312B, 0x41},
|
||||
{0x312E, 0x00},
|
||||
{0x312F, 0x00},
|
||||
{0x3130, 0x0C},
|
||||
{0x3141, 0x2A},
|
||||
{0x3142, 0x9F},
|
||||
{0x3147, 0x18},
|
||||
{0x3149, 0x18},
|
||||
{0x314B, 0x01},
|
||||
{0x3150, 0x50},
|
||||
{0x3152, 0x00},
|
||||
{0x3156, 0x2C},
|
||||
{0x315A, 0x0A},
|
||||
{0x315B, 0x2F},
|
||||
{0x315C, 0xE0},
|
||||
{0x315F, 0x02},
|
||||
{0x3160, 0x1F},
|
||||
{0x3163, 0x1F},
|
||||
{0x3164, 0x7F},
|
||||
{0x3165, 0x7F},
|
||||
{0x317B, 0x94},
|
||||
{0x317C, 0x00},
|
||||
{0x317D, 0x02},
|
||||
{0x318C, 0x00},
|
||||
|
||||
{COMMAND_UPDATE, 0x01},
|
||||
{0x0000, 0x00},
|
||||
};
|
||||
|
||||
static int reset(sensor_t *sensor)
|
||||
{
|
||||
// Reset sensor.
|
||||
uint8_t reg=0xff;
|
||||
for (int retry=HIMAX_BOOT_RETRY; retry >= 0 && reg != HIMAX_MODE_STANDBY; retry--) {
|
||||
if (cambus_writeb2(&sensor->bus, sensor->slv_addr, SW_RESET, HIMAX_RESET) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(1);
|
||||
|
||||
if (cambus_readb2(&sensor->bus, sensor->slv_addr, MODE_SELECT, ®) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (reg == HIMAX_MODE_STANDBY) {
|
||||
break;
|
||||
} else if (retry == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(10);
|
||||
}
|
||||
|
||||
// Write default regsiters
|
||||
int ret = 0;
|
||||
for (int i=0; default_regs[i][0] && ret == 0; i++) {
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, default_regs[i][0], default_regs[i][1]);
|
||||
}
|
||||
|
||||
// Set mode to streaming
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MODE_SELECT, HIMAX_MODE_STREAMING);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_reg(sensor_t *sensor, uint16_t reg_addr)
|
||||
{
|
||||
uint8_t reg_data;
|
||||
if (cambus_readb2(&sensor->bus, sensor->slv_addr, reg_addr, ®_data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return reg_data;
|
||||
}
|
||||
|
||||
static int write_reg(sensor_t *sensor, uint16_t reg_addr, uint16_t reg_data)
|
||||
{
|
||||
return cambus_writeb2(&sensor->bus, sensor->slv_addr, reg_addr, reg_data);
|
||||
}
|
||||
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
|
||||
{
|
||||
switch (pixformat) {
|
||||
case PIXFORMAT_BAYER:
|
||||
case PIXFORMAT_GRAYSCALE:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static const uint16_t VGA_regs[][2] = {
|
||||
{PLL1_CONFIG, 0x04}, // Core = MCLK/1 PCLKO = MCLK/2 REG = MCLK/1
|
||||
{H_SUBSAMPLE, 0x00},
|
||||
{V_SUBSAMPLE, 0x00},
|
||||
{BINNING_MODE, 0x00},
|
||||
{WIN_MODE, 0x00},
|
||||
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_VGA-4)>>8},
|
||||
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_VGA-4)&0xFF},
|
||||
{FRAME_LEN_LINES_H, (HIMAX_FRAME_LENGTH_VGA>>8)},
|
||||
{FRAME_LEN_LINES_L, (HIMAX_FRAME_LENGTH_VGA&0xFF)},
|
||||
{LINE_LEN_PCK_H, (HIMAX_LINE_LEN_PCK_VGA>>8)},
|
||||
{LINE_LEN_PCK_L, (HIMAX_LINE_LEN_PCK_VGA&0xFF)},
|
||||
{ROI_START_END_H, 0xF0},
|
||||
{ROI_START_END_V, 0xE0},
|
||||
{COMMAND_UPDATE, 0x01},
|
||||
{0x0000, 0x00},
|
||||
};
|
||||
|
||||
static const uint16_t QVGA_regs[][2] = {
|
||||
{PLL1_CONFIG, 0x05}, // Core = MCLK/1 PCLKO = MCLK/2 REG = MCLK/2
|
||||
{H_SUBSAMPLE, 0x01},
|
||||
{V_SUBSAMPLE, 0x01},
|
||||
{BINNING_MODE, 0x00},
|
||||
{WIN_MODE, 0x00},
|
||||
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_QVGA-4)>>8},
|
||||
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_QVGA-4)&0xFF},
|
||||
{FRAME_LEN_LINES_H, (HIMAX_FRAME_LENGTH_QVGA>>8)},
|
||||
{FRAME_LEN_LINES_L, (HIMAX_FRAME_LENGTH_QVGA&0xFF)},
|
||||
{LINE_LEN_PCK_H, (HIMAX_LINE_LEN_PCK_QVGA>>8)},
|
||||
{LINE_LEN_PCK_L, (HIMAX_LINE_LEN_PCK_QVGA&0xFF)},
|
||||
{ROI_START_END_H, 0xF0},
|
||||
{ROI_START_END_V, 0xE0},
|
||||
{COMMAND_UPDATE, 0x01},
|
||||
{0x0000, 0x00},
|
||||
};
|
||||
|
||||
static const uint16_t QQVGA_regs[][2] = {
|
||||
{PLL1_CONFIG, 0x05}, // Core = MCLK/1 PCLKO = MCLK/2 REG = MCLK/2
|
||||
{H_SUBSAMPLE, 0x02},
|
||||
{V_SUBSAMPLE, 0x02},
|
||||
{BINNING_MODE, 0x00},
|
||||
{WIN_MODE, 0x00},
|
||||
{MAX_INTG_H, (HIMAX_FRAME_LENGTH_QQVGA-4)>>8},
|
||||
{MAX_INTG_L, (HIMAX_FRAME_LENGTH_QQVGA-4)&0xFF},
|
||||
{FRAME_LEN_LINES_H, (HIMAX_FRAME_LENGTH_QQVGA>>8)},
|
||||
{FRAME_LEN_LINES_L, (HIMAX_FRAME_LENGTH_QQVGA&0xFF)},
|
||||
{LINE_LEN_PCK_H, (HIMAX_LINE_LEN_PCK_QQVGA>>8)},
|
||||
{LINE_LEN_PCK_L, (HIMAX_LINE_LEN_PCK_QQVGA&0xFF)},
|
||||
{ROI_START_END_H, 0xF0},
|
||||
{ROI_START_END_V, 0xD0},
|
||||
{COMMAND_UPDATE, 0x01},
|
||||
{0x0000, 0x00},
|
||||
};
|
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
{
|
||||
int ret=0;
|
||||
switch (framesize) {
|
||||
case FRAMESIZE_VGA:
|
||||
for (int i=0; VGA_regs[i][0] && ret == 0; i++) {
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, VGA_regs[i][0], VGA_regs[i][1]);
|
||||
}
|
||||
break;
|
||||
case FRAMESIZE_QVGA:
|
||||
for (int i=0; QVGA_regs[i][0] && ret == 0; i++) {
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, QVGA_regs[i][0], QVGA_regs[i][1]);
|
||||
}
|
||||
break;
|
||||
case FRAMESIZE_QQVGA:
|
||||
for (int i=0; QQVGA_regs[i][0] && ret == 0; i++) {
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, QQVGA_regs[i][0], QQVGA_regs[i][1]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_framerate(sensor_t *sensor, int framerate)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t pll_cfg = 0;
|
||||
uint8_t osc_div = 0;
|
||||
bool highres = false;
|
||||
|
||||
if (sensor->framesize == FRAMESIZE_VGA) {
|
||||
highres = true;
|
||||
}
|
||||
|
||||
if (framerate <= 10) {
|
||||
osc_div = (highres == true) ? 0x03 : 0x03;
|
||||
} else if (framerate <= 15) {
|
||||
osc_div = (highres == true) ? 0x02 : 0x03;
|
||||
} else if (framerate <= 30) {
|
||||
osc_div = (highres == true) ? 0x01 : 0x02;
|
||||
} else {
|
||||
// Set to the max possible FPS at this resolution.
|
||||
osc_div = (highres == true) ? 0x00 : 0x01;
|
||||
}
|
||||
|
||||
ret |= cambus_readb2(&sensor->bus, sensor->slv_addr, PLL1_CONFIG, &pll_cfg);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, PLL1_CONFIG, (pll_cfg & 0xFC) | osc_div);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_brightness(sensor_t *sensor, int level)
|
||||
{
|
||||
uint8_t ae_mean;
|
||||
// Simulate brightness levels by setting AE loop target mean.
|
||||
switch (level) {
|
||||
case 1:
|
||||
ae_mean = 150;
|
||||
break;
|
||||
case 2:
|
||||
ae_mean = 200;
|
||||
break;
|
||||
case 3:
|
||||
ae_mean = 250;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
ae_mean = 100;
|
||||
break;
|
||||
}
|
||||
return cambus_writeb2(&sensor->bus, sensor->slv_addr, AE_TARGET_MEAN, ae_mean);
|
||||
}
|
||||
|
||||
static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
|
||||
{
|
||||
int ret = 0;
|
||||
int gain = 0x0;
|
||||
switch (gainceiling) {
|
||||
case GAINCEILING_2X:
|
||||
gain = 0x01;
|
||||
break;
|
||||
case GAINCEILING_4X:
|
||||
gain = 0x02;
|
||||
break;
|
||||
case GAINCEILING_8X:
|
||||
gain = 0x03;
|
||||
break;
|
||||
case GAINCEILING_16X:
|
||||
gain = 0x04;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MAX_AGAIN, (gain & 0x07));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_colorbar(sensor_t *sensor, int enable)
|
||||
{
|
||||
return cambus_writeb2(&sensor->bus, sensor->slv_addr, TEST_PATTERN_MODE, enable & 0x1);
|
||||
}
|
||||
|
||||
static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling)
|
||||
{
|
||||
uint8_t ae_ctrl = 0;
|
||||
int ret = cambus_readb2(&sensor->bus, sensor->slv_addr, AE_CTRL, &ae_ctrl);
|
||||
if (!enable && (!isnanf(gain_db)) && (!isinff(gain_db))) {
|
||||
gain_db = IM_MAX(IM_MIN(gain_db, 24.0f), 0.0f);
|
||||
uint8_t gain = fast_ceilf(fast_log2(fast_expf((gain_db / 20.0f) * fast_log(10.0f))));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, AE_CTRL, (ae_ctrl & 0xFE));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, ANALOG_GAIN, ((gain & 0x7)<<4));
|
||||
} else if (enable && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
|
||||
gain_db_ceiling = IM_MAX(IM_MIN(gain_db_ceiling, 24.0f), 0.0f);
|
||||
uint8_t gain = fast_ceilf(fast_log2(fast_expf((gain_db_ceiling / 20.0f) * fast_log(10.0f))));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MAX_AGAIN, (gain & 0x07));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, AE_CTRL, (ae_ctrl | 0x01));
|
||||
}
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, COMMAND_UPDATE, 0x01);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_gain_db(sensor_t *sensor, float *gain_db)
|
||||
{
|
||||
uint8_t gain;
|
||||
if (cambus_readb2(&sensor->bus, sensor->slv_addr, ANALOG_GAIN, &gain) != 0) {
|
||||
return -1;
|
||||
}
|
||||
*gain_db = fast_floorf(fast_log(1 << (gain>>4)) / fast_log(10.0f) * 20.0f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_vt_pix_clk(sensor_t *sensor, uint32_t *vt_pix_clk)
|
||||
{
|
||||
uint8_t reg;
|
||||
if (cambus_readb2(&sensor->bus, sensor->slv_addr, PLL1_CONFIG, ®) != 0) {
|
||||
return -1;
|
||||
}
|
||||
// 00 -> MCLK / 1
|
||||
// 01 -> MCLK / 2
|
||||
// 10 -> MCLK / 4
|
||||
// 11 -> MCLK / 8
|
||||
uint32_t vt_sys_div = (1 << (reg & 0x03));
|
||||
|
||||
// vt_pix_clk = MCLK / vt_sys_div
|
||||
*vt_pix_clk = OMV_XCLK_FREQUENCY / vt_sys_div;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
|
||||
{
|
||||
uint8_t ae_ctrl = 0;
|
||||
int ret = cambus_readb2(&sensor->bus, sensor->slv_addr, AE_CTRL, &ae_ctrl);
|
||||
|
||||
if (enable) {
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, AE_CTRL, (ae_ctrl | 0x01));
|
||||
} else {
|
||||
uint32_t line_len;
|
||||
uint32_t frame_len;
|
||||
uint32_t coarse_int;
|
||||
uint32_t vt_pix_clk = 0;
|
||||
|
||||
switch (sensor->framesize) {
|
||||
case FRAMESIZE_VGA:
|
||||
line_len = HIMAX_LINE_LEN_PCK_VGA;
|
||||
frame_len = HIMAX_FRAME_LENGTH_VGA;
|
||||
break;
|
||||
case FRAMESIZE_QVGA:
|
||||
line_len = HIMAX_LINE_LEN_PCK_QVGA;
|
||||
frame_len = HIMAX_FRAME_LENGTH_QVGA;
|
||||
break;
|
||||
case FRAMESIZE_QQVGA:
|
||||
line_len = HIMAX_LINE_LEN_PCK_QQVGA;
|
||||
frame_len = HIMAX_FRAME_LENGTH_QQVGA;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret |= get_vt_pix_clk(sensor, &vt_pix_clk);
|
||||
coarse_int = fast_roundf(exposure_us * (vt_pix_clk / 1000000.0f) / line_len);
|
||||
|
||||
if (coarse_int < 2) {
|
||||
coarse_int = 2;
|
||||
} else if (coarse_int > (frame_len-4)) {
|
||||
coarse_int = frame_len-4;
|
||||
}
|
||||
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, AE_CTRL, (ae_ctrl & 0xFE));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, INTEGRATION_H, coarse_int>>8);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, INTEGRATION_L, coarse_int&0xff);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, COMMAND_UPDATE, 0x01);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t line_len;
|
||||
uint32_t coarse_int = 0;
|
||||
uint32_t vt_pix_clk = 0;
|
||||
switch (sensor->framesize) {
|
||||
case FRAMESIZE_VGA:
|
||||
line_len = HIMAX_LINE_LEN_PCK_VGA;
|
||||
break;
|
||||
case FRAMESIZE_QVGA:
|
||||
line_len = HIMAX_LINE_LEN_PCK_QVGA;
|
||||
break;
|
||||
case FRAMESIZE_QQVGA:
|
||||
line_len = HIMAX_LINE_LEN_PCK_QQVGA;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
ret |= get_vt_pix_clk(sensor, &vt_pix_clk);
|
||||
ret |= cambus_readb2(&sensor->bus, sensor->slv_addr, INTEGRATION_H, &((uint8_t*)&coarse_int)[1]);
|
||||
ret |= cambus_readb2(&sensor->bus, sensor->slv_addr, INTEGRATION_L, &((uint8_t*)&coarse_int)[0]);
|
||||
*exposure_us = fast_roundf(coarse_int * line_len / (vt_pix_clk / 1000000.0f));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable)
|
||||
{
|
||||
uint8_t reg;
|
||||
int ret = cambus_readb2(&sensor->bus, sensor->slv_addr, IMG_ORIENTATION, ®);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, IMG_ORIENTATION, HIMAX_SET_HMIRROR(reg, enable)) ;
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, COMMAND_UPDATE, 0x01);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable)
|
||||
{
|
||||
uint8_t reg;
|
||||
int ret = cambus_readb2(&sensor->bus, sensor->slv_addr, IMG_ORIENTATION, ®);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, IMG_ORIENTATION, HIMAX_SET_VMIRROR(reg, enable)) ;
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, COMMAND_UPDATE, 0x01);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ioctl(sensor_t *sensor, int request, va_list ap)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (request) {
|
||||
case IOCTL_HIMAX_OSC_ENABLE: {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_ENABLE: {
|
||||
int ret = 0;
|
||||
uint8_t md_ctrl = 0;
|
||||
uint32_t enable = va_arg(ap, uint32_t) & 0x01;
|
||||
ret |= cambus_readb2(&sensor->bus, sensor->slv_addr, MD_CTRL, &md_ctrl);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_CTRL, (md_ctrl & 0xFE) | enable);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_WINDOW: {
|
||||
int ret = 0;
|
||||
int32_t roi_w = 0;
|
||||
int32_t roi_h = 0;
|
||||
int32_t roi_max_h = 14;
|
||||
|
||||
int32_t x1 = va_arg(ap, int32_t);
|
||||
int32_t y1 = va_arg(ap, int32_t);
|
||||
int32_t x2 = va_arg(ap, int32_t) + x1;
|
||||
int32_t y2 = va_arg(ap, int32_t) + y1;
|
||||
|
||||
switch (sensor->framesize) {
|
||||
case FRAMESIZE_VGA:
|
||||
roi_w = HIMAX_MD_ROI_VGA_W;
|
||||
roi_h = HIMAX_MD_ROI_VGA_H;
|
||||
roi_max_h = 14;
|
||||
break;
|
||||
case FRAMESIZE_QVGA:
|
||||
roi_w = HIMAX_MD_ROI_QVGA_W;
|
||||
roi_h = HIMAX_MD_ROI_QVGA_H;
|
||||
roi_max_h = 14;
|
||||
break;
|
||||
case FRAMESIZE_QQVGA:
|
||||
roi_w = HIMAX_MD_ROI_QQVGA_W;
|
||||
roi_h = HIMAX_MD_ROI_QQVGA_H;
|
||||
roi_max_h = 13;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
x1 = MAX((x1 / roi_w - 1), 0);
|
||||
y1 = MAX((y1 / roi_h - 1), 0);
|
||||
x2 = MIN((x2 / roi_w) + !!(x2 % roi_w), 0xF);
|
||||
y2 = MIN((y2 / roi_h) + !!(y2 % roi_h), roi_max_h);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, ROI_START_END_H, ((x2 & 0xF) << 4) | (x1 & 0x0F));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, ROI_START_END_V, ((y2 & 0xF) << 4) | (y1 & 0x0F));
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_THRESHOLD: {
|
||||
uint32_t threshold = va_arg(ap, uint32_t) & 0x3F;
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_TH_STR_L, threshold);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_TH_STR_H, threshold);
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LIGHT_COEF, threshold);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_CLEAR: {
|
||||
ret = cambus_writeb2(&sensor->bus, sensor->slv_addr, INT_CLEAR, (1 << 3));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hm0360_init(sensor_t *sensor)
|
||||
{
|
||||
// Initialize sensor structure.
|
||||
sensor->reset = reset;
|
||||
sensor->read_reg = read_reg;
|
||||
sensor->write_reg = write_reg;
|
||||
sensor->set_pixformat = set_pixformat;
|
||||
sensor->set_framesize = set_framesize;
|
||||
sensor->set_framerate = set_framerate;
|
||||
sensor->set_brightness = set_brightness;
|
||||
sensor->set_gainceiling = set_gainceiling;
|
||||
sensor->set_colorbar = set_colorbar;
|
||||
sensor->set_auto_gain = set_auto_gain;
|
||||
sensor->get_gain_db = get_gain_db;
|
||||
sensor->set_auto_exposure = set_auto_exposure;
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->ioctl = ioctl;
|
||||
|
||||
// Set sensor flags
|
||||
sensor->hw_flags.vsync = 0;
|
||||
sensor->hw_flags.hsync = 0;
|
||||
sensor->hw_flags.pixck = 0;
|
||||
sensor->hw_flags.fsync = 0;
|
||||
sensor->hw_flags.jpege = 0;
|
||||
sensor->hw_flags.gs_bpp = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif //(OMV_ENABLE_HM0360 == 1)
|
||||
15
src/omv/sensors/hm0360.h
Normal file
15
src/omv/sensors/hm0360.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2022 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* HM0360 driver.
|
||||
*/
|
||||
#ifndef __HM0360_H__
|
||||
#define __HM0360_H__
|
||||
#define HM0360_XCLK_FREQ (24000000)
|
||||
int hm0360_init(sensor_t *sensor);
|
||||
#endif // __HM0360_H__
|
||||
154
src/omv/sensors/hm0360_regs.h
Normal file
154
src/omv/sensors/hm0360_regs.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2022 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* HM0360 register definitions.
|
||||
*/
|
||||
#ifndef __REG_REGS_H__
|
||||
#define __REG_REGS_H__
|
||||
|
||||
// Read only registers
|
||||
#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_ORDER 0x0007
|
||||
// Sensor mode control
|
||||
#define MODE_SELECT 0x0100
|
||||
#define IMG_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 PLL1_CONFIG 0x0300
|
||||
#define PLL2_CONFIG 0x0301
|
||||
#define PLL3_CONFIG 0x0302
|
||||
// Frame timing control
|
||||
#define FRAME_LEN_LINES_H 0x0340
|
||||
#define FRAME_LEN_LINES_L 0x0341
|
||||
#define LINE_LEN_PCK_H 0x0342
|
||||
#define LINE_LEN_PCK_L 0x0343
|
||||
// Monochrome programming
|
||||
#define MONO_MODE 0x0370
|
||||
#define MONO_MODE_ISP 0x0371
|
||||
#define MONO_MODE_SEL 0x0372
|
||||
// Binning mode control
|
||||
#define H_SUBSAMPLE 0x0380
|
||||
#define V_SUBSAMPLE 0x0381
|
||||
#define BINNING_MODE 0x0382
|
||||
// Test pattern control
|
||||
#define TEST_PATTERN_MODE 0x0601
|
||||
// Black level control
|
||||
#define BLC_TGT 0x1004
|
||||
#define BLC2_TGT 0x1009
|
||||
#define MONO_CTRL 0x100A
|
||||
// VSYNC / HSYNC / pixel shift registers
|
||||
#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 control
|
||||
#define AE_CTRL 0x2000
|
||||
#define AE_CTRL1 0x2001
|
||||
#define CNT_ORGH_H 0x2002
|
||||
#define CNT_ORGH_L 0x2003
|
||||
#define CNT_ORGV_H 0x2004
|
||||
#define CNT_ORGV_L 0x2005
|
||||
#define CNT_STH_H 0x2006
|
||||
#define CNT_STH_L 0x2007
|
||||
#define CNT_STV_H 0x2008
|
||||
#define CNT_STV_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
|
||||
#define FS_CTRL 0x203B
|
||||
#define FS_60HZ_H 0x203C
|
||||
#define FS_60HZ_L 0x203D
|
||||
#define FS_50HZ_H 0x203E
|
||||
#define FS_50HZ_L 0x203F
|
||||
#define FRAME_CNT_TH 0x205B
|
||||
#define AE_MEAN 0x205D
|
||||
#define AE_CONVERGE 0x2060
|
||||
#define AE_BLI_TGT 0x2070
|
||||
// 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
|
||||
|
||||
// Register bits/values
|
||||
#define HIMAX_RESET 0x01
|
||||
#define HIMAX_MODE_STANDBY 0x00
|
||||
#define HIMAX_MODE_STREAMING 0x01 // I2C triggered streaming enable
|
||||
#define HIMAX_MODE_STREAMING_NFRAMES 0x03 // Output N frames
|
||||
#define HIMAX_MODE_STREAMING_TRIG 0x05 // Hardware Trigger
|
||||
#define HIMAX_SET_HMIRROR(r, x) ((r&0xFE)|((x&1)<<0))
|
||||
#define HIMAX_SET_VMIRROR(r, x) ((r&0xFD)|((x&1)<<1))
|
||||
|
||||
#define PCLK_RISING_EDGE 0x00
|
||||
#define PCLK_FALLING_EDGE 0x01
|
||||
#define AE_CTRL_ENABLE 0x00
|
||||
#define AE_CTRL_DISABLE 0x01
|
||||
|
||||
#endif //__REG_REGS_H__
|
||||
Loading…
Reference in New Issue
Block a user