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.

[参考译文] AM6422:MCU+ SDK:EPWM:EPWM_tbTimebaseClkCfg 不选择更优的预分频器组合

Guru**** 2463330 points
Other Parts Discussed in Thread: AM6442

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1473320/am6422-mcu-sdk-epwm-epwm_tbtimebaseclkcfg-does-not-choose-the-optimal-prescaler-combination

器件型号:AM6422
主题中讨论的其他器件:AM6442

工具与软件:

该设计的链接  EPWM_tbTimebaseClkCfg ePWM.c 中的函数并不总是 hspClkDiv  lspClkDiv 根据允许的值计算和的最佳组合。 这会导致 ePWM 模块的性能欠佳或配置错误。  

预期的行为 :该函数应 hspClkDiv  lspClkDiv 从允许的值中选择和的最佳组合:

  • hspClkDiv:1、2、4、6、8、 10、12、14
  • lspClkDiv:1、2、4、8、16、 32、64,128

实际行为 :该功能并不总是选择最佳组合、这会导致 ePWM 模块配置中出现潜在问题。

添加了示例

  • moduleClk = 25,000,000Hz
  • tbClk = 25,000,000 / 128 = 195,312.5Hz
  • clkDiv = 128  

最佳值

  • hspClkDiv = 1
  • lspClkDiv = 128

实际值  (根据当前行为):

  •  hspClkDiv  lspClkDiv 由于当前逻辑、函数可能计算错误和。 例如、它可以设置:
    • hspClkDiv = 14 (最大允许值)
    • lspClkDiv = 8 (源自 128 / 14)
  • 这会导致配置错误、因为分频器会导致14*8=112、而不是128。 因此、实际的 TBCLK 不是  moduleClk/128, as the user expects, but moduleClk/112
  • 使用 TBCLK 的所有进一步用户计算和函数调用将不准确、因为用户期望生成的频率是调用 ePWM_tbTimebaseClkCfg 后设置的频率

实际值  clkDiv

  • clkDiv = 14 * 8 = 112 (不等于预期的 clkDiv 128)

建议:

  • 此外还提供一种回读结果预分频器(HSPCLKDIV×CLKDIV)或至少读单个预分频器值的方法   

执行

  • 硬件: AM6442
  • SDK 版本:AM64x MCU+ SDK v10.01.00.32
  • 编译器:tiarmclang 4.0.1

它的格式 :问题似乎是从用于确定 hspClkDiv 和值的逻辑产生的 lspClkDiv。 需要更稳健的方法、以确保始终选择最佳组合。

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

    您好、Angel、感谢您的详细信息和建议的修复。 请允许我留出一些时间、以便在内部进行讨论。

    Paula.

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

    感谢您发送编修。 仅供参考、我创建了一个内部票据、以便与我们的开发人员跟进此事。

    Paula.

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

    您好、Paula:

     它的时间范围是否为 AM64x MCU+ SDK V11?

    我们还应询问 Nick Saulnier/Bin Liu、以同样的方式检查和支持 AM64x Linux SDK 的 EPWM 驱动程序。

    谢谢

    吉姆

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

    同时、我们创建了所需函数的自有 C++实现。 您可以植入 C 语言中类似的东西:

    static constexpr std::array<uint32_t, 8> m_lspVal {1, 2, 4, 8, 16, 32, 64, 128};
    static constexpr std::array<uint32_t, 8> m_hspVal {1, 2, 4, 6, 8, 10, 12, 14};
    
    
    float PwmSourceGroup::setOptimalDividers(uint32_t sourceFreq, uint32_t tbFreq)
    {
        int32_t targetDiv = sourceFreq/tbFreq;
    
        int8_t bestLsIdx = -1, bestHsIdx = -1;
        int32_t bestDiff = std::numeric_limits<int>::max();
    
        for (uint8_t lsIdx = 0; lsIdx < m_lspVal.size(); lsIdx++) {
            for (uint8_t hsIdx = 0; hsIdx < m_hspVal.size(); hsIdx++) {
                int32_t div = m_lspVal[lsIdx]*m_hspVal[hsIdx];
                auto cDiff = std::abs(div - targetDiv);
    
                if (cDiff < bestDiff) {
                    bestDiff = cDiff;
                    bestLsIdx = lsIdx;
                    bestHsIdx = hsIdx;
                }
                if (cDiff == 0) {
                    //No better diff to achieve 
                    break;
                }
            }
        }
    
    #define PWMSS_EPWM_OFFSET               (0x0U)
    
        uint32_t regVal = HW_RD_REG16((m_pwmUnitBaseAddress + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBCTL);
        HW_SET_FIELD32(regVal, PWMSS_EPWM_TBCTL_CLKDIV, bestLsIdx);
        HW_SET_FIELD32(regVal, PWMSS_EPWM_TBCTL_HSPCLKDIV, bestHsIdx);
        HW_WR_REG16(((m_pwmUnitBaseAddress + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBCTL),
                    (uint16_t)regVal);
    
        return ((float)sourceFreq/(m_lspVal[bestLsIdx]*m_hspVal[bestHsIdx]));
    }

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

    Jim、您好、我将在这里更新、当它被添加到 MCU+SDK 流水线时。 说实话、我认为 ePWM 的 Linux 驱动程序工作正常、而且它没有 Angel 提到的问题、至少上次我测试时、选择的分频器似乎工作正常、而频率(甚至是低频)工作正常。 但是、如果您遇到任何问题、请告知我们、因为我的测试是少量样本频率的小型测试

    谢谢!

    Paula.

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

    安琪尔、非常感谢!

    Paula.