/ components / micropython / port / src / omv / mt9d111.c
mt9d111.c
  1  /* Copyright 2018 Canaan Inc.
  2   *
  3   * Licensed under the Apache License, Version 2.0 (the "License");
  4   * you may not use this file except in compliance with the License.
  5   * You may obtain a copy of the License at
  6   *
  7   *     http://www.apache.org/licenses/LICENSE-2.0
  8   *
  9   * Unless required by applicable law or agreed to in writing, software
 10   * distributed under the License is distributed on an "AS IS" BASIS},
 11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   * See the License for the specific language governing permissions and
 13   * limitations under the License.
 14   */
 15  #include <stdio.h>
 16  #include "mt9d111.h"
 17  #include "dvp.h"
 18  #include "plic.h"
 19  #include "sleep.h"
 20  #include "sensor.h"
 21  #include "mphalport.h"
 22  #include "cambus.h"
 23  #include "printf.h"
 24  
 25  static i2c_device_number_t i2c_dev_tmp = -2; // i2c_device_number_t components/micropython/port/src/omv/cambus.c
 26  
 27  /**
 28   * \brief Struct to store an register address and its value.
 29   */
 30  struct Register
 31  {
 32      uint8_t     address;    /**< struct Register address. */
 33      uint16_t    value;      /**< struct Register value. */
 34  };
 35  
 36  /**
 37   * \brief Default registers values (Values after boot).
 38   */
 39  const struct Register reg_default_vals[] = 
 40  {
 41      {MT9D111_REG_ROW_START,                                 0x001C},
 42      {MT9D111_REG_COLUMN_START,                              0x003C},
 43      {MT9D111_REG_ROW_WIDTH,                                 0x04B0},
 44      {MT9D111_REG_COL_WIDTH,                                 0x0640},
 45      {MT9D111_REG_HORIZONTAL_BLANKING_B,                     0x0204},
 46      {MT9D111_REG_VERTICAL_BLANKING_B,                       0x002F},
 47      {MT9D111_REG_HORIZONTAL_BLANKING_A,                     0x00FE},
 48      {MT9D111_REG_VERTICAL_BLANKING_A,                       0x000C},
 49      {MT9D111_REG_SHUTTER_WIDTH,                             0x04D0},
 50      {MT9D111_REG_ROW_SPEED,                                 0x0001},
 51      {MT9D111_REG_EXTRA_DELAY,                               0x0000},
 52      {MT9D111_REG_SHUTTER_DELAY,                             0x0000},
 53      {MT9D111_REG_RESET,                                     0x0000},
 54      {MT9D111_REG_FRAME_VALID_CONTROL,                       0x0000},
 55      {MT9D111_REG_READ_MODE_B,                               0x0300},
 56      {MT9D111_REG_READ_MODE_A,                               0x8400},
 57      {MT9D111_REG_DARK_COL_ROWS,                             0x010F},
 58      {MT9D111_REG_FLASH,                                     0x0608},
 59      {MT9D111_REG_EXTRA_RESET,                               0x8000},
 60      {MT9D111_REG_LINE_VALID_CONTROL,                        0x0000},
 61      {MT9D111_REG_BOTTOM_DARK_ROWS,                          0x0007},
 62      {MT9D111_REG_GREEN_1_GAIN,                              0x0020},
 63      {MT9D111_REG_BLUE_GAIN,                                 0x0020},
 64      {MT9D111_REG_RED_GAIN,                                  0x0020},
 65      {MT9D111_REG_GREEN_2_GAIN,                              0x0020},
 66      {MT9D111_REG_GLOBAL_GAIN,                               0x0020},
 67      {MT9D111_REG_ROW_NOISE,                                 0x042A},
 68      {MT9D111_REG_BLACK_ROWS,                                0x00FF},
 69      {MT9D111_REG_DARK_G1_AVERAGE,                           0x0000},
 70      {MT9D111_REG_DARK_B_AVERAGE,                            0x0000},
 71      {MT9D111_REG_DARK_R_AVERAGE,                            0x0000},
 72      {MT9D111_REG_DARK_G2_AVERAGE,                           0x0000},
 73      {MT9D111_REG_CALIB_THRESHOLD,                           0x231D},
 74      {MT9D111_REG_CALIB_CONTROL,                             0x0080},
 75      {MT9D111_REG_CALIB_GREEN_1,                             0x0000},
 76      {MT9D111_REG_CALIB_BLUE,                                0x0000},
 77      {MT9D111_REG_CALIB_RED,                                 0x0000},
 78      {MT9D111_REG_CALIB_GREEN_2,                             0x0000},
 79      {MT9D111_REG_CLOCK_CONTROL,                             0xE000},
 80      {MT9D111_REG_PLL_CONTROL_1,                             0x1000},
 81      {MT9D111_REG_PLL_CONTROL_2,                             0x0500},
 82      {MT9D111_REG_GLOBAL_SHUTTER_CONTROL,                    0x0000},
 83      {MT9D111_REG_START_INTEGRATION_T1,                      0x0064},
 84      {MT9D111_REG_START_READOUT_T2,                          0x0064},
 85      {MT9D111_REG_ASSERT_STROBE_T3,                          0x0096},
 86      {MT9D111_REG_DEASSERT_STROBE_T4,                        0x00C8},
 87      {MT9D111_REG_ASSERT_FLASH,                              0x0064},
 88      {MT9D111_REG_DEASSERT_FLASH,                            0x0078},
 89      {MT9D111_REG_EXTERNAL_SAMPLE_1,                         0x0000},
 90      {MT9D111_REG_EXTERNAL_SAMPLE_2,                         0x0000},
 91      {MT9D111_REG_EXTERNAL_SAMPLE_3,                         0x0000},
 92      {MT9D111_REG_EXTERNAL_SAMPLING_CONTROL,                 0x0000},
 93      {MT9D111_REG_PAGE_REGISTER,                             0x0000},
 94      {MT9D111_REG_BYTEWISE_ADDRESS,                          0x0000},
 95      {MT9D111_REG_CONTEXT_CONTROL,                           0x0000}
 96  };
 97  
 98  /**
 99   * \brief QVGA (320x240) at 30 FPS.
100   *
101   * \see https://github.com/ArduCAM/Arduino/blob/master/ArduCAM/mt9d111_regs.h
102   */
103  const struct Register reg_vals_qvga_30fps[] =
104  {
105      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
106      {0x33                                                               ,   0x0343},    // RESERVED_CORE_33
107  
108      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_1},
109      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA115},    // SEQ_LLMODE
110      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0020},    // SEQ_LLMODE
111  
112      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
113      {0x38                                                               ,   0x0866},    // RESERVED_CORE_38
114  
115      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_2},
116      {MT9D111_REG_LENS_CORRECTION_CONTROL                                ,   0x0168},    // LENS_CORRECTION_CONTROL
117      {MT9D111_REG_ZONE_BOUNDARIES_X1_AND_X2                              ,   0x6432},    // ZONE_BOUNDS_X1_X2
118      {MT9D111_REG_ZONE_BOUNDARIES_X0_AND_X3                              ,   0x3296},    // ZONE_BOUNDS_X0_X3
119      {MT9D111_REG_ZONE_BOUNDARIES_X4_AND_X5                              ,   0x9664},    // ZONE_BOUNDS_X4_X5
120      {MT9D111_REG_ZONE_BOUNDARIES_Y1_AND_Y2                              ,   0x5028},    // ZONE_BOUNDS_Y1_Y2
121      {MT9D111_REG_ZONE_BOUNDARIES_Y0_AND_Y3                              ,   0x2878},    // ZONE_BOUNDS_Y0_Y3
122      {MT9D111_REG_ZONE_BOUNDARIES_Y4_AND_Y5                              ,   0x7850},    // ZONE_BOUNDS_Y4_Y5
123      {MT9D111_REG_CENTER_OFFSET                                          ,   0x0000},    // CENTER_OFFSET
124      {MT9D111_REG_FX_FOR_RED_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY       ,   0x0152},    // FX_RED
125      {MT9D111_REG_FX_FOR_GREEN_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY     ,   0x015C},    // FX_GREEN
126      {MT9D111_REG_FX_FOR_BLUE_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY      ,   0x00F4},    // FX_BLUE
127      {MT9D111_REG_FY_FOR_RED_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY       ,   0x0108},    // FY_RED
128      {MT9D111_REG_FY_FOR_GREEN_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY     ,   0x00FA},    // FY_GREEN
129      {MT9D111_REG_FY_FOR_BLUE_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY      ,   0x00CF},    // FY_BLUE
130      {MT9D111_REG_DF_DX_FOR_RED_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY    ,   0x09AD},    // DF_DX_RED
131      {MT9D111_REG_DF_DX_FOR_GREEN_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY  ,   0x091E},    // DF_DX_GREEN
132      {MT9D111_REG_DF_DX_FOR_BLUE_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY   ,   0x0B3F},    // DF_DX_BLUE
133      {MT9D111_REG_DF_DY_FOR_RED_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY    ,   0x0C85},    // DF_DY_RED
134      {MT9D111_REG_DF_DY_FOR_GREEN_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY  ,   0x0CFF},    // DF_DY_GREEN
135      {MT9D111_REG_DF_DY_FOR_BLUE_COLOR_AT_THE_FIRST_PIXEL_OF_THE_ARRAY   ,   0x0D86},    // DF_DY_BLUE
136      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_0_RED_COLOR                 ,   0x163A},    // SECOND_DERIV_ZONE_0_RED
137      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_0_GREEN_COLOR               ,   0x0E47},    // SECOND_DERIV_ZONE_0_GREEN
138      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_0_BLUE_COLOR                ,   0x103C},    // SECOND_DERIV_ZONE_0_BLUE
139      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_1_RED_COLOR                 ,   0x1D35},    // SECOND_DERIV_ZONE_1_RED
140      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_1_GREEN_COLOR               ,   0x173E},    // SECOND_DERIV_ZONE_1_GREEN
141      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_1_BLUE_COLOR                ,   0x1119},    // SECOND_DERIV_ZONE_1_BLUE
142      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_2_RED_COLOR                 ,   0x1663},    // SECOND_DERIV_ZONE_2_RED
143      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_2_GREEN_COLOR               ,   0x1569},    // SECOND_DERIV_ZONE_2_GREEN
144      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_2_BLUE_COLOR                ,   0x104C},    // SECOND_DERIV_ZONE_2_BLUE
145      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_3_RED_COLOR                 ,   0x1015},    // SECOND_DERIV_ZONE_3_RED
146      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_3_GREEN_COLOR               ,   0x1010},    // SECOND_DERIV_ZONE_3_GREEN
147      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_3_BLUE_COLOR                ,   0x0B0A},    // SECOND_DERIV_ZONE_3_BLUE
148      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_4_RED_COLOR                 ,   0x0D53},    // SECOND_DERIV_ZONE_4_RED
149      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_4_GREEN_COLOR               ,   0x0D51},    // SECOND_DERIV_ZONE_4_GREEN
150      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_4_BLUE_COLOR                ,   0x0A44},    // SECOND_DERIV_ZONE_4_BLUE
151      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_5_RED_COLOR                 ,   0x1545},    // SECOND_DERIV_ZONE_5_RED
152      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_5_GREEN_COLOR               ,   0x1643},    // SECOND_DERIV_ZONE_5_GREEN
153      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_5_BLUE_COLOR                ,   0x1231},    // SECOND_DERIV_ZONE_5_BLUE
154      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_6_RED_COLOR                 ,   0x0047},    // SECOND_DERIV_ZONE_6_RED
155      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_6_GREEN_COLOR               ,   0x035C},    // SECOND_DERIV_ZONE_6_GREEN
156      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_6_BLUE_COLOR                ,   0xFE30},    // SECOND_DERIV_ZONE_6_BLUE
157      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_7_RED_COLOR                 ,   0x4625},    // SECOND_DERIV_ZONE_7_RED
158      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_7_GREEN_COLOR               ,   0x47F3},    // SECOND_DERIV_ZONE_7_GREEN
159      {MT9D111_REG_SECOND_DERIVATIVE_FOR_ZONE_7_BLUE_COLOR                ,   0x5859},    // SECOND_DERIV_ZONE_7_BLUE
160      {MT9D111_REG_X2_FACTORS                                             ,   0x0000},    // X2_FACTORS
161      {MT9D111_REG_GLOBAL_OFFSET_OF_FXY_FUNCTION                          ,   0x0000},    // GLOBAL_OFFSET_FXY_FUNCTION
162      {MT9D111_REG_K_FACTOR_IN_K_FX_FY                                    ,   0x0000},    // K_FACTOR_IN_K_FX_FY
163  
164      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_1},
165      {MT9D111_REG_COLOR_PIPELINE_CONTROL                                 ,   0x01FC},    // COLOR_PIPELINE_CONTROL
166  
167      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_1},
168      {MT9D111_REG_YUV_YCbCr_CONTROL                                      ,   0x0004},    // YUV_YCBCR_CONTROL
169  
170      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
171      {MT9D111_REG_CLOCK_CONTROL                                          ,   0xA000},    // CLOCK_ENABLING
172  
173      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_1},
174      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA102},    // SEQ_MODE
175      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x001F},    // SEQ_MODE
176      {MT9D111_REG_COLOR_PIPELINE_CONTROL                                 ,   0x01FC},    // COLOR_PIPELINE_CONTROL
177      {MT9D111_REG_COLOR_PIPELINE_CONTROL                                 ,   0x01EC},    // COLOR_PIPELINE_CONTROL
178      {MT9D111_REG_COLOR_PIPELINE_CONTROL                                 ,   0x01FC},    // COLOR_PIPELINE_CONTROL
179      {MT9D111_REG_2D_APERTURE_CORRECTION_PARAMETERS                      ,   0x0F08},    // APERTURE_PARAMETERS
180      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x270B},    // MODE_CONFIG
181      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0030},    // MODE_CONFIG, JPEG disabled for A and B
182      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA121},    // SEQ_CAP_MODE
183      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x007F},    // SEQ_CAP_MODE (127 frames before switching to Preview)
184  
185      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
186      {MT9D111_REG_HORIZONTAL_BLANKING_B                                  ,   0x00ED},    // HORZ_BLANK_B
187      {MT9D111_REG_VERTICAL_BLANKING_B                                    ,   0x000B},    // VERT_BLANK_B
188      {MT9D111_REG_HORIZONTAL_BLANKING_A                                  ,   0x0193},    // HORZ_BLANK_A
189      {MT9D111_REG_VERTICAL_BLANKING_A                                    ,   0x000B},    // VERT_BLANK_A
190      {MT9D111_REG_READ_MODE_B                                            ,   0x0700},    // READ_MODE_B (Image flip settings)
191      {MT9D111_REG_READ_MODE_A                                            ,   0x8400},    // READ_MODE_A (1ADC)
192  
193      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_1},
194      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2717},    // MODE_SENSOR_X_DELAY_A
195      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0187},    // MODE_SENSOR_X_DELAY_A
196      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x270F},    // MODE_SENSOR_ROW_START_A
197      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x001C},    // MODE_SENSOR_ROW_START_A
198      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2711},    // MODE_SENSOR_COL_START_A
199      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x003C},    // MODE_SENSOR_COL_START_A
200      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2713},    // MODE_SENSOR_ROW_HEIGHT_A
201      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x04B0},    // MODE_SENSOR_ROW_HEIGHT_A
202      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2715},    // MODE_SENSOR_COL_WIDTH_A
203      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0640},    // MODE_SENSOR_COL_WIDTH_A
204      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2719},    // MODE_SENSOR_ROW_SPEED_A
205      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0011},    // MODE_SENSOR_ROW_SPEED_A
206      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2707},    // MODE_OUTPUT_WIDTH_B
207      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0640},    // MODE_OUTPUT_WIDTH_B
208      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2709},    // MODE_OUTPUT_HEIGHT_B
209      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x04B0},    // MODE_OUTPUT_HEIGHT_B
210      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x271B},    // MODE_SENSOR_ROW_START_B
211      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x001C},    // MODE_SENSOR_ROW_START_B
212      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x271D},    // MODE_SENSOR_COL_START_B
213      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x003C},    // MODE_SENSOR_COL_START_B
214      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x271F},    // MODE_SENSOR_ROW_HEIGHT_B
215      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x04B0},    // MODE_SENSOR_ROW_HEIGHT_B
216      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2721},    // MODE_SENSOR_COL_WIDTH_B
217      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0640},    // MODE_SENSOR_COL_WIDTH_B
218      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2723},    // MODE_SENSOR_X_DELAY_B
219      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x03B1},    // MODE_SENSOR_X_DELAY_B
220      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2725},    // MODE_SENSOR_ROW_SPEED_B
221      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0011},    // MODE_SENSOR_ROW_SPEED_B
222  
223      // Maximum Slew-Rate on IO-Pads (for Mode A)
224      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x276B},    // MODE_FIFO_CONF0_A
225      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0027},    // MODE_FIFO_CONF0_A
226      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x276D},    // MODE_FIFO_CONF1_A
227      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0xE0E2},    // MODE_FIFO_CONF1_A
228      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA76F},    // MODE_FIFO_CONF2_A
229      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x00E1},    // MODE_FIFO_CONF2_A
230  
231      // Maximum Slew-Rate on IO-Pads (for Mode B)
232      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2772},    // MODE_FIFO_CONF0_B
233      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0027},    // MODE_FIFO_CONF0_B
234      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2774},    // MODE_FIFO_CONF1_B
235      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0xE0E1},    // MODE_FIFO_CONF1_B
236      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA776},    // MODE_FIFO_CONF2_B
237      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x00E1},    // MODE_FIFO_CONF2_B
238  
239      // Set maximum integration time to get a minimum of 15 fps at 45MHz
240      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA20E},    // AE_MAX_INDEX
241      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0004},    // AE_MAX_INDEX
242  
243      // Set minimum integration time to get a maximum of 15 fps at 45MHz
244      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA20D},    // AE_MAX_INDEX
245      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0004},    // AE_MAX_INDEX
246  
247      // Configue all GPIO for output and set low to save power
248      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x9078},
249      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0000},
250      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x9079},
251      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0000},
252      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x9070},
253      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0000},
254      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x9071},
255      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0000},
256  
257      // Gamma and contrast
258      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA743},    // MODE_GAM_CONT_A
259      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0003},    // MODE_GAM_CONT_A
260      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA744},    // MODE_GAM_CONT_B
261      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0003},    // MODE_GAM_CONT_B
262  
263      // Set PLL (MCLK = 19 MHz , PCLK = 79 MHz)
264      // Set PLL (MCLK = 45 MHz , PCLK = 45 MHz)  -> From Wizard
265      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
266      {MT9D111_REG_CONTEXT_CONTROL                                        ,   0x0000},
267  
268      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
269  
270      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_1},
271      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2735},    // MODE_CROP_X0_A
272      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0000},    // MODE_CROP_X0_A
273      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2737},    // MODE_CROP_X1_A
274      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   1600},      // MODE_CROP_X1_A
275      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x2739},    // MODE_CROP_Y0_A
276      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0000},    // MODE_CROP_Y0_A
277      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0x273B},    // MODE_CROP_Y1_A
278      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   1200},      // MODE_CROP_Y1_A
279      {MT9D111_REG_MICROCONTROLLER_VARIABLE_ADDRESS                       ,   0xA103},    // SEQ_CMD, Do capture
280      {MT9D111_REG_MICROCONTROLLER_VARIABLE_DATA                          ,   0x0005},
281  
282      {MT9D111_REG_PAGE_REGISTER                                          ,   MT9D111_REG_PAGE_0},
283  };
284  
285  static int mt9d111_read_reg(sensor_t *sensor, uint8_t reg_addr)
286  {
287      printk("%s sensor %p\r\n", __func__, sensor);
288      return 0;
289  }
290  
291  static int mt9d111_write_reg(sensor_t *sensor, uint8_t reg_addr, uint16_t reg_data)
292  {
293      printk("%s sensor %p\r\n", __func__, sensor);
294      return 0;
295  }
296  
297  static int mt9d111_set_pixformat(sensor_t *sensor, pixformat_t pixformat)
298  {
299      printk("%s sensor %p\r\n", __func__, sensor);
300      return 0;
301  }
302  
303  static int mt9d111_set_framesize(sensor_t *sensor, framesize_t framesize)
304  {
305      printk("%s sensor %p framesize %d\r\n", __func__, sensor, framesize);
306      uint16_t width = resolution[framesize][0];
307      uint16_t height = resolution[framesize][1];
308  
309      // if (framesize == FRAMESIZE_QQVGA)
310  
311      // this->SetResolution(MT9D111_MODE_CAPTURE, width, height);
312  
313      /* delay n ms */
314      mp_hal_delay_ms(100);
315      dvp_set_image_size(width, height);
316      return 0;
317  }
318  
319  static int mt9d111_set_framerate(sensor_t *sensor, framerate_t framerate)
320  {
321      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
322      return 0;
323  }
324  
325  static int mt9d111_set_contrast(sensor_t *sensor, int level)
326  {
327      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
328      return 0;
329  }
330  
331  static int mt9d111_set_brightness(sensor_t *sensor, int level)
332  {
333      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
334      return 0;
335  }
336  
337  static int mt9d111_set_saturation(sensor_t *sensor, int level)
338  {
339      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
340      return 0;
341  }
342  
343  static int mt9d111_set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
344  {
345      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
346      return 0;
347  }
348  
349  static int mt9d111_set_quality(sensor_t *sensor, int qs)
350  {
351      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
352      return 0;
353  }
354  
355  static int mt9d111_set_colorbar(sensor_t *sensor, int enable)
356  {
357      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
358      return 0;
359  }
360  
361  static int mt9d111_set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling)
362  {
363      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
364      return 0;
365  }
366  
367  static int mt9d111_get_gain_db(sensor_t *sensor, float *gain_db)
368  {
369      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
370      return 0;
371  }
372  
373  static int mt9d111_set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
374  {
375      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
376      return 0;
377  }
378  
379  static int mt9d111_get_exposure_us(sensor_t *sensor, int *exposure_us)
380  {
381      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
382      return 0;
383  }
384  
385  static int mt9d111_set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db)
386  {
387      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
388      return 0;
389  }
390  
391  static int mt9d111_get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db)
392  {
393      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
394      return 0;
395  }
396  
397  static int mt9d111_set_hmirror(sensor_t *sensor, int enable)
398  {
399      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
400      return 0;
401  }
402  
403  static int mt9d111_set_vflip(sensor_t *sensor, int enable)
404  {
405      printk("%s %s %d\r\n", __func__, __FILE__, __LINE__);
406      return 0;
407  }
408  
409  static int mt9d11_write(i2c_device_number_t i2c_dev_tmp, uint8_t reg, uint16_t val)
410  {
411      uint8_t tmp[3] = { 0 };
412      tmp[0] = (uint8_t)(reg & 0xff);
413      tmp[1] = (uint8_t)((val >> 8) & 0xff);
414      tmp[2] = (uint8_t)(val & 0xff);
415      int ret = maix_i2c_send_data(i2c_dev_tmp, MT9D111_CONFIG_I2C_ID, tmp, 3, 20);
416      msleep(20);
417      return ret;
418  }
419  
420  static uint16_t mt9d11_read(i2c_device_number_t i2c_dev_tmp, uint8_t reg)
421  {
422      uint8_t buf[2] = { 0 };
423      maix_i2c_send_data(i2c_dev_tmp, MT9D111_CONFIG_I2C_ID, reg, 1, 20);
424      int ret = maix_i2c_recv_data(i2c_dev_tmp, MT9D111_CONFIG_I2C_ID, NULL, 0, buf, 2, 30);
425      msleep(20);
426      if (ret == 0)
427      {
428          return (buf[0] << 8) + buf[1];
429      }
430      return -1;
431  }
432  
433  uint16_t mt9d111_read_id(i2c_device_number_t extern_i2c_dev_tmp)
434  {
435      i2c_dev_tmp = extern_i2c_dev_tmp; // TODO remove after implementation cambus_readw and cambus_writew
436      // return 0x1519;
437      mt9d11_write(i2c_dev_tmp, MT9D111_REG_PAGE_REGISTER, MT9D111_REG_PAGE_0);
438      uint16_t id = mt9d11_read(i2c_dev_tmp, MT9D111_REG_RESERVED);
439      // printk("[mt9d11] Sensor ID:0x%x,req:0x1519\r\n", id);
440      return id;
441  }
442  
443  static int mt9d111_reset(sensor_t *sensor)
444  {
445      for (uint8_t i = 0; i < (sizeof(reg_vals_qvga_30fps) / sizeof(struct Register)); i++)
446      {
447          mt9d11_write(i2c_dev_tmp, reg_vals_qvga_30fps[i].address, reg_vals_qvga_30fps[i].value);
448      }
449      return 0;
450  }
451  
452  int mt9d111_init(sensor_t *sensor)
453  {
454      //Initialize sensor structure.
455      sensor->gs_bpp = 2;
456      sensor->reset = mt9d111_reset;
457      sensor->read_reg = mt9d111_read_reg;
458      sensor->write_reg = mt9d111_write_reg;
459      sensor->set_pixformat = mt9d111_set_pixformat;
460      sensor->set_framesize = mt9d111_set_framesize;
461      sensor->set_framerate = mt9d111_set_framerate;
462      sensor->set_contrast = mt9d111_set_contrast;
463      sensor->set_brightness = mt9d111_set_brightness;
464      sensor->set_saturation = mt9d111_set_saturation;
465      sensor->set_gainceiling = mt9d111_set_gainceiling;
466      sensor->set_quality = mt9d111_set_quality;
467      sensor->set_colorbar = mt9d111_set_colorbar;
468      sensor->set_auto_gain = mt9d111_set_auto_gain;
469      sensor->get_gain_db = mt9d111_get_gain_db;
470      sensor->set_auto_exposure = mt9d111_set_auto_exposure;
471      sensor->get_exposure_us = mt9d111_get_exposure_us;
472      sensor->set_auto_whitebal = mt9d111_set_auto_whitebal;
473      sensor->get_rgb_gain_db = mt9d111_get_rgb_gain_db;
474      sensor->set_hmirror = mt9d111_set_hmirror;
475      sensor->set_vflip = mt9d111_set_vflip;
476  
477      // Set sensor flags
478      SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 0);
479      SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_HSYNC, 0);
480      SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
481      SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
482      SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 1);
483  
484      return 0;
485  }