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.

TIVA PWM Interrupt not working

Other Parts Discussed in Thread: EK-TM4C123GXL, TM4C123GH6PM

Hello.

I know that are already a few posts regarding this problem but solutions from those are not working for me.

I am using TIVA LaunchPad (EK-TM4C123GXL), and my code is a modified lab 15 from LaunchPad workshop:

#include "inc/tm4c123gh6pm.h"
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/rom.h"

#define PWM_FREQUENCY 55

int main(void)
{
    volatile uint32_t ui32Load;
    volatile uint32_t ui32PWMClock;
    volatile uint32_t ui32Adjust;
    ui32Adjust = 500;

    ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_64);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    ROM_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
    ROM_GPIOPinConfigure(GPIO_PF1_M1PWM5);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3);

    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
    ROM_GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_DIR_MODE_IN);
    ROM_GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

    ui32PWMClock = SysCtlClockGet() / 64;
    ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
    PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, ui32Load);

    ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5, ui32Adjust * ui32Load / 1000);
    ROM_PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT, true);
    ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_2);

    PWMIntEnable(PWM1_BASE, PWM_INT_GEN_2);
    IntEnable(INT_PWM1_2);
    PWMGenIntTrigEnable(PWM1_BASE, PWM_INT_GEN_2, PWM_INT_CNT_ZERO);
    IntMasterEnable();

    while(1)
    {
        if ((ROM_GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4)==0x00) && (ui32Adjust > 10 ))
        {
            ui32Adjust--;
            ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5, ui32Adjust * ui32Load / 1000);
        }

        if ((ROM_GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_0)==0x00) && (ui32Adjust < 900))
        {
            ui32Adjust++;
            ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5, ui32Adjust * ui32Load / 1000);
        }

        SysCtlDelay(100000);
    }
}

void PWM1Gen2IntHandler(void)
{
    PWMGenIntClear(PWM1_BASE, PWM_INT_GEN_2, PWM_INT_CNT_ZERO);

    if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3))
    {
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
    }
    else
    {
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x8);
    }
}

As you can see, the difference from the LaunchPad Workshop Lab15 is that I am modifying the intensity of the Red LED. This parts works.

But I have also an interrupt on that PWM which does not execute: more, the code execution does not hang into IntDefaultHandler()'s forever loop. This interrupt just does not come.

Any ideas?

  • Our code is very similar - yet has run successfully on LX4F (and ill-fated LM3S) for past 4+ years.  Really must applaud you for "getting" PF1 as PWM1 - many (most) miss this. 

    As you list failed PWM1 interrupt - have you properly declared & placed that PWM1 interrupt w/in your start-up file?

    If yes - then we must resort to (perhaps) minor details:  (or not)

    For robustness - we issue a, "ROM_PWMGenIntClear()" prior to:
       ROM_PWMGenIntTrigEnable()
       ROM_PWMIntEnable()
       ROM_IntEnable()
     
    We note that your sequence differs - suggest that you switch to ours which (again) has long worked.  Your parameter usage appears (almost!) perfect.  (was sure we'd find something - and indeed - we did!)
     
    *** and - upon reread (your code) we find:
      
    PWMGenIntTrigEnable(PWM1_BASE, PWM_INT_GEN_2, PWM_INT_CNT_ZERO);
    PWMGenIntClear(PWM1_BASE, PWM_INT_GEN_2, PWM_INT_CNT_ZERO);
     
    Parameter 2 is wrong there - is it not?  Should be PWM_GEN_2 - both functions - says this reporter...  (unless "rebrand" has changed... always a possibility & continued delight...)  Mistake here will surely "kill" your desired interrupt!  You reported reading "several posts re: PWM" - clearly none from this reporter (#1 in PWM posts & verified {147/582} total PWM posts...)

    Should this "solve" - following is surplus but may prove of value to you/others...
     
    Note that you "mix" both ROM_PWM() & PWM() function calls.  Single call to non-ROM negates any benefit of employing ROM...
     
    Do not favor your use of "calculated values" (for both Period & PulseWidth Set) during initial test/verification.  Far safer to use hard coded, conservative values - to eliminate complications.  (at least during early tests)
     
    You define PWM Freq. as 55 - might that prove challenging for the PWM Generator?  (even though you've slowed the PWM Clock)  Suggest 1KHz as more of a, "sure thing." 
     
    And - you've got a wealth of include files.  If you've escaped any IDE "squawks" (over repeated or conflicting definitions) you should be ok.  Check & resolve via, "find in files" if multiple definitions are found...
  • Thank you for your quick answer. Indeed, that parameter was wrong.

    I hope that my silly issue was not too much trouble , but I've spent several hours trying to figure out what was wrong  and I just could not see the forest for the trees.

    Thank you again!

  • Issue was not trouble - devil very much in the detail - and you got everything else right.  BTW - forest/trees very much "in play" - our incandescently lumed, design/development lab.  Thank you @ bon chance, mon ami...