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.

Unable to properly read from FPGA using EMIF DMA

I am attempting to read 960 halfwords from an FPGA which is connected to EMIF ASYNC 1. The read is requested and actioned properly (it can be seen on a logic analyzer) but there are 'holes' in the array that the data is read into. Reads are alternated between channel 0 and channel 1 with two separate destination buffers. The packet control for channel 0 is set up as :

struct /* 0x000-0x400 */
{
uint32 ISADDR = 0x60000038;
uint32 IDADDR = address of buffer 0 (0x0800ac20);
uint32 ITCOUNT = 0x000103c0;  (1 block  of 960 )
uint32 rsvd1;
uint32 CHCTRL = 0x00005002; (Auto-init off, write mode post inc - indexed shows same problem- 

                                                     read mode constant, ttype 0 (hw requests 1 frame), read and write size 16 bits,

                                                    chain is no channel
uint32 EIOFF = 0x00020000;
uint32 FIOFF = 0x00000000;
uint32 rsvd2;
}PCP[32U];

Channel 1 is the same except for the buffer address.

The read is triggered by 

            dmaSetChEnable( DMA_CH0, DMA_SW); 

or similar for channel 1

The code checks to see if any DMA is in progress by calling

 dmaIsChannelActive( DMA_CH0 );

 dmaIsChannelActive( DMA_CH1 );

No DMA is started unless both are inactive.

The memory for the EMIF region is set up as device shareable.

The holes are in the same place for every read each time the DMA is actioned but seem to move every time the software is restarted. They are always on a 32byte boundary and a multiple of 32 bytes in size leading me to suspect a FIFO issue. Changing the setup to read 80 blocks of 12 does not fix the problem.

  • Hi Andy,
    Is this the LC4357 device?

    Sorry, I have to ask a few questions to narrow down the problem area.

    1. You said that from logic analyzer you can see all the reads (960 of them) performed. Is this true? I want to isolate problem area between EMIF and DMA. If the reads by EMIF is proper then we can focus on the DMA, i.e. the datapath from EMIF->Interconnect->DMA_FIFO->Interconnect->L2 SRAM and from L2SRAM->Cache->CPU.

    2. What are the values in the so called 'holes'? Are they just zeros or some random values?
    3. Is it true that if you only have one active DMA channel and you will still see 'holes' in the destination buffer?

    Below are some experiments that I'd like you to try.

    1. You said the holes are multiple of 32 bytes. Even though the DMA FIFO is 32-bytes the cache line is also 32 bytes. I don't think the problem is due to the FIFO. You declared the EMIF as a device-shareable region. But you didn't say how you configure the MPU setting for these buffers? Are you in write-back cache scheme? If you are in write-back cache scheme can you change to write-through? Or as a experiment, if you have the cache enabled can you simply disable it and see if it makes a difference. If you have write-back cache scheme then what is written by the DMA to the buffer will not be seen by the CPU if these buffer addresses are already stored in the cache tag address memory.

    2. If the above experiment does not make any differences then you can play with #2 experiment. Can you first initialize the holes in the buffer with some known values? After the DMA is triggered I want to know if these pre-initialized values are overwritten with new values or they stay the same. This helps me to know if the DMA skipping the transfers or not.
  • Charles,

     I disabled the cache and it all started working . I had already done the experiments so I can tell you (and anyone else who may urn across this post) :

    1: We only had one DMA access. We alternate on two channels but only one can be active at a time. This allows us to process the buffers in 'slow time'. The logic analyzer showed that all 960 reads were performed and that the data that was placed in RAM (as opposed to the holes)  was in the right place (i.e.  the correct offset from the start of the block).

    2: I filled the buffer with 'A5's and they stayed there so the holes were areas where no write occurred rather than areas where zero was written.

    3 : I tried changing the cache to write-through but it made no difference.

    Thanks for the fast response and good advice. We will leave cache turned off.

  • Hi Andy,
    Glad that your problem is resolved. However, I'm puzzled that the write-through scheme does not work. I'm not familiar with your application. Disabling the cache will reduce the MCU performance. Is this something your application can live with?
  • I changed the type to NORMAL_OIWTNOWA_SHARED and it made no difference. We are okay with leaving cache turned off since we believe it makes the code more deterministic and can take the hit on MCU performance.
  • Hi Andy,
    Can you give a try for NORMAL_OIWTNOWA_NONSHARED for the L2 SRAM starting at 0x08000000? I also agree that with the cache turned off it is more deterministic.
  • Charles,
    That works fine. When I looked I had changed the EMIF region starting at 0x60000000 not the region starting at 0x08000000. Sorry for the confusion. I think it is a good thing we can now turn cache on if we need the extra performance.

    Thank you again for your help
    Regards
    Andy
  • Glad that it works now.