This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DMA buffer configuration

Hi

I m working on TMS570 DMA module. I have taken the demo code provided by TI as a reference and trying for various lengths of destination and source buffers. following are the configurations I have selected.

uint8 Source_address[20] ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

uint8 Destination_address[10];

Frame count = 1

Element Count = 20

Read Element size = 8 bit

Write Element size = 8 bit

Auto Init mode is 1

post increment read and write address

transfer type is frame transfer

As per the post in

http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/217878/768351.aspx#768351

I m having destination buffer to hold10 bytes and source to hold 20. Eleventh byte that is copied from the source should be written to the first location in destination buffer. this is not happening. can anyone tell me what configurations I need to have to make my destination buffer hold the latest ten bytes?

 

Thanks and Regards

pallavi

 

  • Pallavi,

    DMA will work as follows with your setting.

    (1) 20 bytes are  transferred to the memory with the start address of Destination_address[0]. Although you only defined 10 bytes for this array, DMA will continue with linear address increment till all 20 bytes are transferred.

    (2) If you do not use hardware trigger, the operation in (1) will be repeated forever because the autoinit bit is set. When autoinit bit is set, DMA will repeat its operation once the block transfer is complete.

    We may be able to provide more suggestions if you can share information about what you want to achieve.

    Thanks and regards,

    Zhaohong

  • hi,

    Thanks for the response.

    I might need some more suggestions on the points below.

    1. My application should copy the data present in SCIRX buffer[SCI buffer is filled with continuous stream of bytes] and load the data into the destination buffer created in RAM.
    2. I m unaware of the number of bytes I ll be receiving hence i cant allocate fixed number of bytes to my destination buffer. Due to memory constraints I cant provide a large buffer, So I ll have to go with, say 50 bytes max.
    3. Whenever i read the destination buffer it should provide me the latest 50 bytes of data and there should not be any data loss. So i want my destination buffer to be a circular buffer.
    4. What can the DMA configurations be so as to satisfy the above requirements?

    And to add to this. i tried hardware triggering using the configurations i shared before by making following changes

    •  In SCI i enabled the SCI RX DMA(bit 17 of  SCI Set Interrupt Register)
    • Addressing mode read as Constant.

    With these settings i was unable to read the data from SCIRX buffer.

    Thanks and Regards

    pallavi

     

     

  • Pallavi,

    I would suggest you setting up the DMA block transfer size to the buffer size. Enable DMA HBC and BTC interrupt. Enable autoinit. When a buffer is half full, DMA HBC interrupt is triggered. The first half of the buffer is filled with new data. When the buffer is full, BTC interrupt is triggered. DMA will automatically restart transferring data to the beginning of the buffer. The attached source code provide an example of how to set up DMA with LIN in SCI mode.

    7317.sci_dma.zip

    Please let me know if this answers your question.

    Thanks and regards,

    Zhaohong

  • Zhaohong,

    Thank you very much for the quick response.

    Isn't there any other way other than using interrupts? Application doesn't allow us to use interrupts.

    Please let me know what could be done if i go for polling mode instead of interrupts.

    Thanks and regards

    Pallavi

     

     

     

     

     

     

  • Hi Zhaohong,

    I am working with Pallavi on this project, thank you very much for all your help.

    I don't think that the use of interrupts is necessary for us. I assume you suggested that so we know when there are 50 bytes available and so should perform the read of the destination buffer.

    In fact we will be polling for new data at a fixed time period and what we need is to read anything received via the SCI interface since the last read. We will set the size of the destination buffer to be about twice the size of the amount we would expect to receive in the given period. So initially we know the DMA engine will begin populating the destination buffer at the first location and the first time we need to read we request the current destination address from the DMA engine. We read from the initial destination address to the current destination address and then store the current destination address. Next time we use the stored value as our starting point in the destination buffer and again request the current destination address from the DMA engine and so it continues. As you say, with auto initialisation enabled and with DMA requests being generated by the SCI module each time a frame of data is available for transfer, the data will be transferred until the defined block size has been transferred and then automatically reset the destination address to the start of the buffer.

    The only concern I have is retrieving the current destination address from the DMA module. I have read on another thread on this forum that the CDADDR in the working control packet is only updated when an arbitration between DMA channels occurs, so with only a single DMA channel enabled we may not be able to use this to find the real current destination address. From other forum postings on this subject I believe that the destination address for the current active block is held in PBACDADDR so this could be used to get hold of the current destination. However, in some cases our application requires 2 DMA channels to be simulaneously running and as pointed out in the other thread I have read on this subject if we were to use DMASTAT register to determine the current active channel and then read PBACDADDR if the channel we needed was currently active, there is a small but real chance that an arbitration could have occurred by the time we read the value in PBACDADDR.

    I have considered the possibility of reading DMASTAT before and after the read of PBACDADDR on the assumption that if the active channel is unchanged from one read to the next that there has not been an arbitration, but we wondered if there was a less clunky solution to this problem.

    Thanks,

    Mark.

     

  • Mark,

    A DMA channel is switched out of the queue when there is no pending transfer. The addresses in the working control packet always reflect the addresses of the last completed transfer.

    Thanks and regards,

    Zhaohong

  • Hi Zhaohong,

    The behaviour you describe is what we had hoped and would mean our application will behave as expected.

    In this case though, could you please explain what is being described in the following thread?

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/158061.aspx

    Thanks,.

    Mark. 

  • Mark,

    I took a look at this thread you referred. In order to make the address in working control packet updated after transferring one byte from SCI, you need to set up the following.

    (1) There is only one element in a frame. the element size is 8 bit.

    (2) The trigger to DMA is set for frame transfer.

    (3) Enable DMA on SCI module

    SCI will generate a DMA request after receiving a byte. This request triggers a DMA frame transfer from SCI RX buffer to system RAM.  The address in the working packet is updated after the completion of frame transfer.

    Thanks and regards,

    Zhaohong

  • Mark,

    Do you need more information on this topic? Would you please select the "verified" button if you consider that this question is answered?

    Thanks and regards,

    Zhaohong