工具/软件:
我有一个带有 C6672的定制电路板、该电路板配置为根复合体、连接到外部 PCIe 端点器件。 C6672正在运行裸机(无 RTOS)、我将使用 CSL 库来配置中断。
在 PCIe 初始化期间、我将 INTN_EN_SET (0x21800188)和 INTN_EN_CLR (0x2180018C)设置为1、并将所有 msin_IRQ 寄存器设置为0 (0x21800100至0x21800170)
INTC 和 CPINTC 配置会导致设置以下寄存器:
ENABLE_REG 无符号整数[32][0x00000000、0x00040000、0x00000000、0x00000000、0x00000000...] (十六进制) 0x02600300
ENABLE_CLR_REG 无符号整数[32][0x00000000、0x00040000、0x00000000、0x00000000、0x00000000……] (十六进制) 0x02600380
enable_hind_REG unsigned int[8][0x00000001、0x00000000、0x00000000、0x00000000、0x00000000……] (十六进制) 0x02601500
GLOBAL_ENABLE_HINT_REG unsigned int 0x00000001 (十六进制) 0x02600010
当外部器件产生 PCIe 旧 INTA 中断时、我会看到以下寄存器被修改:
INTn _RAW_STATUS (0x21800180)= 1
INTn (0x21800184)= 1。
RAW_STATUS_REG unsigned int[32][0x00000000、0x00040000、0x00000000、0x00000000、0x00000000……] (十六进制) 0x02600200
ENA_STATUS_REG unsigned int[32][0x00000000、0x00040000、0x00000000、0x00000000、0x00000000……] (十六进制) 0x02600280
但是、连接到事件的 ISR 不会执行。
我可以通过向外部器件中的寄存器写入值、向 INTN_STATUS 写入1以及向 IRQ_EOI (0x21800050)写入0来清除中断。 清除中断后、我通过查看 INTN_RAW_STATUS 和 INTN_STATUS 寄存器设置回1来验证是否再次触发中断。
我按照 SPRUGW4A KeyStone 架构芯片中断控制器(CIC)用户指南第2.3节"中断服务"中的代码示例附加了下面的代码。
如有任何建议、我将不胜感激。
#include <ti/csl/cslr_device.h> #include <ti/csl/csl_cpIntcAux.h> #include <csl_intc.h> #include <csl_intcAux.h> CSL_IntcContext Intcontext; //For CorePac INTC CSL_IntcObj intcPCIe; //For CorePac INTC CSL_IntcHandle hIntcPCIe; //For CorePac INTC CSL_IntcEventHandlerRecord Record; //For CorePac INTC CSL_CPINTC_Handle cphnd; //For chip-level CIC Int16 sys_event; Int16 host_event; void InitializeInterrupts( void ) { CSL_IntcGlobalEnableState state; /* Setup the global Interrupt */ Intcontext.numEvtEntries = 1; Intcontext.eventhandlerRecord = &Record; CSL_intcInit( &Intcontext ); CSL_intcGlobalNmiEnable( ); /* Enable NMIs */ CSL_intcGlobalEnable( &state ); /* Enable Global Interrupts */ cphnd = CSL_CPINTC_open( 0 ); /* Initialize the chip level CIC CSL handle. */ } /** * This method connects a System Event to a Core Event. * @note System Events are listed in SPRS708E Table 7-38 CIC0 Event Inputs (Secondary Interrupts for C66x CorePacs) * @note Host Events are listed in Figure 7-32 TMS320C6672 System Event Inputs * @param[in] kusSystemEvent System Event from SPRS708E Table 7-38 CIC0 Event Inputs * @param[in] kusHostEvent Host Event from SPRS708E Figure 7-32 TMS320C6672 System Event Inputs * @return This method returns nothing. */ void ConnectEvents( uint16_t kusSystemEvent, uint16_t kusHostEvent ) { CSL_IntcParam vectId1; /// @par Process Design Language /// -# Record the System Event, Host Event, and MOL pointer sys_event = kusSystemEvent; host_event = kusHostEvent; /// -# Map the CIC input event to the CorePac input event /// -# Map the input system event to a channel. /// - Note, the mapping from channel to Host event is fixed. /// -# Enable the system interrupt /// -# Enable the channel (output). /// -# Enable all host interrupts. CSL_CPINTC_disableAllHostInterrupt( cphnd ); CSL_CPINTC_setNestingMode( cphnd, CPINTC_NO_NESTING ); CSL_CPINTC_mapSystemIntrToChannel( cphnd, sys_event, 0 ); CSL_CPINTC_enableSysInterrupt( cphnd, sys_event ); CSL_CPINTC_enableHostInterrupt( cphnd, 0 ); CSL_CPINTC_enableAllHostInterrupt( cphnd ); /// -# Hook an ISR to the CorePac input event. /// -# Hook the ISR (CSL_intcPlugEventHandler) /// -# Clear the Interrupt /// -# Enable the Event & the interrupt vectId1 = CSL_INTC_VECTID_12; //4 through 15 are available hIntcPCIe = CSL_intcOpen( &intcPCIe, host_event, // selected event ID &vectId1, NULL ); Record.handler = ( CSL_IntcEventHandler )&SISR; Record.arg = ( void* )host_event; CSL_intcPlugEventHandler( hIntcPCIe, &( Record ) ); CSL_intcHwControl( hIntcPCIe, CSL_INTC_CMD_EVTCLEAR, NULL ); CSL_intcHwControl( hIntcPCIe, CSL_INTC_CMD_EVTENABLE, NULL ); } void SISR( void* kopEventId ) { /// @par Process Design Language /// -# Disable the CIC0 host interrupt output CSL_CPINTC_disableHostInterrupt( cphnd, 0 ); /// -# Clear the CIC0 system interrupt CSL_CPINTC_clearSysInterrupt( cphnd, sys_event ); ... /// -# Service the interrupt at source ... /// -# Clear the CorePac interrupt CSL_intcHwControl( hIntcPCIe, CSL_INTC_CMD_EVTCLEAR, NULL ); /// -# Enable the CIC0 host interrupt output CSL_CPINTC_enableHostInterrupt( cphnd, 0 ); } void main( void ) { ... InitializeInterrupts( ); ConnectEvents( CSL_INTC0_PCIEXPRESS_LEGACY_INTA, CSL_GEM_CIC0_OUT0_OR_CIC1_OUT0 ); ... }