Skip to main content
Associate
May 24, 2024
Question

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

  • May 24, 2024
  • 0 replies
  • 798 views

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 */

}