cancel
Showing results for 
Search instead for 
Did you mean: 

BSP Camera Driver not writing to Frame Buffer - using ov2640 image sensor and 32F746G board

SolH
Associate

Hi all,

I am working on a university project to build a small IOT camera. I am using the 32F746GDISCOVERY board with the STM32F746NG MCU along with the ov2460 image sensor from WaveShare, and the B-CAMS-OMV board as an adaptor.

My code is based on an example for the STMF7508 Disco board, however, I have switched out the ov9655 BSP used in the example for the ov2460 BSP provided by STM.

Initially, I am attempting to display a continuous video feed on the LCD screen using the following data path:

Image Sensor → DCMI → DMA2 → Camera Frame buffer → DMA2 → LCD Frame buffer

I am able to communicate with the image sensor through I2C and successfully read the ID. When the image sensor is initialised, I am receiving frame event callbacks, however, no data is being written to the camera frame buffer. The DMA transfer between the camera frame buffer and the LCD frame buffer seems to be working fine.

I am pretty stumped as to why no data is being written to the camera Frame buffer and I have been working solidly on this problem over the last few weeks.

It looks like there is an issue with the DCMI DMA transfer. There could also be a problem in the configuration of the image sensor, however, this seems unlikely as I am receiving frame callbacks.

I was wondering if anyone had any experience with image sensors and STM32 MCUs and might be able to point me in the right direction.

I have attached my code below along with the CubeMX configurations I am using for DCMI and DMA2. The photo below shows a white screen on the LCD where the camera feed should be displayed as the camera frame buffer is memset to 255 upon initialisation.

0693W00000Y8GNDQA3.jpg 

0693W00000Y8GMoQAN.png0693W00000Y8GMtQAN.png 

0693W00000Y8GMyQAN.png0693W00000Y8GN3QAN.png0693W00000Y8GN8QAN.pngCamera.c

#include "camera.h"
 
 
 
DMA2D_HandleTypeDef hdma2d_eval;
static TS_StateTypeDef  TS_State;
 
uint32_t  i, previous_mode = CONTINOUS_MODE;
uint32_t  *ptrLcd;
uint8_t status = CAMERA_OK;
 
 
uint8_t *cam_fb;
uint32_t cam_fb_size;
 
 
 
 
void LCD_init(void) {
 
BSP_LCD_Init();
BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
 
	uint32_t  *ptrLcd;
 
 
	  /* Init LCD screen buffer */
	  ptrLcd = (uint32_t*)(LCD_FRAME_BUFFER);
	  for (int i=0; i<(BSP_LCD_GetXSize()*BSP_LCD_GetYSize()); i++)
	  {
	    ptrLcd[i]=0;
	  }
 
	  BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, LCD_FRAME_BUFFER);
	  //BSP_LCD_LayerRgb565Init(LTDC_ACTIVE_LAYER, LCD_FRAME_BUFFER);
 
	  /* Set LCD Foreground Layer  */
	  BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER);
 
	  BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
 
	  /* Clear the LCD */
	  BSP_LCD_Clear(LCD_COLOR_BLACK);
	  BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
	  BSP_LCD_FillRect(340, 80, 80, 30);
	  BSP_LCD_FillRect(340, 150, 80, 30);
	  BSP_LCD_DrawRect(8, 8, 322, 242);
	  BSP_LCD_DrawRect(9, 9, 321, 241);
	  BSP_LCD_SetFont(&Font12);
	  BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
	  BSP_LCD_SetBackColor(LCD_COLOR_BLUE);
	  BSP_LCD_DisplayStringAt(345, 90, (uint8_t *)"CONTINUOUS", LEFT_MODE);
	  BSP_LCD_DisplayStringAt(345, 160, (uint8_t *)" SNAPSHOT", LEFT_MODE);
	  BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
 
	  printf("done screen\n");
}
 
void I2C_CameraTest(void) {
	uint16_t CameraID = 0;
	printf("\nHello World\n");
	//uint16_t ov5640_ReadID(uint16_t DeviceAddr)
	//CameraID = ov5640_ReadID(CAMERA_I2C_ADDRESS);
	CameraID = ov2640_ReadID(CAMERA_I2C_ADDRESS);
	printf("\n%i\n", CameraID);
 
 
}
 
void cameraTestLoop(void) {
	while(1) {
		I2C_CameraTest();
		HAL_Delay(500);
	}
}
 
 
void initialiseCapture(void) {
status = BSP_CAMERA_Init(RESOLUTION_R320x240);
if(status != CAMERA_OK)
{
  BSP_LCD_SetFont(&Font16);
  BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
  BSP_LCD_FillRect(10, 10, 320, 240);
  BSP_LCD_SetTextColor(LCD_COLOR_RED);
  BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
  BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"CAMERA sensor is unpluged", LEFT_MODE);
  BSP_LCD_DisplayStringAt(20, 120, (uint8_t *)"Plug the OV2640 sensor   ", LEFT_MODE);
  BSP_LCD_DisplayStringAt(20, 140, (uint8_t *)"on P1 camera connector   ", LEFT_MODE);
  BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"And restart the program  ", LEFT_MODE);
}
else
{
 
//  cam_fb_size = 320*240*2;			// Resolution * color depth; RGB565=16bit=2byte
//
//  cam_fb = (uint8_t *) malloc(cam_fb_size);
 
  memset(CAMERA_FRAME_BUFFER, 255, cam_fb_size);
 
  BSP_CAMERA_Init(RESOLUTION_R320x240);
  BSP_CAMERA_ContinuousStart((uint8_t *)CAMERA_FRAME_BUFFER);
 
}
}
 
 
 
void BSP_CAMERA_LineEventCallback(void)
{
  static uint32_t tmp, tmp2, counter;
 
  if(240 > counter)
  {
    LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_FRAME_BUFFER + tmp), (uint32_t *)(LCD_FRAME_BUFFER + 0x4B28 + tmp2));
    tmp  = tmp + 320*sizeof(uint16_t);
    tmp2 = tmp2 + (480) * sizeof(uint32_t);
    counter++;
  }
  else
  {
 
    tmp = 0;
    tmp2 = 0;
    counter = 0;
  }
}
 
 
 
 
/**
  * @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
  */
 
//void BSP_CAMERA_FrameEventCallback(void) {}
 
void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst)
{
  /* 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_OUTPUT_ARGB8888;
  //hdma2d_eval.Init.ColorMode    = DMA2D_OUTPUT_RGB565;
  hdma2d_eval.Init.OutputOffset = 0;
 
  /* Foreground Configuration */
  hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
  hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
  hdma2d_eval.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
  hdma2d_eval.LayerCfg[1].InputOffset = 0;
 
  hdma2d_eval.Instance = DMA2D;
 
  /* DMA2D Initialization */
  if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK)
  {
    if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK)
    {
      if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, 320, 1) == HAL_OK)
      {
        /* Polling For DMA transfer */
    	 // printf("polling for DMA transfer!");
        HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
      }
    }
  }
  else
  {
    /* FatFs Initialization Error */
	  printf("/nFatFs Initialization Error/n");
    while(1);
  }
}

Camera.h

#ifndef INC_CAMERA_H_
#define INC_CAMERA_H_
 
#include "stm32f7xx_hal.h"
#include "stm32746g_discovery.h"
#include "stm32746g_discovery_sdram.h"
#include "stm32746g_discovery_camera.h"
#include "stdio.h"
#include "stdlib.h"
#include "LCD.h"
#include "string.h"
//#include "ov5460.h"
//#include "../../Drivers/BSP/Components/ov5640/ov5640.h"
//#include "../Drivers/BSP/Components/ov9665/ov9665.h"
 
 
#define CAMERA_FRAME_BUFFER               0xC0260000
//#define CAMERA_FRAME_BUFFER               0x60000000
#define LCD_FRAME_BUFFER                  0xC0130000
 
//#define CAMERA_I2C_ADDRESS (uint16_t)0x60
void I2C_CameraTest(void);
//void cameraTestLoop(void);
void statusTest(void);
void initialiseCapture(void);
//void DCMI_GetCaptureMode(void);
//void runCamera(void);
void BSP_CAMERA_LineEventCallback(void);
void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst);
 
#endif /* INC_CAMERA_H_ */

Thank you,

1 ACCEPTED SOLUTION

Accepted Solutions
KDJEM.1
ST Employee

Hello @SolH and welcome to the Community :),

I checked the OV2640 datasheet camera and I found that the vertical synchronization polarity should be Active High. And you have configured the vertical synchronization polarity at active low.

Could you please change this configuration and let me know if the issue is solved.

For more details, I advise you to refer the AN5020 and precisely Hardware (or external) synchronization section.

Also, I recommend you to take a look at DCMI examples based on STM32CubeMX shared in AN5020 application note.

Thank you.

Kaouthar.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

1 REPLY 1
KDJEM.1
ST Employee

Hello @SolH and welcome to the Community :),

I checked the OV2640 datasheet camera and I found that the vertical synchronization polarity should be Active High. And you have configured the vertical synchronization polarity at active low.

Could you please change this configuration and let me know if the issue is solved.

For more details, I advise you to refer the AN5020 and precisely Hardware (or external) synchronization section.

Also, I recommend you to take a look at DCMI examples based on STM32CubeMX shared in AN5020 application note.

Thank you.

Kaouthar.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.