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);
}