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.

EDMA3 LLD driver



Hello,

I am using LLD driver of edma3 on c6767/omapl137 starter kit. I am building an application that copy a data from external SDRAM to internal RAM, and generates interrupt on completion.

It almost working, copies the data successifully, and sometimes even generates an interrupt[:|], but it has some issues:

1. It works only when I define .text section in BIOS in SDRAM. Why?

2. I am a lillte confused on how the interrupt is working with this driver - is it uses ECM dispatcher or not? If I configure the program to ECM dispatcher, where do I define the pointer to interrupt handler? Is there any help on ECM Module? I've found only help for LLD Driver, but ECM_Dispatch and all other functions descriptions are missing.

3. When I use direct (without the dispatcher) interrupt (interrupt event 8 - transfer completion) and, say, link it to CPU interrupt #5, it SOMTIMES generate an interrupt, ususally if I perform step by step run, not when I let it run.

But mostly my software crushes! It simply generates an NMI interrupt and then jumps to some random location.

I dont think that this is a stack overflow, since I increased the stack big time, and it didnt helped.

I did build my program in such way that it starts the EDMA transfer, exits the function, and pendsby semaphore, until completion interrupt is generated - the interrupt releases the semaphore.

I use the function given by LLD driver edma3_lld_01_10_00_01.

 

Thank You

Arye

 

This is part of the code that relates to edma, it is a simplified version of what is provided in example:


unsigned int ch1Id = 0;
EDMA3_DRV_Result result = EDMA3_DRV_SOK;
extern EDMA3_DRV_Handle hEdma;

// Interrupt Handler
#pragma CODE_SECTION(EDMA3_Interrupt_Handler,".CodeBuffer");
void EDMA3_Interrupt_Handler()
{
 result = EDMA3_DRV_SOK;

 SEM_postBinary(&EDMA3_SEM);

 result = EDMA3_DRV_freeChannel (hEdma, ch1Id);
}


#pragma CODE_SECTION(Edma3_Transfer,".CodeBuffer")
void Edma3_Transfer(signed char * dstBuff1,
                       signed char * srcBuff1,
                       unsigned int length)
{
/*
    EDMA3_DRV_ChainOptions chain = {EDMA3_DRV_TCCHEN_DIS,
                                    EDMA3_DRV_ITCCHEN_DIS,
                                    EDMA3_DRV_TCINTEN_DIS,
                                    EDMA3_DRV_ITCINTEN_DIS};
*/

//    EDMA3_DRV_Result result = EDMA3_DRV_SOK; // dwefined externally
    static unsigned int BRCnt = 0;
    static int srcbidx = 0, desbidx = 0;
    static int srccidx = 0, descidx = 0;
    static unsigned int tcc1 = 0;

 unsigned int restore_value;

// ----------- arguments of example function ------------------
    static unsigned int acnt = 4;
    static unsigned int bcnt;
    static unsigned int ccnt = 1;
//    EDMA3_DRV_SyncType syncType = EDMA3_DRV_SYNC_AB;
// ------------------------------------------------------------
 bcnt = length;
 result = EDMA3_DRV_SOK;

 // Save interrupt state
// restore_value = HWI_disable();

#ifdef EDMA3_ENABLE_DCACHE
    /*
    * Note: These functions are required if the buffer is in DDR.
    * For other cases, where buffer is NOT in DDR, user
    * may or may not require the below functions.
    */
    /* Flush the Source Buffers */
    if (result == EDMA3_DRV_SOK)
     result = Edma3_CacheFlush((unsigned int)srcBuff1, (acnt*bcnt*ccnt));

    /* Invalidate the Destination Buffers */
    if (result == EDMA3_DRV_SOK)
        result = Edma3_CacheInvalidate((unsigned int)dstBuff1, (acnt*bcnt*ccnt));
#endif  /* EDMA3_ENABLE_DCACHE */

    /* Set B count reload as B count. */
    BRCnt = bcnt;

    /* Setting up the SRC/DES Index */
    srcbidx = (int)acnt;
    desbidx = (int)acnt;

    /* AB Sync Transfer Mode */
    srccidx = ((int)acnt * (int)bcnt);
    descidx = ((int)acnt * (int)bcnt);

/*
    // Transfer complete chaining enable
    chain.tcchEn = EDMA3_DRV_TCCHEN_EN;
    // Intermediate transfer complete chaining disabled
    chain.itcchEn = EDMA3_DRV_ITCCHEN_DIS;
    // Transfer complete interrupt is enabled
    chain.tcintEn = EDMA3_DRV_TCINTEN_EN;
    // Intermediate transfer complete interrupt is disabled
    chain.itcintEn = EDMA3_DRV_ITCINTEN_DIS;
*/
    /* Setup for Channel 1*/
    tcc1 = EDMA3_DRV_TCC_ANY;
    ch1Id = EDMA3_DRV_DMA_CHANNEL_ANY;

    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_requestChannel (hEdma, &ch1Id, &tcc1,(EDMA3_RM_EventQueue)0,&callback1, NULL);
    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_setSrcParams (hEdma, ch1Id,(unsigned int)(srcBuff1),EDMA3_DRV_ADDR_MODE_INCR,EDMA3_DRV_W8BIT);
    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_setDestParams (hEdma, ch1Id,(unsigned int)(dstBuff1),EDMA3_DRV_ADDR_MODE_INCR,EDMA3_DRV_W8BIT);
    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_setSrcIndex (hEdma, ch1Id, srcbidx, srccidx);
    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_setDestIndex (hEdma, ch1Id, desbidx, descidx);
    if (result == EDMA3_DRV_SOK)
   result = EDMA3_DRV_setOptField (hEdma,ch1Id,EDMA3_DRV_OPT_FIELD_TCINTEN,1u);

    /* AB Sync Transfer Mode */
    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_setTransferParams (hEdma, ch1Id, acnt, bcnt,ccnt, BRCnt,EDMA3_DRV_SYNC_AB);

    if (result == EDMA3_DRV_SOK)
        result = EDMA3_DRV_enableTransfer (hEdma, ch1Id,EDMA3_DRV_TRIG_MODE_MANUAL);
 
// HWI_restore(restore_value);
}