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.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mt9d111.cpp Source File

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