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 always empty

Part Number: AM2634


Tool/software:

Hi!

I am having trouble using the SDFM FIFO, or when not using the SDFM FIFO, consistently reading valid new filter data.

I am running the following function, triggered by a 10kHz ISR. The ISR is triggered from a 10kHz ePWM, I am not intending to use an SDFM data ready interrupt to know when to pull new filter data. I want to pull the most recent valid filter data in this ISR.

FIFO ISSUES

In the current function I see SDFM_getModulatorStatus constantly returns TRUE (system healthy)

In the current function I see SDFM_getFIFODataCount constantly return 0.

If I bypass SDFM_getFIFODataCount and just read SDFM_getFIFOData, the data returns 0.

SDFM_getFIFOData OBSERVATIONS

If I bypass SDFM_getFIFODataCount and replace SDFM_getFIFOData with SDFM_getFilterData, it returns valid data "most" of the time. There are 100x magnitude outliers that are read every couple seconds with no consistency, suggesting these outliers are invalid read data. The "accurate data" does follow a trend of the controlled injected current on the SDFM sensor, as I rise current, the SDFM data rises, as I lower, it lowers.

If I bypass SDFM_getFIFODataCount, replace SDFM_getFIFOData with SDFM_getFilterData, but only attempt to grab data when SDFM_getNewFilterDataStatus returns TRUE (new filter data is available), I never see SDFM_getNewFilterDataStatus return TRUE, always FALSE (no new filter data is available). This is odd bc SDFM_getFilterData by itself does return some accurate data.

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?
    }
}

Here are my syscfg settings per SDFM:

A few questions:

  1. How can I use the SDFM fifo correctly to get valid data at a 10kHz epwm triggered interrupt?
  2. If I dont use the fifo, what function can I use or settings to ensure I only grab valid data with SDFM_getFilterData? (SDFM_getNewFilterDataStatus always returns FALSE)
  3. Should I select the "Use PWM Synchronization" option with "SDFM sync source is PWM0 SOCA"? I want valid SDFM data at the same rate as my ePWM.

Thank you!

  • Hi Justin,

    Thanks for providing this information. I will look into this FIFO usage further, but a quick answer for number 3. You will need to select the Use PWM Synchronization in order to get the data at the 10KHz rate of your PWM.

    Best Regards,

    Zackary Fleenor

  • Thanks Zackary, looking forward to your response.

  • Hi Zackary, we found the solution to this problem. Any SDFM readings require the interrupt to be enabled, regardless if we want to trigger a ISR or xbar off the interrupt. This enabled the FIFO andSDFM_getNewFilterDataStatus to work properly.

    One question I have past this is working with the SDFM comparators, how in software can we know if the SDFM event 1 or event 2 has been triggered? Could you please provide a code snippet I can run in a main loop to check if the SDFM comparator has triggered an event interrupt pls. Thanks!

  • Hello Justin,

    Appologies for the delayed response while I was OOO last week. I am glad to hear you have resolved the original issue. I am looking into your second query now and will provide an updated response before the end of the week.

    Best Regards,

    Zackary Fleenor

  • Hi Justin,

    The SDFM_getThresholdStatus() API provides that status of whether the threshold is above/below or within limits. This should be called within the ISR itself to determine the event trigger, not within the main loop.

    //*****************************************************************************
    //
    //! 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));
    }
     

    Best Regards,

    Zackary Fleenor