AnsweredAssumed Answered

HAL+STM32F429I DISCOVERY+DCMI+DMA

Question asked by maskey.abhas on Nov 9, 2015
I am only posting this as a last resort after making sure that I could nothing more about it. Just need fresh pair of eyes to check if I have missed out something.

I am trying to use the HAL library to interface a POA030R image sensor (custom board) with the STM32F429I DISCOVERY Board through DCMI using DMA to store buffer on the internal memory. Right now the issue is:

1. The camera is shooting blanks (0x00h)
2. Which i checked with the PCLK and there's basically nothing (used digital oscilloscope)

My code is as follows:
my main(void) code:
HAL_Init();
 
/* Configure the system clock to 180 MHz */
SystemClock_Config();
 
/* Configure MCO1 as 22.5 MHz for image sensor clock */
HAL_RCC_MCOConfig (RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_2);
 
/* POA030R Camera function calls */
Configure_POA030R();
 
/* Initialize DMA and then DCMI */
POA030R_Init();
 
/* Extract Image */
POA030R_ImageOut();
 
/* Infinite loop */
while (1)
{
}

Configure_POA030R function basically calls on I2C to configure the internal registers to set the mode to QVGA in YCbCr (Y Cb Y Cr) format

The POA030R_Init() function is where I initialize DMA and DCMI
 
static void POA030R_Init(void)
{
  static DMA_HandleTypeDef hdma_poa030r;
  GPIO_InitTypeDef GPIO_Init_Structure;
  DCMI_HandleTypeDef *hdcmi = &hdcmi_poa030r;
   
  /*** Enable peripherals and GPIO clocks ***/
  /* Enable DCMI clock */
  __DCMI_CLK_ENABLE();
 
  /* Enable DMA2 clock */
  __DMA2_CLK_ENABLE();
   
  /* Enable GPIO clocks */
  __GPIOA_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();
  __GPIOD_CLK_ENABLE();
  __GPIOE_CLK_ENABLE();
 
  /*** Configure the GPIO ***/
  /* Configure DCMI GPIO as alternate function */
  /* PA4    HREF
     PA6    PIXCLK */
  GPIO_Init_Structure.Pin       = GPIO_PIN_4 | GPIO_PIN_6;
  GPIO_Init_Structure.Mode      = GPIO_MODE_AF_PP;
  GPIO_Init_Structure.Pull      = GPIO_PULLUP;
  GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
  GPIO_Init_Structure.Alternate = GPIO_AF13_DCMI; 
  HAL_GPIO_Init(GPIOA, &GPIO_Init_Structure);
 
  /* PB7    VSYNC */
  GPIO_Init_Structure.Pin       = GPIO_PIN_7 | GPIO_PIN_8;
  GPIO_Init_Structure.Mode      = GPIO_MODE_AF_PP;
  GPIO_Init_Structure.Pull      = GPIO_PULLUP;
  GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
  GPIO_Init_Structure.Alternate = GPIO_AF13_DCMI;  
  HAL_GPIO_Init(GPIOB, &GPIO_Init_Structure);
 
  /* PC6    D0
     PC7    D1
     PC11   D4 */
  GPIO_Init_Structure.Pin       = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_11;
  GPIO_Init_Structure.Mode      = GPIO_MODE_AF_PP;
  GPIO_Init_Structure.Pull      = GPIO_PULLUP;
  GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
  GPIO_Init_Structure.Alternate = GPIO_AF13_DCMI;  
  HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure);
   
  /* PD3    D5 */
  GPIO_Init_Structure.Pin       = GPIO_PIN_3;
  GPIO_Init_Structure.Mode      = GPIO_MODE_AF_PP;
  GPIO_Init_Structure.Pull      = GPIO_PULLUP;
  GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
  GPIO_Init_Structure.Alternate = GPIO_AF13_DCMI;  
  HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
 
  /* PE0    D2
     PE1    D3
     PE5    D6
     PE6    D7 */
  GPIO_Init_Structure.Pin       = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 |\
                                  GPIO_PIN_6;
  GPIO_Init_Structure.Mode      = GPIO_MODE_AF_PP;
  GPIO_Init_Structure.Pull      = GPIO_PULLUP;
  GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
  GPIO_Init_Structure.Alternate = GPIO_AF13_DCMI;  
  HAL_GPIO_Init(GPIOE, &GPIO_Init_Structure);
   
  /*** Configure the DMA ***/
  /* Set the parameters to be configured */
  hdma_poa030r.Init.Channel             = DMA_CHANNEL_1;
  hdma_poa030r.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  hdma_poa030r.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_poa030r.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_poa030r.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_poa030r.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  hdma_poa030r.Init.Mode                = DMA_CIRCULAR;
  hdma_poa030r.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
  hdma_poa030r.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;        
  hdma_poa030r.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  hdma_poa030r.Init.MemBurst            = DMA_MBURST_SINGLE;
  hdma_poa030r.Init.PeriphBurst         = DMA_PBURST_SINGLE;
 
  hdma_poa030r.Instance = DMA2_Stream1;
 
  /* Associate the initialized DMA handle to the DCMI handle */
  __HAL_LINKDMA(hdcmi, DMA_Handle, hdma_poa030r);
   
  /*** Configure the NVIC for DCMI and DMA ***/
  /* NVIC configuration for DCMI transfer complete interrupt */
  HAL_NVIC_SetPriority(DCMI_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DCMI_IRQn); 
   
  /* NVIC configuration for DMA2D transfer complete interrupt */
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
   
  /* Configure the DMA stream */
  HAL_DMA_Init(hdcmi->DMA_Handle);
   
  /* Configure DCMI for POA030R*/
  DCMI_POA030R_Init();
}
 
static void DCMI_POA030R_Init(void)
{
    DCMI_HandleTypeDef *phdcmi = &hdcmi_poa030r;
 
  /* Configure the DCMI to interface with POA030R Sensor */
  phdcmi->Init.CaptureRate            = DCMI_CR_ALL_FRAME;
  phdcmi->Init.HSPolarity             = DCMI_HSPOLARITY_LOW;
  phdcmi->Init.SynchroMode            = DCMI_SYNCHRO_HARDWARE;
  phdcmi->Init.VSPolarity             = DCMI_VSPOLARITY_LOW;
  phdcmi->Init.ExtendedDataMode       = DCMI_EXTEND_DATA_8B;
  phdcmi->Init.PCKPolarity            = DCMI_PCKPOLARITY_RISING;
  phdcmi->Instance                    = DCMI;
 
  HAL_DCMI_Init(phdcmi);
}

After that I call in the POA030R_ImageOut function to spit out the image
static void POA030R_ImageOut(void)
{
  HAL_DCMI_Start_DMA(&hdcmi_poa030r, DCMI_MODE_SNAPSHOT, (uint32_t) POA030R_BUFFER, 0x9600);
   
  /*Random check of value*/
  printf ("0x%x\n\r", POA030R_BUFFER[2]);
}
0x9600 refers to hex value of (320*240*2/4) where 320*240*2 total size in Bytes divided by word transfer (4Bytes) so 0x9600 is the DMA buffer size
the buffer is declared as:
/* Buffer for image as defined in main.h */
uint8_t POA030R_BUFFER[IMAGE_BUFFER_SIZE];
 
 
/* For POA030R receive buffer (QVGA) [main.h] */
#define PIXEL_WIDTH                     320
#define PIXEL_HEIGHT                    240
#define PER_PIXEL_BYTES                 2   /* Average of 2 Bytes per pixel */ 
#define IMAGE_BUFFER_SIZE               (PIXEL_WIDTH * PIXEL_HEIGHT * PER_PIXEL_BYTES)

I have placed my interrupts on the main.c file. They have been declared as:
/**
  * @brief  This function handles DMA2 Stream1 interrupt request.
  * @param  None
  * @retval None
  */
void DMA2_Stream1_IRQHandler(void)
{
  HAL_DMA_IRQHandler(hdcmi_poa030r.DMA_Handle);
}
 
/**
  * @brief  This function handles DCMI interrupt request.
  * @param  None
  * @retval None
  */
void DCMI_IRQHandler(void)
{
 HAL_DCMI_IRQHandler(&hdcmi_poa030r);
}

If anyone could let me know what the issue is, i would be more than grateful. Thanks in advanced!

Outcomes