AM6422: MCU+ SDK: EPWM: EPWM_tbTimebaseClkCfg does not choose the optimal prescaler combination

Part Number: AM6422
Other Parts Discussed in Thread: AM6442

Tool/software:

Description: The EPWM_tbTimebaseClkCfg function from epwm.c does not always calculate the optimal combination of hspClkDiv and lspClkDiv from the allowed values. This can result in suboptimal performance or incorrect configuration of the EPWM module. 

Expected Behavior: The function should select the optimal combination of hspClkDiv and lspClkDiv from the allowed values:

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

Actual Behavior: The function does not always select the optimal combination, leading to potential issues in the EPWM module configuration.

Example:

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

Optimal Values:

  • hspClkDiv = 1
  • lspClkDiv = 128

Actual Values (according to current behavior):

  • The function might incorrectly calculate hspClkDiv and lspClkDiv due to the current logic. For example, it could set:
    • hspClkDiv = 14 (maximum allowed value)
    • lspClkDiv = 8 (derived from 128 / 14)
  • This results in an incorrect configuration since the divider results in 14*8=112, not 128. Thus, the actual tbClk is not moduleClk/128, as the user expects, but moduleClk/112
  • All further user calculations and function calls using the tbClk will not be accurate, since the user expects the resulting frequency to be the one set after calling EPWM_tbTimebaseClkCfg

Actual clkDiv:

  • clkDiv = 14 * 8 = 112 (which is not equal to the expected clkDiv of 128)

Proposal:

  • Also provide a way to read back the resulting prescaler (HSPCLKDIV × CLKDIV) or at least the single prescaler values  

Environment:

  • Hardware: AM6442
  • SDK Version: AM64x MCU+ SDK v10.01.00.32
  • Compiler: tiarmclang 4.0.1

Additional Information: The issue seems to arise from the logic used to determine the values of hspClkDiv and lspClkDiv. A more robust approach is needed to ensure the optimal combination is always selected.

  • Hi Angel, thanks for your detailed information and proposed fix. Allow me some time to take a look and discuss it internally.

    Paula

  • Hi Angel, thanks again for your feedback. FYI, I created an internal ticket to follow this up with our developers.

    Paula

  • Hi Paula:

     Would the timeframe for this be AM64x MCU+ SDK V11?

    We should also inquire thru Nick Saulnier/Bin Liu that the EPWM drivers for the AM64x Linux SDKs be likewise checked and supported for same.

    thanks

    Jim

  • Meanwhile, we created an own C++ implementation of the required function. Probably something similar in C is what you would be implmenting:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi Jim, I will update here when it gets added to MCU+SDK pipeline. To be honest I think EPWM's Linux driver works OK, and it doesn't have the issue mentioned by Angel, at least last time I tested it, scalers seem to be selected ok, and frequencies (even low frequencies) worked as expected. But, please let us know if you face any issues as my tests was a small few-samples frequencies test

    thank you,

    Paula

  • Angel, thanks a lot!

    Paula