AnsweredAssumed Answered

DCMI ov2640 JPEG, not working

Question asked by mccarty.michael on Sep 17, 2013
Latest reply on Sep 12, 2014 by polyakov.mikhail
Hello All,
  I've been working with the ov2640 example. I'm 95% sure I can get QQVGA out of the camera just fine; however, when I run through the registers for Jpeg I never get anything sensible out of the camera. I've tried toggling all of the clock signals and I've tried with jpeg on and off. I've even tried the registers from the ArduCam. Sometimes I get a lot of 0,1,2,3 data or 11,12,13 data but I never see any data that looks anything like jpeg. 

In the example ov2460 they dont ever actually use the jpeg modes since they were outputting directly to the lcd. 

I watch the dma2_stream1 ndtr register after the dcmi operation returns a frame int. With one setting of clocks I get about 8k of data used in the dma, but is all zeros when I look at the data. Most/all other settings I get all of the dma data (ntdr=0) or no bytes used in dma. When it uses all the bytes its garbage data, so I think I'm just enabling the clocks when I should not, getting garbage data (as I should). 

Any pointers are much appreciated ! If I can get jpeg data from this camera it will be the start of something wonderful ! 

/**
  * @brief  Initializes the hardware resources (I2C and GPIO) used to configure
  *         the OV2640 camera.
  * @param  None
  * @retval None
  */
void OV2640_HW_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  I2C_InitTypeDef  I2C_InitStruct;
 
  /*** Configures the DCMI GPIOs to interface with the OV2640 camera module ***/
  /* Enable DCMI GPIOs clocks */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE);
 
  /* Connect DCMI pins to AF13 ************************************************/
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);//HSYNC
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);//PCLK
 
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI);
 
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);//VSYNC
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_DCMI);
 
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource4, GPIO_AF_DCMI);
 
    /* DCMI GPIO configuration **************************************************/
    /*
  D0 -- PC6
  D1 -- PC7
  D2 -- PE0
  D3 -- PE1
  D4 -- PE4
  D5 -- PB6
  D6 -- PB8
  D7 -- PB9
  PCK - PA6
  HS -- PA4
  VS -- PB7
  XCLK -- PA8 // mc0 driven
  Y1,Y0 Not connected
  RST -- PC12 // active low
  PWDN -- PC10 // active hi
  */
   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; 
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
 
  /* PCLK(PA6) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  // setup the pwdn and rst pins
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 |GPIO_Pin_12;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  // pdwn set low to disable (active high)
  GPIO_ResetBits(GPIOC, GPIO_Pin_10);
  // rst low to reset for 200 ms
  GPIO_ResetBits(GPIOC, GPIO_Pin_12);
  Delay(200);
  // rst high to disable (active low)
  GPIO_SetBits(GPIOC, GPIO_Pin_12);
  // should be running now !
   
 
  /****** Configures the I2C2 used for OV2640 camera module configuration *****/
 /* I2C2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
 
  /* Connect I2C2 pins to AF4 */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);
   
  /* Configure I2C2 GPIOs */ 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  /* Configure I2C2 */
  /* I2C DeInit */
  I2C_DeInit(I2C2);
     
  /* Enable the I2C peripheral */
  I2C_Cmd(I2C2, ENABLE);
  
  /* Set the I2C structure parameters */
  I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStruct.I2C_OwnAddress1 = 0xFE;
  I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStruct.I2C_ClockSpeed = 30000;
   
  /* Initialize the I2C peripheral w/ selected parameters */
  I2C_Init(I2C2, &I2C_InitStruct);
   
  // start pa8 to drive the camera clock
  MCO1_Init();
}
 
void OV2640_Init(ImageFormat_TypeDef ImageFormat)
{
  DCMI_InitTypeDef DCMI_InitStructure;
  DMA_InitTypeDef  DMA_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /*** Configures the DCMI to interface with the OV2640 camera module ***/
  /* Enable DCMI clock */
  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);
 
  /* DCMI configuration */
  DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_SnapShot;
  DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Embedded;
  DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising;
  DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
    // check for jpeg, assume jpg if not the two bmp formats
    if(ImageFormat != BMP_QQVGA && ImageFormat != BMP_QVGA)
    {
        DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_Low;
    }
  DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;
  DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
  DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
 
  DCMI_Init(&DCMI_InitStructure);
 
    // check for jpeg, assume jpg if not the two bmp formats
    if(ImageFormat != BMP_QQVGA && ImageFormat != BMP_QVGA)
    {
        DCMI_JPEGCmd(ENABLE);
    }
 
  //
  /* DCMI Interrupts config ***************************************************/
  DCMI_ITConfig(DCMI_IT_VSYNC, ENABLE);
  DCMI_ITConfig(DCMI_IT_LINE, ENABLE);
  DCMI_ITConfig(DCMI_IT_FRAME, ENABLE);
  DCMI_ITConfig(DCMI_IT_ERR, ENABLE);
  DCMI_ITConfig(DCMI_IT_OVF, ENABLE);
       
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);
 
  /* Configures the DMA2 to transfer Data from DCMI */
  /* Enable DMA2 clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
   
  /* DMA2 Stream1 Configuration */ 
  DMA_DeInit(DMA2_Stream1);
 
  DMA_InitStructure.DMA_Channel = DMA_Channel_1; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;  
  DMA_InitStructure.DMA_Memory0BaseAddr =  (uint32_t)frame_bufferA;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = sizeof(frame_bufferA) / sizeof(u32); // since it is doing it in 32 bit words
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word; // this was half word i think ?
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;        
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
 
  /* DMA2 IRQ channel Configuration */
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);
 
}
 
void OV2640_TakePic(ImageFormat_TypeDef ImageFormat)
{
    OV2640_Init(ImageFormat);
    // start dma and dcmi
    DMA_Cmd(DMA2_Stream1, ENABLE);
    DCMI_Cmd(ENABLE);
    Delay(200);
    // start the capture !
    DCMI_CaptureCmd(ENABLE);
}

Outcomes