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.

uPP receive

Other Parts Discussed in Thread: OMAPL138

Hello,

I am using an OMAPL138 to interface to a fpga over the uPP.  I wrote a linux uPP driver and want to stream data from the fpga to the omap.  I have UPCTR set for a read threshold of 256 bytes on the receive channel.  The dma is setup for 1 line of 4096 bytes.  My c program is also set to read the data in 4096 byte buffers.  when I initiate the program to read data only 1 4096 byte line is read from the uPP.  I am wondering if my reloading of the dma parameters is incorrect.  This is how I setup the data transactions:

-load upp parameters

-enable interrupts

-setup first set of dma descriptors (data should come across here)

-setup a pending set of dma descriptors (when the ISR is called the interrupt is re-enabled and the next set of pending descriptors are programmed).

Any help would be appreciated, thanks, Scott 

  • Scott,

    The procedure that you describe seems correct.  It may be helpful to test the low-level uPP code that is the basis for your Linux driver in a simple, bare-metal application to make sure that it works as expected.

    One thing to note is that all three uPP DMA descriptor registers (per channel) must be written each time you program a new transfer, even if the new transfer is identical to the previous transfer.  Also, pointers to these registers should be defined as volatile to ensure that the compiler does not "optimize out" successive attempts to write a constant value to the same register.

    You may also want to enable the DPEx events (if they're not already enabled) to make sure that you're not encountering any problem when you program the each DMA transfer from your ISR.

    Hope this helps.

  • Joe,

    I've got another question about setting the active and pending DMA transfers.  In my application I have a fpga attached to the OMAP on the uPP.  The fpga is sampling data and I want to read it into the linux kernel running on the ARM.  I have a linux driver I wrote, that uses a ping-pong buffer scheme to read the data from the current and pending DMA transfers.  It appears I am getting discontinuities in the data and I am wondering if I have the initial current and pending DMA transfers programmed correct.

    My application is supposed to program the initial and pending DMA transfers from userspace via mapped memory to the uPP registers.  Then the driver updates the DMA registers, in an ISR, until I get all the data I am trying to read.  

    To program a DMA transfers I need to set the 3 DMA descriptor registers and then I enable the EOW interrupt.  Do I then need to do the same for the pending or is the method of programming the pending DMA different?

    Thanks, Scott

  • Scott,

    Generally speaking, keeping an active and pending DMA transfer programmed at all times should help you avoid "missing" data words (i.e. discontinuities).  You're correct that both DMA transfers (active and pending) are programmed by writing to the same three descriptor registers (i.e. UPID0/1/2 or UPQD0/1/2).  Please note that all three registers must be written each time, even if the "new" value for one of the registers is the same as in the previous transfer.  Also, it's only valid to write to these registers when the PEND bit in UPIS2 (or UPQS2) is zero-valued.  The uPP DMA only supports one pending transfer per channel at a time.  If you want to queue up multiple transfers, you will need to implement and manage some sort of linked list in your driver code.

    Also, it should not be necessary to re-enable the EOW interrupt event each time your program a DMA transfer.  EOWI and EOWQ events should only need to be enabled once when you initialize the uPP peripheral.

    Hope this helps.

  • Thanks for the reply Joe.

    So I have some questions about streaming data.  My application is looking to stream ~60Mbps from the fpga through the ARM to a SATA disk.  Here they are:

    • What kind of window size would you recommend?  Should it me several MBytes, or KBytes?  
    • Is a single line better than multiple lines? 
    • Also, in setting the pending DMA transfer, should I start by programming the initial and pending at the beginning of the application and then have the driver set the next pending at the EOW or should I break up the window into 2 lines, program the initial DMA and then program the pending on the EOL?
    Thanks in advance.
  • Scott,

    I recommend using larger uPP transfer sizes as is practical in your application.  That allows you to spend less time handling uPP interrupts and programming new transfers.  Generally, as long as your "small" size transfers are at least in the kilobyte range, you should be OK either way.

    There are a few potential advantages to breaking up your overall transfer into multiple lines:

    • Larger transfer sizes (i.e. greater than the maximum line size)
    • EOL interrupts can allow you to process some incoming data before the overall transfer is complete
    • Lines can be in discontinuous locations in memory (i.e. you can have gaps between lines)
    • You can repeat the same line to save space in memory (i.e. if you want to send a repeating pattern)

    Whether these are helpful to you will depend on your application.  If not, you can just use single line transfers.

    Finally, it's generally a good approach to program an active and pending transfer immediately, then program a new pending transfer every time you handle an EOW event.  The only thing to be careful about (when programming a new pending transfer) is checking the PEND bit to make sure the "old" pending transfer has already become active.

    Hope this helps.