Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
mt9f002.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Freek van Tienen <freek.v.tienen@gmail.com>
3  *
4  * This file is part of Paparazzi.
5  *
6  * Paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  *
20  */
21 
27 #include "std.h"
28 #include "mt9f002.h"
29 #include "mt9f002_regs.h"
30 #include "math/pprz_algebra_int.h"
31 #include "boards/bebop.h"
33 
34 #include <stdio.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <sys/ioctl.h>
38 #include <linux/i2c-dev.h>
39 #include <linux/videodev2.h>
40 #include <linux/v4l2-mediabus.h>
41 
42 #define MT9F002_MAX_WIDTH 4608
43 #define MT9F002_MAX_HEIGHT 3288
44 
45 /* Camera structure */
47  .output_size = {
50  },
51  .sensor_size = {
54  },
55  .crop = {
56  .x = 0,
57  .y = 0,
60  },
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,
65  .buf_cnt = 5,
66  .filters = VIDEO_FILTER_ISP,
67  .cv_listener = NULL,
68  .fps = MT9F002_TARGET_FPS,
69  .camera_intrinsics = {
70  .focal_x = MT9F002_FOCAL_X,
71  .focal_y = MT9F002_FOCAL_Y,
72  .center_x = MT9F002_CENTER_X,
73  .center_y = MT9F002_CENTER_Y,
74  .Dhane_k = MT9F002_DHANE_K
75  }
76 };
77 
81 static void write_reg(struct mt9f002_t *mt, uint16_t addr, uint32_t val, uint8_t len)
82 {
83  mt->i2c_trans.buf[0] = addr >> 8;
84  mt->i2c_trans.buf[1] = addr & 0xFF;
85 
86  // Fix sigdness based on length
87  if (len == 1) {
88  mt->i2c_trans.buf[2] = val & 0xFF;
89  } else if (len == 2) {
90  mt->i2c_trans.buf[2] = (val >> 8) & 0xFF;
91  mt->i2c_trans.buf[3] = val & 0xFF;
92  } else if (len == 4) {
93  mt->i2c_trans.buf[2] = (val >> 24) & 0xFF;
94  mt->i2c_trans.buf[3] = (val >> 16) & 0xFF;
95  mt->i2c_trans.buf[4] = (val >> 8) & 0xFF;
96  mt->i2c_trans.buf[5] = val & 0xFF;
97  } else {
98  printf("[MT9F002] write_reg with incorrect length %d\r\n", len);
99  }
100 
101  // Transmit the buffer
103 }
104 
108 static uint32_t read_reg(struct mt9f002_t *mt, uint16_t addr, uint8_t len)
109 {
110  uint32_t ret = 0;
111  mt->i2c_trans.buf[0] = addr >> 8;
112  mt->i2c_trans.buf[1] = addr & 0xFF;
113 
114  // Transmit the buffer and receive back
116 
117  /* Fix sigdness */
118  for (uint8_t i = 0; i < len; i++) {
119  ret |= mt->i2c_trans.buf[len - i - 1] << (8 * i);
120  }
121  return ret;
122 }
123 
127 static inline void mt9f002_mipi_stage1(struct mt9f002_t *mt)
128 {
129  write_reg(mt, MT9F002_RESET_REGISTER, 0x0118, 2);
130  write_reg(mt, MT9F002_MODE_SELECT, 0x00, 1);
131 
132  uint32_t serialFormat;
133  if (mt->interface == MT9F002_HiSPi) {
134  serialFormat = (3 << 8) | 2; // 2 Serial lanes
135  } else {
136  serialFormat = (2 << 8) | 2; // 2 Serial lanes
137  }
138  write_reg(mt, MT9F002_SERIAL_FORMAT, serialFormat, 2);
139  uint32_t dataFormat = (8 << 8) | 8; // 8 Bits pixel depth
140  write_reg(mt, MT9F002_CPP_DATA_FORMAT, dataFormat, 2);
141 
142  write_reg(mt, MT9F002_MFR_3D00, 0x0435, 2);
143  write_reg(mt, MT9F002_MFR_3D02, 0x435D, 2);
144  write_reg(mt, MT9F002_MFR_3D04, 0x6698, 2);
145  write_reg(mt, MT9F002_MFR_3D06, 0xFFFF, 2);
146  write_reg(mt, MT9F002_MFR_3D08, 0x7783, 2);
147  write_reg(mt, MT9F002_MFR_3D0A, 0x101B, 2);
148  write_reg(mt, MT9F002_MFR_3D0C, 0x732C, 2);
149  write_reg(mt, MT9F002_MFR_3D0E, 0x4230, 2);
150  write_reg(mt, MT9F002_MFR_3D10, 0x5881, 2);
151  write_reg(mt, MT9F002_MFR_3D12, 0x5C3A, 2);
152  write_reg(mt, MT9F002_MFR_3D14, 0x0140, 2);
153  write_reg(mt, MT9F002_MFR_3D16, 0x2300, 2);
154  write_reg(mt, MT9F002_MFR_3D18, 0x815F, 2);
155  write_reg(mt, MT9F002_MFR_3D1A, 0x6789, 2);
156  write_reg(mt, MT9F002_MFR_3D1C, 0x5920, 2);
157  write_reg(mt, MT9F002_MFR_3D1E, 0x0C20, 2);
158  write_reg(mt, MT9F002_MFR_3D20, 0x21C0, 2);
159  write_reg(mt, MT9F002_MFR_3D22, 0x4684, 2);
160  write_reg(mt, MT9F002_MFR_3D24, 0x4892, 2);
161  write_reg(mt, MT9F002_MFR_3D26, 0x1A00, 2);
162  write_reg(mt, MT9F002_MFR_3D28, 0xBA4C, 2);
163  write_reg(mt, MT9F002_MFR_3D2A, 0x8D48, 2);
164  write_reg(mt, MT9F002_MFR_3D2C, 0x4641, 2);
165  write_reg(mt, MT9F002_MFR_3D2E, 0x408C, 2);
166  write_reg(mt, MT9F002_MFR_3D30, 0x4784, 2);
167  write_reg(mt, MT9F002_MFR_3D32, 0x4A87, 2);
168  write_reg(mt, MT9F002_MFR_3D34, 0x561A, 2);
169  write_reg(mt, MT9F002_MFR_3D36, 0x00A5, 2);
170  write_reg(mt, MT9F002_MFR_3D38, 0x1A00, 2);
171  write_reg(mt, MT9F002_MFR_3D3A, 0x5693, 2);
172  write_reg(mt, MT9F002_MFR_3D3C, 0x4D8D, 2);
173  write_reg(mt, MT9F002_MFR_3D3E, 0x4A47, 2);
174  write_reg(mt, MT9F002_MFR_3D40, 0x4041, 2);
175  write_reg(mt, MT9F002_MFR_3D42, 0x8200, 2);
176  write_reg(mt, MT9F002_MFR_3D44, 0x24B7, 2);
177  write_reg(mt, MT9F002_MFR_3D46, 0x0024, 2);
178  write_reg(mt, MT9F002_MFR_3D48, 0x8D4F, 2);
179  write_reg(mt, MT9F002_MFR_3D4A, 0x831A, 2);
180  write_reg(mt, MT9F002_MFR_3D4C, 0x00B4, 2);
181  write_reg(mt, MT9F002_MFR_3D4E, 0x4684, 2);
182  write_reg(mt, MT9F002_MFR_3D50, 0x49CE, 2);
183  write_reg(mt, MT9F002_MFR_3D52, 0x4946, 2);
184  write_reg(mt, MT9F002_MFR_3D54, 0x4140, 2);
185  write_reg(mt, MT9F002_MFR_3D56, 0x9247, 2);
186  write_reg(mt, MT9F002_MFR_3D58, 0x844B, 2);
187  write_reg(mt, MT9F002_MFR_3D5A, 0xCE4B, 2);
188  write_reg(mt, MT9F002_MFR_3D5C, 0x4741, 2);
189  write_reg(mt, MT9F002_MFR_3D5E, 0x502F, 2);
190  write_reg(mt, MT9F002_MFR_3D60, 0xBD3A, 2);
191  write_reg(mt, MT9F002_MFR_3D62, 0x5181, 2);
192  write_reg(mt, MT9F002_MFR_3D64, 0x5E73, 2);
193  write_reg(mt, MT9F002_MFR_3D66, 0x7C0A, 2);
194  write_reg(mt, MT9F002_MFR_3D68, 0x7770, 2);
195  write_reg(mt, MT9F002_MFR_3D6A, 0x8085, 2);
196  write_reg(mt, MT9F002_MFR_3D6C, 0x6A82, 2);
197  write_reg(mt, MT9F002_MFR_3D6E, 0x6742, 2);
198  write_reg(mt, MT9F002_MFR_3D70, 0x8244, 2);
199  write_reg(mt, MT9F002_MFR_3D72, 0x831A, 2);
200  write_reg(mt, MT9F002_MFR_3D74, 0x0099, 2);
201  write_reg(mt, MT9F002_MFR_3D76, 0x44DF, 2);
202  write_reg(mt, MT9F002_MFR_3D78, 0x1A00, 2);
203  write_reg(mt, MT9F002_MFR_3D7A, 0x8542, 2);
204  write_reg(mt, MT9F002_MFR_3D7C, 0x8567, 2);
205  write_reg(mt, MT9F002_MFR_3D7E, 0x826A, 2);
206  write_reg(mt, MT9F002_MFR_3D80, 0x857C, 2);
207  write_reg(mt, MT9F002_MFR_3D82, 0x6B80, 2);
208  write_reg(mt, MT9F002_MFR_3D84, 0x7000, 2);
209  write_reg(mt, MT9F002_MFR_3D86, 0xB831, 2);
210  write_reg(mt, MT9F002_MFR_3D88, 0x40BE, 2);
211  write_reg(mt, MT9F002_MFR_3D8A, 0x6700, 2);
212  write_reg(mt, MT9F002_MFR_3D8C, 0x0CBD, 2);
213  write_reg(mt, MT9F002_MFR_3D8E, 0x4482, 2);
214  write_reg(mt, MT9F002_MFR_3D90, 0x7898, 2);
215  write_reg(mt, MT9F002_MFR_3D92, 0x7480, 2);
216  write_reg(mt, MT9F002_MFR_3D94, 0x5680, 2);
217  write_reg(mt, MT9F002_MFR_3D96, 0x9755, 2);
218  write_reg(mt, MT9F002_MFR_3D98, 0x8057, 2);
219  write_reg(mt, MT9F002_MFR_3D9A, 0x8056, 2);
220  write_reg(mt, MT9F002_MFR_3D9C, 0x9256, 2);
221  write_reg(mt, MT9F002_MFR_3D9E, 0x8057, 2);
222  write_reg(mt, MT9F002_MFR_3DA0, 0x8055, 2);
223  write_reg(mt, MT9F002_MFR_3DA2, 0x817C, 2);
224  write_reg(mt, MT9F002_MFR_3DA4, 0x969B, 2);
225  write_reg(mt, MT9F002_MFR_3DA6, 0x56A6, 2);
226  write_reg(mt, MT9F002_MFR_3DA8, 0x44BE, 2);
227  write_reg(mt, MT9F002_MFR_3DAA, 0x000C, 2);
228  write_reg(mt, MT9F002_MFR_3DAC, 0x867A, 2);
229  write_reg(mt, MT9F002_MFR_3DAE, 0x9474, 2);
230  write_reg(mt, MT9F002_MFR_3DB0, 0x8A79, 2);
231  write_reg(mt, MT9F002_MFR_3DB2, 0x9367, 2);
232  write_reg(mt, MT9F002_MFR_3DB4, 0xBF6A, 2);
233  write_reg(mt, MT9F002_MFR_3DB6, 0x816C, 2);
234  write_reg(mt, MT9F002_MFR_3DB8, 0x8570, 2);
235  write_reg(mt, MT9F002_MFR_3DBA, 0x836C, 2);
236  write_reg(mt, MT9F002_MFR_3DBC, 0x826A, 2);
237  write_reg(mt, MT9F002_MFR_3DBE, 0x8245, 2);
238  write_reg(mt, MT9F002_MFR_3DC0, 0xFFFF, 2);
239  write_reg(mt, MT9F002_MFR_3DC2, 0xFFD6, 2);
240  write_reg(mt, MT9F002_MFR_3DC4, 0x4582, 2);
241  write_reg(mt, MT9F002_MFR_3DC6, 0x6A82, 2);
242  write_reg(mt, MT9F002_MFR_3DC8, 0x6C83, 2);
243  write_reg(mt, MT9F002_MFR_3DCA, 0x7000, 2);
244  write_reg(mt, MT9F002_MFR_3DCC, 0x8024, 2);
245  write_reg(mt, MT9F002_MFR_3DCE, 0xB181, 2);
246  write_reg(mt, MT9F002_MFR_3DD0, 0x6859, 2);
247  write_reg(mt, MT9F002_MFR_3DD2, 0x732B, 2);
248  write_reg(mt, MT9F002_MFR_3DD4, 0x4030, 2);
249  write_reg(mt, MT9F002_MFR_3DD6, 0x4982, 2);
250  write_reg(mt, MT9F002_MFR_3DD8, 0x101B, 2);
251  write_reg(mt, MT9F002_MFR_3DDA, 0x4083, 2);
252  write_reg(mt, MT9F002_MFR_3DDC, 0x6785, 2);
253  write_reg(mt, MT9F002_MFR_3DDE, 0x3A00, 2);
254  write_reg(mt, MT9F002_MFR_3DE0, 0x8820, 2);
255  write_reg(mt, MT9F002_MFR_3DE2, 0x0C59, 2);
256  write_reg(mt, MT9F002_MFR_3DE4, 0x8546, 2);
257  write_reg(mt, MT9F002_MFR_3DE6, 0x8348, 2);
258  write_reg(mt, MT9F002_MFR_3DE8, 0xD04C, 2);
259  write_reg(mt, MT9F002_MFR_3DEA, 0x8B48, 2);
260  write_reg(mt, MT9F002_MFR_3DEC, 0x4641, 2);
261  write_reg(mt, MT9F002_MFR_3DEE, 0x4083, 2);
262  write_reg(mt, MT9F002_MFR_3DF0, 0x1A00, 2);
263  write_reg(mt, MT9F002_MFR_3DF2, 0x8347, 2);
264  write_reg(mt, MT9F002_MFR_3DF4, 0x824A, 2);
265  write_reg(mt, MT9F002_MFR_3DF6, 0x9A56, 2);
266  write_reg(mt, MT9F002_MFR_3DF8, 0x1A00, 2);
267  write_reg(mt, MT9F002_MFR_3DFA, 0x951A, 2);
268  write_reg(mt, MT9F002_MFR_3DFC, 0x0056, 2);
269  write_reg(mt, MT9F002_MFR_3DFE, 0x914D, 2);
270  write_reg(mt, MT9F002_MFR_3E00, 0x8B4A, 2);
271  write_reg(mt, MT9F002_MFR_3E02, 0x4700, 2);
272  write_reg(mt, MT9F002_MFR_3E04, 0x0300, 2);
273  write_reg(mt, MT9F002_MFR_3E06, 0x2492, 2);
274  write_reg(mt, MT9F002_MFR_3E08, 0x0024, 2);
275  write_reg(mt, MT9F002_MFR_3E0A, 0x8A1A, 2);
276  write_reg(mt, MT9F002_MFR_3E0C, 0x004F, 2);
277  write_reg(mt, MT9F002_MFR_3E0E, 0xB446, 2);
278  write_reg(mt, MT9F002_MFR_3E10, 0x8349, 2);
279  write_reg(mt, MT9F002_MFR_3E12, 0xB249, 2);
280  write_reg(mt, MT9F002_MFR_3E14, 0x4641, 2);
281  write_reg(mt, MT9F002_MFR_3E16, 0x408B, 2);
282  write_reg(mt, MT9F002_MFR_3E18, 0x4783, 2);
283  write_reg(mt, MT9F002_MFR_3E1A, 0x4BDB, 2);
284  write_reg(mt, MT9F002_MFR_3E1C, 0x4B47, 2);
285  write_reg(mt, MT9F002_MFR_3E1E, 0x4180, 2);
286  write_reg(mt, MT9F002_MFR_3E20, 0x502B, 2);
287  write_reg(mt, MT9F002_MFR_3E22, 0x4C3A, 2);
288  write_reg(mt, MT9F002_MFR_3E24, 0x4180, 2);
289  write_reg(mt, MT9F002_MFR_3E26, 0x737C, 2);
290  write_reg(mt, MT9F002_MFR_3E28, 0xD124, 2);
291  write_reg(mt, MT9F002_MFR_3E2A, 0x9068, 2);
292  write_reg(mt, MT9F002_MFR_3E2C, 0x8A20, 2);
293  write_reg(mt, MT9F002_MFR_3E2E, 0x2170, 2);
294  write_reg(mt, MT9F002_MFR_3E30, 0x8081, 2);
295  write_reg(mt, MT9F002_MFR_3E32, 0x6A67, 2);
296  write_reg(mt, MT9F002_MFR_3E34, 0x4257, 2);
297  write_reg(mt, MT9F002_MFR_3E36, 0x5544, 2);
298  write_reg(mt, MT9F002_MFR_3E38, 0x8644, 2);
299  write_reg(mt, MT9F002_MFR_3E3A, 0x9755, 2);
300  write_reg(mt, MT9F002_MFR_3E3C, 0x5742, 2);
301  write_reg(mt, MT9F002_MFR_3E3E, 0x676A, 2);
302  write_reg(mt, MT9F002_MFR_3E40, 0x807D, 2);
303  write_reg(mt, MT9F002_MFR_3E42, 0x3180, 2);
304  write_reg(mt, MT9F002_MFR_3E44, 0x7000, 2);
305  write_reg(mt, MT9F002_MFR_3E46, 0x0000, 2);
306  write_reg(mt, MT9F002_MFR_3E48, 0x0000, 2);
307  write_reg(mt, MT9F002_MFR_3E4A, 0x0000, 2);
308  write_reg(mt, MT9F002_MFR_3E4C, 0x0000, 2);
309  write_reg(mt, MT9F002_MFR_3E4E, 0x0000, 2);
310  write_reg(mt, MT9F002_MFR_3E50, 0x0000, 2);
311  write_reg(mt, MT9F002_MFR_3E52, 0x0000, 2);
312  write_reg(mt, MT9F002_MFR_3E54, 0x0000, 2);
313  write_reg(mt, MT9F002_MFR_3E56, 0x0000, 2);
314  write_reg(mt, MT9F002_MFR_3E58, 0x0000, 2);
315  write_reg(mt, MT9F002_MFR_3E5A, 0x0000, 2);
316  write_reg(mt, MT9F002_MFR_3E5C, 0x0000, 2);
317  write_reg(mt, MT9F002_MFR_3E5E, 0x0000, 2);
318  write_reg(mt, MT9F002_MFR_3E60, 0x0000, 2);
319  write_reg(mt, MT9F002_MFR_3E62, 0x0000, 2);
320  write_reg(mt, MT9F002_MFR_3E64, 0x0000, 2);
321  write_reg(mt, MT9F002_MFR_3E66, 0x0000, 2);
322  write_reg(mt, MT9F002_MFR_3E68, 0x0000, 2);
323  write_reg(mt, MT9F002_MFR_3E6A, 0x0000, 2);
324  write_reg(mt, MT9F002_MFR_3E6C, 0x0000, 2);
325  write_reg(mt, MT9F002_MFR_3E6E, 0x0000, 2);
326  write_reg(mt, MT9F002_MFR_3E70, 0x0000, 2);
327  write_reg(mt, MT9F002_MFR_3E72, 0x0000, 2);
328  write_reg(mt, MT9F002_MFR_3E74, 0x0000, 2);
329  write_reg(mt, MT9F002_MFR_3E76, 0x0000, 2);
330  write_reg(mt, MT9F002_MFR_3E78, 0x0000, 2);
331  write_reg(mt, MT9F002_MFR_3E7A, 0x0000, 2);
332  write_reg(mt, MT9F002_MFR_3E7C, 0x0000, 2);
333  write_reg(mt, MT9F002_MFR_3E7E, 0x0000, 2);
334  write_reg(mt, MT9F002_MFR_3E80, 0x0000, 2);
335  write_reg(mt, MT9F002_MFR_3E82, 0x0000, 2);
336  write_reg(mt, MT9F002_MFR_3E84, 0x0000, 2);
337  write_reg(mt, MT9F002_MFR_3E86, 0x0000, 2);
338  write_reg(mt, MT9F002_MFR_3E88, 0x0000, 2);
339  write_reg(mt, MT9F002_MFR_3E8A, 0x0000, 2);
340  write_reg(mt, MT9F002_MFR_3E8C, 0x0000, 2);
341  write_reg(mt, MT9F002_MFR_3E8E, 0x0000, 2);
342  write_reg(mt, MT9F002_MFR_3E90, 0x0000, 2);
343  write_reg(mt, MT9F002_MFR_3E92, 0x0000, 2);
344  write_reg(mt, MT9F002_MFR_3E94, 0x0000, 2);
345  write_reg(mt, MT9F002_MFR_3E96, 0x0000, 2);
346  write_reg(mt, MT9F002_MFR_3E98, 0x0000, 2);
347  write_reg(mt, MT9F002_MFR_3E9A, 0x0000, 2);
348  write_reg(mt, MT9F002_MFR_3E9C, 0x0000, 2);
349  write_reg(mt, MT9F002_MFR_3E9E, 0x0000, 2);
350  write_reg(mt, MT9F002_MFR_3EA0, 0x0000, 2);
351  write_reg(mt, MT9F002_MFR_3EA2, 0x0000, 2);
352  write_reg(mt, MT9F002_MFR_3EA4, 0x0000, 2);
353  write_reg(mt, MT9F002_MFR_3EA6, 0x0000, 2);
354  write_reg(mt, MT9F002_MFR_3EA8, 0x0000, 2);
355  write_reg(mt, MT9F002_MFR_3EAA, 0x0000, 2);
356  write_reg(mt, MT9F002_MFR_3EAC, 0x0000, 2);
357  write_reg(mt, MT9F002_MFR_3EAE, 0x0000, 2);
358  write_reg(mt, MT9F002_MFR_3EB0, 0x0000, 2);
359  write_reg(mt, MT9F002_MFR_3EB2, 0x0000, 2);
360  write_reg(mt, MT9F002_MFR_3EB4, 0x0000, 2);
361  write_reg(mt, MT9F002_MFR_3EB6, 0x0000, 2);
362  write_reg(mt, MT9F002_MFR_3EB8, 0x0000, 2);
363  write_reg(mt, MT9F002_MFR_3EBA, 0x0000, 2);
364  write_reg(mt, MT9F002_MFR_3EBC, 0x0000, 2);
365  write_reg(mt, MT9F002_MFR_3EBE, 0x0000, 2);
366  write_reg(mt, MT9F002_MFR_3EC0, 0x0000, 2);
367  write_reg(mt, MT9F002_MFR_3EC2, 0x0000, 2);
368  write_reg(mt, MT9F002_MFR_3EC4, 0x0000, 2);
369  write_reg(mt, MT9F002_MFR_3EC6, 0x0000, 2);
370  write_reg(mt, MT9F002_MFR_3EC8, 0x0000, 2);
371  write_reg(mt, MT9F002_MFR_3ECA, 0x0000, 2);
372  write_reg(mt, MT9F002_MFR_3176, 0x4000, 2);
373  write_reg(mt, MT9F002_MFR_317C, 0xA00A, 2);
374  write_reg(mt, MT9F002_MFR_3EE6, 0x0000, 2);
375  write_reg(mt, MT9F002_MFR_3ED8, 0xE0E0, 2);
376  write_reg(mt, MT9F002_MFR_3EE8, 0x0001, 2);
377  write_reg(mt, MT9F002_SMIA_TEST, 0x0005, 2);
378 }
379 
383 static inline void mt9f002_mipi_stage2(struct mt9f002_t *mt)
384 {
385  write_reg(mt, MT9F002_SMIA_TEST, 0x0045, 2);
386 }
387 
391 static inline void mt9f002_mipi_stage3(struct mt9f002_t *mt)
392 {
393  write_reg(mt, MT9F002_EXTRA_DELAY , 0x0000, 2);
394  write_reg(mt, MT9F002_RESET_REGISTER , 0x0118, 2);
395  write_reg(mt, MT9F002_MFR_3EDC, 0x68CF, 2);
396  write_reg(mt, MT9F002_MFR_3EE2, 0xE363, 2);
397 }
398 
402 static inline void mt9f002_parallel_stage1(struct mt9f002_t *mt)
403 {
404  write_reg(mt, MT9F002_RESET_REGISTER , 0x0010, 2);
405  write_reg(mt, MT9F002_GLOBAL_GAIN , 0x1430, 2);
406  write_reg(mt, MT9F002_RESET_REGISTER , 0x0010, 2);
407  write_reg(mt, MT9F002_RESET_REGISTER , 0x0010, 2);
408  write_reg(mt, MT9F002_RESET_REGISTER , 0x0010, 2);
409  write_reg(mt, MT9F002_DAC_LD_14_15 , 0xE525, 2);
410  write_reg(mt, MT9F002_CTX_CONTROL_REG, 0x0000, 2);
411  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xF873, 2);
412  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x08AA, 2);
413  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3219, 2);
414  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3219, 2);
415  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3219, 2);
416  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3200, 2);
417  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3200, 2);
418  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3200, 2);
419  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3200, 2);
420  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x3200, 2);
421  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x1769, 2);
422  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
423  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
424  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
425  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
426  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
427  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
428  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA6F3, 2);
429  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xAFF3, 2);
430  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xFA64, 2);
431  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xFA64, 2);
432  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xFA64, 2);
433  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xF164, 2);
434  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xFA64, 2);
435  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xFA64, 2);
436  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xFA64, 2);
437  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xF164, 2);
438  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x276E, 2);
439  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
440  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
441  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
442  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x28CF, 2);
443  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
444  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
445  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
446  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x18CF, 2);
447  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2363, 2);
448  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2363, 2);
449  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2352, 2);
450  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2363, 2);
451  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2363, 2);
452  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2363, 2);
453  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2352, 2);
454  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x2352, 2);
455  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA394, 2);
456  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA394, 2);
457  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x8F8F, 2);
458  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA3D4, 2);
459  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA394, 2);
460  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xA394, 2);
461  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x8F8F, 2);
462  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x8FCF, 2);
463  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC23, 2);
464  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC63, 2);
465  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC63, 2);
466  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC23, 2);
467  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC23, 2);
468  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC63, 2);
469  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC63, 2);
470  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0xDC23, 2);
471  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x0F73, 2);
472  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
473  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
474  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
475  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
476  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
477  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
478  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C0, 2);
479  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x85C4, 2);
480  write_reg(mt, MT9F002_CTX_WR_DATA_REG, 0x0000, 2);
481  write_reg(mt, MT9F002_ANALOG_CONTROL4, 0x8000, 2);
482  write_reg(mt, MT9F002_DAC_LD_14_15 , 0xE525, 2);
483  write_reg(mt, MT9F002_DATA_PEDESTAL_ , 0x00A8, 2);
484  write_reg(mt, MT9F002_RESET_REGISTER , 0x0090, 2);
485  write_reg(mt, MT9F002_SERIAL_FORMAT , 0x0301, 2);
486  write_reg(mt, MT9F002_RESET_REGISTER , 0x1090, 2);
487  write_reg(mt, MT9F002_SMIA_TEST , 0x0845, 2);
488  write_reg(mt, MT9F002_RESET_REGISTER , 0x1080, 2);
489  write_reg(mt, MT9F002_DATAPATH_SELECT, 0xD880, 2);
490  write_reg(mt, MT9F002_RESET_REGISTER , 0x9080, 2);
491  write_reg(mt, MT9F002_DATAPATH_SELECT, 0xD880, 2);
492  write_reg(mt, MT9F002_RESET_REGISTER , 0x10C8, 2);
493  write_reg(mt, MT9F002_DATAPATH_SELECT, 0xD880, 2);
494 }
495 
499 static inline void mt9f002_parallel_stage2(struct mt9f002_t *mt)
500 {
501  write_reg(mt, MT9F002_ANALOG_CONTROL4, 0x8000, 2);
502  write_reg(mt, MT9F002_READ_MODE, 0x0041, 2);
503 
504  write_reg(mt, MT9F002_READ_MODE , 0x04C3, 2);
505  write_reg(mt, MT9F002_READ_MODE , 0x04C3, 2);
506  write_reg(mt, MT9F002_ANALOG_CONTROL5 , 0x0000, 2);
507  write_reg(mt, MT9F002_ANALOG_CONTROL5 , 0x0000, 2);
508  write_reg(mt, MT9F002_ANALOG_CONTROL5 , 0x0000, 2);
509  write_reg(mt, MT9F002_ANALOG_CONTROL5 , 0x0000, 2);
510  write_reg(mt, MT9F002_DAC_LD_28_29 , 0x0047, 2);
511  write_reg(mt, MT9F002_COLUMN_CORRECTION , 0xB080, 2);
512  write_reg(mt, MT9F002_COLUMN_CORRECTION , 0xB100, 2);
513  write_reg(mt, MT9F002_DARK_CONTROL3 , 0x0020, 2);
514  write_reg(mt, MT9F002_DAC_LD_24_25 , 0x6349, 2);
515  write_reg(mt, MT9F002_ANALOG_CONTROL7 , 0x800A, 2);
516  write_reg(mt, MT9F002_RESET_REGISTER , 0x90C8, 2);
517  write_reg(mt, MT9F002_CTX_CONTROL_REG , 0x8005, 2);
518  write_reg(mt, MT9F002_ANALOG_CONTROL7 , 0x800A, 2);
519  write_reg(mt, MT9F002_DAC_LD_28_29 , 0x0047, 2);
520  write_reg(mt, MT9F002_DAC_LD_30_31 , 0x15F0, 2);
521  write_reg(mt, MT9F002_DAC_LD_30_31 , 0x15F0, 2);
522  write_reg(mt, MT9F002_DAC_LD_30_31 , 0x15F0, 2);
523  write_reg(mt, MT9F002_DAC_LD_28_29 , 0x0047, 2);
524  write_reg(mt, MT9F002_DAC_LD_28_29 , 0x0047, 2);
525  write_reg(mt, MT9F002_RESET_REGISTER , 0x10C8, 2);
526  //write_reg(mt, MT9F002_RESET_REGISTER , 0x14C8, 2); // reset bad frame
528  write_reg(mt, MT9F002_DIGITAL_TEST , 0x0000, 2);
529  //write_reg(mt, MT9F002_DATAPATH_SELECT , 0xd881, 2); // permanent line valid
530  write_reg(mt, MT9F002_DATAPATH_SELECT , 0xd880, 2);
531  write_reg(mt, MT9F002_READ_MODE , 0x0041, 2);
532  write_reg(mt, MT9F002_X_ODD_INC , mt->x_odd_inc, 2);
533  write_reg(mt, MT9F002_Y_ODD_INC , mt->y_odd_inc, 2);
534  write_reg(mt, MT9F002_MASK_CORRUPTED_FRAMES , 0x0001, 1); // 0 output corrupted frame, 1 mask them
535 }
536 
540 static inline void mt9f002_set_pll(struct mt9f002_t *mt)
541 {
542  // Update registers
549 
550  uint16_t smia = read_reg(mt, MT9F002_SMIA_TEST, 2);
551  write_reg(mt, MT9F002_SMIA_TEST, (smia & 0xFFBF) | (mt->shift_vt_pix_clk_div << 6), 2); // shift_vt_pix_clk_div
552 
553  uint16_t row_speed = read_reg(mt, MT9F002_ROW_SPEED, 2);
554  row_speed = (row_speed & 0xFFF8) | (mt->rowSpeed_2_0 & 0x07); // rowSpeed_2_0
555  row_speed = (row_speed & 0xF8FF) | ((mt->row_speed_10_8 & 0x07) << 8); // row_speed_10_8
556  row_speed = (row_speed & (~0x70)) | (0x2 << 4); // Change opclk_delay
557  write_reg(mt, MT9F002_ROW_SPEED, row_speed, 2);
558 
559  // Compute clocks
560  mt->vt_pix_clk = mt->input_clk_freq * (float)mt->pll_multiplier * (float)(1 + mt->shift_vt_pix_clk_div)
561  / ((float)mt->pre_pll_clk_div * (float)mt->vt_sys_clk_div * (float)mt->vt_pix_clk_div);
562  mt->op_pix_clk = mt->input_clk_freq * (float)mt->pll_multiplier
563  / ((float)mt->pre_pll_clk_div * (float)mt->op_sys_clk_div * (float)mt->op_pix_clk_div);
564 }
565 
570 static void mt9f002_set_blanking(struct mt9f002_t *mt)
571 {
572  /* Read some config values in order to calculate blanking configuration */
573  uint16_t min_line_blanking_pck = read_reg(mt, MT9F002_MIN_LINE_BLANKING_PCK, 2);
574  uint16_t x_odd_inc = read_reg(mt, MT9F002_X_ODD_INC, 2);
575  uint16_t min_frame_blanking_lines = read_reg(mt, MT9F002_MIN_FRAME_BLANKING_LINES, 2);
576  uint16_t min_line_length_pck = read_reg(mt, MT9F002_MIN_LINE_LENGTH_PCK, 2);
577 
578  /* Calculate minimum line length */
579  float subsampling_factor = (float)(1 + x_odd_inc) / 2.0f; // See page 52
580  uint16_t min_line_length = Max(min_line_length_pck,
581  mt->scaled_width / subsampling_factor + min_line_blanking_pck); // EQ 9
582  min_line_length = Max(min_line_length,
583  (mt->scaled_width - 1 + x_odd_inc) / subsampling_factor / 2 + min_line_blanking_pck);
584  if (mt->interface == MT9F002_MIPI ||
585  mt->interface == MT9F002_HiSPi) {
586  min_line_length = Max(min_line_length,
587  ((uint16_t)((float)mt->scaled_width * mt->vt_pix_clk / mt->op_pix_clk) / 2) + 0x005E); // 2 lanes, pll clocks
588  } else {
589  min_line_length = Max(min_line_length,
590  ((uint16_t)((float)mt->scaled_width * mt->vt_pix_clk / mt->op_pix_clk)) + 0x005E); // pll clocks
591  }
592 
593  /* Do some magic to get it to work with P7 ISP (with horizontal blanking) */
594  uint32_t clkRatio_num = mt->op_sys_clk_div * mt->op_pix_clk_div * mt->row_speed_10_8 * (1 + mt->shift_vt_pix_clk_div);
595  uint32_t clkRatio_den = mt->vt_sys_clk_div * mt->vt_pix_clk_div;
596 
597  /* Divide by the GCD to find smallest ratio */
598  uint32_t clkRatio_gcd = int32_gcd(clkRatio_num, clkRatio_den);
599  clkRatio_num = clkRatio_num / clkRatio_gcd;
600  clkRatio_den = clkRatio_den / clkRatio_gcd;
601 
602  /* Calculate minimum horizontal blanking, since fpga line_length must be divisible by 2 */
603  uint32_t min_horizontal_blanking = clkRatio_num;
604  if ((clkRatio_den % 2) != 0) {
605  min_horizontal_blanking = 2 * clkRatio_num;
606  }
607 
608  /* Fix fpga correction based on min horizontal blanking */
609  if ((min_line_length % min_horizontal_blanking) != 0) {
610  min_line_length += min_horizontal_blanking - (min_line_length % min_horizontal_blanking);
611  }
612 
613  /* Calculate minimum frame length lines */
614  uint16_t min_frame_length = (mt->scaled_height) / subsampling_factor + min_frame_blanking_lines; // (EQ 10)
615 
616  /* Calculate FPS we get using these minimums (Maximum FPS) */
617  mt->line_length = min_line_length;
618  mt->frame_length = min_frame_length;
619  mt->real_fps = mt->vt_pix_clk * 1000000 / (float)(mt->line_length * mt->frame_length);
620 
621  /* Check if we need to downscale the FPS and bruteforce better solution */
622  if (mt->target_fps < mt->real_fps) {
623  float min_fps_err = fabs(mt->target_fps - mt->real_fps);
624  float new_fps = mt->real_fps;
625 
626  // Go through all possible line lengths
627  for (uint16_t ll = min_line_length; ll <= MT9F002_LINE_LENGTH_MAX; ll += min_horizontal_blanking) {
628  // Go through all possible frame lengths
629  for (uint16_t fl = min_frame_length; fl < MT9F002_FRAME_LENGTH_MAX; ++fl) {
630  new_fps = mt->vt_pix_clk * 1000000 / (float)(ll * fl);
631 
632  // Calculate FPS error and save if it is better
633  float fps_err = fabs(mt->target_fps - new_fps);
634  if (fps_err < min_fps_err) {
635  min_fps_err = fps_err;
636  mt->line_length = ll;
637  mt->frame_length = fl;
638  mt->real_fps = new_fps;
639  }
640 
641  // Stop searching if FPS is lower or equal
642  if (mt->target_fps > new_fps) {
643  break;
644  }
645  }
646 
647  // Calculate if next step is still needed (since we only need to go one step below target_fps)
648  new_fps = mt->vt_pix_clk * 1000000 / (float)(ll * min_frame_length);
649 
650  // Stop searching if FPS is lower or equal
651  if (mt->target_fps > new_fps) {
652  break;
653  }
654  }
655  }
656 
657  /* Actually set the calculated values */
660 }
661 
667 {
668  /* Fetch minimum and maximum integration times */
669  uint16_t coarse_integration_min = read_reg(mt, MT9F002_COARSE_INTEGRATION_TIME_MIN, 2);
670  uint16_t coarse_integration_max = mt->frame_length - read_reg(mt, MT9F002_COARSE_INTEGRATION_TIME_MAX_MARGIN, 2);
671  uint16_t fine_integration_min = read_reg(mt, MT9F002_FINE_INTEGRATION_TIME_MIN, 2);
672  uint16_t fine_integration_max = mt->line_length - read_reg(mt, MT9F002_FINE_INTEGRATION_TIME_MAX_MARGIN, 2);
673 
674  /* Compute fine and coarse integration time */
675  uint32_t integration = mt->target_exposure * mt->vt_pix_clk * 1000;
676  uint16_t coarse_integration = integration / mt->line_length;
677  uint16_t fine_integration = integration % mt->line_length;
678 
679  /* Make sure fine integration is inside bounds */
680  if (fine_integration_min > fine_integration || fine_integration > fine_integration_max) {
681  int32_t upper_coarse_integration = coarse_integration + 1;
682  int32_t upper_fine_integration = fine_integration_min;
683 
684  int32_t lower_coarse_integration = coarse_integration - 1;
685  int32_t lower_fine_integration = fine_integration_max;
686 
687  // Check if lower case is invalid (take upper coarse)
688  if (lower_coarse_integration < coarse_integration_min) {
689  coarse_integration = upper_coarse_integration;
690  fine_integration = upper_fine_integration;
691  }
692  // Check if upper case is invalid (take lower coarse)
693  else if (upper_coarse_integration > coarse_integration_max) {
694  coarse_integration = lower_coarse_integration;
695  fine_integration = lower_fine_integration;
696  }
697  // Both are good
698  else {
699  // Calculate error to decide which is better
700  int32_t upper_error = abs((mt->line_length * upper_coarse_integration + upper_fine_integration) - integration);
701  int32_t lower_error = abs((mt->line_length * lower_coarse_integration + lower_fine_integration) - integration);
702 
703  if (upper_error < lower_error) {
704  coarse_integration = upper_coarse_integration;
705  fine_integration = upper_fine_integration;
706  } else {
707  coarse_integration = lower_coarse_integration;
708  fine_integration = lower_fine_integration;
709  }
710  }
711  }
712 
713  /* Fix saturations */
714  Bound(fine_integration, fine_integration_min, fine_integration_max);
715  Bound(coarse_integration, coarse_integration_min, coarse_integration_max);
716 
717  /* Set the registers */
718  mt->real_exposure = (float)(coarse_integration * mt->line_length + fine_integration) / (mt->vt_pix_clk * 1000);
719  write_reg(mt, MT9F002_COARSE_INTEGRATION_TIME, coarse_integration, 2);
720  write_reg(mt, MT9F002_FINE_INTEGRATION_TIME_, fine_integration, 2);
721 }
722 
726 static uint16_t mt9f002_calc_gain(float gain)
727 {
728  // Check if gain is valid
729  if (gain < 1.0) {
730  gain = 1.0;
731  }
732 
733  // Calculation of colamp, analg3 and digital gain based on table 19 p56
734  uint8_t colamp_gain, analog_gain3, digital_gain;
735  if (gain < 1.50) {
736  // This is not recommended
737  colamp_gain = 0;
738  analog_gain3 = 0;
739  digital_gain = 1;
740  } else if (gain < 3.0) {
741  colamp_gain = 1;
742  analog_gain3 = 0;
743  digital_gain = 1;
744  } else if (gain < 6.0) {
745  colamp_gain = 2;
746  analog_gain3 = 0;
747  digital_gain = 1;
748  } else if (gain < 16.0) {
749  colamp_gain = 3;
750  analog_gain3 = 0;
751  digital_gain = 1;
752  } else if (gain < 32.0) {
753  colamp_gain = 3;
754  analog_gain3 = 0;
755  digital_gain = 2;
756  } else {
757  colamp_gain = 3;
758  analog_gain3 = 0;
759  digital_gain = 4;
760  }
761 
762  // Calculate gain 2 (fine gain)
763  uint16_t analog_gain2 = gain / (float)digital_gain / (float)(1 << colamp_gain) / (float)(1 << analog_gain3) * 64.0;
764  Bound(analog_gain2, 1, 127);
765 
766  return (analog_gain2 & 0x7F) | ((analog_gain3 & 0x7) << 7) | ((colamp_gain & 0x3) << 10) | ((digital_gain & 0xF) << 12);
767 }
768 
772 void mt9f002_set_gains(struct mt9f002_t *mt)
773 {
778 }
779 
781 {
782  /* Set output resolution */
785 
786  /* Set scaling */
787  if (mt->output_scaler < 0.125) {
788  mt->output_scaler = 0.125;
789  printf("[MT9F002] Warning, ouput_scaler too small, changing to %f\n", mt->output_scaler);
790  } else if (mt->output_scaler > 1.) {
791  mt->output_scaler = 1.;
792  printf("[MT9F002] Warning, ouput_scaler too small, changing to %f\n", mt->output_scaler);
793  }
794  uint16_t scaleFactor = ceil((float)MT9F002_SCALER_N / mt->output_scaler);
795  mt->output_scaler = (float)MT9F002_SCALER_N / scaleFactor;
796  int x_skip_factor = (mt->x_odd_inc + 1) / 2;
797  int y_skip_factor = (mt->y_odd_inc + 1) / 2;
798  mt->scaled_width = mt->output_width * x_skip_factor / mt->output_scaler + mt->x_odd_inc - 1;
799  mt->scaled_height = mt->output_height * y_skip_factor / mt->output_scaler + mt->y_odd_inc - 1;
800 
801  if (mt->scaled_width % (x_skip_factor * 8) != 0) {
802  mt->scaled_width = floor(mt->scaled_width / (x_skip_factor * 8)) * (x_skip_factor * 8);
803  printf("[MT9F002] Warning, scaled_width not a multiple of %i, changing to %i\n", 8 * x_skip_factor, mt->scaled_width);
804  }
805  if (mt->scaled_height % (y_skip_factor * 8) != 0) {
806  mt->scaled_height = floor(mt->scaled_height / (y_skip_factor * 8)) * (y_skip_factor * 8);
807  printf("[MT9F002] Warning, scaled_height not a multiple of %i, changing to %i\n", 8 * y_skip_factor, mt->scaled_height);
808  }
809  if (mt->output_scaler < 1.0) {
810  write_reg(mt, MT9F002_SCALING_MODE, 2, 2); // Vertical and horizontal scaling
811  write_reg(mt, MT9F002_SCALE_M, scaleFactor, 2);
812  }
813  printf("[MT9F002] OUTPUT_SIZE: (%i, %i)\tSCALED_SIZE: (%i, %i)\n", mt->output_width, mt->output_height,
814  mt->scaled_width,
815  mt->scaled_height);
816  /* bound offsets */
817  if (mt->offset_x * MT9F002_MAX_WIDTH + mt->scaled_width / 2 > MT9F002_MAX_WIDTH) {mt->offset_x = 1 - (float)mt->scaled_width / 2 / MT9F002_MAX_WIDTH;}
818  if (-mt->offset_x * MT9F002_MAX_WIDTH > mt->scaled_width) {mt->offset_x = -(float)mt->scaled_width / 2 / MT9F002_MAX_WIDTH;}
819 
820  if (mt->offset_y * MT9F002_MAX_HEIGHT + mt->scaled_height / 2 > MT9F002_MAX_HEIGHT) {mt->offset_y = 1 - (float)mt->scaled_height / 2 / MT9F002_MAX_HEIGHT;}
821  if (-mt->offset_y * MT9F002_MAX_HEIGHT > mt->scaled_height / 2) {mt->offset_y = -(float)mt->scaled_height / 2 / MT9F002_MAX_HEIGHT;}
822 
823  /* Set position (based on offset and subsample increment) */
824  uint16_t start_addr_x = (uint16_t)((MT9F002_MAX_WIDTH - mt->scaled_width) / 2 + mt->offset_x * MT9F002_MAX_WIDTH);
825  uint16_t start_addr_y = (uint16_t)((MT9F002_MAX_HEIGHT - mt->scaled_height) / 2 + mt->offset_y * MT9F002_MAX_HEIGHT);
826 
827  if (start_addr_x < 24) {
828  start_addr_x = 24;
829  printf("[MT9F002] Warning, offset_y too small with given output_scaler, changing to %i\n", start_addr_x);
830  }
831 
832  if (start_addr_x % (x_skip_factor * 8) != 0) {
833  start_addr_x = round(start_addr_x / (x_skip_factor * 8)) * (x_skip_factor * 8);
834  printf("[MT9F002] Warning, offset_x not a multiple of %i, changing to %i\n", 8 * x_skip_factor, start_addr_x);
835  }
836  if (start_addr_y % (y_skip_factor * 8) != 0) {
837  start_addr_y = round(start_addr_y / (y_skip_factor * 8)) * (y_skip_factor * 8);
838  printf("[MT9F002] Warning, offset_y not a multiple of %i, changing to %i\n", 8 * y_skip_factor, start_addr_y);
839  }
840  write_reg(mt, MT9F002_X_ADDR_START, start_addr_x, 2);
841  write_reg(mt, MT9F002_Y_ADDR_START, start_addr_y , 2);
842  uint16_t end_addr_x = start_addr_x + mt->scaled_width - 1;
843  uint16_t end_addr_y = start_addr_y + mt->scaled_height - 1;
844  write_reg(mt, MT9F002_X_ADDR_END, end_addr_x, 2);
845  write_reg(mt, MT9F002_Y_ADDR_END, end_addr_y, 2);
846 
847  // set statistics to correct values
852 
853  isp_config.statistics_yuv.window_pos_x.window_x_end = mt->scaled_width - 1;
854  isp_config.statistics_yuv.window_pos_y.window_y_end = mt->scaled_height - 1;
855  isp_config.statistics_yuv.increments_log2.x_log2_inc = log2(x_skip_factor);
856  isp_config.statistics_yuv.increments_log2.x_log2_inc = log2(y_skip_factor);
857 }
858 
863 void mt9f002_init(struct mt9f002_t *mt)
864 {
865  /* Reset the device */
866  //TODO???
867 
868  /* Setup i2c transaction */
870 
871  /* Software reset */
872  write_reg(mt, MT9F002_SOFTWARE_RESET, 0x1, 1);
873  usleep(1000000); // Wait for one second
874 
875  /* Based on the interface configure stage 1 */
876  if (mt->interface == MT9F002_MIPI || mt->interface == MT9F002_HiSPi) {
878  } else {
880  }
881 
882  /* Set the PLL based on Input clock and wanted clock frequency */
883  mt9f002_set_pll(mt);
884 
885  /* Based on the interface configure stage 2 */
886  if (mt->interface == MT9F002_MIPI || mt->interface == MT9F002_HiSPi) {
888  } else {
890  }
891 
893 
894  /* Update blanking (based on FPS) */
896 
897  /* Update exposure (based on target_exposure) */
899 
900  /* Update gains for the different pixel colors */
901  mt9f002_set_gains(mt);
902 
903  /* Based on the interface configure stage 3 */
904  if (mt->interface == MT9F002_MIPI || mt->interface == MT9F002_HiSPi) {
906  }
907 
908  /* Turn the stream on */
909  write_reg(mt, MT9F002_MODE_SELECT, 0x01, 1);
910 }
#define MT9F002_DAC_LD_30_31
Definition: mt9f002_regs.h:622
#define MT9F002_MFR_3E16
Definition: mt9f002_regs.h:521
#define MT9F002_MFR_3E04
Definition: mt9f002_regs.h:512
#define MT9F002_MFR_3E3E
Definition: mt9f002_regs.h:541
static void mt9f002_parallel_stage2(struct mt9f002_t *mt)
Configure stage 2 for parallel connection.
Definition: mt9f002.c:499
#define MT9F002_SOFTWARE_RESET
Definition: mt9f002_regs.h:54
unsigned short uint16_t
Definition: types.h:16
#define MT9F002_MFR_3D88
Definition: mt9f002_regs.h:450
#define MT9F002_MFR_3E4A
Definition: mt9f002_regs.h:547
#define MT9F002_MFR_3E26
Definition: mt9f002_regs.h:529
#define MT9F002_MFR_3E8A
Definition: mt9f002_regs.h:579
#define MT9F002_MFR_317C
Definition: mt9f002_regs.h:613
#define MT9F002_MFR_3E32
Definition: mt9f002_regs.h:535
#define MT9F002_MFR_3D3A
Definition: mt9f002_regs.h:411
#define MT9F002_MFR_3E8C
Definition: mt9f002_regs.h:580
#define MT9F002_FINE_INTEGRATION_TIME_MIN
Definition: mt9f002_regs.h:107
#define MT9F002_MFR_3D32
Definition: mt9f002_regs.h:407
#define MT9F002_X_ADDR_END
Definition: mt9f002_regs.h:82
#define MT9F002_CENTER_X
Definition: mt9f002.h:114
#define MT9F002_MFR_3D14
Definition: mt9f002_regs.h:392
#define MT9F002_MFR_3E66
Definition: mt9f002_regs.h:561
#define MT9F002_MFR_3DC8
Definition: mt9f002_regs.h:482
union avi_isp_statistics_yuv_increments_log2 increments_log2
#define MT9F002_MFR_3E0E
Definition: mt9f002_regs.h:517
#define MT9F002_MFR_3EC4
Definition: mt9f002_regs.h:608
#define MT9F002_MFR_3E94
Definition: mt9f002_regs.h:584
#define MT9F002_MFR_3D7C
Definition: mt9f002_regs.h:444
#define MT9F002_FINE_INTEGRATION_TIME_
Definition: mt9f002_regs.h:177
void mt9f002_set_exposure(struct mt9f002_t *mt)
Set the exposure configuration Depends on the blanking (and therefore the FPS)
Definition: mt9f002.c:666
#define MT9F002_MFR_3E7C
Definition: mt9f002_regs.h:572
#define MT9F002_MFR_3E8E
Definition: mt9f002_regs.h:581
#define MT9F002_MFR_3E1C
Definition: mt9f002_regs.h:524
#define MT9F002_MFR_3DC4
Definition: mt9f002_regs.h:480
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
#define MT9F002_MFR_3EB4
Definition: mt9f002_regs.h:600
#define MT9F002_LINE_LENGTH_PCK
Definition: mt9f002_regs.h:79
#define MT9F002_MFR_3EBC
Definition: mt9f002_regs.h:604
uint8_t x_odd_inc
X increment for subsampling (1,3,7,15,31 accepted)
Definition: mt9f002.h:166
#define MT9F002_MASK_CORRUPTED_FRAMES
Definition: mt9f002_regs.h:56
#define MT9F002_MFR_3E46
Definition: mt9f002_regs.h:545
#define MT9F002_CTX_WR_DATA_REG
Definition: mt9f002_regs.h:235
#define MT9F002_MFR_3EAE
Definition: mt9f002_regs.h:597
#define MT9F002_MFR_3E6A
Definition: mt9f002_regs.h:563
#define MT9F002_MIN_FRAME_BLANKING_LINES
Definition: mt9f002_regs.h:136
union avi_isp_statistics_bayer_window_y window_y
#define MT9F002_MFR_3E4C
Definition: mt9f002_regs.h:548
uint16_t output_height
Output height.
Definition: mt9f002.h:159
#define MT9F002_LINE_LENGTH_MAX
Definition: mt9f002_regs.h:7
uint16_t op_sys_clk_div
Fixed PLL config from calculator tool.
Definition: mt9f002.h:139
#define MT9F002_MFR_3D86
Definition: mt9f002_regs.h:449
struct img_size_t output_size
Output image size.
Definition: video_device.h:56
uint8_t rowSpeed_2_0
Fixed PLL config from calculator tool.
Definition: mt9f002.h:141
#define MT9F002_MFR_3DF8
Definition: mt9f002_regs.h:506
#define MT9F002_MFR_3EB8
Definition: mt9f002_regs.h:602
#define MT9F002_MFR_3D20
Definition: mt9f002_regs.h:398
#define MT9F002_MFR_3DB8
Definition: mt9f002_regs.h:474
#define MT9F002_OUTPUT_HEIGHT
Definition: mt9f002.h:35
uint16_t vt_pix_clk_div
Fixed PLL config from calculator tool.
Definition: mt9f002.h:134
#define MT9F002_MFR_3D46
Definition: mt9f002_regs.h:417
#define MT9F002_MFR_3DDA
Definition: mt9f002_regs.h:491
#define MT9F002_MFR_3DCC
Definition: mt9f002_regs.h:484
#define MT9F002_MFR_3D18
Definition: mt9f002_regs.h:394
#define MT9F002_MFR_3D2C
Definition: mt9f002_regs.h:404
#define MT9F002_DAC_LD_14_15
Definition: mt9f002_regs.h:619
#define MT9F002_MFR_3E7A
Definition: mt9f002_regs.h:571
#define MT9F002_MFR_3E72
Definition: mt9f002_regs.h:567
#define MT9F002_MFR_3DB0
Definition: mt9f002_regs.h:470
#define MT9F002_MFR_3D7A
Definition: mt9f002_regs.h:443
#define MT9F002_MFR_3D6A
Definition: mt9f002_regs.h:435
uint16_t pll_multiplier
Fixed PLL config from calculator tool.
Definition: mt9f002.h:137
#define MT9F002_SCALING_MODE
Definition: mt9f002_regs.h:90
#define MT9F002_MFR_3D9A
Definition: mt9f002_regs.h:459
#define MT9F002_MFR_3D38
Definition: mt9f002_regs.h:410
#define MT9F002_MFR_3EE6
Definition: mt9f002_regs.h:614
uint16_t scaled_width
Width after corrected scaling.
Definition: mt9f002.h:161
static void mt9f002_mipi_stage1(struct mt9f002_t *mt)
Configure stage 1 for both MiPi and HiSPi connection.
Definition: mt9f002.c:127
#define MT9F002_MFR_3DDE
Definition: mt9f002_regs.h:493
#define MT9F002_MFR_3E3C
Definition: mt9f002_regs.h:540
#define MT9F002_MFR_3DD6
Definition: mt9f002_regs.h:489
#define MT9F002_FINE_INTEGRATION_TIME_MAX_MARGIN
Definition: mt9f002_regs.h:108
void mt9f002_set_resolution(struct mt9f002_t *mt)
Definition: mt9f002.c:780
#define MT9F002_BLUE_GAIN
Definition: mt9f002_regs.h:205
#define MT9F002_CENTER_Y
Definition: mt9f002.h:117
#define MT9F002_MFR_3DA0
Definition: mt9f002_regs.h:462
#define MT9F002_X_ODD_INC
Definition: mt9f002_regs.h:87
#define MT9F002_MFR_3D64
Definition: mt9f002_regs.h:432
#define MT9F002_MFR_3D60
Definition: mt9f002_regs.h:430
#define MT9F002_MFR_3D4E
Definition: mt9f002_regs.h:421
#define MT9F002_MFR_3DAE
Definition: mt9f002_regs.h:469
#define MT9F002_MFR_3E28
Definition: mt9f002_regs.h:530
#define MT9F002_MFR_3E48
Definition: mt9f002_regs.h:546
#define MT9F002_MFR_3E38
Definition: mt9f002_regs.h:538
#define MT9F002_ADDRESS
Definition: mt9f002_regs.h:4
#define MT9F002_MFR_3D96
Definition: mt9f002_regs.h:457
#define MT9F002_MFR_3E6C
Definition: mt9f002_regs.h:564
#define MT9F002_COARSE_INTEGRATION_TIME_MIN
Definition: mt9f002_regs.h:105
#define MT9F002_DIGITAL_TEST
Definition: mt9f002_regs.h:226
#define MT9F002_MFR_3D24
Definition: mt9f002_regs.h:400
#define MT9F002_MFR_3DC0
Definition: mt9f002_regs.h:478
#define MT9F002_ANALOG_CONTROL4
Definition: mt9f002_regs.h:248
#define MT9F002_MFR_3E9C
Definition: mt9f002_regs.h:588
#define MT9F002_DAC_LD_28_29
Definition: mt9f002_regs.h:621
#define MT9F002_MFR_3E86
Definition: mt9f002_regs.h:577
static uint32_t read_reg(struct mt9f002_t *mt, uint16_t addr, uint8_t len)
Read multiple bytes from a register.
Definition: mt9f002.c:108
float gain_blue
Gain for the Blue pixels [1.5 -> 63.50].
Definition: mt9f002.h:154
#define MT9F002_READ_MODE
Definition: mt9f002_regs.h:201
#define MT9F002_CTX_CONTROL_REG
Definition: mt9f002_regs.h:234
#define MT9F002_MFR_3D7E
Definition: mt9f002_regs.h:445
#define MT9F002_MFR_3EE2
Definition: mt9f002_regs.h:617
#define MT9F002_MFR_3D1A
Definition: mt9f002_regs.h:395
#define MT9F002_MFR_3E5A
Definition: mt9f002_regs.h:555
#define MT9F002_MFR_3E92
Definition: mt9f002_regs.h:583
#define MT9F002_MFR_3DF4
Definition: mt9f002_regs.h:504
#define MT9F002_VT_PIX_CLK_DIV
Definition: mt9f002_regs.h:72
#define MT9F002_MFR_3D1C
Definition: mt9f002_regs.h:396
#define MT9F002_MFR_3DAC
Definition: mt9f002_regs.h:468
#define MT9F002_MFR_3DD4
Definition: mt9f002_regs.h:488
#define MT9F002_MFR_3E5E
Definition: mt9f002_regs.h:557
#define MT9F002_MFR_3EBA
Definition: mt9f002_regs.h:603
HiSPi type connection.
Definition: mt9f002.h:126
#define MT9F002_MFR_3DA6
Definition: mt9f002_regs.h:465
float offset_y
Offset from top in pixels.
Definition: mt9f002.h:164
#define MT9F002_MFR_3D44
Definition: mt9f002_regs.h:416
#define MT9F002_MFR_3E2C
Definition: mt9f002_regs.h:532
#define MT9F002_MFR_3E40
Definition: mt9f002_regs.h:542
uint8_t y_odd_inc
Y increment for subsampling (1,3,7 accepted)
Definition: mt9f002.h:167
uint16_t vt_sys_clk_div
Fixed PLL config from calculator tool.
Definition: mt9f002.h:135
#define MT9F002_MFR_3E62
Definition: mt9f002_regs.h:559
#define MT9F002_MFR_3E34
Definition: mt9f002_regs.h:536
#define MT9F002_MFR_3E54
Definition: mt9f002_regs.h:552
#define MT9F002_MFR_3E0A
Definition: mt9f002_regs.h:515
#define MT9F002_MFR_3D9E
Definition: mt9f002_regs.h:461
#define MT9F002_MFR_3D28
Definition: mt9f002_regs.h:402
#define MT9F002_OP_SYS_CLK_DIV
Definition: mt9f002_regs.h:77
#define MT9F002_SCALER_N
Definition: mt9f002_regs.h:6
#define MT9F002_MFR_3D0E
Definition: mt9f002_regs.h:389
union avi_isp_statistics_bayer_window_x window_x
#define MT9F002_DAC_LD_24_25
Definition: mt9f002_regs.h:620
#define MT9F002_MFR_3E64
Definition: mt9f002_regs.h:560
#define MT9F002_SERIAL_FORMAT
Definition: mt9f002_regs.h:258
bool i2c_blocking_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 and wait for it to complete.
Definition: i2c.c:337
#define MT9F002_MIN_LINE_LENGTH_PCK
Definition: mt9f002_regs.h:133
#define MT9F002_MFR_3EDC
Definition: mt9f002_regs.h:616
#define MT9F002_DATA_PEDESTAL_
Definition: mt9f002_regs.h:183
#define MT9F002_ANALOG_CONTROL5
Definition: mt9f002_regs.h:249
#define MT9F002_MFR_3E56
Definition: mt9f002_regs.h:553
void mt9f002_init(struct mt9f002_t *mt)
Initialisation of the Aptina MT9F002 CMOS sensor (front camera)
Definition: mt9f002.c:863
float offset_x
Offset from left in pixels.
Definition: mt9f002.h:163
#define MT9F002_MFR_3D48
Definition: mt9f002_regs.h:418
#define MT9F002_MFR_3DEC
Definition: mt9f002_regs.h:500
#define MT9F002_MFR_3D78
Definition: mt9f002_regs.h:442
#define MT9F002_MFR_3DFA
Definition: mt9f002_regs.h:507
#define MT9F002_MFR_3D8E
Definition: mt9f002_regs.h:453
struct libisp_config isp_config
Definition: libisp_config.c:4
#define MT9F002_Y_OUTPUT_SIZE
Definition: mt9f002_regs.h:85
#define MT9F002_MFR_3DC2
Definition: mt9f002_regs.h:479
#define MT9F002_MFR_3EC8
Definition: mt9f002_regs.h:610
#define MT9F002_MFR_3D40
Definition: mt9f002_regs.h:414
#define MT9F002_MFR_3DB6
Definition: mt9f002_regs.h:473
#define MT9F002_MFR_3D66
Definition: mt9f002_regs.h:433
float output_scaler
Output scale.
Definition: mt9f002.h:160
#define MT9F002_MFR_3E22
Definition: mt9f002_regs.h:527
uint8_t shift_vt_pix_clk_div
Fixed PLL config from calculator tool.
Definition: mt9f002.h:140
#define MT9F002_MFR_3E60
Definition: mt9f002_regs.h:558
#define MT9F002_FOCAL_Y
Definition: mt9f002.h:111
#define MT9F002_MFR_3D50
Definition: mt9f002_regs.h:422
#define MT9F002_MFR_3EB0
Definition: mt9f002_regs.h:598
#define MT9F002_COARSE_INTEGRATION_TIME
Definition: mt9f002_regs.h:62
#define MT9F002_MFR_3DA2
Definition: mt9f002_regs.h:463
uint8_t row_speed_10_8
Fixed PLL config from calculator tool.
Definition: mt9f002.h:142
#define MT9F002_MFR_3D94
Definition: mt9f002_regs.h:456
#define MT9F002_MFR_3E98
Definition: mt9f002_regs.h:586
#define MT9F002_MFR_3DFC
Definition: mt9f002_regs.h:508
#define MT9F002_MFR_3E2A
Definition: mt9f002_regs.h:531
#define MT9F002_MFR_3DA4
Definition: mt9f002_regs.h:464
transaction set to done by user level
Definition: i2c.h:59
#define MT9F002_MFR_3D4C
Definition: mt9f002_regs.h:420
enum mt9f002_interface interface
Interface used to connect.
Definition: mt9f002.h:132
#define MT9F002_MFR_3D52
Definition: mt9f002_regs.h:423
#define MT9F002_GREEN1_GAIN
Definition: mt9f002_regs.h:204
static void mt9f002_mipi_stage3(struct mt9f002_t *mt)
Configure stage 3 for both MiPi and HiSPi connection.
Definition: mt9f002.c:391
#define MT9F002_MFR_3DB4
Definition: mt9f002_regs.h:472
#define MT9F002_MFR_3D90
Definition: mt9f002_regs.h:454
#define MT9F002_MFR_3D98
Definition: mt9f002_regs.h:458
#define MT9F002_MFR_3DDC
Definition: mt9f002_regs.h:492
static uint16_t mt9f002_calc_gain(float gain)
Calculate the gain based on value of 1.0 -> 63.50.
Definition: mt9f002.c:726
uint16_t line_length
Calculated line length of blanking.
Definition: mt9f002.h:145
#define MT9F002_MFR_3D68
Definition: mt9f002_regs.h:434
#define MT9F002_DHANE_K
Definition: mt9f002.h:120
float real_fps
Real calculated FPS.
Definition: mt9f002.h:149
#define MT9F002_MFR_3E6E
Definition: mt9f002_regs.h:565
#define MT9F002_DATAPATH_SELECT
Definition: mt9f002_regs.h:211
#define MT9F002_RESET_REGISTER
Definition: mt9f002_regs.h:180
#define MT9F002_MFR_3DE6
Definition: mt9f002_regs.h:497
static void mt9f002_parallel_stage1(struct mt9f002_t *mt)
Configure stage 1 for parallel connection.
Definition: mt9f002.c:402
#define MT9F002_MFR_3E96
Definition: mt9f002_regs.h:585
#define MT9F002_MFR_3D3E
Definition: mt9f002_regs.h:413
#define MT9F002_MFR_3DBA
Definition: mt9f002_regs.h:475
#define MT9F002_MFR_3DB2
Definition: mt9f002_regs.h:471
uint16_t val[TCOUPLE_NB]
#define MT9F002_MFR_3E12
Definition: mt9f002_regs.h:519
#define MT9F002_MFR_3D62
Definition: mt9f002_regs.h:431
unsigned long uint32_t
Definition: types.h:18
static void mt9f002_set_pll(struct mt9f002_t *mt)
Set the PLL registers based on config.
Definition: mt9f002.c:540
#define MT9F002_MFR_3EA2
Definition: mt9f002_regs.h:591
#define MT9F002_MFR_3D8A
Definition: mt9f002_regs.h:451
float gain_green1
Gain for the GreenR pixels [1.5 -> 63.50].
Definition: mt9f002.h:153
#define MT9F002_ANALOG_CONTROL7
Definition: mt9f002_regs.h:250
uint16_t output_width
Output width.
Definition: mt9f002.h:158
#define MT9F002_MFR_3DFE
Definition: mt9f002_regs.h:509
#define MT9F002_MFR_3E24
Definition: mt9f002_regs.h:528
#define MT9F002_MFR_3DAA
Definition: mt9f002_regs.h:467
#define MT9F002_MFR_3E80
Definition: mt9f002_regs.h:574
#define MT9F002_MFR_3DE4
Definition: mt9f002_regs.h:496
#define MT9F002_MFR_3EB2
Definition: mt9f002_regs.h:599
#define MT9F002_MFR_3D12
Definition: mt9f002_regs.h:391
#define MT9F002_FRAME_LENGTH_LINES
Definition: mt9f002_regs.h:78
static void write_reg(struct mt9f002_t *mt, uint16_t addr, uint32_t val, uint8_t len)
Write multiple bytes to a single register.
Definition: mt9f002.c:81
#define MT9F002_MFR_3DE8
Definition: mt9f002_regs.h:498
#define MT9F002_SCALE_M
Definition: mt9f002_regs.h:92
#define MT9F002_MFR_3EB6
Definition: mt9f002_regs.h:601
#define MT9F002_MFR_3DEA
Definition: mt9f002_regs.h:499
#define MT9F002_MFR_3E90
Definition: mt9f002_regs.h:582
void mt9f002_set_gains(struct mt9f002_t *mt)
Sets the GreenR, Blue, Red and GreenB gains.
Definition: mt9f002.c:772
#define MT9F002_MFR_3E20
Definition: mt9f002_regs.h:526
float vt_pix_clk
Calculated based on PLL.
Definition: mt9f002.h:143
#define MT9F002_MFR_3E9A
Definition: mt9f002_regs.h:587
#define MT9F002_MFR_3E58
Definition: mt9f002_regs.h:554
#define MT9F002_MFR_3D26
Definition: mt9f002_regs.h:401
float target_fps
FPS wanted.
Definition: mt9f002.h:148
#define MT9F002_X_OUTPUT_SIZE
Definition: mt9f002_regs.h:84
#define MT9F002_COLUMN_CORRECTION
Definition: mt9f002_regs.h:233
#define MT9F002_MFR_3E76
Definition: mt9f002_regs.h:569
#define MT9F002_DARK_CONTROL3
Definition: mt9f002_regs.h:237
#define MT9F002_MFR_3EAA
Definition: mt9f002_regs.h:595
#define MT9F002_MFR_3D74
Definition: mt9f002_regs.h:440
#define MT9F002_Y_ADDR_END
Definition: mt9f002_regs.h:83
#define MT9F002_MFR_3D10
Definition: mt9f002_regs.h:390
#define MT9F002_MFR_3DBC
Definition: mt9f002_regs.h:476
#define MT9F002_EXTRA_DELAY
Definition: mt9f002_regs.h:179
#define MT9F002_MFR_3E08
Definition: mt9f002_regs.h:514
#define MT9F002_MFR_3E5C
Definition: mt9f002_regs.h:556
float gain_red
Gain for the Red pixels [1.5 -> 63.50].
Definition: mt9f002.h:155
#define MT9F002_MFR_3D84
Definition: mt9f002_regs.h:448
#define MT9F002_MFR_3D0C
Definition: mt9f002_regs.h:388
#define Max(x, y)
Definition: main_fbw.c:53
#define MT9F002_MFR_3D06
Definition: mt9f002_regs.h:385
#define MT9F002_MFR_3E0C
Definition: mt9f002_regs.h:516
#define MT9F002_OUTPUT_WIDTH
Definition: mt9f002.h:39
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
#define MT9F002_MFR_3DD2
Definition: mt9f002_regs.h:487
#define MT9F002_MFR_3E52
Definition: mt9f002_regs.h:551
#define MT9F002_MFR_3D1E
Definition: mt9f002_regs.h:397
#define MT9F002_MFR_3D58
Definition: mt9f002_regs.h:426
#define MT9F002_MAX_WIDTH
Definition: mt9f002.c:42
union avi_isp_statistics_yuv_window_pos_y window_pos_y
#define MT9F002_COARSE_INTEGRATION_TIME_MAX_MARGIN
Definition: mt9f002_regs.h:106
signed long int32_t
Definition: types.h:19
#define MT9F002_MFR_3EC6
Definition: mt9f002_regs.h:609
#define MT9F002_MFR_3D92
Definition: mt9f002_regs.h:455
#define MT9F002_MFR_3E3A
Definition: mt9f002_regs.h:539
#define MT9F002_MFR_3D4A
Definition: mt9f002_regs.h:419
struct i2c_periph * i2c_periph
I2C peripheral used to communicate over.
Definition: mt9f002.h:169
float gain_green2
Gain for the GreenB pixels [1.5 -> 63.50].
Definition: mt9f002.h:156
#define MT9F002_MFR_3D5C
Definition: mt9f002_regs.h:428
#define MT9F002_VT_SYS_CLK_DIV
Definition: mt9f002_regs.h:73
#define MT9F002_MFR_3DBE
Definition: mt9f002_regs.h:477
Initialization and configuration of the MT9F002 CMOS Chip.
#define MT9F002_MFR_3E50
Definition: mt9f002_regs.h:550
#define MT9F002_MODE_SELECT
Definition: mt9f002_regs.h:52
#define MT9F002_OP_PIX_CLK_DIV
Definition: mt9f002_regs.h:76
float real_exposure
Real exposure time in ms.
Definition: mt9f002.h:151
#define MT9F002_MFR_3D54
Definition: mt9f002_regs.h:424
#define MT9F002_MFR_3DE2
Definition: mt9f002_regs.h:495
#define MT9F002_MFR_3E18
Definition: mt9f002_regs.h:522
#define MT9F002_MFR_3E42
Definition: mt9f002_regs.h:543
#define MT9F002_GREEN2_GAIN
Definition: mt9f002_regs.h:207
#define MT9F002_MFR_3ECA
Definition: mt9f002_regs.h:611
#define MT9F002_SMIA_TEST
Definition: mt9f002_regs.h:209
#define MT9F002_MFR_3D8C
Definition: mt9f002_regs.h:452
#define MT9F002_MFR_3EC2
Definition: mt9f002_regs.h:607
struct i2c_transaction i2c_trans
I2C transaction for comminication with CMOS chip.
Definition: mt9f002.h:170
#define MT9F002_MFR_3E1A
Definition: mt9f002_regs.h:523
#define MT9F002_GLOBAL_GAIN
Definition: mt9f002_regs.h:208
#define MT9F002_MFR_3D04
Definition: mt9f002_regs.h:384
#define MT9F002_MFR_3E82
Definition: mt9f002_regs.h:575
#define MT9F002_MFR_3E44
Definition: mt9f002_regs.h:544
#define MT9F002_MFR_3E02
Definition: mt9f002_regs.h:511
#define VIDEO_FILTER_ISP
Enable ISP.
Definition: video_device.h:35
#define MT9F002_MFR_3ED8
Definition: mt9f002_regs.h:615
#define MT9F002_MFR_3DF0
Definition: mt9f002_regs.h:502
unsigned char uint8_t
Definition: types.h:14
#define MT9F002_Y_ADDR_START
Definition: mt9f002_regs.h:81
#define MT9F002_MFR_3D80
Definition: mt9f002_regs.h:446
#define MT9F002_MFR_3DC6
Definition: mt9f002_regs.h:481
#define MT9F002_MFR_3E74
Definition: mt9f002_regs.h:568
struct avi_isp_statistics_yuv_regs statistics_yuv
YUV statistics parameters.
Definition: libisp.h:86
#define MT9F002_MFR_3D6C
Definition: mt9f002_regs.h:436
#define MT9F002_MFR_3D56
Definition: mt9f002_regs.h:425
#define MT9F002_MFR_3D2E
Definition: mt9f002_regs.h:405
#define MT9F002_CPP_DATA_FORMAT
Definition: mt9f002_regs.h:59
#define MT9F002_MFR_3E10
Definition: mt9f002_regs.h:518
#define MT9F002_MFR_3E00
Definition: mt9f002_regs.h:510
#define MT9F002_MFR_3DD8
Definition: mt9f002_regs.h:490
#define MT9F002_MFR_3EAC
Definition: mt9f002_regs.h:596
#define MT9F002_MFR_3E36
Definition: mt9f002_regs.h:537
uint16_t op_pix_clk_div
Fixed PLL config from calculator tool.
Definition: mt9f002.h:138
#define MT9F002_MFR_3E70
Definition: mt9f002_regs.h:566
#define MT9F002_MFR_3EA4
Definition: mt9f002_regs.h:592
#define MT9F002_MFR_3EBE
Definition: mt9f002_regs.h:605
#define MT9F002_MFR_3D76
Definition: mt9f002_regs.h:441
#define MT9F002_MFR_3D16
Definition: mt9f002_regs.h:393
#define MT9F002_MFR_3EA0
Definition: mt9f002_regs.h:590
#define MT9F002_MFR_3E2E
Definition: mt9f002_regs.h:533
#define MT9F002_MFR_3D08
Definition: mt9f002_regs.h:386
#define MT9F002_MFR_3D5E
Definition: mt9f002_regs.h:429
#define MT9F002_PLL_MULTIPLIER
Definition: mt9f002_regs.h:75
#define MT9F002_MFR_3DF6
Definition: mt9f002_regs.h:505
struct avi_isp_statistics_bayer_regs statistics_bayer
Statistics bayer parameters.
Definition: libisp.h:69
#define MT9F002_MFR_3D42
Definition: mt9f002_regs.h:415
float op_pix_clk
Calculated based on PLL.
Definition: mt9f002.h:144
#define MT9F002_MFR_3E4E
Definition: mt9f002_regs.h:549
#define MT9F002_Y_ODD_INC
Definition: mt9f002_regs.h:89
#define MT9F002_MFR_3176
Definition: mt9f002_regs.h:612
uint16_t pre_pll_clk_div
Fixed PLL config from calculator tool.
Definition: mt9f002.h:136
#define MT9F002_MFR_3DEE
Definition: mt9f002_regs.h:501
#define MT9F002_MFR_3D30
Definition: mt9f002_regs.h:406
#define MT9F002_MFR_3EC0
Definition: mt9f002_regs.h:606
#define MT9F002_MFR_3E68
Definition: mt9f002_regs.h:562
#define MT9F002_MFR_3DCA
Definition: mt9f002_regs.h:483
#define MT9F002_MFR_3D70
Definition: mt9f002_regs.h:438
#define MT9F002_RED_GAIN
Definition: mt9f002_regs.h:206
#define MT9F002_MFR_3D00
Definition: mt9f002_regs.h:382
static void mt9f002_set_blanking(struct mt9f002_t *mt)
Set the blanking configuration Blanking of the MT9F002 depends on the target FPS. ...
Definition: mt9f002.c:570
#define MT9F002_MFR_3EE8
Definition: mt9f002_regs.h:618
#define MT9F002_MFR_3D3C
Definition: mt9f002_regs.h:412
#define MT9F002_MFR_3EA6
Definition: mt9f002_regs.h:593
#define MT9F002_MFR_3D0A
Definition: mt9f002_regs.h:387
#define MT9F002_MFR_3DF2
Definition: mt9f002_regs.h:503
#define MT9F002_FRAME_LENGTH_MAX
Definition: mt9f002_regs.h:8
#define MT9F002_MFR_3E78
Definition: mt9f002_regs.h:570
#define MT9F002_MFR_3E1E
Definition: mt9f002_regs.h:525
#define MT9F002_MFR_3DE0
Definition: mt9f002_regs.h:494
uint16_t scaled_height
Height after corrected scaling.
Definition: mt9f002.h:162
#define MT9F002_MFR_3E7E
Definition: mt9f002_regs.h:573
#define MT9F002_MFR_3E88
Definition: mt9f002_regs.h:578
#define MT9F002_MFR_3D5A
Definition: mt9f002_regs.h:427
union avi_isp_statistics_yuv_window_pos_x window_pos_x
uint32_t int32_gcd(uint32_t a, uint32_t b)
#define MT9F002_MFR_3D82
Definition: mt9f002_regs.h:447
uint16_t w
The width.
Definition: image.h:75
#define MT9F002_MFR_3E84
Definition: mt9f002_regs.h:576
#define MT9F002_TARGET_FPS
Definition: mt9f002.h:75
static void mt9f002_mipi_stage2(struct mt9f002_t *mt)
Configure stage 2 for both MiPi and HiSPi connection.
Definition: mt9f002.c:383
#define BAYERSTATS_STATY
Definition: libisp.h:8
#define MT9F002_MFR_3D72
Definition: mt9f002_regs.h:439
#define MT9F002_MFR_3D22
Definition: mt9f002_regs.h:399
#define MT9F002_MFR_3DCE
Definition: mt9f002_regs.h:485
#define MT9F002_PRE_PLL_CLK_DIV
Definition: mt9f002_regs.h:74
#define MT9F002_MFR_3D36
Definition: mt9f002_regs.h:409
#define MT9F002_MFR_3E06
Definition: mt9f002_regs.h:513
#define MT9F002_MIN_LINE_BLANKING_PCK
Definition: mt9f002_regs.h:135
#define MT9F002_MFR_3D2A
Definition: mt9f002_regs.h:403
#define MT9F002_FOCAL_X
Definition: mt9f002.h:108
#define MT9F002_X_ADDR_START
Definition: mt9f002_regs.h:80
#define MT9F002_MAX_HEIGHT
Definition: mt9f002.c:43
#define MT9F002_ROW_SPEED
Definition: mt9f002_regs.h:178
#define MT9F002_MFR_3E9E
Definition: mt9f002_regs.h:589
V4L2 device settings.
Definition: video_device.h:55
uint16_t frame_length
Calculated frame length of blanking.
Definition: mt9f002.h:146
float input_clk_freq
Input clock frequency.
Definition: mt9f002.h:133
#define MT9F002_MFR_3D34
Definition: mt9f002_regs.h:408
MIPI type connection.
Definition: mt9f002.h:125
#define MT9F002_MFR_3DA8
Definition: mt9f002_regs.h:466
#define MT9F002_MFR_3D02
Definition: mt9f002_regs.h:383
float target_exposure
Target exposure time in ms.
Definition: mt9f002.h:150
#define MT9F002_MFR_3E14
Definition: mt9f002_regs.h:520
bool i2c_blocking_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction and wait for it to complete.
Definition: i2c.c:295
Paparazzi fixed point algebra.
#define MT9F002_MFR_3EA8
Definition: mt9f002_regs.h:594
#define MT9F002_MFR_3D6E
Definition: mt9f002_regs.h:437
#define MT9F002_MFR_3E30
Definition: mt9f002_regs.h:534
#define MT9F002_MFR_3D9C
Definition: mt9f002_regs.h:460
struct video_config_t front_camera
Definition: mt9f002.c:46
#define BAYERSTATS_STATX
Definition: libisp.h:7
#define MT9F002_MFR_3DD0
Definition: mt9f002_regs.h:486