cancel
Showing results for 
Search instead for 
Did you mean: 

Appropriate method to store pixel data to data buffer?

wyattcurtis
Associate

I am attempting to interface an OV7670 camera with an STM32F4 discovery board via DCMI. Upon image capture, I am receiving an overflow error. I believe (but am not certain) this is due to the method I am using to store pixel data to the buffer. I am trying to capture a single QVGA (320*240) image with RGB565 resolution. There are two bytes per pixel, and thus two pixels per word exerted by the DCMI. My current method is to store to an array; however, I feel that I am ignoring a critical component on how to properly address/configure memory buffers for DMA storage. My ultimate objective is to move this data from the DMA memory buffer to an LCD and PC (via UART).

I have attached my DCMI/DMA configuration code, in addition to screenshots of some of the errors I am receiving, these errors were recorded by reducing the buffer size to 100. Could this be the cause of my observation of this error (would occur only in the case where the data transfer length < frame transfer length)? From my understanding an overrun may occur when the DMA has finished its data transfer length but the DCMI is still sending data, thus triggering an overrun. Though I am no expert.

Can someone help me out with this?

DCMI/DMA Configuration:

void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hdcmi->Instance==DCMI)
  {
    /* Peripheral clock enable */
    __HAL_RCC_DCMI_CLK_ENABLE();
  
    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
 
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    /* DCMI DMA Init */
    /* DCMI Init */
    hdma_dcmi.Instance = DMA2_Stream1;
    hdma_dcmi.Init.Channel = DMA_CHANNEL_1;
    hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
    hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_dcmi.Init.Mode = DMA_NORMAL;
    hdma_dcmi.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
    hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    hdma_dcmi.Init.MemBurst = DMA_MBURST_INC4;
    hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
    if (HAL_DMA_Init(&hdma_dcmi) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(hdcmi,DMA_Handle,hdma_dcmi);
 
    /* DCMI interrupt Init */
    HAL_NVIC_SetPriority(DCMI_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DCMI_IRQn);
  }
}

Main Function:

int main(void)
{
  HAL_Init();
 
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DCMI_Init();
  MX_I2C1_Init();
  MX_UART4_Init();
	InitOV7670();
	__HAL_DCMI_ENABLE_IT(&hdcmi,DCMI_IT_ERR | DCMI_IT_FRAME | DCMI_IT_OVF | DCMI_IT_VSYNC);
	__HAL_DCMI_DISABLE_IT(&hdcmi, DCMI_IT_LINE);
	HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
	static uint32_t FRAME_BUFFER[320*240/2];
  HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t) FRAME_BUFFER,  320*240/2);
  while (1)
  {
  }
}

2 REPLIES 2

Hi. What microcontroler do you use?

Uc.2361
Associate II

Hi @oleksandr.karbivsky​ 

As he mentioned the it is STM32f4 discovery board , the controller would be STM32F407VGT6