mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #1219 from kwagyeman/kwabena/mt9v034_refactor
Kwabena/mt9v034 refactor
This commit is contained in:
commit
1329542c2b
@ -11,152 +11,97 @@
|
||||
#include "omv_boardconfig.h"
|
||||
#if (OMV_ENABLE_MT9V034 == 1)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cambus.h"
|
||||
#include "sensor.h"
|
||||
#include "mt9v034.h"
|
||||
#include "mt9v034_regs.h"
|
||||
#include "py/mphal.h"
|
||||
#include "framebuffer.h"
|
||||
|
||||
#define MT9V034_MAX_HEIGHT (480)
|
||||
#define MT9V034_MAX_WIDTH (752)
|
||||
#define MT9V034_CHIP_VERSION (0x00)
|
||||
#define MT9V034_COL_START (0x01)
|
||||
#define MT9V034_COL_START_MIN (1)
|
||||
#define MT9V034_COL_START_MAX (752)
|
||||
#define MT9V034_ROW_START (0x02)
|
||||
#define MT9V034_ROW_START_MIN (4)
|
||||
#define MT9V034_ROW_START_MAX (482)
|
||||
#define MT9V034_WINDOW_HEIGHT (0x03)
|
||||
#define MT9V034_WINDOW_HEIGHT_MIN (1)
|
||||
#define MT9V034_WINDOW_HEIGHT_MAX (480)
|
||||
#define MT9V034_WINDOW_WIDTH (0x04)
|
||||
#define MT9V034_WINDOW_WIDTH_MIN (1)
|
||||
#define MT9V034_WINDOW_WIDTH_MAX (752)
|
||||
#define MT9V034_HORIZONTAL_BLANKING (0x05)
|
||||
#define MT9V034_HORIZONTAL_BLANKING_MIN (43)
|
||||
#define MT9V034_HORIZONTAL_BLANKING_MAX (1023)
|
||||
#define MT9V034_HORIZONTAL_BLANKING_DEF (94)
|
||||
#define MT9V034_VERTICAL_BLANKING (0x06)
|
||||
#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_SHUTTER_WIDTH1 (0x08)
|
||||
#define MT9V034_SHUTTER_WIDTH2 (0x09)
|
||||
#define MT9V034_SHUTTER_WIDTH_CONTROL (0x0A)
|
||||
#define MT9V034_TOTAL_SHUTTER_WIDTH (0x0B)
|
||||
#define MT9V034_TOTAL_SHUTTER_WIDTH_MIN (1)
|
||||
#define MT9V034_TOTAL_SHUTTER_WIDTH_MAX (32767)
|
||||
#define MT9V034_RESET (0x0C)
|
||||
#define MT9V034_READ_MODE (0x0D)
|
||||
#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_ANALOG_GAIN (0x35)
|
||||
#define MT9V034_ANALOG_GAIN_MIN (16)
|
||||
#define MT9V034_ANALOG_GAIN_MAX (64)
|
||||
#define MT9V034_MAX_ANALOG_GAIN (0x36)
|
||||
#define MT9V034_MAX_ANALOG_GAIN_MAX (127)
|
||||
#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_AGC_ENABLE (1 << 1)
|
||||
#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_FINE_SHUTTER_WIDTH_TOTAL (0xD5)
|
||||
#define ACTIVE_SENSOR_WIDTH (752)
|
||||
#define ACTIVE_SENSOR_HEIGHT (480)
|
||||
|
||||
#define MICROSECOND_CLKS (1000000)
|
||||
static int16_t readout_x = 0;
|
||||
static int16_t readout_y = 0;
|
||||
|
||||
static int reset(sensor_t *sensor)
|
||||
{
|
||||
DCMI_PWDN_HIGH();
|
||||
mp_hal_delay_ms(1);
|
||||
|
||||
DCMI_PWDN_LOW();
|
||||
mp_hal_delay_ms(1);
|
||||
|
||||
DCMI_RESET_LOW();
|
||||
mp_hal_delay_ms(1);
|
||||
|
||||
DCMI_RESET_HIGH();
|
||||
mp_hal_delay_ms(1);
|
||||
|
||||
int ret = 0;
|
||||
readout_x = 0;
|
||||
readout_y = 0;
|
||||
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_RESET, MT9V034_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)));
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL,
|
||||
(chip_control & (~MT9V034_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_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE,
|
||||
read_mode | MT9V034_READ_MODE_ROW_FLIP | MT9V034_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...
|
||||
|
||||
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);
|
||||
|
||||
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_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_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 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_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_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_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 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);
|
||||
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_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, MT9V034_AEC_AGC_ENABLE,
|
||||
MT9V034_AEC_ENABLE | MT9V034_AEC_ENABLE_B | MT9V034_AGC_ENABLE | MT9V034_AGC_ENABLE_B);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sleep(sensor_t *sensor, int enable)
|
||||
{
|
||||
if (enable) {
|
||||
DCMI_PWDN_HIGH();
|
||||
mp_hal_delay_ms(1);
|
||||
} else {
|
||||
DCMI_PWDN_LOW();
|
||||
mp_hal_delay_ms(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_reg(sensor_t *sensor, uint16_t reg_addr)
|
||||
{
|
||||
uint16_t reg_data;
|
||||
|
||||
if (cambus_readw(&sensor->bus, sensor->slv_addr, reg_addr, ®_data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return reg_data;
|
||||
}
|
||||
|
||||
@ -170,43 +115,62 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
|
||||
if (pixformat != PIXFORMAT_GRAYSCALE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
{
|
||||
uint16_t width = resolution[framesize][0];
|
||||
uint16_t height = resolution[framesize][1];
|
||||
uint16_t chip_control, read_mode;
|
||||
int ret = 0;
|
||||
uint16_t w = resolution[framesize][0];
|
||||
uint16_t h = resolution[framesize][1];
|
||||
|
||||
if ((width > MT9V034_MAX_WIDTH) || (height > MT9V034_MAX_HEIGHT)) {
|
||||
if ((w > ACTIVE_SENSOR_WIDTH) || (h > ACTIVE_SENSOR_HEIGHT)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t read_mode;
|
||||
if (cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, &read_mode) != 0) {
|
||||
// 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;
|
||||
|
||||
if (cambus_readw(&sensor->bus, sensor->slv_addr, read_mode_addr, &read_mode) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read_mode_mul = 1;
|
||||
read_mode &= 0xFFF0;
|
||||
|
||||
if ((width <= (MT9V034_MAX_WIDTH / 4)) && (height <= (MT9V034_MAX_HEIGHT / 4))) {
|
||||
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;
|
||||
} else if ((width <= (MT9V034_MAX_WIDTH / 2)) && (height <= (MT9V034_MAX_HEIGHT / 2))) {
|
||||
} 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;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int readout_x_max = (ACTIVE_SENSOR_WIDTH - (w * read_mode_mul)) / 2;
|
||||
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - (h * read_mode_mul)) / 2;
|
||||
readout_x = IM_MAX(IM_MIN(readout_x, readout_x_max), -readout_x_max);
|
||||
readout_y = IM_MAX(IM_MIN(readout_y, readout_y_max), -readout_y_max);
|
||||
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_COL_START,
|
||||
((MT9V034_MAX_WIDTH - (width * read_mode_mul)) / 2) + MT9V034_COL_START_MIN);
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_ROW_START,
|
||||
((MT9V034_MAX_HEIGHT - (height * read_mode_mul)) / 2) + MT9V034_ROW_START_MIN);
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_WINDOW_WIDTH, width * read_mode_mul);
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_WINDOW_HEIGHT, height * read_mode_mul);
|
||||
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
|
||||
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
|
||||
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.
|
||||
// The minimum total row time is 690 columns (horizontal width + horizontal blanking). The minimum
|
||||
@ -214,14 +178,21 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
// 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, MT9V034_HORIZONTAL_BLANKING,
|
||||
MT9V034_HORIZONTAL_BLANKING_DEF + (MT9V034_MAX_WIDTH - IM_MIN(width * read_mode_mul, 640)));
|
||||
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)));
|
||||
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_READ_MODE, read_mode);
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_PIXEL_COUNT, (width * height) / 8);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
ret |= cambus_writew(&sensor->bus, sensor->slv_addr, MT9V034_PIXEL_CLOCK,
|
||||
(read_mode_mul == 1) ? MT9V034_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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -242,16 +213,19 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
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)) | ((enable != 0) ? MT9V034_AGC_ENABLE : 0));
|
||||
(reg & (~(MT9V034_AGC_ENABLE | MT9V034_AGC_ENABLE_B))) |
|
||||
((enable != 0) ? (MT9V034_AGC_ENABLE | MT9V034_AGC_ENABLE_B) : 0));
|
||||
ret |= sensor->snapshot(sensor, NULL, NULL); // 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.0) * fast_log(10.0)) * 16.0), 127), 0);
|
||||
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);
|
||||
} 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.0) * fast_log(10.0)) * 16.0), 127), 16);
|
||||
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db_ceiling / 20.0f) * fast_log(10.0f)) * 16.0f), 64), 16);
|
||||
|
||||
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);
|
||||
@ -262,42 +236,59 @@ 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 gain;
|
||||
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_ANALOG_GAIN, &gain);
|
||||
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, ®);
|
||||
|
||||
*gain_db = 20.0 * (fast_log((gain & 0x7F) / 16.0) / fast_log(10.0));
|
||||
if (reg & (context ? MT9V034_AGC_ENABLE_B : MT9V034_AGC_ENABLE)) {
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AGC_GAIN_OUTPUT, &gain);
|
||||
} else {
|
||||
int analog_gain = context ? MT9V034_ANALOG_GAIN_B : MT9V034_ANALOG_GAIN;
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, analog_gain, &gain);
|
||||
}
|
||||
|
||||
*gain_db = 20.0 * (fast_log((gain & 0x7F) / 16.0f) / fast_log(10.0f));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
|
||||
{
|
||||
uint16_t reg, row_time_0, row_time_1;
|
||||
int 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 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)) | ((enable != 0) ? MT9V034_AEC_ENABLE : 0));
|
||||
(reg & (~(MT9V034_AEC_ENABLE | MT9V034_AEC_ENABLE_B))) |
|
||||
((enable != 0) ? (MT9V034_AEC_ENABLE | MT9V034_AEC_ENABLE_B) : 0));
|
||||
ret |= sensor->snapshot(sensor, NULL, NULL); // Force shadow mode register to update...
|
||||
|
||||
if ((enable == 0) && (exposure_us >= 0)) {
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_WINDOW_WIDTH, &row_time_0);
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING, &row_time_1);
|
||||
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;
|
||||
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 exposure = IM_MIN(exposure_us, MICROSECOND_CLKS / 2) * (MT9V034_XCLK_FREQ / MICROSECOND_CLKS);
|
||||
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 exposure = IM_MIN(exposure_us, MICROSECOND_CLKS / 2) * (clock / MICROSECOND_CLKS);
|
||||
int row_time = row_time_0 + row_time_1;
|
||||
int coarse_time = exposure / row_time;
|
||||
int fine_time = exposure % row_time;
|
||||
|
||||
// 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);
|
||||
} else if ((enable != 0) && (exposure_us >= 0)) {
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_WINDOW_WIDTH, &row_time_0);
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING, &row_time_1);
|
||||
|
||||
int exposure = IM_MIN(exposure_us, MICROSECOND_CLKS / 2) * (MT9V034_XCLK_FREQ / MICROSECOND_CLKS);
|
||||
int row_time = row_time_0 + row_time_1;
|
||||
int coarse_time = exposure / row_time;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -305,14 +296,32 @@ 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 int_rows, int_pixels, row_time_0, row_time_1;
|
||||
int ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_TOTAL_SHUTTER_WIDTH, &int_rows);
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, &int_pixels);
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_WINDOW_WIDTH, &row_time_0);
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING, &row_time_1);
|
||||
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, ®);
|
||||
|
||||
*exposure_us = ((int_rows * (row_time_0 + row_time_1)) + int_pixels) / (MT9V034_XCLK_FREQ / MICROSECOND_CLKS);
|
||||
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;
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
if (reg & (context ? MT9V034_AEC_ENABLE_B : MT9V034_AEC_ENABLE)) {
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_AEC_EXPOSURE_OUTPUT, &int_rows);
|
||||
} else {
|
||||
int total_shutter_width = context ? MT9V034_TOTAL_SHUTTER_WIDTH_B : MT9V034_TOTAL_SHUTTER_WIDTH;
|
||||
ret |= cambus_readw(&sensor->bus, sensor->slv_addr, total_shutter_width, &int_rows);
|
||||
}
|
||||
|
||||
*exposure_us = ((int_rows * (row_time_0 + row_time_1)) + int_pixels) / (clock / MICROSECOND_CLKS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -322,6 +331,9 @@ static int set_hmirror(sensor_t *sensor, int enable)
|
||||
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));
|
||||
ret |= sensor->snapshot(sensor, NULL, NULL); // Force shadow mode register to update...
|
||||
return ret;
|
||||
}
|
||||
@ -332,21 +344,59 @@ static int set_vflip(sensor_t *sensor, int enable)
|
||||
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));
|
||||
ret |= sensor->snapshot(sensor, NULL, NULL); // Force shadow mode register to update...
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
// framesize w/h.
|
||||
int tmp_readout_w = resolution[sensor->framesize][0];
|
||||
int tmp_readout_h = resolution[sensor->framesize][1];
|
||||
if (sensor->framesize == FRAMESIZE_INVALID) {
|
||||
tmp_readout_w = ACTIVE_SENSOR_WIDTH;
|
||||
tmp_readout_h = ACTIVE_SENSOR_HEIGHT;
|
||||
}
|
||||
|
||||
if ((tmp_readout_w <= (ACTIVE_SENSOR_WIDTH / 4)) && (tmp_readout_h <= (ACTIVE_SENSOR_HEIGHT / 4))) {
|
||||
tmp_readout_w *= 4;
|
||||
tmp_readout_h *= 4;
|
||||
} else if ((tmp_readout_w <= (ACTIVE_SENSOR_WIDTH / 2)) && (tmp_readout_h <= (ACTIVE_SENSOR_HEIGHT / 2))) {
|
||||
tmp_readout_w *= 2;
|
||||
tmp_readout_h *= 2;
|
||||
}
|
||||
|
||||
switch (request) {
|
||||
case IOCTL_SET_READOUT_WINDOW: {
|
||||
int tmp_readout_x = va_arg(ap, int);
|
||||
int tmp_readout_y = va_arg(ap, int);
|
||||
int readout_x_max = (ACTIVE_SENSOR_WIDTH - tmp_readout_w) / 2;
|
||||
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - tmp_readout_h) / 2;
|
||||
tmp_readout_x = IM_MAX(IM_MIN(tmp_readout_x, readout_x_max), -readout_x_max);
|
||||
tmp_readout_y = IM_MAX(IM_MIN(tmp_readout_y, readout_y_max), -readout_y_max);
|
||||
bool changed = (tmp_readout_x != readout_x) ||
|
||||
(tmp_readout_y != readout_y);
|
||||
readout_x = tmp_readout_x;
|
||||
readout_y = tmp_readout_y;
|
||||
if (changed && (sensor->framesize != FRAMESIZE_INVALID)) {
|
||||
ret |= set_framesize(sensor, sensor->framesize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IOCTL_GET_READOUT_WINDOW: {
|
||||
*va_arg(ap, int *) = readout_x;
|
||||
*va_arg(ap, int *) = readout_y;
|
||||
*va_arg(ap, int *) = tmp_readout_w;
|
||||
*va_arg(ap, int *) = tmp_readout_h;
|
||||
break;
|
||||
}
|
||||
case IOCTL_SET_TRIGGERED_MODE: {
|
||||
int enable = va_arg(ap, int);
|
||||
ret = cambus_readw(&sensor->bus, sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control);
|
||||
@ -375,9 +425,9 @@ static int ioctl(sensor_t *sensor, int request, va_list ap)
|
||||
|
||||
int mt9v034_init(sensor_t *sensor)
|
||||
{
|
||||
// Initialize sensor structure.
|
||||
sensor->gs_bpp = sizeof(uint8_t);
|
||||
sensor->reset = reset;
|
||||
sensor->sleep = sleep;
|
||||
sensor->read_reg = read_reg;
|
||||
sensor->write_reg = write_reg;
|
||||
sensor->set_pixformat = set_pixformat;
|
||||
@ -389,15 +439,17 @@ int mt9v034_init(sensor_t *sensor)
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->set_lens_correction = set_lens_correction;
|
||||
sensor->ioctl = ioctl;
|
||||
|
||||
// Set sensor flags
|
||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 0);
|
||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_HSYNC, 0);
|
||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 0);
|
||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 1);
|
||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 0);
|
||||
SENSOR_HW_FLAGS_SET(sensor, SWNSOR_HW_FLAGS_RGB565_REV, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // (OMV_ENABLE_MT9V034 == 1)
|
||||
|
||||
@ -10,6 +10,6 @@
|
||||
*/
|
||||
#ifndef __MT9V034_H__
|
||||
#define __MT9V034_H__
|
||||
#define MT9V034_XCLK_FREQ 27000000
|
||||
#define MT9V034_XCLK_FREQ 26666666
|
||||
int mt9v034_init(sensor_t *sensor);
|
||||
#endif // __MT9V034_H__
|
||||
|
||||
163
src/omv/sensors/mt9v034_regs.h
Normal file
163
src/omv/sensors/mt9v034_regs.h
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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)
|
||||
Loading…
Reference in New Issue
Block a user