Hi,all:
我现在6678上面遇到一个CIC中断不能触发,我eventid = 20,然后映射到cpu中断
向量8上面。但是,我能断定自己的事件已经被触发,接收到中断事件,程序就是不能
进入ISR处理函数。我想能不能手动模拟这个事件eventid = 20,手动触发中断测试我自己的
中断配置是否正确。请专家指教。谢谢!
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.
结合手册看C:\ti\pdk_C6678_1_1_2_6\packages\ti\csl\example\cpintc这个例子。
我的代码就是从cpintc 例子拷贝过来的,我用的最前边的代码,
没有使用CIC映射。
Void myIsr()
{
System_printf("SRIO isr coming\n");
}
void Setup_SRIO_ISR()
{
Uint32 rawStatus;
Uint16 index;
intcContext.eventhandlerRecord = EventHandler;
intcContext.numEvtEntries = 10;
if (CSL_intcInit(&intcContext) != CSL_SOK)
{
System_printf("Error: GEM-INTC initialization failed\n");
return;
}
if (CSL_intcGlobalNmiEnable() != CSL_SOK)
{
System_printf("Error: GEM-INTC global NMI enable failed\n");
return;
}
if (CSL_intcGlobalEnable(&state) != CSL_SOK)
{
System_printf ("Error: GEM-INTC global enable failed\n");
return;
}
vectId = CSL_INTC_VECTID_14;
hTest = CSL_intcOpen (&intcObj, 20, &vectId , NULL);
if (hTest == NULL)
{
System_printf("Error: GEM-INTC Open failed\n");
return;
}
EventRecord.handler = &myIsr;
EventRecord.arg = 0;
if (CSL_intcPlugEventHandler(hTest,&EventRecord) != CSL_SOK)
{
System_printf("Error: GEM-INTC Plug event handler failed\n");
return;
}
if (CSL_intcHwControl(hTest,CSL_INTC_CMD_EVTENABLE, NULL) != CSL_SOK)
{
System_printf("Error: GEM-INTC CSL_INTC_CMD_EVTENABLE command failed\n");
return;
}
System_printf ("Debug: GEM-INTC Configuration Completed\n");
}
我想问下,我能不能手动触发eventid = 20 的事件?怎么做到?
你可以看看KeyStone Architecture Chip Interrupt Controller (CIC) User Guide这个文档,
Host interrupt event 是不能手工触发的,但system interrupt event可以。
Hi,Allen:
我在板子上面跑了cpintc.test.c代码,发现原始配置是能跑的,可以手动触发system中断,
但是,我修改了systemid 中断号之后,发现有些中断号能进中断,有些不能进中断,刚好
我想要的112号就不能进中断,请问是什么问题么?
原始配置:
systemid = 3
channel = 3
hostid = 3
eventid = 63
vectorid = 4
((CSL_CPINTC_RegsOvly)CSL_CP_INTC_0_REGS)->STATUS_SET_INDEX_REG = 3;
我自己的配置是:
systemid = 112
channel = 3
hostid = 3
eventid = 63
vectorid = 4
((CSL_CPINTC_RegsOvly)CSL_CP_INTC_0_REGS)->STATUS_SET_INDEX_REG = 112;
谢谢!
Hi,Allen:
1.
谢谢回复,112号手动触发问题已经解决了,看来是原来代码存在bug。
2.
请问怎么测试eventid 中断配置是否正确,就是不用CIC,不是systemid,你之前说
不能用手动触发,但是有其他方法判断么?
3.
接着112号中断可以手动触发的问题,我现在能够实现手动触发了,但是,实际触发不了SRIO
112号中断,我用SRIO _througoutputExample,DSP1发送给DSP0,而且在consumer端能够
看到 ICSR已经置位,但是,就是没有进入中断ISR。
4.
我如果不用CIC直接用20号eventid ,用cpintc_test提供代码,看到ICSR置位,还是不能进入ISR
不能手动设host event,实际上,你可以把system event对应到不同的host event上来做这个事;
SRIO里检查ICRR是不是设置对,CIC设置是不是设置对了,首页有一个Keystone 1的测试代码,你可以参考怎么设置doorbell的中断来做。
你的流程是没有问题的,应该是某个地方配置的不对。
Hi,Allen:
ICRR 应该没错。
如果doorbell 映射到INTDST16,配置如下:
CSL_SRIO_SetDoorbellRoute (hSrio, 0);
for (i = 0; i < 16; i++)
{
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 0, i, 0);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 1, i, 1);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 2, i, 2);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 3, i, 3);
}
如果doorbell映射到INTDST0配置如下
CSL_SRIO_SetDoorbellRoute (hSrio, 1);
for (i = 0; i < 16; i++)
{
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 0, i, 0);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 1, i, 1);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 2, i, 2);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 3, i, 3);
}
而且INTDST0 每次发送前设置了interrupt pacing 和rate
pConfig = (CSL_SrioRegs*)(0x02900000);
CSL_SRIO_EnableInterruptPacing (pConfig, 0);
CSL_SRIO_SetInterruptPacing (pConfig, 0, 0x00000001);
发送端触发的是doorbell reg0 bit0 。两种方式下,接收端都能看到相应的ICSR置位,
即接收到doorbell 中断。但是,不能触发ISR。
Hi,Allen:
1.
你说的参考代码,中断设置用中断向量ASM 直接绑定中断向量。我这里是要用CSL 函数。
2.
如果我想让doorbell reg0 bit0 映射到INTDST16,该怎么设置?
除了将interrupt_ctl register 置为0之外,还需要设置doorbell0_ICR0 = 16么?
即
先设置CSL_SRIO_SetDoorbellRoute (hSrio, 0);
再设置CSL_SRIO_RouteDoorbellInterrupts (hSrio, 0, 0, 16) (??还是CSL_SRIO_RouteDoorbellInterrupts (hSrio, 0, 0, 0))
还是只要设置CSL_SRIO_SetDoorbellRoute (hSrio, 0);就可以了?
上面几种组合我都试过了,中断绑定代码也不可能有错了。就是不能触发
3.
能够提供一个CSL 配置SRIO ,实现触发20号中断的例程
ASM和CSL原理上是一样的,你可以借鉴例子的代码里如何设置中断,必要时的时候对比寄存器的值是否是一样的,这个例子是在EVM板上验证过的。
你可以在你的工程里配置完SRIO以后,手动触发一个system event,看到底是哪一块出了问题。
SRIO_Interrupt_Map interrupt_map[]=
{
/*interrupt_event*/ /*INTDST_number*/
{DOORBELL0_0_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_1_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_2_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_3_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_4_INT, INTDST_16} /*route to core 0*/
};
SRIO_Interrupt_Cfg interrupt_cfg;
void SRIO_Interrupts_Init(void)
{
/*map SRIO doorbell interrupts to INT4.
map message descriptor accumulation low priority channel 0 interrupt
to INT5*/
gpCGEM_regs->INTMUX1 =
(CSL_GEM_INTDST_N_PLUS_16<<CSL_CGEM_INTMUX1_INTSEL4_SHIFT)|
(CSL_GEM_QM_INT_LOW_0<<CSL_CGEM_INTMUX1_INTSEL5_SHIFT);
/*Clear all DSP core events*/
gpCGEM_regs->EVTCLR[0]= 0xFFFFFFFF;
gpCGEM_regs->EVTCLR[1]= 0xFFFFFFFF;
gpCGEM_regs->EVTCLR[2]= 0xFFFFFFFF;
gpCGEM_regs->EVTCLR[3]= 0xFFFFFFFF;
//clear DSP core interrupt flag
ICR= IFR;
//enable INT4, 5
IER = 3|(1<<4)|(1<<5);
/*Interrupt Service Table Pointer to begining of LL2 memory*/
ISTP= 0x800000;
//enable GIE
TSR = TSR|1;
interrupt_cfg.interrupt_map = interrupt_map;
interrupt_cfg.uiNumInterruptMap =
sizeof(interrupt_map)/sizeof(SRIO_Interrupt_Map);
/*interrupt rate control is not used in this test*/
interrupt_cfg.interrupt_rate= NULL;
interrupt_cfg.uiNumInterruptRateCfg= 0;
interrupt_cfg.doorbell_route_ctl= SRIO_DOORBELL_ROUTE_TO_DEDICATE_INT;
srio_cfg.interrupt_cfg = &interrupt_cfg;
}
void KeyStone_SRIO_Interrupt_init(
SRIO_Interrupt_Cfg * interrupt_cfg)
{
Uint32 i;
Uint32 reg, shift;
volatile Uint32 * ICRR= (volatile Uint32 *)gpSRIO_regs->DOORBELL_ICRR;
if(NULL == interrupt_cfg)
return;
/* Clear all the interrupts */
for(i=0; i<2; i++)
{
gpSRIO_regs->LSU_ICSR_ICCR[i].RIO_LSU_ICCR = 0xFFFFFFFF ;
}
for(i=0; i<4; i++)
{
gpSRIO_regs->DOORBELL_ICSR_ICCR[i].RIO_DOORBELL_ICCR = 0xFFFFFFFF;
}
gpSRIO_regs->RIO_ERR_RST_EVNT_ICCR = 0xFFFFFFFF;
if(NULL != interrupt_cfg->interrupt_map)
{
for(i=0; i<interrupt_cfg->uiNumInterruptMap; i++)
{
/* Get register index for the interrupt source*/
reg = interrupt_cfg->interrupt_map[i].interrupt_event >> 16;
/* Get shift value for the interrupt source*/
shift = interrupt_cfg->interrupt_map[i].interrupt_event & 0x0000FFFF;
ICRR[reg]= (ICRR[reg]&(~(0xF<<shift))) /*clear the field*/
|(interrupt_cfg->interrupt_map[i].INTDST_number<<shift);
}
}
gpSRIO_regs->RIO_INTERRUPT_CTL = interrupt_cfg->doorbell_route_ctl;
/*disable interrupt rate control*/
gpSRIO_regs->RIO_INTDST_RATE_DIS= 0xFFFF;
for(i= 0; i< 16; i++)
{
gpSRIO_regs->RIO_INTDST_RATE_CNT[i]= 0;
}
if(NULL != interrupt_cfg->interrupt_rate)
{
/*setup interrupt rate for specific INTDST*/
for(i= 0; i<interrupt_cfg->uiNumInterruptRateCfg; i++)
{
/*enable rate control for this INTDST*/
gpSRIO_regs->RIO_INTDST_RATE_DIS &=
~(1<<interrupt_cfg->interrupt_rate[i].INTDST_number);
/*set interrupt rate counter for this INTDST*/
gpSRIO_regs->RIO_INTDST_RATE_CNT[i]=
interrupt_cfg->interrupt_rate[i].interrupt_rate_counter;
}
}
return;
}
6678 EVENT20 是INTDST n+16 直接映射
core 0 对应 INTDST 16
core 1 对应 INTDST 17
以此类推
这个只要检查INTMUX里对应中断的值是不是20就可以了,
也就是你需要检查的寄存器是 INTMUX, IER
INTMUX 见 TMS320C66x DSP CorePac User Guide
Armstrong 说:我看了确实是20,我配的是INTSEL9 =20,证明了中断配置没问题。
下面的问题就是,怎么知道自己的doorbell packet 是否触发了INTDST16事件?
Hi,Allen:
我已经证明了我的中断配置和SRIO配置都没有问题,但是还是不能进入ISR。
1.中断配置
我直接用INTDST16,将INTDST16绑定在vector id = 9上面,而且,看了INTMUX寄存器
确认了INTSEL9 = 20.证明中断配置没有任何问题。
2.SRIO配置
将doorbell reg0 bit0 映射到INTDST16上做如下配置
CSL_SRIO_SetDoorbellRoute (hSrio, 0);
CSL_SRIO_RouteDoorbellInterrupts (hSrio, 0, 0, 0);
上面配置都没有问题的前提下,我在接收端能够看到doorbell[0].ICSR[0] = 1,
证明接收端已经收到了doorbell 中断,同时,数据也能看得到,但是,就是
不能进入中断。
你好!
我使用FPGA给C6678发送doorbell也出现了同样的问题!
我是使用CIC0的112号system event,对应到21号 event number 再到4号cpu中断。测试手动设置112号system event可以进入中断isr。
但是,收到doorbell后就是进不了isr,doorbell使用reg#0 bit#0,使用INTDST0,可以看到收到了doorbell,但就是不进中断,srio doorbell这边要让doorbell产生中断还需要些什么配置么?
你们的问题解决了么?
你好,我刚开始看SRIO中断,需要实现的当其它设备通过SRIO给DSP发送数据,发送完后,应该是通过doorbell中断通知CPU的,然后CPU再去处理。看了SRIO user guide和CIC文档,看了至少三遍,还是没有头绪。有一下几个问题,希望能得到解答
1. DSP的中断配置具体怎么做?中断函数怎么挂载?假设现在CPU收到中断后要去处理接受的数据,CPU怎么知道数据存放在哪里以及具体收到了多少数据?
2. doorbell中断的四个寄存器的每位怎么映射到intdst中断的,随机分配还是有限制?
3. system中断到host中断的映射是随机还是?
4. 必须要使用CIC么?
以上的问题有没有例程可以参考,需要看那些文档?由于是初学,可能描述的不是很准确,希望能详细解答,非常感激。
你好,你的回答确实能与手册上吻合,KeyStone也确实有这样的例程,我也确实是这样的配置。而且也读了ICSR寄存器,看到里面置位了,可就是进不了isr。你能不能Srio中断中的Doorbell是不是和其他的中断源不一样啊?比如不能单独引发中断进入isr?,需要其他方式配合才能进入isr?