Part Number: TM4C1294NCPDT
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