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.

EDMA CSL with SYS/BIOS 6 Help

Other Parts Discussed in Thread: SYSBIOS

I need some help getting a simple code to run. After viewing the workshop videos and trying to implement a quick edma3 transfer of 1 1D array with 16 elements to another 1D array I have reviewed everything I can and cannot get it to work. I'm copying the rCSL manually trigger edma example in my sys/bios 6 code.

I can get the Manually trigger edma example code to work when running just a C project but when running in sys/bios 6 dst is not equal to src.

I added to my cfg file to:

var hwiedm3ccParams = new Hwi.Params();
hwiedm3ccParams.instance.name = "hwiedm3cc";
hwiedm3ccParams.eventId = 8;
hwiedm3ccParams.maskSetting = xdc.module("ti.sysbios.interfaces.IHwi").MaskingOption_ALL;
Program.global.hwiedm3cc = Hwi.create(4, "&edma3ccisr", hwiedm3ccParams);

and that part seems to work because I can trace the code into and out of my edma3ccisr function which is simply posting a semaphore.

I have both the example variables declaration and my own smaller array but I'm only trying to get the rCSL example part of the code working.

Here is my code:

/*
* ======== taskFxn ========
*/
void task0function(UArg a0, UArg a1)
{

System_printf("enter task0function()\n");
int i = 0, j=0, cnt=0;

for(i=0; i<ARRAY_SIZE; i++)
{
src[i]=i;
dst[i]=17;
System_printf("%d,",src[i]);
}

System_printf("\n");

for(i=0;i<SRC_ARRAYS;i++)
{
for(j=0;j<SRC_ARRAY_SIZE;j++)
{
srcBuffer[i][j]=cnt++;
dstBuffer[i][j]=17;
System_printf("%d,",srcBuffer[i][j]);
}
}

System_printf("\n");

System_flush(); /* force SysMin output to console */

// Clear Event Registers
CSL_FINST(edma3ccRegs->ECR, EDMA3CC_ECR_REG, MASK);
CSL_FINST(edma3ccRegs->SECR, EDMA3CC_SECR_REG, MASK);

// Enable Channel 10 to DSP (Region 1)
CSL_FINST(edma3ccRegs->DRA[CSL_EDMA3_REGION_1].DRAE,
EDMA3CC_DRAE_E10, ENABLE);

// Assign Channel 10 to Queue 0
CSL_FINST(edma3ccRegs->DMAQNUM[1], EDMA3CC_DMAQNUM_E2, Q0);

// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[EDMA_EVENT10].OPT = CSL_EDMA3CC_OPT_RESETVAL;

// Config PaRAM OPT (Enable TC Interrupt; Set TCC)
edma3ccRegs->PARAMSET[EDMA_EVENT10].OPT =
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT10);

// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[EDMA_EVENT10].SRC = (Uint32)&srcBuffer;
edma3ccRegs->PARAMSET[EDMA_EVENT10].DST = (Uint32)&dstBuffer;

// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[EDMA_EVENT10].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, XFER_BYTES) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, XFER_ARRAYS);
edma3ccRegs->PARAMSET[EDMA_EVENT10].CCNT = XFER_FRAMES;

// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[EDMA_EVENT10].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, SRC_ARRAY_SIZE) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, DST_ARRAY_SIZE);

// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[EDMA_EVENT10].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0);

// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[EDMA_EVENT10].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, PaRAM_NULL_LINK) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, 0);

// Enable Interrupts for Channel 10
CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I10, SET);

//Intrinsic Function to Enable Interrupts
_enable_interrupts();

// Manually Enable Event 10
CSL_FINST(edma3ccRegs->ESR, EDMA3CC_ESR_E10, SET);

Semaphore_pend(sem0, BIOS_WAIT_FOREVER);

for(i=0; i<ARRAY_SIZE; i++)
{
System_printf("%d,",dst[i]);
}

System_printf("\n");

for(i=0;i<DST_ARRAYS;i++)
{
for(j=0;j<DST_ARRAY_SIZE;j++)
{
System_printf("%d,",dstBuffer[i][j]);
}
}

System_printf("\n");

//Intrinsic Function to Disable Interrupts
_disable_interrupts();

System_printf("exit task0function()\n");

/* force SysMin output to console */
System_flush();

BIOS_exit(0);
}

/*
* ======== edma3isr ========
*/

int edma3ccisr()
{
System_printf("enter edma3ccisr()\n");

Uint32 regIPR, IxBitMask, IxCounter;
while(edma3ccRegs->IPR != 0)
{
// Read Interrupt Pending Register
regIPR = edma3ccRegs->IPR;

// Loop for Set Interrupt Pending Bit
for(IxCounter = 0; IxCounter < 32; IxCounter++)
{
IxBitMask = 1 << IxCounter;
if(regIPR & IxBitMask)
{
// Exit Example on Correct Interrupt
if(IxCounter == EDMA_EVENT10)
Semaphore_post(sem0);
else
System_printf("Interrupt not supported!\n");

// Clear Pending Interrupt
edma3ccRegs->ICR = IxBitMask;
break;
}
}
}

System_printf("exit edma3ccisr()\n");
return 0;
}

This is my console output:

enter task0function()
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
enter edma3ccisr()
exit edma3ccisr()
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,17,
exit task0function()

any help will be greatly appreciated. I know I'm close but can't figure out what am I missing.

  • Hi,

    Thanks for your post.

    I have reviewed your EDMA setup, PaRAM intialization, DSP INTC setup, EDMA manual trig DSP example code and it seems to be OK.

    I understand from the bios config file that, the event id 8 which is for "EDMA3_0_CC0_INT1" transfer completion interrupt is mapped to the maskable HWI "CPUINT4". May be, you could route it  to any of the other available maskable CPUINT5 through 15 and try it and i mean, you could route it any other CPU interrupt available from 5 to 15.

    Also, you could try enabling EDMA3 CC0 and TC0, TC1 error interrupts through their event ID's below, thereby, you could detect the errors in CC and TC's  if any:

    56                              EDMA3_0_CC0_ERRINT                                      EDMA3_0 Channel Controller 0 Error Interrrupt

    57                              EDMA3_0_TC0_ERRINT                                      EDMA3_0 Transfer Controller 0 Error Interrrupt

    58                              EDMA3_0_TC1_ERRINT                                      EDMA3_0 Transfer Controller 1 Error Interrrupt

    Again, you have to wait for event 10 completion interrupt after manually setting Event 10 and I think, there is some messup in the below code before disabling interrupts:

    Semaphore_pend(sem0, BIOS_WAIT_FOREVER);

    for(i=0; i<ARRAY_SIZE; i++)

    {

    System_printf("%d,",dst[i]);

    }

    System_printf("\n");

    for(i=0;i<DST_ARRAYS;i++)

    {

    for(j=0;j<DST_ARRAY_SIZE;j++)

    {

    System_printf("%d,",dstBuffer[i][j]);

    }

    }

    System_printf("\n");

    //Intrinsic Function to Disable Interrupts

    _disable_interrupts();

    Kindly validate the above code snippet and i think, the problem should arise probably only on the above piece of code and none other than this.

    I think,  _disable_interrupts() function should be followed immediately after Semaphore_pend()  which should be valid, please check the below code for the same and try it:

    Semaphore_pend(sem0, BIOS_WAIT_FOREVER);

    //Intrinsic Function to Disable Interrupts

    _disable_interrupts();

    for(i=0; i<ARRAY_SIZE; i++)

    {

    System_printf("%d,",dst[i]);

    }

    System_printf("\n");

    for(i=0;i<DST_ARRAYS;i++)

    {

    for(j=0;j<DST_ARRAY_SIZE;j++)

    {

    System_printf("%d,",dstBuffer[i][j]);

    }

    }

    System_printf("\n");

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • Thanks Sivaraj Kuppuraj for your replied.

    I fixed the problem but I don't understand the why. I have an idea but it is not very strong. If you see the code below, it is the initialization of the src and dst array, it has System_printf and the flush to the console so I can see how the src array will start.

    Once I removed it it works. I can print, after the semaphore is posted from the interrupts and the src and dst are equal. Maybe there is something with the system_flush or printf that disrupts the ISR. What do you think?

    Maybe you have a good point, and I can try to disable the interrupts, but that function is an intrinsic function really doing nothing. If I trace its implementation the function is empty. I can also get the code to run if I comment out both the enable and disable interrupt. Intrinsic functions.


    /*
    * ======== taskFxn ========
    */
    void task0function(UArg a0, UArg a1)
    {

    System_printf("enter task0function()\n");
    int i = 0, j=0, cnt=0;

    for(i=0; i<ARRAY_SIZE; i++)
    {
    src[i]=i;
    dst[i]=17;
    System_printf("%d,",src[i]);
    }

    System_printf("\n");

    for(i=0;i<SRC_ARRAYS;i++)
    {
    for(j=0;j<SRC_ARRAY_SIZE;j++)
    {
    srcBuffer[i][j]=cnt++;
    dstBuffer[i][j]=17;
    System_printf("%d,",srcBuffer[i][j]);
    }
    }

    System_printf("\n");

    System_flush(); /* force SysMin output to console */
  • Hi,

    Yes, you are right. Even, i would recommend you not to use "System_flush()"and "System_printf" which are really not necessary, i believe so.

    Kindly retain the intrinsic functions like enable and disable interrupts in the code when you use any bios api calls or any dsp kernel library api calls in order to have smoother operation. Anyway, glad that you have succeeded in integrating Sysbios 6 code on rCSL manually trigger edma example.

    Thanks for your update.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------