mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Update FLIR Lepton driver.
* Fix window code. * Support smaller resolutions.
This commit is contained in:
parent
7d16d008f9
commit
804d97f5b0
112
src/omv/lepton.c
112
src/omv/lepton.c
@ -141,6 +141,7 @@ static int reset(sensor_t *sensor)
|
||||
}
|
||||
|
||||
LEP_AGC_ROI_T roi;
|
||||
|
||||
if (LEP_GetAgcROI(&tmp_handle, &roi) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
@ -151,6 +152,7 @@ static int reset(sensor_t *sensor)
|
||||
if (LEP_SetAgcEnableState(&tmp_handle, LEP_AGC_ENABLE) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LEP_SetAgcCalcEnableState(&tmp_handle, LEP_AGC_ENABLE) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
@ -287,6 +289,8 @@ static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||
|
||||
static int snapshot(sensor_t *sensor, image_t *image)
|
||||
{
|
||||
fb_update_jpeg_buffer();
|
||||
|
||||
if ((!h_res) || (!v_res) || (!sensor->framesize) || (!sensor->pixformat)) {
|
||||
return -1;
|
||||
}
|
||||
@ -361,57 +365,57 @@ static int snapshot(sensor_t *sensor, image_t *image)
|
||||
}
|
||||
}
|
||||
|
||||
//image_t img;
|
||||
//img.w = sensor->fb_w;
|
||||
//img.h = sensor->fb_h;
|
||||
//img.bpp = MAIN_FB()->bpp; // invalid
|
||||
//img.data = MAIN_FB()->pixels; // valid
|
||||
image_t img;
|
||||
img.w = MAIN_FB()->u;
|
||||
img.h = MAIN_FB()->v;
|
||||
img.bpp = MAIN_FB()->bpp; // invalid
|
||||
img.data = MAIN_FB()->pixels; // valid
|
||||
|
||||
//float x_scale = resolution[sensor->framesize][0] / ((float) h_res);
|
||||
//float y_scale = resolution[sensor->framesize][1] / ((float) v_res);
|
||||
float x_scale = resolution[sensor->framesize][0] / ((float) h_res);
|
||||
float y_scale = resolution[sensor->framesize][1] / ((float) v_res);
|
||||
// MAX == KeepAspectRationByExpanding - MIN == KeepAspectRatio
|
||||
//float scale = IM_MAX(x_scale, y_scale);
|
||||
//int x_offset = (resolution[sensor->framesize][0] - (h_res * scale)) / 2;
|
||||
//int y_offset = (resolution[sensor->framesize][1] - (v_res * scale)) / 2;
|
||||
//// The code below upscales the source image to the requested frame size
|
||||
//// and then crops it to the window set by the user.
|
||||
float scale = IM_MAX(x_scale, y_scale);
|
||||
int x_offset = (resolution[sensor->framesize][0] - (h_res * scale)) / 2;
|
||||
int y_offset = (resolution[sensor->framesize][1] - (v_res * scale)) / 2;
|
||||
// The code below upscales the source image to the requested frame size
|
||||
// and then crops it to the window set by the user.
|
||||
|
||||
//for (int yyy = fast_floorf(y * scale) + y_offset,
|
||||
// yyyy = fast_ceilf((y + 1) * scale) + y_offset; yyy < yyyy; yyy++) {
|
||||
// if ((sensor->fb_y <= yyy) && (yyy < (sensor->fb_y + sensor->fb_h))) {
|
||||
for (int yyy = fast_floorf(y * scale) + y_offset,
|
||||
yyyy = fast_ceilf((y + 1) * scale) + y_offset; yyy < yyyy; yyy++) {
|
||||
if ((MAIN_FB()->y <= yyy) && (yyy < (MAIN_FB()->y + MAIN_FB()->v))) {
|
||||
|
||||
// for (int xxx = fast_floorf(x * scale) + x_offset,
|
||||
// xxxx = fast_ceilf((x + VOSPI_LINE_PIXELS) * scale) + x_offset; xxx < xxxx; xxx++) {
|
||||
// if ((sensor->fb_x <= xxx) && (xxx < (sensor->fb_x + sensor->fb_w))) {
|
||||
for (int xxx = fast_floorf(x * scale) + x_offset,
|
||||
xxxx = fast_ceilf((x + VOSPI_LINE_PIXELS) * scale) + x_offset; xxx < xxxx; xxx++) {
|
||||
if ((MAIN_FB()->x <= xxx) && (xxx < (MAIN_FB()->x + MAIN_FB()->u))) {
|
||||
|
||||
// int i = (xxx / scale) - x;
|
||||
// // Value is the 14-bit value from the FLIR IR camera.
|
||||
// // However, with AGC enabled only the bottom 8-bits are non-zero.
|
||||
// int value = ((buffer[(i*2)+4] << 8) | (buffer[(i*2)+5] << 0)) & 0x3FFF;
|
||||
int i = (xxx / scale) - x;
|
||||
// Value is the 14-bit value from the FLIR IR camera.
|
||||
// However, with AGC enabled only the bottom 8-bits are non-zero.
|
||||
int value = ((buffer[(i*2)+4] << 8) | (buffer[(i*2)+5] << 0)) & 0x3FFF;
|
||||
|
||||
// int t_x = xxx - sensor->fb_x;
|
||||
// int t_y = yyy - sensor->fb_y;
|
||||
int t_x = xxx - MAIN_FB()->x;
|
||||
int t_y = yyy - MAIN_FB()->y;
|
||||
|
||||
// if (h_mirror) t_x = sensor->fb_w - t_x - 1;
|
||||
// if (v_flip) t_y = sensor->fb_h - t_y - 1;
|
||||
if (h_mirror) t_x = MAIN_FB()->u - t_x - 1;
|
||||
if (v_flip) t_y = MAIN_FB()->v - t_y - 1;
|
||||
|
||||
// switch (sensor->pixformat) {
|
||||
// case PIXFORMAT_RGB565: {
|
||||
// IMAGE_PUT_RGB565_PIXEL(&img, t_x, t_y, rainbow_table[value & 0xFF]);
|
||||
// break;
|
||||
// }
|
||||
// case PIXFORMAT_GRAYSCALE: {
|
||||
// IMAGE_PUT_GRAYSCALE_PIXEL(&img, t_x, t_y, value & 0xFF);
|
||||
// break;
|
||||
// }
|
||||
// default: {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
switch (sensor->pixformat) {
|
||||
case PIXFORMAT_RGB565: {
|
||||
IMAGE_PUT_RGB565_PIXEL(&img, t_x, t_y, rainbow_table[value & 0xFF]);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL(&img, t_x, t_y, value & 0xFF);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x += VOSPI_LINE_PIXELS;
|
||||
}
|
||||
@ -424,6 +428,28 @@ static int snapshot(sensor_t *sensor, image_t *image)
|
||||
}
|
||||
}
|
||||
|
||||
MAIN_FB()->w = MAIN_FB()->u;
|
||||
MAIN_FB()->h = MAIN_FB()->v;
|
||||
|
||||
switch (sensor->pixformat) {
|
||||
case PIXFORMAT_RGB565: {
|
||||
MAIN_FB()->bpp = sizeof(uint16_t);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
MAIN_FB()->bpp = sizeof(uint8_t);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
image->w = MAIN_FB()->w;
|
||||
image->h = MAIN_FB()->h;
|
||||
image->bpp = MAIN_FB()->bpp;
|
||||
image->data = MAIN_FB()->pixels;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -6,17 +6,16 @@
|
||||
* MT9V034 driver.
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include STM32_HAL_H
|
||||
#include "cambus.h"
|
||||
#include "sensor.h"
|
||||
#include "mt9v034.h"
|
||||
#include "systick.h"
|
||||
#include "framebuffer.h"
|
||||
#include "omv_boardconfig.h"
|
||||
|
||||
#define MT9V034_MAX_HEIGHT (480)
|
||||
#define MT9V034_MAX_WIDTH (752)
|
||||
#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)
|
||||
@ -33,9 +32,11 @@
|
||||
#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_DOUT_ENABLE (1 << 7)
|
||||
@ -57,8 +58,8 @@
|
||||
#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_COLOR (1 << 2)
|
||||
#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 6)
|
||||
#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)
|
||||
@ -94,42 +95,74 @@
|
||||
#define MT9V034_AEC_ENABLE (1 << 0)
|
||||
#define MT9V034_AGC_ENABLE (1 << 1)
|
||||
#define MT9V034_THERMAL_INFO (0xC1)
|
||||
|
||||
#define MT9V034_WINDOW_HEIGHT_A (0x03)
|
||||
#define MT9V034_WINDOW_WIDTH_A (0x04)
|
||||
#define MT9V034_HORIZONTAL_BLANKING_A (0x05)
|
||||
#define MT9V034_VERTICAL_BLANKING_A (0x06)
|
||||
#define MT9V034_COARSE_SHUTTER_WIDTH_TOTAL_A (0x0B)
|
||||
#define MT9V034_ANALOG_GAIN_CONTROL (0x35)
|
||||
#define MT9V034_ID_REG (0x6B)
|
||||
#define MT9V034_MAX_GAIN (0xAB)
|
||||
#define MT9V034_FINE_SHUTTER_WIDTH_TOTAL_A (0xD5)
|
||||
#define MT9V034_MAX_EXPOSE (0xAD)
|
||||
#define MT9V034_PIXEL_COUNT (0xB0)
|
||||
#define MT9V034_FINE_SHUTTER_WIDTH_TOTAL (0xD5)
|
||||
|
||||
#define MICROSECOND_CLKS (1000000)
|
||||
|
||||
static bool sensor_has_cfa = false;
|
||||
|
||||
static int reset(sensor_t *sensor)
|
||||
{
|
||||
// NOTE: TODO This doesn't reset register configuration.
|
||||
cambus_writew(sensor->slv_addr, MT9V034_RESET, 1);
|
||||
DCMI_PWDN_HIGH();
|
||||
systick_sleep(1);
|
||||
|
||||
// Delay 10 ms
|
||||
systick_sleep(10);
|
||||
DCMI_PWDN_LOW();
|
||||
systick_sleep(1);
|
||||
|
||||
DCMI_RESET_LOW();
|
||||
systick_sleep(1);
|
||||
|
||||
DCMI_RESET_HIGH();
|
||||
systick_sleep(1);
|
||||
|
||||
uint16_t reg_data;
|
||||
int ret = 0;
|
||||
|
||||
// Setup reconmended reserved register settings.
|
||||
ret |= cambus_writew(sensor->slv_addr, 0x13, 0x2D2E);
|
||||
ret |= cambus_writew(sensor->slv_addr, 0x20, 0x01C7);
|
||||
ret |= cambus_writew(sensor->slv_addr, 0x24, 0x001B);
|
||||
ret |= cambus_writew(sensor->slv_addr, 0x2B, 0x0003);
|
||||
ret |= cambus_writew(sensor->slv_addr, 0x2F, 0x0003);
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_READ_MODE,
|
||||
MT9V034_READ_MODE_ROW_FLIP | MT9V034_READ_MODE_COL_FLIP);
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_PIXEL_OPERATION_MODE,
|
||||
MT9V034_PIXEL_OPERATION_MODE_HDR | MT9V034_PIXEL_OPERATION_MODE_COLOR);
|
||||
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_ID_REG, ®_data);
|
||||
|
||||
sensor_has_cfa = ((reg_data >> 9) & 0x7) == 0x6;
|
||||
|
||||
cambus_writew(sensor->slv_addr, MT9V034_CHIP_CONTROL, 0x0088);
|
||||
cambus_writew(sensor->slv_addr, MT9V034_READ_MODE,
|
||||
(MT9V034_READ_MODE_ROW_FLIP | MT9V034_READ_MODE_COL_FLIP));
|
||||
cambus_writew(sensor->slv_addr, MT9V034_RESET, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sleep(sensor_t *sensor, int enable)
|
||||
{
|
||||
if (enable) {
|
||||
DCMI_PWDN_HIGH();
|
||||
systick_sleep(1);
|
||||
} else {
|
||||
DCMI_PWDN_LOW();
|
||||
systick_sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_reg(sensor_t *sensor, uint8_t reg_addr)
|
||||
{
|
||||
uint16_t reg_data;
|
||||
|
||||
if (cambus_readw(sensor->slv_addr, reg_addr, ®_data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return reg_data;
|
||||
}
|
||||
|
||||
@ -145,30 +178,45 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
|
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
{
|
||||
int ret=0;
|
||||
uint16_t readmode = 0;
|
||||
uint16_t width = resolution[framesize][0];
|
||||
uint16_t width = resolution[framesize][0];
|
||||
uint16_t height = resolution[framesize][1];
|
||||
|
||||
if ((width * 4) <= MT9V034_MAX_WIDTH && (height * 4) <= MT9V034_MAX_HEIGHT) {
|
||||
width *= 4; height *= 4;
|
||||
readmode |= MT9V034_READ_MODE_ROW_BIN_4;
|
||||
readmode |= MT9V034_READ_MODE_COL_BIN_4;
|
||||
} else if ((width * 2) <= MT9V034_MAX_WIDTH && (height * 2) <= MT9V034_MAX_HEIGHT) {
|
||||
width *= 2; height *= 2;
|
||||
readmode |= MT9V034_READ_MODE_ROW_BIN_2;
|
||||
readmode |= MT9V034_READ_MODE_COL_BIN_2;
|
||||
if ((width > MT9V034_MAX_WIDTH) || (height > MT9V034_MAX_HEIGHT)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
readmode |= MT9V034_READ_MODE_ROW_FLIP;
|
||||
readmode |= MT9V034_READ_MODE_COL_FLIP;
|
||||
cambus_writew(sensor->slv_addr, MT9V034_READ_MODE, readmode);
|
||||
uint16_t readmode;
|
||||
int ret = 0;
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &readmode);
|
||||
readmode &= 0xFFF0;
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_WINDOW_WIDTH, width);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_COL_START, (MT9V034_MAX_WIDTH - width ) / 2 + MT9V034_COL_START_MIN);
|
||||
if (((width * 4) <= MT9V034_MAX_WIDTH) && ((height * 4) <= MT9V034_MAX_HEIGHT)) {
|
||||
width *= 4;
|
||||
height *= 4;
|
||||
if ((!sensor_has_cfa) || (sensor->pixformat == PIXFORMAT_GRAYSCALE)) {
|
||||
readmode |= MT9V034_READ_MODE_COL_BIN_4 | MT9V034_READ_MODE_ROW_BIN_4;
|
||||
}
|
||||
} else if (((width * 2) <= MT9V034_MAX_WIDTH) && ((height * 2) <= MT9V034_MAX_HEIGHT)) {
|
||||
width *= 2;
|
||||
height *= 2;
|
||||
if ((!sensor_has_cfa) || (sensor->pixformat == PIXFORMAT_GRAYSCALE)) {
|
||||
readmode |= MT9V034_READ_MODE_COL_BIN_2 | MT9V034_READ_MODE_ROW_BIN_2;
|
||||
}
|
||||
}
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_WINDOW_HEIGHT, height);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ROW_START, (MT9V034_MAX_HEIGHT - height) / 2 + MT9V034_ROW_START_MIN);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_COL_START, ((MT9V034_MAX_WIDTH - width) / 2) + MT9V034_COL_START_MIN);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ROW_START, ((MT9V034_MAX_HEIGHT - height) / 2) + MT9V034_ROW_START_MIN);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_WINDOW_WIDTH, width);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_WINDOW_HEIGHT, height);
|
||||
// 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
|
||||
// horizontal blanking is 61. When the window width is set below 627, horizontal blanking
|
||||
// must be increased.
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING,
|
||||
MT9V034_HORIZONTAL_BLANKING_DEF + (MT9V034_MAX_WIDTH - width));
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_READ_MODE, readmode);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_PIXEL_COUNT,
|
||||
(resolution[framesize][0] * resolution[framesize][1]) / 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -185,7 +233,6 @@ static int set_contrast(sensor_t *sensor, int level)
|
||||
static int set_brightness(sensor_t *sensor, int level)
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int set_saturation(sensor_t *sensor, int level)
|
||||
@ -198,7 +245,22 @@ static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_quality(sensor_t *sensor, int quality)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_colorbar(sensor_t *sensor, int enable)
|
||||
{
|
||||
uint16_t test;
|
||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_TEST_PATTERN, &test);
|
||||
ret |= cambus_writew(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));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_special_effect(sensor_t *sensor, sde_t sde)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -213,8 +275,8 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
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);
|
||||
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, ®);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, (reg & 0xFF80) | gain);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN, ®);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN, (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);
|
||||
|
||||
@ -228,7 +290,7 @@ 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->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, &gain);
|
||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN, &gain);
|
||||
|
||||
*gain_db = 20.0 * (fast_log((gain & 0x7F) / 16.0) / fast_log(10.0));
|
||||
|
||||
@ -237,24 +299,22 @@ static int get_gain_db(sensor_t *sensor, float *gain_db)
|
||||
|
||||
static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
|
||||
{
|
||||
uint16_t reg, row_limit_0, row_limit_1, row_time_0, row_time_1;
|
||||
uint16_t reg, row_time_0, row_time_1;
|
||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, ®);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_AEC_AGC_ENABLE,
|
||||
(reg & (~MT9V034_AEC_ENABLE)) | ((enable != 0) ? MT9V034_AEC_ENABLE : 0));
|
||||
|
||||
if ((enable == 0) && (exposure_us >= 0)) {
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_HEIGHT_A, &row_limit_0);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_VERTICAL_BLANKING_A, &row_limit_1);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_WIDTH_A, &row_time_0);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING_A, &row_time_1);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_WIDTH, &row_time_0);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING, &row_time_1);
|
||||
|
||||
int exposure = exposure_us * (27000000 / 1000000);
|
||||
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 = IM_MIN((exposure / row_time), (row_limit_0 + row_limit_1));
|
||||
int coarse_time = exposure / row_time;
|
||||
int fine_time = exposure % row_time;
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_COARSE_SHUTTER_WIDTH_TOTAL_A, coarse_time);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL_A, fine_time);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_TOTAL_SHUTTER_WIDTH, coarse_time);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, fine_time);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -263,12 +323,12 @@ 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->slv_addr, MT9V034_COARSE_SHUTTER_WIDTH_TOTAL_A, &int_rows);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL_A, &int_pixels);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_WIDTH_A, &row_time_0);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING_A, &row_time_1);
|
||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_TOTAL_SHUTTER_WIDTH, &int_rows);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, &int_pixels);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_WIDTH, &row_time_0);
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING, &row_time_1);
|
||||
|
||||
*exposure_us = ((int_rows * (row_time_0 + row_time_1)) + int_pixels) / (27000000 / 1000000);
|
||||
*exposure_us = ((int_rows * (row_time_0 + row_time_1)) + int_pixels) / (MT9V034_XCLK_FREQ / MICROSECOND_CLKS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -287,9 +347,8 @@ static int set_hmirror(sensor_t *sensor, int enable)
|
||||
{
|
||||
uint16_t read_mode;
|
||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL,
|
||||
(read_mode & (~MT9V034_READ_MODE_COL_FLIP)) | ((enable != 0) ? MT9V034_READ_MODE_COL_FLIP : 0));
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_READ_MODE, // inverted behavior
|
||||
(read_mode & (~MT9V034_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_COL_FLIP : 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -297,17 +356,11 @@ static int set_vflip(sensor_t *sensor, int enable)
|
||||
{
|
||||
uint16_t read_mode;
|
||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL,
|
||||
(read_mode & (~MT9V034_READ_MODE_ROW_FLIP)) | ((enable != 0) ? MT9V034_READ_MODE_ROW_FLIP : 0));
|
||||
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_READ_MODE, // inverted behavior
|
||||
(read_mode & (~MT9V034_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_ROW_FLIP : 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_special_effect(sensor_t *sensor, sde_t sde)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||
{
|
||||
return 0;
|
||||
@ -315,8 +368,7 @@ static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||
|
||||
int mt9v034_init(sensor_t *sensor)
|
||||
{
|
||||
// Initialize sensor structure.
|
||||
sensor->gs_bpp = 1;
|
||||
sensor->gs_bpp = sizeof(uint8_t);
|
||||
sensor->reset = reset;
|
||||
sensor->sleep = sleep;
|
||||
sensor->read_reg = read_reg;
|
||||
@ -328,6 +380,7 @@ int mt9v034_init(sensor_t *sensor)
|
||||
sensor->set_brightness = set_brightness;
|
||||
sensor->set_saturation = set_saturation;
|
||||
sensor->set_gainceiling = set_gainceiling;
|
||||
sensor->set_quality = set_quality;
|
||||
sensor->set_colorbar = set_colorbar;
|
||||
sensor->set_auto_gain = set_auto_gain;
|
||||
sensor->get_gain_db = get_gain_db;
|
||||
@ -340,7 +393,6 @@ int mt9v034_init(sensor_t *sensor)
|
||||
sensor->set_special_effect = set_special_effect;
|
||||
sensor->set_lens_correction = set_lens_correction;
|
||||
|
||||
// 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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user