text: #ifndef _DCMI_OV7670_INITABLE_H
  #define _DCMI_OV7670_INITABLE_H
  
  // https://github.com/iabdalkader/openmv/blob/master/src/omv/ov2640_regs.h
  
  // http://code.google.com/p/open9x/source/browse/trunk/src/x9d/STM32F2xx_StdPeriph_Lib_V1.1.0/Project/STM32F2xx_StdPeriph_Examples/DCMI/Camera/dcmi_ov2640.c?r=1737
  
  // QCIF: http://embeddedprogrammer.blogspot.ca/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
  
  /* OV2640 Registers definition when DSP bank selected (0xFF = 0x00) */
  #define OV2640_DSP_R_BYPASS     0x05
  #define OV2640_DSP_Qs           0x44
  #define OV2640_DSP_CTRL         0x50
  #define OV2640_DSP_HSIZE1       0x51
  #define OV2640_DSP_VSIZE1       0x52
  #define OV2640_DSP_XOFFL        0x53
  #define OV2640_DSP_YOFFL        0x54
  #define OV2640_DSP_VHYX         0x55
  #define OV2640_DSP_DPRP         0x56
  #define OV2640_DSP_TEST         0x57
  #define OV2640_DSP_ZMOW         0x5A
  #define OV2640_DSP_ZMOH         0x5B
  #define OV2640_DSP_ZMHH         0x5C
  #define OV2640_DSP_BPADDR       0x7C
  #define OV2640_DSP_BPDATA       0x7D
  #define OV2640_DSP_CTRL2        0x86
  #define OV2640_DSP_CTRL3        0x87
  #define OV2640_DSP_SIZEL        0x8C
  #define OV2640_DSP_HSIZE2       0xC0
  #define OV2640_DSP_VSIZE2       0xC1
  #define OV2640_DSP_CTRL0        0xC2
  #define OV2640_DSP_CTRL1        0xC3
  #define OV2640_DSP_R_DVP_SP     0xD3
  #define OV2640_DSP_IMAGE_MODE   0xDA
  #define OV2640_DSP_RESET        0xE0
  #define OV2640_DSP_MS_SP        0xF0
  #define OV2640_DSP_SS_ID        0x7F
  #define OV2640_DSP_SS_CTRL      0xF8
  #define OV2640_DSP_MC_BIST      0xF9
  #define OV2640_DSP_MC_AL        0xFA
  #define OV2640_DSP_MC_AH        0xFB
  #define OV2640_DSP_MC_D         0xFC
  #define OV2640_DSP_P_STATUS     0xFE
  #define OV2640_DSP_RA_DLMT      0xFF
  
  /* OV2640 Registers definition when sensor bank selected (0xFF = 0x01) */
  #define OV2640_SENSOR_GAIN       0x00
  #define OV2640_SENSOR_COM1       0x03
  #define OV2640_SENSOR_REG04      0x04
  #define OV2640_SENSOR_REG08      0x08
  #define OV2640_SENSOR_COM2       0x09
  #define OV2640_SENSOR_PIDH       0x0A
  #define OV2640_SENSOR_PIDL       0x0B
  #define OV2640_SENSOR_COM3       0x0C
  #define OV2640_SENSOR_COM4       0x0D
  #define OV2640_SENSOR_AEC        0x10
  #define OV2640_SENSOR_CLKRC      0x11
  #define OV2640_SENSOR_COM7       0x12
  #define OV2640_SENSOR_COM8       0x13
  #define OV2640_SENSOR_COM9       0x14
  #define OV2640_SENSOR_COM10      0x15
  #define OV2640_SENSOR_HREFST     0x17
  #define OV2640_SENSOR_HREFEND    0x18
  #define OV2640_SENSOR_VSTART     0x19
  #define OV2640_SENSOR_VEND       0x1A
  #define OV2640_SENSOR_MIDH       0x1C
  #define OV2640_SENSOR_MIDL       0x1D
  #define OV2640_SENSOR_AEW        0x24
  #define OV2640_SENSOR_AEB        0x25
  #define OV2640_SENSOR_W          0x26
  #define OV2640_SENSOR_REG2A      0x2A
  #define OV2640_SENSOR_FRARL      0x2B
  #define OV2640_SENSOR_ADDVSL     0x2D
  #define OV2640_SENSOR_ADDVHS     0x2E
  #define OV2640_SENSOR_YAVG       0x2F
  #define OV2640_SENSOR_REG32      0x32
  #define OV2640_SENSOR_ARCOM2     0x34
  #define OV2640_SENSOR_REG45      0x45
  #define OV2640_SENSOR_FLL        0x46
  #define OV2640_SENSOR_FLH        0x47
  #define OV2640_SENSOR_COM19      0x48
  #define OV2640_SENSOR_ZOOMS      0x49
  #define OV2640_SENSOR_COM22      0x4B
  #define OV2640_SENSOR_COM25      0x4E
  #define OV2640_SENSOR_BD50       0x4F
  #define OV2640_SENSOR_BD60       0x50
  #define OV2640_SENSOR_REG5D      0x5D
  #define OV2640_SENSOR_REG5E      0x5E
  #define OV2640_SENSOR_REG5F      0x5F
  #define OV2640_SENSOR_REG60      0x60
  #define OV2640_SENSOR_HISTO_LOW  0x61
  #define OV2640_SENSOR_HISTO_HIGH 0x62
  
  typedef struct {
    uint8_t Manufacturer_ID1;
    uint8_t Manufacturer_ID2;
    uint8_t Version;
    uint8_t PID;
  } OV2640_IDTypeDef;
  
  const static uint8_t OV2640_AUTOEXPOSURE_LEVEL0[] =
  {
    0xFF, 0x01,
    0x24, 0x20,
    0x25, 0x18,
    0x26, 0x60
  };
  
  const static uint8_t OV2640_AUTOEXPOSURE_LEVEL1[] =
  {
    0xFF, 0x01,
    0x24, 0x34,
    0x25, 0x1c,
    0x26, 0x70
  };
  
  const static uint8_t OV2640_AUTOEXPOSURE_LEVEL2[] =
  {
    0xFF, 0x01,
    0x24, 0x3e,
    0x25, 0x38,
    0x26, 0x81
  };
  
  const static uint8_t OV2640_AUTOEXPOSURE_LEVEL3[] =
  {
    0xFF, 0x01,
    0x24, 0x48,
    0x25, 0x40,
    0x26, 0x81
  };
  
  const static uint8_t OV2640_AUTOEXPOSURE_LEVEL4[] =
  {
    0xFF, 0x01,
    0x24, 0x58,
    0x25, 0x50,
    0x26, 0x92
  };
  
  const unsigned char OV2640_JPEG_INIT[][2] =
  {
    { 0xff, 0x00 },
    { 0x2c, 0xff },
    { 0x2e, 0xdf },
  
    { 0xff, 0x01 },
    { 0x3c, 0x32 },
    { 0x11, 0x00 }, //{ 0x11, 0x30 },  // STM runs at 168 mhz with 25 mhz crystal. xclock div is 4 = 42mhz. we divide by 2
    { 0x09, 0x02 },
    { 0x04, 0x28 },
    { 0x13, 0xe5 }, // enable banding filter
    // { 0x13, 0x25 }, // Exposure Auto/Etc
    { 0x14, 0x48 },
    { 0x2c, 0x0c },
    { 0x33, 0x78 },
    { 0x3a, 0x33 },
    { 0x3b, 0xfB },
    { 0x3e, 0x00 },
    { 0x43, 0x11 },
    { 0x16, 0x10 },
    { 0x39, 0x92 },
    { 0x35, 0xda },
    { 0x22, 0x1a },
    { 0x37, 0xc3 },
    { 0x23, 0x00 },
    { 0x34, 0xc0 },
    { 0x36, 0x1a },
    { 0x06, 0x88 },
    { 0x07, 0xc0 },
    { 0x0d, 0x87 },
    { 0x0e, 0x41 },
    { 0x4c, 0x00 },
    { 0x48, 0x00 },
    { 0x5B, 0x00 },
    { 0x42, 0x03 },
    { 0x4a, 0x81 },
    { 0x21, 0x99 },
    { 0x24, 0x40 },
    { 0x25, 0x38 },
    { 0x26, 0x82 },
    { 0x5c, 0x00 },
    { 0x63, 0x00 },
    { 0x61, 0x70 },
    { 0x62, 0x80 },
    { 0x7c, 0x05 },
    { 0x20, 0x80 },
    { 0x28, 0x30 },
    { 0x6c, 0x00 },
    { 0x6d, 0x80 },
    { 0x6e, 0x00 },
    { 0x70, 0x02 },
    { 0x71, 0x94 },
    { 0x73, 0xc1 },
    { 0x12, 0x40 },
    { 0x17, 0x11 },
    { 0x18, 0x43 },
    { 0x19, 0x00 },
    { 0x1a, 0x4b },
    { 0x32, 0x09 },
    { 0x37, 0xc0 },
    { 0x4f, 0x60 },
    { 0x50, 0xa8 },
    { 0x6d, 0x00 },
    { 0x3d, 0x38 },
  //  { 0x46, 0x3f }, // frame timing
    { 0x46, 0x00 }, // frame timing
    { 0x4f, 0x60 },
  //  { 0x0c, 0x3c },
    { 0x0c, 0x3a }, // automatic banding filter
    { 0xff, 0x00 },
    { 0xe5, 0x7f },
    { 0xf9, 0xc0 },
    { 0x41, 0x24 },
    { 0xe0, 0x14 },
    { 0x76, 0xff },
    { 0x33, 0xa0 },
    { 0x42, 0x20 },
    { 0x43, 0x18 },
    { 0x4c, 0x00 },
    { 0x87, 0xd5 },
    { 0x88, 0x3f },
    { 0xd7, 0x03 },
    { 0xd9, 0x10 },
    { 0xd3, 0x82 },
    { 0xc8, 0x08 },
    { 0xc9, 0x80 },
    { 0x7c, 0x00 },
    { 0x7d, 0x00 },
    { 0x7c, 0x03 },
    { 0x7d, 0x48 },
    { 0x7d, 0x48 },
    { 0x7c, 0x08 },
    { 0x7d, 0x20 },
    { 0x7d, 0x10 },
    { 0x7d, 0x0e },
    { 0x90, 0x00 },
    { 0x91, 0x0e },
    { 0x91, 0x1a },
    { 0x91, 0x31 },
    { 0x91, 0x5a },
    { 0x91, 0x69 },
    { 0x91, 0x75 },
    { 0x91, 0x7e },
    { 0x91, 0x88 },
    { 0x91, 0x8f },
    { 0x91, 0x96 },
    { 0x91, 0xa3 },
    { 0x91, 0xaf },
    { 0x91, 0xc4 },
    { 0x91, 0xd7 },
    { 0x91, 0xe8 },
    { 0x91, 0x20 },
    { 0x92, 0x00 },
    { 0x93, 0x06 },
    { 0x93, 0xe3 },
    { 0x93, 0x05 },
    { 0x93, 0x05 },
    { 0x93, 0x00 },
    { 0x93, 0x04 },
    { 0x93, 0x00 },
    { 0x93, 0x00 },
    { 0x93, 0x00 },
    { 0x93, 0x00 },
    { 0x93, 0x00 },
    { 0x93, 0x00 },
    { 0x93, 0x00 },
    { 0x96, 0x00 },
    { 0x97, 0x08 },
    { 0x97, 0x19 },
    { 0x97, 0x02 },
    { 0x97, 0x0c },
    { 0x97, 0x24 },
    { 0x97, 0x30 },
    { 0x97, 0x28 },
    { 0x97, 0x26 },
    { 0x97, 0x02 },
    { 0x97, 0x98 },
    { 0x97, 0x80 },
    { 0x97, 0x00 },
    { 0x97, 0x00 },
    { 0xc3, 0xed },
    { 0xa4, 0x00 },
    { 0xa8, 0x00 },
    { 0xc5, 0x11 },
    { 0xc6, 0x51 },
    { 0xbf, 0x80 },
    { 0xc7, 0x10 },
    { 0xb6, 0x66 },
    { 0xb8, 0xA5 },
    { 0xb7, 0x64 },
    { 0xb9, 0x7C },
    { 0xb3, 0xaf },
    { 0xb4, 0x97 },
    { 0xb5, 0xFF },
    { 0xb0, 0xC5 },
    { 0xb1, 0x94 },
    { 0xb2, 0x0f },
    { 0xc4, 0x5c },
    { 0xc0, 0x64 },
    { 0xc1, 0x4B },
    { 0x8c, 0x00 },
    { 0x86, 0x3D },
    { 0x50, 0x00 },
    { 0x51, 0xC8 },
    { 0x52, 0x96 },
    { 0x53, 0x00 },
    { 0x54, 0x00 },
    { 0x55, 0x00 },
    { 0x5a, 0xC8 },
    { 0x5b, 0x96 },
    { 0x5c, 0x00 },
    { 0xd3, 0x00 }, //{ 0xd3, 0x7f }, 
    { 0xc3, 0xed },
    { 0x7f, 0x00 },
    { 0xda, 0x00 },
    { 0xe5, 0x1f },
    { 0xe1, 0x67 },
    { 0xe0, 0x00 },
    { 0xdd, 0x7f },
    { 0x05, 0x00 },
  
    { 0x12, 0x40 },
    { 0xd3, 0x04 }, //{ 0xd3, 0x7f }, 
    { 0xc0, 0x16 },
    { 0xC1, 0x12 },
    { 0x8c, 0x00 },
    { 0x86, 0x3d },
    { 0x50, 0x00 },
    { 0x51, 0x2C },
    { 0x52, 0x24 },
    { 0x53, 0x00 },
    { 0x54, 0x00 },
    { 0x55, 0x00 },
    { 0x5A, 0x2c },
    { 0x5b, 0x24 },
    { 0x5c, 0x00 },
  };
  
  
  const unsigned char OV2640_YUV422[][2] =
  {
    { 0xFF, 0x00 },
    { 0x05, 0x00 },
    { 0xDA, 0x10 },
    { 0xD7, 0x03 },
    { 0xDF, 0x00 },
    { 0x33, 0x80 },
    { 0x3C, 0x40 },
    { 0xe1, 0x77 },
    { 0x00, 0x00 },
  };
  
  //static const uint8_t jpeg_regs[][2] = {
  //  { BANK_SEL, BANK_SEL_DSP },
  //  { RESET, RESET_DVP },
  //  { IMAGE_MODE, IMAGE_MODE_JPEG_EN | IMAGE_MODE_RGB565 },
  //  { 0xD7, 0x03 },
  //  { 0xE1, 0x77 },
  //  { QS, 0x0C },
  //  { RESET, 0x00 },
  //  { 0, 0 },
  //};
  
  const unsigned char OV2640_JPEG[][2] =
  {
    { 0xe0, 0x14 },
    { 0xe1, 0x77 },
    { 0xe5, 0x1f },
    { 0xd7, 0x03 },
    { 0xda, 0x10 },
    { 0xe0, 0x00 },
    { 0xFF, 0x01 },
    { 0x04, 0x08 },
  };
  
  
  
  #define VAL_SET(x, mask, rshift, lshift)  \
  		((((x) >> rshift) & mask) << lshift)
  
  #define   CTRLI_V_DIV_SET(x)    VAL_SET(x, 0x3, 0, 3)
  #define   CTRLI_H_DIV_SET(x)    VAL_SET(x, 0x3, 0, 0)
  
  #define CTRLI       0x50
  #define   CTRLI_LP_DP           0x80
  #define R_DVP_SP    0xD3 /* DVP output speed control */
  
  const unsigned char OV2640_640x480_JPEG[][2] =
  {
    { 0xff, 0x01 },
    { 0x12, 0x40 },
    { 0x17, 0x11 },
    { 0x18, 0x43 },
    { 0x19, 0x00 },
    { 0x1a, 0x4b },
    { 0x32, 0x09 },
  //  { 0x4f, 0xca },
    { 0x4f, 0x65 }, // 50 hz banding filter (15fsp)
  //  { 0x50, 0xa8 },
    { 0x50, 0x54 },  // 60 hz banding filter (15fsp)
  //  { 0x5a, 0x23 },
    { 0x5a, 0x57 }, // 6 step for 50hz, 8 step for 60hz (15fsp)
    { 0x6d, 0x00 },
    { 0x39, 0x12 },
    { 0x35, 0xda },
    { 0x22, 0x1a },
    { 0x37, 0xc3 },
    { 0x23, 0x00 },
    { 0x34, 0xc0 },
    { 0x36, 0x1a },
    { 0x06, 0x88 },
    { 0x07, 0xc0 },
    { 0x0d, 0x87 },
    { 0x0e, 0x41 },
    { 0x4c, 0x00 },
  
    { 0xff, 0x00 }, // 0xff = 0
    { 0xe0, 0x04 },
  
    { 0xc0, 0x64 },  // Image Horizontal Size (100 * 8 for svga) !!!!!!!!!!!!!!!
    { 0xc1, 0x4b }, // Image vertical size (75 * 8 for svga) !!!!!!!!!!!!!!!!!
  
    { 0x86, 0x35 },
    { 0x50, 0x89 },
    { 0x51, 0xc8 },
    { 0x52, 0x96 },
    { 0x53, 0x00 },
    { 0x54, 0x00 },
    { 0x55, 0x00 },
    { 0x57, 0x00 },
  
    { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(0) | \
    CTRLI_H_DIV_SET(0) },
  
    { 0x5a, 0x50 }, // out width (real/4) resolution: 88 * 4 = 320
    { 0x5b, 0x3c }, // out height (real/4) resolution: 72 * 4 = 240
  
    //{ 0x5a, 0xa0 },
    //{ 0x5b, 0x78 },
  
  
    { 0x5c, 0x00 },
  //  { R_DVP_SP, 0x0a },
    { R_DVP_SP, 0x0a }, // speed control
  
    { 0xe0, 0x00 },
    //{ 0xd3, 0x0a }
  
    //{ 0xff, 0x01 },
    //{ 0x11, 0x080 }, // clock doubler
  };
  
  
  
  
  
  
  
  
  
  /* JPG 352x288 */
  const unsigned char OV2640_352x288_JPEG[][2] =
  {
    0xff, 0x01, // SENSOR
    0x12, 0x40, // svga *** SHOULD BE CIF !!!!!!!!!!!!!!!!1
    0x03, 0x0A,  // for svga // CIF !!!!!!!!!!!!!!!!!!!11
    0x13, 0x25, // auto exposure, auto agc, min exposure 1/120s
    0x17, 0x11, // horizontal window start (default)
    0x18, 0x43, // horizontal window end (svga/cif)
    0x19, 0x00, // vertical window start (svga/cif)
    0x1a, 0x4b, // vertical window end
    0x32, 0x09, // clock divide (svga/cif)
    0x4f, 0xca, // light banding (50 hz)
    0x50, 0xa8, // light banding (60 hz)
    0x5a, 0x23, // ??
    0x6d, 0x00, // ??
    0x39, 0x12, // ??
    0x35, 0xFA, // seems to control a pll or jpeg compression value as well as a birghtness on the left. Bit 0 makes everything black. Bit 1 turns it on. Bit 2 makes brightness on left. Seems bit 4-7 is a multiplier. Setting this to FA allows compression to be higher (11 instead of 12)
    0x22, 0x1a, // some sort of contrast? sometimes seems to make teh colors blury
    0x37, 0xc3, // bit 7 is a zoom, bit 0 seems to be an auto contrast of some sort
    0x23, 0x00, // a brightness
    0x34, 0xc0, // zoom and some contrast setting (top bits are contrast)
    0x36, 0x1a, // 0x00 // some type of brightness
    0x06, 0x88, // ??
    0x07, 0xc0, // ??
    0x0d, 0x87, // power down pin
    0x0e, 0x41, // some kind of brightness setting
    0x4c, 0x00, // bit 6 makes everything dark, bit 4 makes picture purple
  
    // WE WANT 352x288
  
    0xff, 0x00, // DSP
    0xc7, 0x10, // auto light mode (check software notes for different light modes i.e. cloudy, office, sunny, etc)
    0xe0, 0x04, // Reset JPEG
    0xc0, 0x64, // Image Horizontal Size (100 * 8 for svga) !!!!!!!!!!!!!!!
    0xc1, 0x4b, // Image vertical size (75 * 8 for svga) !!!!!!!!!!!!!!!!!
    0x86, 0x35, // Enable Modules (CMX, UV_AVG, SDE, DCW)
    0x50, 0xC9, // 4:3 or 16:9 or 1:1 V/H Divider (LD_DP, v/1, h/1) the LD_DP helps jpeg compress faster and ROUND. When disabled, the complicated jpeg images do not complete compressing !!!!!!!!!!!!!!!
    0x51, 0xc8, // hsize (real/4) 800 for svga mode (this is the sensor resolution, not the output resolution)
    0x52, 0x96, // vsize (real/4) 600 for svga mode (this is the sensor resolutoin, not the output resolution)
    0x53, 0x00, // offset X
    0x54, 0x00, // offset Y
    0x55, 0x00, // size and offset
    0x57, 0x00, // ??
  
    0x5a, 0x50, // out width (real/4) resolution: 88 * 4 = 320
    0x5b, 0x3c, // out height (real/4) resolution: 72 * 4 = 240
  
    //0x5a, 0x58, // out width (real/4) resolution: 88 * 4 = 352
    //0x5b, 0x48, // out height (real/4) resolution: 72 * 4 = 288
  
    0x5c, 0x00, // zoom
    0xe0, 0x00, // Reset nothing
  };
  
  
  #endif
  