Okay ..here is my original code.
I have tried two approaches.
[1] The code as shown .... with the bios referencing _edmaIsr.
I have the edma commented so that the link option is disabled.
As I mentioned in the original email, if I allow one IRQ to be processed,
I see that at the end of the 2x4Kx16 transfers on the emif, I see 16
calls to the ISR being made. If I enable
// if (EDMA_intTest(EdmaMcAsp_RcvTcc))
and use that to clear
EDMA_intClear(EdmaMcAsp_RcvTcc);
then I can run for a few cycles before the ISR is not called.
If I remove the above test, and unconditionally, issue
EDMA_intClear(EdmaMcAsp_RcvTcc);
the the ISR is called almost continuously.
[2] Add the
// EDMA_intHook(EdmaMcAsp_RcvTcc, edmaIsr);
into the edma initialization routine, and change the BIOS setup
to point to EDMA_intDispatcher.
In this case, the edmaIsr is never entered.
---------------------------------------------------------------
I appreciate your offer to review. I find debugging the problems
like shooting in the dark. I suspect what I am doing is not that
elaborate, I just can not find similar examples in TI documentation,
or code composer help.
Thanks in advance.
------------------------------------------------------------------
// Edma variables for McBsp
static int McBspStartedFlag;
static int McAspStartedFlag;
static int EdmaXmtTcc; // XMIT Trasnfer Complete code
static EDMA_Config Xmtcfg; // Config Structure for McBSP Xmit
// Edma variables for McAsp
static EDMA_Handle hEdmaMcAsp_RcvRld[ADBLKS]; // Reload-Link Parameter
Blocks
static int EdmaMcAsp_RcvTcc; // Receive Transfer
Complete Code
static int EdmaChARevt0; // Remapped EDMA Events
void edmaIsr (void);
#define DSP_FPGA_DMA (Uint32 *) 0xB0000398
#define DSP_CHIP_CTR (Uint32 *) 0xB00003C0
void InitEDMA_McAsp(void)
{
int i;
EDMA_Config cfg;
gAdBlkNum = -1; // Init Most recent blocknumber
gAdBlkCnt = 0; // Init blk received counter
// EdmaChARevt0 = EDMA_map(EDMA_CHA_AREVT0, 12); // McAsp0 Receive Event
EdmaChARevt0 = EDMA_map(EDMA_CHA_EXTINT6, 12); // IRQ6 Event
EdmaMcAsp_RcvTcc = EDMA_intAlloc(-1); // Allocate a trasnfer complete code,
int number
EDMA_intDisable (EdmaMcAsp_RcvTcc); // Disable Interupt, Clears bit in
CIER
EDMA_intClear (EdmaMcAsp_RcvTcc); // Clear any pending interrupt, Clears
bit CIPR
hEdmaMcAsp_Rcv = EDMA_open(EdmaChARevt0, EDMA_OPEN_RESET ); // Open the
receive EDMA
i = EDMA_allocTableEx(ADBLKS,&hEdmaMcAsp_RcvRld[0]);
cfg.opt = EDMA_OPT_RMK(
EDMA_OPT_PRI_LOW,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE, // Don't increment Source Adress
EDMA_OPT_2DD_NO,
// EDMA_OPT_DUM_IDX, // Increment Destination Address DUM = 011)
EDMA_OPT_DUM_INC, // Increment Destination Address DUM = 011)
EDMA_OPT_TCINT_YES, // Enable transfer Complete interrupt
EDMA_OPT_TCC_OF(EdmaMcAsp_RcvTcc),
// EDMA_OPT_LINK_YES,
EDMA_OPT_LINK_NO,
EDMA_OPT_FS_YES); // EDMA_OPT_FS_YES => FS = 0x1
cfg.src = EDMA_SRC_RMK( 0x80000000);
cfg.dst = EDMA_DST_RMK(&gAdBuf[0]);
cfg.cnt = EDMA_CNT_RMK(0, 2048); // 1 frame, 2048 elements
cfg.idx = EDMA_IDX_RMK(8192,4); // (Bytes/frame,Bytes/element)
cfg.rld = EDMA_RLD_RMK(2048, EDMA_getTableAddress(hEdmaMcAsp_RcvRld[0]));
// cfg.rld = EDMA_RLD_RMK(0, 0);
// Setup the primary EDMA Configuration for receive (Bit Definitions can be
found in csl_edmahal.h.)
EDMA_config (hEdmaMcAsp_Rcv, &cfg);
for(i=0; i<ADBLKS;i++)
{
cfg.dst = EDMA_DST_RMK(&gAdBuf[2*i*ADBLK_LEN]); // 2* due to HS data.
if(i != ADBLKS-1)
cfg.rld =
EDMA_RLD_RMK(2048,EDMA_getTableAddress(hEdmaMcAsp_RcvRld[i+1]));
else
cfg.rld = EDMA_RLD_RMK(2048,EDMA_getTableAddress(hEdmaMcAsp_RcvRld[0]));
EDMA_config(hEdmaMcAsp_RcvRld[i], &cfg);
}
// EDMA_intHook(EdmaMcAsp_RcvTcc, edmaIsr);
EDMA_intEnable(EdmaMcAsp_RcvTcc); // Sets the Tcc bit in the CIER
return;
} // InitEDMA_McAsp( )
// Setup the EDMA Interrupt to use the DSP/BIOS HWI Dispatcher
void initEDMAInterrupt(void)
{
IRQ_globalEnable();
IRQ_nmiEnable();
IRQ_map(IRQ_EVT_EDMAINT, 8);
IRQ_enable(IRQ_EVT_EDMAINT); // Enable EDMA-to-CPU interrupt (
interrupt 8 )
return;
}
void edmaIsr(void)
{
Uint32 t, ADC_BufErrCnt_prev;
IfcHostStat *host_stat;
msgObj msg; // Mailbox Message Object
// *DSP_FPGA_DMA = 0x00000000;
*DSP_CHIP_CTR = 0x00000000;
// host_stat = &gHostStatus;
// t = CLK_gethtime();
// if (McAspStartedFlag) STS_delta(&McaspRcvInt, t);
// STS_set(&McaspRcvInt,t);
// McAspStartedFlag = 1;
// McAsp Receive EDMA Complete
// if (EDMA_intTest(EdmaMcAsp_RcvTcc))
// {
// ADC_BufErrCnt_prev = gADC_BufErrCnt;
// if (gAdc_InProgressFlag == 2)
// {
// gADC_BufErrCnt++;
// gRfInputStatus |= ADC_BUFFER_OVERWRITE_ERROR;
// }
// if (gADC_BufErrCnt != ADC_BufErrCnt_prev)
// {
// host_stat->adc_buf_error_count = gADC_BufErrCnt;
// InterruptSBC(); // Status change; Set IRQ to SBC
// }
// gAdc_InProgressFlag++;
gAdBlkCnt++;
if(++gAdBlkNum == ADBLKS) {gAdBlkNum = 0;} // Indicate which block is
full
// if(gAdBlkNum != ADBLKS-1)
// cfg.rld =
EDMA_RLD_RMK(2048,EDMA_getTableAddress(hEdmaMcAsp_RcvRld[gAdBlkNum+1]));
// else
// cfg.rld =
EDMA_RLD_RMK(2048,EDMA_getTableAddress(hEdmaMcAsp_RcvRld[0]));
// EDMA_config(hEdmaMcAsp_RcvRld[i], &cfg);
EDMA_intClear(EdmaMcAsp_RcvTcc); // Clear the Pending Flag
// msg.msgId = EDMA_DONE;
// msg.msgCmd = AD_BLKRDY;
// post msg - timeout must be 0 for hwi
// MBX_post(&mbxNextOp, &msg, 0); // then Send a message
// }
return;
}
------------------------------------------------------------------
--
Regards,
John Retta
Owner and Designer
Retta Technical Consulting Inc.
303-926-0068
email : jretta@rtc-inc.com
web : www.rtc-inc.com
"Brad Griffis" <bradgriffis@hotmail.com> wrote in message
news:sZqdnaxvOPC8wMXbnZ2dnUVZ_hynnZ2d@comcast.com...
> John Retta wrote:
>> I have a legacy application that runs on a 6713 that uses
>> the BIOS for scheduling and IRQ handling. I am using CC 3.1.
>> Four mcasp channels
>> are steered into a single edma channel, and 4Kx32 buffers are stored.
>> I volunteered to code and test a modification where the 4 MCASP channels
>> were replaced with a 4Kx32 block transfer over the emif.
>>
>> Seems straight forward enough. I am collecting emif blocks fine, but
>> at the conclusion of the block transfer, my ISR is being invoked
>> multiple times. (16 x on one block transfer .. but this degrades into
>> continous IRQs when transfers are sustained).
>>
>> I have one call, several emails into TI ... still waiting for a response.
>>
>> [1] So ideas as to what I am doing wrong?
>> The documentation on the linkages between the DSP EDMA IRQ dispatcher
>> are minimal/nonexistent. I can provide my code in next posting ...
>> but I think the symptom may be enough at this point.
>>
>> [2] I found a related problem on dsprelated.com from June 2003.
>> The user believed a solution was to bypass the HWI IRQ dispatcher
>> function,
>> and requested details on how to proceed. He received a really good reply
>> where 3 step process identified (create asm HWI handler to
>> save config, enter C handler; create a C ISR, and change BIOS function
>> link to asm handler. I can't seem to "fill in the steps of the
>> asm handler for the C6713. Namely, can't find equivalent include filss
>> or description of what is passed to HWI_enter/HWI exit.
>>
>> I am FPGA designer, but I thought this would be easy enough to tackle.
>> What I thought might only take a day has taken over 10 days, and I am
>> not done. I am finding reference material, but it is fairly distibuted,
>> and not enough to come to compete closure.
>>
>> Thanks in advance.
>>
>> Here is the step 1 for creating asm for c62 series processor.
>> -------------------------------------------------------------------------
>>
>> 1) Create an HWI handler in assembly (indeed, hwi.h62 cannot
>> be used in a C file...)
>>
>> --------- hwi_int4.s62 - begin -------------
>> .include "c62.h62"
>> .include "hwi.h62"
>>
>> .text
>> .global _hwi_int4_c_handler
>> .global _hwi_int4_handler
>>
>> _hwi_int4_handler:
>>
>> ; Save Context
>> HWI_enter C64_ATEMPS, C64_BTEMPS, C64_CTEMPS, 0xFFFF, 0
>>
>> ; Clear int source
>> mvkl 0x0000010, a3 ; assuming here Int4
>> mvc a3, ICR
>>
>> ; Call int handler
>> b _hwi_int4_c_handler ; assuming near call is ok (memory model)
>> mvkl _hwi_int4_end, b3
>> mvkh _hwi_int4_end, b3
>> nop 3
>>
>> _hwi_int4_end:
>> ; Restore context
>> HWI_exit C64_ATEMPS, C64_BTEMPS, C64_CTEMPS, 0xFFFF, 0
>>
>> .end
>>
>> ------------------------------------------------------------------
>>
>
> Yikes, I think you're headed in the wrong direction. I would definitely
> stick with your original scheme where EDMA_intDispatcher in conjunction
> with a handler for that specific transfer completion.
>
> The function EDMA_intDispatcher is actually a CSL function, not a BIOS
> function. Its purpose is simple: to read the CIPR register of the EDMA
> to determine which specific EDMA channel completed and then to call the
> corresponding handler. (FYI, it also clears the corresponding bit from
> CIPR so you wouldn't get the same interrupt over and over again).
>
> From what you describe it sounds like your issue is somewhere in your EDMA
> setup. Perhaps you should post your code being used to configure the EDMA
> Parameter Sets.
>
> Brad