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.

[参考译文] AM2634:SDFM FIFO 始终为空

Guru**** 2549900 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1538379/am2634-sdfm-fifo-always-empty

器件型号:AM2634


工具/软件:

您好!

我在使用 SDFM FIFO 时遇到问题、或在不使用 SDFM FIFO 时、无法持续读取有效的新滤波器数据。

我正在运行以下函数、该函数由 10kHz ISR 触发。 ISR 由 10kHz ePWM 触发、我无意使用 SDFM 数据就绪中断来了解何时获取新的滤波器数据。 我想在此 ISR 中拉取最新的有效滤波器数据。

FIFO 问题

在当前函数中、我会看到 SDFM_getModulatorStatus 持续返回 TRUE(系统运行状况)

在当前函数中、我看到  SDFM_getFIFODataCount 不断返回 0。

如果我绕过  SDFM_getFIFODataCount 并刚刚读取 SDFM_getFIFOData、 则数据返回 0。

SDFM_getFIFOData 观察结果

如果我 绕过 SDFM_getFIFODataCount 并 将 SDFM_getFIFOData 替换为 SDFM_getFilterData、则大部分时间会返回有效数据。 每隔几秒读取一次 100x 幅度异常值、且没有一致性、这表明这些异常值是无效的读取数据。 “精确数据“确实遵循 SDFM 传感器上受控注入电流的趋势、随着 I RISE 电流、SDFM 数据会随着 I LOW 的电流而升高。

如果 我 绕过 SDFM_getFIFODataCount、将 SDFM_getFIFOData 替换为 SDFM_getFilterData、但只在 SDFM_getNewFilterDataStatus 返回 true(新的滤波器数据可用)时尝试获取数据、我永远不会看到 SDFM_getNewFilterDataStatus 返回 true、始终为 false(没有新的滤波器数据可用)。 这是奇数的 bc SDFM_getFilterData 本身确实会返回一些准确的数据。

void sdfm_readAllChannels(void)
{
    for (uint8_t i = 0; i < 8; i++)
    {
        uint32_t base_addr = gSdfmBaseAddrs[channel_config->module];
        uint32_t filter = channel_config->filter;
        bool modulator_status = SDFM_getModulatorStatus(base_addr, filter);
        if (modulator_status)
        {
            uint16_t fifo_data_count = SDFM_getFIFODataCount(base_addr, filter);
            if(fifo_data_count == 0){
                raw_value = -1;
            }
            else if(fifo_data_count>=1) {
                uint32_t filter_data = SDFM_getFIFOData(base_addr, filter);
                raw_value = (int16_t)(filter_data >> CSL_SDFM_SDDATA1_DATA32HI_SHIFT);
                SDFM_clearWaitForSyncFlag(base_addr, filter); // Is this needed?
            }
            else {
                raw_value = -2;
            }
        }
        else
        {
            raw_value = -3;
        }
        raw_field[i] = raw_value;
    }
    // Clear interrupt flags
    for (uint32_t module = 0; module < SDFM_MODULE_COUNT; module++)
    {
        SDFM_clearInterruptFlag(gSdfmBaseAddrs[module], SDFM_MAIN_INTERRUPT_FLAG | 0xFFFF); // Is this needed?
    }
}

以下是每个 SDFM 的 syscfg 设置:

几个 问题:

  1. 如何正确使用 SDFM fifo 以 10kHz EPWM 触发中断下获取有效数据?
  2. 如果我不使用 FIFO、可以使用什么函数或设置来确保只使用  SDFM_getFilterData 获取有效数据? (SDFM_getNewFilterDataStatus 始终返回 false)
  3. 我是否应该选择带有“SDFM SYNC SOURCE IS PWM0 SOCA“的“Use PWM Synchronization“选项? 我希望 SDFM 数据与 EPWM 的速率相同。

谢谢!

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

    尊敬的 Justin:

    感谢您提供此信息。 我将进一步研究 FIFO 的使用情况、但这是第 3 题的快速答案。 要以 PWM 的 10kHz 速率获取数据、您需要选择 Use PWM Synchronization。

    此致、

    Zackary Fleenor

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

    感谢 Zackary、期待您的答复。

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

    嗨 Zackary ,我们 找到了 这个问题的解决方案。 任何 SDFM 读数都需要启用中断、无论我们要在中断中触发 ISR 还是 XBar。 这使得 FIFO 和 SDFM_getNewFilterDataStatus 能够正常工作。

    我发现的一个问题是使用 SDFM 比较器、我们如何在软件中知道是否触发了 SDFM 事件 1 或事件 2? 您能提供一个代码片段、我可以在主循环中运行、以检查 SDFM 比较器是否触发了事件中断。 谢谢!

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

    您好 Justin、

    上周我在 OOO 的时候,对延迟的回应表示歉意。 我很高兴听到您已解决了原始问题。 我现在正在查看您的第二个查询、并将在本周结束前提供更新的回复。

    此致、

    Zackary Fleenor

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

    尊敬的 Justin:

    SDFM_getThresholdStatus () API 提供阈值是高于/低于还是在限制范围内的状态。 应在 ISR 内部调用该函数来确定事件触发、而不是在主循环内。

    //*****************************************************************************
    //
    //! Get the Comparator threshold status.
    //!
    //! \param base is the base address of the SDFM module
    //! \param filterNumber is the filter number.
    //!
    //! This function returns the Comparator output threshold status for the given
    //! filterNumber.
    //!
    //! \return Returns the following status flags.
    //! - \b SDFM_OUTPUT_WITHIN_THRESHOLD if the output is within the
    //!                                   specified threshold.
    //! - \b SDFM_OUTPUT_ABOVE_THRESHOLD  if the output is above the high
    //!                                   threshold
    //! - \b SDFM_OUTPUT_BELOW_THRESHOLD  if the output is below the low
    //!                                   threshold.
    //!
    //*****************************************************************************
    static inline uint32_t
    SDFM_getThresholdStatus(uint32_t base, uint32_t filterNumber)
    {
        //
        // Read SDIFLG high/low threshold bits
        //
        return((uint32_t)((HW_RD_REG32(base + CSL_SDFM_SDIFLG) >>
                (2U * (uint16_t)filterNumber)) & 0x3U));
    }
     

    此致、

    Zackary Fleenor