cancel
Showing results for 
Search instead for 
Did you mean: 

DCMI Issues, looking for insight.

stbbrad3
Associate II
Posted on November 07, 2011 at 17:23

Hello everyone,

I have had a couple porblems resolved by sharing with the community here. I am now moving into the toughest part of my project. I am incorporating a Micron VGA CMOS Digital Image Sensor that I have previously had working on an 8051 through an Altera FPGA chip.

The image sensor only put out intersperesed 8 bit serial LVDS so I have it going through a de-serializer and all the signals look perfectly fine as expected. I have 1 byte of data the Pixel clock and H and V Syncs all wired into the STM3220g eval board, which has the F207IG on board.

Now that the quick introduction is out of the way. Let me get started out with what I am seeing. I have DMA setup to transfer a picture into SRAM and this is happening, except for the fact that all my image data is exactly the same. The DMA is transferring 0x04040404 into memory as that is all that is put in the data register. I know this is not all the data that the camera is putting out as it I have it setup in test mode putting out a grayscale image. I know that it is seeing something from the camera though as it is not getting anythign in the data register when i disconnect the camera.

I do notice some discrepencies between the memory map file and the reference manual from what I am actually seeing in the DCMI_SR. In Crossworks Studio I am seeing:

DRDY

CECS

SECS

CEIS

SEIS

Where in the reference manual it is showing:

FNE

VSYNCE

HSYNC

Has anyone else noticed these differences or know what the CECS,SECS, CEIS, SEIS may stand for?

The DRDY, CECS, and SECS flags are the onse being set. When DRDY is set so is CECS, and SECS is reset. When SECS is set, DRDY and CECS are reset.

Regarding my issue, I know I really didn't address with a question as I am a bit confused still with working with this DCMI. I will at keep everyone posted on my progress.

Please if you have any experience using DCMI and are willing to share I am willing to read!

Thanks,

Brad
47 REPLIES 47
re
Associate II
Posted on January 27, 2012 at 01:45

Hi H.brad. I'm working with the DCMI module as well and was successful to output the image to the FSMC. As I need to do some image processing, I need to output the data to the SRAM before showing it in the FSMC. But I'm having trouble to output it to SRAM. I believe I'm making some mistake in the DMA and SRAM (?) settings. 

I'm brand new to STM32, DMA and SRAM, so I don't really know what I need to configure in order to make it work. do you have the example code you can show me?

stbbrad3
Associate II
Posted on January 27, 2012 at 14:55

Hello Gasoto,

I am trying to undertand what you mean by you successfully output o FSMC but have trouble with SRAM. From what I understand the FSMC is only responsible for transfering to SRAM. Assuming you get your SRAM working correctly with simple block write/read tests you can check out the other thread I started about the DMA issues I was having.

Depending on your image size you may need to look into the double buffer somewhat explained in the other thread.

You can find it here: [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Some more DCMI problems F207IG&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx?Paged%3DTRUE%26p_StickyPost%3D%26p_DiscussionLastUpdated%3D20120122%252022%253a30%253a16%26p_ID%3D20595%26View%3D%257bF47A9ED8%252dE726%252d42BE%252dACED%252d732F13B66581%257d%26FolderCTID%3D0x012001%26PageFirstRow%3D41&currentviews=130]Some More DCMI Issues.

Good Luck.

Brad

re
Associate II
Posted on January 27, 2012 at 16:47

Oh yeah. It was a huge misunderstanding on my part (I was thinking the FSMC driver was responsible only to drive the image to the LCD display).  I was able to drive the image to the LCD driver, which uses FSMC, but I'm unable to store the image in any other place of the SRAM, I believe I'm having some issues in configuring either DMA or FSMC.

Now that I noticed what it actually is, I'll try to configure the FSMC the same way you did above.

Currently I'm working with a 320x240 px image for testing purposes, but I expect to use the full range of my ov2640 sensor and get it working on 2MP.

Thanks for the fast reply. I'll let you know if I get it working properly :)

stbbrad3
Associate II
Posted on January 27, 2012 at 21:28

I am still kind of new with these micros and programming in general. The LCD from what I understand is pulling from an SRAM address. What I think would be your best bet would be to transfer from the DCMI to the FSMC(SRAM) to a location that you can perform your image processing. While your processing is happening you could directly read from the orignal image and write to the LCD SRAM address. When finish set some sort of flag or trigger that will update your display. 

I am sure there are better solutions, but this may be a good starting point.

Cheers,

Brad

re
Associate II
Posted on January 27, 2012 at 21:32

Ok, I was able to successfully write into the sram base address (0x64000000).

I set up the camera to snapshot mode, and in the frame interruption I reset the M0AR to 0x64000000, send Enable to the DMA stream and send the DCMI command to get a new  frame capture. but the DMA doesn't seem to update the data after the first frame is captured, and no new frame interrupt is generated.  Below is the code for my frame interrupt. Is there anything wrong with that?

  DCMI_ClearFlag(DCMI_FLAG_FRAMERI);

    

  DCMI_CaptureCmd(ENABLE);

  

  DMA2_Stream1->M0AR = 0x64000000;

  DMA_Cmd(DMA2_Stream1, ENABLE); 

    

    My DMA channel is configured as below:

DMA_InitStructure.DMA_Channel = DMA_Channel_1;  

  DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;

  //DMA_InitStructure.DMA_Memory0BaseAddr =  FSMC_LCD_ADDRESS;

  DMA_InitStructure.DMA_Memory0BaseAddr =  0x64000000;

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

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

  DMA_DoubleBufferModeConfig(DMA2_Stream1, 0x6403FFFC, DMA_Memory_0);

  DMA_DoubleBufferModeCmd(DMA2_Stream1, ENABLE);

  DMA_ITConfig(DMA2_Stream1, DMA_IT_TC , ENABLE);

There's actually no need for me to output the image to the lcd, I was doing that only to verify the data. 

By the way, I see that you generated BMPs from the data you captured. How did you do that? 

  

stbbrad3
Associate II
Posted on January 30, 2012 at 19:13

Hello again,

Is the only place you enable your DMA transfer in the Interrupt handler for the frame end?

From my experience for single frame capturing I enable the DMA first. I only poll for the frame end in a while loop. The intterupt that should be serviced for larger images in double buffer mode is the DMA Stream interrupt... see my code for capturing one image below.

uint8_t Camera_Capture_Image ( void )

{      

    /* Disable any old interrupts before enabling DMA 

       WARNING: This is not specified in the reference manual,

                but MUST be done before enabling stream.       */

    DMA_ClearITPendingBit ( DCMI_DMA_STREAM, DMA_IT_TCIF1  |

                                             DMA_IT_HTIF1  |

                                             DMA_IT_TEIF1  |

                                             DMA_IT_DMEIF1 |

                                             DMA_IT_FEIF1  );

 

    DMA2_Stream1->M0AR = DCMI_IMAGE_SRAM_ADDRESS;

    DMA_DoubleBufferModeConfig(DMA2_Stream1, DCMI_IMAGE_SRAM_ADDRESS + ( 0xffff * 4 ), DMA_Memory_0);

 

    /* Enable DMA transfer */

    DMA_Cmd ( DCMI_DMA_STREAM, ENABLE );

   

    /* Wait for DMA to start up */

    while ( DISABLE == DMA_GetCmdStatus ( DCMI_DMA_STREAM ) );

    /* Enable DCMI interface */

    DCMI_Cmd ( ENABLE );    

    DCMI_ITConfig ( DCMI_IT_FRAME, ENABLE );  

   

    /* Start Image capture */

    DCMI_CaptureCmd ( ENABLE );

   

    while ( 0 == DCMI_GetFlagStatus ( DCMI_FLAG_FRAMERI ) );

   

    DCMI_CaptureCmd ( DISABLE );   

    DCMI_Cmd ( DISABLE );

    DMA2_Stream1->M0AR = DCMI_IMAGE_SRAM_ADDRESS;

    DMA_DoubleBufferModeConfig(DMA2_Stream1, DCMI_IMAGE_SRAM_ADDRESS + ( 0xffff * 4 ), DMA_Memory_0);

    DMA_Cmd ( DCMI_DMA_STREAM, DISABLE );

    /* Wait for DMA to stop */

    while ( ENABLE == DMA_GetCmdStatus ( DCMI_DMA_STREAM ) );

     

    return ERROR_SUCCESS;

} void DMA2_Stream1_IRQHandler(void)

{

    static uint8_t ucCount = 0;

    DMA_ClearITPendingBit ( DMA2_Stream1, DMA_IT_TCIF1 );

    ucCount++;

    // The first interrupt moves the initial buffer out by 0x7fff8

    if ( 1 == ucCount )

    {

        DMA2_Stream1->M0AR = DCMI_IMAGE_SRAM_ADDRESS + ( 0xFFFF * 8 );

    }

    // The third interrupt will

//    else if ( 3 == ucCount )

//    {

//        DMA2_Stream1->M0AR = DCMI_IMAGE_SRAM_ADDRESS;

//        DMA2_Stream1->M1AR = DCMI_IMAGE_SRAM_ADDRESS + ( 0xFFFF * 4 );

//        ucCount = 0;

//    }

}

Brad

re
Associate II
Posted on February 01, 2012 at 20:43

Great news! it worked!

I'm also doing the image processing already. The next steps are configure the ov2640 sensor to aquire bigger pictures and move to the USB stack. but that will be topic for a new thread, shall I require any assistance. Thank you guys so far for the help =)

baris_togrul
Associate II
Posted on June 23, 2012 at 12:49

Hi guys ! I am tring to get a valid data from DCMI but no success so far.

Main idea is taking QCIF B&W image from DCMI through DMA and write this data to a variable located in internal ram.

By the way i am using ov7670 with 32f407vg discovery board.

I suspect that DCMI port is not sending request signal to DMA.

I did not adjust any interrupt.Do i have to ?

I am using logic analyzer to see data flow.SCCB and data flow looks valid on the camera side

lead me my masters:)

uint32_t image[13000]; //Ram allocated for qcif image

void init_xclk()

//8mhz clock signal created.working properly so i did not write here

}

void init_registers()

    //ov7670 registeres are adjusted in here.working properly so i did not write here

}

void init_dcmi()

{

  GPIO_InitTypeDef GPIO_InitStructure;

  DCMI_InitTypeDef DCMI_InitStructure;

  DMA_InitTypeDef  DMA_InitStructure;

 GPIO_InitTypeDef portd;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |       RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOB, ENABLE);

RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

  DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;

  DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;

  DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; 

  DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;  //I am not sure but datasheet says so 

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

    

  DMA_Cmd(DMA2_Stream1, DISABLE);

  DMA_DeInit(DMA2_Stream1);

  DMA_InitStructure.DMA_Channel = DMA_Channel_1;  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x50050028; //DCMI DR 

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&image[0];

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

  DMA_InitStructure.DMA_BufferSize = 1; 

  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_Circular;//

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

  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;

  DMA_Init(DMA2_Stream1, &DMA_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9 ;

  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_4 | GPIO_Pin_6 | GPIO_Pin_10 | GPIO_Pin_9 ;

  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_0 | GPIO_Pin_1 | 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(GPIOE, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_DCMI);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,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);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_DCMI);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_DCMI);

}

int l;

int main(void) {

 

  for(l=0;l<13000;l++) image[l]=1; //initial value adjusting for debugging

  init_xclk();

  init_dcmi();

  SCCB_GPIO_Config(); //this function coming from ahother c file.but this also works properly.

  init_registers();

DMA_Cmd(DMA2_Stream1,ENABLE);

DCMI_Cmd(ENABLE);

delay_us(10000);

DCMI_CaptureCmd(ENABLE);

  while (1) ;

  

}

re
Associate II
Posted on June 23, 2012 at 22:00

I would suggest you to set a frame capture interrupt, and check the data on the DMA output address. Your problem might be on DMA configuration ;)

I´ve some issues with ov7740, do you  know the compatibility between this model and the one you´re using? Do you have any software configuration tool for OV sensors?

baris_togrul
Associate II
Posted on June 26, 2012 at 19:51

I tried to add frame capture interrupt.

i added 

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

to enable interrupt,after that i also added 

DCMI_ITConfig(DCMI_IT_FRAME,ENABLE);

and

void DCMI_IT_FRAME_IRQHandler(void)

{

GPIO_SetBits(GPIOD,GPIO_Pin_12); // connected to the green led 

}

i set break point into interrupt but code never reaches here.

so problem is also at DCMI i guess :)

I do not have any software conf. tool for ov7670,instead of i configure it in my code if you meant this.

(sorry for the late response.girls hu? way more complicated than arm stuffs :)  )