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
Posted on November 01, 2012 at 14:29

There is no flow control between the DMA streams, so you can't set an out bound transfer against data you haven't yet received. Technically you can, but it's prone to data corruption, ie missing/losing.

Exchange regions of memory that the DMA Tx and Rx operations are using, or keep a list of regions/buffers which you pass off to each task as one completes.
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 02, 2012 at 06:30

thanks.

         if i have u array of 20 charecters name string[20]. and I want to transfer only 20 bytes of that array,

1-how can i do that?

currently I have managed to transfer data of string[] through DMA over Usart TX , but it continues to transfer data from memory even after 20 bytes....and stops after transmitting large chunk of data! I am curious about

2-how DMA control this property?

3-how it knows when to stop transmitting DATA?

4-if it didn't know then why, after transmitting a large chunk of data form memory, it stops?

Thanks.
frankmeyer9
Associate II
Posted on November 02, 2012 at 10:05

currently I have managed to transfer data of string[] through DMA over Usart TX , but it continues to transfer data from memory even after 20 bytes....and stops after transmitting large chunk of data! I am curious about

 

Providing the involved source code would be helpful.

      if i have u array of 20 charecters name string[20]. and I want to transfer only 20 bytes of that array,

 

 

1-how can i do that?

 

  DMA_InitStructure.DMA_BufferSize = 20;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

3-how it knows when to stop transmitting DATA?

 

When all data items, according to your configuration, are transmitted.

The DMA may restart with the first item, if circular mode is configured. That would not make sense for feeding the UART, but is useful for the ADC.

4-if it didn't know then why, after transmitting a large chunk of data form memory, it stops?

 

You probably configured something else then 20, and might even end up in some fault handler. But that is hard to judge without the source code...

Posted on November 02, 2012 at 10:23

Definitely sounds like you're using Circular mode, DMA by itself just needs a length/size setting, and it should stop.

Don't use Circular mode, and use the TC (Terminal Count) interrupt to set up the next transfer, or not, as appropriate.
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 02, 2012 at 10:47

very thanks. I just thought that I should upload some part of my code.

while(1) { DMA_Configuration(); DMA_Cmd(DMA1_Stream6, ENABLE); while (DMA_GetFlagStatus(DMA1_Stream6, DMA_FLAG_TCIF2) == RESET); DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_HTIF2 | DMA_FLAG_TCIF2); STM_EVAL_LEDOn(LED1); while(1); //USART_ClearFlag(USART2, USART_FLAG_TC); } ijust wanna tell after a large chunk of transmission , the transmission stops.  and LED1 didnt get ON. means the CODE stuck in between some where..!!!

 i will look upon the things u have mentioned
its
Associate II
Posted on November 02, 2012 at 11:27

Here is complete main.c

 

 

char TxString[] = ''The quick brown fox jumps over the lazy dog\r\n'';

 #define USART2_DR_ADDRESS                ((uint32_t)USART2 + 0x04)

 

 

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

 

void RCC_Configuration(void)

{

  /* Enable DMA clock */    

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);  

 

  /* Enable GPIO clock */

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

 

  /* Enable UART clock */

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

}

 

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

 

void GPIO_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

 

   

 

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

    GPIO_Init(GPIOA, &GPIO_InitStructure);  

 

   

}

 

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

 

void USART_Configuration(void)

{

 // USART_InitTypeDef USART_InitStructure;

 USART_InitTypeDef USART_InitStructure;

 

  /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/

  /* USART configured as follow:

        - BaudRate = 115200 baud

        - Word Length = 8 Bits

        - One Stop Bit

        - No parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

 

 

   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);

    

    USART_InitStructure.USART_BaudRate = 115200;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure.USART_StopBits = USART_StopBits_1;

    USART_InitStructure.USART_Parity = USART_Parity_No;

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Tx;

    USART_Init(USART2, &USART_InitStructure);

   

 

 

  /* Enable the USART1 */

  USART_Cmd(USART2, ENABLE);

}

 

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

 

void DMA_Configuration(void)

{

  DMA_InitTypeDef DMA_InitStructure1;

 

   DMA_DeInit(DMA1_Stream6);

   

 

  DMA_InitStructure1.DMA_PeripheralBaseAddr = USART2_DR_ADDRESS;

  DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure1.DMA_Mode =  DMA_Mode_Circular;    //DMA_Mode_Normal;

  DMA_InitStructure1.DMA_Priority = DMA_Priority_VeryHigh;

  DMA_InitStructure1.DMA_FIFOMode =DMA_FIFOMode_Enable;

  DMA_InitStructure1.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

  DMA_InitStructure1.DMA_MemoryBurst = DMA_MemoryBurst_Single;

  DMA_InitStructure1.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

 

    

    DMA_InitStructure1.DMA_Channel = DMA_Channel_4 ;

    DMA_InitStructure1.DMA_DIR = DMA_DIR_MemoryToPeripheral;   

     

     

    DMA_InitStructure1.DMA_Memory0BaseAddr = (uint32_t)TxString;

    DMA_InitStructure1.DMA_BufferSize = 32 ;   //sizeof(TxString) - 1;

 

    DMA_Init(DMA1_Stream6, &DMA_InitStructure1);  

}

 

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

 

int main(void)

{

  RCC_Configuration();

 

  GPIO_Configuration();

 

  USART_Configuration();

 

 

          USART_SendData(USART2,'K');  

    while (USART_GetFlagStatus( USART2, USART_FLAG_TC) != SET) ;

                         USART_ClearFlag(USART2, USART_FLAG_TC);

 

                     

      USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

        

                        

                          

            STM_EVAL_LEDOff(LED1);              

  while(1)

  {            

    DMA_Configuration();

             

    DMA_Cmd(DMA1_Stream6, ENABLE);

                  

        

    while (DMA_GetFlagStatus(DMA1_Stream6, DMA_FLAG_TCIF2) == RESET);  

    DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_HTIF2  | DMA_FLAG_TCIF2);    

               

 

                  STM_EVAL_LEDOn(LED1);

                while(1);

               

                            

         //USART_ClearFlag(USART2, USART_FLAG_TC);  

          

  }

}

 

I have received the array content on hyper terminal but after that I got  a very large chunk of data, and the stops... but LED1 didnt get ON.

thanks

Posted on November 02, 2012 at 12:57

while(DMA_GetFlagStatus(DMA1_Stream6, DMA_FLAG_TCIF2) == RESET);

DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_HTIF2 | DMA_FLAG_TCIF2); Six not TWO

DMA_InitStructure1.DMA_Mode =  DMA_Mode_Circular;

Circular is repetitive.

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 05, 2012 at 05:59

thanks,clive. my bad.

but I have make this correction, i got same result. My led1 did'nt blink aslo? can't understand that behavior, is that mean controller is stuck in while(getstatus....)?

I have also tried ur code u posted in ''DMA Memory To UART5''. but i got the same result. I got lot of data on my hyperterminal actually the same data as in my code. it always stops at the specif location (how i know that? because of same character appear every time)

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fDMA%20Memory%20To%20UART5&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentview...

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

hi. thank God.

ahhhhhhhhhhhhhhhh

I had set DMA flow control as hardware flow control for camera in DMA.c, I set it to Memory flow control and voilaaaaaaaa... It runs perfect... thanks all for ur help..

now i am thinking what i have to do as camera use hardware control and uart use dma memory flow control?? will check it and update my status...

thanks again