2011-11-07 08:23 AM
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, Brad2012-01-26 04:45 PM
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?2012-01-27 05:55 AM
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¤tviews=130]Some More DCMI Issues. Good Luck. Brad2012-01-27 07:47 AM
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 :)2012-01-27 12:28 PM
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, Brad2012-01-27 12:32 PM
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?2012-01-30 10:13 AM
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; // } } Brad2012-02-01 11:43 AM
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 =)2012-06-23 03:49 AM
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 sidelead me my masters:)uint32_t image[13000]; //Ram allocated for qcif imagevoid 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) ; }2012-06-23 01:00 PM
2012-06-26 10:51 AM
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);andvoid 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 :) )