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.

[参考译文] AM6548:如何为 PRU 选择 IEP 计时器?

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1231115/am6548-how-to-choose-iep-timer-for-pru

器件型号:AM6548

您好、TI!

在 AM65中使用多个 PRU。 而在 TRM 中、内部有 IEP0和 IEP1。

是否有任何标准可为特定的 PRU 选择 IEP0或 IEP 1?

谢谢。

埃里克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ,如果有任何标准可以为特定的 PRU 选择 IEP0或 IEP 1?

    IEP0和 IEP1是 ICSSG 内的共享计时器实例。  由 PRU 固件架构决定将哪个 IEP 用于 PRU。

    此致

    普拉泰什

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

    也就是说、我可以将 IEP0或 IEP1用于 PRU0_0、RTU0_0、TX_PRU0_0、 PRU0_1、RTU0_1、  TX_PRU0_1?

    如果我选择 IEP0但它无法正常工作、我如何才能知道出了什么问题?

    埃里克

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

    我遇到了一个问题、即我的其中一个 PRU 只能使用 IEP1。 但是、如果我更改为 IEP0、它将无法正常工作。

    我的 IEP 设置如下:

    #define IEPCounter CT_IEP0

    /*设置 PRU 同步到 VCLK 模式、时钟速度250MHz*/
    CT_CFG.CORE_SYNC_REG_BIT.CORE_vbusp_sync_en = 1;

    /*将 IEP 设置为同步模式,时钟频率为250MHz*/
    CT_CFG.iepclk_reg_bit.IEP_OCP_clk_en = 1;


    /*禁用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0;

    /*复位计数寄存器*/
    IEPCounter.count_reg0 = 0xFFFFFFFF;
    IEPCounter.count_reg1 = 0xFFFFFFFF;

    /*清除溢出状态寄存器*/
    IEPCounter.GLOBAL_STATUS_REG_BIT.cnT_OVF = 0x1;

    /*清除比较状态*/
    IEPCounter.CMP_STATUS_reg = 0xFFFFFFFF;

    /*设置比较值*/
    IEPCounter.cmp0_reg0 = OutFreqMax_ns;
    IEPCounter.cmp0_reg1 = 0;

    /*发生事件时启用 CMP0和复位*/
    IEPCounter.CMP_cfg_reg_bit.CMP_en = 0x1;//启用 CMP0事件
    IEPCounter.CMP_cfg_reg_bit.cmp0_rst_cnT_en = 0x1;//启用计数器复位

    /*设置增量值*/
    IEPCounter.global_cfg_reg_bit.default_inc = 4;

    /*禁用补偿*/
    IEPCounter.compen_reg_bit.compen_cnt = 0x0;

    /*启用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0x1;

    您能 帮助 检查是否有任何问题吗?  

    埃里克

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

    /*设置 PRU 同步到 VCLK 模式、时钟速度250MHz*/
    CT_CFG.CORE_SYNC_REG_BIT.CORE_vbusp_sync_en = 1;

    /*将 IEP 设置为同步模式,时钟频率为250MHz*/
    CT_CFG.iepclk_reg_bit.IEP_OCP_clk_en = 1;

    [/报价]

    是否可以确保只执行这些操作一次、在运行 PRU 固件之前、也可以从 R5F 执行此操作。

    但如果我更改为 IEP0,则无法使用

    什么不起作用? 您是否确保上述配置已在 IEP0寄存器中生效

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

    尊敬的

    /*设置 PRU 同步到 VCLK 模式、时钟速度250MHz*/
    CT_CFG.CORE_SYNC_REG_BIT.CORE_vbusp_sync_en = 1;

    /*将 IEP 设置为同步模式,时钟频率为250MHz*/
    CT_CFG.iepclk_reg_bit.IEP_OCP_clk_en = 1;

    我将确保只设置了一次。 我可以确保在 PRU0_0启动时执行一次。

    "不工作"一词的含义如下:

    在我们的程序中、我们有一些代码、

    for (;;)
    {
      如果(IEPCounter.CMP_STATUS_REG_BIT.CMP_STATUS == 0x1)// CMP0事件被发出
      {
        /*清除 CMP0状态*/
        IEPCounter.CMP_STATUS_REG_BIT.CMP_STATUS = 0x1;
        中断;
      }

    如果我更改为 IEP0、它将始终处于 for 循环中、无法跳出 for 循环。

    但是、如果我更改为 IEP1、则可能会 中断 for 循环并继续。

    我不确定 IEP 设置是否有任何错误。

    您可以帮助检查一下吗?

    谢谢。

    埃里克

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

    您是否可以粘贴 IEP0和 IEP1内存浏览器屏幕截图、以使 ICSSG 实例用于非工作和工作场景?

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

    尊敬的

    不确定这是不是你想要的。 如果我错了,请告诉我。

    IEP1 (工作)

    IEP0 (非工作)

    埃里克

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

    可以、但看起来它们都是0、不应该是0、您可以从 R5F 中执行此操作、或分别为 ICSS 本地存储器映射使用0x2E000 (IEP0)和0x2F000 (IEP1)地址。

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

    尊敬的

    我终于找到了。  

    IEP1 (工作)

    IEP0 (不工作)

    埃里克

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

    看一下寄存器转储、您的 IEP0配置有一个问题、您是独立运行该固件还是与某种工业以太网协议一起运行该固件?

    /* Set compare values*/
    IEPCounter.cmp0_reg0 = OutFreqMax_ns;
    IEPCounter.cmp0_reg1 = 0;

    /* Enable CMP0 and reset on event */
    IEPCounter.cmp_cfg_reg_bit.cmp_en = 0x1; // enable CMP0 event
    IEPCounter.cmp_cfg_reg_bit.cmp0_rst_cnt_en = 0x1; // enable the reset of counter

    我看上文看不到 IEP0生效、但 shadow_en 位设置且  IEPCounter.cmp0_reg0 = 0。 因此、有效地说、IEP COUNT_reg0将始终保持为零、这与日志中看到的情况相同! 您能否尝试通过存储器浏览器更新上述寄存器、看看它是否起作用?

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

    尊敬的

    我们单独运行 PRU 固件。  

    我找到了一件事。  

    当我只从 CCS 中将 IEP0加载到 PRU0_1时、可以设置比较值寄存器。 它可以分解上面的 for 循环、并且它可以起作用。

    之后、我厌倦了加载 PRU0_0、后者也使用 IEP0、因此我的 PRU0_1不再工作。  

    当时、我试图覆盖 存储器映射中的比较值、但我也做不到。

    我的 PRU0_0 IEP 设置如下所示、不确定它们是否已定位。

    /*启用影子模式*/
    IEPCounter.CMP_cfg_reg_bit.shadow_en = 1;

    /*禁用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0;

    /*复位计数寄存器*/
    IEPCounter.count_reg0 = 0xFFFFFFFF;
    IEPCounter.count_reg1 = 0xFFFFFFFF;

    /*设置增量值*/
    IEPCounter.global_cfg_reg_bit.default_inc = 4;

    /*启用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0x1;

    埃里克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    /*启用影子模式*/
    IEPCounter.CMP_cfg_reg_bit.shadow_en = 1;

    是的、它与此相关、您在这里想要实现什么?

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

    尊敬的

    我的 PRU 代码来自我们的 PRU 工程师、但原因不明。

    在使用 TRM 进行检查后、影子模式位看起来启用32位操作。 默认为64位。  

    有一句话不是很清楚。 您能帮助解释一下吗?

    "这将启用比较寄存器的影子复制功能"

    埃里克

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

    是的、对于此用例-您无法从一个内核以影子模式运行 IEP0/1、也无法从另一个内核以正常模式运行 IEP0/1。 如果您需要循环行为、则使用影子模式、在本例中、当 CMP0命中时、周期将由硬件从 CMPx 寄存器的高32位复制。

    您正在运行的代码假设采用64位模式、因此对影子_EN 的配置不正确。

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

    尊敬的

    我厌倦了对我的用例进行实验。

    在运行 PRU0_1时、我曾尝试将 R30控制为高电平。

    __R30 = 0;
    for (;;)
    {
    如果(IEPCounter.CMP_STATUS_REG_BIT.CMP_STATUS == 0x1)// CMP0事件被发出
    {
    /*清除 CMP0状态*/
    IEPCounter.CMP_STATUS_REG_BIT.CMP_STATUS = 0x1;
    中断;


    __R30 = 1;

    在控制 R30前、我们初始化 IEP1 计时器、并得到如下的波形。 看起来还不错。

    /*禁用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0;

    /*复位计数寄存器*/
    IEPCounter.count_reg0 = 0xFFFFFFFF;
    IEPCounter.count_reg1 = 0xFFFFFFFF;

    /*清除溢出状态寄存器*/
    IEPCounter.GLOBAL_STATUS_REG_BIT.cnT_OVF = 0x1;

    /*清除比较状态*/
    IEPCounter.CMP_STATUS_reg = 0xFFFFFFFF;

    /*设置比较值*/
    IEPCounter.cmp0_reg0 = OutFreqMax_ns;
    IEPCounter.cmp0_reg1 = 0;

    /*发生事件时启用 CMP0和复位*/
    IEPCounter.CMP_cfg_reg_bit.CMP_en = 0x1;//启用 CMP0事件
    IEPCounter.CMP_cfg_reg_bit.cmp0_rst_cnT_en = 0x1;//启用计数器复位

    /*设置增量值*/
    IEPCounter.global_cfg_reg_bit.default_inc = 4;

    /*禁用补偿*/
    IEPCounter.compen_reg_bit.compen_cnt = 0x0;

    /*启用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0x1;

    #pragma MUST_ITERATE (1)
    对于(I = 0;I < HSPO_Channel;I++、g_pSharedPoCrtl++)
    {
    g_pSharedPoCrtl->hspPOCr = HspPOTypeAB;

    但是、当我加载以10位优先级运行的 PRU0_0时、 IEP0 ,它在此仅执行 IEP 设置。 复位代码是循环的、在此测试中将其删除。

    void IEPTimer_init (void)
    {
    #if 已定义(PRU0_0)
    /*设置 PRU 同步到 VCLK 模式、时钟速度250MHz*/
    CT_CFG.CORE_SYNC_REG_BIT.CORE_vbusp_sync_en = 1;

    /*将 IEP 设置为同步模式,时钟频率为250MHz*/
    CT_CFG.iepclk_reg_bit.IEP_OCP_clk_en = 1;
    #endif


    /*启用影子模式*/
    //IEPCounter.CMP_cfg_reg_bit.shadow_en = 1;//I 已在此处标记 shadow_en。

    /*禁用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0;

    /*复位计数寄存器*/
    IEPCounter.count_reg0 = 0xFFFFFFFF;
    IEPCounter.count_reg1 = 0xFFFFFFFF;

    /*设置增量值*/
    IEPCounter.global_cfg_reg_bit.default_inc = 4;

    /*启用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0x1;

    PRU0_1控制的 R30波形变得不稳定。  

    不过、我认为同时运行 PRU0_0和 PRU0_1时并不正常。

    那么、您能帮助说明如何进行 IEP 设置吗?

    谢谢。

    埃里克

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

    void IEPTimer_init(void)
    {
    #if defined(PRU0_0)
    /* Set PRU Sync-to-VCLK Mode, Clock speed 250MHz*/
    CT_CFG.core_sync_reg_bit.core_vbusp_sync_en = 1;

    /* Set IEP as sync mode, the clock is 250MHz*/
    CT_CFG.iepclk_reg_bit.iep_ocp_clk_en = 1;
    #endif

    那么、您将按照什么顺序运行它呢? PRU0_1首先通过 R30生成脉冲、然后通过 PRU0_0生成脉冲、您无法在运行 PRU0_1后执行上述初始化!

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

    尊敬的

    我的顺序是首先执行 PRU0_0循环编程、然后执行 PRU0_1、 生成脉冲等。

    我尝试的步骤仅用于测试。

    根据我的理解、每个 PRU 都应该是独立的、不会受到他人的影响。

    那么、您认为 PRU0_0和 PRU0_1的 IEP 设置是否正确?  

    void IEPTimer_init (void) // 这适用于 PRU0_0
    {
    #if 已定义(PRU0_0)
    /*设置 PRU 同步到 VCLK 模式、时钟速度250MHz*/
    CT_CFG.CORE_SYNC_REG_BIT.CORE_vbusp_sync_en = 1;

    /*将 IEP 设置为同步模式,时钟频率为250MHz*/
    CT_CFG.iepclk_reg_bit.IEP_OCP_clk_en = 1;
    #endif


    /*启用影子模式*/
    //IEPCounter.CMP_cfg_reg_bit.shadow_en = 1;  //我已经在这里标记了 shadow_en。

    /*禁用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0;

    /*复位计数寄存器*/
    IEPCounter.count_reg0 = 0xFFFFFFFF;
    IEPCounter.count_reg1 = 0xFFFFFFFF;

    /*设置增量值*/
    IEPCounter.global_cfg_reg_bit.default_inc = 4;

    /*启用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0x1;

    以下条件适用于 PRU0_1

    /*禁用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0;

    /*复位计数寄存器*/
    IEPCounter.count_reg0 = 0xFFFFFFFF;
    IEPCounter.count_reg1 = 0xFFFFFFFF;

    /*清除溢出状态寄存器*/
    IEPCounter.GLOBAL_STATUS_REG_BIT.cnT_OVF = 0x1;

    /*清除比较状态*/
    IEPCounter.CMP_STATUS_reg = 0xFFFFFFFF;

    /*设置比较值*/
    IEPCounter.cmp0_reg0 = OutFreqMax_ns;
    IEPCounter.cmp0_reg1 = 0;

    /*发生事件时启用 CMP0和复位*/
    IEPCounter.CMP_cfg_reg_bit.CMP_en = 0x1;//启用 CMP0事件
    IEPCounter.CMP_cfg_reg_bit.cmp0_rst_cnT_en = 0x1;//启用计数器复位

    /*设置增量值*/
    IEPCounter.global_cfg_reg_bit.default_inc = 4;

    /*禁用补偿*/
    IEPCounter.compen_reg_bit.compen_cnt = 0x0;

    /*启用计数器*/
    IEPCounter.global_cfg_reg_bit.cnT_enable = 0x1;

    谢谢。

    埃里克