cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with initialization of MX_DMA2D_Init() - Camera and LCD screen

Nathanael7
Associate II

I am trying to replicate the DCMI_SnapshotMode example from scratch, because the example doesn't have an .ioc file. I must say that it also didn't work at first because some files were missing in the example. It took me weeks to piece it all together and I was so close to give up, until I solved my last problem that I still don't understand (hence this post). I'm using a STM32H747I-DISCO board, with the MB116-A09 LCD screen and the MB1379-2V8-A05 camera.

The problem comes from MX_DMA2D_Init(). After the code is generated from the .ioc file, all the initialization steps are placed just before /* USER CODE BEGIN 2 */ (line 10 below). Doing so, it will display nothing. But if MX_DMA2D_Init() is written after UTIL_LCD_Clear() (line 30 below), then it works. Why is it so? I don't understand it, because UTIL_LCD_Clear is basically just filling the screen with a rectangle. Why does it impact the DMA2D initialization?

Can somebody explain why?

I am using CubeIDE v.1.14.1.
Here is my main code with the MX_DMA2D_Init function below. This code works. I also attach the ioc file.

Many thanks for your help,
Nathanaël

 

int main(void)
{
  MPU_Config();
  SCB_EnableICache();
  SCB_EnableDCache();
  HAL_Init();
  SystemClock_Config();

  /* Initialize all configured peripherals */
  // MX_DMA2D_Init();  //HERE IS THE PROBLEM
  /* USER CODE BEGIN 2 */
  
  BSP_LED_Init(LED_GREEN);
  BSP_LED_On(LED_GREEN);

  //initialize LCD
  BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE);
  UTIL_LCD_SetFuncDriver(&LCD_Driver);

  // Reset and power down camera
  BSP_CAMERA_PwrDown(0);

  BSP_LCD_DisplayOn(0);
  UTIL_LCD_Clear(LCD_COLOR_ARGB8888_LIGHTBLUE);
  UTIL_LCD_SetFont(&Font24);
  UTIL_LCD_SetBackColor(LCD_COLOR_ARGB8888_GREEN);
  UTIL_LCD_SetTextColor(LCD_COLOR_ARGB8888_BLACK);

  //initialize DMA2D
  MX_DMA2D_Init();  //MUST be after UTIL_LCD_Clear()

  //initialize camera
  BSP_CAMERA_Init(0, CAMERA_R320x240, CAMERA_PF_RGB565);
  BSP_CAMERA_SetMirrorFlip(0, CAMERA_MIRRORFLIP_NONE);

  // Wait 1s to let auto-loops in the camera module converge and lead to correct exposure
  HAL_Delay(1000);

  UTIL_LCD_DisplayStringAt(0, 430, (uint8_t*)"Taking a picture", CENTER_MODE);

  //Start camera and take a picture
  BSP_CAMERA_Start(0, (uint8_t *)CAMERA_FRAME_BUFFER, CAMERA_MODE_SNAPSHOT);

  // Wait until camera frame is ready : DCMI Frame event
  while(camera_frame_ready == 0){}
  camera_frame_ready = 0;

  // Stop the camera to avoid having the DMA2D work in parallel of Display which cause perturbation of LTDC
  BSP_CAMERA_Stop(0);

  //put picture in the middle of the screen
  uint32_t xPos, yPos, dest_address;
  xPos = (width - res_camera_x)/2;
  yPos = (height - res_camera_y)/2;
  dest_address = (uint32_t)LCD_FRAME_BUFFER + (yPos * width + xPos) * ARGB8888_BYTE_PER_PIXEL;

  HAL_DMA2D_Start_IT(&hdma2d, (uint32_t)CAMERA_FRAME_BUFFER, dest_address, res_camera_x, res_camera_y);

  // Wait until DMA2D transfer complete : LCD frame is ready
  while(lcd_frame_ready == 0){}
  lcd_frame_ready = 0;

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    BSP_LED_Toggle(LED_GREEN);
	  HAL_Delay(750);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

static void MX_DMA2D_Init(void)
{
  /* USER CODE BEGIN DMA2D_Init 0 */
  /* USER CODE END DMA2D_Init 0 */

  /* USER CODE BEGIN DMA2D_Init 1 */
  /* USER CODE END DMA2D_Init 1 */
  hdma2d.Instance = DMA2D;
  hdma2d.Init.Mode = DMA2D_M2M_PFC;
  hdma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
  hdma2d.Init.OutputOffset = 800-320;
  hdma2d.LayerCfg[1].InputOffset = 0;
  hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
  hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
  hdma2d.LayerCfg[1].InputAlpha = 0xff;
  hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;
  hdma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR;
  hdma2d.LayerCfg[1].ChromaSubSampling = DMA2D_NO_CSS;
  if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN DMA2D_Init 2 */

  //set private callback function for complete transfer
  hdma2d.XferCpltCallback = DMA2D_TransferCompleteCallback;

  /* USER CODE END DMA2D_Init 2 */

}

 

 

0 REPLIES 0