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.

ECU (VoLIB 2.1.0.1) crashes when running on multiple channels in real time (C6746)

Hi,

I'm using the Echo Canceller Unit Package (ECU) from VoLIB 2.1.0.1 for C64 + in the C6746 DSP in a custom board. I'm running it in real time and I'm facing an unusual problem: when running the ECU in MULTICHANNEL mode, the program breaks after a while (may be 1 second or 20, it varies from time to time). But when I run only one channel, I do not have this problem. If I remove the ECU algorithm and do only a talkthrough, I don't have this problem either. 

When I say the code breaks, it means that I either get silence in the phone or I don't get any signal at all, or even a high pitch noise for several seconds and then silence.

Here's a picture of a recording in the moment the algorithm crashes:

The channel below is the residual echo. As we can see, the echo was being canceled until it dropped suddenly.

ECU Configurations: Filter tail: 32ms, Filter segment: 32ms, 10ms samples, SEARCH OFF, NLP ON.

The ECU main function (ecuSendIn) takes about 100us to run, so it's not a problem of sample overlapping. The signal reception is done using EDMA + McBSP and Ping-Pong Buffers.

I have absolutely no idea of what is happening. I'm uploading my code to anyone who might know what I am doing wrong. Any help is desirable. I can't debug the code, there's no emulator in our custom board, so everything is done using a single led connected to a DSP GPIO port. 

0257.4527.echo_cancel.c

Thanks in advance,

Regards,

Leonardo Batista

  • Hi Leonardo Batista,

    Moving your post to TI-RTOS Forum to get appropriate response.

    TI-TRTOS forum handles the following.

    TI-RTOS Real-time Operating System and other embedded software products including SYS/BIOS, DSP/BIOS, IPC, SYSLINK, and TCP/IP (NDK), the Multicore SDK, Industrial SDK, DSPLIB, IMGLIB, VoLIB, OpenMP, and OpenCL

    Regards,

    Shankari.

  • Hi Leonardo,

    As you already verified that ecuSendIn takes about 100us to run, the silence/high pitch signal issue doesn't seem to be caused by MIPS / channel density that typically happens in multi-channel mode and causes ECU non-functional. The issue is more like ECU instance or signal buffers get corrupted when more channels are running sequentially. A few things you might want to check are:

    1. add error check followed by each malloc() to ensure heap size is enough and buffers are malloc-ed properly.
    2. decrease the channel number from current 8 to 2 to see if the problem still occurs.
    3. skip one or two channels, e.g. for (i = 0; i < NC; i+=2) instead of for (i = 0; i < NC; i++) to check if that can avoid buffer corruption.
    4. feed silence signal to Rin and let Sin pass through, if there is buffer corruption, you probably still observe high pitch or silence after ECU processing.

    Also, to experiment a variety of Rin/Sin signal (e.g, CSS in test vector provided in the VoLIB, tone) may help investigate if the echo issue is correlated with a particular signal category in case it’s not a buffer corruption problem. And you probably have tried with different ECU configuration (tail length, NLP).

    Regards, Garrett

  • Hi Garret, thank you very much for your answer.

    I tried everything you suggested, here it is everything I've noticed:

    1 - Everything is ok. I'm using now a structure for the buffers and the size and alignment seem ok, no errors returned in any of the ECU configuration functions.

    2 - Even with 2 channels the problem occur. I'm still able to run one channel per time, that is, I may have 8 channels running and use each channel separately, but not at the sime time. If I try to run 2 simultaneously, the code breaks very fast.

    3  - Here's something new (8 channel configuration): I tried a 2 offset, no changes. 3 offset, no changes. But when I put an offset of 4 (i+=4), the code DIDN'T crash. I ran channel 0 and 4  (and also 1 and 5, 2 and 6, 4 and 8) simultaneously and everything went perfect, the echo was canceled and there were no buffer corruption whatsoever.

    4 - Another discovery. Using RinBuf = 0xD5 (I'm using A-law), the code DIDN'T break even with an offset of 1. I assume then that the code only breaks when echo is canceling, if not, it runs smoothly.

    For the variety of signals, I'm using real time conversations and different files for all tests. I also changed the configuration several times, but nothing different happened.

    I have no idea how I can solve this problem of buffer corruption. I do not know how the ecuSendIn function operates and why it corrupts the buffers when they are sequential. The alignments seem ok, but of course, I can be wrong about this. Any ideas how this can be solved? Anyone had similar problem?

    Thank you again for your attention,

    Regards,

    Leonardo Trierveiler.

  • Leonardo,

    >>I'm using now a structure for the buffers...

    Do you mean you are using the similar way as in ecusimfun.c below to configure ecuBufs for each channel? You may post your updated code here. I think we need to carefully look at the buffer allocation part which appears to be the culprit in multi-channel mode.

    iramSeg_t iramSeg = {

    #if ecu_DELAY_LINE_COMPRESS

        &ecu_pcm_expand[0],

        &piu_ecu_receive[0],

    #else

        &piu_ecu_receive[0],

    #endif

    #if ecu_SEARCH_ENABLE

        &ecu_srch_filter[0],

    #endif

        &ecu_bg_work[0],

        &ecu_bg_e[0],

        &ecu_bg_filter[0],

        &ecu_fg_filter[0]

      };


      for (i = 0; i < ecuNbufs; i++) {

        ecuBufs[i] = bufs[i];

        if (i == ecu_FG_FLTSEG) {   /* FG Filter */

          ecuBufs[i].base = iramSeg.ecu_fg_filter_ptr;

          ecuBufs[i].size = IRAM_ECU_FG_FLTSEG_LENGTH*sizeof(Fract);

        }

        else if (i == ecu_BG_FLTSEG) {  /* BG Filter */

          ecuBufs[i].base = iramSeg.ecu_bg_filter_ptr;

          ecuBufs[i].size = IRAM_ECU_BG_FLTSEG_LENGTH*sizeof(Fract);

        }

    ......

    Regards,
    Garrett

  • Hi Garret,

    This is my new configuration using struct (I'm only pasting the definitions, not the whole code again). Everything is declared outside main()

    static struct
    {
    ecomemBuffer_t ecuBufsAlloc[17*12/2];
    tint buf_0[664/2];
    Fract buf_1[512/2];
    Fract buf_2[512/2];
    linSample buf_4[416/2];
    Fract buf_7[12/2];
    Fract buf_8[16/2];
    Fract buf_9[16/2];
    tint buf_10[12/2];
    tint buf_11[12/2];
    Fract align_buf[1];
    } ecuBuffers [NC];

    linSample buf_3[80/2];
    linSample buf_5[676/2];

    Buffers 3 and 5 are declared outside as they are stratch buffers.

    Now, inside the echo_cancel.c (the file I sent before), substituting the malloc and pointer declarations for the ecuNew()

    i  goes from 0 to NC (number of channels)

    ecuInsts[i].ecuBufs = &ecuBuffers[i].ecuBufsAlloc[0];

    buf_0_ptr = &ecuBuffers[i].buf_0[0];
    buf_1_ptr = &ecuBuffers[i].buf_1[0];
    buf_2_ptr = &ecuBuffers[i].buf_2[0];
    buf_3_ptr = &buf_3[0];
    buf_4_ptr = &ecuBuffers[i].buf_4[0];
    buf_5_ptr = &buf_5[0];
    buf_7_ptr = &ecuBuffers[i].buf_7[0];
    buf_8_ptr = &ecuBuffers[i].buf_8[0];
    buf_9_ptr = &ecuBuffers[i].buf_9[0];
    buf_10_ptr = &ecuBuffers[i].buf_10[0];
    buf_11_ptr = &ecuBuffers[i].buf_11[0];

    ecuInsts[i].ecuBufs[0] = ecuInsts[i].ecuBuf_getparam[0];
    ecuInsts[i].ecuBufs[0].base = buf_0_ptr;

    ecuInsts[i].ecuBufs[1] = ecuInsts[i].ecuBuf_getparam[1];
    ecuInsts[i].ecuBufs[1].base = buf_1_ptr;

    ecuInsts[i].ecuBufs[2] = ecuInsts[i].ecuBuf_getparam[2];
    ecuInsts[i].ecuBufs[2].base = buf_2_ptr;

    ecuInsts[i].ecuBufs[3] = ecuInsts[i].ecuBuf_getparam[3];
    ecuInsts[i].ecuBufs[3].base = buf_3_ptr;

    ecuInsts[i].ecuBufs[4] = ecuInsts[i].ecuBuf_getparam[4];
    ecuInsts[i].ecuBufs[4].base = buf_4_ptr;

    ecuInsts[i].ecuBufs[5] = ecuInsts[i].ecuBuf_getparam[5];
    ecuInsts[i].ecuBufs[5].base = buf_5_ptr;

    ecuInsts[i].ecuBufs[7] = ecuInsts[i].ecuBuf_getparam[7];
    ecuInsts[i].ecuBufs[7].base = buf_7_ptr;

    ecuInsts[i].ecuBufs[8] = ecuInsts[i].ecuBuf_getparam[8];
    ecuInsts[i].ecuBufs[8].base = buf_8_ptr;

    ecuInsts[i].ecuBufs[9] = ecuInsts[i].ecuBuf_getparam[9];
    ecuInsts[i].ecuBufs[9].base = buf_9_ptr;

    ecuInsts[i].ecuBufs[10] = ecuInsts[i].ecuBuf_getparam[10];
    ecuInsts[i].ecuBufs[10].base = buf_10_ptr;

    ecuInsts[i].ecuBufs[11] = ecuInsts[i].ecuBuf_getparam[11];
    ecuInsts[i].ecuBufs[11].base = buf_11_ptr;

    result = ecuNew(&ecuInsts[i].ecuInst, ecunBufs, ecuInsts[i].ecuBufs, &ecuInsts[i].ecuCfgNew);

    Everything else is exactly the same.

    Note that at the end of the struct, I added "Fract align_buf[1];". I needed to include this buffer to align the entire second instance or else the code would break inside ecuNew (returning result = 1) when i = 1. When I put align_buf[1], this error was fixed, but I sincerely don't know if this may be the cause of the buffer corruption.

    Notice also that all sizes are divided by two. I simply did that because all buffers would have double the necessary size I would want. 

    The next two pictures are the complete buffers parameters 

    Instance 0:

    (log2align | mclass    volatile | size    address).

    Instance 1:

    As you can see from the first 3 buffers (0, 1 and 2), the sizes match based on the buffer address. I also don't think this is the problem. I didn't put anything in the buffers with size zero: 6,12, 13, 14, 15, 16.

    Thank you for your attention,

    Regards,

    Leonardo Trierveiler

  • Well, 

    Tried different configurations in the last 5 days but I got nothing. Sometimes eight channels work, sometimes it doesn't. Until now, nothing solid has happened. The code still breaks randomly

  • Leonardo,

    I don’t see obvious error in your buffer allocation. But this is a bit interesting:

    >> Note that at the end of the struct, I added "Fract align_buf[1];". I needed to include this buffer to align the entire second instance or else the code would break inside ecuNew (returning result = 1) when i = 1.

    ecuNew error 1 indicates there is buffer size or alignment error when creating an instance of ECU and initializing memory buffers. In the case you added Fract align_buf[1] that resolved error, it seemed the error was caused by buffer alignment. To confirm this, and hopefully it can give us some clue why multi-channel randomly fails, can you step into the ecuNew disassembly code (without Fract align_buf[1]) and find out which instruction posts the error 1? So we can know which particular buffer is incorrectly aligned, and from there we may be able to know more if any buffer need to increase size or just need be aligned.

    Regards, Garrett

  • Garret,

    The way I used to find out the buffer alignment problem was running the disassembly code. The code was breaking when an "AND" operation was running. The line did the "AND" between the base addres of the buffer and a number that I actually don't remember, but, when the result returned something different than 0, the "ecuNew()" would abort and give me result = 1. This happened with "buf_0" from instances 1, 3, 5, etc.

    Here:

    Before the AND operation

    After the AND operation. A1 is 4 and the code breaks.

    Adresseses of the first 4 instances WITHOUTH Fract align_buf[1]:

    After I added the Fract align_buf[1], the alignment was ok and the ecuNew() returned 0 for every instance.


    I'll run the code and edit this after I find the correct line in the code.


    Thank you.

    Regards,

    Leonardo Trierveiler

  • Hi Leonardo,

    You log indicates the code broke around ECU_SEARCH_FILTER_BUF without Fract align_buf[1]. Did you try to enable the ECU_SEARCH and allocate the ecu_SEARCH_FILTER_BUF (14)? That should resolve your multi-channel ECU issue.

    #define ecu_FG_FLTSEG             1

    #define ecu_BG_FLTSEG             2

    #define ecu_BG_E_BUF              3

    #define ecu_RECEIVE_IN            4

    #define ecu_EXPAND_DL_BUF         5

    #define ecu_BG_UPDATE_BUF         6

    #define ecu_SEARCH_FILTER_BUF     14

     

    Regards, Garrett

  • Hi, Garret.

    Unfortunately, I've alredy tried that. When I tried using a 64ms filter tail, I enabled the SEARCH filter and the code broke anyway. When working with 32ms, the SEARCH filters buffers have size 0, as they are not used in the echo cancelling process. 

    I also tried doubling the size of all buffers, but that didn't solve my problem either. What really bugs me about this problem is that the crashes are RANDOM. Sometimes, I can connect the eight channels, run a test sample or two, then, out of nowhere, the code breaks. When I try again, it breaks in the first try. Some crashes only disable 4 channels, and the other keep working normally. It is commom also to happen timeslots shifts when I run a test sample. I'm wondering what could be a source for a problem that is absolutely random, making almost impossible to simulate the same problem twice in a row.

    Here it is some images of the problem occurring:

    First of all, this is the expected signal in the osciloscope when everything is running ok (Each frame sync has 32 timeslots, in our case, the 16 first timeslots serves as Sin and the 16 remaining serves as Rin). In my example, I'm running 8 channels simultaneously). Each timeslot carries one byte from each channel.

    Little zoom:

    And here we have some of the errors when the code breaks:

    Timeslot shift:

    timeslot shift + only 1 bit returning

    Everything goes to zero:

    But NOTHING like this happens when RinBuffer = 0xD5 (no echo is being cancelled) or when I remove the echo canceller function. I thought at first that this could be some DMA problem, but I strongly believe that this is not the case. I'm also using a heap size of 0x8000 and a stack size of 0x8000. Everything is inside L2SRAM. The DSP clock is 375MHz.

    Do you have any examples of codes running multiple channels in real time? Maybe it is some minor/major configuration that I'm overlooking. In an extreme case, do you think this may be caused by some bug in the API? 

    Thank you again,

    Regards,

    Leonardo Trierveiler

  • Leonardo,

    >>When I tried using a 64ms filter tail, I enabled the SEARCH filter and the code broke anyway
    Do you mean code still broke in ecuNew returing result = 1 without "Fract align_buf[1]" in the case, or ECU is broken with silence/high pitch signal in multi-channel mode?
    If it's still ecuNew returning 1, that would be worthy step into ecuNew again.

    Also, have you tried the default configuration as below in the VOLIB ECU test project? You can limit channel number to 4 if no enough internal memory for 128ms tail length in your application.
    ecuSim->ecu_fltseg_length = SIU_MAX_ECU_FLTSEG_LENGTH; /* 32ms default ECU segment duration */
    ecuSim->ecu_num_fltseg = SIU_MAX_ECU_FLTSEG; /* default 3 active filter segments max */
    ecuSim->ecu_filter_length = SIU_MAX_ECU_FILTER_LENGTH ; /* 128ms default ECU tail */
    ecuSim->hyb_filter_length = SIU_MAX_HYBRID_LENGTH; /* 128ms default hybrid path */

    ecuSim->ecuCtl.u.ctl_mask[0] = ecu_ENABLE_ECHO_CANCELLER | /* ENABLE ECU, ENABLE NLP, ENABLE UPDATE */
    ecu_ENABLE_UPDATE |
    // ecu_ENABLE_NLP |
    ecu_ENABLE_AUTO_UPDATE |
    ecu_ENABLE_SEARCH |
    ecu_ENABLE_CNG_ADAPT |
    ecu_ENABLE_OPNLP_DETECT;
    ecuSim->ecuCtl.u.ctl_mask[1] = ecu_ENABLE_NLP_PHASE_RND;

    >>It is commom also to happen timeslots shifts when I run a test sample
    What exactly signals are in the top and bottom of your osciloscope captures? In any chance, ECU should not cause timeslot shift. It's more likely that McBSP/EDMA driver cause ECU broken. There are quite some discussions on McBSP channel swapping issue and solution, you probably have read it: http://processors.wiki.ti.com/index.php/McBSP_Channel_Swapping

    And I happened to find the disccussion "Problem with McBSP + EDMA with Ping-Pong buffers" http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/259360.aspx, which was brought up by you, was this resolved?

    I could not find a real time multi-channel example code for you, but if you simulate the multi-channel case with testing vectors offline, does the issue still happen?

    Regards, Garrett

  • Garret,

    I'll try using the default settings, but I'm not very optimistic about it. After I test it, I'll edit this post.

    >>> Do you mean code still broke in ecuNew returing result = 1 without "Fract align_buf[1]" in the case, or ECU is broken with silence/high pitch signal in multi-channel mode?


     Yes, the code broke there, but for the same reason: some buffer address was ending with the value C (xxxx xxxC), and when the AND operation occurred, 7 & C (0111 & 1100), it returned a value different from 0, therefore, forcing ecuNew() to return 1. I added again the align_buf[1] to realign every buffer in the second instace to make the code works again. The only way to ecuNew() return 0 is when ALL addresses end with either 0 or 8, that's when the AND operation returns zero and the functions may progress (I believe that's how it works). Here it is the addresses of the buffers in 4 instances when ecuNew() doesn't flag a problem:

    As you can see, every address ends with either 0 or 8.

    Translating the oscilloscope captures for you: the top signal (yellow) is the Frame Sync (8kHz, from an external source). I'm using mainly to set the trigger and see the bottom channel (blue) correctly, which is a sample from each channel. It's something like this:

    Frame Sync:

    Sin_ch0 (0) Sin_ch1 (0) Sin_ch2 (0) Sin_ch3 (0) Sin_ch4 (0) Sin_ch5 (0)  Sin_ch6 (0) Sin_ch7 (0) 

    0 0 0 0 0 0 0 0

    Rin_ch0 (0) Rin_ch1 (0) Rin_ch2 (0) Rin_ch3 (0) Rin_ch4 (0) Rin_ch5 (0) Rin_ch6 (0) Rin_ch7 (0)

    0 0 0 0 0 0 0 0

    Frame Sync:

    Sin_ch0 (1) Sin_ch1 (1) Sin_ch2 (1) Sin_ch3 (1) Sin_ch4 (1) Sin_ch5 (1)  Sin_ch6 (1) Sin_ch7 (1) 

    0 0 0 0 0 0 0 0

    Rin_ch0 (1) Rin_ch1 (1) Rin_ch2 (1) Rin_ch3 (1) Rin_ch4 (1) Rin_ch5 (1) Rin_ch6 (1) Rin_ch7 (1)

    0 0 0 0 0 0 0 0

    and so on.

    About the DMA: I don't have any problem with McBSP + EDMA when I do a talkthrough or the RinBuffer = 0xD5 case. The timeslot shift happens randomly when I try the multichannel mode in the ECU. Sometimes it happes, sometimes it doesn't. There's no logic for this problem to show up.

    The DMA works separately just fine, so does the ECU when using SIMULATION mode. Opening a file and running 16 channels simultaneously do not cause the code to crash. So, both configurations work fine when working separately, but does not seem to get along when working together.

    Regarding the Channel Swapping problem, I believe that this is more appropriate when the DSP boots and the firmware runs the first time, right after enabling the EDMA and the McBSP. When I boot and run the code, the DMA is ok, with the timeslots in the right place. If I don't put any audio to have its echo canceled, the DMA rests just fine, without any modification. The problem occurs right after enabling the eight channels when running in the ECU multi channel mode.

    About my problem with the Ping Pong buffers, that is resolved. I'm working right now with the edma in ping pong mode, but in another DSP (c6746). I created that topic right after I started hacking the DevKit of the DSP c6657. I'm new to the Texas' DSP, so I still have difficulties with peripherals' configurations.

    To avoid any doubt, I'm anexing my McBSP and DMA configuration. 

    3288.mcbsp_dma.c

    The clock is also external and has the frequency of 2.080MHz

    Now I'm wondering if the problem may be caused by a DMA error or this continues being an ECU isolated cause. I'm actually running out of options of what I may try to make this work. 

    Thank you very much for your attention,

    Regards,

    Leonardo Trierveiler

  • Hi Leonardo,

    >>As you can see, every address ends with either 0 or 8.

    Yes, some of ECU buffers such as expanded delay line buffer requires log2(N) alignment, where N=3, i.e. need to be aligned to 8 bytes.

     >> The DMA works separately just fine, so does the ECU when using SIMULATION mode. Opening a file and running 16 channels simultaneously do not cause the code to crash. So, both configurations work fine when working separately, but does not seem to get along when working together.

    It looks like the ECU broken is the effect of McBSP/DMA malfunction. You probably need to open another thread for reviewing your McBSP/DMA configuration, so the expert on C6746 peripheral configuration can have chance to read it and comment. You can keep the thread open, we will revisit this after McBSP/DMA configuration is reviewed.

    Regards, Garrett

  • Hi Garret,

    I'll indeed create the topic, just to be sure, but I still believe that the DMA is not the source of the problem. 

    I ran several tests trying to prove this:

    1 - A simple talkthrough, TX = RX, not using ping pong buffers, but only a DMA linked to itself. Ran several tests and the DMA did not break.

    2 - Using ping-pong configuration, I did again TX = RX. No problems  were noticed. The DMA worked like expected for the whole time.

    3 - In my third test, as I'm receiving my audio in A-Law, I uncompressed the Sin Buffer to Linear using muaTblAlaw and then I compressed again to A-law using muaTblAlawCmpr. As Rout = Rin, I did not modify anything and just did the talkthrough. Again, no problems were noticed. DMA worked perfectly.

    4 - In the final test, I just enabled the function ecuSendIn(). It took less than a second to the code to crash. The high pitch noise was heard and everything went to zero. Either my ECU configuration is WRONG or the code is hitting another kind of exeption inside. I'll program a SPI port to read the adresses that the DMA is configured to see if any memory leak is happening. That would explain why simulation works and real time don't.

    The funny thing is that, again, only when Rin = 0xD5 the code won't break. Is there any condition inside the ecuSendIn that reads Rin inputs and do not process if it is all zero? Because it avoids hitting the exception somehow.

    Seeing the ecuSendIn() description, I noticed this:

    /**
    * @brief Signal an ECU to perform echo cancellation
    *
    *
    * This function causes the ECU to perform echo cancellation on
    * a frame of input data.
    *
    * @param[in, out] ecuInst Pointer to ECU instance
    * @param[in, out] vsend_in Send-in signal buffer pointer (linear buffer)
    * @param[in, out] vrecv_in Recv-out signal buffer pointer (HW circular buffer)
    * @param[in, out] vsend_out Send-out signal buffer pointer (linear buffer)
    *
    * @return void
    *
    */

    Does the RinBuffer need any special alignment or treatment  since he'll be used as a circular buffer? What HW stand for? 

    I'll create the topic about the DMA today and link it here as soon as it's created.

    Thank you again for all your help,

    Best Regards,

    Leonardo Trierveiler 

  • Hi Leonardo,

    >>Is there any condition inside the ecuSendIn that reads Rin inputs and do not process if it is all zero? Because it avoids hitting the exception somehow.

    No, no such condition exists in ecuSendIn. But when Rin is always zero, the ECU adaptive filter coefficients are never able to be trained, hence the echo will not be cancelled.

    >>Does the RinBuffer need any special alignment or treatment  since he'll be used as a circular buffer? What HW stand for?

    In the thread http://e2e.ti.com/support/embedded/bios/f/355/t/193193.aspx?pi239031349=1, Charlie provided code to illustrate how to pack the PCM data for the call to ecuSendIn() (copied below).

    In the case that if application doesn't call ecuSendIn in each frame, a circular buffer for Rin is required, ideally a HW (hardware) circular buffer is preferred, see http://www.ti.com/lit/an/spra645a/spra645a.pdf for HW circular buffer configuration.

    The code to illustrate how to pack the PCM data for the call to ecuSendIn():

        linSample sinBuffer[80];

        linSample soutBuffer[80];

        linSample rinLinear[80];

        tint      rinCompr[80];

        tword     rinBuffer[80];

        tint length = 80;

        tint i;

       

        /* Compress A-law delay line samples */

        muaTblAlawCmpr (length, rinLinear, rinCompr);

     

        /* Pack samples for delay line compression */

        for (i=0; i<length; i++) {

          rinBuffer[i] = rinCompr[i] & 0xFF;

        }

     

        /* ECU send-path processing */

        ecuSendIn (inst, (void *) sinBuffer, (void *) rinBuffer, (void *) soutBuffer);

        

    Regards, Garrett

  • Hi Garret,

    About the Rin packing, as I'm receveing the data alredy in A-law format, I assume I don't need this step. As shown in my code, I need to do the inverse to the Sin buffer. I first uncompress from A-law to Linear and, after running the ecuSendIn, I compress the linear Sout to A-law again. This is the right way, right? Why Sin must be Linear and Rin in compressed?

    But, until now, I made no progress in my problem, it still persists. 

    And I opened another topic in the C6746 forum about the McBSP + EDMA. According to , the configuration is ok. And I proved later doing several tests trying to break the EDMA, but I couldn't make it without involving the ecuSendIn() function.

    Here's the topic:

    http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/115/p/303129/1056999.aspx#1056999

    Now I'm trying to determine if there is any memory corruption by declaring and configuring 8 channels but only running the first one. Then, I read the content of the second instance and see if the buffers have any random data. So far, I couldn't detect any memory corruption, limiting even more my options on how I can solve this. I reconfigured all the ECU parameters but no differences were noted.

    Using DSP C6746, I should use the c64+ library, right? I know I read that somewhere here in the forums, but I couldn't find anything in the documentations.

    Best Regards,

    Leonardo Trierveiler

  • Leonardo,

    Yes, you are packing Rin and coding Sin in right way. These should have been proved when you are running ECU with single channel. To have Rin compressed is mainly for memory reduction purpose.

    >>Using DSP C6746, I should use the c64+ library, right?

    Yes, see the explanation in the same thread  http://e2e.ti.com/support/embedded/bios/f/355/t/193193.aspx?pi239031349=1, “ the C64x+ libraries will execute on the C674x DSP core.  From the "TMS320C674x DSP Megamodule Reference Guide" (sprufk5a) -- "The C674x CPU combines support of the C64x+ DSP and C67x+ DSP instruction sets. The C674x devices are object code compatible with the C64x+ and C67x+ devices."

    Regards, Garrett

  • Hi Garret,

    It finally worked! At first, I was working with the following DMA settings:

    Each sample with 4 bytes (acnt = 4).

    An array with 8 samples (bcnt = 8)

    A single frame (ccnt = 1)

    After each frame sync, I did the channel sorting by CPU, not DMA. After the matrix was full, I just changed to another buffer while the previous one was processing (a simple ping pong buffer). And it used to work, all talkthrough tests worked ok and other algorithms worked with this configuration. But in the echo canceller it wasn't working. We don't know for sure what the real cause or problem was, but, when I changed the channel sorting to the DMA, the problem got fixed. Here's my new configuration of the DMA:

    acnt = 1

    bcnt = 32

    ccnt = 80.

    I had to change also the McBSP configuration, from 8 words of 4 bytes to 32 words of 1 byte (RCR and XCR registers).

    I honestly thought that my configuration couldn't cause this problem. We have filters and other algorithms running that uses the same DMA setting and we never had any crash issues.

    Now I'll try to get the channel density we desire (60 channels). If I have any doubt, do I open another thread or may I use this one?

    Thank you very much for your help and attention,

    Best Regards,

    Leonardo Trierveiler

  • Hi Leonardo,


    Thanks for the update. Glad to know you have finally fixed the problem.

    Please open a new thread if you have any doubt on channel density or ECU performance.

    Regards, Garrett