diff --git a/src/omv/Makefile b/src/omv/Makefile index 159d07a5e..e22a11b89 100644 --- a/src/omv/Makefile +++ b/src/omv/Makefile @@ -33,7 +33,7 @@ SRCS += $(addprefix sensors/, \ ov7690.c \ ov7725.c \ ov9650.c \ - mt9v034.c \ + mt9v0xx.c \ mt9m114.c \ lepton.c \ hm01b0.c \ diff --git a/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/omv_boardconfig.h b/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/omv_boardconfig.h index 34f3d1ee8..a5723aae5 100644 --- a/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/omv_boardconfig.h +++ b/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/BORMIO/omv_boardconfig.h b/src/omv/boards/BORMIO/omv_boardconfig.h index 7c64f027f..4f7f64437 100644 --- a/src/omv/boards/BORMIO/omv_boardconfig.h +++ b/src/omv/boards/BORMIO/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/NANO33/omv_boardconfig.h b/src/omv/boards/NANO33/omv_boardconfig.h index 44b2301ed..99b85a35e 100644 --- a/src/omv/boards/NANO33/omv_boardconfig.h +++ b/src/omv/boards/NANO33/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/OPENMV2/omv_boardconfig.h b/src/omv/boards/OPENMV2/omv_boardconfig.h index 56a708533..d18a4bf83 100644 --- a/src/omv/boards/OPENMV2/omv_boardconfig.h +++ b/src/omv/boards/OPENMV2/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/OPENMV3/omv_boardconfig.h b/src/omv/boards/OPENMV3/omv_boardconfig.h index 466690226..9bc095613 100644 --- a/src/omv/boards/OPENMV3/omv_boardconfig.h +++ b/src/omv/boards/OPENMV3/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/OPENMV4/omv_boardconfig.h b/src/omv/boards/OPENMV4/omv_boardconfig.h index 412de472b..43a0b978a 100644 --- a/src/omv/boards/OPENMV4/omv_boardconfig.h +++ b/src/omv/boards/OPENMV4/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/OPENMV4P/omv_boardconfig.h b/src/omv/boards/OPENMV4P/omv_boardconfig.h index 178c8ea67..a9c599be0 100644 --- a/src/omv/boards/OPENMV4P/omv_boardconfig.h +++ b/src/omv/boards/OPENMV4P/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/OPENMVPT/omv_boardconfig.h b/src/omv/boards/OPENMVPT/omv_boardconfig.h index e816ca524..db118760e 100644 --- a/src/omv/boards/OPENMVPT/omv_boardconfig.h +++ b/src/omv/boards/OPENMVPT/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/PICO/omv_boardconfig.h b/src/omv/boards/PICO/omv_boardconfig.h index e0176de5d..731ecd596 100644 --- a/src/omv/boards/PICO/omv_boardconfig.h +++ b/src/omv/boards/PICO/omv_boardconfig.h @@ -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) diff --git a/src/omv/boards/PORTENTA/omv_boardconfig.h b/src/omv/boards/PORTENTA/omv_boardconfig.h index 56dd48a7b..a01422b36 100644 --- a/src/omv/boards/PORTENTA/omv_boardconfig.h +++ b/src/omv/boards/PORTENTA/omv_boardconfig.h @@ -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) diff --git a/src/omv/common/sensor.h b/src/omv/common/sensor.h index 5b6f21a61..ccdb397ab 100644 --- a/src/omv/common/sensor.h +++ b/src/omv/common/sensor.h @@ -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) diff --git a/src/omv/common/sensor_utils.c b/src/omv/common/sensor_utils.c index f7b15034b..0a9647ab5 100644 --- a/src/omv/common/sensor_utils.c +++ b/src/omv/common/sensor_utils.c @@ -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: diff --git a/src/omv/modules/py_sensor.c b/src/omv/modules/py_sensor.c index bda0d70df..dc9f3dd74 100644 --- a/src/omv/modules/py_sensor.c +++ b/src/omv/modules/py_sensor.c @@ -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 */ diff --git a/src/omv/ports/nrf/omv_portconfig.mk b/src/omv/ports/nrf/omv_portconfig.mk index a8085f0e0..92c7d3847 100644 --- a/src/omv/ports/nrf/omv_portconfig.mk +++ b/src/omv/ports/nrf/omv_portconfig.mk @@ -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 \ diff --git a/src/omv/ports/rp2/omv_portconfig.cmake b/src/omv/ports/rp2/omv_portconfig.cmake index 493d35162..a711e3756 100644 --- a/src/omv/ports/rp2/omv_portconfig.cmake +++ b/src/omv/ports/rp2/omv_portconfig.cmake @@ -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 diff --git a/src/omv/ports/stm32/omv_portconfig.mk b/src/omv/ports/stm32/omv_portconfig.mk index 591feecf3..6997fe293 100644 --- a/src/omv/ports/stm32/omv_portconfig.mk +++ b/src/omv/ports/stm32/omv_portconfig.mk @@ -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 \ diff --git a/src/omv/sensors/mt9v034_regs.h b/src/omv/sensors/mt9v034_regs.h deleted file mode 100644 index 1213052ec..000000000 --- a/src/omv/sensors/mt9v034_regs.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * 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) diff --git a/src/omv/sensors/mt9v034.c b/src/omv/sensors/mt9v0xx.c similarity index 51% rename from src/omv/sensors/mt9v034.c rename to src/omv/sensors/mt9v0xx.c index f46184e4c..ee417a320 100644 --- a/src/omv/sensors/mt9v034.c +++ b/src/omv/sensors/mt9v0xx.c @@ -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 #include @@ -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, ®); + 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, ®); + 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, ®); - 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, ®); + 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, ®); - 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, ®); - 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, ®); + 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, ®); + 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, ®); - 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, ®); + 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, ®); + 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, ®); - 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, ®); - 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, ®); + 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, ®); + 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, ®); - 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) diff --git a/src/omv/sensors/mt9v034.h b/src/omv/sensors/mt9v0xx.h similarity index 63% rename from src/omv/sensors/mt9v034.h rename to src/omv/sensors/mt9v0xx.h index 1aea084ef..f10a15840 100644 --- a/src/omv/sensors/mt9v034.h +++ b/src/omv/sensors/mt9v0xx.h @@ -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__ diff --git a/src/omv/sensors/mt9v0xx_regs.h b/src/omv/sensors/mt9v0xx_regs.h new file mode 100644 index 000000000..c5135ae2f --- /dev/null +++ b/src/omv/sensors/mt9v0xx_regs.h @@ -0,0 +1,171 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * 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) diff --git a/src/uvc/src/usbd_uvc.c b/src/uvc/src/usbd_uvc.c index 1ef613e90..e29ce1a3c 100644 --- a/src/uvc/src/usbd_uvc.c +++ b/src/uvc/src/usbd_uvc.c @@ -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;