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.

TM4C123G PWM Clock divide by 64 not working

Other Parts Discussed in Thread: TM4C1294NCPDT

I need to generate a very low frequency PWM. The period has to be around 1/2 to 1 second. The only way I can get a frequency that low is to use the SYSCTL_PWMDIV_64 in the PWM clock set. Unfortunately, this parameter doesn't seem to work. Everything up until SYSCTL_PWMDIV_32 works as expected but when I try to use SYSCTL_PWMDIV_64 no output is generated by the PWM.  For now I have just divided down the system clock as well, but that isn't a solution I want to use long term.


Is there something I'm missing about not being able to use SYSCTL_PWMDIV_64?

  • Jo-Jo Smith said:
    Is there something I'm missing?

    I missed your MCU upon first few reads.  (note that it's "buried" @ top of forum when your post is open for reading)  Suspect that it's better to repeat your MCU and IDE w/in the body of the post.  (somewhere - iirc - such suggestion has been past made...)

    Have you checked most current errata - mated to your MCU Rev? 

    Is your system clock dialed up high enough that a, "PWM divide by 64 is eased/enabled?"  (agree that's bit of a reach - but am "poking" for an answer)

    May prove worthwhile for you to carefully survey all pertinent PWM Registers (there are many - sorry) and check to see if one or several, "misbehave" during your failed, "divide by 64."

    And - another longshot (but imaginative) have you tested to see if same holds true upon a different PWM pin or generator?  The more you can "generalize" the problem's occurrence - the better the chance for a solution...

  • Your response wasn't helpful. Please don't respond if you have nothing constructive to add, or you are unable to post without snark.


    Let me try this again...

    Using this line in my code generates the expected output:

    ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_32);

    Using this line doesn't generate any output:

    ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_64);

    All things staying the same replacing the first line with the second should halve the period, not kill the output all together, right?

    Full function follows:

    ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_64);       //This line doesn't work
       
       ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
       ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
       
       ROM_GPIOPinConfigure(GPIO_PA7_M1PWM3);
       ROM_GPIOPinTypePWM(GPIO_PORTA_BASE, GPIO_PIN_7);
       
       ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
       
       ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, PWM_PERIOD_COUNT);
       
       ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_3, PWM_PERIOD_COUNT/2);
       ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_1);
       
       PWMOutputState(PWM1_BASE, PWM_OUT_3_BIT, true);

  • Believe a fair read will show any, "snark" resides your writing.

    Sounds much like a past reported errata.  (as stated - clearly - rejected/answering post)  There were impacting changes w/in certain versions of TivaWare and newly introduced MCU Registers...

    After very quick/dirty review - following (related) post reveals:  (there are multiple...)

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/263733.aspx

    And vendor engineer past found/advised, "set the PWM divider after the SysctlPeripheralEnable function -- that appears to work reliably."  I cannot confirm - but appears worth a try...

    [edit] and now - based upon this poster's feedback (17:08) - "can" confirm suggestion - immediately above - has worked - resolved this poster's issue...

  • Sorry, I was trying to respond to your first reply, but you revised it before I had a chance to post my response.  In the future I will be sure to include the part number in the body of the post.

    Unfortunately, the debugger I'm using isn't working correctly, so I can't view the PWM registers.  I was hoping there was a simple explanation, but I guess I'll have to see if I can get my debugger working properly if I want to investigate further.

  • Indeed I feel your/others' pain.  Spend some time here - truly trying to be helpful/useful.  (we're not paid much!)  If you vector up to the top of the forum you'll note some of my forum improvement suggestions)

    Look again at my 2nd post - some have reported very similar to you.

    Our small tech firm does not use TivaWare - I can report that under StellarisWare our LX4F fully enables PWM divide.  Perhaps that's an option for you.  (vendor sure to resist, though)

    It's understandable that users become frustrated/discouraged - you explained your issue well - but the occurrence of IDE and library changes, "sounded my alarm bell!"

  • I tired setting the clock divider after enabling the peripheral, as suggested above, and that seems to work OK.

    Thanks for the help.

  • Good for you - glad you persisted.  (too bad "world peace" - not this easy...)  From a start-up stumble - we emerge friends...

    I'd get that debugger up/running asap.  You're methodical enough to benefit greatly from the data/insight it provides...

  • Adding to the same subject, as I had a similar problem but used a different solution (as the one above did not work for me...)

    Initially I had tried the "obvious":

    1
    2
    SysCtlPWMClockSet(SYSCTL_PWMDIV_32);
    // Should set the PWM clock to use SysClock divided BUT THIS IS NOT WORKING!!!

    However, on Tiva uC's the register which sets the divider has changed. Up to version 2.1.0, as far as I am aware, there is no TivaWare function for that.

    So I wrote directly to the proper register as below:

    1
    2
    HWREG(PWM0_BASE + 0xFC8) = (256 + 5);
    // Set register PWMCC to use SysClock divided by 64

    Value 5 can be anything from 0 to 5, and divides by 2, 4, 8, 16, 32, 64. This worked just fine.

    The processor I am using is the TM4C1294NCPDT, that comes on the Evaluation Board.

  • Good info - thanks for that.

    To be clearer, (256 + 5) enables the PWMDIV by 64, (256 + 4) by 32 - and the sequence continues as you list.

    Would you be so good to confirm?  And thanks...

  • You're most welcome!

    Yes, that's exactly how the divider works.

    The 256 means "use the divider", and the second number means which divider to use.

    And the "mysterious"  0xFC8 value is the offset from the PWM0 base address to the PWMCC register location, which can be seen on page 1752 of the TM4C1294NCPDT datasheet. 

  • Hi, I'm well aware of the fact this is an old topic so I apologize for bringing it back, but as an additional information for TM4C1294 users: looking at sysctl.c and pwm.c files from tivaware/driverlib (version 2.1.0)  it seems like TM4C1294 uses a different set of functions for setting/retrieving PWM clock, namely:

    	//*****************************************************************************
    	///
    	//! Sets the PWM clock configuration.
    	//!
    	//! \param ui32Base is the base address of the PWM module.
    	//! \param ui32Config is the configuration for the PWM clock; it must be one of
    	//! \b PWM_SYSCLK_DIV_1, \b PWM_SYSCLK_DIV_2, \b PWM_SYSCLK_DIV_4,
    	//! \b PWM_SYSCLK_DIV_8, \b PWM_SYSCLK_DIV_16, \b PWM_SYSCLK_DIV_32, or
    	//! \b PWM_SYSCLK_DIV_64.
    	//!
    	//! This function sets the PWM clock divider as the PWM clock source.  It also
    	//! configures the clock frequency to the PWM module as a division of the
    	//! system clock.  This clock is used by the PWM module to generate PWM
    	//! signals; its rate forms the basis for all PWM signals.
    	//!
    	//! \note This function should not be used with TM4C123 devices.  For
    	//! TM4C123 devices, the SysCtlPWMClockGet() function should be used.
    	//!
    	//! \note The clocking of the PWM is dependent upon the system clock rate as
    	//! configured by SysCtlClockFreqSet().
    	//!
    	//! \return None.
    	//
    	//*****************************************************************************
    
    	void PWMClockSet(uint32_t ui32Base, uint32_t ui32Config)
    
    	//*****************************************************************************
    	//
    	//! Gets the current PWM clock configuration.
    	//!
    	//! \param ui32Base is the base address of the PWM module.
    	//!
    	//! This function returns the current PWM clock configuration.
    	//!
    	//! \note This function should not be used with TM4C123 devices.  For
    	//! TM4C123 devices, the SysCtlPWMClockGet() function should be used.
    	//!
    	//! \return Returns the current PWM clock configuration; is one of
    	//! \b PWM_SYSCLK_DIV_1, \b PWM_SYSCLK_DIV_2, \b PWM_SYSCLK_DIV_4,
    	//! \b PWM_SYSCLK_DIV_8, \b PWM_SYSCLK_DIV_16, \b PWM_SYSCLK_DIV_32,
    	//! or \b PWM_SYSCLK_DIV_64.
    	//
    	//*****************************************************************************
    
    	uint32_t PWMClockGet(uint32_t ui32Base)

    File tivaware/driverlib/pwm.c (lines 1965 to 2055)