Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Cortex ARM => Konuyu başlatan: Mucit23 - 09 Nisan 2014, 15:49:21

Başlık: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 09 Nisan 2014, 15:49:21
Arkadaşlar Merhaba,

STM32F4'ün DMA modülü hakkında bir sorum olacak.

DMA transfer complete kesmesi, DMA nın buffer boyutu 1 den büyükse eğer dma her tetiklendiğinde kesme oluşurmu? Yoksa bufferin dolması beklenip öylemi kesme oluşur?

Sıkıntım şurada, DCMI ile DMA yı tetikliyorum. DMA dan istediğim, verdiğim dizinin bütün elemanlarına yeni değerleri yerleştirince kesme oluştursun.

DMA ayarlarım aşağıdaki gibi
  /* Enable DMA2 clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 
 
  /* DMA2 Stream1 Configuration */ 
  DMA_DeInit(DMA2_Stream1);

  DMA_InitStructure.DMA_Channel = DMA_Channel_1; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &image_array;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 19200;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  /* DMA Interrupts config ***************************************************/
  DMA_ITConfig(DMA2_Stream1,DMA_IT_TC, ENABLE);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);


Kesme oluşuyor fakat dizinin dolması beklenmeden kesme oluşuyor. Yani DCMI'dan her tetik geldiğinde tahminimce DMA değeri alıp dizinin ilgili elemanına taşıyor ardından kesme oluşuyor. Üstelik süreklide oluşmuyor. DMA'nın Memory adresine FSMC adresini yazsam sürekli kesme oluşuyor ama dizi adresi verince tek bir frame boyunca kesme oluşuyor ardında duruyor.

Bu neden kaynaklanabilir?

Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: superconductor - 09 Nisan 2014, 16:13:30
Hocam cozunurluk ve renk derinliginiz nedir? Acaba dma initde buyuklukler word oldugundanmi interrupt  once olusuyor diye dusundum.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Klein - 09 Nisan 2014, 17:40:23
TC kesmesi;  Buffer'in tamamı doldurulduktan sonra gerekleşir.  DMA ile kullanıln donanıma bağlı olarak değişiklik göstereceğini zannetmem. Belki bazı istisnalar olabilir ama ihtimal vermiyorum.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 09 Nisan 2014, 17:47:05
Hocam DCMI dan gelen data 16bitlik (öyle olması gerekiyor) ama dma veri büyüklüklerini half word yapınca dma hiç çalışmıyor. 

Diziyi ise uint16_t türünde tanımlamışım.

Bu işlemi aslında adc ile yaptım.  Adc den dma yı tetikliyorum. Dma ise 64 adet örneği sırayla diziye yerleştirip en sonda kesme oluşuyordu. Dma ayarları hemen hemen aynı.

Hocam peki başka neden kaynaklanabilir
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Klein - 09 Nisan 2014, 18:13:56
DMA hata kesmelerini de aktif edip , hataya düşüp düşmediğini kontol et. Belki bir yerlerde hataya düşüyor ve farketmiyor olabilirsin.
Ayrıca her TC kesmesinde bir sayıcıyı artırıp gerçekten veri adedi kadar  kesme geliyor mu  bakmak gerek.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 09 Nisan 2014, 21:09:11
Hocam dediklerinizi deneyeyim.

Acaba DMA buffer boyutu ile olabilirmi? Boyut şuanda 19200. Bu halde iken sadece tek bir frame boyunca kesme geliyor. (Öyle olduğunu tahmin ediyorum. ) Buffer boyutunu düşürmeyi denedim artık sürekli kesme oluşmaya başladı. Ama bufferin dolmasıyla değil yine aynı şekilde buffere yeni bir eleman geldiğinde kesme oluşuyor. Çok saçma bir durum.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 10 Nisan 2014, 11:27:59
Çalıştırdım çok şükür. Tam emin olmamakla birlikte interrupt rutininde problem olduğunu düşünüyorum.

İnterrupt rutinin aşağıdaki gibi yaptım.
void DMA2_Stream1_IRQHandler(void)
{
int i=0;
  if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
  {
STM_EVAL_LEDToggle(LED3);
    for (i=0;i<19200;i++)
{
      LCD_WriteRAM(image_array[i]);
    }
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
  }
}


Önceden DCMI dan data gelir gelmez lcd ye gönderiliyordu. Şimdi ilk önce diziye biriktiriliyor sonra LCD ye gönderiliyor. Bu yüzden görüntü biraz yavaşladı gibi. Fakat bir problem var. Kamera biraz çalışıyor sonra sistem donuyor. Yani artık interrupt oluşmuyor. Bu neden kaynaklanabilir?

Klein hocam birde şunu sorayım? DMA nın veri alacağı adres 32 bit, Yazacağı adres ise 16 bitlik ise DMA bu durumda nasıl davranır?

Mesela DCMI Data Register 32 bitlik, Bu yüzden DMA_PeripheralDataSize ve  DMA_MemoryDataSize değerlerini WORD yapmasam çalışmıyor dma, Halbuki DCMI Data register 32 bit olmasına rağmen ben 16 bitlik data alıyorum.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 11 Nisan 2014, 00:01:56
Arkadaşlar sistemin donmasını çözemedim henüz. Ama şöyle bir durum var Kamera DCMI veya DMA donanımlarında donma olmuyor. Tümüyle MCU donuyor. Yani örneğin arka planda dcmi dma kesme felan kamera ile uğraşırken main de led yakıp söndürüyorum. Bazen 1 dk bazen 30 saniye sistem çalışıyor sonra tümüyle mcu donuyor. Çünkü mainde yakıp söndürdüğüm led'de artık yanıp sönmüyor.

Bu durum DMA ile diziye değer yazmadan önce olmuyordu.

DMA ve DCMI deki hata kesmelerinide açıyorum hata kesmeside oluşmuyor.

Olası problemler neler olabilir? Acaba DMA ile ilgili bir durummu?
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 11 Nisan 2014, 10:58:19
Konu güncel.

Dünden beri bakınıyorum çözüm bulamadım. Nedense DMA ile Diziye veri yazınca oluyor bu durum. İşlemci Tümüyle donuyor. DMA ile Direk FSMC ye veri yazınca donma olmuyor.

DMA ve DCMI den hata kesmesi gelmiyor.
Nasıl çözebilirim. Açıkçası nereye bakacağımıda bilmiyorum. Fikri olan varmı?
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: SpeedyX - 11 Nisan 2014, 11:07:19
İşlemci resetleniyor olabilir mi?
Buffer boyutları (dma-size) değişip çok büyük veri aktarımı yapıyor olabilir mi?
DMA DCMI bayrağını kontrol ederek yazma yaptığı için problem çıkmıyor ama kontrolsüz sabit boyutla yazma yapınca overflow türevi bir olay oluşma ihtimali var.
Yazma boyutlarıyla oynayıp farkediyor mu kontrol edebilirsin.
DMA başlatmadan kesmeleri iptal edip deneme yapabilirsin.
Bir küçük ihtimal de, DMA ile yazdığın yere kesme de veya main de asenkron yazma yapılma durumu.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 11 Nisan 2014, 13:06:14
Hocam işlemci resetlense tekrar baştan başlaması gerekmezmi? Bende artık hiçbir kodu isleyemez hale geliyor. Tümüyle mcu donuyor. Hocam bence dma buffer boyutuyla ilgili bir problem var. Daha once dma kesmesi problemi varkeb farklı buffer boyutlarıyla farklı sonuçlar almıştım. Ama anlamıyorum dma zaten max. 16 bit bufferi desteklemiyormu. Yani teoride benim buffer size degerine 0xFFFF verebilmem gerekir. Neden dma problem çıkartıyor anlamıyorum.  Eğer overflow durumları varsa nasil tespit edebilirim?
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: SpeedyX - 11 Nisan 2014, 13:48:01
Yazma yapılan dizi değişkenin aralığının dışına çıkılıyor olabilir, debuggerda conditional breakpoint desteği varsa, şartlı durdurma yapılarak görülebilir.

Peki DMA ile diziden diziye kopyalama yapmayı deneyebilir misin? Öncelikle diğer donanımla alakası olmadığına emin olmak lazım.
Yada şimdiki setup ında olduğu gibi, tek bir RAM değişkeninden büyük diziye kopyalama yap, tüm dizi aynı değerle dolsun.
Sorun DMA ise yine kilitlenmesi gerekiyor.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 11 Nisan 2014, 14:22:41
Hocam Diziden diziye kopyalamayı nasıl yaparım? DMA yı tetikleyecek bir donanım olması gerekmezmi? Yine DCMI ile Tetikleyip Peripheral Adress kısmına ikinci dizinin adresinimi vereceğim?

Aslında Dma Bufferini 1 yapıp kesme içerisinde sırayla kendim diziye değer yazsam daha iyi olacak gibi. Sizin dediğiniz testleri bir yapayım. Olmadı kesme içerisinde direk diziye kendim yazacağım. Hem zaten dizi boyutu büyüdüğü zaman (örneğin 320x240 olsa) yine böyle yapmak zorunda kalacağım.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: SpeedyX - 11 Nisan 2014, 15:25:59
Kopyalama ile ilgili şurada kod var;
http://www.embedds.com/using-direct-memory-access-dma-in-stm23-projects/ (http://www.embedds.com/using-direct-memory-access-dma-in-stm23-projects/)

Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 11 Nisan 2014, 15:36:02
Deneyelim hocam
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 11 Nisan 2014, 22:59:47
Hocam dediğinizi yaptım. Yaklaşık 10 dk oldu hala çalışıyor.
Ayarlardada pek birşey yapmadım.
  /* Enable DMA2 clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 
 
  /* DMA2 Stream1 Configuration */ 
  DMA_DeInit(DMA2_Stream1);

  DMA_InitStructure.DMA_Channel = DMA_Channel_1; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &image;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &image_array;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 19200;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  /* DMA Interrupts config ***************************************************/
  DMA_ITConfig(DMA2_Stream1,DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA2_Stream1,DMA_IT_FE, ENABLE);
DMA_ITConfig(DMA2_Stream1,DMA_IT_TE, ENABLE);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);


DCMI yine aktif durumda. Yaptığım tek şey peripheral adres bölümüne yine boyutu 19200 olan bir dizinin adresini atadım. Ayrıca DMA_PeripheralInc özelliğini aktif ettim.

DMA TC kesmesi yaklaşık 581 us aralıklarla oluşuyor.

DMA nın hata kesmelerinde oluşan yok. Yani DMA bu haliyle sıkıntısı çalışıyor diyebiliriz. Peki bundan sonra ne yapayım hocam acaba DCMI'mi problemli çalışıyor? Başka ne tür testler yapabilirim

Birde şunu sorayım. Yukarıdaki DMA ilgili ayarlarda DMA yı DCMI ye bağlayan şey nedir? Merak ettiğim nokta şu. DMA tetikleme sinyalini nereden alır bu durumdayken? DCMI dan yine alsa transfer süresi yine aynı olurdu ama DMA daha hızlı çalışıyor. DCMI Capture işlemini durduruncada DMA çalışmıyor? Bunu açıklayabilirmisiniz.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: SpeedyX - 12 Nisan 2014, 15:38:52
Merhaba,

datasheet de DMA2 kısmında bir tablo var, kontrol etmedim ama muhtemelen DCMI enable ise DMA2 oraya bağlı olarak geliyor. PeripheralToMemory seçerek de tam olarak DCMI dan veri alınacağı belirleniyor.
İlginç olan, kodunda DMA_DIR_PeripheralToMemory seçmiş olmana rağmen hızlı bir şekilde memory to memory kopyalama yapmış olması. Burada kopyalamayı DCMI tetiklemeli yapması beklenir, bildiğim kadarıyla.

Projede başka DMA kullanan kod var mı?
DCMI init kodlarını görebilir miyim?
DCMI overflow kesmesi oluşuyor mu?
Kamera hangi boyutta resim gönderiyor? - DMA ayarlarına göre (Word), size olarak resim/4 verilmeli.


Aşağıdaki kodda sorun var sanırım, tanım char image_array[19200] şeklinde ise & işaretini kaldırmalısın yada &image_array[0] şeklinde kullanmalısın.
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &image_array;

DMA_Mode_Circular yerine DMA_Mode_Normal deneyip tek resim almaya çalışabilirsin.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 13 Nisan 2014, 12:40:09
Hocam kusura bakmayın cevapta biraz geciktim.
Alıntı yapılan: SpeedyX - 12 Nisan 2014, 15:38:52
İlginç olan, kodunda DMA_DIR_PeripheralToMemory seçmiş olmana rağmen hızlı bir şekilde memory to memory kopyalama yapmış olması. Burada kopyalamayı DCMI tetiklemeli yapması beklenir, bildiğim kadarıyla.
Hocam bu konuda kesinlikle haklısınız. Eğer Şuanda DMA, DCMI ile bağlantılı çalışıyorsa neden veri transferini hızlı yapsın? Eğer DCMı den tetik sinyali alıyorsa DCMI nin hızında transfer yapması gerekir
DMA nın nasıl DCMI'ye bağlandığını anladım sanırım. Dediğiniz gibi aşağıdaki tablo açıklıyor.
(http://s7.postimg.cc/ei33kv5zv/Ekran_Al_nt_s.jpg)
Biz DCMI ve DMA Stream1'i aktif ettiğimiz zaman galiba doğrudan DMA, DCMI den tetikleme sinyali alacak şekilde ayarlanıyor. Bu yüzden DCMI Capture işlemini durdurduğumda DMA çalışmıyor. Ama DCMı çalıştığında neden DMA hızlı çalışıyor bu sorunun cevabını arıyorum.  ???

Projede birde ADC3 kullanıyor ama ADC yi hiç init etmiyorum bile. Ayrıca ADC3, DMA2_Stream0'ı kullanıyor.
DCMI init kodlarım bunlar hocam.
/**
  ******************************************************************************
  * @file    DCMI/OV9655_Camera/dcmi_ov9655.c
  * @author  MCD Application Team
  * @version V0.1.4
  * @date    10/15/2010
  * @brief   This file includes the driver for OV9655 Camera module mounted on
  *          STM3220F-EVAL board RevA.
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  */

/* Includes ------------------------------------------------------------------*/
#include "OV9655.h"
#include "stm32f4xx.h"
#include "I2C.h"
#include "main.h"
/** @addtogroup DCMI_OV9655_Camera
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
   RCC_ClocksTypeDef RCC_Clocks;
/* Private define ------------------------------------------------------------*/
   #define  TIMEOUT  2
   #define  DCMI_DR_ADDRESS     0x50050028
   #define  FSMC_LCD_ADDRESS    0x60020000
/* Bits definitions ----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
   __IO uint16_t image_array[19200];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Pin Map -------------------------------------------------------------------*/
/*
      DCMI D0    = PC6
DCMI D1    = PC7
DCMI D2    = PE0
DCMI D3    = PE1
      DCMI D4    = PE4
DCMI D5    = PB6
DCMI D6    = PE5
DCMI D7    = PE6
      DCMI HSYNC = PA4
DCMI VSYNC = PB7
DCMI XCLK  = PC9
DCMI PXCLK = PA6
I2C_SCL    = PB8
I2C_SDA    = PB9
*/


/**
  * @brief  Configures the OV9655 DCMI
  * @param  None
  * @retval None
  */
uint8_t OV9655_Configuration(void){
int i=0;
OV9655_IDTypeDef OV9655_ID;
/*OV9655 MCO Configuration*/
OV9655_MCO_Configuration();
/* I2C configuration */
  Soft_I2C_Configuration();
  for(i=0;i<10000;i++){}
  /* Reset and check the presence of the OV9655 camera module */
  if (DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x12, 0x80)==0xFF)
  {
     return (0xFF); //Camera Failed!
  }
/* Camera Ok!*/
  for(i=0;i<10000;i++){}
   
  DCMI_OV9655_ReadID(&OV9655_ID);

  /* OV9655 Camera size setup */   
  #if defined (QQVGA_SIZE)
    DCMI_OV9655_QQVGASizeSetup();
  #elif defined (QVGA_SIZE)
    DCMI_OV9655_QVGASizeSetup();
  #endif
//OV9655_config_window(272,16,320,240);
  /* Set the RGB565 mode */
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM7, 0x63);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM15, 0xd0);

  /* Invert the HRef signal*/
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM10, 0x08);
/* OV9655 Camera DCMI setup */
  OV9655_DCMI_Configuration();

  return (0x00);
}

/**
  * @brief  Configures the MCO Module
  * @param  None
  * @retval None
  */
void OV9655_MCO_Configuration(void){
  GPIO_InitTypeDef GPIO_InitStructure;
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCO);
 
  RCC_PLLI2SCmd(DISABLE);
 
  RCC_PLLI2SConfig(240, 5); // 192..432, 2..7, ie range of 27.429 Mhz to 192 MHz
  /* PLLI2SSCLK = 240 / 5 = 48Mhz */
/* MCO2 Output Freq = 48 / 2 = 24Mhz*/
  RCC_MCO2Config(RCC_MCO2Source_PLLI2SCLK, RCC_MCO2Div_2); // 24 MHz with default PLL fComp
 
  RCC_PLLI2SCmd(ENABLE);
 
  while(RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY) == RESET);
}

/**
  * @brief  Configures the DCMI to interface with the OV9655 camera module.
  * @param  None
  * @retval None
  */
void OV9655_DCMI_Configuration(void)
{
  DCMI_InitTypeDef DCMI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  DMA_InitTypeDef  DMA_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable DCMI GPIOs clocks */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE |
                         RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA, ENABLE);

  /* Enable DCMI clock */
  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);

  /* Connect DCMI pins to AF13 ************************************************/
  /* PCLK */
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);
  /* D0-D7 */
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource4, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_DCMI);
  /* VSYNC */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);
  /* HSYNC */
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);
 
  /* DCMI GPIO configuration **************************************************/
  /* D0 D1(PC6/7) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; 
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  /* D2..D4(PE0/1/4) D6/D7(PE5/6) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1
                              | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
  GPIO_Init(GPIOE, &GPIO_InitStructure);

  /* D5(PB6), VSYNC(PB7) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* PCLK(PA6) HSYNC(PA4)*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  /* DCMI configuration *******************************************************/
  DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
  DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
  DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising;
  DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
  DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_High;
  DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
  DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
 
  DCMI_Init(&DCMI_InitStructure);

//  /* DCMI Interrupts config ***************************************************/
//  DCMI_ITConfig(DCMI_IT_VSYNC, ENABLE);
//  DCMI_ITConfig(DCMI_IT_LINE, ENABLE);
//  DCMI_ITConfig(DCMI_IT_FRAME, ENABLE);
  DCMI_ITConfig(DCMI_IT_ERR, ENABLE);
  DCMI_ITConfig(DCMI_IT_OVF, ENABLE);

     
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);
//
  /* Configures the DMA2 to transfer Data from DCMI to the LCD ****************/
  /* Enable DMA2 clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 
 
  /* DMA2 Stream1 Configuration */ 
  DMA_DeInit(DMA2_Stream1);

  DMA_InitStructure.DMA_Channel = DMA_Channel_1; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &image_array[0];
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 19200;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  /* DMA Interrupts config ***************************************************/
  DMA_ITConfig(DMA2_Stream1,DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA2_Stream1,DMA_IT_FE, ENABLE);
DMA_ITConfig(DMA2_Stream1,DMA_IT_TE, ENABLE);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);

}

/**
  * @brief  Reset the OV9655 SCCB registers.
  * @param  None
  * @retval None
  */
void DCMI_OV9655_Reset(void)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM7, SCCB_REG_RESET);   
}
/**
  * @brief  Set the QVGA size(240*320).
  * @param  None
  * @retval None
  */
void DCMI_OV9655_QVGASizeSetup(void)

  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x00, 0x12);//
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x01, 0x80);//78
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x02, 0x80);//48
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x03, 0x02);//02
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x04, 0x03);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x05, 0x39);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x06, 0x39);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x07, 0x39);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x08, 0x38);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x09, 0x03);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0a, 0x96);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0b, 0x57);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0c, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0d, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0e, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0f, 0x00);//old val 0xc0
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x10, 0x7b);//old val 7b
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x11, 0x00);//old val 0x80
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x12, 0x63);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x13, 0xEF);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x14, 0x2A);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x15, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x16, 0x24);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x17, 0x18);//18
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x18, 0x04);//04
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x19, 0x01);//01
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1a, 0x81);//81
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1b, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1c, 0x7F);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1d, 0xA2);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1E, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1F, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x20, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x21, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x22, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x23, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x24, 0x60);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x25, 0x36);
  Delay(TIMEOUT);    
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x26, 0x72);
  Delay(TIMEOUT);    
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x27, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x28, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x29, 0x15);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2a, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2b, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2c, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2d, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2e, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2f, 0x38);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x30, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x31, 0x30);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x32, 0x12);//12
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x33, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x34, 0x3f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x35, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x36, 0x3a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x37, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x38, 0x72);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x39, 0x57);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3a, 0xca);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3b, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3c, 0x0c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3d, 0x99);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3e, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3f, 0xc1);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x40, 0xd0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x41, 0x41);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x42, 0xc0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x43, 0x0a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x44, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x45, 0x46);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x46, 0x62);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x47, 0x2a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x48, 0x3c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x49, 0x48);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4a, 0xec);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4b, 0xfc);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4c, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4d, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4e, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4f, 0x98);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x50, 0x98);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x51, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x52, 0x28);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x53, 0x70);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x54, 0x98);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x55, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x56, 0x48);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x57, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x58, 0x1a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x59, 0x85);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5a, 0xa9);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5b, 0x64);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5c, 0x84);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5d, 0x53);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5e, 0x0e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5f, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x60, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x61, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x62, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x63, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x64, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x65, 0x20);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x66, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x67, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x68, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x69, 0x0a);//
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6a, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6b, 0x0a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6c, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6d, 0x55);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6e, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6f, 0x9d);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x70, 0x21);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x71, 0x78);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x72, 0x11);//
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x73, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x74, 0x10);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x75, 0x10);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x76, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x77, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x78, 0x28);//Test
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x79, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7A, 0x12);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7B, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7C, 0x16);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7D, 0x30);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7E, 0x5e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7F, 0x72);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x80, 0x82);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x81, 0x8e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x82, 0x9a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x83, 0xa4);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x84, 0xac);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x85, 0xb8);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x86, 0xc3);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x87, 0xd6);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x88, 0xe6);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x89, 0xf2);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8a, 0x24);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8b, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8c, 0x80);
//  Delay(TIMEOUT);
//  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8d, 0x00);
//  Delay(TIMEOUT);
//  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8e, 0x00);
//  Delay(TIMEOUT);
//  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8f, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x90, 0x71);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x91, 0x6f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x9d, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x9e, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x9f, 0x7a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa0, 0x6D);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa1, 0x40);//
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa2, 0x9D);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa4, 0x50);//50
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa5, 0x68);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa6, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa8, 0xc1);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa9, 0xef);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xaa, 0x92);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xab, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xac, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xad, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xae, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xaf, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb2, 0xf2);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb3, 0x20);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb4, 0x20);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb5, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb6, 0xaf);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb7, 0xee);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb8, 0xee);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb9, 0x0c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbb, 0xae);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbc, 0x7c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbd, 0x7d);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbe, 0x7e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbf, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc0, 0xaa);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc1, 0xc0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc2, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc3, 0x4e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc5, 0x2e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc6, 0x05);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc7, 0x81);//81
  Delay(TIMEOUT);
DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc8, 0x06);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc9, 0xe0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xca, 0xe8);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcb, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcc, 0xd8);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcd, 0x93);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xce, 0xe3);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcf, 0x74);
  Delay(TIMEOUT);
}

/**
  * @brief  Set the QQVGA size(120*160).
  * @param  None
  * @retval None
  */
void DCMI_OV9655_QQVGASizeSetup(void)
{
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x00, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x01, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x02, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x03, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x04, 0x03);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x05, 0x39);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x06, 0x39);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x07, 0x39);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x08, 0x38);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x09, 0x03);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0a, 0x96);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0b, 0x57);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0c, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0d, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0e, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x0f, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x10, 0x7b);//old val 7b
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x11, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x12, 0x63);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x13, 0xef);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x14, 0x2a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x15, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x16, 0x24);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x17, 0x18);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x18, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x19, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1a, 0x81);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1b, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1c, 0x7F);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1d, 0xA2);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1e, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x1F, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x20, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x21, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x22, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x23, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x24, 0x60);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x25, 0x36);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x26, 0x72);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x27, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x28, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x29, 0x15);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2a, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2b, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2c, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2d, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2e, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x2f, 0x38);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x30, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x31, 0x30);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x32, 0xa4);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x33, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x34, 0x3f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x35, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x36, 0x3a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x37, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x38, 0x72);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x39, 0x57);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3a, 0xca);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3b, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3c, 0x0c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3d, 0x99);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3e, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x3f, 0xc1);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x40, 0xd0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x41, 0x41);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x42, 0xc0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x43, 0x0a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x44, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x45, 0x46);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x46, 0x62);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x47, 0x2a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x48, 0x3c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x49, 0x48);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4a, 0xfC);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4b, 0xfc);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4c, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4d, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4e, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x4f, 0x98);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x50, 0x98);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x51, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x52, 0x28);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x53, 0x70);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x54, 0x98);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x55, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x56, 0x48);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x57, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x58, 0x1a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x59, 0x85);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5a, 0xa9);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5b, 0x64);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5c, 0x84);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5d, 0x53);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5e, 0x0e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x5f, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x60, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x61, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x62, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x63, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x64, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x65, 0x20);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x66, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x67, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x68, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x69, 0x0a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6a, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6b, 0x0a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6c, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6d, 0x55);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6e, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x6f, 0x9d);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x70, 0x21);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x71, 0x78);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x72, 0x22);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x73, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x74, 0x10);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x75, 0x10);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x76, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x77, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x78, 0x28);//Test
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x79, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7A, 0x12);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7B, 0x08);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7C, 0x16);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7D, 0x30);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7E, 0x5e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x7F, 0x72);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x80, 0x82);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x81, 0x8e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x82, 0x9a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x83, 0xa4);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x84, 0xac);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x85, 0xb8);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x86, 0xc3);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x87, 0xd6);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x88, 0xe6);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x89, 0xf2);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8a, 0x24);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8b, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x8c, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x90, 0x71);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x91, 0x6F);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x9d, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x9e, 0x02);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0x9f, 0x7a);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa0, 0x6D);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa1, 0x40);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa2, 0x9D);//
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa4, 0x50);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa5, 0x68);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa6, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa8, 0xc1);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xa9, 0xef);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xaa, 0x92);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xab, 0x04);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xac, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xad, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xae, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xaf, 0x80);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb2, 0xf2);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb3, 0x20);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb4, 0x20);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb5, 0x00);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb6, 0xaf);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb7, 0xee);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb8, 0xee);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xb9, 0x0c);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbb, 0xae);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbc, 0x7C);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbd, 0x7D);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbe, 0x7E);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xbf, 0x7f);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc0, 0xaa);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc1, 0xc0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc2, 0x01);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc3, 0x4e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc5, 0x2e);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc6, 0x05);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc7, 0x82);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc8, 0x06);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xc9, 0xe0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xca, 0xe8);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcb, 0xf0);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcc, 0xd8);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcd, 0x93);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xce, 0xe3);
  Delay(TIMEOUT);
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS,0xcf, 0x74);
  Delay(TIMEOUT);
}

/**
  * @brief  Read the OV9655 Manufacturer identifier.
  * @param  OV9655ID: pointer to the OV9655 Manufacturer identifier.
  * @retval None
  */
void DCMI_OV9655_ReadID(OV9655_IDTypeDef* OV9655ID)
{
  OV9655ID->Manufacturer_ID1 = DCMI_SingleRandomRead(OV9655_DEVICE_WRITE_ADDRESS, OV9655_MIDH);
  OV9655ID->Manufacturer_ID2 = DCMI_SingleRandomRead(OV9655_DEVICE_WRITE_ADDRESS, OV9655_MIDL);
  OV9655ID->Version = DCMI_SingleRandomRead(OV9655_DEVICE_WRITE_ADDRESS, OV9655_VER);
  OV9655ID->PID = DCMI_SingleRandomRead(OV9655_DEVICE_WRITE_ADDRESS, OV9655_PID);
}

/**
  * @brief  Set the Internal Clock Prescaler.
  * @param  OV9655_Prescaler: the new value of the prescaler.
  *   This parameter can be a value between 0x0 and 0x1F
  * @retval None
  */
void DCMI_OV9655_SetPrescaler(uint8_t OV9655_Prescaler)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_CLKRC, OV9655_Prescaler);
}

/**
  * @brief  Select the Output Format.
  * @param  OV9655_OuputFormat: the Format of the ouput Data. 
  *   This parameter can be a value between 0x0 and 0x1F
  *     @arg OUTPUT_FORMAT_RAWRGB_DATA
  *     @arg OUTPUT_FORMAT_RAWRGB_INTERP   
  *     @arg OUTPUT_FORMAT_YUV             
  *     @arg OUTPUT_FORMAT_RGB   
  * @retval None
  */
void DCMI_OV9655_SelectOutputFormat(uint8_t OV9655_OuputFormat)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM7, OV9655_OuputFormat);
}

/**
  * @brief  Select the Output Format Resolution.
  * @param  OV9655_FormatResolution: the Resolution of the ouput Data.
  *   This parameter can FORMAT_CTRL_15fpsVGA a value between 0x0 and 0x1F
  *     @arg FORMAT_CTRL_15fpsVGA
  *     @arg FORMAT_CTRL_30fpsVGA_NoVArioPixel   
  *     @arg FORMAT_CTRL_30fpsVGA_VArioPixel     
  * @retval None
  */
void DCMI_OV9655_SelectFormatResolution(uint8_t OV9655_FormatResolution)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM7, OV9655_FormatResolution);
}

/**
  * @brief  Set the new value of OV9655 registers
  * @param  OV9655_Register: the OV9655 Register to be configured.
  * @param  Register_Val: The new value to be set
  * @retval None
  */
void DCMI_OV9655_SetRegister(uint8_t OV9655_Register, uint8_t Register_Val)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_Register, Register_Val);
}

/**
  * @brief  Select the HREF Control signal option
  * @param  OV9665_HREFControl: the HREF Control signal option.
  *   This parameter can FORMAT_CTRL_15fpsVGA a value between 0x0 and 0x1F
  *     @arg OV9665_HREFControl_Opt1: HREF edge offset to data output.
  *     @arg OV9665_HREFControl_Opt2: HREF end 3 LSB   
  *     @arg OV9665_HREFControl_Opt3: HREF start 3 LSB     
  * @retval None
  */
void DCMI_OV9655_HREFControl(uint8_t OV9665_HREFControl)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_HREF, OV9665_HREFControl);
}

/**
  * @brief  Select the RGB format option
  * @param  OV9665_RGBOption: the RGB Format option.
  *   This parameter can FORMAT_CTRL_15fpsVGA a value between 0x0 and 0x1F
  *     @arg RGB_NORMAL
  *     @arg RGB_565 
  *     @arg RGB_555   
  * @retval None
  */
void DCMI_OV9655_SelectRGBOption(uint8_t OV9665_RGBOption)
{
  DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, OV9655_COM15, OV9665_RGBOption);
}

/**
  * @brief  config_OV7660_window
  * @param  //(140,16,640,480) is good for VGA
  * //(272,16,320,240) is good for QVGA
  * @retval None
  */
void OV9655_config_window(uint16_t startx, uint16_t starty, uint16_t width, uint16_t height)
{
uint16_t endx=(startx+width);
uint16_t endy=(starty+height*2);// must be "height*2"
uint8_t temp_reg1=0, temp_reg2=0;
uint8_t state,temp;

state = state;    //Prevent report warning

state = DCMI_SingleRandomRead(OV9655_DEVICE_WRITE_ADDRESS, 0x03);
temp_reg1 &= 0xC0;
state = DCMI_SingleRandomRead(OV9655_DEVICE_WRITE_ADDRESS, 0x32);
temp_reg2 &= 0xC0;

// Horizontal
temp = temp_reg2|((endx&0x7)<<3)|(startx&0x7);
state = DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, 0x32, temp );
temp = (startx&0x7F8)>>3;
state = DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, 0x17, temp );
temp = (endx&0x7F8)>>3;
state = DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, 0x18, temp );

// Vertical
temp = temp_reg1|((endy&0x7)<<3)|(starty&0x7);
state = DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, 0x03, temp );
temp = (starty&0x7F8)>>3;
state = DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, 0x19, temp );
temp = (endy&0x7F8)>>3;
state = DCMI_SingleRandomWrite(OV9655_DEVICE_WRITE_ADDRESS, 0x1A, temp );
}

/**
  * @brief  Writes a byte at a specific Camera register
  * @param  Device: OV9655 write address.
  * @param  Addr: OV9655 register address.
  * @param  Data: data to be written to the specific register
  * @retval None
  */
uint8_t DCMI_SingleRandomWrite(uint8_t Device, uint16_t Addr, uint8_t Data)
{
I2C_Delay();

I2C_Start();
I2C_SendByte(Device);
if(I2C_WaitAck()==0xFF) return(0xFF);
I2C_SendByte(Addr);
if(I2C_WaitAck()==0xFF) return(0xFF);
I2C_SendByte(Data);
if(I2C_WaitAck()==0xFF) return(0xFF);
I2C_Stop();

  return(0x00);
}
/**
  * @brief  Reads a byte from a specific Camera register
  * @param  Device: OV9655 write address.
  * @param  Addr: OV9655 register address.
  * @retval data read from the specific register
  */
uint8_t DCMI_SingleRandomRead(uint8_t Device, uint16_t Addr)
{
unsigned char Recieved_Data=0;
  I2C_Delay();
I2C_Start();
I2C_SendByte(Device);
if(I2C_WaitAck()==0xFF) return(0xFF);
I2C_SendByte(Addr);
if(I2C_WaitAck()==0xFF) return(0xFF);
I2C_Stop();
I2C_Start();
I2C_SendByte(Device+1);
  if(I2C_WaitAck()==0xFF) return(0xFF);
Recieved_Data=I2C_ReceiveByte();
I2C_Stop();
return Recieved_Data;
}


/**
  * @}
  */

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/


İnterrupt rutinlerimde aşağıdaki gibi.

/**
  * @brief  This function handles DMA2_Stream1.
  * @param  None
  * @retval None
  */
void DMA2_Stream1_IRQHandler(void)
{
int i=0;
  if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
  {
STM_EVAL_LEDToggle(LED3);  
    for (i=0;i<19200;i++)
{
      LCD_WriteRAM(image_array[i]);
    }
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
  }
  if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_FEIF1))
  {
    LCD_DisplayStringLine(0,170,"Fifo Error");
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_FEIF1);
  }
  if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TEIF1))
  {
    LCD_DisplayStringLine(0,170,"Transfer Error");
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TEIF1);
  }
}


/**
  * @brief  This function handles DCMI Handler.
  * @param  None
  * @retval None
  */
void DCMI_IRQHandler(void)
   
if (DCMI_GetITStatus(DCMI_IT_VSYNC) != RESET)
{    
DCMI_ClearITPendingBit(DCMI_IT_VSYNC);
}

if (DCMI_GetITStatus(DCMI_IT_LINE) != RESET)
{
DCMI_ClearITPendingBit(DCMI_IT_LINE);
}

if (DCMI_GetITStatus(DCMI_IT_FRAME) != RESET)
{
DCMI_ClearITPendingBit(DCMI_IT_FRAME);
}

if (DCMI_GetITStatus(DCMI_IT_OVF) != RESET)
{
LCD_DisplayStringLine(0,170,"DCMI OverFlow Error");
DCMI_ClearITPendingBit(DCMI_IT_OVF);
}

if (DCMI_GetITStatus(DCMI_IT_ERR) != RESET)
{
LCD_DisplayStringLine(0,170,"DCMI Error");
DCMI_ClearITPendingBit(DCMI_IT_ERR);
}
}


Bu arada memory kısmında dizi tanımlamasını  &image_array[0] şeklinde yaptım.

Hocam DCMI ve DMA'nın bütün hata kesmeleri açık. Normal olarak çalışırken hiçbiri oluşmuyor. Overflow kesmeside oluşmuyor

Kamerayı ise QQVGA boyutlarında görüntü verecek şekilde init ediyorum. Yani image boyutu 160x120(19200) Bu görüntüyü DMA ile direk ekrana göndersem hiçbir problem çıkmıyor ama tanımladığım image_array isimli diziye yazınca sıkıntı oluşuyor.

DMA mode'yi normal yapıncada yine sıkıntı yok tek bir resim geliyor ekrana basılıyor ondan sonra artık resim gelmiyor ve DCMI Overflow kesmesi oluşuyor. (Normal bir durum diye düşünüyorum)
Benim aklıma birtek şu konu takılıyor

DCMI DR registeri 32 bitlik

(http://s7.postimg.cc/fbdmykkqf/Ekran_Al_nt_s.jpg) (http://postimg.cc/image/fbdmykkqf/)
Biz kameradan 16 bit RGB565 datası alıyoruz. DMA bu 32bitlik adresten datayı alıp benim tanımlamış olduğum 16 bitlik diziye taşıyor. Yaptığı bütün iş budur. Acaba Peripheral ile Memory data boyutları farklı olduğu içinmi donuyor?

DMA ayarlarında her türlü olasılığı denedim. Peripheral kısmı ile Memory kısmını HalfWord yapsam DMA çalışmıyor ve Transfer Error kesmesi oluşuyor. Peripheral Adresi Word olduğu sürece DMA çalışıyor. Ne yapayım sizce
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: SpeedyX - 14 Nisan 2014, 08:39:53
Merhaba,
Alıntı yapılan: Mucit23 - 13 Nisan 2014, 12:40:09DMA mode'yi normal yapıncada yine sıkıntı yok tek bir resim geliyor ekrana basılıyor ondan sonra artık resim gelmiyor ve DCMI Overflow kesmesi oluşuyor. (Normal bir durum diye düşünüyorum)
Bütün kodlar aynıyken dma mode normal yapınca çalışıyor mu? Eğer evet ise; lcd ye yazma işlemini interrupt içinde yapma, zaten programın ilerledikçe ondan vazgeçmen gerekecek.

Streaming yaparken 2 buffer kullanılır, ilk buffer dolunca kesmede bir flag set ederek, dma mem adresi 2. buffer olarak düzenlenir, mainde bu buffer içeriği lcd ye gönderilir, diğer buffer dolunca, 1.buffer dma ile ilişkilendirilip, main de 2.buffer lcd ye gönderilir. Basit bir pointer ile bufferlar arası switch edilebilir. CMSIS de DoubleStreaming ile ilgili birşeyler görmüştüm sanki...
Kesme oluşup for döngüsünde lcd ye yazma yapılırken dma çalışmaya devam ediyor ve orada işler karışıyor olabilir.
Yada kolaylık olsun diye, kesme oluşunca DCMI duraklatılabilinir.

Senin program mantığına göre dma mode normal olup, resim buffera alındıktan sonra lcd ye gönderilir ve artından dma tekrar başlatılır, fakat yine dcmi duraklatma gerekebilir.

DMA neden hızlı çalışıyor? - DCMI tetikleme flagı hızlı değişiyor olabilir. Bu flag da kameradan alınan clock a dolaylı olarak bağlı.

Öncelikle kesmede lcd ye yazma işlemini kaldırmayı dene, sonucu görelim.
Başlık: Ynt: STM32F4 DMA interrupt problemi?
Gönderen: Mucit23 - 14 Nisan 2014, 09:39:45
Tamam hocam interrupt içinde bir flagı aktif e dip main içerisinde lcd ye aktarım işlemi yapayım. 

Mesajlarda sınır gibi birşey var dünki mesajımı kısa kesmek zorunda kalmıştım.
Main kodu'da aşağıdaki gibi.
int main()
{
SystemInit();
if (SysTick_Config(SystemCoreClock / 3119))//1ms
  {
    /* Capture error */
    while (1);
  }

  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);
  STM3240F_LCD_Init(); 
LCD_Clear(Black);
LCD_SetColors(Green,Black);
LCD_SetFont(&Font8x8);

    if(OV9655_Configuration()==0xFF)
{
     LCD_DisplayStringLine(0,0,"Camera Failed");
    }else{
       LCD_DisplayStringLine(0,0,"Camera OK!");
    }
/* Start Image capture */

LCD_SetDisplayWindow(0, 0, 159, 119);
  LCD_WriteRAM_Prepare();

  /* Enable DMA transfer */
  DMA_Cmd(DMA2_Stream1, ENABLE);
  /* Enable DCMI interface */
  DCMI_Cmd(ENABLE);
/* Start Image capture */
  DCMI_CaptureCmd(ENABLE);
 
while(1)
{
STM_EVAL_LEDToggle(LED4);
     for (i=0;i<1000000;i++);

}
}