您好:
我用定时器触发EDMA3进行数据传输,EDMA传输完成时,产生一个EDMA传输完成事件,该事件通过INTC,产生一个事件给核内中断控制器,产生一个中断.结果,这个中断只产生一次,INTC初始化操作方式:
cphnd = CSL_CPINTC_open(0);
CSL_CPINTC_disableAllHostInterrupt(cphnd);
CSL_CPINTC_mapSystemIntrToChannel(cphnd, cp_event, 0);
CSL_CPINTC_enableSysInterrupt(cphnd, cp_event);
CSL_CPINTC_enableHostInterrupt(cphnd,hostIntr);
CSL_CPINTC_enableAllHostInterrupt(cphnd);
如果我在中断函数中,再次调用
CSL_CPINTC_disableAllHostInterrupt(cphnd);
CSL_CPINTC_enableAllHostInterrupt(cphnd);
这个中断可以连续进去.
但是,如果有多个系统级事件输入INTC,我在中断中做以上操作,会导致INTC接收不到任何系统级事件,直到enable.我查看INTC的手册,里面也有对单个HostInterrupt的disable和enable,我试了试,但是不管用,麻烦TI的技术支持给分下下原因.还要一点就是标题上提到的,INTC同一时刻能否有多个事件输入?谢谢!
Andy Yin:
si cheng你好,
需要在中断函数中清CPINTC systemInterrupt,以及EDMA pendding Interrupt register,可调用如下两个函数执行。
CSL_CPINTC_clearSysInterrupt(…);
CSL_edma3ClearLoPendingInterrupts(…); or CSL_edma3ClearHiPendingInterrupts(…);
si cheng:
回复 Andy Yin:
您好:
我在中断中调用了CSL_CPINTC_clearSysInterrupt(…);CSL_edma3ClearLoPendingInterrupts(…); CSL_edma3ClearHiPendingInterrupts(…);但是没有效果。我手动触发EDMA传输,进中断,执行CSL_CPINTC_clearSysInterrupt(…);CSL_edma3ClearLoPendingInterrupts(…); CSL_edma3ClearHiPendingInterrupts(…);这些操作后,等出了中断后,继续手动触发,可以连续进入中断。
但是如果改成定时器触发,中断中的设置同手动触发,结果中断只能进一次,下一次进不去,但是EDMA数据传输完成。说明问题出在INTC控制器。我怀疑是定时器触发EDMA传输频率太频繁了,导致INTC控制器接收输入事件时出问题了。我对比了出问题前后INTC寄存器数值,发现INTC寄存器数值没变化,按理说应该可以进行下一次传输,但是只有我再中断中调用
CSL_CPINTC_disableAllHostInterrupt(cphnd);
CSL_CPINTC_enableAllHostInterrupt(cphnd);
这两个函数后,下一次中断才能进去。
如果一下个事件输入到INTC时,INTC正在处理上一个事件,这个样会导致INTC异常吗?也就是标题上说的,INTC能否同一时刻处理多个输入事件?
谢谢!
Thomas Yang1:
首先明确一点,你说的INTC是CPINTC, 不是Core INTC。
CPINTC需要enable后才能输出event给system event, 你观察到的现象是正确的。详细原因是:
在level trigger模式下,如果不加host disable和host enable可能存在未清掉level中断源(比如对于Queue pend,在pop和clear之间,又来了一个push操作)导致在CPINTC的输出端没有一个edge输出给core,这样会丢失中断,所以建议你加上host disable 和host enable。 对于pulse trigger模式(比如EDMA,SRIO等)建议也加上这个操作。
对于你的第2个问题,CPINTC同一时刻可以有多个事件输入。如果没有响应你可以查看drop missing interrupt(INTXSTAT )但需要注意每次要清除这个标志,否则你就抓不到第2次的了。
si cheng:
回复 Thomas Yang1:
您好:
这个问题我已经解决,之前,我open EDMA获取的handle设置成全局了,在中断函数中调用函数
CSL_edma3GetLoPendingInterrupts(
CSL_Edma3Handle hModule,
Int region,
CSL_BitMask32* intrLo
)
获取EDMA的中断状态位,这个函数中使用的hModule,是在初始化EDMA的一个函数中调用open获取的handle,结果发现这个函数返回的数据异常,就知道了是没有清除EDMA的中断状态位(IPR),.之后.我在中断中open EDMA重新获取一个handle,调用上述函数,完成EDMA中断标志位清除就可以了.
在找bug的过程中,我发现CPINTC初始化时,必须操作以下两个函数
CSL_CPINTC_enableHostInterrupt(cphnd, channleNum);
CSL_CPINTC_enableAllHostInterrupt(cphnd);
才能让CPINTC正常工作,如果在CPINTC初始化时,只调用其中一个函数,CPINTC不能正常工作(注:这两个操作只是CPINTC初始化的一部分).我想知道这两个函数有什么区别?文档中说的是CSL_CPINTC_enableHostInterrupt只是使能某一个HostInterrupt,而CSL_CPINTC_enableAllHostInterrupt是一次性使能所有的HostInterrupt.按理说,我要使用哪个HostInterrupt,只需使能哪个HostInterrupt,因此只需调用CSL_CPINTC_enableHostInterrupt(cphnd, channleNum);即可.
但实际上,这两个必须全部调用才行,请TI的技术支持指教!
谢谢!