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.

[参考译文] AM6442:有触发器的重复中断38 = IEP_CAPR[0]

Guru**** 2469930 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1467170/am6442-repeated-interrupts-for-with-trigger-38-iep_capr-0

器件型号:AM6442

工具与软件:

大家好!

我已经在使用捕获 上一篇文章的指示,但我想做它的中断. 它按照我收到的指导工作,但我仍然得到许多呼叫每秒(而不是一个)。 在两秒钟内说出>1M 的呼叫。

我尝试过的最重要的事情:

-不使用任务管理器,我认为中断7是有效的,但在我确认它后仍然得到激活
-仅配置捕获6.

我是否必须执行其他操作来确认该中断? 共享相关代码。

此致。

inline void pad_config_aka_dtb() {
  hw_wr_reg32(0x00a40034, 0x010016);
  hw_wr_reg32(0x00a40038, 0x010016);
  hw_wr_reg32(0x00a4003C, 0x010016);
  hw_wr_reg32(0x00a40040, 0x010016);
  // pin mux for LATCH_IN - time sync router PRG1_IEP0_EDC_LATCH_IN0
  hw_wr_reg32(0x000F4100, 0x00040002);
  // time sync router PRG1_IEP0_EDC_LATCH_IN1
  // hw_wr_reg32(0x00a40028, 0x00010009);
}

void reset_counter_iep_IEP0() {
  /* Disable counter */
  CT_IEP0.global_cfg_reg_bit.cnt_enable = 0;
  /* 64 bits */
  CT_IEP0.cmp_cfg_reg_bit.shadow_en = 0;
  /* Reset Count register */
  CT_IEP0.count_reg0_bit.count_lo = 0;
  CT_IEP0.count_reg1_bit.count_hi = 0;
  /* Clear overflow status register */
  CT_IEP0.global_status_reg_bit.cnt_ovf = 1;
}

void configure_counter_IEP0() {
  CT_IEP0.global_cfg_reg_bit.default_inc = 4;
  CT_IEP0.global_cfg_reg_bit.cnt_enable = 1;

  CT_IEP0.cmp_cfg_reg_bit.cmp_en = 0;      // enable compensation
  CT_IEP0.compen_reg_bit.compen_cnt = 0;   // count for compensation
  CT_IEP0.global_cfg_reg_bit.cmp_inc = 0;  // inc when compensation is active
  CT_IEP0.slow_compen_reg_bit.slow_compen_cnt =
      0;  // Slow disabled when we enable compensation
  CT_IEP0.cap_cfg_reg = 0x0003FFC0;
  // CT_IEP0.cap_cfg_reg = 0x10000;
}

#define PRU1_0_TASK_MGR_REG_BASE (0x300aa000UL)

// This one calls ISR in C, after saving the registers.
extern void tm_ch4_send(void);

#define CSL_ICSS_G_PR1_IEP0_SLV_CAPR6_REG0 (0x00000050U)

volatile int count = 0;

inline void config_task_manager() {
  // disable task manager, pru_io/firmware/common/icss_tm_macros.in
  __asm(" TSEN 0;");

  // clear event from previous debug.
  hw_wr_reg32(PRU1_0_TASK_MGR_REG_BASE, 0x0fff);
  asm("   xin     252, &r0.b3,1");
  asm("   nop ");
  asm("   nop ");

  hw_wr_reg32(PRU1_0_TASK_MGR_REG_BASE, 0x0000);

  // configure task manager for iep_task, TS2 is highest priority and can
  // pre-empt TS1
  //  general purpose mode = 2,
  //  TS2_S0 = tm_ch4_send (bit 7)
  hw_wr_reg32(PRU1_0_TASK_MGR_REG_BASE, 0x0182);

  // // set address of tm_ch4_send
  // // TS2_0
  hw_wr_reg32(PRU1_0_TASK_MGR_REG_BASE + 0x1c, (unsigned int)tm_ch4_send);
  // set TS2 trigger to
  // S2_0 (bit 7-0)  iep0_cmp0 = 16
  // S2_1 (bit 15-8) iep0_cmp1 = 17
  // 0x26 = 38, IEP_CAPR[0] event.
  // 0x26 is the one we need.
  hw_wr_reg32(PRU1_0_TASK_MGR_REG_BASE + 0x40, 0x1126);

  // enable task manager
  __asm(" TSEN 1;");
}

// Called from ASM

#pragma RETAIN(pps_isr)
void pps_isr() {
  uint32_t reg2 = CT_IEP0.cap_status_reg;
  uint32_t reg0 = CT_IEP0.capr6_reg0;
  uint32_t reg1 = CT_IEP0.capr6_reg1;

  *(icssg_shared_mem_) = 0;
  *(icssg_shared_mem_ + 1) = count++;
  *(icssg_shared_mem_ + 2) = reg0;
  *(icssg_shared_mem_ + 3) = reg1;
  *(icssg_shared_mem_ + 3) = reg2;
}

void main() {
  reset_counter_iep_IEP0();
  pad_config_aka_dtb();
  configure_counter_IEP0();
  config_task_manager();

  *(icssg_shared_mem_) = 0;
  *(icssg_shared_mem_ + 1) = 0;
  *(icssg_shared_mem_ + 2) = 0;
  *(icssg_shared_mem_ + 3) = 0;
  *(icssg_shared_mem_ + 4) = 0;

  while (1) {
  }
}

; ----------------------------------------------------------------------------
; task tm_ch4_send
;
; ----------------------------------------------------------------------------

  .global     tm_ch4_send
  .global pps_isr

TM_YIELD_XID        .set 252
BANK0_ID             .set   10

tm_ch4_send:
    xout    BANK0_ID, &r0, 120         ; save R0-r26

    JAL r3.w2, ||pps_isr||

    nop
    xin     TM_YIELD_XID, &R0.b3,1  ; exit task after two instructions/cycles
    nop
    xin    BANK0_ID, &r0, 120     ; save R0-r26
    nop
    nop ; unreachable
    nop ; unreachable

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

     您好!

    很抱歉、我延迟了响应、我查看了之前的 e2e 并了解了您要尝试执行的操作。

    您是否能够尝试在 cap6/pps ISR 中添加以下代码?

    下面的代码会清除 INTC 状态寄存器中的 CAP6事件

    LDI     R0、12;IEP0锁存器 In0的事件编号为12
    sbco  &R0、 c0、0x24、4;正在写入清除索引状态寄存器中要清除的事件编号。

    如果您需要任何帮助、请告诉我

    谢谢、此致、
    Manoj.

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

    非常感谢 Manoj!

    因此、我在汇编 ISR 中尝试了以下操作:

        ldi     R7, 12
        sbco    &R7, c0, 0x24, 4

    而且仍然有多次调用(似乎没完没了)。

    我也在 C ISR 中尝试过、但重复的调用仍在发生。

     CT_INTC.STATUS_CLR_INDEX_REG_BIT.STATUS_CLR_INDEX = 12

    当我在没有任务管理器的情况下将中断12映射到__R31&30时、我获得中断 并以同样的方式清除它们不起作用。 我确保这些设置来自 PRG1_IEP0_EDC_LATCH_IN0中断。

    在测试中、我尝试像在示例中那样映射中断、而不使用任务管理器、但我仍然只有在启用了 PPS 时才获得中断、但我无法清除它。

    #define PRU0_HOST_INT 30
    
    if (__R31 & PRU0_HOST_INT) {
      CT_INTC.STATUS_CLR_INDEX_REG_bit.STATUS_CLR_INDEX = 12;
    }

    此致。


    注意:我进行了一些编辑、以阐明当不使用任务管理器时、我使用的是中断12、而不是7。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我在没有任务管理器的情况下将中断12映射到__R31&30时、我获取了中断 并以同样的方式清除了中断、但这种方法无法正常工作。 我确保它们来自 PRG1_IEP0_EDC_LATCH_IN0中断。[/QUOT]

    Nelson、如果不在这里工作、你是什么意思?即使在清除 INTC 中的捕获事件并读取捕获寄存器后、也可以看到任务在无限次内执行?

    您能否共享 INTC 配置代码?

    此致、
    Manoj.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    嗨、Manoj! 有。
    但我今天一直在调试、我只注意到这种情况并不是无限的。 IRQ 保持放置1/2秒。
    更改:
    -移动到使用 INTC (不使用任务管理器)
    -使用 RTU1_1,当我移动它的行为就像 PRU1_0一样,我以前在那里测试。

    为了记录、如果我禁用 PPS、程序将停止、当我再次启用它时、程序将恢复正常工作。
    也许这是我需要的东西? 应将其视为输入引脚、并在其上升时触发?
    希望这能提供更多信息! 想知道以更好的方式解决缺少什么。
    我想我们可以进一步配置中断的工作方式、以便在需要时触发中断。
    我检查了一下 TRM、没找到、但已经很晚了。
    我尝试了几种组合、这种组合产生的闪烁每秒切换一次 LED。
    如果我不清除弹齿中断、那么下面的代码将不起作用。
     
     int previous = 0;
     CT_INTC.STATUS_CLR_INDEX_REG_BIT.STATUS_CLR_INDEX = LATCH_0_INT;
     while (1){
       INT Current = 0;
       如果(__R31和 HOST_INT){
         电流= 1;
         CT_INTC.STATUS_CLR_INDEX_REG_BIT.STATUS_CLR_INDEX = LATCH_0_INT;
       }
       if (当前!=上一个){
         上一个=当前;
         if (当前){
           toogle_led();
           PPS_ISR();
         }
       }
     }

    和闪烁 的视频比例 :-)
    调试输出示例。 首先是 ISR 调用计数、然后是捕获的值(未完成补偿)。

    $./panic-show
    0x4 => 0x7
    0x8 => 0x895b4a1e
    0xC => 0xc00780
    $./panic-show
    0x4 => 0x8
    0x8 => 0x9842007b
    0xC => 0xc00780
    $./panic-show
    0x4 => 0x9
    0x8 => 0xa728b6da
    0xC => 0xc00780
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,在一些研究后,我发现了两件事。

    1) 1)确保事件为电平、而不是脉冲

    2) 2)在 另一个线程中 、Nick 建议使用_R31在循环中等待上升沿。 与我正在执行的操作类似、但速度更快。

    "">e2e.ti.com/.../level.jpeg" width="496">

    所以、我可以使用它。

    我猜是可以将任务管理器配置为在上升沿触发、这样我就可以使 RTU 保持休眠或执行其他操作。 我从用于捕获 IEP CMP 事件的代码中继承了任务管理器配置、并且可能可以为此用例进行配置。

    我将标记为解决,我不再被阻止。 但我仍然想知道使用任务管理器是否更好。

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

    IEP 锁存器事件直接作为 PRUICSS INTC 控制器的输入提供、您可以将触发器类型配置为电平或边沿

    但我仍然想知道是否最好使用任务管理器。

    您可以使用任务管理器、如果需要在任务处于非活动状态时处理任何事情、则上下文存储和恢复只需2个周期。

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

    Manoj 您好、感谢您的深入了解。

    如何使用 INTC 控制器更改触发器类型?

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

    你好、Manoj。 非常感谢提示。 这对 INTC 来说是有效的。 现在要使用它。

    CT_INTC.TYPE_REG0_BIT.TYPE_12 = 1

    现在、想知道如何使用任务管理器来执行它。 将在周一进行检查。