Question
DCMI ov2640 JPEG, not working
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