cancel
Showing results for 
Search instead for 
Did you mean: 

simultanous DMA filling and USART Tx from memory + camera output

its
Associate II
Posted on November 01, 2012 at 07:56

hi:

I have interfaced camera with STM32F4 discovery. currently I am capturing the frame and after the first capture is complete, I disable Camera capture and start sending data from memory over USART2. it sequential. and works fine.

now , I want to send data over USART2 at the same time as after each DMA memory location filled by camera DATA.

Or i want to send the first frame data from DMA0 buffer while at the same time the next frame data will be filling to DMA1 buffer.(in double buffer mode)

is it possible.  and how>? any hint....

#dcmi-dma-camera #dma #usart #dcmi #wait-for-you--clive1-!-!-!
31 REPLIES 31
simonlanghart9
Associate
Posted on November 20, 2012 at 14:06

Hi tech.harris and clive

@tech.harris

You wrote ''I have interfaced camera with STM32F4 discovery. currently I am capturing the frame and after the first capture is complete, I disable Camera capture and start sending data from memory over USART2. it sequential. and works fine.''

Currently I'm trying exactly the same, I just want to capture a single image, and send the data over USART3. But I receive wrong image data (I received some data but the were just partly correct and  the length of data were always different). Is it possible that you share your/this source code. Maybe this would help to solve my problem.

To avoid misunderstandings: I do not mean the source code that use the DMA for the USART, that you've already posted.

I also use the also the TM32F4-Discovery, but this is my first experience with ARM-Processors. I hope I'm right here with my question.

Thanks for your help. I use as a camera the TCM8230MD.

Here is my shorted code:

/**********************************************************************/

uint8_t frame_buffer[50688]; //(176*144*2)

/**********************************************************************/

int main(void)

{

/* Initialization all LEDs*/

LEDs_Init();

/* USART3 initialization */

USART3_Init(57600);

/* Configure EXTI Line2 */

PushButton_Init(); 

/* Image Sensor initialization (GPIO + DCMI-GPIO,RESET,CLK,I2C,Camera START-UP-Sequence with QCIF(176*144))*/

IS_Init();

//Until here all works fine, I checked the camera signals also with the osc!!!

/* DCMI and DMA initialization */

     DCMI_DMA_Init();

     DMA_Cmd(DMA2_Stream1, ENABLE);

     DCMI_Cmd(ENABLE);

     Delay_ms(200);

     DCMI_CaptureCmd(ENABLE);

while (1)

{

}

}

/**********************************************************************/

/* DCMI and DMA initialization */

void DCMI_DMA_Init(void)

{

DCMI_InitTypeDef DCMI_InitStructure;

DMA_InitTypeDef  DMA_InitStructure;

RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);

DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; 

DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; 

DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_Low;   //VS is high when the sensor is transmitting data

DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;            //HS is high when the sensor is transmitting data

DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising;       

DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;

DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;

DCMI_Init(&DCMI_InitStructure);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

DMA_DeInit(DMA2_Stream1);

DMA_StructInit(&DMA_InitStructure);

// 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 = 0x3180; //(176*144*2)/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;

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

}

/**********************************************************************/

// EXTI for PushButton

void EXTI2_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line2) != RESET)

{

LED_Toggle(LED4_CB);

USART3_SendFrame();

/* Clear the EXTI line 1 pending bit */

EXTI_ClearITPendingBit(EXTI_Line2);

}

}

/**********************************************************************/

void USART3_SendFrame(void)

{

int i;

for(i=0;i<50688;i++)

{

USART3_SendData((uint16_t)frame_buffer[i]);

}

}

/**********************************************************************/

its
Associate II
Posted on November 21, 2012 at 09:57

@ simon

              do you have PCB or using wire connections?

Posted on November 21, 2012 at 13:30

What does USART3_SendData() look like?

Sending 50KB in a burst to a PC serial port might be overwhelming, are you using any flow control?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
simonlanghart9
Associate
Posted on November 21, 2012 at 16:03

@tech.haris 

@clive1

thanks for your support, I checked again my code several hours again, i solved the problem, now it works fine.

I changed these parts:

/************************************/

//new Buffer Size:

uint32_t frame_buffer[176*144];

/************************************/

//new DMA Buffer Size:

DMA_InitStructure.DMA_BufferSize = (sizeof(frame_buffer)/sizeof(uint32_t));

DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //not essential

/************************************/

//and the new UART send routine as follow:

void USART3_SendFrame(void)

{

int t i;

for(i = 0;i < (sizeof(frame_buffer)/sizeof(uint32_t)); i++)

//for(i=0;i<352;i++)

//for(i=0;i<40000;i++)

{

USART3_SendData((uint16_t)frame_buffer[i]);

USART3_SendData((uint16_t) (frame_buffer[i] >> 8));

USART3_SendData((uint16_t) (frame_buffer[i] >> 16));

USART3_SendData((uint16_t) (frame_buffer[i] >> 24));

}

}

/************************************/

Anyway thanks for your time, maybe i need your help another time

Simon

its
Associate II
Posted on November 22, 2012 at 06:05

it kind a basic question,, but I want to know exact sysclck operating in STM32F4 Discovery, in example projects. 

HSE=8 Mhz

HSI=?

PLL=?

thanks

Posted on November 22, 2012 at 06:12

For settings review STM32F4-Discovery_FW_v1.1.0\Project\Audio_playback_and_record\src\system_stm32f4xx.c

PLL = 336 MHz

HSI = 16 MHz
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
its
Associate II
Posted on November 23, 2012 at 06:53

and

SYSCLK=?

thanks
Posted on November 23, 2012 at 13:32

From the cited file :

*=============================================================================
* Supported STM32F4xx device revision | Rev A
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 8000000
*-----------------------------------------------------------------------------
* PLL_M | 8
*-----------------------------------------------------------------------------
* PLL_N | 336
*-----------------------------------------------------------------------------
* PLL_P | 2
*-----------------------------------------------------------------------------
* PLL_Q | 7
*-----------------------------------------------------------------------------
* PLLI2S_N | 258
*-----------------------------------------------------------------------------
* PLLI2S_R | 3
*-----------------------------------------------------------------------------

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
its
Associate II
Posted on November 26, 2012 at 06:58

hi,

  I have buffer, which is initialized by 'O' in sensor_check() function, filled by DCMI through DMA after a frame capture. when I show its content in main () through USART over hyperterminal, it depict very right result. but when I call the same routine in WaveRecorderUpdate(void) from waverecorder.c some intial portion about 300 bytes of the image data is coruptted  with 'O', from which i have initialized the buffer. any idea?

     main()

   {

      ...

      ....

  /* SysTick end of count event each 10ms */

  RCC_GetClocksFreq(&RCC_Clocks);

  SysTick_Config(RCC_Clocks.HCLK_Frequency  / 100);

 

  /* Initialize the repeat status */

  RepeatState = 0;

  LED_Toggle = 7;

 

#if defined MEDIA_IntFLASH

 

  WavePlayBack(I2S_AudioFreq_48k);

  while (1);

 

#elif defined MEDIA_USB_KEY

 

  /* Initialize User Button */

  STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);

   

  /* Init Host Library */

  USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &USBH_MSC_cb, &USR_Callbacks);

 init_usart();          

 check_sensor();

frame_capture();   // after commenting both of these lines frame_capture and while(1)

while(1);         //     i call the frame_capture through  WaveRecorderUpdate(void) which  called 

                     //         deep in USR_Callbacks. I use the same software flow of audio recorder.

 while (1)

  {

          /* Host Task handler */

                  USBH_Process(&USB_OTG_Core, &USB_Host);

                  

  }

 

#endif

 

}

WaveRecorderUpdate(void)

{

 frame_capture();

}

if data was like this 130 2 130 2 130 2 130 2 130 (which is start code of frame)

I got this from WaveRecorderUpdate(void) 79 79 79 79 79 79 79 (which is ascii for 'O')

remaining data is same. and image is constructed with little bit errors.

thanks.
its
Associate II
Posted on December 26, 2012 at 05:27

the problem in last post is solved. the problem is occurring as i am shutting down DMA immediately after next frame detection or some time due to high frequency of PCLK.

I have memory constraints to hold image data greater than 32768 bytes. Can I use external RAM/memory for that to overcome this limitation so that I can get high resolution image data? will that fast enough for DMA to write there from DCMI_DR?