Edma 2channel transfer loop

Greeting again everyone!.

I am using beaglebone with angstrom.

I am trying( by writing a kernel module ) to loop two dma channels together but i cant figure out how…

Here is what i want. i want the completion of the 1st channel to trigger the final interrupt(callback1) and also channel 2.
and at the completion of channel 2 to trigger the final interrupt (callback2) and also channel 1. etc… creating a loop between ch1 and ch2.

By linking the channels it seems that i cant link channel 2 back to channel 1. (

edma_link(ch1, ch2);
edma_link(ch2, ch1); system fail.

i can only link ch2 on its self

edma_link(ch1, ch2);
edma_link(ch2, ch2);

but i dont want that.

By chaining the final interrupt is not going off. so i dont want that either.

I tried to link edma_link(ch1, ch2) then chain ch2 with a ch3 and have edma_link(ch3, ch1);

but then ch1 callback1 returns DMA_CC_ERROR with its paramset being NULL (so the error is from that).

Any suggestions ?

I am working on EDMA ATM as well. I was curious if you could write a little bit about how you are initializing the channels and setting up the transfers. Are you writing a kernel module for this and interfacing to it in user-space?

Appreciate any insight, having a hard time digging up info on using EDMA on the Beaglebone

Hi Terrence.

Yes i am writing a kernel module and interfacing with it from user space.

As i went through the same period like you do now i’ll be glad to help you.

The first step is to allocate the buffers that the edma will use
source and destination buffers as well . as edma needs special buffers.
The second step is to allocate the channels you want.
Then comes the configuration of the transfer of each channel.

As you can understand i cant describe the hole process in detail as edma and its applications are quite complicated.
if you can be more specific ill be glad to give you more specific information.

I am working on EDMA ATM as well. I was curious if you could write a little bit about how you are initializing the channels and setting up the transfers. Are you writing a kernel module for this and interfacing to it in user-space?

Appreciate any insight, having a hard time digging up info on using EDMA on the Beaglebone

Hi Terrence,

Best place to understand how to work with EDMA is this link:

http://processors.wiki.ti.com/index.php/EricScottVideos

Under C6000, look at the videos on EDMA3. Clearly this is working under SysBIOS, but the concepts are the same. Once you understand these concepts, it will be easier for you to understand how the Linux drivers use EDMA.

Regards,
John

Hi Dimitris,

Thanks for responding (posted this on my buddy’s PC Terrence while he was logged on, apologies.)

I just got a really good environment built for compiling kernel modules right on the BeagleBone Black. Makefile setup nicely, generates KO files that load nicely using “modprobe” - all is well with the World.

Now, to write C code.

I have been studying the am335x TRM, specifically the Ping Pong Buffer sections - eventually the goal is to write a ping pong buffer that receives from SPI RX FIFO.

To get me started in the right direction I am looking for simple C code to basically setup DMA how you suggested:

  • Allocating Buffers, Channels
  • Configuring transfers

… and send a very simple transfer of data.

I have been searching through EDMA.c and SPI code within the BBB code to see how they are doing it but simple C code would def. help me understand things.

Thanks in advance for your help,

I am attaching you a file with a test code from texas that shows the initial setup for 3 transfer techniques. Study it i think one can get the main idea from it.

I also advise you to take a look at the bare metal examples of TI for the am335x (the starterware) they have an example with edma transferring from the spi , check it out.

Dimitris.

edma_test.c (19.5 KB)

Greetings Andrew.

The code from the starterware is for bare metal that is correct , but it can help you greatly by using it as a guide of what need to be done to take and give data from and to the spi .

Interfacing between KERNEL DRIVER and USERLAND CODE

Firstly I don’t think i am an expert, as a recently started to duel with these kind of stuff my self. so i may miss something.

The point of creating a kernel module is to access hardware that is not available to you from user space or rewrite a driver .

The kernel module and the userland api are two completely different things , that communicate with its other . And for most cases i think you can think the module as a slave and the main api as a master.

For one example of interfacing between your kernel module and your userland code check this link : http://www.linuxforu.com/2011/08/io-control-in-linux/ .
From what i know directly accesing a function is possible but its neither the correct way nor an easy one so don’t do it , this is not how this works.

Check this link that provides more than enough to get you started i think http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html .

Virtual versus Physical

check this out about the memory types http://www.makelinux.net/ldd3/chp-15-sect-1

An example of hwreg
#define HWREG(x) (*((volatile unsigned int *)(x)))