Update MT driver to support the 22/24/32/34

This commit is contained in:
Kwabena W. Agyeman 2022-01-02 13:54:17 -08:00
parent 21df1c38da
commit 84f53d01bb
22 changed files with 410 additions and 343 deletions

View File

@ -33,7 +33,7 @@ SRCS += $(addprefix sensors/, \
ov7690.c \
ov7725.c \
ov9650.c \
mt9v034.c \
mt9v0xx.c \
mt9m114.c \
lepton.c \
hm01b0.c \

View File

@ -43,7 +43,7 @@ extern unsigned char *OMV_UNIQUE_ID_ADDR;
#define OMV_ENABLE_OV7690 (0)
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
@ -162,7 +162,7 @@ void pico_reset_to_bootloader(void);
#define DCMI_PIO (pio0)
#define DCMI_SM (0)
#define DCMI_DMA (0)
#define DCMI_DMA_IRQ (DMA_IRQ_0)
#define DCMI_DMA_IRQ (DMA_IRQ_0)
#define DCMI_DMA_CHANNEL (0)
#define DCMI_PWDN_PIN (0)

View File

@ -50,7 +50,7 @@
#define OMV_ENABLE_OV7690 (1)
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_MT9M114 (1)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)

View File

@ -40,7 +40,7 @@
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9M114 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
#define OMV_ENABLE_PAJ6100 (0)

View File

@ -53,7 +53,7 @@
#define OMV_ENABLE_OV7725 (1)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9M114 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
#define OMV_ENABLE_PAJ6100 (0)

View File

@ -53,7 +53,7 @@
#define OMV_ENABLE_OV7725 (1)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9M114 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
#define OMV_ENABLE_PAJ6100 (0)

View File

@ -60,7 +60,7 @@
#define OMV_ENABLE_OV7725 (1)
#define OMV_ENABLE_OV9650 (1)
#define OMV_ENABLE_MT9M114 (1)
#define OMV_ENABLE_MT9V034 (1)
#define OMV_ENABLE_MT9V0XX (1)
#define OMV_ENABLE_LEPTON (1)
#define OMV_ENABLE_HM01B0 (0)
#define OMV_ENABLE_PAJ6100 (1)

View File

@ -63,7 +63,7 @@
#define OMV_ENABLE_OV7725 (1)
#define OMV_ENABLE_OV9650 (1)
#define OMV_ENABLE_MT9M114 (1)
#define OMV_ENABLE_MT9V034 (1)
#define OMV_ENABLE_MT9V0XX (1)
#define OMV_ENABLE_LEPTON (1)
#define OMV_ENABLE_HM01B0 (0)
#define OMV_ENABLE_PAJ6100 (1)

View File

@ -60,7 +60,7 @@
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9M114 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
#define OMV_ENABLE_PAJ6100 (0)

View File

@ -43,7 +43,7 @@ extern unsigned char *OMV_UNIQUE_ID_ADDR;
#define OMV_ENABLE_OV7690 (0)
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_MT9V0XX (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)

View File

@ -57,7 +57,7 @@
#define OMV_ENABLE_OV7725 (1)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9M114 (0)
#define OMV_ENABLE_MT9V034 (1)
#define OMV_ENABLE_MT9V0XX (1)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (1)
#define OMV_ENABLE_GC2145 (1)

View File

@ -17,7 +17,7 @@
#define OV2640_SLV_ADDR (0x60)
#define OV5640_SLV_ADDR (0x78)
#define OV7725_SLV_ADDR (0x42)
#define MT9V034_SLV_ADDR (0xB8)
#define MT9V0XX_SLV_ADDR (0xB8)
#define MT9M114_SLV_ADDR (0x90)
#define LEPTON_SLV_ADDR (0x54)
#define HM01B0_SLV_ADDR (0x48)
@ -38,12 +38,14 @@
#define OV7690_ID (0x76)
#define OV7725_ID (0x77)
#define OV9650_ID (0x96)
#define MT9V034_ID (0x13)
#define MT9V0X2_ID_V_1 (0x1311)
#define MT9V0X2_ID_V_2 (0x1312)
#define MT9V0X2_ID (0x1313)
#define MT9V0X4_ID (0x1324)
#define MT9M114_ID (0x2481)
#define LEPTON_ID (0x54)
#define HM01B0_ID (0xB0)
#define GC2145_ID (0x21)
// Wide ID
#define PAJ6100_ID (0x6100)
#define FROGEYE2020_ID (0x2020)

View File

@ -22,7 +22,7 @@
#include "ov7670.h"
#include "ov7690.h"
#include "ov9650.h"
#include "mt9v034.h"
#include "mt9v0xx.h"
#include "mt9m114.h"
#include "lepton.h"
#include "hm01b0.h"
@ -253,11 +253,11 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed)
break;
#endif //(OMV_ENABLE_OV7725 == 1) || (OMV_ENABLE_OV7670 == 1) || (OMV_ENABLE_OV7690 == 1)
#if (OMV_ENABLE_MT9V034 == 1)
case MT9V034_SLV_ADDR:
cambus_readb(&sensor.bus, sensor.slv_addr, ON_CHIP_ID, &sensor.chip_id);
#if (OMV_ENABLE_MT9V0XX == 1)
case MT9V0XX_SLV_ADDR:
cambus_readw2(&sensor.bus, sensor.slv_addr, ON_CHIP_ID, &sensor.chip_id_w);
break;
#endif //(OMV_ENABLE_MT9V034 == 1)
#endif //(OMV_ENABLE_MT9V0XX == 1)
#if (OMV_ENABLE_MT9M114 == 1)
case MT9M114_SLV_ADDR:
@ -357,14 +357,19 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed)
break;
#endif // (OMV_ENABLE_OV9650 == 1)
#if (OMV_ENABLE_MT9V034 == 1)
case MT9V034_ID:
if (sensor_set_xclk_frequency(MT9V034_XCLK_FREQ) != 0) {
#if (OMV_ENABLE_MT9V0XX == 1)
case MT9V0X2_ID_V_1:
case MT9V0X2_ID_V_2:
// Force old versions to the newest.
sensor.chip_id_w = MT9V0X2_ID;
case MT9V0X2_ID:
case MT9V0X4_ID:
if (sensor_set_xclk_frequency(MT9V0XX_XCLK_FREQ) != 0) {
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = mt9v034_init(&sensor);
init_ret = mt9v0xx_init(&sensor);
break;
#endif //(OMV_ENABLE_MT9V034 == 1)
#endif //(OMV_ENABLE_MT9V0XX == 1)
#if (OMV_ENABLE_MT9M114 == 1)
case MT9M114_ID:

View File

@ -988,22 +988,31 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_read_reg_obj, py_sensor_re
STATIC const mp_map_elem_t globals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sensor)},
// Pixel Formats
{ MP_OBJ_NEW_QSTR(MP_QSTR_BINARY), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_BINARY)}, /* 1BPP/BINARY*/
{ MP_OBJ_NEW_QSTR(MP_QSTR_GRAYSCALE), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_GRAYSCALE)},/* 1BPP/GRAYSCALE*/
{ MP_OBJ_NEW_QSTR(MP_QSTR_RGB565), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_RGB565)}, /* 2BPP/RGB565*/
{ MP_OBJ_NEW_QSTR(MP_QSTR_BAYER), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_BAYER)}, /* 1BPP/RAW*/
{ MP_OBJ_NEW_QSTR(MP_QSTR_YUV422), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_YUV422)}, /* 2BPP/YUV422*/
{ MP_OBJ_NEW_QSTR(MP_QSTR_JPEG), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_JPEG)}, /* JPEG/COMPRESSED*/
// Image Sensors
{ MP_OBJ_NEW_QSTR(MP_QSTR_OV2640), MP_OBJ_NEW_SMALL_INT(OV2640_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_OV5640), MP_OBJ_NEW_SMALL_INT(OV5640_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_OV7670), MP_OBJ_NEW_SMALL_INT(OV7670_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_OV7690), MP_OBJ_NEW_SMALL_INT(OV7690_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_OV7725), MP_OBJ_NEW_SMALL_INT(OV7725_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_OV9650), MP_OBJ_NEW_SMALL_INT(OV9650_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_MT9V034), MP_OBJ_NEW_SMALL_INT(MT9V034_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_MT9V022), MP_OBJ_NEW_SMALL_INT(MT9V0X2_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_MT9V024), MP_OBJ_NEW_SMALL_INT(MT9V0X4_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_MT9V032), MP_OBJ_NEW_SMALL_INT(MT9V0X2_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_MT9V034), MP_OBJ_NEW_SMALL_INT(MT9V0X4_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_MT9M114), MP_OBJ_NEW_SMALL_INT(MT9M114_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_LEPTON), MP_OBJ_NEW_SMALL_INT(LEPTON_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_HM01B0), MP_OBJ_NEW_SMALL_INT(HM01B0_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_GC2145), MP_OBJ_NEW_SMALL_INT(GC2145_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_PAJ6100), MP_OBJ_NEW_SMALL_INT(PAJ6100_ID)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_FROGEYE2020), MP_OBJ_NEW_SMALL_INT(FROGEYE2020_ID)},
// Special effects
{ MP_OBJ_NEW_QSTR(MP_QSTR_NORMAL), MP_OBJ_NEW_SMALL_INT(SDE_NORMAL)}, /* Normal/No SDE */

View File

@ -116,7 +116,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
ov7690.o \
ov7725.o \
ov9650.o \
mt9v034.o \
mt9v0xx.o \
mt9m114.o \
lepton.o \
hm01b0.o \

View File

@ -113,7 +113,7 @@ target_sources(${MICROPY_TARGET} PRIVATE
${TOP_DIR}/${OMV_DIR}/sensors/ov7690.c
${TOP_DIR}/${OMV_DIR}/sensors/ov7725.c
${TOP_DIR}/${OMV_DIR}/sensors/ov9650.c
${TOP_DIR}/${OMV_DIR}/sensors/mt9v034.c
${TOP_DIR}/${OMV_DIR}/sensors/mt9v0xx.c
${TOP_DIR}/${OMV_DIR}/sensors/mt9m114.c
${TOP_DIR}/${OMV_DIR}/sensors/lepton.c
${TOP_DIR}/${OMV_DIR}/sensors/hm01b0.c

View File

@ -150,7 +150,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
ov7690.o \
ov7725.o \
ov9650.o \
mt9v034.o \
mt9v0xx.o \
mt9m114.o \
lepton.o \
hm01b0.o \
@ -514,7 +514,7 @@ UVC_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
ov7670.o \
ov7725.o \
ov9650.o \
mt9v034.o \
mt9v0xx.o \
mt9m114.o \
lepton.o \
hm01b0.o \

View File

@ -1,163 +0,0 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* MT9V034 driver.
*/
#define MT9V034_CHIP_VERSION (0x00)
#define MT9V034_COL_START (0x01)
#define MT9V034_COL_START_B (0xC9)
#define MT9V034_COL_START_MIN (1)
#define MT9V034_COL_START_MAX (752)
#define MT9V034_ROW_START (0x02)
#define MT9V034_ROW_START_B (0xCA)
#define MT9V034_ROW_START_MIN (4)
#define MT9V034_ROW_START_MAX (482)
#define MT9V034_WINDOW_HEIGHT (0x03)
#define MT9V034_WINDOW_HEIGHT_B (0xCB)
#define MT9V034_WINDOW_HEIGHT_MIN (1)
#define MT9V034_WINDOW_HEIGHT_MAX (480)
#define MT9V034_WINDOW_WIDTH (0x04)
#define MT9V034_WINDOW_WIDTH_B (0xCC)
#define MT9V034_WINDOW_WIDTH_MIN (1)
#define MT9V034_WINDOW_WIDTH_MAX (752)
#define MT9V034_HORIZONTAL_BLANKING (0x05)
#define MT9V034_HORIZONTAL_BLANKING_B (0xCD)
#define MT9V034_HORIZONTAL_BLANKING_MIN_1 (61)
#define MT9V034_HORIZONTAL_BLANKING_MIN_2 (71)
#define MT9V034_HORIZONTAL_BLANKING_MIN_4 (91)
#define MT9V034_HORIZONTAL_BLANKING_MAX (1023)
#define MT9V034_HORIZONTAL_BLANKING_DEF (94)
#define MT9V034_VERTICAL_BLANKING (0x06)
#define MT9V034_VERTICAL_BLANKING_B (0xCE)
#define MT9V034_VERTICAL_BLANKING_MIN (4)
#define MT9V034_VERTICAL_BLANKING_MAX (3000)
#define MT9V034_VERTICAL_BLANKING_DEF (45)
#define MT9V034_CHIP_CONTROL (0x07)
#define MT9V034_CHIP_CONTROL_MASTER_MODE (1 << 3)
#define MT9V034_CHIP_CONTROL_SNAP_MODE (3 << 3)
#define MT9V034_CHIP_CONTROL_MODE_MASK (3 << 3)
#define MT9V034_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
#define MT9V034_CHIP_CONTROL_SEQUENTIAL (1 << 8)
#define MT9V034_CHIP_CONTROL_RESERVED (1 << 9)
#define MT9V034_CHIP_CONTROL_CONTEXT (1 << 15)
#define MT9V034_SHUTTER_WIDTH1 (0x08)
#define MT9V034_SHUTTER_WIDTH1_B (0xCF)
#define MT9V034_SHUTTER_WIDTH2 (0x09)
#define MT9V034_SHUTTER_WIDTH2_B (0xD0)
#define MT9V034_SHUTTER_WIDTH_CONTROL (0x0A)
#define MT9V034_SHUTTER_WIDTH_CONTROL_B (0xD1)
#define MT9V034_TOTAL_SHUTTER_WIDTH (0x0B)
#define MT9V034_TOTAL_SHUTTER_WIDTH_B (0xD2)
#define MT9V034_TOTAL_SHUTTER_WIDTH_MIN (1)
#define MT9V034_TOTAL_SHUTTER_WIDTH_MAX (32767)
#define MT9V034_RESET (0x0C)
#define MT9V034_RESET_SOFT_RESET (1 << 0)
#define MT9V034_READ_MODE (0x0D)
#define MT9V034_READ_MODE_B (0x0E)
#define MT9V034_READ_MODE_ROW_BIN_2 (1 << 0)
#define MT9V034_READ_MODE_ROW_BIN_4 (1 << 1)
#define MT9V034_READ_MODE_COL_BIN_2 (1 << 2)
#define MT9V034_READ_MODE_COL_BIN_4 (1 << 3)
#define MT9V034_READ_MODE_ROW_FLIP (1 << 4)
#define MT9V034_READ_MODE_COL_FLIP (1 << 5)
#define MT9V034_READ_MODE_DARK_COLS (1 << 6)
#define MT9V034_READ_MODE_DARK_ROWS (1 << 7)
#define MT9V034_PIXEL_OPERATION_MODE (0x0F)
#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 0)
#define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 1)
#define MT9V034_PIXEL_OPERATION_MODE_HDR_B (1 << 8)
#define MT9V034_ADC_COMPANDING_MODE (0x1C)
#define MT9V034_ADC_COMPANDING_MODE_LINEAR (2 << 0)
#define MT9V034_ADC_COMPANDING_MODE_LINEAR_B (2 << 8)
#define MT9V034_ANALOG_GAIN (0x35)
#define MT9V034_ANALOG_GAIN_B (0x36)
#define MT9V034_ANALOG_GAIN_MIN (16)
#define MT9V034_ANALOG_GAIN_MAX (64)
#define MT9V034_V1_CONTROL (0x31)
#define MT9V034_V1_CONTROL_B (0x39)
#define MT9V034_V2_CONTROL (0x32)
#define MT9V034_V2_CONTROL_B (0x3A)
#define MT9V034_V3_CONTROL (0x33)
#define MT9V034_V3_CONTROL_B (0x3B)
#define MT9V034_V4_CONTROL (0x34)
#define MT9V034_V4_CONTROL_B (0x3C)
#define MT9V034_FRAME_DARK_AVERAGE (0x42)
#define MT9V034_DARK_AVG_THRESH (0x46)
#define MT9V034_DARK_AVG_LOW_THRESH_MASK (255 << 0)
#define MT9V034_DARK_AVG_LOW_THRESH_SHIFT (0)
#define MT9V034_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
#define MT9V034_DARK_AVG_HIGH_THRESH_SHIFT (8)
#define MT9V034_ROW_NOISE_CORR_CONTROL (0x70)
#define MT9V034_ROW_NOISE_CORR_ENABLE (1 << 5)
#define MT9V034_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7)
#define MT9V034_PIXEL_CLOCK (0x72)
#define MT9V034_PIXEL_CLOCK_INV_LINE (1 << 0)
#define MT9V034_PIXEL_CLOCK_INV_FRAME (1 << 1)
#define MT9V034_PIXEL_CLOCK_XOR_LINE (1 << 2)
#define MT9V034_PIXEL_CLOCK_CONT_LINE (1 << 3)
#define MT9V034_PIXEL_CLOCK_INV_PXL_CLK (1 << 4)
#define MT9V034_TEST_PATTERN (0x7F)
#define MT9V034_TEST_PATTERN_DATA_MASK (1023 << 0)
#define MT9V034_TEST_PATTERN_DATA_SHIFT (0)
#define MT9V034_TEST_PATTERN_USE_DATA (1 << 10)
#define MT9V034_TEST_PATTERN_GRAY_MASK (3 << 11)
#define MT9V034_TEST_PATTERN_GRAY_NONE (0 << 11)
#define MT9V034_TEST_PATTERN_GRAY_VERTICAL (1 << 11)
#define MT9V034_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11)
#define MT9V034_TEST_PATTERN_GRAY_DIAGONAL (3 << 11)
#define MT9V034_TEST_PATTERN_ENABLE (1 << 13)
#define MT9V034_TEST_PATTERN_FLIP (1 << 14)
#define MT9V034_AEC_AGC_ENABLE (0xAF)
#define MT9V034_AEC_ENABLE (1 << 0)
#define MT9V034_AEC_ENABLE_B (1 << 8)
#define MT9V034_AGC_ENABLE (1 << 1)
#define MT9V034_AGC_ENABLE_B (1 << 9)
#define MT9V034_THERMAL_INFO (0xC1)
#define MT9V034_ID_REG (0x6B)
#define MT9V034_MAX_GAIN (0xAB)
#define MT9V034_MAX_EXPOSE (0xAD)
#define MT9V034_PIXEL_COUNT (0xB0)
#define MT9V034_AGC_GAIN_OUTPUT (0xBA)
#define MT9V034_AEC_EXPOSURE_OUTPUT (0xBB)
#define MT9V034_FINE_SHUTTER_WIDTH_TOTAL (0xD5)
#define MT9V034_FINE_SHUTTER_WIDTH_TOTAL_B (0xD8)
#define MICROSECOND_CLKS (1000000)

View File

@ -6,10 +6,10 @@
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* MT9V034 driver.
* MT9V0XX driver.
*/
#include "omv_boardconfig.h"
#if (OMV_ENABLE_MT9V034 == 1)
#if (OMV_ENABLE_MT9V0XX == 1)
#include <stdint.h>
#include <stdlib.h>
@ -17,8 +17,8 @@
#include "cambus.h"
#include "sensor.h"
#include "mt9v034.h"
#include "mt9v034_regs.h"
#include "mt9v0xx.h"
#include "mt9v0xx_regs.h"
#include "py/mphal.h"
#define ACTIVE_SENSOR_WIDTH (752)
@ -33,65 +33,73 @@ static int reset(sensor_t *sensor)
readout_x = 0;
readout_y = 0;
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_RESET, MT9V034_RESET_SOFT_RESET);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_RESET, MT9V0XX_RESET_SOFT_RESET);
uint16_t chip_control;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL,
(chip_control & (~MT9V034_CHIP_CONTROL_RESERVED)));
if (sensor->chip_id_w == MT9V0X4_ID) {
uint16_t chip_control;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL,
(chip_control & (~MT9V0X4_CHIP_CONTROL_RESERVED)));
}
uint16_t read_mode;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE,
read_mode | MT9V034_READ_MODE_ROW_FLIP | MT9V034_READ_MODE_COL_FLIP);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_READ_MODE, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_READ_MODE,
read_mode | MT9V0XX_READ_MODE_ROW_FLIP | MT9V0XX_READ_MODE_COL_FLIP);
// We have to copy the differences from context A into context B registers so that we can
// ping-pong between them seamlessly...
if (sensor->chip_id_w == MT9V0X4_ID) {
// We have to copy the differences from context A into context B registers so that we can
// ping-pong between them seamlessly...
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE_B, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE_B,
read_mode | MT9V034_READ_MODE_ROW_FLIP | MT9V034_READ_MODE_COL_FLIP);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0X4_READ_MODE_B, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_READ_MODE_B,
read_mode | MT9V0XX_READ_MODE_ROW_FLIP | MT9V0XX_READ_MODE_COL_FLIP);
uint16_t shutter_width1;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_SHUTTER_WIDTH1, &shutter_width1);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_SHUTTER_WIDTH1_B, shutter_width1);
uint16_t shutter_width1;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_SHUTTER_WIDTH1, &shutter_width1);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_SHUTTER_WIDTH1_B, shutter_width1);
uint16_t shutter_width2;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_SHUTTER_WIDTH2, &shutter_width2);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_SHUTTER_WIDTH2_B, shutter_width2);
uint16_t shutter_width2;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_SHUTTER_WIDTH2, &shutter_width2);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_SHUTTER_WIDTH2_B, shutter_width2);
uint16_t shutter_control;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_SHUTTER_WIDTH_CONTROL, &shutter_control);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_SHUTTER_WIDTH_CONTROL_B, shutter_control);
uint16_t shutter_control;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_SHUTTER_WIDTH_CONTROL, &shutter_control);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_SHUTTER_WIDTH_CONTROL_B, shutter_control);
uint16_t voltage_level_1;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_V1_CONTROL, &voltage_level_1);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_V1_CONTROL_B, voltage_level_1);
uint16_t voltage_level_1;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_V1_CONTROL, &voltage_level_1);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_V1_CONTROL_B, voltage_level_1);
uint16_t voltage_level_2;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_V2_CONTROL, &voltage_level_2);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_V2_CONTROL_B, voltage_level_2);
uint16_t voltage_level_2;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_V2_CONTROL, &voltage_level_2);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_V2_CONTROL_B, voltage_level_2);
uint16_t voltage_level_3;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_V3_CONTROL, &voltage_level_3);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_V3_CONTROL_B, voltage_level_3);
uint16_t voltage_level_3;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_V3_CONTROL, &voltage_level_3);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_V3_CONTROL_B, voltage_level_3);
uint16_t voltage_level_4;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_V4_CONTROL, &voltage_level_4);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_V4_CONTROL_B, voltage_level_4);
uint16_t voltage_level_4;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_V4_CONTROL, &voltage_level_4);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_V4_CONTROL_B, voltage_level_4);
uint16_t analog_gain;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN, &analog_gain);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN_B, analog_gain);
uint16_t analog_gain;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, &analog_gain);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_ANALOG_GAIN_B, analog_gain);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_PIXEL_OPERATION_MODE,
0);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_PIXEL_OPERATION_MODE,
0);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_ADC_COMPANDING_MODE,
MT9V034_ADC_COMPANDING_MODE_LINEAR | MT9V034_ADC_COMPANDING_MODE_LINEAR_B);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_ADC_COMPANDING_MODE,
MT9V0XX_ADC_COMPANDING_MODE_LINEAR | MT9V0X4_ADC_COMPANDING_MODE_LINEAR_B);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE,
MT9V034_AEC_ENABLE | MT9V034_AEC_ENABLE_B | MT9V034_AGC_ENABLE | MT9V034_AGC_ENABLE_B);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE,
MT9V0XX_AEC_ENABLE | MT9V0X4_AEC_ENABLE_B | MT9V0XX_AGC_ENABLE | MT9V0X4_AGC_ENABLE_B);
}
if (sensor->chip_id_w == MT9V0X2_ID) {
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X2_PIXEL_CLOCK, MT9V0XX_PIXEL_CLOCK_INV_PXL_CLK);
}
return ret;
}
@ -130,20 +138,20 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
return -1;
}
if (cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control) != 0) {
if (cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control) != 0) {
return -1;
}
// EDIT: WORKS BETTER TO STAY IN CONTEXT A
//
// Determine which context to switch to...
int context = 1; // chip_control & MT9V034_CHIP_CONTROL_CONTEXT;
int read_mode_addr = context ? MT9V034_READ_MODE : MT9V034_READ_MODE_B;
int col_start_addr = context ? MT9V034_COL_START : MT9V034_COL_START_B;
int row_start_addr = context ? MT9V034_ROW_START : MT9V034_ROW_START_B;
int window_height_addr = context ? MT9V034_WINDOW_HEIGHT : MT9V034_WINDOW_HEIGHT_B;
int window_width_addr = context ? MT9V034_WINDOW_WIDTH : MT9V034_WINDOW_WIDTH_B;
int horizontal_blanking_addr = context ? MT9V034_HORIZONTAL_BLANKING : MT9V034_HORIZONTAL_BLANKING_B;
int context = 1; // chip_control & MT9V0X4_CHIP_CONTROL_CONTEXT;
int read_mode_addr = context ? MT9V0XX_READ_MODE : MT9V0X4_READ_MODE_B;
int col_start_addr = context ? MT9V0XX_COL_START : MT9V0X4_COL_START_B;
int row_start_addr = context ? MT9V0XX_ROW_START : MT9V0X4_ROW_START_B;
int window_height_addr = context ? MT9V0XX_WINDOW_HEIGHT : MT9V0X4_WINDOW_HEIGHT_B;
int window_width_addr = context ? MT9V0XX_WINDOW_WIDTH : MT9V0X4_WINDOW_WIDTH_B;
int horizontal_blanking_addr = context ? MT9V0XX_HORIZONTAL_BLANKING : MT9V0X4_HORIZONTAL_BLANKING_B;
if (cambus_readw(&sensor->bus, sensor->slv_addr, read_mode_addr, &read_mode) != 0) {
return -1;
@ -154,10 +162,10 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
if ((w <= (ACTIVE_SENSOR_WIDTH / 4)) && (h <= (ACTIVE_SENSOR_HEIGHT / 4))) {
read_mode_mul = 4;
read_mode |= MT9V034_READ_MODE_COL_BIN_4 | MT9V034_READ_MODE_ROW_BIN_4;
read_mode |= MT9V0XX_READ_MODE_COL_BIN_4 | MT9V0XX_READ_MODE_ROW_BIN_4;
} else if ((w <= (ACTIVE_SENSOR_WIDTH / 2)) && (h <= (ACTIVE_SENSOR_HEIGHT / 2))) {
read_mode_mul = 2;
read_mode |= MT9V034_READ_MODE_COL_BIN_2 | MT9V034_READ_MODE_ROW_BIN_2;
read_mode |= MT9V0XX_READ_MODE_COL_BIN_2 | MT9V0XX_READ_MODE_ROW_BIN_2;
}
int readout_x_max = (ACTIVE_SENSOR_WIDTH - (w * read_mode_mul)) / 2;
@ -166,69 +174,83 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
readout_y = IM_MAX(IM_MIN(readout_y, readout_y_max), -readout_y_max);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, col_start_addr,
readout_x_max - readout_x + MT9V034_COL_START_MIN); // sensor is mirrored by default
readout_x_max - readout_x + MT9V0XX_COL_START_MIN); // sensor is mirrored by default
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, row_start_addr,
readout_y_max - readout_y + MT9V034_ROW_START_MIN); // sensor is mirrored by default
readout_y_max - readout_y + MT9V0XX_ROW_START_MIN); // sensor is mirrored by default
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, window_width_addr, w * read_mode_mul);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, window_height_addr, h * read_mode_mul);
// Notes: 1. The MT9V034 uses column parallel analog-digital converters, thus short row timing is not possible.
// Notes: 1. The MT9V0XX uses column parallel analog-digital converters, thus short row timing is not possible.
// The minimum total row time is 690 columns (horizontal width + horizontal blanking). The minimum
// horizontal blanking is 61. When the window width is set below 627, horizontal blanking
// must be increased.
//
// The STM32H7 needs more than 94+(752-640) clocks between rows otherwise it can't keep up with the pixel rate.
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, horizontal_blanking_addr,
MT9V034_HORIZONTAL_BLANKING_DEF + (ACTIVE_SENSOR_WIDTH - IM_MIN(w * read_mode_mul, 640)));
MT9V0XX_HORIZONTAL_BLANKING_DEF + (ACTIVE_SENSOR_WIDTH - IM_MIN(w * read_mode_mul, 640)));
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, read_mode_addr, read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_PIXEL_COUNT, (w * h) / 8);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_PIXEL_COUNT, (w * h) / 8);
// We need more setup time for the pixel_clk at the full data rate...
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_PIXEL_CLOCK,
(read_mode_mul == 1) ? MT9V034_PIXEL_CLOCK_INV_PXL_CLK : 0);
if (sensor->chip_id_w == MT9V0X4_ID) {
// We need more setup time for the pixel_clk at the full data rate...
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_PIXEL_CLOCK,
(read_mode_mul == 1) ? MT9V0XX_PIXEL_CLOCK_INV_PXL_CLK : 0);
}
// EDIT: WORKS BETTER TO STAY IN CONTEXT A
//
// Flip the context.
// ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL,
// chip_control ^ MT9V034_CHIP_CONTROL_CONTEXT);
// ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL,
// chip_control ^ MT9V0X4_CHIP_CONTROL_CONTEXT);
return ret;
}
static int set_colorbar(sensor_t *sensor, int enable)
{
uint16_t test;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_TEST_PATTERN, &test);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_TEST_PATTERN,
(test & (~(MT9V034_TEST_PATTERN_ENABLE | MT9V034_TEST_PATTERN_GRAY_MASK)))
| ((enable != 0) ? (MT9V034_TEST_PATTERN_ENABLE | MT9V034_TEST_PATTERN_GRAY_VERTICAL) : 0));
int mask = (sensor->chip_id_w == MT9V0X4_ID)
? (MT9V0X4_ROW_NOISE_CORR_ENABLE | MT9V0X4_ROW_NOISE_CORR_ENABLE_B)
: MT9V0X2_ROW_NOISE_CORR_ENABLE;
uint16_t reg;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_TEST_PATTERN, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_TEST_PATTERN,
(reg & (~(MT9V0XX_TEST_PATTERN_ENABLE | MT9V0XX_TEST_PATTERN_GRAY_MASK)))
| ((enable != 0) ? (MT9V0XX_TEST_PATTERN_ENABLE | MT9V0XX_TEST_PATTERN_GRAY_VERTICAL) : 0));
ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_ROW_NOISE_CORR_CONTROL, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_ROW_NOISE_CORR_CONTROL,
(reg & (~mask)) | ((enable == 0) ? mask : 0));
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
return ret;
}
static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling)
{
int agc_mask = (sensor->chip_id_w == MT9V0X4_ID)
? (MT9V0XX_AGC_ENABLE | MT9V0X4_AGC_ENABLE_B)
: MT9V0XX_AGC_ENABLE;
uint16_t reg;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE,
(reg & (~(MT9V034_AGC_ENABLE | MT9V034_AGC_ENABLE_B))) |
((enable != 0) ? (MT9V034_AGC_ENABLE | MT9V034_AGC_ENABLE_B) : 0));
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE,
(reg & (~agc_mask)) | ((enable != 0) ? agc_mask : 0));
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db / 20.0f) * fast_log(10.0f)) * 16.0f), 64), 16);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN, (reg & 0xFF80) | gain);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN_B, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN_B, (reg & 0xFF80) | gain);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, (reg & 0xFF80) | gain);
if (sensor->chip_id_w == MT9V0X4_ID) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0X4_ANALOG_GAIN_B, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_ANALOG_GAIN_B, (reg & 0xFF80) | gain);
}
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db_ceiling / 20.0f) * fast_log(10.0f)) * 16.0f), 64), 16);
int max_gain = (sensor->chip_id_w == MT9V0X4_ID) ? MT9V0X4_MAX_GAIN : MT9V0X2_MAX_GAIN;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_MAX_GAIN, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_MAX_GAIN, (reg & 0xFF80) | gain_ceiling);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, max_gain, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, max_gain, (reg & 0xFF80) | gain_ceiling);
}
return ret;
@ -237,14 +259,14 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
static int get_gain_db(sensor_t *sensor, float *gain_db)
{
uint16_t chip_control, reg, gain;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
int context = chip_control & MT9V034_CHIP_CONTROL_CONTEXT;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, &reg);
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control);
int context = chip_control & MT9V0X4_CHIP_CONTROL_CONTEXT;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE, &reg);
if (reg & (context ? MT9V034_AGC_ENABLE_B : MT9V034_AGC_ENABLE)) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AGC_GAIN_OUTPUT, &gain);
if (reg & (context ? MT9V0X4_AGC_ENABLE_B : MT9V0XX_AGC_ENABLE)) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_AGC_GAIN_OUTPUT, &gain);
} else {
int analog_gain = context ? MT9V034_ANALOG_GAIN_B : MT9V034_ANALOG_GAIN;
int analog_gain = context ? MT9V0X4_ANALOG_GAIN_B : MT9V0XX_ANALOG_GAIN;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, analog_gain, &gain);
}
@ -254,25 +276,27 @@ static int get_gain_db(sensor_t *sensor, float *gain_db)
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
{
int aec_mask = (sensor->chip_id_w == MT9V0X4_ID)
? (MT9V0XX_AEC_ENABLE | MT9V0X4_AEC_ENABLE_B)
: MT9V0XX_AEC_ENABLE;
uint16_t chip_control, reg, read_mode_reg, row_time_0, row_time_1;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
int context = chip_control & MT9V034_CHIP_CONTROL_CONTEXT;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE,
(reg & (~(MT9V034_AEC_ENABLE | MT9V034_AEC_ENABLE_B))) |
((enable != 0) ? (MT9V034_AEC_ENABLE | MT9V034_AEC_ENABLE_B) : 0));
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control);
int context = chip_control & MT9V0X4_CHIP_CONTROL_CONTEXT;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE, &reg);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE,
(reg & (~aec_mask)) | ((enable != 0) ? aec_mask : 0));
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
int read_mode = context ? MT9V034_READ_MODE_B : MT9V034_READ_MODE;
int window_width = context ? MT9V034_WINDOW_WIDTH_B : MT9V034_WINDOW_WIDTH;
int horizontal_blanking = context ? MT9V034_HORIZONTAL_BLANKING_B : MT9V034_HORIZONTAL_BLANKING;
int read_mode = context ? MT9V0X4_READ_MODE_B : MT9V0XX_READ_MODE;
int window_width = context ? MT9V0X4_WINDOW_WIDTH_B : MT9V0XX_WINDOW_WIDTH;
int horizontal_blanking = context ? MT9V0X4_HORIZONTAL_BLANKING_B : MT9V0XX_HORIZONTAL_BLANKING;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, read_mode, &read_mode_reg);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, window_width, &row_time_0);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, horizontal_blanking, &row_time_1);
int clock = MT9V034_XCLK_FREQ;
if (read_mode_reg & MT9V034_READ_MODE_COL_BIN_2) clock /= 2;
if (read_mode_reg & MT9V034_READ_MODE_COL_BIN_4) clock /= 4;
int clock = sensor_get_xclk_frequency();
if (read_mode_reg & MT9V0XX_READ_MODE_COL_BIN_2) clock /= 2;
if (read_mode_reg & MT9V0XX_READ_MODE_COL_BIN_4) clock /= 4;
int exposure = IM_MIN(exposure_us, MICROSECOND_CLKS / 2) * (clock / MICROSECOND_CLKS);
int row_time = row_time_0 + row_time_1;
@ -281,14 +305,21 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
// Fine shutter time is global.
if ((enable == 0) && (exposure_us >= 0)) {
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_TOTAL_SHUTTER_WIDTH, coarse_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_TOTAL_SHUTTER_WIDTH_B, coarse_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, fine_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL_B, fine_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_TOTAL_SHUTTER_WIDTH, coarse_time);
if (sensor->chip_id_w == MT9V0X4_ID) {
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL, fine_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_TOTAL_SHUTTER_WIDTH_B, coarse_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL_B, fine_time);
}
} else if ((enable != 0) && (exposure_us >= 0)) {
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_MAX_EXPOSE, coarse_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, fine_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL_B, fine_time);
int max_expose = (sensor->chip_id_w == MT9V0X4_ID) ? MT9V0X4_MAX_EXPOSE : MT9V0X2_MAX_EXPOSE;
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, max_expose, coarse_time);
if (sensor->chip_id_w == MT9V0X4_ID) {
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL, fine_time);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL_B, fine_time);
}
}
return ret;
@ -296,28 +327,30 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
static int get_exposure_us(sensor_t *sensor, int *exposure_us)
{
uint16_t chip_control, reg, read_mode_reg, row_time_0, row_time_1, int_pixels, int_rows;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
int context = chip_control & MT9V034_CHIP_CONTROL_CONTEXT;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, &reg);
uint16_t chip_control, reg, read_mode_reg, row_time_0, row_time_1, int_pixels = 0, int_rows = 0;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control);
int context = chip_control & MT9V0X4_CHIP_CONTROL_CONTEXT;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_AGC_ENABLE, &reg);
int read_mode = context ? MT9V034_READ_MODE_B : MT9V034_READ_MODE;
int window_width = context ? MT9V034_WINDOW_WIDTH_B : MT9V034_WINDOW_WIDTH;
int horizontal_blanking = context ? MT9V034_HORIZONTAL_BLANKING_B : MT9V034_HORIZONTAL_BLANKING;
int fine_shutter_width_total = context ? MT9V034_FINE_SHUTTER_WIDTH_TOTAL_B : MT9V034_FINE_SHUTTER_WIDTH_TOTAL;
int read_mode = context ? MT9V0X4_READ_MODE_B : MT9V0XX_READ_MODE;
int window_width = context ? MT9V0X4_WINDOW_WIDTH_B : MT9V0XX_WINDOW_WIDTH;
int horizontal_blanking = context ? MT9V0X4_HORIZONTAL_BLANKING_B : MT9V0XX_HORIZONTAL_BLANKING;
int fine_shutter_width_total = context ? MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL_B : MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, read_mode, &read_mode_reg);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, window_width, &row_time_0);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, horizontal_blanking, &row_time_1);
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, fine_shutter_width_total, &int_pixels);
if (sensor->chip_id_w == MT9V0X4_ID) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, fine_shutter_width_total, &int_pixels);
}
int clock = MT9V034_XCLK_FREQ;
if (read_mode_reg & MT9V034_READ_MODE_COL_BIN_2) clock /= 2;
if (read_mode_reg & MT9V034_READ_MODE_COL_BIN_4) clock /= 4;
int clock = sensor_get_xclk_frequency();
if (read_mode_reg & MT9V0XX_READ_MODE_COL_BIN_2) clock /= 2;
if (read_mode_reg & MT9V0XX_READ_MODE_COL_BIN_4) clock /= 4;
if (reg & (context ? MT9V034_AEC_ENABLE_B : MT9V034_AEC_ENABLE)) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AEC_EXPOSURE_OUTPUT, &int_rows);
if (reg & (context ? MT9V0X4_AEC_ENABLE_B : MT9V0XX_AEC_ENABLE)) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_AEC_EXPOSURE_OUTPUT, &int_rows);
} else {
int total_shutter_width = context ? MT9V034_TOTAL_SHUTTER_WIDTH_B : MT9V034_TOTAL_SHUTTER_WIDTH;
int total_shutter_width = context ? MT9V0X4_TOTAL_SHUTTER_WIDTH_B : MT9V0XX_TOTAL_SHUTTER_WIDTH;
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, total_shutter_width, &int_rows);
}
@ -328,12 +361,16 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
static int set_hmirror(sensor_t *sensor, int enable)
{
uint16_t read_mode;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, // inverted behavior
(read_mode & (~MT9V034_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_COL_FLIP : 0));
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE_B, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE_B, // inverted behavior
(read_mode & (~MT9V034_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_COL_FLIP : 0));
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_READ_MODE, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_READ_MODE, // inverted behavior
(read_mode & (~MT9V0XX_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V0XX_READ_MODE_COL_FLIP : 0));
if (sensor->chip_id_w == MT9V0X4_ID) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0X4_READ_MODE_B, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_READ_MODE_B, // inverted behavior
(read_mode & (~MT9V0XX_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V0XX_READ_MODE_COL_FLIP : 0));
}
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
return ret;
}
@ -341,12 +378,16 @@ static int set_hmirror(sensor_t *sensor, int enable)
static int set_vflip(sensor_t *sensor, int enable)
{
uint16_t read_mode;
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, // inverted behavior
(read_mode & (~MT9V034_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_ROW_FLIP : 0));
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE_B, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE_B, // inverted behavior
(read_mode & (~MT9V034_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_ROW_FLIP : 0));
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_READ_MODE, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_READ_MODE, // inverted behavior
(read_mode & (~MT9V0XX_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V0XX_READ_MODE_ROW_FLIP : 0));
if (sensor->chip_id_w == MT9V0X4_ID) {
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0X4_READ_MODE_B, &read_mode);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0X4_READ_MODE_B, // inverted behavior
(read_mode & (~MT9V0XX_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V0XX_READ_MODE_ROW_FLIP : 0));
}
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
return ret;
}
@ -356,7 +397,7 @@ static int ioctl(sensor_t *sensor, int request, va_list ap)
int ret = 0;
uint16_t chip_control;
// The MT9V034 does not have a hardware scaler so the readout w/h must be equal to the
// The MT9V0XX does not have a hardware scaler so the readout w/h must be equal to the
// framesize w/h.
int tmp_readout_w = resolution[sensor->framesize][0];
int tmp_readout_h = resolution[sensor->framesize][1];
@ -399,18 +440,18 @@ static int ioctl(sensor_t *sensor, int request, va_list ap)
}
case IOCTL_SET_TRIGGERED_MODE: {
int enable = va_arg(ap, int);
ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL,
(chip_control & (~MT9V034_CHIP_CONTROL_MODE_MASK))
| ((enable != 0) ? MT9V034_CHIP_CONTROL_SNAP_MODE : MT9V034_CHIP_CONTROL_MASTER_MODE));
ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control);
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL,
(chip_control & (~MT9V0XX_CHIP_CONTROL_MODE_MASK))
| ((enable != 0) ? MT9V0XX_CHIP_CONTROL_SNAP_MODE : MT9V0XX_CHIP_CONTROL_MASTER_MODE));
ret |= sensor->snapshot(sensor, NULL, 0); // Force shadow mode register to update...
break;
}
case IOCTL_GET_TRIGGERED_MODE: {
int *enable = va_arg(ap, int *);
ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V0XX_CHIP_CONTROL, &chip_control);
if (ret >= 0) {
*enable = ((chip_control & MT9V034_CHIP_CONTROL_MODE_MASK) == MT9V034_CHIP_CONTROL_SNAP_MODE);
*enable = ((chip_control & MT9V0XX_CHIP_CONTROL_MODE_MASK) == MT9V0XX_CHIP_CONTROL_SNAP_MODE);
}
break;
}
@ -423,7 +464,7 @@ static int ioctl(sensor_t *sensor, int request, va_list ap)
return ret;
}
int mt9v034_init(sensor_t *sensor)
int mt9v0xx_init(sensor_t *sensor)
{
// Initialize sensor structure.
sensor->reset = reset;
@ -451,4 +492,4 @@ int mt9v034_init(sensor_t *sensor)
return 0;
}
#endif // (OMV_ENABLE_MT9V034 == 1)
#endif // (OMV_ENABLE_MT9V0XX == 1)

View File

@ -6,10 +6,10 @@
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* MT9V034 driver.
* MT9V0XX driver.
*/
#ifndef __MT9V034_H__
#define __MT9V034_H__
#define MT9V034_XCLK_FREQ 26666666
int mt9v034_init(sensor_t *sensor);
#endif // __MT9V034_H__
#ifndef __MT9V0XX_H__
#define __MT9V0XX_H__
#define MT9V0XX_XCLK_FREQ 26666666
int mt9v0xx_init(sensor_t *sensor);
#endif // __MT9V0XX_H__

View File

@ -0,0 +1,171 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* MT9V0XX driver.
*/
#define MT9V0XX_CHIP_VERSION (0x00)
#define MT9V0XX_COL_START (0x01)
#define MT9V0X4_COL_START_B (0xC9)
#define MT9V0XX_COL_START_MIN (1)
#define MT9V0XX_COL_START_MAX (752)
#define MT9V0XX_ROW_START (0x02)
#define MT9V0X4_ROW_START_B (0xCA)
#define MT9V0XX_ROW_START_MIN (4)
#define MT9V0XX_ROW_START_MAX (482)
#define MT9V0XX_WINDOW_HEIGHT (0x03)
#define MT9V0X4_WINDOW_HEIGHT_B (0xCB)
#define MT9V0XX_WINDOW_HEIGHT_MIN (1)
#define MT9V0XX_WINDOW_HEIGHT_MAX (480)
#define MT9V0XX_WINDOW_WIDTH (0x04)
#define MT9V0X4_WINDOW_WIDTH_B (0xCC)
#define MT9V0XX_WINDOW_WIDTH_MIN (1)
#define MT9V0XX_WINDOW_WIDTH_MAX (752)
#define MT9V0XX_HORIZONTAL_BLANKING (0x05)
#define MT9V0X4_HORIZONTAL_BLANKING_B (0xCD)
#define MT9V0X2_HORIZONTAL_BLANKING_MIN (43)
#define MT9V0XX_HORIZONTAL_BLANKING_MIN_1 (61)
#define MT9V0XX_HORIZONTAL_BLANKING_MIN_2 (71)
#define MT9V0XX_HORIZONTAL_BLANKING_MIN_4 (91)
#define MT9V0XX_HORIZONTAL_BLANKING_MAX (1023)
#define MT9V0XX_HORIZONTAL_BLANKING_DEF (94)
#define MT9V0XX_VERTICAL_BLANKING (0x06)
#define MT9V0X4_VERTICAL_BLANKING_B (0xCE)
#define MT9V0XX_VERTICAL_BLANKING_MIN (4)
#define MT9V0XX_VERTICAL_BLANKING_MAX (3000)
#define MT9V0XX_VERTICAL_BLANKING_DEF (45)
#define MT9V0XX_CHIP_CONTROL (0x07)
#define MT9V0XX_CHIP_CONTROL_MASTER_MODE (1 << 3)
#define MT9V0XX_CHIP_CONTROL_SNAP_MODE (3 << 3)
#define MT9V0XX_CHIP_CONTROL_MODE_MASK (3 << 3)
#define MT9V0XX_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
#define MT9V0XX_CHIP_CONTROL_SEQUENTIAL (1 << 8)
#define MT9V0X4_CHIP_CONTROL_RESERVED (1 << 9)
#define MT9V0X4_CHIP_CONTROL_CONTEXT (1 << 15)
#define MT9V0XX_SHUTTER_WIDTH1 (0x08)
#define MT9V0X4_SHUTTER_WIDTH1_B (0xCF)
#define MT9V0XX_SHUTTER_WIDTH2 (0x09)
#define MT9V0X4_SHUTTER_WIDTH2_B (0xD0)
#define MT9V0XX_SHUTTER_WIDTH_CONTROL (0x0A)
#define MT9V0X4_SHUTTER_WIDTH_CONTROL_B (0xD1)
#define MT9V0XX_TOTAL_SHUTTER_WIDTH (0x0B)
#define MT9V0X4_TOTAL_SHUTTER_WIDTH_B (0xD2)
#define MT9V0XX_TOTAL_SHUTTER_WIDTH_MIN (1)
#define MT9V0XX_TOTAL_SHUTTER_WIDTH_MAX (32767)
#define MT9V0XX_RESET (0x0C)
#define MT9V0XX_RESET_SOFT_RESET (1 << 0)
#define MT9V0XX_READ_MODE (0x0D)
#define MT9V0X4_READ_MODE_B (0x0E)
#define MT9V0XX_READ_MODE_ROW_BIN_2 (1 << 0)
#define MT9V0XX_READ_MODE_ROW_BIN_4 (1 << 1)
#define MT9V0XX_READ_MODE_COL_BIN_2 (1 << 2)
#define MT9V0XX_READ_MODE_COL_BIN_4 (1 << 3)
#define MT9V0XX_READ_MODE_ROW_FLIP (1 << 4)
#define MT9V0XX_READ_MODE_COL_FLIP (1 << 5)
#define MT9V0XX_READ_MODE_DARK_COLS (1 << 6)
#define MT9V0XX_READ_MODE_DARK_ROWS (1 << 7)
#define MT9V0XX_PIXEL_OPERATION_MODE (0x0F)
#define MT9V0X4_PIXEL_OPERATION_MODE_HDR (1 << 0)
#define MT9V0X4_PIXEL_OPERATION_MODE_COLOR (1 << 1)
#define MT9V0X4_PIXEL_OPERATION_MODE_HDR_B (1 << 8)
#define MT9V0XX_ADC_COMPANDING_MODE (0x1C)
#define MT9V0XX_ADC_COMPANDING_MODE_LINEAR (2 << 0)
#define MT9V0X4_ADC_COMPANDING_MODE_LINEAR_B (2 << 8)
#define MT9V0XX_ANALOG_GAIN (0x35)
#define MT9V0X4_ANALOG_GAIN_B (0x36)
#define MT9V0XX_ANALOG_GAIN_MIN (16)
#define MT9V0XX_ANALOG_GAIN_MAX (64)
#define MT9V0XX_V1_CONTROL (0x31)
#define MT9V0X4_V1_CONTROL_B (0x39)
#define MT9V0XX_V2_CONTROL (0x32)
#define MT9V0X4_V2_CONTROL_B (0x3A)
#define MT9V0XX_V3_CONTROL (0x33)
#define MT9V0X4_V3_CONTROL_B (0x3B)
#define MT9V0XX_V4_CONTROL (0x34)
#define MT9V0X4_V4_CONTROL_B (0x3C)
#define MT9V0XX_FRAME_DARK_AVERAGE (0x42)
#define MT9V0XX_DARK_AVG_THRESH (0x46)
#define MT9V0XX_DARK_AVG_LOW_THRESH_MASK (255 << 0)
#define MT9V0XX_DARK_AVG_LOW_THRESH_SHIFT (0)
#define MT9V0XX_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
#define MT9V0XX_DARK_AVG_HIGH_THRESH_SHIFT (8)
#define MT9V0XX_ROW_NOISE_CORR_CONTROL (0x70)
#define MT9V0X2_ROW_NOISE_CORR_ENABLE (1 << 5)
#define MT9V0X4_ROW_NOISE_CORR_ENABLE (1 << 0)
#define MT9V0X4_ROW_NOISE_CORR_ENABLE_B (1 << 8)
#define MT9V0X2_ROW_NOISE_CORR_USE_BLK_AVG (1 << 11)
#define MT9V0X4_ROW_NOISE_CORR_USE_BLK_AVG (1 << 1)
#define MT9V0X4_ROW_NOISE_CORR_USE_BLK_AVG_B (1 << 9)
#define MT9V0X2_PIXEL_CLOCK (0x74)
#define MT9V0X4_PIXEL_CLOCK (0x72)
#define MT9V0XX_PIXEL_CLOCK_INV_LINE (1 << 0)
#define MT9V0XX_PIXEL_CLOCK_INV_FRAME (1 << 1)
#define MT9V0XX_PIXEL_CLOCK_XOR_LINE (1 << 2)
#define MT9V0XX_PIXEL_CLOCK_CONT_LINE (1 << 3)
#define MT9V0XX_PIXEL_CLOCK_INV_PXL_CLK (1 << 4)
#define MT9V0XX_TEST_PATTERN (0x7F)
#define MT9V0XX_TEST_PATTERN_DATA_MASK (1023 << 0)
#define MT9V0XX_TEST_PATTERN_DATA_SHIFT (0)
#define MT9V0XX_TEST_PATTERN_USE_DATA (1 << 10)
#define MT9V0XX_TEST_PATTERN_GRAY_MASK (3 << 11)
#define MT9V0XX_TEST_PATTERN_GRAY_NONE (0 << 11)
#define MT9V0XX_TEST_PATTERN_GRAY_VERTICAL (1 << 11)
#define MT9V0XX_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11)
#define MT9V0XX_TEST_PATTERN_GRAY_DIAGONAL (3 << 11)
#define MT9V0XX_TEST_PATTERN_ENABLE (1 << 13)
#define MT9V0XX_TEST_PATTERN_FLIP (1 << 14)
#define MT9V0XX_AEC_AGC_ENABLE (0xAF)
#define MT9V0XX_AEC_ENABLE (1 << 0)
#define MT9V0X4_AEC_ENABLE_B (1 << 8)
#define MT9V0XX_AGC_ENABLE (1 << 1)
#define MT9V0X4_AGC_ENABLE_B (1 << 9)
#define MT9V0XX_THERMAL_INFO (0xC1)
#define MT9V0XX_ID_REG (0x6B)
#define MT9V0X2_MAX_GAIN (0x36)
#define MT9V0X4_MAX_GAIN (0xAB)
#define MT9V0X2_MAX_EXPOSE (0xBD)
#define MT9V0X4_MAX_EXPOSE (0xAD)
#define MT9V0XX_PIXEL_COUNT (0xB0)
#define MT9V0XX_AGC_GAIN_OUTPUT (0xBA)
#define MT9V0XX_AEC_EXPOSURE_OUTPUT (0xBB)
#define MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL (0xD5)
#define MT9V0X4_FINE_SHUTTER_WIDTH_TOTAL_B (0xD8)
#define MICROSECOND_CLKS (1000000)

View File

@ -767,7 +767,9 @@ static uint8_t USBD_UVC_EP0_RxReady (USBD_HandleTypeDef *pdev)
*/
static uint8_t *USBD_UVC_GetFSCfgDesc (uint16_t *length)
{
if (sensor_get_id(&sensor) != MT9V034_ID) {
int id = sensor_get_id(&sensor);
if ((id != MT9V0X2_ID) && (id != MT9V0X4_ID) && (id != HM01B0_ID) && (id != PAJ6100_ID)) {
USBD_UVC_CfgFSDesc.uvc_vs_frames_formats_desc = uvc_vs_frames_formats_desc;
} else {
USBD_UVC_CfgFSDesc.uvc_vs_frames_formats_desc = uvc_vs_frames_formats_desc_gs;