STM32F7 OV2640

Başlatan yldzelektronik, 10 Haziran 2020, 15:09:47

yldzelektronik

Merhabalar,

STM32F7 ile OV2640 kullanarak bir kamera çalışması yapıyorum.

Şuan kameradan görüntüyü ekrana aktarabiliyorum. Ancak görüntüde kaymalar yaşıyorum. Bu sorunu aşamadım.

Aşağıda kullandığım kodlar var. Ayrıca durumu gösteren bir video/resim de var. Yaşadığım sorunlar ile ilgili yardıma ihtiyacım var.

Frame kayması oluşuyor. Bunun sebebi nedir?

Kamera ayarları:
/**
  * @brief  Initializes the camera.
  * @param  Resolution: Camera Resolution 
  * @retval Camera status
  */
uint8_t BSP_CAMERA_Init(uint32_t Resolution)
{ 
  DCMI_HandleTypeDef *phdcmi;
  
  uint8_t ret = CAMERA_ERROR;
  
  /* Get the DCMI handle structure */
  phdcmi = &hdcmi_eval;
  
  /*** Configures the DCMI to interface with the camera module ***/
  /* DCMI configuration */
  phdcmi->Instance              = DCMI;
  phdcmi->Init.CaptureRate      = DCMI_CR_ALL_FRAME;  
  phdcmi->Init.HSPolarity      = DCMI_HSPOLARITY_LOW;
  phdcmi->Init.VSPolarity      = DCMI_VSPOLARITY_LOW;
  phdcmi->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
  phdcmi->Init.SynchroMode      = DCMI_SYNCHRO_HARDWARE;
  phdcmi->Init.PCKPolarity      = DCMI_PCKPOLARITY_RISING;

  /* DCMI Initialization */
  BSP_CAMERA_MspInit();  
  HAL_DCMI_Init(phdcmi);
  
  if(ov2640_ReadID(CAMERA_I2C_ADDRESS) == OV2640_ID)
  { 
    /* Initialize the camera driver structure */
    camera_drv = &ov2640_drv;    
    
    /* Camera Init */  
    camera_drv->Init(CAMERA_I2C_ADDRESS, Resolution);
    
    /* Return CAMERA_OK status */
    ret = CAMERA_OK;
  } 
  
  current_resolution = Resolution;
  
  return ret;
}
//

/**
  * @brief  Initializes the DCMI MSP.
  */
__weak void BSP_CAMERA_MspInit(void)
{
  static DMA_HandleTypeDef hdma_eval;
  GPIO_InitTypeDef GPIO_InitStructure;
  DCMI_HandleTypeDef *hdcmi = &hdcmi_eval;
  
  /*** Enable peripherals and GPIO clocks ***/
  /* Enable DCMI clock */
  __HAL_RCC_DCMI_CLK_ENABLE();

  /* Enable DMA2 clock */
  __HAL_RCC_DMA2_CLK_ENABLE(); 
  
  /* Enable GPIO clocks */  
  DCMI_D0_GPIO_CLK_ENABLE();
  DCMI_D1_GPIO_CLK_ENABLE();
  DCMI_D2_GPIO_CLK_ENABLE();
  DCMI_D3_GPIO_CLK_ENABLE();    
  DCMI_D4_GPIO_CLK_ENABLE();
  DCMI_D5_GPIO_CLK_ENABLE();
  DCMI_D6_GPIO_CLK_ENABLE();
  DCMI_D7_GPIO_CLK_ENABLE();
  DCMI_PWDN_GPIO_CLK_ENABLE();
  DCMI_VSYNC_GPIO_CLK_ENABLE();
  DCMI_HSYNC_GPIO_CLK_ENABLE();
  DCMI_PIXCLK_GPIO_CLK_ENABLE();  

  /*** Configure the GPIO ***/
  /* Configure DCMI GPIO as alternate function */
  /* SYNC Pins */
  GPIO_InitStructure.Pin = DCMI_VSYNC_GPIO_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStructure.Pull = GPIO_PULLUP ;
  GPIO_InitStructure.Alternate = DCMI_VSYNC_AF;
  HAL_GPIO_Init(DCMI_VSYNC_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_HSYNC_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_VSYNC_AF;
  HAL_GPIO_Init(DCMI_HSYNC_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_PIXCLK_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_PIXCLK_AF;
  HAL_GPIO_Init(DCMI_PIXCLK_GPIO_PORT, &GPIO_InitStructure);
  
  /* DATA Pins */
  GPIO_InitStructure.Pin = DCMI_D0_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D0_AF;
  HAL_GPIO_Init(DCMI_D0_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D1_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D1_AF;
  HAL_GPIO_Init(DCMI_D1_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D2_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D2_AF;
  HAL_GPIO_Init(DCMI_D2_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D3_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D3_AF;
  HAL_GPIO_Init(DCMI_D3_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D4_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D4_AF;
  HAL_GPIO_Init(DCMI_D4_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D5_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D5_AF;
  HAL_GPIO_Init(DCMI_D5_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D6_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D6_AF;
  HAL_GPIO_Init(DCMI_D6_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = DCMI_D7_GPIO_PIN;
  GPIO_InitStructure.Alternate = DCMI_D7_AF;
  HAL_GPIO_Init(DCMI_D7_GPIO_PORT, &GPIO_InitStructure);

  /* CTRL Pin */
  GPIO_InitStructure.Pin = DCMI_PWDN_GPIO_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;    
  HAL_GPIO_Init(DCMI_PWDN_GPIO_PORT, &GPIO_InitStructure);
  
  /* LIGHT Pin */
  GPIO_InitStructure.Pin = DCMI_LIGHT_GPIO_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;    
  HAL_GPIO_Init(DCMI_LIGHT_GPIO_PORT, &GPIO_InitStructure);
  
  /* Turn off flash light */
  HAL_GPIO_WritePin(DCMI_LIGHT_GPIO_PORT, DCMI_LIGHT_GPIO_PIN, GPIO_PIN_RESET);
  
  /* Power down camera */
  HAL_GPIO_WritePin(DCMI_PWDN_GPIO_PORT,DCMI_PWDN_GPIO_PIN,GPIO_PIN_SET);
  HAL_Delay(100);
  
  /* Power up camera */
  HAL_GPIO_WritePin(DCMI_PWDN_GPIO_PORT,DCMI_PWDN_GPIO_PIN,GPIO_PIN_RESET);
  HAL_Delay(100);
  
  /*** Configure the DMA ***/
  /* Set the parameters to be configured */
  hdma_eval.Instance                = DMA2_Stream1;
  hdma_eval.Init.Mode                = DMA_CIRCULAR;
  hdma_eval.Init.Channel            = DMA_CHANNEL_1;
  hdma_eval.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_eval.Init.PeriphInc          = DMA_PINC_DISABLE;
  hdma_eval.Init.MemBurst            = DMA_MBURST_SINGLE;
  hdma_eval.Init.PeriphBurst        = DMA_PBURST_SINGLE;
  hdma_eval.Init.Priority            = DMA_PRIORITY_HIGH;
  hdma_eval.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  hdma_eval.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_eval.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  hdma_eval.Init.Direction          = DMA_PERIPH_TO_MEMORY;
  hdma_eval.Init.FIFOThreshold      = DMA_FIFO_THRESHOLD_FULL;

  /* Associate the initialized DMA handle to the DCMI handle */
  __HAL_LINKDMA(hdcmi, DMA_Handle, hdma_eval);
  
  /*** Configure the NVIC for DCMI and DMA ***/
  /* NVIC configuration for DCMI transfer complete interrupt */
  HAL_NVIC_SetPriority(DCMI_IRQn, 0x0F, 0);
  HAL_NVIC_EnableIRQ(DCMI_IRQn);  
  
  /* NVIC configuration for DMA2D transfer complete interrupt */
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0x0F, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
  
  /* Configure the DMA stream */
  HAL_DMA_Init(hdcmi->DMA_Handle);  
}
//

Aşağıda ise ISR var:
/**
  * @brief  Line Event callback.
  */
__weak void BSP_CAMERA_LineEventCallback(void)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DCMI_LineEventCallback could be implemented in the user file
  */
}
//

/**
  * @brief  VSYNC Event callback.
  */
__weak void BSP_CAMERA_VsyncEventCallback(void)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DCMI_VsyncEventCallback could be implemented in the user file
  */
}
//

/**
  * @brief  Frame event callback
  * @param  hdcmi: pointer to the DCMI handle  
  */
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{        
  BSP_CAMERA_FrameEventCallback();
}
//

/**
  * @brief  Frame Event callback.
  */
__weak void BSP_CAMERA_FrameEventCallback(void)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DCMI_FrameEventCallback could be implemented in the user file
  */
}
//

/**
  * @brief  Error callback
  * @param  hdcmi: pointer to the DCMI handle  
  */
void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
{        
  BSP_CAMERA_ErrorCallback();
}
//

/**
  * @brief  Error callback.
  */
__weak void BSP_CAMERA_ErrorCallback(void)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DCMI_ErrorCallback could be implemented in the user file
  */
}
//

/**
  * @brief  Line event callback.
  * @param  None
  * @retval None
  */
void BSP_CAMERA_LineEventCallback(void)
{
  static uint32_t camera_datapointer, lcd_datapointer, line_number;
  
  if(line_number < y_res)
  {
    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_FB_ADDRESS + camera_datapointer), (uint32_t *)(LCD_LAYER_0_FB_ADDRESS + lcd_datapointer));
    camera_datapointer = camera_datapointer + x_res * (sizeof(uint16_t)); 
    lcd_datapointer = lcd_datapointer + x_res * (sizeof(uint16_t));
    line_number++;
  }
  else
  {
    camera_datapointer = 0;
    lcd_datapointer = 0;
    line_number = 0;
  }
}
//

void BSP_CAMERA_VsyncEventCallback(void)
{
//  static DMA2D_HandleTypeDef hdma2d_eval;  
//  
//  /* Enable DMA2D clock */
//  __HAL_RCC_DMA2D_CLK_ENABLE();
//  
//  /* Configure the DMA2D Mode, Color Mode and output offset */
//  hdma2d_eval.Init.Mode        = DMA2D_M2M;
//  hdma2d_eval.Init.ColorMode    = DMA2D_RGB565;
//  hdma2d_eval.Init.OutputOffset = 0;    
//  
//  /* Foreground Configuration */
//  hdma2d_eval.LayerCfg[1].InputOffset    = 0;
//  hdma2d_eval.LayerCfg[1].InputAlpha      = 0xFF;
//  hdma2d_eval.LayerCfg[1].InputColorMode  = DMA2D_INPUT_RGB565;
//  hdma2d_eval.LayerCfg[1].AlphaMode      = DMA2D_NO_MODIF_ALPHA;
//  
//  hdma2d_eval.Instance = DMA2D;
//  
//  /* DMA2D Initialization */
//  if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK) 
//  {
//    if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK) 
//    {
//      if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)CAMERA_FB_ADDRESS, (uint32_t)LCD_LAYER_0_FB_ADDRESS, x_res, y_res) == HAL_OK)
//      {
//        /* Polling For DMA transfer */  
//        HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
//      }
//    }
//  }
}
//

/**
  * @brief  Converts a line to an ARGB8888 pixel format.
  * @param  pSrc: Pointer to source buffer
  * @param  pDst: Output color  
  * @retval None
  */
static void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst)
{ 
  static DMA2D_HandleTypeDef hdma2d_eval;  
  
  /* Enable DMA2D clock */
  __HAL_RCC_DMA2D_CLK_ENABLE();
  
  /* Configure the DMA2D Mode, Color Mode and output offset */
  hdma2d_eval.Init.Mode        = DMA2D_M2M;
  hdma2d_eval.Init.ColorMode    = DMA2D_RGB565;
  hdma2d_eval.Init.OutputOffset = 0;    
  
  /* Foreground Configuration */
  hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
  hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
  hdma2d_eval.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
  hdma2d_eval.LayerCfg[1].InputOffset = 0;
  
  hdma2d_eval.Instance = DMA2D; 
  
  /* DMA2D Initialization */
  if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK) 
  {
    if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK) 
    {
      if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, x_res, 1) == HAL_OK)
      {
        /* Polling For DMA transfer */  
        HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
      }
    }
  } 
}
//

Burada bir video var. Çözünürlük oldukça düşük olarak ayarladım.

Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Frame sürekli olarak kayıyor ekranda. DMA fifo kapalı ve circular mode açık.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Sorunun dma ile ilgili olmadığı kanaatine vardım.

Eğer yanılmıyorsam, sorunun kaynağı ltdc. Görüntü ekranda sürekli kayıyor. Ama soldan sağa tarafa kayıyor yalnızca. Yukarıdan aşağıya konusunda bir sorun yok.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Sorun ile ilgili başka bir video daha çektim. Biraz daha anlaşılır olabilir.

Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Mucit23

Üstad senin şu kablolarda da sorun olabilir. Yüksek frekanslı sinyaller var biliyorsunuz. Bu yüzden kablolama işi çok düzgün yapılması lazım.

yldzelektronik

En korktuğum kısım öyle bir durum olması :)

Benim de aklıma geldi. Kamerayı hareket ettirdikçe ekrandaki kayma hızı artıyor fark ettiysen.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Mucit23

Evet farkettim. O yüzden mümkünse düzgün bir PCB ile bağlantıları hallet. Fazla bağlantı noktası olmasın. STM32F7 de kamera ile uğraşırken doğrudan film ile anakarta bağlıyordum kamerayı böyle bir sorun olmuyordu.

Sen kameraya 24Mhz clock uyguladığın zaman kamera sana 12MHz lik pixel clock sinyali gönderiyor. Arada birkaç clock atlasan senkronizasyon bozulacak.

yldzelektronik

PCB konusu şuan çözemeyeceğim bir şey. Ama ona da bakacağım. Şimdi ekrandaki pencereyi bir azalttım kayma çok azaldı. Ama görüntü yatayda bozuk çıktı. 480 değil 479 yaptım yani.

Bir diğer konu da DMA bir süre sonra duruyor. Bir süre sonra DME error oluşuyor. Bu da otomatik olarak DMA yı kapatıyor.

Kayma ve dma sorunu ilişkili olabilir mi acaba?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

RaMu

Hiç yorma kendini kablolu haliyle, elle basit bir pcb basıp kamera ve ekran yollarını uygun bir şekilde taşısan problem çıkabilecek bir noktayı elemiş oluyorsun.
Ben olsam kablolu denemezdim bile.

Benimde soracağım bir şey var:
F7 mcu için hazır kit mi kullanıyorsun?
F7 mcu sipariş ettik bir arkadaşla,
buna pcb çizeceğiz, kendin mcu pcbsini hazırladıysan tecrübenden faydalanmak isterim.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

yldzelektronik

#9
@Mucit23 sana ne desem bilemiyorum abi :D Sorun çözüldü. Bağlantıları düzelttim sorun ortadan kalktı. Hem görüntü kayma sorunu hem de dma durması sorunu.

@RaMu kendi hazırladığım pcbleri kullanıyorum. Konnektörüm olmadığı için böyle bir yol izledim.

Ürün bu: https://www.linkedin.com/feed/update/urn:li:activity:6672328533894860800

Yardımcı olabileceğim bir konu varsa her zaman...

Düzeltme: DMA sorunu halen devam ediyor.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

RaMu

Pcb bayağı yakışıklıymış.
Konuyu daha fazla baltalamamak için yeni bir konu açtım,
önerin olursa konuya beklerim.
https://www.picproje.org/index.php/topic,77737.0.html
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html