AnsweredAssumed Answered

STM32F7 DMA2D Bug!!!

Question asked by Mucit23 on Feb 25, 2016
Latest reply on Feb 26, 2016 by Amel N
Hi all

I'm working with STM32F7 Discover and STM32F4-Discam, OV9655 kamera. I have a problem with the DMA2D hardware. Please help me.

I getting the image from the OV9655 camera. When all the images taken, DCMI Frame interrupt occurs. Then I start the DMA2D hardware. 

if (HAL_DMA2D_Start_IT(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, xsize, 240) == HAL_OK)
}

When the transfer is complete, it consists of the DMA2D Transfer Complete interrupt. But in reality, it conveys only a frame.  Then, the screen does not update. But the whole system continues to work (DCMI Frame interrupt, DMA2D Transfer Complete interrupt vs) 

this is my al working code
main.c
/**
  ******************************************************************************
  * @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);
         //BSP_CAMERA_SnapshotStart((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)
{
 
}
 
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;
 
}
 
/**
  * @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();
}
 
#ifdef USE_FULL_ASSERT
 
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  /* Infinite loop */
  while (1)
  {
  }
}
#endif /* USE_FULL_ASSERT */
 
/**
  * @}
  */
 
/**
  * @}
  */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

If I reduce the size of data then the system works. For example; DMA2D  transfer size 320x50
DMA2D does not work when Data size 320x60 and more. 

Sorry for my English. 

What could be the problem.. Please help me


DMA2D I have a problem with the hardware.
DMA2D I have a problem with the hardware.
DMA2D I have a problem with the hardware.
Sorry for English.

Outcomes