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.

TM4C129ENCPDT: How to slow down the PWM period

Part Number: TM4C129ENCPDT

Hello,

I have TI-RTOS application with 4 PWMs, each of them using separate PWM Generator (outputs PWM0, PWM3, PWM5 and PWM6).

- Upon start it calls: 

void EK_TM4C129EXL_initPWM(void)
{
/* Enable PWM peripherals */
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

/*
* Enable PWM output on GPIO pins. PWM output is connected to an Ethernet
* LED on the development board (D4). The PWM configuration
* below will disable Ethernet functionality.
*/

//
// Configure the GPIO Pin Mux for PF3
// for M0PWM3
//
GPIOPinConfigure(GPIO_PF3_M0PWM3);
GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_3);
#ifndef PWM_TEST
//
// Configure the GPIO Pin Mux for PG0
// for  M0PWM0
//
GPIOPinConfigure(GPIO_PF0_M0PWM0);
GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0);
#endif
//
// Configure the GPIO Pin Mux for PG1
// for M0PWM5
//
GPIOPinConfigure(GPIO_PG1_M0PWM5);
GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_1);

// Configure the GPIO Pin Mux for PK4
// for M0PWM6
//
GPIOPinConfigure(GPIO_PK4_M0PWM6);
GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4);

PWM_init();
}

- Then starts the PWMs individually, e.g.:

PWM_Params_init(&Output1PWMparams);
Output1PWMparams.period = 100;// Period in microseconds
Output1PWMparams.dutyMode = PWM_DUTY_TIME;
Output1PWMhandle = PWM_open(Board_PWM5, &Output1PWMparams);
if (Output1PWMhandle == NULL)
{
System_abort("Error initializing PWM 5\n");
}
PWM_setDuty(Output1PWMhandle, 10);

I can use any combination of periods (50, 100, 300 us), however when trying slower periods (2000 and 40000 us) the PWM_open fails, not able to set the pre-scaler.

How can I accomplish to slow down the period for some PWMs, and be able to concurrently have fast and slow periods on different outputs?

Please advise. Thank you,

Dalibor

  • I can use any combination of periods (50, 100, 300 us), however when trying slower periods (2000 and 40000 us) the PWM_open fails, not able to set the pre-scaler.

    Please note that PWM counter is only 16 bits. At 120Mhz, the maximum period is about 540uS only. 

    You can divide the PWM timebase by programming the PWMCC register.

    However, TI-RTOS PWM driver does not have a function to program this register. You can use the TivaWare API to program the divider by calling PWMClockSet() 

  • Thank you, Charles. This must be a path forward, but I ran into problem to mix this TI-RTOS project with the TivaWare. Trying to call the ROM based function ROM_PWMClockSet(Board_PWM5,clkdiv); but it bombs out. I was not able to successfully install the TivaWare viaTM4C ARM® Cortex®-M4F MCU (2.1.4.178), it gets downloaded and installed, but when selecting an example, it asks me to install it again. How can I include successfully the classic TivaWare or ROM based functions?

    Please advise.

    Dalibor

  • This is what you need to do. 

    1. Add the below header files. 

    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/rom.h"
    #include "driverlib/pwm.h"

    2. Add the TARGET_IS_TM4C129_RA2 symbol. 

    3. Call something like below. 

    ROM_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_8);  // Sysclk divide by 8.

  • Hello Charles,

    I actually had it implemented, only missing headers:

    #include <stdbool.h>
    #include "inc/hw_memmap.h"

    Also, I had defined TARGET_IS_TM4C129_RA0. Which is correct for TM4C129ENCPDT?

    After the changes the result is the same. The code compiles fine, runs to the breakpoint at ROM_PWMClockSet and when I step over it aborts. Here is the calling stack:

    Any ideas?

  • Hi Dalibor,

      You need to make sure the PWM module is enabled before you call PWMClockSet which means you need to call Board_initPWM() first before you call PWMClockSet. If this is not the cause of the problem, then please refer the below links for diagnosing exceptions. 

  • Hi Charles,

    I have abandoned the mix PWM functionality with TI-RTOS and ROM based functions, which caused my crashes. Instead, I have used all the PWM module functions from the TivaWare and followed the examples. It is all working fine, except setting of the PWM clock divider. Regardless of the value I set, the result is corresponding with the direct CPU clock. The examples using changed the CPU clock to 25MHz and the PWM without the divider. I cannot slow down the CPU clock due to other modules. Is there anything special needed to get SYSCTL_PWMDIV_64 divider?

    Here is my PWM initialization:

    uint32_t clock;

    //
    // Set the PWM clock to the system clock.
    //

    SysCtlPWMClockSet(SYSCTL_PWMDIV_64);
    clock = SysCtlPWMClockGet(); => Always get 0


    //
    // The PWM peripheral must be enabled for use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    //

    GPIOPinConfigure(GPIO_PF0_M0PWM0);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0);

    etc...

    Please advise

  • SysCtlPWMClockSet(SYSCTL_PWMDIV_64);
    clock = SysCtlPWMClockGet(); => Always get 0

    Hi,

      You should not use SysCtlPWMClockSet() for TM4C129 device. This API is only for TM4C123. You should be using PWMClockSet() instead for TM4C129. 

  • Hi Charles,

    thank you again for the quick response. I have changed the code to:

    uint32_t clock;

    //
    // Set the PWM clock to the system clock.
    //

    PWMClockSet(PWM0_BASE,PWM_SYSCLK_DIV_1);
    clock = PWMClockGet(PWM0_BASE);

    Unfortunately, when executing the PWMClockSet it errors out and aborts. I must have some configuration issue. Using 

    and

    Is my configuration correct? Also please point me to the documentation you have made the screenshot from.

    Thank you,

    Dalibor

  • Hi Dalibor,

      I was referring to the TivaWare Peripheral Driver Library user's guide. You can also find it in the TivaWare SDK installation under the /docs directory.

    Does it compile fine? 

    You need to make sure you only call PWMClockSet() after you call SysCtlPeripheralEnable() or it will abort. Without first enabling PWM module by calling SysCtlPeripheralEnable(), it will abort for any access to the module's registers. This is most likely what you are seeing. 

      

  • Thank you, Charles. Yes, I was wondering why the example sets the clock before enabling the module. This was probably the reason, it was setting CPU clock instead of PWM clock to get the timing. All good now.

    Regards,

    Dalibor