cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Observer
Observer
6,525 Views
Registered: ‎05-20-2014

Axi DMA simple transfer addressing question

Jump to solution

Hi,

 

I am using the AXI-DMA pheripheral to stream data from the PL to the DDR memory of the zynq. To transfer the data I use the XAxiDma_SimpleTransfer( ) function.

 

The problem I have is that I cannot transfer data to the same location in the ddr memory twice. The DMA only seems to transfer again if I increase the address with the offset of the previous transferlength.

 

Is there a way to resolve this ?

 

Note: I already tried to reset the DMA controller but that doesn't solve the problem.

1 Solution

Accepted Solutions
Highlighted
Teacher
Teacher
9,066 Views
Registered: ‎03-31-2012

>> question that remains for me is why is it not enough to invalidate the range just once? Tests I have done seem to show that I have to invalidate the range everytime after the DMA has written to an address

 

that's the nature of caching. you invalidate it, it becomes valid when you read it to see what dma has transferred. now when the dma writes to the same address again, there is nothing telling the cache controller that those entries which point to the now updated dram locations have become stale. so you can't read the new data. Normally this would be the responsibility of the snoop logic ie to look over the addresses belonging to the transactions between PL masters and dram and invalidate the cache entries if/when those dram addresses are written to. Alas this logic is not cheap so it only exists on the ACP. If your master uses ACP to write to dram, you will not have to invalidate the cache everytime yourself the snoop logic will do it for you. If you use another PS slave port (to connect your master) then it becomes your responsibility to do this. You have two options: either set a range of dram aside and mark it uncachable or everytime you get the dram write complete interrupt invalidate the range yourself.

 

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.

View solution in original post

Tags (5)
7 Replies
Highlighted
Observer
Observer
6,521 Views
Registered: ‎05-20-2014

An update:

 

I have found that the addressing problem was caused by the cache.

I had enabled both Icache and Dcache, however I used the invalidate range function to make sure that my data range would not be used for caching. However that only seems to work once. As soon as I write data to the range the next time the DMA is not allowed to write on that location again.

 

When I disable the caching completely this problem is resolved.

 

Is it necessary to invalidate a range every time you want to write to it ? 

0 Kudos
Highlighted
Teacher
Teacher
6,515 Views
Registered: ‎03-31-2012
what makes you say "The DMA only seems to transfer again" ? is it possible that dma is transferring but you don't see it from the PS because the cache controller doesn't know that the data has been updated so you read the previous values ?
- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
Highlighted
Observer
Observer
6,510 Views
Registered: ‎05-20-2014

thanks muzaffer,

 

I think you are right, the dma will have completed the action because the interrupt is generated. It seems that your statement is right,

 

question that remains for me is why is it not enough to invalidate the range just once? Tests I have done seem to show that I have to invalidate the range everytime after the DMA has written to an address

0 Kudos
Highlighted
Teacher
Teacher
9,067 Views
Registered: ‎03-31-2012

>> question that remains for me is why is it not enough to invalidate the range just once? Tests I have done seem to show that I have to invalidate the range everytime after the DMA has written to an address

 

that's the nature of caching. you invalidate it, it becomes valid when you read it to see what dma has transferred. now when the dma writes to the same address again, there is nothing telling the cache controller that those entries which point to the now updated dram locations have become stale. so you can't read the new data. Normally this would be the responsibility of the snoop logic ie to look over the addresses belonging to the transactions between PL masters and dram and invalidate the cache entries if/when those dram addresses are written to. Alas this logic is not cheap so it only exists on the ACP. If your master uses ACP to write to dram, you will not have to invalidate the cache everytime yourself the snoop logic will do it for you. If you use another PS slave port (to connect your master) then it becomes your responsibility to do this. You have two options: either set a range of dram aside and mark it uncachable or everytime you get the dram write complete interrupt invalidate the range yourself.

 

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.

View solution in original post

Tags (5)
Highlighted
Participant
Participant
5,227 Views
Registered: ‎05-28-2008

Hi, Thanks for your description.

 

You mean that when I want to read from an address of DDR, I should invalidate the range. And also when I try to write to an address of DDR, I should also invalidate the range ?

 

For example, When I am using DMA to move ADC data from PL to range (A) in DDR, and then move range (A) to range (B) using memcpy in PS, then, I should

 

1. invalidate range (A), start DMA,

2. invalidate range (A), invalidate range(B)

3. memcpy A -> B

 

and the suppose I want to transfer range (B) via TCP, should I

4. invalidate range (B) again

5. tcp_send( B )

 

Is it correct ?

 

Thanks in advance !

0 Kudos
Highlighted
Adventurer
Adventurer
3,162 Views
Registered: ‎02-12-2017

The post is old I know, but I didn't want to create a new one.

I would like to know how to write a simple c program to do a simple transfer of data to ddr and back?

Can anyone post such a code? That would be great. Thanks!

0 Kudos
Highlighted
Observer
Observer
71 Views
Registered: ‎08-30-2019

Good Question!

A great help to me!

0 Kudos