DMA2D büyük boyutlu transfer problemi

Başlatan Mucit23, 25 Şubat 2016, 11:38:42

Mucit23

Selamlar,

ST'deki bu garip problemlerden usandım artık. Bir türlü sistemi oturtturamıyorum. Saçma sapan problemlerle uğraşmaktan gına geldi.

Yapılacak iş basit. Kamera 320x240 boyutunda görüntü alıyor. Görüntünün tamamı alındığı zaman DCMI_Frame kesmesi oluşuyor. Ben bu kesme oluştuğu zaman gidip hafızadaki 320x240 boyutundaki görüntüyü DMA2D donanımına aktarmam lazım. DMA2D donanımı görüntüyü alıp LCD'nin hafızasına yazınca kesme oluşacak ve 1 frame aktarılmış olacak. Yapılacak iş bundan ibaret.

Lafta böyle ama gerçekte ise durum şöyle oluyor.

DCMI görüntünün tamamı geldikten sonra frame kesmesini oluşturuyor. Bu aşamada sıkıntı yok. Ben DCMI kesmesi oluşur oluşmaz gidip DMA2D donanımına start veriyorum. Tam olarak aşağıdaki komutla.

      if (HAL_DMA2D_Start_IT(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, 320, 240) == HAL_OK)
      { 

      }

pSrc = Kaynak Adresi
pDst = Hedef Adres
320 = Matrisin X eksenindeki boyutu
240 = Matrisin Y eksenindeki boyutu.
Parametreler bu şekilde

Yukarıdaki komut çalışınca yaklaşık 4.64 ms sonra DMA2D Transfer Complete kesmesi oluşuyor. Yani verinin tamamı aktarılmış oluyor. Fakat gerçekte ise Sadece 1 frame aktarılıp daha sonra ekrana görüntü aktarılmıyor. Fakat arka planda DCMI Frame kesmesi oluşmaya devam ediyor, Frame kesmesi olunca DMA2D'ye start verilip yine 320x240 boyutundaki buffer aktarılınca tekrar DMA2D Transfer Complete kesmesi oluşuyor. Ama ekrandaki görüntü güncellenmiyor.

Yani Herşey düzgün çalışıyor gibi

Yukarıdaki kodlar bir şekilde düzgün çalışıyor. Mesela Transfer boyutunu 320x240 değilde 320x50 yapınca görüntünün 320x50 boyutundaki bir kısmı ekrana geliyor ve sistem olması gerektiği gibi çalışıyor ama transfer boyutunu 320x60 veya daha büyük yaptığımda başta bahsettiğim gibi ekrana tam bir görüntü gelip sistem duruyor.

Mantıken bir hatamı yapıyorum anlamış değilim. Bildiğim kadarıyla STM'nin bu donanımlarıyla forumda benden başka uğraşan yok. Konuyu açma sebebim sizlerin bu tür mantık hatalarım varsa beni uyarmanız yönünde. Bu yüzden bu konuda uğraşsanızda uğraşmasanızda konu hakkında tahimin fikirlerinizi almak istiyorum.

Çalışan bütün kodlarım aşağıda
/**
  ******************************************************************************
  * @file    Camera/Src/main.c
  * @author  MCD Application Team
  * @version V1.0.2
  * @date    18-November-2015 
  * @brief   
  ******************************************************************************
  * @attention
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/** @addtogroup STM32F7xx_HAL_Examples
  * @{
  */

/** @addtogroup BSP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Global extern variables ---------------------------------------------------*/

  TIM_HandleTypeDef  TimHandle;
	ADC_HandleTypeDef    AdcHandle;
	DMA2D_HandleTypeDef hdma2d_eval;
	
	char Char_Array[30];
/* Variable used to get converted value */
   uint16_t reg_val=0;
	 
   uint32_t tmp=0, tmp2=0, counter=0;
	 uint8_t line_tc_flag, frame_tc_flag;
	 
/* Private function prototypes -----------------------------------------------*/
  static void DMA2D_Config(void);
  static void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst);
	static void TransferError(DMA2D_HandleTypeDef* dma2dHandle);
  static void TransferComplete(DMA2D_HandleTypeDef* dma2dHandle);
	
	static void LCD_Config(void);
	static void GPIO_Config(void);
	static void SystemClock_Config(void);
	static void CPU_CACHE_Enable(void);
	
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
 int main(void)
{
  CPU_CACHE_Enable();

  HAL_Init();
  /* Configure the system clock to 200 Mhz */
  SystemClock_Config();

  BSP_LED_Init(LED1);

  /* Configure the User Button in GPIO Mode */
  BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);

  /*##-1- Initialize the LCD #################################################*/
  LCD_Config();
	GPIO_Config();
	DMA2D_Config();
	
	BSP_LCD_SetLayerWindow(1, xoffset,yoffset, xsize, ysize);

  if(BSP_CAMERA_Init(resolution)==CAMERA_OK)
	{  
	    BSP_LCD_DisplayStringAtLine(1,(uint8_t *)"Camera INIT OK");
		 /* Start the Camera Capture */ 
             BSP_CAMERA_ContinuousStart((uint8_t *)CAMERA_START_ADRES); 
	}
	else
	{
	   BSP_LCD_DisplayStringAtLine(1,(uint8_t *)"Camera INIT ERROR");
	}

  while (1)
  { 
		         if(frame_tc_flag==1)
			{
		            BSP_LED_Toggle(LED1);
		            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
			    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
		            frame_tc_flag=0;
			}
  }  
}

/**
  * @brief  Frame Event callback.
  * @param  None
  * @retval None
  */
void BSP_CAMERA_FrameEventCallback(void)
{
   frame_tc_flag=1;
}

/**
  * @brief  Camera line event callback
  * @param  None
  * @retval None
  */
void BSP_CAMERA_LineEventCallback(void)
{
//  static uint32_t tmp, tmp2, counter;

//  if(ysize > counter)
//  {
//    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
//    tmp  = tmp + xsize*sizeof(uint16_t);
//    tmp2 = tmp2 + xsize*sizeof(uint32_t);
//    counter++;
//  }
//  else
//  {
//    tmp = 0;
//    tmp2 = 0;
//    counter = 0;
//  }
}

void DMA2D_Config(void)
{
  /* Enable DMA2D clock */
  __HAL_RCC_DMA2D_CLK_ENABLE();

  /* Configure the DMA2D Mode, Color Mode and output offset */
  hdma2d_eval.Init.Mode         = DMA2D_M2M_PFC;
  hdma2d_eval.Init.ColorMode    = DMA2D_ARGB8888;
  hdma2d_eval.Init.OutputOffset = 0;
	
	  /* DMA2D Callbacks Configuration */
  hdma2d_eval.XferCpltCallback  = TransferComplete;
  hdma2d_eval.XferErrorCallback = TransferError;
	
  /* Foreground Configuration */
  hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
  hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
  hdma2d_eval.LayerCfg[1].InputColorMode = CM_RGB565;
  hdma2d_eval.LayerCfg[1].InputOffset = 0;

  hdma2d_eval.Instance = DMA2D;
	
  if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK)
  {
  }
	
	if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK)
	{

	}
	/*  Configure the DMA2D interrupts   */
  HAL_NVIC_SetPriority(DMA2D_IRQn, 0, 0);  
  HAL_NVIC_EnableIRQ(DMA2D_IRQn);   
}

/**
  * @brief  Converts a line to an ARGB8888 pixel format.
  * @param  pSrc: Pointer to source buffer
  * @param  pDst: Output color
  * @param  xSize: Buffer width
  * @param  ColorMode: Input color mode
  * @retval None
  */
static void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst)
{
      if (HAL_DMA2D_Start_IT(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, 320, 240) == HAL_OK)
      {  
      }
}

/**
  * @brief  DMA2D Transfer completed callback
  * @param  hdma2d: DMA2D handle. 
  * @note   This example shows a simple way to report end of DMA2D transfer, and 
  *         you can add your own implementation. 
  * @retval None
  */
static void TransferComplete(DMA2D_HandleTypeDef *hdma2d)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  line_tc_flag=1;
  //HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_7);
}

/**
  * @brief  DMA2D error callbacks
  * @param  hdma2d: DMA2D handle
  * @note   This example shows a simple way to report DMA2D transfer error, and you can
  *         add your own implementation.
  * @retval None
  */
static void TransferError(DMA2D_HandleTypeDef *hdma2d)
{

}

/**
  * @brief  LCD configuration
  * @param  None
  * @retval None
  */
static void LCD_Config(void)
{
	
  /* Initialize the LCD */
  BSP_LCD_Init();

	//BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, LCD_FRAME_BUFFER);
  /* LCD Initialization */ 
  BSP_LCD_LayerDefaultInit(0, LCD_BG_START_ADRES);
  BSP_LCD_LayerDefaultInit(1, LCD_FG_START_ADRES);

  /* Enable the LCD */ 
  BSP_LCD_DisplayOn(); 
  
  /* Set LCD Foreground Layer  */
  BSP_LCD_SelectLayer(1);

  BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
	  /* Configure the transparency for foreground and background :
     Increase the transparency */
  BSP_LCD_SetTransparency(0, 0);
  BSP_LCD_SetTransparency(1, 255);

  BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
  BSP_LCD_SetTextColor(LCD_COLOR_BLACK);

  /* Clear the LCD */
  BSP_LCD_Clear(LCD_COLOR_BLACK);

}

/**
  * @brief  GPIO configuration
  * @param  None
  * @retval None
  */
static void GPIO_Config(void)
{
  GPIO_InitTypeDef  gpio_init_structure;
  __HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOG_CLK_ENABLE();

	  /* Configure the GPIO D0, D1, D2 pin */
    gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
    gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init_structure.Pull = GPIO_NOPULL;
    gpio_init_structure.Speed = GPIO_SPEED_HIGH;
  
    HAL_GPIO_Init(GPIOC, &gpio_init_structure);
	
	  gpio_init_structure.Pin = GPIO_PIN_6 ;
	  
	  HAL_GPIO_Init(GPIOG, &gpio_init_structure);
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 216000000
  *            HCLK(Hz)                       = 216000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 25
  *            PLL_N                          = 400
  *            PLL_P                          = 2
  *            PLL_Q                          = 9
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 7
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  HAL_StatusTypeDef ret = HAL_OK;

  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 400;  
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 9;
  
  ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
  
  /* Activate the OverDrive to reach the 216 MHz Frequency */  
  ret = HAL_PWREx_EnableOverDrive();
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 
  
  ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }  
}

/**
  * @brief  Check for user input.
  * @param  None
  * @retval Input state (1 : active / 0 : Inactive)
  */
uint8_t CheckForUserInput(void)
{
  if (BSP_PB_GetState(BUTTON_KEY) != RESET)
  {
    HAL_Delay(10);
    while (BSP_PB_GetState(BUTTON_KEY) != RESET);
    return 1 ;
  }
  return 0;
}


/**
  * @brief  CPU L1-Cache enable.
  *         Invalidate Data cache before enabling
  *         Enable Data & Instruction Cache
  * @param  None
  * @retval None
  */
static void CPU_CACHE_Enable(void)
{
  (*(uint32_t *) 0xE000ED94) &= ~0x5;
  (*(uint32_t *) 0xE000ED98) = 0x0; //MPU->RNR
  (*(uint32_t *) 0xE000ED9C) = 0x20010000 |1<<4; //MPU->RBAR
  (*(uint32_t *) 0xE000EDA0) = 0<<28 | 3 <<24 | 0<<19 | 0<<18 | 1<<17 | 0<<16 | 0<<8 | 30<<1 | 1<<0 ; //MPU->RASE  WT
  (*(uint32_t *) 0xE000ED94) = 0x5;

  /* Invalidate I-Cache : ICIALLU register*/
  SCB_InvalidateICache();	
	
  /* Enable branch prediction */
  SCB->CCR |= (1 <<18); 
  __DSB();

  /* Enable I-Cache */
  SCB_EnableICache();	
	
  /* Enable D-Cache */
  SCB_InvalidateDCache();
  SCB_EnableDCache();
}


z

#1
Veri kaynağı ve Hedef her ikisi de rammı?

Yoksa birisi çevrebirimi diğeri ram mı?

ARM tartışmalarında aşağıdaki sorun olmuştu. Sonra nedeni de ortaya çıkmıştı ama nedenini nerede yazdığımı arayıp bulmaya üşendim.

https://www.picproje.org/index.php/topic,35794.msg264169.html#msg264169

mesaj birleştirme:: 25 Şubat 2016, 12:00:40


Öncelikle DMA'yi devre dışı bırakıp sözkonusu transferi soft olarak sen yaptığında sorun olup olmadığını gözlemledin mi?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Abi şöyle açıklamaya çalışayım

DCMI donanımı DMA ile ilişkili bunlar kendi aralarında çalışıyorlar. DCMI donanımı DMA vasıtasıyla görüntüyü alıp Camera için RAM'de tanımlamış olduğum adrese yazıyor. Bütün bir frame, RAM'e aktarıldıktan sonra frame kesmesi oluşuyor. Sonrasında DMA2D donanımına Hedef Adres ve Kaynak adresini ve veri boyutunu (x*y) verip DMA2D'nin aktarımı tamamlamasını bekliyorum.

Evet Sizin dediğiniz gibi Kaynak adres ile Hedef Adresin ikiside ram. LCD'de RAM'den alan kullanıyor. LCD nin kullandığı ram alanına yazma yapınca değişim doğrudan ekranda görünüyor. DMA2D donanımı Memory to Memory şeklinde yazma yapıyor. Fakat DMA donanımı Peripheral to Memory şeklinde transfer yapıyor. Çünkü veriyi DCMI'dan alıyor.

Kamerayı aslında SnapShot Modunda deniyorum onda da sorun devam ediyor.
Yani DCMI'yi snapshot modunda çalıştırıyorum. DCMI donanımı 1 frame aktarıp frame kesmesini oluşturup duruyor. Ardından Bende frame kesmesi oluşunca DMA2D ye start verip DMA2D nin kesme oluşturmasını bekliyorum. DMA2d kesme oluşturunca tekrar kamerayı snapshot modunda çalıştırıp işlemlerin tekrarlanmasını bekliyorum. @z hocam Snapshot modunda çalışınca işlem sonunda dcmi ve dma veri aktarımı durduruyor olması lazım.

Kamera 320x240 boyutunda 30fps de çalışıyor. Bir framenin gelmesi 33.3ms civarı sürüyor.
DMA2D nin 320x240 boyutundaki bir veriyi ekrana aktarması 4,64ms sürüyor. Zamanlamada da problem olmaması lazım.


z

#3
Peki Rame veri aktarımı yapıldıktan sonra frame kesmesi geldiğinde DMA2D yi hiç işin içine sokmadan Ramdan Rama veri aktarımını sen yazılımla byte byte yada 32 32 yaptığında görüntü update oluyormu?

Sorunu köşeye sıkıştırmak lazım.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Hocam akşam dersten dolayı bakamadım sabah bakıp tekrar yazacağım.

Mucit23

#5
@z hocam onu düşündüm aslında ama şöyle bir durum var.

LCD ARGB8888 formatında çalışıyor. Her bir pixel 32bit yer kaplıyor.
Kamera ise RGB565 formatında görüntü veriyor. Her bir pixel 16 bit.

Arada dönüşüm yapmak gerekiyor dolayısıyla. Onuda düşündüm ama hızlı çalışan bir yöntem bulamadım.

Ama yine bir denemeyi düşünüyorum. DMA2D yi devreye sokmadan for döngüsüyle doğrudan LCD 'nin hafızasına verileri yazacağım. Dönüşüm olmadığı için görüntü bozuk çıkacaktır ama donma olmaması lazım



mesaj birleştirme:: 26 Şubat 2016, 10:14:36

@z

Abi denedim.
RGB dönüşüm yapılmadığı için aşağıdaki gibi oldu.


Ama sıkıntı yok 30FPS de görüntü geldiği gibi basılıyor. Donma tıkanma titreme vs hiçbirşey yok.
Bunun için main'de aşağıdaki kodları yazdım.

frame kesmesi geldiği zaman hemen işleme başlanıyor.
  
while (1)
  { 
      if(frame_tc_flag==1)
     {
	BSP_LED_Toggle(LED1);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
        for(counter=0;counter<320*240;counter++)
	{
	    rgb565_data  = *(__IO uint16_t*) (CAMERA_START_ADRES  + 2*counter);
	    *(__IO uint32_t*) (LCD_FG_START_ADRES + 4*counter) = 0xFF000000 | rgb565_data;
	}
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);				
	frame_tc_flag=0;
    }
  }


Görüntünün çıkması için Alpha değerini FF yapmak gerekiyor. Bu yüzden okunan pixellere 0xFF000000 | rgb565_data işlemini uyguladım.

For döngüsünün tamamlanması 24,30ms civarı sürüyor.

Yani Sorun kesinlikle DMA2D donanımında olmalı.

Benim anlamadığım kısım şu.

Kodun orjinalinde DCMI_Line kesmesi oluştuğunda kesme içerisinde bir satırlık veri ekrana gönderiliyor. Yani veri satır satır gönderiliyor ekrana.
Bu işi yapan orjinal kodlar aşağıdaki gibi. Çalışması son derece basit.
void BSP_CAMERA_LineEventCallback(void)
{
  static uint32_t tmp, tmp2, counter;

  if(ysize > counter)
  {
    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
    tmp  = tmp + xsize*2;
    tmp2 = tmp2 + xsize*4;
    counter++;
  }
  else
  {
    tmp = 0;
    tmp2 = 0;
    counter = 0;
  }
}

Bu haliyle çalışıyor hiçbir sıkıntı yok.

Şimdi diyorumki madem satır satır gönderilmesi gerekiyor. Bi bildikleri vardır herhalde diyorum ve Frame kesmesi geldiğinde kesme içerisinde aşağıdaki kodları çalıştırıyorum.

void BSP_CAMERA_FrameEventCallback(void)
{
  uint32_t tmp=0, tmp2=0, counter=0;
  while(ysize>counter)
  {
    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
    tmp  = tmp + xsize*2;
    tmp2 = tmp2 + xsize*4;
    counter++;
  }
}


Yapılan iş aynı. Satır satır basmak yerine frame kesmesi geldiğinde bütün bir resmi basıyorum. Bunun için kesme içerisinde basitçe bir döngü kurdum. Ama sonuç konunun en başındakiyle aynı. İlk kez çalışınca tam bir görüntü basılıyor sonrasında sistem donup kalıyor. Döngü sayısını 50 yapıyorum normal olarak görüntünün ilk 50 satırı basılıyor ve donma olmuyor.

İşte böyle olunca tıkanıp kalıyorum  ??? ???

Mucit23

Şöyle birşey yaptım.

DMA2D'yi tek bir satır basacak şekilde ayarladım.

Main içerisinde frame kesmesi gelince satır satır resmi basmayı düşündüm.

if(frame_tc_flag==1)
	{
		BSP_LED_Toggle(LED1);
				
		tmp=0;tmp2=0;counter=0;
				
		while(ysize>counter)
		{ 
			LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
			while(line_tc_flag==0){}
			line_tc_flag=0;
					
			tmp  = tmp + xsize*2;
			tmp2 = tmp2 + xsize*4;
			counter++;
		}
		frame_tc_flag=0;
	}


ilk while döngüsünün içerisinde satırlar taranıyor. 320x240 image için döngü sayısı 240 olacak.

iç taraftaki while(line_tc_flag==0){} satırında ise DMA2D donanımının Transfer Complete kesme oluşturmasını bekliyorum. Kesme oluşursa bir sonraki satır için DMA2D ye adreslerle birlikte start verilecek.

Mantığımı yanlış kuruyorum anlamadım ama reel de çalışmıyor. Debug'da ise adım adım takip edince çalışıyor görünüyor. Çünkü DMA2D TC kesmesi oluşuyor ana programdaki döngülerde çalışıyor görünüyor.

DMA2D de kesme olmadan transfer yaptığımda konunun en başındaki sorun oluyor. bir frame basılıp sonrasında sistem duruyor.

@z hocam bir önerin var mı?

z

#7
frame_tc_flag=0; satırından sonra laf olsun diye işlemciyi 5...10 cycle oyalayacak kod eklermisin. Sanırım sorunu anladım.

Şöyle de deneyebilirsin.

if(frame_tc_flag==1)
	{
		frame_tc_flag=0;

                BSP_LED_Toggle(LED1);
				
		tmp=0;tmp2=0;counter=0;
				
		while(ysize>counter)
		{ 
			LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_START_ADRES + tmp) , (uint32_t *)(LCD_FG_START_ADRES + tmp2));
			while(line_tc_flag==0){}
			line_tc_flag=0;
					
			tmp  = tmp + xsize*2;
			tmp2 = tmp2 + xsize*4;
			counter++;
		}
	}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

@z hocam şimdi okula geldim. Dersim var. Yarinda istanbula geleceğim.  Artık pazartesi bakmayı düşünüyorum. 

z

Bu nasıl bir hayat. Akşama doğru okula gitmek, ertesi gün şehirler arası yolculuk.

Tuhaf.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Abi tempo bayağı yoğun. Sabah işteyim. Akşamda eem geceden devam ediyorum.  Öyle oluyorki günde 7-8 saat derse giriyorum.  Akşam evin yolunu şaşırdıgım oluyor. Bu yüzden işi böyle kesik kesik ilerliyor.

İstanbul bu haftaya özgü.  Pazar akşam döneceğim. Aklınıza yatmayan konu nedir hocam varsa elestirilerinizi almak isterin


Mucit23

@z hocam kamerada şöyle bir gelişme var. Dün tekrar baktım.

Bu sorun sadece 320x240 çözünürlükte oluyor. Acaba görüntü boyutu çok yüksek diyemi böyle sorunlar oluşuyor diye düşünüp kamerayı 160x120 çözünürlüğe ayarladım. 160x120 çözünürlükte hiçbir sıkıntı yok. Kamera çalışıyor DCMI çalışıyor DMA kesmeleri ve DMA2D kesmeleri hepsi olması gerektiği gibi çalışıyor. Bende main içerisinde istediğim gibi görüntüyü basabiliyorum.

Sonradan 640x480 çözünürlük ile deneyeyim dedim. Kamera 640x480 çözünürlüğe ayarlanıp daha önce olduğu gibi Main içerisinde de sıkıntı olmadan görüntüyü basabildim. Kamera, DCMI, DCMI_Crop özelliği ve DMA2D vs hepsi çalışıyor. Mainde kendim basıyorum ve donma veya titreme yok.

Sorun sadece 320x240 çözünürlükte oluyor. Bu konuda fikrinizi almak isterim. 320x240 çözünürlükte neden problem olur? Bu sorunun cevabını arıyorum.

Belki kamerayı 640x480 çözünürlüğe ayarlayıp bu görünütünün tam ortasında DCMI CROP ile 320x240 parça çıkarabilirim. Ama 640x480'da görüntü zoom yapılmış gibi görünüyor ve 24Mhz dahili osilatör için sadece 15FPS de çalışıyor. 30FPS için 48Mhz clock lazım. Bunun içinde ya kamera üzerindeki kristal değişecek yada MCO ile 48Mhz sinyal alıp bir şekilde kameraya uygulamak gerekir. O işde biraz sıkıntılı.

Ben bu konunun üzerine biraz daha gitmek istiyorum. Başka ne tür testler uygulayabilirim? Fikriniz var mı?



z

frame_tc_flag=0;

Bunu en sona değil de en başa almakla değişen hiç bir şey olmadımı? (Bu flag hardware ait değil mi?)
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Yok abi hardware değil.

Ben frame_tc_flag diye global bir değişken tanımladım. DCMI_Frame kesmesi gelirse bu değişkenin değerini 1 yapıyorum.

Main döngüsü içerisinde ise if ile bu değişkeni kontrol ediyorum. Değeri 1 olmuşsa  görüntüyü ekrana basıp tekrardan değişkenin değerini sıfırlıyorum. Amacım kesme alt programından bağımsız olmak. Değişken hardware değil.