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: Decoding APWM signal inside AM2634

Part Number: AM2634
Other Parts Discussed in Thread: UCC21732

Tool/software:

Hi TI Expert,

We are using AM2634 controller along with UCC21732 for current feedback that outputs an APWM signal at 400KHz frequency.

1) Could you please advice the best way to decode the APWM signal inside AM2634 controller? 
     I have looked into the ECAP peripheral to decode the APWM signals duty cycle. However, our control loop runs at 10KHz and we want the current reading at 10KHz instead of 400KHz. 
     So please let me know if there are other peripherals within the microcontroller that I can use to decode the APWM signal and filter and average it to 10KHz.

2) Please recommend an IC chip that we can use to convert the APWM signal to analog signal?

Thank you!

  • Hi Sue

    1. Could you please advice the best way to decode the APWM signal inside AM2634 controller? 
      1. Have you referred the EXAMPLES_DRIVERS_ECAP_CAPTURE_PWM - This example reads a PWM wave and determines its frequency and duty cycle
      2. You can also refer to the ECAP_SIGNAL_MONITORING example - 
        1. This example configures 6 ECAP moudule, with a total of 6 signal
          * monitoring modules enabled, each with one configuration that are supported.
          * All ECAPs are enabled with Interrupts for the Errors from the Signal Monitoring
          * Modules. An EPWM is configured to provide the input, routed to ECAP via
          * GPI and Inputxbar. This input is varied in a way to cross min and max values from
          * the siganl monitoring modules and the application checks for the interrupt flags
          * are well as the debug range values.
      3. Let me know if any of these help!
    2. Please recommend an IC chip that we can use to convert the APWM signal to analog signal?
      1. Let me get an expert to comment on this

    Regards,
    Akshit

  • Hi Akshit,

    Thanks for your response!
    I am familiar with ECAP peripheral and decoding signal frequency and duty cycle using ECAP.
    In my case, we have a 400KHz current sensor APWM signal that we need to decode inside AM2634 and then filter and average it to 10KHz. What is the best way to do this conversion if we want to avoid computational overhead needed for filtering and averaging the signal to reduce to a lower frequency in software? Can we use any other peripherals here? Please let us know.


    I was also looking into SDFM module but was confused with the type of input SDFM accepts. Can we directly feed an APWM signal to SDFM module for filtering?

    Thanks!

  • Hey Sue,

    I will let Akshit provide additional comments for your last repsonse.

    In regards to your 2nd question:

    2) Please recommend an IC chip that we can use to convert the APWM signal to analog signal?

    Please refer to the app note below:

    https://www.ti.com/lit/spra490/

    It provides details on implementing a 3rd Order Low-Pass Filter that can be used to convert discrete PWM signals to a continuous analog voltage.

    Best Regards,

    Zackary Fleenor

  • Hi Sue

    Apologies for the delayed response!

    To answer your queries:

    I was also looking into SDFM module but was confused with the type of input SDFM accepts. Can we directly feed an APWM signal to SDFM module for filtering?

    No, we cannot directly feed APWM signals to SDFM module, and SDFM module does not seem like the appropriate peripheral to use for your particular application.

    I see you are also using an external RC Low-Pass Filter, therefore there are 2 main ways to decode this signal with minimal overhead.

    1. External RC Low-Pass Filter + ADC

    This method offloads the bulk of the filtering and averaging task to external analog hardware, significantly reducing the computational load on the AM2634's CPU.

    1. Concept:
      The 400kHz APWM signal's duty cycle represents the analog current value. An RC low-pass filter can convert this PWM signal into an analog DC voltage proportional to its average duty cycle. This analog voltage is then sampled by the AM2634's ADC at your desired 10kHz rate.

    2. Implementation Steps:

      • External RC Filter:

        • Connect the APWM output of the UCC21732 to a simple RC low-pass filter (a resistor in series followed by a capacitor to ground).

        • The output of this filter (the voltage across the capacitor) will be an analog representation of the averaged duty cycle.

        • Filter Design: The cutoff frequency (fc = 1 / (2 * π * R * C)) of the filter needs careful selection:

          • It must be low enough to significantly attenuate the 400kHz PWM ripple. A cutoff frequency of, for example, 20kHz to 40kHz would provide good ripple reduction.

          • It must be high enough to allow the filter's output to respond to changes in current that are relevant to your 10kHz control loop. The filter will introduce a phase lag and response delay.

          • Example: For a cutoff frequency of ~30kHz, you might use R = 1kΩ and C ≈ 5.3nF (a standard 4.7nF or 5.6nF capacitor could be chosen and tuned).

        • Ensure the APWM signal voltage levels are compatible with the RC components and the AM2634's ADC input range (typically 0 to 3.3V).

      • AM2634 ADC Configuration:

        • Connect the output of the RC filter to an analog input pin of one of the AM2634's ADCs.

        • Configure the ADC to sample this input at a 10kHz rate. This sampling can be triggered by an ePWM module or a general-purpose timer configured to generate events every 100µs (1/10kHz).

        • The AM2634 ADC modules also feature hardware oversampling and decimation (hardware averaging). You can enable this feature to average a few ADC samples for each 10kHz reading, further improving signal quality with no additional CPU overhead.

      • Software:

        • When an ADC conversion is complete (typically signaled by an interrupt), read the ADC result register. This digital value directly represents the filtered and averaged current measurement, updated at 10kHz.

        • The CPU's role is minimal: trigger ADC, read result. The primary filtering and averaging happen in the external analog circuit and potentially the ADC hardware.

    3. Advantages for Your Goal:

      • Minimal CPU Computational Overhead: The averaging is performed by the external RC circuit and optionally by the ADC's hardware averaging.

      • Simple software: Read ADC result at 10kHz.

    4. Considerations:

      • Requires external components (one resistor and one capacitor per APWM channel).

      • The filter's characteristics (response time, attenuation) are fixed by the R and C values.

      • Accuracy can be affected by component tolerances and analog noise. Careful PCB layout is recommended.


    2. All-MCU Solution: eCAP + DMA + Software Averaging

    To avoid external analog components and keep the signal processing entirely within the digital domain of the MCU, this is a viable approach, though it involves some software computation for averaging.

    1. Concept:
      The eCAP peripheral measures the duty cycle of the 400kHz APWM signal. DMA is used to transfer these high-frequency readings to memory without CPU intervention. A timer then triggers a software routine at 10kHz to calculate the average of the collected duty cycle readings.

    2. Implementation Steps:

      • eCAP Configuration:

        • Configure an eCAP module in APWM capture mode to continuously measure the pulse width (on-time) and period of the 400kHz signal. The eCAP can be set to generate an event (and optionally an interrupt) after each full PWM cycle measurement.

      • DMA Configuration:

        • Configure a DMA channel to transfer the eCAP's capture registers (e.g., containing pulse width and period values, or raw timestamps) to a circular buffer in RAM. The DMA transfer should be triggered by an eCAP event (e.g., capture event 4, indicating a full cycle measurement). This offloads the data movement from the CPU.

      • Timer for 10kHz Averaging:

        • Configure a general-purpose timer or an ePWM module to generate an interrupt at a 10kHz rate (every 100µs).

      • Software Averaging (in 10kHz ISR):

        • In the 10kHz timer interrupt service routine (ISR):

          • Access the circular buffer populated by the DMA.

          • Read the most recent set of duty cycle readings. Since the APWM is 400kHz and your control loop is 10kHz, you would average approximately 40 (400kHz / 10kHz) duty cycle samples.

          • Calculate the average of these samples. This average is your 10kHz current reading.

          • The calculation would involve summing ~40 values and dividing.

    3. Advantages:

      • No external analog filtering components needed (assuming the APWM signal levels are directly compatible with MCU I/O).

      • Filtering algorithm (e.g., simple moving average, weighted average) can be flexibly implemented and modified in software.

      • Potentially higher precision in the raw duty cycle measurement if the eCAP clock is sufficiently high.

    4. Considerations:

      • Software Overhead: While DMA handles data transfer, the CPU is still responsible for performing the averaging calculation (e.g., summing ~40 numbers and a division) every 100µs. This is generally manageable for an AM2634 but is more computational work than the RC filter + ADC method.

      • More complex MCU peripheral configuration (eCAP, DMA, Timer).


    Let me know if one of these suits your requirements, I will be trying method#2 on my setup as well!

    Regards,
    Akshit

  • Hi Akshit,

    Thank you for the detailed response. It is very helpful.
    I am interested in solution #2 ( All-MCU Solution: eCAP + DMA + Software Averaging) and have already started working on it, however, I am facing some difficulty in configuring the DMA.

    Could you please share your project once you have it working?

    Thank you so much! 

  • Hi Sue

    Yes, I'll share it asap. for the meanwhile, you can share the difficulties you are facing with configuring DMA.

    I'll try to help you resolve those.

    Regards,
    Akshit

  • Hi Akshit,

    I have configured the EDMA in EVENT mode so that the DMA transfer is triggered upon an ECAP event. The ECAP capture registers are copied into a buffer, capturing 40 duty samples before I average them. I want the DMA transfers to be continuously triggered as long as ECAP captures the events.
    However, I am seeing the DMA transfers happening only once after I start running the code.
    Could you please tell me how to set the DMA transfers to be continuous?
    Also, did you get a chance to share your project where I can access it from?

    Thank you!

  • Hi Sue,

    It's good to hear that the detailed response was helpful and that you're making progress with the eCAP + DMA + Software Averaging solution!

    You're on the right track by configuring the EDMA in Event mode to be triggered by eCAP events and copying data to a buffer. The issue of DMA transfers happening only once after collecting the initial 40 samples is a common one and usually relates to how the EDMA PaRAM set is configured for subsequent transfers.

    To achieve this scenario where you collect 40 samples, process them, and then collect the next 40 samples into the same buffer, you need to ensure the EDMA channel is properly re-armed after each block of 40 transfers is complete. This is typically done within the EDMA's Transfer Completion Interrupt Service Routine (ISR).

    Here's how you can set up the DMA for continuous block transfers:

    1. EDMA PaRAM Set Configuration:

    For the EDMA channel triggered by your eCAP:

    • OPT (Options Parameter):
    • Set TCINTEN = 1 (Transfer Completion Interrupt Enable) to generate an interrupt after C_CNT transfers are done.
    • Set TCC (Transfer Completion Code) to a value that will be used to identify the interrupt source. This could be the channel number itself or a specific code.
    • SYNCDIM = 0 (A-synchronized transfer, which is typical for peripheral-triggered DMA).
    • STATIC = 0: This means the PaRAM set will not be automatically reloaded from the LINK address after completion. We will handle re-arming manually in the ISR.
    • SRC (Source Address): Address of the eCAP capture register(s) holding the duty cycle information.
    • A_CNT (A Count): Size of a single eCAP register element (e.g., 4 bytes for a 32-bit register).
    • B_CNT (B Count): Number of eCAP register elements that constitute one full duty cycle reading (e.g., if you read both ON-time and PERIOD registers, B_CNT might be 2, and A_CNT would be the size of one of those registers).
    • DST (Destination Address): Starting address of your destination buffer in memory (e.g., your_capture_buffer[0]).
    • SRC_BIDX (Source B Index): Offset to the next source element after A_CNT bytes are transferred. If reading consecutive eCAP registers, this would be A_CNT. If reading the same register, it's 0.
    • DST_BIDX (Destination B Index): Offset to the next destination element. Typically A_CNT to store elements contiguously.
    • LINK (Link Address): Set to 0xFFFF (or the defined null link address for your EDMA, e.g., EDMA_NULL_LINK_ADDRESS). This prevents the EDMA from automatically linking to another PaRAM set.
    • B_CNT_RLD (B Count Reload): Typically set equal to B_CNT.
    • SRC_CIDX (Source C Index): Usually 0 if the source doesn't change across C_CNT iterations.
    • DST_CIDX (Destination C Index): Offset applied to the destination address after each B_CNT transfer. This should be A_CNT * B_CNT to move to the slot for the next full duty cycle sample.
    • C_CNT (C Count): Set to 40. This will trigger the Transfer Completion Interrupt after 40 duty cycle samples have been transferred.

    2. EDMA Transfer Completion ISR:

    This ISR will be executed after 40 samples are transferred.

    Acknowledge/Clear the Interrupt:

    • Clear the EDMA channel's specific interrupt flag in the Interrupt Pending Register (e.g., IPR or IPRH).
    • Clear the Transfer Completion Code status by writing to the Interrupt Clear Register (e.g., ICR or ICRH) for the TCC value you configured.
    • Your device's driver library should have functions for this (e.g., EDMA_clrIntr(baseAddr, channelNum) and EDMA_clrMissedEvent(baseAddr, channelNum) or similar).

    Process Data:

    • Access your destination buffer which now contains 40 fresh duty cycle samples.
    • Perform your averaging calculation.

    Re-arm the DMA for the Next Block:

    • Reset Destination Address: Since you want to reuse the same buffer for the next 40 samples, you must reset the DST field in the PaRAM set for this channel back to the beginning of your buffer.
    • Re-enable the DMA Channel: After the C_CNT is exhausted for a non-linked PaRAM set, the channel is typically disabled. You need to re-enable it to accept new trigger events from the eCAP. This is often done by writing to the Event Enable Set Register (EESR or EESRH).

    Why it might be happening only once currently:

    If the DMA transfers only once, it's likely because:

    The LINK address is null (0xFFFF).

    The STATIC bit in OPT is 0 (or the PaRAM is not set to be static).

    After C_CNT (40) transfers, the channel completes its current PaRAM configuration and becomes disabled or simply doesn't have its parameters (like DST) reset for the next intended block into the same buffer.

    The Transfer Completion Interrupt, if enabled, is not correctly re-arming the channel by resetting necessary parameters (especially DST) and re-enabling event triggering.

    Also, did you get a chance to share your project where I can access it from?

    While I don't have  a full, runnable project file, the ecap_edma.c example is a good foundation. You'll need to adapt its DMA configuration and particularly implement the DMA interrupt service routine as described above to handle the "collect 40, average, reset DMA, and repeat" logic.

    Let me know if it helps!

    Regards,
    Akshit

  • hi Akshit,

    Thank you for your response.
    My code is set up exactly as you describe above. However, I'm still not able to do continuous DMA transfers.

    Here are my observations -
    1) when LINK = 0x4000, after first DMA transfer happens, the execution enters ISR. At this time, register readings are EMR=0, EER=1, IER=1, IPR=1.
         Writing ICR=1 does not clear IPR. 
          ISR keeps getting triggered without any new DMA transfers (buffer does not update with new duty cycle) as IPR remains set to 1.

    2) when LINK = 0xFFFF, after first DMA transfer happens, the execution enters ISR. At this time, register readings are EMR=1, ER=1, EER=1, SER=1,                 IER=1,  IPR=0. Calling EDMA_clrMissEvtRegion() does not clear EMR. I reset the destination address and re-enable the DMA channel again in ISR, but          the execution gets stuck in SemaphoreP_pend() loop and I do not see ISR triggering after that.

    3) My project compiles fine but while debugging I'm unable to step into EDMA SDK APIs. I have checked my project properties and it is pretty similar to the example projects. Could you tell me if I might be missing any configuration here?

    Could you please try to reproduce this issue on your end and let me know how to resolve it?
    I have tried working on ecap_edma example project as well but see similar results when I try to set up for continuous transfers. Please see below thread related to it.
    e2e.ti.com/.../am2634-q1-requesting-suggestions-to-resolve-issue-related-to---dma-triggered-continuously-by-ecap

    Thank you!

  • Below is my ISR set up - 




  • Hi Akshit,
    Did you get a chance to reproduce the issue I'm facing on your end? Appreciate your inputs ASAP. Thank you!

  • I resolved it. Thanks for your inputs!

  • Hi Sue,

    My apologies for not getting that project to you sooner! I'm genuinely thrilled to hear you've managed to resolve the issue independently!

    If it's not too much trouble, and especially if any of our previous troubleshooting steps pointed you in the right direction, would you mind sharing the exact solution or what ultimately clicked for you? We'd love to learn from your experience and incorporate it as a real-world example in our SDK.

    Thanks so much for the update and for your incredible patience!

  • Hi Akshit,

    I had initially programed the edmaParam.linkAddr with the address offset of the same parameter set as I thought it will automatically update the PaRAM set of a channel for continuous transfers. However, that did not work for me. It only helped in avoiding the EMR bit set.

    Re-programming the parameter set, re-requesting the channel and re-enabling the transfer after every block transfer worked. 

  • I have a follow up question - 
    the above code adds a bit of overhead specially when you are programming for multiple DMA channels in real-time applications.
    Is there a way I can directly write to registers (like in C2000 controllers - code show below) in AM2634? I have tried searching but haven't found registers structures made available to users in AM2634 SDK.

  • Hi Sue,

    Thank you so much for sharing the solution with me!

    the above code adds a bit of overhead specially when you are programming for multiple DMA channels in real-time applications.
    Is there a way I can directly write to registers (like in C2000 controllers - code show below) in AM2634? I have tried searching but haven't found registers structures made available to users in AM2634 SDK.

    You can directly write to registers in AM2634 as well, I'd recommend you to use the AM263x Register Addendum, along with the {MCU_PLUS_SDK_PATH}/source/drivers/edma/v0 folder for edma registers and similarly for other peripherals as well.

    The driver should be helpful in getting an idea on how registers are programmed in AM263x.

    Regards,
    Akshit