cancel
Showing results for 
Search instead for 
Did you mean: 

DCMI camera interface program with DMA with STM32f4-discovery board

theparitt
Associate II
Posted on July 23, 2012 at 02:15

Hi,

I am now trying to integrate my STM32Discovery board with OV7670 camera module without using any external ram from LCD. However I found a problem and I cannot get any data. I have tested it in many ways from counting the number of HCLK line per VSYNC to see the camera-output signal from my oscilloscope. I found the problem that everytime I enable camera-capture ( DCMI_CaptureCmd(Enable) ) It always generate overflow interrupt ( DCMI_GetFlagStatus(DCMI_FLAG_OVFRI) == SET). I suspect that my DMA procedure is incorrect. Could someone help me to trace my code to find errors? Note: I set my OV7670 output resolution to 320x240 QVGA. First i declare memory to store the data from camera

int8_t frame_buffer[320*240]; //store frame data in here

Here is the code that I initialize my GPIO and also enable interrupt for debugging purpose..

int8_t frame_buffer[320*240];
EXTI_InitTypeDef EXTI_InitStructure;
void DCMI_GPIO_Configure()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB
| RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE);
/* B7: VSYNC*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);
/* A4: HSYNC*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);
/* A6: PCLK*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);
/* C6: data0*/
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI);
/* C7: data1*/
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI);
/* E0: data2*/
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI);
/* E1: data3*/
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI);
/* E4: data4*/
GPIO_PinAFConfig(GPIOE, GPIO_PinSource4, GPIO_AF_DCMI);
/* B6: data5*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);
/* E5: data6*/
GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_DCMI);
/* E6: data7*/
GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_DCMI);
/* DCMI GPIO configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
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_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(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
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(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
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(GPIOE, &GPIO_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

Here is my DCMI configuration part.

void DCMI_Configure(void)
{
DCMI_InitTypeDef DCMI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/*** Configures the DCMI to interface with the OV2640 camera module ***/
/* Enable DCMI clock */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);
/* DCMI configuration */
//bit[14]: DCMI_Enable
//bit[13:12]: reserved
DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; //bit[11:10]: 8bit-data/pclk
DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_1of4_Frame; //bit[9:8]: Frame Capture Rate Control
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High; //LOW?HIGH? //bit[7]: VSYNC active @low
DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_High; //bit[6]: HSYNC active @high
DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; //bit[5]: PCLK at Rising Edge
DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; //bit[4]: use hardware VSYNC/HSYNC
//DCMI_JPEGCmd(ENABLE/DISABLE) bit[3]: JPEG Mode
//bit[2]: Crop mode
DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; //bit[1]: capture mode 0:continue(หลังจา�? Capture�?ล้ว CaptureCmd ยัง Enable) 1:snapshot
//bit[0]: capture 0:disable/1:enable
//ตั้งค่าทั้งหมดให้ DCMI
DCMI_Init(&DCMI_InitStructure);
//----- mask interrupt for DCMI -----
DCMI_ITConfig(DCMI_IT_VSYNC, ENABLE);
DCMI_ITConfig(DCMI_IT_LINE, ENABLE);
DCMI_ITConfig(DCMI_IT_FRAME, ENABLE);
DCMI_ITConfig(DCMI_IT_OVF, ENABLE);
DCMI_ITConfig(DCMI_IT_ERR, ENABLE);
/* 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_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(DCMI_BASE + 0x28);
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&frame_buffer[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 0xFFFF;
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_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
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);
}

and Here is my main.c

void main()
{ 
......
DCMI_GPIO_Configure()
DCMI_Configure(void)
.....
DMA_Cmd(DMA2_Stream1, ENABLE);
DCMI_Cmd(ENABLE);
DCMI_CaptureCmd(ENABLE);
int z = 0;
while(1);
}

and this is the way I debug my code using interrupt .

int count = 0;
int start = 0;
void DCMI_IRQHandler(void)
{
if(DCMI_GetFlagStatus(DCMI_FLAG_VSYNCRI) == SET)
{
if(start == 0)
{
start = 1;
}
else
{
start = 0;
}
}
else if(DCMI_GetFlagStatus(DCMI_FLAG_LINERI) == SET)
{
if(start == 1)
{
count++;
}
else
{
if(count != 0)
{
//printf(''count: %d \n\n'', count); //just dor counting the number of line
}
count = 0;
}
}
else if(DCMI_GetFlagStatus(DCMI_FLAG_FRAMERI) == SET)
{
printf(''DCMI_FLAG_FRAMERI \n\n'');
}
else if(DCMI_GetFlagStatus(DCMI_FLAG_ERRRI) == SET)
{
printf(''DCMI_FLAG_ERRRI \n\n'');
}
else if(DCMI_GetFlagStatus(DCMI_FLAG_OVFRI) == SET)
{
printf(''DCMI_FLAG_OVFRI \n\n''); //********** Unfortunately.. my code always comes here
}
DCMI_ClearFlag(DCMI_FLAG_VSYNCRI);
DCMI_ClearFlag(DCMI_FLAG_LINERI);
DCMI_ClearFlag(DCMI_FLAG_FRAMERI);
DCMI_ClearFlag(DCMI_FLAG_ERRRI);
DCMI_ClearFlag(DCMI_FLAG_OVFRI);
}

So my first thought is DMA error. I am not sure how to fix it. Everything seems correct. The reason that I don't want to use LCD and connect as external ram because I would like to only save the data to SD card and make my system as small as possible. I don't need to display an image to a user. :) #ask-smarter-questions #dcmi-dma-stm32f4-sicovery-camera
28 REPLIES 28
huangfeiquan
Associate
Posted on August 01, 2012 at 17:12

I'v been got in the same issue.If you get new situation, please update it here.Thank you!

huangfeiquan
Associate
Posted on August 01, 2012 at 17:20

My issues are 

1. DCMI overflow interrupttion comes out all the time. If VSYNC and HSYNC polarity are set low, overflow doesn't come out any more, but data in DR register is empty.

2. The other issue is that DMA doesn't transmit data from DR register to memory. DMA interruptions never occur.

amin23
Associate II
Posted on August 02, 2012 at 09:21

Hi,

First of all to store QVGA image you need at least 150k-Byte of memory, because the image size is 320*240*2 = 150KByte (2 means the image resolution is 16-bit)

So ''int8_t frame_buffer[320*240];'''' should be ''uint8_t frame_buffer[320*240*2];''

// DMA2 configuration

DMA_InitStructure.DMA_Channel = DMA_Channel_1;

DMA_InitStructure.DMA_PeripheralBaseAddr =  (uint32_t)(DCMI_BASE + 0x28);

DMA_InitStructure.DMA_Memory0BaseAddr =  (uint32_t)frame_buffer;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

DMA_InitStructure.DMA_BufferSize = 0x9600;//0x9600 = Image size /4

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_MemoryDataSize_Word;

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// First take one picture

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;

Here below few comments:

I see. Thanks for point it out.  How can I transfer data larger than 0xFFFF. ?   

 

since my data is 320 * 240 = 76800 which is larger than the limitation of DMA.

>>> the Max DMA Buffer Size is 0xFFFF word, this means 0xFFFF * 4 = 262140 Bytes

When I read frame_buffer array, I get 0 0 0  0 0 0 for every pixel

>>> these is the fix: DMA_InitStructure.DMA_Memory0BaseAddr =  (uint32_t)frame_buffer;

chtatasever
Associate II
Posted on January 16, 2013 at 12:36

Hi, when I try to compile it I get browse errors that files are not available. Could you tell me how to add these files before compile'em? Thanks.

chtatasever
Associate II
Posted on January 16, 2013 at 12:54

Hi moodaeng,

or can you pls send me the project files? adnanoktar41@hotmail.com

Posted on January 16, 2013 at 16:06

Hi, when I try to compile it I get browse errors that files are not available. Could you tell me how to add these files before compile'em? Thanks.

 

You'll need to learn how to drive your unspecified tool-chain/IDE. This may mean you need to ADD files to your project from the F4 firmware libraries, and make sure you have the assorted INCLUDE PATHS specified so the compiler can find what it's looking for. The firmware libraries include template projects for the bigger tool chain vendors. If you are using MAKE you will need to add ''-I'' options to the compiler command line which specify the directory(s) in which the assorted include files may exist in.

Assuming the OP doesn't return, provide more context about your situation, what you're using, which files is it missing, etc.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
chtatasever
Associate II
Posted on January 16, 2013 at 18:12

First of all, thanks a lot for your interest; I am trying to hold the data from OV7670 camera using DCMI module in an array. I am using Keil uVision 4 to compile. I copied codes  and saved each of them with extension of .c in the project folder (for example GPIO_Configure as the name of file for first part of codes). I am looking for F4 firmware libraries now. Any further suggestions? 

Posted on January 16, 2013 at 19:15

Well definitely project templates for Keil 4

http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4discovery_fw.zip

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
chtatasever
Associate II
Posted on January 16, 2013 at 19:58

chtatasever
Associate II
Posted on January 17, 2013 at 20:21

at least can you tell me how can I implement this project? I've downloaded the rar file you suggested stm32f4discovery_fw.zip. thanks.