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.

TM4C123GE6PM: Reading PWM pulse width

Part Number: TM4C123GE6PM


Hello,

I am trying to determine the PWM pulse width value on 4 pins: PF0, PF1, PF2, PF3. Right now I am using PF1 to generate PWM (works great). Originally I used 32-bit timers Timer0 and Timer1 to read pulse width on PF0 and PF2 and that worked well. Since I need a total of 4 pins I decided to split Timer0 and Timer1 into split 16-bit timers. The moment I do that my code stops working. I am not getting the proper value anymore. Testing showed that the interrupt handler works properly, ISR determines which pin caused interrupt properly, pulse width calculation is correct. I think the timers setup causes problems. I would appreciate any help, thank you.

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_timer.h"
#include "inc/tm4c123ge6pm.h" // Definitions for the interrupt and register assignments.
#include "inc/hw_gpio.h"
#include "driverlib/fpu.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/pin_map.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#include "driverlib/pwm.h"
#include "utils/uartstdio.h"


void ConfigureUART(void);
void ConfigureTimers(void);
void ConfigurePWM(void);
void ConfigureGPIO(void);
void IntDefaultHandler(void);
void InputPF0(void);
void InputPF1(void);
void InputPF2(void);
void InputPF3(void);

void print_float(double v);

uint32_t systemClock;
// PF0 is tied to timer 0A
volatile float pulseWidth0 = 0;
volatile uint32_t timer0AValue = 0;
// PF1 is tied to timer 0B
volatile float pulseWidth1 = 0;
volatile uint32_t timer0BValue = 0;
// PF2 is tied to timer 1A
volatile float pulseWidth2 = 0;
volatile uint32_t timer1AValue = 0;
// PF3 is tied to timer 1B
volatile float pulseWidth3 = 0;
volatile uint32_t timer1BValue = 0;
double timerPeriod;


int main(void)
{
    volatile uint32_t load;
    volatile uint32_t dutyCycle;
    volatile uint32_t pwmClock;
    uint32_t pwmFrequency = 1000;  // sets PWM frequency to Hz


    // System clock, 200/10 = 20 MHz
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |SYSCTL_OSC_MAIN);
    systemClock = SysCtlClockGet();
    timerPeriod = (double)1/systemClock;

    // Configuring PWM clock
    SysCtlPWMClockSet(SYSCTL_PWMDIV_64);
    pwmClock = SysCtlClockGet() / 64;
    load = ((pwmClock/pwmFrequency) - 1); // setting PWM period
    dutyCycle = load/2; // 50% duty cycle

    ConfigurePWM();
    ConfigureUART();
    ConfigureTimers();
    ConfigureGPIO();

    // Set PWM period
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, load);

    // PWM duty cycle
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5_BIT, dutyCycle);


    while(1)
    {
        PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5, dutyCycle);

    }
}


void ConfigurePWM(void)

{
    // Enable the peripherals
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); // Module 1

    // Configure pins as PWM
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
    GPIOPinConfigure(GPIO_PF1_M1PWM5);

    // Configure the PWM generator
    PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN);

    // Turn on output pin
    PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT, true);

    // Enable PWM generator
    PWMGenEnable(PWM1_BASE, PWM_GEN_2);
}
// Have to attach PF1
void ConfigureGPIO(void)
{
    // Configuring PF0, PF1, PF2, PF3 as inputs and attaching interrupt to them
    // PF1 is removed for now since it generates PWM
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    // Wait for the peripheral to be ready
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)){}
    // Unlock the pins on port F
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0xFF;
    GPIOIntRegister(GPIO_PORTF_BASE, IntDefaultHandler);
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
    GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_BOTH_EDGES);
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_0 | GPIO_INT_PIN_2 | GPIO_INT_PIN_3);

}

void ConfigureUART(void)
{

   // Enable the GPIO Peripheral used by the UART.
   SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

   // Enable UART0
   SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

   // Configure GPIO Pins for UART mode.
   GPIOPinConfigure(GPIO_PA0_U0RX);
   GPIOPinConfigure(GPIO_PA1_U0TX);
   GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

   // Use the internal 16MHz oscillator as the UART clock source.
   UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

   // Initialize the UART for console I/O.
   UARTStdioConfig(0, 115200, 16000000);


}

void ConfigureTimers(void)
{

    // Timer 0 is 32-bits split into 16-bit timer A and 16-bit timer B
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)){}
    TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP | TIMER_CFG_B_PERIODIC_UP));

    // Timer 1 is 32-bits split into 16-bit timer A and 16-bit timer B
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER1)){}
    TimerConfigure(TIMER1_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP | TIMER_CFG_B_PERIODIC_UP));

}

void IntDefaultHandler(void)
{
    uint32_t status = 0;
    status = GPIOIntStatus(GPIO_PORTF_BASE, true);

    // Clear interrupt flag
    GPIOIntClear(GPIO_PORTF_BASE,status);

    // Check which pin triggered the interrupt
    if((status & GPIO_INT_PIN_0) == GPIO_INT_PIN_0)
    {
        InputPF0();
    }

    if((status & GPIO_INT_PIN_1) == GPIO_INT_PIN_1)
    {
        InputPF1();
    }
    if((status & GPIO_INT_PIN_2) == GPIO_INT_PIN_2)
    {
        InputPF2();
    }
    if((status & GPIO_INT_PIN_3) == GPIO_INT_PIN_3)
     {
         InputPF3();
     }


}

void InputPF0(void)
{
    // Check the input pin state
    if ( GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_0) == GPIO_PIN_0) // rising edge
    {
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0;    // load 0 to the timer
        TimerEnable(TIMER0_BASE,TIMER_A); //start timer to record
    }
    else // falling edge
    {
        TimerDisable(TIMER0_BASE,TIMER_A); //stop timer
        timer0AValue = TimerValueGet(TIMER0_BASE,TIMER_A); //record value
        pulseWidth0 = (double)(timerPeriod*timer0AValue*1000000); // PWM width in us
     }
    UARTprintf("\nTimer PF0 = %d\n", timer0AValue);
    print_float(pulseWidth0);

}

void InputPF1(void)
{
    // Check the input pin state
     if ( GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1) == GPIO_PIN_1) // rising edge
     {
       HWREG(TIMER0_BASE + TIMER_O_TBV) = 0;    // load 0 to the timer
       TimerEnable(TIMER0_BASE,TIMER_B); //start timer to record
     }
     else // falling edge
     {
       TimerDisable(TIMER0_BASE,TIMER_B); //stop timer
       timer0BValue = TimerValueGet(TIMER0_BASE,TIMER_B); //record value
       pulseWidth1 = (double)(timerPeriod*timer0BValue*1000000); // PWM width in us
     }
     UARTprintf("\nTimer PF1 = %d\n", timer0BValue);
     print_float(pulseWidth1);
}

void InputPF2(void)
{
    // Check the input pin state
     if ( GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2) == GPIO_PIN_2) // rising edge
     {
       HWREG(TIMER1_BASE + TIMER_O_TAV) = 0;    // load 0 to the timer
       TimerEnable(TIMER1_BASE,TIMER_A); //start timer to record
     }
     else // falling edge
     {
       TimerDisable(TIMER1_BASE,TIMER_A); //stop timer
       timer1AValue = TimerValueGet(TIMER1_BASE,TIMER_A); //record value
       pulseWidth2 = (double)(timerPeriod*timer1AValue*1000000); // PWM width in us
     }
     UARTprintf("\nTimer PF2 = %d\n", timer1AValue);
     print_float(pulseWidth2);
}

void InputPF3(void)
{

    // Check the input pin state
     if ( GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3) == GPIO_PIN_3) // rising edge
     {
       HWREG(TIMER1_BASE + TIMER_O_TBV) = 0;    // load 0 to the timer
       TimerEnable(TIMER1_BASE,TIMER_B); //start timer to record
     }
     else // falling edge
     {
       TimerDisable(TIMER1_BASE,TIMER_B); //stop timer
       timer1BValue = TimerValueGet(TIMER1_BASE,TIMER_B); //record value
       pulseWidth3 = (double)(timerPeriod*timer1BValue*1000000); // PWM width in us
     }
     UARTprintf("\nTimer PF3 = %d\n", timer1BValue);
     print_float(pulseWidth3);
}

void print_float(double v)
{
  int decimal = 2;
  int i = 1;
  int intPart, fractPart;
  for (;decimal!=0; i*=10, decimal--);
  intPart = (int)v;
  fractPart = (int)((v-(double)(int)v)*i);
  if(fractPart < 0) fractPart *= -1;
  UARTprintf("%i.%i us\n\r", intPart, fractPart);
}

  • There are a lot of problems with the code. For example, I wouldn't use intdefaulthandler as my isr name....

    You may want to think what kind of signal you are trying to measure and think through an approach first.

    For fast pulses I would consider using captures.

    For slower pulses, the possibility opens up. For example you can use gpio interrupts and read off a free running clock for duty cycles...

    But first you have to understand the beast (pulse train) you are dealing with.
  • Thank you for your reply. The goal is to be able to measure 1000 us to 2000 us PWM signals that are coming from RC receiver. In my code I enable the appropriate timer when a rising edge is detected and disable it when the falling edge is detected. And then I convert the amount of ticks to microseconds.
  • May I note yours as an "excellently constructed & presented post?"       Very well done.

    Now that said - immediately noted:

    void IntDefaultHandler(void)
    {
    uint32_t status = 0;
    status = GPIOIntStatus(GPIO_PORTF_BASE, true);

    // Clear interrupt flag
    GPIOIntClear(GPIO_PORTF_BASE,status);

    // Check which pin triggered the interrupt
    if((status & GPIO_INT_PIN_0) == GPIO_INT_PIN_0)
    {
    InputPF0();
    }

    and continues...

    Had you noted that you've chosen the "Default Name" for each/every "to be implemented" Interrupt Service Routine - listed (repeatedly) w/in your "Start-Up file?"       Can that be good?     I am "beyond surprised" that you report this "SO INVITING" (every interrupt source under the sun!) ISR to function.

    Might your "inaccuracy result" from a, "Timer Over-flow?"    Reducing the timer's range from 32 bits to 16 - demands that you properly, "Clear and/or Reset the Timer - prior to each/every "Timer Enable" to prevent such unwanted overflow.      Suggest that you look there (Timer Overflow, first) and kindly report...

  • It is hard to imagine that this framework actually works. They seem to be designed for a particular type of waveform, like non concurrently arriving pulse trains.

    I would suggest that you step back and really think about your approach.
  • I must plead (very) temporary insanity for suggesting (earlier) that your move from 32 bit timer to 16 bit timer - caused an overflow.     If your System Clock (which i now note) is 20MHz - your 16 bit timer should enable up to 3mS of time measure - prior to overflow.

    That said - directly from the "Peripheral Driver Library User Guide" (SO helpful) arrives:

    "When configured for a pair of half-width timers, each timer is separately configured."      And alas - you configured "together" - not separately!   (i.e. A & B appear w/in the SAME TimerConfigure()!)

    TimerConfigure(TIMER1_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP | TIMER_CFG_B_PERIODIC_UP);    // your existing config - suspect you need TWO such configs!    "A" & "B"

    That 2nd - 16 bit config -  (highlighted delightfully, above) may have to "stand on its own"    (I do not make these rules!)      Your test is "Quick & Easy" - thus (my kind) of test...

    This data gleaning (may) - resolve your issue!       

    ARM  MCUs are noted for "multiple timers" - your desire to "conserve resources" - at the cost of your programming mission - of course - cannot be supported!  

    (note:  several "bouts" of temporary (disability) plagued this posting.   Order may have (just now) 14:07 CST - been restored...)

  • Thank you for your replies. I tried to do the following as you suggested and it gives another wrong value.
    The values I want to see is 500 us (PWM signals is 1kHz)
    The values is 2974 us if I use
    TimerConfigure(TIMER1_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP | TIMER_CFG_B_PERIODIC_UP);

    The values is 3275 us if I use
    TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP));
    TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC_UP));
  • Thank you - yours is a complete (and quick) response - much appreciated.

    Well - that's troubling - the data I supplied came directly from the PDL - usually it is "Spot On."

    May I confirm that your MCU's System Clock remains @ 20MHz? (via your earlier "divide PLL (200MHz) by 10)

    You report two different results - may I ask that you repeat your tests - (say 5 times - back to back) - and see if each result is consistent? Also - how accurate & repeatable is your signal source? Firm/I ALWAYS suggest that "in such troubleshooting" (forego your remote RC means) and drive the Timer Input directly from the MCU's (spare) GPIO - which you can set - and vary - with precision.

    The difference between your readings is 301. At 20MHz that's a difference of 15µS - that very well may result from your source! I calculate your 3275 Timer Counts as a pulse duration of 163.75µS - do you agree? As you note - that's quite FAR - from the desired 500µS! If things are "in order" we'd expect 10,000 Timer Counts to accumulate w/in your Timer - when a 500µS pulse arrives!

    [edit]   I composed this post prior to your (latest) 1000µS info arriving.     I am now confused (more confused) - WHAT really is the Source Signal which you feed to the measuring Timer?    Is it - as I've suggested - coming directly from the MCU?

  • Sorry for confusion, that was a typo. For test purposes PWM is generated from PF1 (which in the future should be input too). PF1 is connected to PF0 where PF0. The PWM signal is 1kHz and 50% duty cycle which should give me 500 microseconds reading on the input. But instead I am reading between 2670 and 2970 microseconds.
  • Firm/I are very strong believers in KISS.    PF0 is a (potentially) distressed pin (it is an NMI pin) - even though you've attempted to "tame it" - may we "Remove it" from this mix?    PF1 is fine - it is just PF0 which I'd REALLY prefer to avoid - ok?

    We appear NOT to be well communicating - might you respond:

    • is your System Clock (still) as listed - 20MHz?
    • have you employed,  "TimerClockSourceSet()?"    It is not shown anywhere in your code listings.    Is it your belief that your Timers are being clocked - via the System Clock - at 20MHz?
    • how have you measured your PWM signal - from PF1 - to be 1KHz?    (with a scope - if not - how?)
    • sending such a continuous PWM signal to PFx - to be measured - proves NOT ideal.    I'd much prefer to see you generate a single, timed pulse.   (just one - easily generated by Timer in One-Shot.)   Might you comply.    (the continuous arrival of the PWM signal - especially at this early stage - is NOT helpful - in fact VIOLATES KISS - and adds time/effort to our task.
    • insure that "nothing else" is connected to your NEW PFx input - which attempts to measure the width of your NEW, ideally One-Shot pulse.   (NOT a continuous PWM signal - at this time)

    Firm/I have (some) experience (record of success) kindly comply as best you are able.    Instructions are (I think) clear & detailed - my effort is unduly increased if bypassed.

  • Yes the system clock is 20MHz. I am using the code below to set it up.
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |SYSCTL_OSC_MAIN);
    systemClock = SysCtlClockGet();
    timerPeriod = (double)1/systemClock;

    Yes, I measure the PWM using scope.

    I will try to generate a single pulse and see if it will be measure accurately. I will let you know the result. Thank you!
  • I think you are overly concerned about the implementation, instead of the basic approach to your design.

    If you are on the wrong track, no amount of perfect implementation will help.

    My advice would be for you to step back and ask yourself as to how you think your approach will work, especially when multiple pulse trains are involved.

    Best of luck.
  • Thank you - appreciated. I believe that you can find a code example w/in "TWare/examples/peripherals/timers/one-shot.c"
    If that cannot be found - the MCU manual well describes how you can produce that.

    By simplifying - we GREATLY INCREASE our chances for success. Too much going on - INVITES unwanted interference - which distracts from our "central issue" - and should be ELIMINATED. "ONE (focused) Battle at a time - surely will work best! (Always!)

    BTW - have you renamed your ISR? As (well qualified) poster Danny - and I noted - you've chosen a "default name" - which may be triggered by ALMOST ANYTHING - and that ALONE may be plaguing your efforts.

    You make no mention to the question: "Use of TimerClockSourceSet()." This possibly enables the PIOSC as Timer's source clock - I prefer NOT to employ PIOSC - which explains my asking.

    And - as earlier listed - do INSURE that no other connections or signals appear at PF1. We seek as pure and isolated a test environment as possible. Once we succeed w/the One-Shot pulse measure (Proving we understand the Timer operation - even at 16 bits - THEN we can restore your desired PWM Measurements - yet I am following KISS - very focused, small steps - advancing toward YOUR GOAL!
  • Danny,

    Agreed - I have asked poster to produce ONE SINGLE "pulse source" - and our attempt is to measure that - and that alone.
    Surely - the measurement of multiple source signals - at this early stage - is w/out much merit.
  • here is a demo of the approach I wrote earlier, on an ATtiny @ 8Mhz, 8:1 prescaler:

    the ISR is quite simple:

    //PCINT isr
    //count cycles on both edges
    ISR(PCINT0_vect) {
    	static uint8_t sPORT=0;					//prior state of the port
    	uint8_t tPORT;							//current state of the port
    	uint8_t dPORT;							//1->pin changed state
    	uint32_t tmp;							//time stamp
    	static uint32_t ticks1[4];				//rising edge timestamps
    
    	tmp = systicks();						//timestamp the edge
    	tPORT = PWMCH_PORT;						//read the port
    	dPORT = tPORT ^ sPORT;					//1->pin changed state
    
    	//test for pin change on ch 0
    	if (dPORT & PWMCH0) {					//ch0 has changed state
    		if (tPORT & PWMCH0) {				//rising edge on PWMCH0
    			pr[0]=tmp - ticks1[0];			//period = distance between two rising edges
    			ticks1[0]=tmp;					//update rising edge time
    		} else {							//falling edge on PWMCH0
    			dc[0]=tmp - ticks1[0];			//duty cycle = distance between rising and falling edges
    		}
    	}
    
    	//test for pin change on ch 1
    	if (dPORT & PWMCH1) {					//ch1 has changed state
    		if (tPORT & PWMCH1) {				//rising edge on PWMCH1
    			pr[1]=tmp - ticks1[1];			//period = distance between two rising edges
    			ticks1[1]=tmp;					//update rising edge time
    		} else {							//falling edge on PWMCH1
    			dc[1]=tmp - ticks1[1];			//duty cycle = distance between rising and falling edges
    		}
    	}
    
    	//repeat for other channels
    
    	sPORT = tPORT;							//save the state
    }
    

    I'm counting two pwm inputs:

    ch0: 1Khz, 10% duty cycle -> pr[0]=1000us, dc[0]=100us;

    ch1: 250Hz, 10% duty cycle -> pr[1]=4000us, dc[1]=400.

    here is a screen shot of the simulation:

    Our period counts are spot on: 1000 and 4000, our dc counts are 101 and 401, off by 1 count.

    Now, your chip will be different, and your code will be different, but the basic concept behind it will be identical. if anything, the isr will be quite a bit simpler on your chip.

    if you take much more than that to do it, there is something seriously wrong.

  • Danny F said:
    if you take much more than that to do it, there is something seriously wrong.

    Will not be the "first time" then - that this reporter falls into the, "seriously wrong" category...     

    In general - I applaud the cleverness demonstrated w/in your code - yet believe (some) more ... IS required!      (unknown is whether "some" rises to poster's definition of  "much.")

    "Some" or (even dreaded) "More" follows:

    • unstated is the "Calling Mechanism" for the ISR!     May we assume that GPIO's are driven by external,  (PWM signals) and that each/every GPIO - so driven - has been programmed to "Interrupt upon such external signal's, "Edge?"     (that should have been included - should it not?)
    • variable  "dPORT" likely defaults to the "lowest PWM channel" - yet the ISR reveals,  "No mechanism" to alter "dPORT" - so that (other) channels may be examined.    Is this true?
    • it is thus assumed that  (somehow)  "dPORT" is (loaded and "aimed") ... outside of the ISR.    (this so - "other" than the "default  dPORT channel" is selected.    Is this correct?      And - if  so - how do you propose "best" implementing this?
    • agree that "w/in the ISR" is NOT the place to calculate the input signals'  Frequency or Duty Cycle - yet the "Coordination & timing" of that (may) demand (some) explanation...    (if clarity is indeed, a goal)

    Your effort is appreciated - yet I continue in the belief that  "KISS" -  by far - best serves the requester.     His first task must be to capture & confirm the measure of a single pulse - NOT a "Pulse Bombardment!"

    Had you "had more time" - it is certain that more "intuitive or recognizable" variable names - could have been chosen.      (dPORT, tPORT, sPORT, tmp ... Not so much!)

  • Hello,

    I do not know why you say that my implementation is wrong because it is clear that it is the only way to do it in my case. I assume that you did not thoroughly read my code and jumped to conclusions. Anyways, the issue I had is resolved. The source of the error was from the way I was printing timer values to the terminal. Apparently UARTprintf has blocking property to it. So having it inside the functions that were called by ISR would just mess up my timer values. When I moved UARTprintf statements to the main while loop everything started to work perfectly. I will try to use UARTSend since it is the proper UART API. Thanks.

  • The issue I had is resolved. The source of the error was from the way I was printing timer values to the terminal. Apparently UARTprintf has blocking property to it. So having it inside the functions that were called by ISR would just mess up my timer values. When I moved UARTprintf statements to the main while loop everything started to work perfectly. I will try to use UARTSend since it is the proper UART API. That was my first TI forum post and I appreciate your patience. Thank you a lot for taking your time to try to help.
  • While we're glad that you believe your isssue solved - would not that  "SAME UART printf" have equally impacted your Timers EARLIER - when they were set to "32 bit mode?"      You reported the 32 bit mode to perform properly - using that  "SAME UART printf!"       I believe that to be true.

    Note that I did suggest that you, "Reduce the WHOLE" of your program - into far smaller, individual pieces - thus enabling the "EASED DETECTION" of the "ERRANT PART(S)."    That guidance may have achieved (somewhat) more than "try to help."

    At any rate - good luck.

    In retrospect - your use of the API Timers' function, "Edge Time Mode" appears a superior means to, "Achieve your PWM measure goal - while enabling, "Many more program code pieces to execute w/out time-delay penalty..."

  • That is actually how I found the error. I opened the file where 32-bit timers worked and the UARTprintf was used in the main while loop. Thank you for the advice!
  • Our posts just crossed - do note my most recent one - (now 2 up!)     Once again - KISS came to one's rescue - Good for you!