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;
|
LEP_AGC_ROI_T roi;
|
||||||
|
|
||||||
if (LEP_GetAgcROI(&tmp_handle, &roi) != LEP_OK) {
|
if (LEP_GetAgcROI(&tmp_handle, &roi) != LEP_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -151,6 +152,7 @@ static int reset(sensor_t *sensor)
|
|||||||
if (LEP_SetAgcEnableState(&tmp_handle, LEP_AGC_ENABLE) != LEP_OK) {
|
if (LEP_SetAgcEnableState(&tmp_handle, LEP_AGC_ENABLE) != LEP_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LEP_SetAgcCalcEnableState(&tmp_handle, LEP_AGC_ENABLE) != LEP_OK) {
|
if (LEP_SetAgcCalcEnableState(&tmp_handle, LEP_AGC_ENABLE) != LEP_OK) {
|
||||||
return -1;
|
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)
|
static int snapshot(sensor_t *sensor, image_t *image)
|
||||||
{
|
{
|
||||||
|
fb_update_jpeg_buffer();
|
||||||
|
|
||||||
if ((!h_res) || (!v_res) || (!sensor->framesize) || (!sensor->pixformat)) {
|
if ((!h_res) || (!v_res) || (!sensor->framesize) || (!sensor->pixformat)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -361,57 +365,57 @@ static int snapshot(sensor_t *sensor, image_t *image)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//image_t img;
|
image_t img;
|
||||||
//img.w = sensor->fb_w;
|
img.w = MAIN_FB()->u;
|
||||||
//img.h = sensor->fb_h;
|
img.h = MAIN_FB()->v;
|
||||||
//img.bpp = MAIN_FB()->bpp; // invalid
|
img.bpp = MAIN_FB()->bpp; // invalid
|
||||||
//img.data = MAIN_FB()->pixels; // valid
|
img.data = MAIN_FB()->pixels; // valid
|
||||||
|
|
||||||
//float x_scale = resolution[sensor->framesize][0] / ((float) h_res);
|
float x_scale = resolution[sensor->framesize][0] / ((float) h_res);
|
||||||
//float y_scale = resolution[sensor->framesize][1] / ((float) v_res);
|
float y_scale = resolution[sensor->framesize][1] / ((float) v_res);
|
||||||
// MAX == KeepAspectRationByExpanding - MIN == KeepAspectRatio
|
// MAX == KeepAspectRationByExpanding - MIN == KeepAspectRatio
|
||||||
//float scale = IM_MAX(x_scale, y_scale);
|
float scale = IM_MAX(x_scale, y_scale);
|
||||||
//int x_offset = (resolution[sensor->framesize][0] - (h_res * scale)) / 2;
|
int x_offset = (resolution[sensor->framesize][0] - (h_res * scale)) / 2;
|
||||||
//int y_offset = (resolution[sensor->framesize][1] - (v_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
|
// The code below upscales the source image to the requested frame size
|
||||||
//// and then crops it to the window set by the user.
|
// and then crops it to the window set by the user.
|
||||||
|
|
||||||
//for (int yyy = fast_floorf(y * scale) + y_offset,
|
for (int yyy = fast_floorf(y * scale) + y_offset,
|
||||||
// yyyy = fast_ceilf((y + 1) * scale) + y_offset; yyy < yyyy; yyy++) {
|
yyyy = fast_ceilf((y + 1) * scale) + y_offset; yyy < yyyy; yyy++) {
|
||||||
// if ((sensor->fb_y <= yyy) && (yyy < (sensor->fb_y + sensor->fb_h))) {
|
if ((MAIN_FB()->y <= yyy) && (yyy < (MAIN_FB()->y + MAIN_FB()->v))) {
|
||||||
|
|
||||||
// for (int xxx = fast_floorf(x * scale) + x_offset,
|
for (int xxx = fast_floorf(x * scale) + x_offset,
|
||||||
// xxxx = fast_ceilf((x + VOSPI_LINE_PIXELS) * scale) + x_offset; xxx < xxxx; xxx++) {
|
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))) {
|
if ((MAIN_FB()->x <= xxx) && (xxx < (MAIN_FB()->x + MAIN_FB()->u))) {
|
||||||
|
|
||||||
// int i = (xxx / scale) - x;
|
int i = (xxx / scale) - x;
|
||||||
// // Value is the 14-bit value from the FLIR IR camera.
|
// Value is the 14-bit value from the FLIR IR camera.
|
||||||
// // However, with AGC enabled only the bottom 8-bits are non-zero.
|
// 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 value = ((buffer[(i*2)+4] << 8) | (buffer[(i*2)+5] << 0)) & 0x3FFF;
|
||||||
|
|
||||||
// int t_x = xxx - sensor->fb_x;
|
int t_x = xxx - MAIN_FB()->x;
|
||||||
// int t_y = yyy - sensor->fb_y;
|
int t_y = yyy - MAIN_FB()->y;
|
||||||
|
|
||||||
// if (h_mirror) t_x = sensor->fb_w - t_x - 1;
|
if (h_mirror) t_x = MAIN_FB()->u - t_x - 1;
|
||||||
// if (v_flip) t_y = sensor->fb_h - t_y - 1;
|
if (v_flip) t_y = MAIN_FB()->v - t_y - 1;
|
||||||
|
|
||||||
// switch (sensor->pixformat) {
|
switch (sensor->pixformat) {
|
||||||
// case PIXFORMAT_RGB565: {
|
case PIXFORMAT_RGB565: {
|
||||||
// IMAGE_PUT_RGB565_PIXEL(&img, t_x, t_y, rainbow_table[value & 0xFF]);
|
IMAGE_PUT_RGB565_PIXEL(&img, t_x, t_y, rainbow_table[value & 0xFF]);
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// case PIXFORMAT_GRAYSCALE: {
|
case PIXFORMAT_GRAYSCALE: {
|
||||||
// IMAGE_PUT_GRAYSCALE_PIXEL(&img, t_x, t_y, value & 0xFF);
|
IMAGE_PUT_GRAYSCALE_PIXEL(&img, t_x, t_y, value & 0xFF);
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// default: {
|
default: {
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
x += VOSPI_LINE_PIXELS;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,17 +6,16 @@
|
|||||||
* MT9V034 driver.
|
* MT9V034 driver.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include STM32_HAL_H
|
#include STM32_HAL_H
|
||||||
#include "cambus.h"
|
#include "cambus.h"
|
||||||
#include "sensor.h"
|
#include "mt9v034.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
#include "framebuffer.h"
|
||||||
#include "omv_boardconfig.h"
|
#include "omv_boardconfig.h"
|
||||||
|
|
||||||
#define MT9V034_MAX_HEIGHT (480)
|
#define MT9V034_MAX_HEIGHT (480)
|
||||||
#define MT9V034_MAX_WIDTH (752)
|
#define MT9V034_MAX_WIDTH (752)
|
||||||
#define MT9V034_CHIP_VERSION (0x00)
|
#define MT9V034_CHIP_VERSION (0x00)
|
||||||
#define MT9V034_COL_START (0x01)
|
#define MT9V034_COL_START (0x01)
|
||||||
#define MT9V034_COL_START_MIN (1)
|
#define MT9V034_COL_START_MIN (1)
|
||||||
@ -33,9 +32,11 @@
|
|||||||
#define MT9V034_HORIZONTAL_BLANKING (0x05)
|
#define MT9V034_HORIZONTAL_BLANKING (0x05)
|
||||||
#define MT9V034_HORIZONTAL_BLANKING_MIN (43)
|
#define MT9V034_HORIZONTAL_BLANKING_MIN (43)
|
||||||
#define MT9V034_HORIZONTAL_BLANKING_MAX (1023)
|
#define MT9V034_HORIZONTAL_BLANKING_MAX (1023)
|
||||||
|
#define MT9V034_HORIZONTAL_BLANKING_DEF (94)
|
||||||
#define MT9V034_VERTICAL_BLANKING (0x06)
|
#define MT9V034_VERTICAL_BLANKING (0x06)
|
||||||
#define MT9V034_VERTICAL_BLANKING_MIN (4)
|
#define MT9V034_VERTICAL_BLANKING_MIN (4)
|
||||||
#define MT9V034_VERTICAL_BLANKING_MAX (3000)
|
#define MT9V034_VERTICAL_BLANKING_MAX (3000)
|
||||||
|
#define MT9V034_VERTICAL_BLANKING_DEF (45)
|
||||||
#define MT9V034_CHIP_CONTROL (0x07)
|
#define MT9V034_CHIP_CONTROL (0x07)
|
||||||
#define MT9V034_CHIP_CONTROL_MASTER_MODE (1 << 3)
|
#define MT9V034_CHIP_CONTROL_MASTER_MODE (1 << 3)
|
||||||
#define MT9V034_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
|
#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_COLS (1 << 6)
|
||||||
#define MT9V034_READ_MODE_DARK_ROWS (1 << 7)
|
#define MT9V034_READ_MODE_DARK_ROWS (1 << 7)
|
||||||
#define MT9V034_PIXEL_OPERATION_MODE (0x0F)
|
#define MT9V034_PIXEL_OPERATION_MODE (0x0F)
|
||||||
#define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 2)
|
#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 0)
|
||||||
#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 6)
|
#define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 1)
|
||||||
#define MT9V034_ANALOG_GAIN (0x35)
|
#define MT9V034_ANALOG_GAIN (0x35)
|
||||||
#define MT9V034_ANALOG_GAIN_MIN (16)
|
#define MT9V034_ANALOG_GAIN_MIN (16)
|
||||||
#define MT9V034_ANALOG_GAIN_MAX (64)
|
#define MT9V034_ANALOG_GAIN_MAX (64)
|
||||||
@ -94,42 +95,74 @@
|
|||||||
#define MT9V034_AEC_ENABLE (1 << 0)
|
#define MT9V034_AEC_ENABLE (1 << 0)
|
||||||
#define MT9V034_AGC_ENABLE (1 << 1)
|
#define MT9V034_AGC_ENABLE (1 << 1)
|
||||||
#define MT9V034_THERMAL_INFO (0xC1)
|
#define MT9V034_THERMAL_INFO (0xC1)
|
||||||
|
#define MT9V034_ID_REG (0x6B)
|
||||||
#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_MAX_GAIN (0xAB)
|
#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)
|
static int reset(sensor_t *sensor)
|
||||||
{
|
{
|
||||||
// NOTE: TODO This doesn't reset register configuration.
|
DCMI_PWDN_HIGH();
|
||||||
cambus_writew(sensor->slv_addr, MT9V034_RESET, 1);
|
systick_sleep(1);
|
||||||
|
|
||||||
// Delay 10 ms
|
DCMI_PWDN_LOW();
|
||||||
systick_sleep(10);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sleep(sensor_t *sensor, int enable)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_reg(sensor_t *sensor, uint8_t reg_addr)
|
static int read_reg(sensor_t *sensor, uint8_t reg_addr)
|
||||||
{
|
{
|
||||||
uint16_t reg_data;
|
uint16_t reg_data;
|
||||||
|
|
||||||
if (cambus_readw(sensor->slv_addr, reg_addr, ®_data) != 0) {
|
if (cambus_readw(sensor->slv_addr, reg_addr, ®_data) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return reg_data;
|
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)
|
static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||||
{
|
{
|
||||||
int ret=0;
|
uint16_t width = resolution[framesize][0];
|
||||||
uint16_t readmode = 0;
|
|
||||||
uint16_t width = resolution[framesize][0];
|
|
||||||
uint16_t height = resolution[framesize][1];
|
uint16_t height = resolution[framesize][1];
|
||||||
|
|
||||||
if ((width * 4) <= MT9V034_MAX_WIDTH && (height * 4) <= MT9V034_MAX_HEIGHT) {
|
if ((width > MT9V034_MAX_WIDTH) || (height > MT9V034_MAX_HEIGHT)) {
|
||||||
width *= 4; height *= 4;
|
return -1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readmode |= MT9V034_READ_MODE_ROW_FLIP;
|
uint16_t readmode;
|
||||||
readmode |= MT9V034_READ_MODE_COL_FLIP;
|
int ret = 0;
|
||||||
cambus_writew(sensor->slv_addr, MT9V034_READ_MODE, readmode);
|
ret |= cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &readmode);
|
||||||
|
readmode &= 0xFFF0;
|
||||||
|
|
||||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_WINDOW_WIDTH, width);
|
if (((width * 4) <= MT9V034_MAX_WIDTH) && ((height * 4) <= MT9V034_MAX_HEIGHT)) {
|
||||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_COL_START, (MT9V034_MAX_WIDTH - width ) / 2 + MT9V034_COL_START_MIN);
|
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_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_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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +233,6 @@ static int set_contrast(sensor_t *sensor, int level)
|
|||||||
static int set_brightness(sensor_t *sensor, int level)
|
static int set_brightness(sensor_t *sensor, int level)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_saturation(sensor_t *sensor, int level)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_quality(sensor_t *sensor, int quality)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int set_colorbar(sensor_t *sensor, int enable)
|
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;
|
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))) {
|
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.0) * fast_log(10.0)) * 16.0), 127), 0);
|
||||||
|
|
||||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, ®);
|
ret |= cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN, ®);
|
||||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, (reg & 0xFF80) | 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))) {
|
} 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.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)
|
static int get_gain_db(sensor_t *sensor, float *gain_db)
|
||||||
{
|
{
|
||||||
uint16_t gain;
|
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));
|
*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)
|
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, ®);
|
int ret = cambus_readw(sensor->slv_addr, MT9V034_AEC_AGC_ENABLE, ®);
|
||||||
ret |= cambus_writew(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));
|
(reg & (~MT9V034_AEC_ENABLE)) | ((enable != 0) ? MT9V034_AEC_ENABLE : 0));
|
||||||
|
|
||||||
if ((enable == 0) && (exposure_us >= 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_WINDOW_WIDTH, &row_time_0);
|
||||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_VERTICAL_BLANKING_A, &row_limit_1);
|
ret |= cambus_readw(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING, &row_time_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);
|
|
||||||
|
|
||||||
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 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;
|
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_TOTAL_SHUTTER_WIDTH, coarse_time);
|
||||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL_A, fine_time);
|
ret |= cambus_writew(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, fine_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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)
|
static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
||||||
{
|
{
|
||||||
uint16_t int_rows, int_pixels, row_time_0, row_time_1;
|
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);
|
int ret = cambus_readw(sensor->slv_addr, MT9V034_TOTAL_SHUTTER_WIDTH, &int_rows);
|
||||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL_A, &int_pixels);
|
ret |= cambus_readw(sensor->slv_addr, MT9V034_FINE_SHUTTER_WIDTH_TOTAL, &int_pixels);
|
||||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_WIDTH_A, &row_time_0);
|
ret |= cambus_readw(sensor->slv_addr, MT9V034_WINDOW_WIDTH, &row_time_0);
|
||||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_HORIZONTAL_BLANKING_A, &row_time_1);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -287,9 +347,8 @@ static int set_hmirror(sensor_t *sensor, int enable)
|
|||||||
{
|
{
|
||||||
uint16_t read_mode;
|
uint16_t read_mode;
|
||||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
|
int ret = cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
|
||||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL,
|
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));
|
(read_mode & (~MT9V034_READ_MODE_COL_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_COL_FLIP : 0));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,17 +356,11 @@ static int set_vflip(sensor_t *sensor, int enable)
|
|||||||
{
|
{
|
||||||
uint16_t read_mode;
|
uint16_t read_mode;
|
||||||
int ret = cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
|
int ret = cambus_readw(sensor->slv_addr, MT9V034_READ_MODE, &read_mode);
|
||||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL,
|
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));
|
(read_mode & (~MT9V034_READ_MODE_ROW_FLIP)) | ((enable == 0) ? MT9V034_READ_MODE_ROW_FLIP : 0));
|
||||||
|
|
||||||
return ret;
|
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)
|
static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef)
|
||||||
{
|
{
|
||||||
return 0;
|
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)
|
int mt9v034_init(sensor_t *sensor)
|
||||||
{
|
{
|
||||||
// Initialize sensor structure.
|
sensor->gs_bpp = sizeof(uint8_t);
|
||||||
sensor->gs_bpp = 1;
|
|
||||||
sensor->reset = reset;
|
sensor->reset = reset;
|
||||||
sensor->sleep = sleep;
|
sensor->sleep = sleep;
|
||||||
sensor->read_reg = read_reg;
|
sensor->read_reg = read_reg;
|
||||||
@ -328,6 +380,7 @@ int mt9v034_init(sensor_t *sensor)
|
|||||||
sensor->set_brightness = set_brightness;
|
sensor->set_brightness = set_brightness;
|
||||||
sensor->set_saturation = set_saturation;
|
sensor->set_saturation = set_saturation;
|
||||||
sensor->set_gainceiling = set_gainceiling;
|
sensor->set_gainceiling = set_gainceiling;
|
||||||
|
sensor->set_quality = set_quality;
|
||||||
sensor->set_colorbar = set_colorbar;
|
sensor->set_colorbar = set_colorbar;
|
||||||
sensor->set_auto_gain = set_auto_gain;
|
sensor->set_auto_gain = set_auto_gain;
|
||||||
sensor->get_gain_db = get_gain_db;
|
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_special_effect = set_special_effect;
|
||||||
sensor->set_lens_correction = set_lens_correction;
|
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_VSYNC, 0);
|
||||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_HSYNC, 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_PIXCK, 0);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user