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.

CSI2 DMA transfer question (AM3703)

Other Parts Discussed in Thread: AM3703

I'm trying to understand how image data from a camera (CSI2-A) can be sent to RAM so I can access it.

I'm working with AM3703 (Gumstix Overo EarthSTORM).

I'm sure CSI2 is receiving image data because I have activity in CSI2_CTX_CTRL1_0. For example the COUNT field [15:8] which I start out at 200 keeps decrementing as frames are being received, also PING_PONG bit (3) keeps toggling.

All that seems left to do is to put an address into CSI2_CTX_DAT_PONG_ADDR_0 and also put the same address into CSI2_CTX_DAT_PING_ADDR_0.

This is where my confusion starts. The datasheet talks a lot about DMA in regards to channels. There is a lot of stuff in the datasheet regarding DMA. One of my questions is if I even need to worry about that. Because from what I see, I only need to put a memory address into PING/PONG ADDR and the data will just be written to that area. Is that true?

Let's say that's true, then my second question is what is the easiest way to come up with this address, remember I just want to look at some data from the camera.

What I have at this time might be completely wrong, but here is what I do:

static void* stuff;
static dma_addr_t mydma;

stuff = kmalloc(1048576, GFP_KERNEL);   //1 MB of space
mydma = dma_map_single(my_device_object, stuff, ksize(stuff), DMA_FROM_DEVICE);

example output:
stuff = 0xea900000
mydma = 0xaa900000

Now I know that 1 MB of space will ultimately not be enough but for debugging purposes it should suffice. I tried writing either addresses to PING/PONG but when I look at the data I don't see any changes.

The way I try to read the data may also be wrong, what I do is something like:

unsigned char* bla;
bla = (unsigned char*) stuff;
for (i = 0 ...
  printk(... bla[i] etc.

In any case, I will post an answer if I figure it out but if anybody can provide me with some insight I would most certainly appreciate it.

  • I will forward this to the software team.
  • Let me just post what I have at this point, which seems to do the trick:

    static void* cpu_handle;
    static dma_addr_t dma_handle;
    static size_t dma_size;
    
    //initialize
    void init_function(void) {
        cpu_handle = NULL;
        dma_size = (size_t) 5048576;    //size is in bytes
    
        cpu_handle = dma_alloc_coherent(NULL, dma_size, &dma_handle, GFP_KERNEL | GFP_DMA);
    
        if (cpu_handle == NULL) {
            return; //error
        }
    
        printk("cpu_handle 0x%p, dma_handle 0x%x\n", cpu_handle, dma_handle);
        //example output: cpu_handle 0xf1a6d000, dma_handle 0xbeb00000
    }
    
    //free memory
    void exit_function(void) {
        if (cpu_handle != NULL)
            dma_free_coherent(NULL, dma_size, cpu_handle, dma_handle);
    }
    
    //access dma memory region
    void read_function(void) {
        unsigned char* bla;
        bla = (unsigned char*) cpu_handle;
    
        //just an example:
        printk("access memory values 0x%x, 0x%x etc.\n", bla[0], bla[1]);
    }
    

  • I forgot to add that I pass NULL instead of the struct device* because I figured I don't need it.
    Also the dma_handle is what I pass to ISS/CSI2 into CSI2_CTX_DAT_PING_ADDR_i and CSI2_CTX_DAT_PONG_ADDR_i.
    I end up seeing data show up in this region that is most most likely from the camera, except it is pretty much garbled and inconsistent, but that's a separate issue.