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