I'm trying to get a sequence of for PWM pulses generated by daisy chaining both A and B timers of timers 1 and 2 using one-shot PWM mode. If I set PHASE_PERIOD to any value that fits in 16 bits the code below works. If I set PHASE_PERIOD to more than 16 bits, it looks like the timer counts down until the first time the 16 least significant bits of Timer 1A hit zero, Timer 1A enable is cleared and then everything stops. Even if I try re-enabling timer 1A, the enable appears to be cleared immediately and the timer stops right away.
The documentation doesn't talk about using one-shot PWM mode and it isn't supported natively by the TI libraries. I had to define my own configuration for it. Is it a valid operating mode?
#define PHASE_PERIOD (65536U)
#define TIMER_CFG_A_ONE_SHOT_PWM (0x009)
#define TIMER_CFG_B_ONE_SHOT_PWM (0x900)
uint32_t load;
TimerConfigure( TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT_PWM | TIMER_CFG_B_ONE_SHOT_PWM );
/* Phase C PWM */
GPIOPinConfigure( GPIO_PS0_T2CCP0 );
GPIOPinTypeTimer( GPIO_PORTS_BASE, GPIO_PIN_0 );
/* Phase D PWM */
GPIOPinConfigure( GPIO_PS1_T2CCP1 );
GPIOPinTypeTimer( GPIO_PORTS_BASE, GPIO_PIN_1 );
TimerConfigure( TIMER2_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT_PWM | TIMER_CFG_B_ONE_SHOT_PWM );
load = PHASE_PERIOD;
// Phase A and B PWM control.
TimerLoadSet( TIMER1_BASE, TIMER_BOTH, load & 0xffff );
TimerPrescaleSet( TIMER1_BASE, TIMER_BOTH, load >> 16 );
// Phase C and D PWM control.
TimerLoadSet( TIMER2_BASE, TIMER_BOTH, load & 0xffff );
TimerPrescaleSet( TIMER2_BASE, TIMER_BOTH, load >> 16 );
/// Phase B-D wait for the previous timer to timeout before starting.
TimerControlWaitOnTrigger( TIMER1_BASE, TIMER_B, true );
TimerControlWaitOnTrigger( TIMER2_BASE, TIMER_BOTH, true );
load /= 2;
TimerMatchSet( TIMER1_BASE, TIMER_BOTH, load & 0xffff );
TimerPrescaleMatchSet( TIMER1_BASE, TIMER_BOTH, load >> 16 );
TimerMatchSet( TIMER2_BASE, TIMER_BOTH, load & 0xffff );
TimerPrescaleMatchSet( TIMER2_BASE, TIMER_BOTH, load >> 16 );
while ( true )
{
if ( (HWREG( TIMER2_BASE + TIMER_O_CTL ) & TIMER_CTL_TBEN) == 0 )
{
// TODO: Set the warmer phase duty cycle
// Enable 2 first since it won't start until timer 1 has completed.
TimerEnable( TIMER2_BASE, TIMER_BOTH );
TimerEnable( TIMER1_BASE, TIMER_BOTH );
}
}
}
Thanks for your help.