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.

Problems with EDMA3

Hello,
Currently we are working with the EVMDM6437 and we cannot make EDMA3 works fine on DM6437 as we did on DM642 and DM6446.

The project is really complex and large so we decided to symplify it and try to fix the EDMA3 troubles with an small program. The problem is related with linked transfers. The aplication works fine if three transfers are linked but when we link 4 transfers the following error appear: TC Program Set already active.

We transfer the contexts of the transfers with IDMA from internal memory to the Parameter Set table, specifically PaRam 20, 21, 22 and 23.
Transfers (through channel 2) are configured to be auto-triggered when the seventh word of 23th PaRam Set was written. We get the error just when the first auto-trigger transfer is performed and the program stop the execution.

We tested this code on a DM6446 DSP with 4 and more linked transfers without problems.

Next We show a piece of the code we have written.

Does anybody know what mean exactly "TC Program Set already active" ?
How could we solve this problem? Any ideas?

Regards,

Fernando & Gonzalo



CODE:

void ddr2_a_L2_2(void) // cuatro Y de 8x8 enlazadas params:20-23
{

*(volatile uint *)((uint)QEESR)= (1<<2);
*(volatile uint *)((uint)QCHMAPn+(2<<2))= (23<<5)|(7<<2);

/* contexto de la transferencia Y1 */
Params[0].option    = 0x0011F00C;
Params[0].src    = (unsigned int)y_mb_DDR2;
Params[0].bcnt_acnt   = ((8)<<16)|8;
Params[0].dst    = (unsigned int)y_mb_L2;
Params[0].dstbidx_srcbidx  = ((8)<<16)|32;
Params[0].bcntrld_link   = 0xFFFF;
Params[0].dstcidx_srccidx  = 0;
Params[0].ccnt    = 1;
/* contexto de la transferencia Y2 */
Params[1].option    = 0x0001F004;
Params[1].src    = (unsigned int)(y_mb_DDR2+8);
Params[1].bcnt_acnt   = ((8)<<16)|8;
Params[1].dst    = (unsigned int)(y_mb_L2+8*8);
Params[1].dstbidx_srcbidx  = ((8)<<16)|32;
Params[1].bcntrld_link   = 0x4280;
Params[1].dstcidx_srccidx  = 0;
Params[1].ccnt    = 1;
/* contexto de la transferencia Y3 */
Params[2].option    = 0x0001F004;
Params[2].src    = (unsigned int)(y_mb_DDR2+8*32);
Params[2].bcnt_acnt   = ((8)<<16)|8;
Params[2].dst    = (unsigned int)(y_mb_L2+8*8*2);
Params[2].dstbidx_srcbidx  = ((8)<<16)|32;
Params[2].bcntrld_link   = 0x42A0;
Params[2].dstcidx_srccidx  = 0;
Params[2].ccnt    = 1;
/* contexto de la transferencia Y4 */
Params[3].option    = 0x0001F004;
Params[3].src    = (unsigned int)(y_mb_DDR2+8+8*32);
Params[3].bcnt_acnt   = ((8)<<16)|8;
Params[3].dst    = (unsigned int)(y_mb_L2+8*8*3);
Params[3].dstbidx_srcbidx  = ((8)<<16)|32;
Params[3].bcntrld_link   = 0x42C0;
Params[3].dstcidx_srccidx  = 0;
Params[3].ccnt    = 1;

/* copio param a la tabla y se autodispara QDMA */
*(volatile uint *)((uint)IDMA0_MASK)=    (uint)0x00000000;
*(volatile uint *)((uint)IDMA0_SOURCE)=    (uint)Params;
*(volatile uint *)((uint)IDMA0_DEST)=      (uint)0x01C04280; // PaRAM 20
*(volatile uint *)((uint)IDMA0_COUNT)=     (uint)0x00000000; // trigger IDMA0
}

  • "TC Program Set already active" sounds like you are trying to reconfigure a a PaRAM set while it is currently in progress, in particular I am guessing that this is telling you that the PROGBUSY bit in the EDMA3TC register as discussed in section 4.4.3 of SPRU987. If this is the case it would seem you just need to wait for the current transfer to finish before re programming the EDMA (potentially disabling the event first to allow it to finish). Have you tried using the EDMA driver included within C:\dvsdk_1_01_00_15\psp_1_00_02_00\edma3?

  • Transfers are programmed for normal completion and they are linked. As discussed in section 2.3.7 of SPRU987:
    "Once the channel completion conditions are met for an event, the transfer parameters located at the link address are loaded into the current DMA or QDMA channel’s associated parameter set. The EDMA3CC reads the entire PaRAM set (8 words) from the PaRAM set specified by LINK and writes all 8 words to the PaRAM set associated with the current channel."

    I understand that associated parameter set is not reloaded automatically with the context of the second transfer until the first one finishes so the waiting is implicit in the linked transfers.

     

  • Would it be possible for you to share the entire application so that I can look into in more detail and provide some help?

  • Sure! Here is the entire application.

    #include "MyXdma.h"

    #include <stdio.h>
    #include <std.h>
    #include <bcache.h>


        typedef struct PARAM{
            unsigned int option;
            unsigned int src;
            unsigned int bcnt_acnt;
            unsigned int dst;
            unsigned int dstbidx_srcbidx;
            unsigned int bcntrld_link;
            unsigned int dstcidx_srccidx;
            unsigned int ccnt;
            }PARAM;    // Tipo Parameter Set


        // buffers in L2
        unsigned char y_mb_L2[16*16];

        // buffers in DDR2
        unsigned char y_mb_DDR2[32*32];


    #pragma DATA_SECTION (Params    , ".Params")
    #pragma DATA_ALIGN(Params,32)    // g0n - 32 bytes aligned

    #pragma DATA_SECTION (y_mb_L2    , ".L2Buffers")

    #pragma DATA_SECTION (y_mb_DDR2    , ".DDR2Buffers")

    #pragma DATA_ALIGN(y_mb_L2,64)

    #pragma DATA_ALIGN(y_mb_DDR2,64)

    PARAM Params[4];

       
    /* lista de ejemplos de transferencias EDMA3 */
    void ddr2_a_L2_2(void);

    void main(void)
    //void decode_tsk_function(void)
    {
        int i;
        int options;


        *(volatile uint *)((uint)DRAE1)=      0xFFFFFFFF;
        *(volatile uint *)((uint)DRAEH1)=     0xFFFFFFFF;
        *(volatile uint *)((uint)QRAE1)=      0x000000FF;   
        *(volatile uint *)((uint)QDMAQNUM)=    0x00000000;
         
       
        /* lanzamos de uno en uno los diferentes ejemplos */

        ddr2_a_L2_2();    // prueba 6   

        while(1);
    }

        void ddr2_a_L2_2(void)    // cuatro Y de 8x8 enlazadas params:20-23
        {
            int i, options;


            *(volatile uint *)((uint)QEESR)= (1<<2);                                  // permite eventos del canal 2
            *(volatile uint *)((uint)QCHMAPn+(2<<2))= (23<<5)|(7<<2);    // asociamos canal 2 al param 20



            /* contexto de la transferencia Y1 */
            Params[0].option             = 0x0011F00C;
            Params[0].src                  = (unsigned int)y_mb_DDR2;
            Params[0].bcnt_acnt         = ((8)<<16)|8;
            Params[0].dst                  = (unsigned int)y_mb_L2;
            Params[0].dstbidx_srcbidx    = ((8)<<16)|32;
            Params[0].bcntrld_link        = 0xFFFF;
            Params[0].dstcidx_srccidx    = 0;
            Params[0].ccnt                = 1;
            /* contexto de la transferencia Y2 */
            Params[1].option             = 0x0001F004;
            Params[1].src                = (unsigned int)(y_mb_DDR2+8);
            Params[1].bcnt_acnt            = ((8)<<16)|8;
            Params[1].dst                = (unsigned int)(y_mb_L2+8*8);
            Params[1].dstbidx_srcbidx    = ((8)<<16)|32;
            Params[1].bcntrld_link        = 0x4280;
            Params[1].dstcidx_srccidx    = 0;
            Params[1].ccnt                = 1;
            /* contexto de la transferencia Y3 */
            Params[2].option             = 0x0001F004;
            Params[2].src                = (unsigned int)(y_mb_DDR2+8*32);
            Params[2].bcnt_acnt            = ((8)<<16)|8;
            Params[2].dst                = (unsigned int)(y_mb_L2+8*8*2);
            Params[2].dstbidx_srcbidx    = ((8)<<16)|32;
            Params[2].bcntrld_link        = 0x42A0;
            Params[2].dstcidx_srccidx    = 0;
            Params[2].ccnt                = 1;
            /* contexto de la transferencia Y4 */
            Params[3].option             = 0x0001F004;
            Params[3].src                = (unsigned int)(y_mb_DDR2+8+8*32);
            Params[3].bcnt_acnt            = ((8)<<16)|8;
            Params[3].dst                = (unsigned int)(y_mb_L2+8*8*3);
            Params[3].dstbidx_srcbidx    = ((8)<<16)|32;
            Params[3].bcntrld_link        = 0x42C0;
            Params[3].dstcidx_srccidx    = 0;
            Params[3].ccnt                = 1;


            INIT_CHANNEL_LOW(0x1F);    // borramos el indicador 0x1F

            /* copio param a la tabla y se autodispara QDMA */
            *(volatile uint *)((uint)IDMA0_MASK)=       (uint)0x00000000;    // se enmascaran ...
            *(volatile uint *)((uint)IDMA0_SOURCE)=    (uint)Params;
            *(volatile uint *)((uint)IDMA0_DEST)=      (uint)0x01C04280;     // PaRAM 20-en adelante
            *(volatile uint *)((uint)IDMA0_COUNT)=     (uint)0x00000000;    // trigger IDMA0

            QDMA_WAIT_NOSET_LOW(0x1F);

        }

     

    IDMA transfers are not the problem. I tried to execute the same application with QDMA transfers disabled and there were no error message, as expected.

    The error "TC Program Set already active" comes just when QDMA transfers start.

    The software I am working with is CCS 3.3 (SR10) and DM6437 Little Endian Simulator

     

    Regards

     

  • Hi Anuj,

    Did you try to compile and run the aplication you asked me for?

    I´m pretty sure that it´s a bug of the DM6437 Simulator.

    Support for DM6437 was added in Service Release 7.
    The problem persists with SR8, 9, 10 and 11.

    Could you report on this fact to the software developers so they try to fix it in SR12?

     

    Thanks,

    Gonzalo

  • Hi Gonzalo,

                 I am trying to reproduce the problem with your source code. Can you send or post "MyXdma.h" header file, without that i am getting into compile errors?

    Regards

    Mani

  • Hi Manivannan E,

           The next code is what you need to compile the program.

        #define EDMA_CC_BASE        0x01C00000  

        #define DRAE1                EDMA_CC_BASE+0x0348
        #define DRAEH1             EDMA_CC_BASE+0x034C
        #define QRAE1                EDMA_CC_BASE+0x0384

        #define QDMAQNUM        EDMA_CC_BASE+0x0260
        #define QCHMAPn            EDMA_CC_BASE+0x0200

        #define QEESR                EDMA_CC_BASE+0x228C

        #define ICRH                EDMA_CC_BASE+0x2274
        #define INIT_CHANNEL_HIGH(id) { *(volatile uint *)((uint)ICRH) = (1 << (id)); }

        #define IDMA0_STAT          0x01820000
        #define IDMA0_MASK         0x01820004
        #define IDMA0_SOURCE  0x01820008
        #define IDMA0_DEST         0x0182000C
        #define IDMA0_COUNT      0x01820010

        #define QDMA_WAIT_NOSET_LOW(id) { while(! (*(volatile uint *)0x01C02268&(1<<(id))) ); } 

        #define INIT_CHANNEL_LOW(id) { *(volatile uint *)((uint)0x01C02270/*ICR*/) =  (1 << (id)); }

     

    Thanks

    Gonzalo

  • Has anybody successfully simulated more than three linked transfers using the DM6437 Simulator?

     

    Gonzalo