cancel
Showing results for 
Search instead for 
Did you mean: 

DCMI ov2640 JPEG, not working

michaelmccartyeng
Associate II
Posted on September 17, 2013 at 04:35

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);
}

#ov2640-one-frame-photo
14 REPLIES 14
michaelmccartyeng
Associate II
Posted on September 19, 2013 at 14:55

I think my clock signal is ok. I've tested several different clock sources and division as long as its within a certain range it seems to work the same. 

I'm skeptical about the pe0/1, why do so many boards have it tied to dcmi if it is tied into the accelerometer which by default has puPd interrupts? If these two bits were always being pulled low no wonder I've had so many issues with my cameras. I had rgb working for a while but it never looked quite right. 

I do plan on using the accel and investigating I can make those interrupts open drain by modifying CTRL_REG3 (22h). Then if I disable the interrupts all together I may see a change in my data. I'm no EE but I think open drain if always disabled will not drive the bus it is connected to. 

Cant believe I spelled interface wrong ! I dont work on this again for a few days but I'll update my post with my findings. 

Posted on September 19, 2013 at 15:30

The Dragon407 has them on PH11/12 (all DCMI Dx pins are H/I banks)

The joys of low pin count STM32 parts, and that the F4-DISCO isn't a straight break-out board. The 100-pin devices are particularly frustrating. I'm using the 144-pin parts, as is the Dragon407. They *REALLY* should have used the 176-pin part, as it's still awfully clashy with the external FSMC (SRAM/NAND/LCD), Ethernet, USART, SDIO.

0690X00000605VXQAY.png

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on September 20, 2013 at 18:28

This is so Great ! I changed the solder jumpers to use c8 and c9 then used those pins within my app. From there I do a DCMI->DMA->Mem transfer, on completion of that the state changes and I do a Mem->DMA->Uart Transfer. From there I have a python app that pulls the data off the serial port and saves it as a file. I attached a 160x120image.

/public/STe2ecommunities/mcu/Lists/STM32Discovery/Attachments/7624/img2.jpg

I've been trying to do this forever, about a year ago I was trying with a aptina sensor and gave up. There are so many paths to take when troubleshooting this stuff if you go down the wrong one it can set you back quite a bit.

Thanks for all the help.

On to streaming ... !

________________

Attachments :

img2.jpg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I03g&d=%2Fa%2F0X0000000bSu%2F2P0Si7zq0ZqyP5CVSp4L4G_z2LRRWdIDK6bac0s1s1o&asPdf=false
ivandevel
Associate II
Posted on October 26, 2013 at 17:49

Hello, Michael! Can you share a source code to capture a JPEG with this sensor?

Mikhail Polyakov
Associate II
Posted on September 12, 2014 at 14:44

Good day, colleagues !

I am trying to interface OV2640  with STM32F4 DCMI  to use it in pfoto mode(to take the single pictures). The datasheet for OV2640 is very poor, the modul with ov2640 have no all signals that have ov2640 chip. Please, help Me to understand following:

Is thare a way to take single photo by ov2640, store it in ov2640 for some time, and than transmit it to my CPU , or ov2640 can only produce video stream, and it is my duty to catch one frame of it and save it in memory, fast enough to keep up with the data output from the ov2640 ?

0690X00000603IRQAY.jpg