Other Parts Discussed in Thread: EK-TM4C1294XL
Hi,
I am using EK-TM4C1294XL EVM. I need to switch between 16 bit Periodic and PWM modes of Timer3 (same pin). Timer PWM mode with system clock source does not work correctly if I use the timer earlier in 16-bit periodic mode with alternating clock source.
In the code below I have configured the timer in 16-bit periodic mode with an alternating clock source. I disable the timer. And then configured it in 16-bit PWM mode with system clock source:
#include <stdbool.h> #include <stdint.h> #include <time.h> #include "driverlib/gpio.h" #include "driverlib/hibernate.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "inc/hw_hibernate.h" #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" void Timer3AIntHandler(void) { MAP_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); } void clock_init(void) { // System Clock 120 MHz MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120E6); // Alternating Clock RTCOSC 32768 Hz MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); while (!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_HIBERNATE)) { } MAP_HibernateEnableExpClk(0);// Enable the Hibernation module for operation. while (!(HWREG(HIB_RIS) & HIB_RIS_WC)) ; // Wait for 32.768kHz clock to stabilize. MAP_HibernateClockConfig(HIBERNATE_OUT_SYSCLK);// 32.768 kHz Osc, Output Hibernate Clk MAP_HibernateRTCEnable(); MAP_HibernateRTCSet(0);// Load initial RTC value. MAP_SysCtlAltClkConfig(SYSCTL_ALTCLK_RTCOSC); } void timer_init(void) { // T3CCP0: TIMERA :PA.6 MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3); while (!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER3)) {} MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); while (!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)) {} MAP_GPIOPinConfigure(GPIO_PA6_T3CCP0); MAP_GPIOPinTypeTimer(GPIO_PORTA_BASE, GPIO_PIN_6); } void set_timer_periodic_mode(void) { // MAP_TimerClockSourceSet(TIMER3_BASE, TIMER_CLOCK_SYSTEM); MAP_TimerClockSourceSet(TIMER3_BASE, TIMER_CLOCK_PIOSC);// alternating clock MAP_TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP); // uint32_t cycles = 120E3;// System clock: 1 ms timeout uint32_t cycles = 32;// Alternating clock: 1 ms timeout MAP_TimerPrescaleSet(TIMER3_BASE, TIMER_A, cycles / 65536); MAP_TimerLoadSet(TIMER3_BASE, TIMER_A, cycles); TimerIntRegister(TIMER3_BASE, TIMER_A, Timer3AIntHandler); MAP_TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT); MAP_IntEnable(INT_TIMER3A); MAP_IntPrioritySet(INT_TIMER3A, 0xA0); MAP_TimerEnable(TIMER3_BASE, TIMER_A); } void disable_timer(void) { MAP_IntDisable(INT_TIMER3A); MAP_TimerIntDisable(TIMER3_BASE, TIMER_TIMA_TIMEOUT); TimerIntUnregister(TIMER3_BASE, TIMER_A); MAP_TimerDisable(TIMER3_BASE, TIMER_A); } void set_timer_pwm_mode(void) { MAP_TimerClockSourceSet(TIMER3_BASE, TIMER_CLOCK_SYSTEM); MAP_TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM); uint32_t cycles = 120E6 / 100;// PWM frequency: 100 Hz uint16_t load = cycles % 65536; uint8_t prescalor = cycles / 65536; uint32_t period = load + prescalor * 65536; uint32_t duty = period / 2;// Dutycyle: 50% MAP_TimerPrescaleSet(TIMER3_BASE, TIMER_A, prescalor); MAP_TimerLoadSet(TIMER3_BASE, TIMER_A, load); MAP_TimerPrescaleMatchSet(TIMER3_BASE, TIMER_A, duty / 65536); MAP_TimerMatchSet(TIMER3_BASE, TIMER_A, duty % 65536); MAP_TimerEnable(TIMER3_BASE, TIMER_A); } int main(void) { clock_init(); MAP_IntMasterEnable(); timer_init(); // Timer3 as 16 bit periodic timer with timeout interrupt set_timer_periodic_mode(); // Disable timer disable_timer(); // Timer3 in PWM mode set_timer_pwm_mode(); while (1) { } }
The switch problem arises only if I use an alternating clock source in 16-bit periodic mode. Could anyone please guide me on whether I am switching between timer modes correctly?
Thank you,
Hassan