37 #include <sys/ioctl.h>
38 #include <linux/i2c-dev.h>
39 #include <linux/videodev2.h>
40 #include <linux/v4l2-mediabus.h>
42 #define MT9F002_MAX_WIDTH 4608
43 #define MT9F002_MAX_HEIGHT 3288
61 .dev_name =
"/dev/video1",
62 .subdev_name =
"/dev/v4l-subdev1",
63 .format = V4L2_PIX_FMT_UYVY,
64 .subdev_format = V4L2_MBUS_FMT_SGRBG10_1X10,
82 }
else if (len == 2) {
85 }
else if (len == 4) {
91 printf(
"[MT9F002] write_reg with incorrect length %d\r\n", len);
111 for (
uint8_t i = 0; i < len; i++) {
127 serialFormat = (3 << 8) | 2;
129 serialFormat = (2 << 8) | 2;
547 row_speed = (row_speed & 0xFFF8) | (mt->
rowSpeed_2_0 & 0x07);
548 row_speed = (row_speed & 0xF8FF) | ((mt->
row_speed_10_8 & 0x07) << 8);
549 row_speed = (row_speed & (~0x70)) | (0x2 << 4);
572 float subsampling_factor = (float)(1 + x_odd_inc) / 2.0f;
573 uint16_t min_line_length =
Max(min_line_length_pck,
574 mt->
scaled_width / subsampling_factor + min_line_blanking_pck);
575 min_line_length =
Max(min_line_length,
576 (mt->
scaled_width - 1 + x_odd_inc) / subsampling_factor / 2 + min_line_blanking_pck);
579 min_line_length =
Max(min_line_length,
582 min_line_length =
Max(min_line_length,
592 clkRatio_num = clkRatio_num / clkRatio_gcd;
593 clkRatio_den = clkRatio_den / clkRatio_gcd;
596 uint32_t min_horizontal_blanking = clkRatio_num;
597 if ((clkRatio_den % 2) != 0) {
598 min_horizontal_blanking = 2 * clkRatio_num;
602 if ((min_line_length % min_horizontal_blanking) != 0) {
603 min_line_length += min_horizontal_blanking - (min_line_length % min_horizontal_blanking);
623 new_fps = mt->
vt_pix_clk * 1000000 / (float)(ll * fl);
626 float fps_err = fabs(mt->
target_fps - new_fps);
627 if (fps_err < min_fps_err) {
628 min_fps_err = fps_err;
641 new_fps = mt->
vt_pix_clk * 1000000 / (float)(ll * min_frame_length);
673 if (fine_integration_min > fine_integration || fine_integration > fine_integration_max) {
674 int32_t upper_coarse_integration = coarse_integration + 1;
675 int32_t upper_fine_integration = fine_integration_min;
677 int32_t lower_coarse_integration = coarse_integration - 1;
678 int32_t lower_fine_integration = fine_integration_max;
681 if (lower_coarse_integration < coarse_integration_min) {
682 coarse_integration = upper_coarse_integration;
683 fine_integration = upper_fine_integration;
686 else if (upper_coarse_integration > coarse_integration_max) {
687 coarse_integration = lower_coarse_integration;
688 fine_integration = lower_fine_integration;
693 int32_t upper_error = abs((mt->
line_length * upper_coarse_integration + upper_fine_integration) - integration);
694 int32_t lower_error = abs((mt->
line_length * lower_coarse_integration + lower_fine_integration) - integration);
696 if (upper_error < lower_error) {
697 coarse_integration = upper_coarse_integration;
698 fine_integration = upper_fine_integration;
700 coarse_integration = lower_coarse_integration;
701 fine_integration = lower_fine_integration;
707 Bound(fine_integration, fine_integration_min, fine_integration_max);
708 Bound(coarse_integration, coarse_integration_min, coarse_integration_max);
727 uint8_t colamp_gain, analog_gain3, digital_gain;
733 }
else if (gain < 3.0) {
737 }
else if (gain < 6.0) {
741 }
else if (gain < 16.0) {
745 }
else if (gain < 32.0) {
756 uint16_t analog_gain2 = gain / (float)digital_gain / (
float)(1 << colamp_gain) / (
float)(1 << analog_gain3) * 64.0;
757 Bound(analog_gain2, 1, 127);
759 return (analog_gain2 & 0x7F) | ((analog_gain3 & 0x7) << 7) | ((colamp_gain & 0x3) << 10) | ((digital_gain & 0xF) << 12);
782 printf(
"[MT9F002] Warning, ouput_scaler too small, changing to %f\n", mt->
output_scaler);
785 printf(
"[MT9F002] Warning, ouput_scaler too small, changing to %f\n", mt->
output_scaler);
789 int x_skip_factor = (mt->
x_odd_inc + 1) / 2;
790 int y_skip_factor = (mt->
y_odd_inc + 1) / 2;
796 printf(
"[MT9F002] Warning, scaled_width not a multiple of %i, changing to %i\n", 8 * x_skip_factor, mt->
scaled_width);
800 printf(
"[MT9F002] Warning, scaled_height not a multiple of %i, changing to %i\n", 8 * y_skip_factor, mt->
scaled_height);
820 if (start_addr_x < 24) {
822 printf(
"[MT9F002] Warning, offset_y too small with given output_scaler, changing to %i\n", start_addr_x);
825 if (start_addr_x % (x_skip_factor * 8) != 0) {
826 start_addr_x = round(start_addr_x / (x_skip_factor * 8)) * (x_skip_factor * 8);
827 printf(
"[MT9F002] Warning, offset_x not a multiple of %i, changing to %i\n", 8 * x_skip_factor, start_addr_x);
829 if (start_addr_y % (y_skip_factor * 8) != 0) {
830 start_addr_y = round(start_addr_y / (y_skip_factor * 8)) * (y_skip_factor * 8);
831 printf(
"[MT9F002] Warning, offset_y not a multiple of %i, changing to %i\n", 8 * y_skip_factor, start_addr_y);
#define MT9F002_DAC_LD_30_31
static void mt9f002_parallel_stage2(struct mt9f002_t *mt)
Configure stage 2 for parallel connection.
#define MT9F002_SOFTWARE_RESET
#define MT9F002_FINE_INTEGRATION_TIME_MIN
#define MT9F002_X_ADDR_END
union avi_isp_statistics_yuv_increments_log2 increments_log2
#define MT9F002_FINE_INTEGRATION_TIME_
void mt9f002_set_exposure(struct mt9f002_t *mt)
Set the exposure configuration Depends on the blanking (and therefore the FPS)
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
#define MT9F002_LINE_LENGTH_PCK
uint8_t x_odd_inc
X increment for subsampling (1,3,7,15,31 accepted)
#define MT9F002_MASK_CORRUPTED_FRAMES
#define MT9F002_CTX_WR_DATA_REG
#define MT9F002_MIN_FRAME_BLANKING_LINES
union avi_isp_statistics_bayer_window_y window_y
uint16_t output_height
Output height.
#define MT9F002_LINE_LENGTH_MAX
uint16_t op_sys_clk_div
Fixed PLL config from calculator tool.
struct img_size_t output_size
Output image size.
uint8_t rowSpeed_2_0
Fixed PLL config from calculator tool.
#define MT9F002_OUTPUT_HEIGHT
uint16_t vt_pix_clk_div
Fixed PLL config from calculator tool.
#define MT9F002_DAC_LD_14_15
uint16_t pll_multiplier
Fixed PLL config from calculator tool.
#define MT9F002_SCALING_MODE
uint16_t scaled_width
Width after corrected scaling.
static void mt9f002_mipi_stage1(struct mt9f002_t *mt)
Configure stage 1 for both MiPi and HiSPi connection.
#define MT9F002_FINE_INTEGRATION_TIME_MAX_MARGIN
void mt9f002_set_resolution(struct mt9f002_t *mt)
#define MT9F002_BLUE_GAIN
#define MT9F002_X_ODD_INC
#define MT9F002_COARSE_INTEGRATION_TIME_MIN
#define MT9F002_DIGITAL_TEST
#define MT9F002_ANALOG_CONTROL4
#define MT9F002_DAC_LD_28_29
static uint32_t read_reg(struct mt9f002_t *mt, uint16_t addr, uint8_t len)
Read multiple bytes from a register.
float gain_blue
Gain for the Blue pixels [1.5 -> 63.50].
#define MT9F002_READ_MODE
#define MT9F002_CTX_CONTROL_REG
#define MT9F002_VT_PIX_CLK_DIV
float offset_y
Offset from top in pixels.
uint8_t y_odd_inc
Y increment for subsampling (1,3,7 accepted)
uint16_t vt_sys_clk_div
Fixed PLL config from calculator tool.
#define MT9F002_OP_SYS_CLK_DIV
union avi_isp_statistics_bayer_window_x window_x
#define MT9F002_DAC_LD_24_25
#define MT9F002_SERIAL_FORMAT
#define MT9F002_MIN_LINE_LENGTH_PCK
#define MT9F002_DATA_PEDESTAL_
#define MT9F002_ANALOG_CONTROL5
void mt9f002_init(struct mt9f002_t *mt)
Initialisation of the Aptina MT9F002 CMOS sensor (front camera)
float offset_x
Offset from left in pixels.
struct libisp_config isp_config
#define MT9F002_Y_OUTPUT_SIZE
float output_scaler
Output scale.
uint8_t shift_vt_pix_clk_div
Fixed PLL config from calculator tool.
#define MT9F002_COARSE_INTEGRATION_TIME
uint8_t row_speed_10_8
Fixed PLL config from calculator tool.
transaction set to done by user level
enum mt9f002_interface interface
Interface used to connect.
#define MT9F002_GREEN1_GAIN
static void mt9f002_mipi_stage3(struct mt9f002_t *mt)
Configure stage 3 for both MiPi and HiSPi connection.
static uint16_t mt9f002_calc_gain(float gain)
Calculate the gain based on value of 1.0 -> 63.50.
uint16_t line_length
Calculated line length of blanking.
float real_fps
Real calculated FPS.
#define MT9F002_DATAPATH_SELECT
#define MT9F002_RESET_REGISTER
static void mt9f002_parallel_stage1(struct mt9f002_t *mt)
Configure stage 1 for parallel connection.
static void mt9f002_set_pll(struct mt9f002_t *mt)
Set the PLL registers based on config.
float gain_green1
Gain for the GreenR pixels [1.5 -> 63.50].
#define MT9F002_ANALOG_CONTROL7
uint16_t output_width
Output width.
#define MT9F002_FRAME_LENGTH_LINES
static void write_reg(struct mt9f002_t *mt, uint16_t addr, uint32_t val, uint8_t len)
Write multiple bytes to a single register.
void mt9f002_set_gains(struct mt9f002_t *mt)
Sets the GreenR, Blue, Red and GreenB gains.
float vt_pix_clk
Calculated based on PLL.
float target_fps
FPS wanted.
#define MT9F002_X_OUTPUT_SIZE
#define MT9F002_COLUMN_CORRECTION
#define MT9F002_DARK_CONTROL3
#define MT9F002_Y_ADDR_END
#define MT9F002_EXTRA_DELAY
float gain_red
Gain for the Red pixels [1.5 -> 63.50].
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
#define MT9F002_OUTPUT_WIDTH
enum I2CTransactionStatus status
Transaction status.
#define MT9F002_MAX_WIDTH
union avi_isp_statistics_yuv_window_pos_y window_pos_y
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
#define MT9F002_COARSE_INTEGRATION_TIME_MAX_MARGIN
struct i2c_periph * i2c_periph
I2C peripheral used to communicate over.
float gain_green2
Gain for the GreenB pixels [1.5 -> 63.50].
#define MT9F002_VT_SYS_CLK_DIV
Initialization and configuration of the MT9F002 CMOS Chip.
#define MT9F002_MODE_SELECT
#define MT9F002_OP_PIX_CLK_DIV
float real_exposure
Real exposure time in ms.
#define MT9F002_GREEN2_GAIN
#define MT9F002_SMIA_TEST
struct i2c_transaction i2c_trans
I2C transaction for comminication with CMOS chip.
#define MT9F002_GLOBAL_GAIN
#define VIDEO_FILTER_ISP
Enable ISP.
#define MT9F002_Y_ADDR_START
struct avi_isp_statistics_yuv_regs statistics_yuv
YUV statistics parameters.
#define MT9F002_CPP_DATA_FORMAT
uint16_t op_pix_clk_div
Fixed PLL config from calculator tool.
#define MT9F002_PLL_MULTIPLIER
struct avi_isp_statistics_bayer_regs statistics_bayer
Statistics bayer parameters.
float op_pix_clk
Calculated based on PLL.
#define MT9F002_Y_ODD_INC
uint16_t pre_pll_clk_div
Fixed PLL config from calculator tool.
static void mt9f002_set_blanking(struct mt9f002_t *mt)
Set the blanking configuration Blanking of the MT9F002 depends on the target FPS. ...
#define MT9F002_FRAME_LENGTH_MAX
uint16_t scaled_height
Height after corrected scaling.
union avi_isp_statistics_yuv_window_pos_x window_pos_x
uint32_t int32_gcd(uint32_t a, uint32_t b)
#define MT9F002_TARGET_FPS
static void mt9f002_mipi_stage2(struct mt9f002_t *mt)
Configure stage 2 for both MiPi and HiSPi connection.
#define MT9F002_PRE_PLL_CLK_DIV
#define MT9F002_MIN_LINE_BLANKING_PCK
#define MT9F002_X_ADDR_START
#define MT9F002_MAX_HEIGHT
#define MT9F002_ROW_SPEED
uint16_t frame_length
Calculated frame length of blanking.
float input_clk_freq
Input clock frequency.
float target_exposure
Target exposure time in ms.
Paparazzi fixed point algebra.
struct video_config_t front_camera