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.

RTOS/OMAP-L138: EDMA of DDR to McASP doesn't exchange information.

Part Number: OMAP-L138
Other Parts Discussed in Thread: OMAPL138, SYSBIOS

Tool/software: TI-RTOS

Hi,

I'm currently using a custom board with the OMAP-L138.

I have wrote code for our own custom codecs so that EDMA carries information to/from the McASP buffers.

My issue is that if I use DDR for my memory locations aka config.bld file, then it doesn't work properly, only the Output buffer to the speaker

will send information, but not get any input from the Microphones.

/*
 *  ======== config.bld ========
 *
 */
var Build = xdc.useModule('xdc.bld.BuildEnvironment');
var Pkg = xdc.useModule('xdc.bld.PackageContents');

/* when constructing a release, release everything */
Pkg.attrs.exportAll = true;

/* Uncomment this to build the app with debug support */
Pkg.attrs.profile = "debug";

/* bin/ is a generated directory that 'xdc clean' should remove */
Pkg.generatedFiles.$add("bin/");

Build.platformTable["ti.platforms.evmOMAPL138:dsp"] = {
    externalMemoryMap: [
        [ "DDR", {
            name: "DDR", space: "code/data", access: "RWX",
            base: 0xC3100000, len: 0x800000,
            comment: "DSP Program Memory (8 MB)"
        }]
    ],
    codeMemory:  "IRAM",
    dataMemory:  "IRAM",
    stackMemory: "IRAM",
    l1DMode: "32k",
    l1PMode: "32k",
    l2Mode: "0k"
};


/*
 *  ======== ti.targets.elf.C674 ========
 */
var C674 = xdc.useModule('ti.targets.elf.C674');
C674.ccOpts.suffix += " -mi10 -mo ";

If I change the code to L2RAM/IRAM then it works properly.

I do not use the EDMA LLD for my EDMA, I just configure the registers myself using CSL.

If I enable the cache on the L2 (32k) and use the DDR then nothing works, nethier input nor output.

If I disable L2 and set it to 0k then only partial functionality works with the DDR.

Is there some caching stuff that I need to be aware when using DDR for the buffers with EDMA/McASP?

XDCtools: 3.50.7.20

SYS/BIOS: 6.52.0.12

omapl138 PDK: 1.0.5

  • Any time you use EDMA the cache can get in the way. The EDMA accesses DRAM directly so the cache may not have had time to write your data to the DDR chip yet. When using EDMA I either use an un-cached area of DRAM or I use internal memory buffers. Be aware if you are using un-cached DRAM you don't want to do a lot of random accesses to the data since it takes so long. You want to only access un-cached memory in big bursts.
  • Yes, this sounds like a typical cache coherence issue. Coherence is handled in hardware for buffers in the L2. When you go to DDR, you need to manually manage coherence. I recommend keeping the buffers cached for performance reasons.

    For documentation, please refer to <bios_install_dir>/docs/cdoc/index.html and drill down to ti.sysbios.family.c64p.Cache. Since you're talking about INPUT data, you need to call the function Cache_inv() BEFORE you do your processing. Something like this:

    Cache_inv(my_audio_input_data, sizeof(my_audio_input_data), 1 /* wait */);
    process_input_data(my_audio_input_data);

    A couple notes:

    1. Make sure that your data buffer is aligned on a L2 cache boundary (i.e. must be 128 byte aligned!!!). Use #pragma DATA_ALIGN(my_audio_input_data, 128) when you declare the data to ensure it.
    2. Make sure your data buffers occupies the full line. You don't want the linker to place anything else in one of these cache lines! For example, let's say you have 254 bytes of data. Make sure you declare a couple of dummy bytes at the end to fill that line (char dummy1; char dummy 2;).
  • Thank you Brad,

    I will try it out. I saw something similar when using the basic McASP example on LCDK.

    So my issue with this then comes that my data is double buffered, aka both the input and the output buffer are each double buffered,

    and have double the storage for future incoming data. Should I then just split my each of the buffers into two separate ones,

    Update the EDMA PaRAM's to handle the proper buffers as needed, and when using Inv and WbInv to take data out/in from the respective

    buffers, use it on the proper buffer.

  • Dmitriy Stepin said:

    So my issue with this then comes that my data is double buffered, aka both the input and the output buffer are each double buffered,

    and have double the storage for future incoming data. Should I then just split my each of the buffers into two separate ones,

    Update the EDMA PaRAM's to handle the proper buffers as needed, and when using Inv and WbInv to take data out/in from the respective

    buffers, use it on the proper buffer.

    Just make sure that the two buffers don't share cache lines and you'll be ok.  Even if you're dealing with first half or second half of an array, it will be easy enough to figure out the offsets and sizes for the cache calls.

    FYI, for an output buffer it is kind of a mirror image of the input buffer in terms of cache operations.  You need a "writeback" function instead of an "invalidate".  And the writeback should be performed after you have written the data to the buffer.  Generally speaking it's not necessary to wait for this function to complete.