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.

[参考译文] TMS320C672:外部生成的 PCIe 旧 INTA 不会触发关联的事件处理程序

Guru**** 2330840 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1517052/tms320c6672-externally-generated-pcie-legacy-inta-is-not-triggering-the-associated-event-handler

部件号:TMS320C6672

工具/软件:

我有一个带有 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 );
   ...
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    负责的工程师目前不在办公室。 请预计回复将延迟1天。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的更新。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Edward:

    您能否更新代码以将 Core-Pac 事件参数设置为91来代替102?

    参考文件: https://www.ti.com/lit/ds/sprs708e/sprs708e.pdf

    此致、

    Betsy Varughese.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Besty、我用91代替了 Core-Pac 事件参数、但我没有看到任何不同的行为。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我会处理中断。 在我的例子中、CSL_IntcEventHandlerRecord 似乎必须是2的数组。 以下是最终代码:

    // TI LLD Includes
    #include <ti/csl/cslr_device.h>
    #include <ti/csl/csl_cpIntcAux.h>
    #include <csl_intc.h>
    #include <csl_intcAux.h>
    #include <ti/csl/cslr_pcie.h>
    
    CSL_IntcContext intcContext;                //For CorePac INTC
    CSL_IntcObj intcObj;                        //For CorePac INTC
    CSL_IntcHandle intcHandle;                  //For CorePac INTC
    CSL_IntcEventHandlerRecord intcRecord[ 2 ]; //For CorePac INTC
    CSL_IntcParam intcVectorId = CSL_INTC_VECTID_4;
    CSL_IntcEventId intcEventId = CSL_GEM_INTC0_OUT0_OR_INTC1_OUT0;
    CSL_CPINTC_Handle cpintcHandle;              //For chip-level CIC
    CSL_CPINTCSystemInterrupt cpintcSystemInterrupt = CSL_INTC0_PCIEXPRESS_LEGACY_INTA;
    CSL_CPINTCChannel cpintcChannel = 0;
    
    void InitializeInterrupts( void )
    {
       CSL_IntcGlobalEnableState state;
       /* Setup the global Interrupt */
       intcContext.numEvtEntries = 2;
       intcContext.eventhandlerRecord = intcRecord;
       CSL_intcInit( &intcContext );
       CSL_intcGlobalNmiEnable( );     /* Enable NMIs */
       CSL_intcGlobalEnable( &state ); /* Enable Global Interrupts */
    }
    
    /**
     * 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)
     * @param[in] kuiCPINTCSystemInterrupt  System Event from SPRS708E Table 7-38 CIC0 Event Inputs
     * @param[in] kuiCPINTCChannel          Channel
     * @return This method returns nothing.
     */
    void ConnectEvent(
       CSL_CPINTCSystemInterrupt kuiCPINTCSystemInterrupt,
       CSL_CPINTCChannel kuiCPINTCChannel )
    {
       /// @par Process Design Language
       /// -# Record the CPINTC System Interrupt and CPINTC Channel
       cpintcSystemInterrupt = kuiCPINTCSystemInterrupt;
       cpintcChannel = kuiCPINTCChannel;
    
       /// -# 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.
       cpintcHandle = CSL_CPINTC_open( 0 );   /* Initialize the chip level CIC CSL handle. */
       CSL_CPINTC_disableAllHostInterrupt( cpintcHandle );
       CSL_CPINTC_setNestingMode( cpintcHandle, CPINTC_NO_NESTING );
       CSL_CPINTC_clearSysInterrupt( cpintcHandle, cpintcSystemInterrupt );
       CSL_CPINTC_enableSysInterrupt( cpintcHandle, cpintcSystemInterrupt );
       CSL_CPINTC_mapSystemIntrToChannel( cpintcHandle, cpintcSystemInterrupt, cpintcChannel );
       CSL_CPINTC_enableHostInterrupt( cpintcHandle, cpintcChannel );
       CSL_CPINTC_enableAllHostInterrupt( cpintcHandle );
    }
    
    
    void InstallHandler(
       CSL_IntcEventId kiIntcEventId,
       CSL_IntcParam kiIntcVectorId )
    {
       CSL_Status cslStatus;
    
       /// @par Process Design Language
       /// -# Record the INTC Event ID and INTC Vector ID
       intcEventId = kiIntcEventId;
       intcVectorId = kiIntcVectorId,
    
       /// -# Hook an ISR to the CorePac input event.
       ///   -# Hook the ISR (CSL_intcPlugEventHandler)
       ///   -# Clear the Interrupt
       ///   -# Enable the Event & the interrupt
       intcHandle =
          CSL_intcOpen(
             &intcObj,
             intcEventId, // selected event ID
             &intcVectorId,
             &cslStatus );
       intcRecord[ 0 ].handler = ( CSL_IntcEventHandler )ISR;
       intcRecord[ 0 ].arg = ( void* )intcEventId;
       CSL_intcPlugEventHandler( intcHandle, intcRecord );
       CSL_intcHwControl( intcHandle, CSL_INTC_CMD_EVTCLEAR, NULL );
       CSL_intcHwControl( intcHandle, CSL_INTC_CMD_EVTENABLE, NULL );
    }
    
    void ISR( void* kopEventId )
    {
       /// @par Process Design Language
       /// -# Disable the CIC0 host interrupt output
       CSL_CPINTC_disableHostInterrupt( cpintcHandle, cpintcChannel );
    
       ...
       
       /// -# Service the interrupt at source
    
       /// -# Clear the CorePac interrupt
       CSL_intcHwControl( intcHandle, CSL_INTC_CMD_EVTCLEAR, NULL );
       CSL_intcEventClear( intcEventId );
    
       /// -# Clear the CIC0 system interrupt
       CSL_CPINTC_clearSysInterrupt( cpintcHandle, cpintcSystemInterrupt );
    
       /// -# Enable the CIC0 host interrupt output
       CSL_CPINTC_enableHostInterrupt( cpintcHandle, cpintcChannel );
    }
    
    void main( void )
    {
       ...
       /// @par Process Design Language
       /// -# Initialize Interrupt
       InitializeInterrupts( );
    
       /// -# Connect the PCIe Legacy INTA to the Host Event
       ConnectEvent(
          CSL_INTC0_PCIEXPRESS_LEGACY_INTA,
          0 );
    
       /// -# Install the Handler
       InstallHandler(
          CSL_GEM_INTC0_OUT0_OR_INTC1_OUT0, 
          CSL_INTC_VECTID_4 );
    }