Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.
mt9d111.cpp
00001 //***************************************************************************** 00002 // MT9D111.c 00003 // 00004 // Micron MT9D111 camera sensor driver 00005 // 00006 // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 00007 // 00008 // 00009 // Redistribution and use in source and binary forms, with or without 00010 // modification, are permitted provided that the following conditions 00011 // are met: 00012 // 00013 // Redistributions of source code must retain the above copyright 00014 // notice, this list of conditions and the following disclaimer. 00015 // 00016 // Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the 00019 // distribution. 00020 // 00021 // Neither the name of Texas Instruments Incorporated nor the names of 00022 // its contributors may be used to endorse or promote products derived 00023 // from this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00026 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00027 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00028 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00029 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00030 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00031 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00032 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00033 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00034 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00035 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 //***************************************************************************** 00038 //***************************************************************************** 00039 // 00040 //! \addtogroup mt9d111 00041 //! @{ 00042 // 00043 //***************************************************************************** 00044 #include <stdio.h> 00045 #include <stdbool.h> 00046 #include <stdint.h> 00047 #include "mbed.h" 00048 #include "cc3100_sl_common.h" 00049 #include "mt9d111.h" 00050 00051 #include "i2cconfig.h" 00052 #include "cli_uart.h" 00053 #include "HttpDebug.h" 00054 #include "app_config.h" 00055 00056 #define RET_OK 0 00057 #define RET_ERROR -1 00058 #define SENSOR_PAGE_REG 0xF0 00059 #define CAM_I2C_SLAVE_WRITE 0xBA//Write 00060 #define CAM_I2C_SLAVE_READ 0xBB//Read 00061 00062 #ifdef MT9D111_CAM 00063 DigitalOut standby(PA_3); 00064 #endif 00065 00066 extern DCMI_HandleTypeDef phdcmi; 00067 00068 /* Soft Reset Sequence */ 00069 static const s_RegList soft_reset_cmd_list[]= { 00070 {0, 0x65, 0xA000 }, // Bypass the PLL 00071 {1, 0xC3, 0x0501 }, // Perform MCU reset 00072 {0, 0x0D, 0x0021 }, // Enable soft reset 00073 {100, 0x00, 0x0032 }, // Delay = 50ms 00074 {0, 0x0D, 0x0000 }, // Disable soft reset 00075 {100, 0x00, 0x01f4 }, // Delay = 500ms 00076 }; 00077 00078 #ifndef ENABLE_JPEG 00079 static const s_RegList preview_on_cmd_list[]= { 00080 {1, 0xC6, 0xA103 }, // SEQ_CMD 00081 {1, 0xC8, 0x0001 }, // SEQ_CMD, Do Preview 00082 {1, 0xC6, 0xA104 }, // SEQ_CMD 00083 {111, 0xC8, 0x0003 }, // SEQ_CMD, Do Preview 00084 {1, 0xC6, 0xA103 }, // SEQ_CMD-refresh 00085 {1, 0xC8, 0x0005 }, // SEQ_CMD-refresh 00086 {1, 0xC6, 0xA103 }, // SEQ_CMD-refresh 00087 {1, 0xC8, 0x0006 }, // SEQ_CMD-refresh 00088 {1, 0xC6, 0xA104 }, // SEQ_CMD 00089 {111, 0xC8, 0x0003 }, // SEQ_CMD, Do Preview 00090 {100, 0x00, 0x01f4 }, // Delay = 500ms 00091 }; 00092 00093 static const s_RegList freq_setup_cmd_List[]= { 00094 {1, 0xC6, 0x276D }, // MODE_FIFO_CONF1_A 00095 {1, 0xC8, 0xE4E2 }, // MODE_FIFO_CONF1_A =(58594) 00096 {1, 0xC6, 0xA76F }, // MODE_FIFO_CONF2_A 00097 {1, 0xC8, 0x00E8 }, // MODE_FIFO_CONF2_A =(232) 00098 (1, 0xC6, 0x2774 ), // MODE_FIFO_CONF1_B ** 00099 (1, 0xC8, 0xE4E2 ), // MODE_FIFO_CONF1_B ** =(58594) 00100 (1, 0xC6, 0xA776 ), // MODE_FIFO_CONF2_B ** 00101 (1, 0xC8, 0x00E8 ), // MODE_FIFO_CONF2_B ** =(232) 00102 {1, 0xC6, 0xA103 }, // SEQ_CMD 00103 {1, 0xC8, 0x0005 }, // SEQ_CMD (Refresh) 00104 // Set maximum integration time to get a minimum of 15 fps at 45MHz 00105 {1, 0xC6, 0xA20E }, // AE_MAX_INDEX 00106 {1, 0xC8, 0x0004 }, // AE_MAX_INDEX 00107 {1, 0xC6, 0xA102 }, // SEQ_MODE 00108 {1, 0xC8, 0x0001 }, // SEQ_MODE 00109 {1, 0xC6, 0xA102 }, // SEQ_MODE 00110 {1, 0xC8, 0x0005 }, // SEQ_MODE 00111 // Set minimum integration time to get a maximum of 15 fps at 45MHz 00112 {1, 0xC6, 0xA20D }, // AE_MAX_INDEX 00113 {1, 0xC8, 0x0004 }, // AE_MAX_INDEX 00114 {1, 0xC6, 0xA103 }, // SEQ_CMD 00115 {1, 0xC8, 0x0005 }, // SEQ_CMD (Refresh) 00116 {100, 0x00, 0x01f4 }, // Delay = 500ms 00117 }; 00118 00119 static const s_RegList image_size_240_320_preview_cmds_list[]= { 00120 {0, 0x07, 0x00FE }, // HORZ_BLANK_A 00121 {0, 0x08, 0x02A0 }, // VERT_BLANK_A 00122 {0, 0x20, 0x0303 }, // READ_MODE_B (Image flip settings) 00123 {0, 0x21, 0x8400 }, // READ_MODE_A (1ADC) 00124 {1, 0xC6, 0x2703 }, // MODE_OUTPUT_WIDTH_A 00125 {1, 0xC8, 0x00F0 }, // MODE_OUTPUT_WIDTH_A = 0xF0 (240) 00126 {1, 0xC6, 0x2705 }, // MODE_OUTPUT_HEIGHT_A 00127 {1, 0xC8, 0x0140 }, // MODE_OUTPUT_HEIGHT_A = 0x0140 (320) 00128 {1, 0xC6, 0x2727 }, // MODE_CROP_X0_A 00129 {1, 0xC8, 0x0000 }, // MODE_CROP_X0_A = 0x00 00130 {1, 0xC6, 0x2729 }, // MODE_CROP_X1_A 00131 {1, 0xC8, 0x00F0 }, // MODE_CROP_X1_A = 0xF0 00132 {1, 0xC6, 0x272B }, // MODE_CROP_Y0_A 00133 {1, 0xC8, 0x0000 }, // MODE_CROP_Y0_A = 0xF0 00134 {1, 0xC6, 0x272D }, // MODE_CROP_Y1_A 00135 {1, 0xC8, 0x0140 }, // MODE_CROP_Y1_A = 0x0140 00136 {1, 0xC6, 0x270F }, // MODE_SENSOR_ROW_START_A 00137 {1, 0xC8, 0x001C }, // MODE_SENSOR_ROW_START_A = 0x001C (28) 00138 {1, 0xC6, 0x2711 }, // MODE_SENSOR_COL_START_A 00139 {1, 0xC8, 0x003C }, // MODE_SENSOR_COL_START_A = 0x003C (60) 00140 {1, 0xC6, 0x2713 }, // MODE_SENSOR_ROW_HEIGHT_A 00141 {1, 0xC8, 0x0280 }, // MODE_SENSOR_ROW_HEIGHT_A = 0x0280 (640) 00142 {1, 0xC6, 0x2715 }, // MODE_SENSOR_COL_WIDTH_A 00143 {1, 0xC8, 0x03C0 }, // MODE_SENSOR_COL_WIDTH_A = 0x03C0 (960) 00144 {1, 0xC6, 0x2717 }, // MODE_SENSOR_X_DELAY_A 00145 {1, 0xC8, 0x0088 }, // MODE_SENSOR_X_DELAY_A = 0x0088 00146 {1, 0xC6, 0x2719 }, // MODE_SENSOR_ROW_SPEED_A 00147 {1, 0xC8, 0x0011 }, // MODE_SENSOR_ROW_SPEED_A = 0x0011 00148 {1, 0xC6, 0xA103 }, // SEQ_CMD 00149 {1, 0xC8, 0x0005 }, // SEQ_CMD = 0x0005 00150 {1, 0xC6, 0xA103 }, // SEQ_CMD 00151 {1, 0xC8, 0x0006 }, // SEQ_CMD = 0x0006 00152 {100, 0x00, 0x01f4 }, // Delay = 500ms 00153 }; 00154 00155 static const s_RegList preview_cmds_list[]= { 00156 00157 {1, 0xC6, 0xA77D }, // MODE_OUTPUT_FORMAT_A 00158 {1, 0xC8, 0x0020 }, // MODE_OUTPUT_FORMAT_A; RGB565 = 0x0020 00159 {1, 0xC6, 0x270B }, // MODE_CONFIG 00160 {1, 0xC8, 0x0030 }, // MODE_CONFIG, JPEG disabled for A and B = 0x0030 00161 {1, 0xC6, 0xA103 }, // SEQ_CMD 00162 {1, 0xC8, 0x0005 }, // SEQ_CMD, refresh = 0x0005 00163 {100, 0x00, 0x01f4 }, // Delay = 500ms 00164 }; 00165 #else 00166 static const s_RegList pll_cmds_list[]= { 00167 {0, 0x65, 0xA000 }, // Disable PLL 00168 // {100, 0x00, 0x0064 }, // Delay =100ms 00169 {0, 0x65, 0xE000 }, // Power DOWN PLL 00170 {100, 0x00, 0x01F4 }, // Delay =500ms 00171 {0, 0x66, 0x3003 }, // M = 48 N = 3 PLL fIN = 8MHz fOUT = 24MHz 00172 // {0, 0x66, 0x7801 }, // M = 120 N = 1 PLL fIN = 8MHz fOUT = 60MHz 00173 {0, 0x67, 0x0501 }, // P = 1 00174 {0, 0x65, 0xA000 }, // Disable PLL 00175 {100, 0x00, 0x01F4 }, // Delay =500ms 00176 {0, 0x65, 0x2000 }, // Enable PLL 00177 {100, 0x00, 0x01F4 }, // Delay =500ms 00178 }; 00179 00180 static const s_RegList capture_cmds_list[]= { 00181 00182 {0, 0x20, 0x0000 }, // READ_MODE_B (Image flip settings) 00183 {100, 0x00, 0x00FA }, // Delay =250ms 00184 {1, 0xC6, 0xA102 }, // SEQ_MODE 00185 {1, 0xC8, 0x0001 }, // SEQ_MODE 00186 {1, 0xC6, 0xA102 }, // SEQ_MODE 00187 {1, 0xC8, 0x0005 }, // SEQ_MODE 00188 {1, 0xC6, 0xA120 }, // Enable Capture video 00189 {1, 0xC8, 0x0002 }, 00190 {1, 0xC6, 0x270B }, // Mode config, disable JPEG bypass 00191 {1, 0xC8, 0x0000 }, 00192 {1, 0xC6, 0x2702 }, // FIFO_config0b, no spoof, adaptive clock 00193 {1, 0xC8, 0x001E }, 00194 {1, 0xC6, 0xA907 }, // JPEG mode config, video 00195 {1, 0xC8, 0x0035 }, 00196 {1, 0xC6, 0xA906 }, // Format YCbCr422 00197 {1, 0xC8, 0x0000 }, 00198 {1, 0xC6, 0xA90A }, // Set the qscale1 00199 {1, 0xC8, 0x0088 }, 00200 {1, 0xC6, 0x2908 }, // Set the restartInt 00201 {1, 0xC8, 0x0020 }, 00202 {100, 0x00, 0x00FA }, // Delay =250ms 00203 {1, 0xC6, 0x2707 }, // MODE_OUTPUT_WIDTH_B 00204 #ifdef XGA_FRAME 00205 {1, 0xC8, 1024 }, 00206 #endif 00207 #ifdef VGA_FRAME 00208 {1, 0xC8, 640 }, 00209 #endif 00210 #ifdef QVGA_FRAME 00211 {1, 0xC8, 320 }, 00212 #endif 00213 {1, 0xC6, 0x2709 }, // MODE_OUTPUT_HEIGHT_B 00214 #ifdef XGA_FRAME 00215 {1, 0xC8, 768 }, 00216 #endif 00217 #ifdef VGA_FRAME 00218 {1, 0xC8, 480 }, 00219 #endif 00220 #ifdef QVGA_FRAME 00221 {1, 0xC8, 240 }, 00222 #endif 00223 {1, 0xC6, 0x2735 }, // MODE_CROP_X0_B 00224 {1, 0xC8, 640 }, 00225 {1, 0xC6, 0x2737 }, // MODE_CROP_X1_B 00226 {1, 0xC8, 1600 }, 00227 {1, 0xC6, 0x2739 }, // MODE_CROP_Y0_B 00228 {1, 0xC8, 480 }, 00229 {1, 0xC6, 0x273B }, // MODE_CROP_Y1_B 00230 {1, 0xC8, 1200 }, 00231 {1, 0xC6, 0xA103 }, //SEQ_CMD 00232 {1, 0xC8, 0x0005 }, //SEQ_CMD, refresh 00233 {100, 0x00, 0x00FA }, // Delay = 250ms 00234 // {111, 0xC8,0x0002 }, //Wait for sequencer change 00235 }; 00236 00237 static const s_RegList bypass_pll_list[]= { 00238 {0, 0x65, 0xA000 }, // Disable PLL 00239 {100, 0x00, 0x01F4 }, // Delay =500ms 00240 }; 00241 00242 static const s_RegList enable_pll_list[]= { 00243 {0, 0x65, 0x2000 }, // Enable PLL 00244 {100, 0x00, 0x01F4 }, // Delay =500ms 00245 }; 00246 00247 static const s_RegList context_a_list[]= { 00248 {1, 0xC6, 0xA103 }, //SEQ_CMD 00249 {1, 0xC8, 0x0001 }, //SEQ_CMD, Do Preview 00250 }; 00251 00252 static const s_RegList enter_standby_list[]= { 00253 {1, 0xC6, 0xA103 }, //SEQ_CMD 00254 {1, 0xC8, 0x0003 }, //SEQ_CMD, standby 00255 }; 00256 00257 static const s_RegList context_b_list[]= { 00258 {1, 0xC6, 0xA103 }, // SEQ_CMD, Do capture 00259 {1, 0xC8, 0x0002 }, // Start capture 00260 }; 00261 00262 static const s_RegList start_capture_cmd_list[]= { 00263 {1, 0xC6, 0xA103 }, // SEQ_CMD, Do capture 00264 {1, 0xC8, 0x0002 }, // Start capture 00265 }; 00266 00267 static const s_RegList stop_capture_cmd_list[]= { 00268 {1, 0xC6, 0xA103 }, // SEQ_CMD, Do capture 00269 {1, 0xC8, 0x0001 }, // Stop capture 00270 }; 00271 00272 #define INDEX_CROP_X0 1 00273 #define INDEX_CROP_X1 3 00274 #define INDEX_CROP_Y0 5 00275 #define INDEX_CROP_Y1 7 00276 #define INDEX_SIZE_WIDTH 12//9 00277 #define INDEX_SIZE_HEIGHT 14//11 00278 static s_RegList resolution_cmds_list[]= { 00279 // {100, 0x00, 0x01F4 }, // Delay =500ms 00280 {1, 0xC6, 0x2735 }, //MODE_CROP_X0_A 00281 {1, 0xC8, 0x0000 }, //MODE_CROP_X0_A 00282 {1, 0xC6, 0x2737 }, //MODE_CROP_X1_A 00283 {1, 0xC8, 1600 }, //MODE_CROP_X1_A 00284 {1, 0xC6, 0x2739 }, //MODE_CROP_Y0_A 00285 {1, 0xC8, 0x0000 }, //MODE_CROP_Y0_A 00286 {1, 0xC6, 0x273B }, //MODE_CROP_Y1_A 00287 {1, 0xC8, 1200 }, //MODE_CROP_Y1_A 00288 {1, 0xC6, 0xA103 }, // SEQ_CMD, Do capture 00289 {1, 0xC8, 0x0005 }, 00290 00291 {1, 0xC6, 0x2707 }, //MODE_OUTPUT_WIDTH_B 00292 {1, 0xC8, 640 }, //MODE_OUTPUT_WIDTH_B 00293 {1, 0xC6, 0x2709 }, //MODE_OUTPUT_HEIGHT_B 00294 {1, 0xC8, 480 }, //MODE_OUTPUT_HEIGHT_B 00295 {100, 0x00, 0x01f4 }, // Delay = 500ms 00296 }; 00297 #endif 00298 static const s_RegList init_cmds_list[]= { 00299 {0, 0x33, 0x0343 }, // RESERVED_CORE_33 00300 {1, 0xC6, 0xA115 }, //SEQ_LLMODE 00301 {1, 0xC8, 0x0020 }, //SEQ_LLMODE 00302 {0, 0x38, 0x0866 }, // RESERVED_CORE_38 00303 {100, 0x00, 0x0064 }, // Delay =100ms 00304 {2, 0x80, 0x0168 }, // LENS_CORRECTION_CONTROL 00305 {2, 0x81, 0x6432 }, // ZONE_BOUNDS_X1_X2 00306 {2, 0x82, 0x3296 }, // ZONE_BOUNDS_X0_X3 00307 {2, 0x83, 0x9664 }, // ZONE_BOUNDS_X4_X5 00308 {2, 0x84, 0x5028 }, // ZONE_BOUNDS_Y1_Y2 00309 {2, 0x85, 0x2878 }, // ZONE_BOUNDS_Y0_Y3 00310 {2, 0x86, 0x7850 }, // ZONE_BOUNDS_Y4_Y5 00311 {2, 0x87, 0x0000 }, // CENTER_OFFSET 00312 {2, 0x88, 0x0152 }, // FX_RED 00313 {2, 0x89, 0x015C }, // FX_GREEN 00314 {2, 0x8A, 0x00F4 }, // FX_BLUE 00315 {2, 0x8B, 0x0108 }, // FY_RED 00316 {2, 0x8C, 0x00FA }, // FY_GREEN 00317 {2, 0x8D, 0x00CF }, // FY_BLUE 00318 {2, 0x8E, 0x09AD }, // DF_DX_RED 00319 {2, 0x8F, 0x091E }, // DF_DX_GREEN 00320 {2, 0x90, 0x0B3F }, // DF_DX_BLUE 00321 {2, 0x91, 0x0C85 }, // DF_DY_RED 00322 {2, 0x92, 0x0CFF }, // DF_DY_GREEN 00323 {2, 0x93, 0x0D86 }, // DF_DY_BLUE 00324 {2, 0x94, 0x163A }, // SECOND_DERIV_ZONE_0_RED 00325 {2, 0x95, 0x0E47 }, // SECOND_DERIV_ZONE_0_GREEN 00326 {2, 0x96, 0x103C }, // SECOND_DERIV_ZONE_0_BLUE 00327 {2, 0x97, 0x1D35 }, // SECOND_DERIV_ZONE_1_RED 00328 {2, 0x98, 0x173E }, // SECOND_DERIV_ZONE_1_GREEN 00329 {2, 0x99, 0x1119 }, // SECOND_DERIV_ZONE_1_BLUE 00330 {2, 0x9A, 0x1663 }, // SECOND_DERIV_ZONE_2_RED 00331 {2, 0x9B, 0x1569 }, // SECOND_DERIV_ZONE_2_GREEN 00332 {2, 0x9C, 0x104C }, // SECOND_DERIV_ZONE_2_BLUE 00333 {2, 0x9D, 0x1015 }, // SECOND_DERIV_ZONE_3_RED 00334 {2, 0x9E, 0x1010 }, // SECOND_DERIV_ZONE_3_GREEN 00335 {2, 0x9F, 0x0B0A }, // SECOND_DERIV_ZONE_3_BLUE 00336 {2, 0xA0, 0x0D53 }, // SECOND_DERIV_ZONE_4_RED 00337 {2, 0xA1, 0x0D51 }, // SECOND_DERIV_ZONE_4_GREEN 00338 {2, 0xA2, 0x0A44 }, // SECOND_DERIV_ZONE_4_BLUE 00339 {2, 0xA3, 0x1545 }, // SECOND_DERIV_ZONE_5_RED 00340 {2, 0xA4, 0x1643 }, // SECOND_DERIV_ZONE_5_GREEN 00341 {2, 0xA5, 0x1231 }, // SECOND_DERIV_ZONE_5_BLUE 00342 {2, 0xA6, 0x0047 }, // SECOND_DERIV_ZONE_6_RED 00343 {2, 0xA7, 0x035C }, // SECOND_DERIV_ZONE_6_GREEN 00344 {2, 0xA8, 0xFE30 }, // SECOND_DERIV_ZONE_6_BLUE 00345 {2, 0xA9, 0x4625 }, // SECOND_DERIV_ZONE_7_RED 00346 {2, 0xAA, 0x47F3 }, // SECOND_DERIV_ZONE_7_GREEN 00347 {2, 0xAB, 0x5859 }, // SECOND_DERIV_ZONE_7_BLUE 00348 {2, 0xAC, 0x0000 }, // X2_FACTORS 00349 {2, 0xAD, 0x0000 }, // GLOBAL_OFFSET_FXY_FUNCTION 00350 {2, 0xAE, 0x0000 }, // K_FACTOR_IN_K_FX_FY 00351 {1, 0x08, 0x01FC }, // COLOR_PIPELINE_CONTROL 00352 {100, 0x00, 0x00C8 }, // Delay =200ms 00353 {1, 0xBE, 0x0004 }, // YUV_YCBCR_CONTROL 00354 {0, 0x65, 0xA000 }, // PLL CLOCK_ENABLING 00355 {100, 0x00, 0x00C8 }, // Delay =200ms 00356 {1, 0xC6, 0x2003 }, //MON_ARG1 00357 {1, 0xC8, 0x0748 }, //MON_ARG1 00358 {1, 0xC6, 0xA002 }, //MON_CMD 00359 {1, 0xC8, 0x0001 }, //MON_CMD 00360 {100, 0x00, 0x01F4 }, //Delay = 500ms 00361 {1, 0xC6, 0xA361 }, //AWB_TG_MIN0 00362 {1, 0xC8, 0x00E2 }, //AWB_TG_MIN0 00363 {1, 0x1F, 0x0018 }, // RESERVED_SOC1_1F 00364 {1, 0x51, 0x7F40 }, // RESERVED_SOC1_51 00365 {100, 0x00, 0x01F4 }, //Delay = 500ms 00366 {0, 0x33, 0x0343 }, // RESERVED_CORE_33 00367 {0, 0x38, 0x0868 }, // RESERVED_CORE_38 00368 {1, 0xC6, 0xA10F }, //SEQ_RESET_LEVEL_TH 00369 {1, 0xC8, 0x0042 }, //SEQ_RESET_LEVEL_TH 00370 {1, 0x1F, 0x0020 }, // RESERVED_SOC1_1F 00371 {1, 0xC6, 0xAB04 }, //HG_MAX_DLEVEL 00372 {1, 0xC8, 0x0008 }, //HG_MAX_DLEVEL 00373 {1, 0xC6, 0xA120 }, //SEQ_CAP_MODE 00374 {1, 0xC8, 0x0002 }, //SEQ_CAP_MODE 00375 {1, 0xC6, 0xA103 }, //SEQ_CMD 00376 {1, 0xC8, 0x0001 }, //SEQ_CMD 00377 {100, 0x00, 0x01F4 }, // Delay =1000ms 00378 {1, 0xC6, 0xA102 }, //SEQ_MODE 00379 {1, 0xC8, 0x001F }, //SEQ_MODE 00380 {1, 0x08, 0x01FC }, // COLOR_PIPELINE_CONTROL 00381 {1, 0x08, 0x01EC }, // COLOR_PIPELINE_CONTROL 00382 {1, 0x08, 0x01FC }, // COLOR_PIPELINE_CONTROL 00383 {1, 0x36, 0x0F08 }, // APERTURE_PARAMETERS 00384 {1, 0xC6, 0x270B }, //MODE_CONFIG 00385 {1, 0xC8, 0x0030 }, //MODE_CONFIG, JPEG disabled for A and B 00386 {1, 0xC6, 0xA121 }, //SEQ_CAP_MODE 00387 {1, 0xC8, 0x007f }, //SEQ_CAP_MODE (127 frames before switching to Preview) 00388 {0, 0x05, 0x011E }, // HORZ_BLANK_B 00389 {0, 0x06, 0x006F }, // VERT_BLANK_B 00390 {0, 0x07, 0xFE }, // HORZ_BLANK_A 00391 {0, 0x08, 19 }, // VERT_BLANK_A 00392 {0, 0x20, 0x0303 }, // READ_MODE_B (Image flip settings) 00393 {0, 0x21, 0x8400 }, // READ_MODE_A (1ADC) 00394 {1, 0xC6, 0x2717 }, //MODE_SENSOR_X_DELAY_A 00395 {1, 0xC8, 792 }, //MODE_SENSOR_X_DELAY_A 00396 {1, 0xC6, 0x270F }, //MODE_SENSOR_ROW_START_A 00397 {1, 0xC8, 0x001C }, //MODE_SENSOR_ROW_START_A 00398 {1, 0xC6, 0x2711 }, //MODE_SENSOR_COL_START_A 00399 {1, 0xC8, 0x003C }, //MODE_SENSOR_COL_START_A 00400 {1, 0xC6, 0x2713 }, //MODE_SENSOR_ROW_HEIGHT_A 00401 {1, 0xC8, 0x04B0 }, //MODE_SENSOR_ROW_HEIGHT_A 00402 {1, 0xC6, 0x2715 }, //MODE_SENSOR_COL_WIDTH_A 00403 {1, 0xC8, 0x0640 }, //MODE_SENSOR_COL_WIDTH_A 00404 {1, 0xC6, 0x2719 }, //MODE_SENSOR_ROW_SPEED_A 00405 {1, 0xC8, 0x0011 }, //MODE_SENSOR_ROW_SPEED_A 00406 {1, 0xC6, 0x2707 }, //MODE_OUTPUT_WIDTH_B 00407 {1, 0xC8, 0x0640 }, //MODE_OUTPUT_WIDTH_B 00408 {1, 0xC6, 0x2709 }, //MODE_OUTPUT_HEIGHT_B 00409 {1, 0xC8, 0x04B0 }, //MODE_OUTPUT_HEIGHT_B 00410 {1, 0xC6, 0x271B }, //MODE_SENSOR_ROW_START_B 00411 {1, 0xC8, 0x001C }, //MODE_SENSOR_ROW_START_B 00412 {1, 0xC6, 0x271D }, //MODE_SENSOR_COL_START_B 00413 {1, 0xC8, 0x003C }, //MODE_SENSOR_COL_START_B 00414 {1, 0xC6, 0x271F }, //MODE_SENSOR_ROW_HEIGHT_B 00415 {1, 0xC8, 0x04B0 }, //MODE_SENSOR_ROW_HEIGHT_B 00416 {1, 0xC6, 0x2721 }, //MODE_SENSOR_COL_WIDTH_B 00417 {1, 0xC8, 0x0640 }, //MODE_SENSOR_COL_WIDTH_B 00418 {1, 0xC6, 0x2723 }, //MODE_SENSOR_X_DELAY_B 00419 {1, 0xC8, 0x0716 }, //MODE_SENSOR_X_DELAY_B 00420 {1, 0xC6, 0x2725 }, //MODE_SENSOR_ROW_SPEED_B 00421 {1, 0xC8, 0x0011 }, //MODE_SENSOR_ROW_SPEED_B 00422 //Maximum Slew-Rate on IO-Pads (for Mode A) 00423 {1, 0xC6, 0x276B }, //MODE_FIFO_CONF0_A 00424 {1, 0xC8, 0x0027 }, //MODE_FIFO_CONF0_A 00425 {1, 0xC6, 0x276D }, //MODE_FIFO_CONF1_A 00426 {1, 0xC8, 0xE1E1 }, //MODE_FIFO_CONF1_A 00427 {1, 0xC6, 0xA76F }, //MODE_FIFO_CONF2_A 00428 {1, 0xC8, 0x00E1 }, //MODE_FIFO_CONF2_A 00429 //Maximum Slew-Rate on IO-Pads (for Mode B) 00430 {1, 0xC6, 0x2772 }, //MODE_FIFO_CONF0_B 00431 {1, 0xC8, 0x0027 }, //MODE_FIFO_CONF0_B 00432 {1, 0xC6, 0x2774 }, //MODE_FIFO_CONF1_B 00433 {1, 0xC8, 0xE1E1 }, //MODE_FIFO_CONF1_B 00434 {1, 0xC6, 0xA776 }, //MODE_FIFO_CONF2_B 00435 {1, 0xC8, 0x00E1 }, //MODE_FIFO_CONF2_B 00436 //Set maximum integration time to get a minimum of 15 fps at 45MHz 00437 {1, 0xC6, 0xA20E }, //AE_MAX_INDEX 00438 {1, 0xC8, 0x0004 }, //AE_MAX_INDEX 00439 //Set minimum integration time to get a maximum of 15 fps at 45MHz 00440 {1, 0xC6, 0xA20D }, //AE_MAX_INDEX 00441 {1, 0xC8, 0x0004 }, //AE_MAX_INDEX 00442 // Configue all GPIO for output and set low to save power 00443 {1, 0xC6, 0x9078 }, 00444 {1, 0xC8, 0x0000 }, 00445 {1, 0xC6, 0x9079 }, 00446 {1, 0xC8, 0x0000 }, 00447 {1, 0xC6, 0x9070 }, 00448 {1, 0xC8, 0x0000 }, 00449 {1, 0xC6, 0x9071 }, 00450 {1, 0xC8, 0x0000 }, 00451 // gamma and contrast 00452 {1, 0xC6, 0xA743 }, // MODE_GAM_CONT_A 00453 {1, 0xC8, 0x0003 }, // MODE_GAM_CONT_A 00454 {1, 0xC6, 0xA744 }, // MODE_GAM_CONT_B 00455 {1, 0xC8, 0x0003 }, // MODE_GAM_CONT_B 00456 {100, 0x00, 0x01f4 }, // Delay =500ms 00457 00458 }; 00459 00460 void getCamId() 00461 { 00462 00463 uint16_t Id = 0; 00464 uint8_t ucBuffer[20]; 00465 00466 ucBuffer[0] = 0x00; 00467 ucBuffer[1] = 0x00; 00468 00469 int lRetVal = -1; 00470 00471 lRetVal = RegLstWrite((s_RegList *)soft_reset_cmd_list, sizeof(soft_reset_cmd_list)/sizeof(s_RegList)); 00472 wait_ms(1); 00473 I2CBufferWrite(CAM_I2C_SLAVE_WRITE,ucBuffer,1,I2C_SEND_STOP); 00474 I2CBufferRead(CAM_I2C_SLAVE_READ,ucBuffer,2,I2C_SEND_STOP); 00475 00476 Id = (uint16_t)ucBuffer[0] << 8 | (uint16_t)ucBuffer[1]; 00477 00478 HttpDebug("\r\nCamera ID = 0x%x\r\n",Id); 00479 00480 if(Id != 0x1519) { 00481 HttpDebug("MT9D111 Camera not found! I2C read/write failed. \n\r"); 00482 HAL_DCMI_MspDeInit (&phdcmi); 00483 while(1); 00484 } 00485 00486 00487 } 00488 00489 //***************************************************************************** 00490 // 00491 //! This function initilizes the camera sensor 00492 //! 00493 //! \param None 00494 //! 00495 //! \return 0 - Success 00496 //! -1 - Error 00497 // 00498 //***************************************************************************** 00499 00500 int CameraSensorInit() 00501 { 00502 HttpDebug("CameraSensorInit \n\r"); 00503 int lRetVal = -1; 00504 00505 lRetVal = RegLstWrite((s_RegList *)init_cmds_list, \ 00506 sizeof(init_cmds_list)/sizeof(s_RegList)); 00507 ASSERT_ON_ERROR(lRetVal); 00508 00509 lRetVal = RegLstWrite((s_RegList *)pll_cmds_list, \ 00510 sizeof(pll_cmds_list)/sizeof(s_RegList)); 00511 ASSERT_ON_ERROR(lRetVal); 00512 00513 #ifndef ENABLE_JPEG 00514 00515 lRetVal = RegLstWrite((s_RegList *)preview_cmds_list, 00516 sizeof(preview_cmds_list)/sizeof(s_RegList)); 00517 ASSERT_ON_ERROR(lRetVal); 00518 lRetVal = RegLstWrite((s_RegList *)image_size_240_320_preview_cmds_list, \ 00519 sizeof(image_size_240_320_preview_cmds_list)/ \ 00520 sizeof(s_RegList)); 00521 ASSERT_ON_ERROR(lRetVal); 00522 lRetVal = RegLstWrite((s_RegList *)freq_setup_cmd_List, 00523 sizeof(freq_setup_cmd_List)/sizeof(s_RegList)); 00524 ASSERT_ON_ERROR(lRetVal); 00525 lRetVal = RegLstWrite((s_RegList *)preview_on_cmd_list, 00526 sizeof(preview_on_cmd_list)/sizeof(s_RegList)); 00527 ASSERT_ON_ERROR(lRetVal); 00528 #endif 00529 return 0; 00530 } 00531 00532 //***************************************************************************** 00533 // 00534 //! This function configures the sensor in JPEG mode 00535 //! 00536 //! \param[in] width - X-Axis 00537 //! \param[in] height - Y-Axis 00538 //! 00539 //! \return 0 - Success 00540 //! -1 - Error 00541 // 00542 //***************************************************************************** 00543 int StartSensorInJpegMode(int width, int height) 00544 { 00545 00546 #ifdef ENABLE_JPEG 00547 int lRetVal = -1; 00548 HttpDebug("\n\rStartSensorInJpegMode \n\r"); 00549 lRetVal = RegLstWrite((s_RegList *)capture_cmds_list, 00550 sizeof(capture_cmds_list)/sizeof(s_RegList)); 00551 ASSERT_ON_ERROR(lRetVal); 00552 #endif 00553 return 0; 00554 } 00555 00556 int StartCaptureCmd() 00557 { 00558 00559 int32_t lRetVal= -1; 00560 00561 #ifdef ENABLE_JPEG 00562 lRetVal = RegLstWrite((s_RegList *)start_capture_cmd_list, 00563 sizeof(start_capture_cmd_list)/sizeof(s_RegList)); 00564 #endif 00565 return 0; 00566 } 00567 00568 int StopCaptureCmd() 00569 { 00570 00571 int32_t lRetVal= -1; 00572 00573 #ifdef ENABLE_JPEG 00574 lRetVal = RegLstWrite((s_RegList *)stop_capture_cmd_list, 00575 sizeof(stop_capture_cmd_list)/sizeof(s_RegList)); 00576 #endif 00577 return 0; 00578 } 00579 00580 //***************************************************************************** 00581 // 00582 //! This function configures the sensor ouput resolution 00583 //! 00584 //! \param[in] width - X-Axis 00585 //! \param[in] height - Y-Axis 00586 //! 00587 //! \return 0 - Success 00588 //! -1 - Error 00589 // 00590 //***************************************************************************** 00591 int CameraSensorResolution(int width, int height) 00592 { 00593 HttpDebug("CameraSensorResolution \n\r"); 00594 #ifdef ENABLE_JPEG 00595 int lRetVal = -1; 00596 00597 lRetVal = RegLstWrite((s_RegList *)stop_capture_cmd_list, 00598 sizeof(stop_capture_cmd_list)/sizeof(s_RegList)); 00599 ASSERT_ON_ERROR(lRetVal); 00600 00601 resolution_cmds_list[INDEX_SIZE_WIDTH].usValue = width; 00602 resolution_cmds_list[INDEX_SIZE_HEIGHT].usValue = height; 00603 lRetVal = RegLstWrite((s_RegList *)resolution_cmds_list, 00604 sizeof(resolution_cmds_list)/sizeof(s_RegList)); 00605 ASSERT_ON_ERROR(lRetVal); 00606 00607 lRetVal = RegLstWrite((s_RegList *)start_capture_cmd_list, 00608 sizeof(start_capture_cmd_list)/sizeof(s_RegList)); 00609 ASSERT_ON_ERROR(lRetVal); 00610 00611 00612 #else 00613 if(width != 240 || height != 256) 00614 return -1; 00615 #endif 00616 return 0; 00617 } 00618 00619 //***************************************************************************** 00620 // 00621 //! This function implements the Register Write in MT9D111 sensor 00622 //! 00623 //! \param1 Register List 00624 //! \param2 No. Of Items 00625 //! 00626 //! \return 0 - Success 00627 //! -1 - Error 00628 // 00629 //***************************************************************************** 00630 static int RegLstWrite(s_RegList *pRegLst, unsigned int ulNofItems) 00631 { 00632 00633 unsigned int ulNdx; 00634 unsigned short usTemp; 00635 unsigned char i; 00636 uint8_t ucBuffer[20]; 00637 unsigned int ulSize; 00638 int lRetVal = -1; 00639 int l = 0; 00640 00641 if(pRegLst == NULL) { 00642 return RET_ERROR; 00643 } 00644 00645 for(ulNdx = 0; ulNdx < ulNofItems; ulNdx++) { 00646 if(pRegLst->ucPageAddr == 100) { 00647 // PageAddr == 100, insret a delay equal to reg value 00648 wait_ms(pRegLst->usValue); 00649 } else { 00650 // Set the page 00651 ucBuffer[0] = SENSOR_PAGE_REG;//0xF0 00652 ucBuffer[1] = 0x00; 00653 ucBuffer[2] = pRegLst->ucPageAddr; 00654 00655 if(0 != I2CBufferWrite(CAM_I2C_SLAVE_WRITE, ucBuffer, 3, I2C_SEND_STOP)) { 00656 HttpDebug("\n\rError writing SENSOR_PAGE_REG \n\r"); 00657 return RET_ERROR; 00658 } 00659 00660 ucBuffer[0] = SENSOR_PAGE_REG; 00661 lRetVal = I2CBufferWrite(CAM_I2C_SLAVE_WRITE, ucBuffer, 1, 0); 00662 ASSERT_ON_ERROR(lRetVal); 00663 lRetVal = I2CBufferRead(CAM_I2C_SLAVE_READ, ucBuffer, 2, I2C_SEND_STOP); 00664 ASSERT_ON_ERROR(lRetVal); 00665 00666 ucBuffer[0] = pRegLst->ucRegAddr; 00667 00668 if(pRegLst->ucPageAddr == 0x1 && pRegLst->ucRegAddr == 0xC8) { 00669 usTemp = 0xC8; 00670 i=1; 00671 while(pRegLst->ucRegAddr == usTemp) { 00672 ucBuffer[i] = (unsigned char)(pRegLst->usValue >> 8); 00673 ucBuffer[i+1] = (unsigned char)(pRegLst->usValue & 0xFF); 00674 i += 2; 00675 usTemp++; 00676 pRegLst++; 00677 ulNdx++; 00678 } 00679 00680 ulSize = (i-2)*2 + 1; 00681 ulNdx--; 00682 pRegLst--; 00683 } else { 00684 ulSize = 3; 00685 ucBuffer[1] = (unsigned char)(pRegLst->usValue >> 8); 00686 ucBuffer[2] = (unsigned char)(pRegLst->usValue & 0xFF); 00687 } 00688 00689 if(0 != I2CBufferWrite(CAM_I2C_SLAVE_WRITE,ucBuffer, ulSize,I2C_SEND_STOP)) { 00690 HttpDebug("\n\rError i2c write \n\r"); 00691 return RET_ERROR; 00692 } 00693 } 00694 00695 pRegLst++; 00696 wait_ms(10); 00697 } 00698 00699 return RET_OK; 00700 } 00701 00702 static int wait_for_seq_state(int state) 00703 { 00704 int i, new_state; 00705 00706 for (i = 0; i < 1000; i++) { 00707 new_state = read_firmware_var(SEQ_DRV_ID, SEQ_STATE_OFFSET, 1); 00708 // HttpDebug("seq state %d\r\n", new_state); 00709 if (new_state == state){ 00710 return 0; 00711 } 00712 wait_ms(2); 00713 } 00714 HttpDebug("Timeout waiting for seq_state %d\r\n", state); 00715 return 1; 00716 } 00717 00718 /* 00719 * Read a 8/16-bit value from a firmware driver given the driver ID and the 00720 * var offset. It assumes logic address. 00721 * The value is returned if successful, or 1 otherwise. 00722 */ 00723 static uint16_t read_firmware_var(int id, int offset, int byte) 00724 { 00725 uint16_t val; 00726 uint8_t ucBuffer[20]; 00727 /* always use logical address */ 00728 val = VAR_ADDRESS_TYPE_LOGIC << VAR_ADDRESS_TYPE_SHIFT; 00729 val |= (byte << VAR_LENGTH_SHIFT); 00730 val |= (id << VAR_DRV_ID_SHIFT); 00731 val |= (offset << VAR_ADDRESS_SHIFT); 00732 00733 ucBuffer[0] = REG_PAGE;//0xF0 00734 ucBuffer[1] = 0x00; 00735 ucBuffer[2] = PAGE_IFP1;//1 00736 00737 /* setup page pointer */ 00738 if (I2CBufferWrite(CAM_I2C_SLAVE_WRITE, (uint8_t*)ucBuffer, 3, I2C_SEND_STOP)){ 00739 return 1; 00740 } 00741 ucBuffer[0] = REG_VAR_ADDR;//0xC6 00742 ucBuffer[1] = val >> 8; 00743 ucBuffer[2] = val & 0x00FF; 00744 00745 /* setup var pointer */ 00746 if (I2CBufferWrite(CAM_I2C_SLAVE_WRITE, (uint8_t*)ucBuffer, 3, I2C_SEND_STOP)){ 00747 return 1; 00748 } 00749 ucBuffer[0] = REG_VAR_DATA;//0xC8 00750 if (I2CBufferWrite(CAM_I2C_SLAVE_WRITE, (uint8_t*)ucBuffer, 1, I2C_SEND_STOP)){ 00751 return 1; 00752 } 00753 00754 /* read the var */ 00755 if (I2CBufferRead(CAM_I2C_SLAVE_READ, ucBuffer, 2, I2C_SEND_STOP)){ 00756 return 1; 00757 } 00758 val = ucBuffer[0] << 8; 00759 val |= ucBuffer[1]; 00760 00761 return val; 00762 } 00763 00764 int Start_still_capture(int frames) 00765 { 00766 int err = 1; 00767 00768 // HttpDebug("Context B comamnd sequence ..."); 00769 err = RegLstWrite((s_RegList *)context_b_list, sizeof(context_b_list)/sizeof(s_RegList)); 00770 if (err){ 00771 return err; 00772 } 00773 /* wait until the seq driver state change */ 00774 err = wait_for_seq_state(SEQ_STATE_CAPTURE); 00775 if (err == 1){ 00776 return err; 00777 } 00778 /* need a few frames delay to stablize the output */ 00779 // wait_ms(500); 00780 00781 return 0; 00782 } 00783 00784 int Stop_still_capture(){ 00785 int err = 1; 00786 00787 // HttpDebug("Context A comamnd sequence ..."); 00788 00789 err = RegLstWrite((s_RegList *)context_a_list, sizeof(context_a_list)/sizeof(s_RegList)); 00790 if (err){ 00791 return err; 00792 } 00793 /* wait until the seq driver state change */ 00794 err = wait_for_seq_state(SEQ_STATE_PREVIEW); 00795 if (err == 1){ 00796 return err; 00797 } 00798 return 0; 00799 } 00800 00801 int cam_power_on(void) 00802 { 00803 00804 int err; 00805 HttpDebug("cam_power_on \r\n"); 00806 /* the caller already enabled our XCLK, wait to make sure it is stable */ 00807 wait_us(100); 00808 /* release STANDBY line */ 00809 cam_exit_standby(); 00810 /* wait 1ms before enable PLL per Micron Tech. Note */ 00811 wait_ms(1); 00812 00813 err = RegLstWrite((s_RegList *)pll_cmds_list, sizeof(pll_cmds_list)/sizeof(s_RegList)); 00814 if (err){ 00815 return err; 00816 } 00817 err = RegLstWrite((s_RegList *)context_a_list, sizeof(context_a_list)/sizeof(s_RegList)); 00818 if (err){ 00819 return err; 00820 } 00821 err = wait_for_seq_state(SEQ_STATE_PREVIEW); 00822 return err; 00823 } 00824 00825 int cam_power_off(void) 00826 { 00827 00828 int err; 00829 00830 /* have to check sequencer is in preview mode */ 00831 if (read_firmware_var(SEQ_DRV_ID, SEQ_STATE_OFFSET, 1) != SEQ_STATE_PREVIEW) { 00832 // printf("Calling power_off while not in preview state!\r\n"); 00833 /* Put sequencer in preview mode */ 00834 err = RegLstWrite((s_RegList *)context_a_list, sizeof(context_a_list)/sizeof(s_RegList)); 00835 if (err){ 00836 HttpDebug("Error writing context_a_list!\r\n"); 00837 return err; 00838 } 00839 err = wait_for_seq_state(SEQ_STATE_PREVIEW); 00840 if (err){ 00841 HttpDebug("Cannot place cam in preview state!\r\n"); 00842 return err; 00843 } 00844 } 00845 00846 /* Issue standby command to sequencer */ 00847 err = RegLstWrite((s_RegList *)enter_standby_list, sizeof(enter_standby_list)/sizeof(s_RegList)); 00848 if (err){ 00849 return err; 00850 } 00851 /* Poll the sequencer until it enters standby state */ 00852 err = wait_for_seq_state(SEQ_STATE_STANDBY); 00853 if (err){ 00854 return err; 00855 } 00856 /* bypass PLL */ 00857 err = RegLstWrite((s_RegList *)bypass_pll_list, sizeof(bypass_pll_list)/sizeof(s_RegList)); 00858 if (err){ 00859 return err; 00860 } 00861 /* assert STANDBY line */ 00862 cam_enter_standby(); 00863 /* the caller can cut off XCLK now */ 00864 return 0; 00865 } 00866 00867 void cam_exit_standby(void) 00868 { 00869 #ifdef MT9D111_CAM 00870 HttpDebug("cam_exit_standby \r\n"); 00871 standby = 0; 00872 #endif 00873 } 00874 00875 void cam_enter_standby(void) 00876 { 00877 #ifdef MT9D111_CAM 00878 HttpDebug("cam_enter_standby \r\n"); 00879 standby = 1; 00880 wait(1); 00881 #endif 00882 } 00883 00884 //***************************************************************************** 00885 // 00886 // Close the Doxygen group. 00887 //! @} 00888 // 00889 //***************************************************************************** 00890
Generated on Tue Jul 12 2022 22:22:38 by 1.7.2