2024-05-24 01:04 AM
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 */
}