Generating 2 PWM signals with 1 timer of XMEGA A1U

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

Is there a way to generate 2 separate PWM signals using compare channels of timer 0/1 of XMEGA A1U, considering that start and stop timings are different. (XMEGA A1U)

 

Example:

PER = 80 us,

Signal 1 is high from 0 to 20 us of a period.

Signal 2 is high from 40 to 70  us of a period.

 

The signals have to be controlled absolutely precise, jitter free, using the timer's OC units, not inside an interrupt, not to mention polling the timer flags.

I cannot use a second timer (I have no spare timer that can be used for PWM control, I'm using all eight). If I had free timer, I'd run it with an offset and use it to control the second signal.

I prefer not using Event system -> DMA - I know I can solve the problem with that, using 2 timer events to toggle any pin.

Also, this has to be done runtime, without stopping the timer.

 

I used to do that control with timer 4/5 of XMEGA E5, but timers 4/5 had the possibility to set the polarity of the PWM control, timers 0/1 can't (I can invert the pins themselves, but that doesn't help in my solution).

Thus inside 1 period I used to reconfigure the CCB channel to set up a second event with inverted polarity, so the first compare match with generate the rising front of the signal and the second compare match of the same CC channel - the falling front (or vice versa).

I used 2 entries in interrupt to do that to reconfigure CCB, but it worked.

 

Here is what I previously did:

#pragma interrupt_handler   TCC4_CCB_interrupt:iv_TCC4_CCB
void TCC4_CCB_interrupt (void)
{
    unsigned char sreg = CPU_SREG;

    if (TCC4_ctrlState == 0) //first entry
    {
        TCC4_CTRLC &= ~(TC4_LCMPB_bm); //prepare toggling of CCB in second entry
        TCC4_CTRLC |= TC4_HCMPB_bm; //0b00100000

        TCC4_CCB = secondEntryTime;
        TCC4_ctrlState = 1;
    }
    else
    {
        TCC4_CTRLC &= ~(TC4_HCMPB_bm); //prepare toggling of CCB in first entry
        TCC4_CTRLC |= TC4_LCMPB_bm; //0b00000010

        TCC4_CCB = firstEntryTime;
        TCC4_ctrlState = 0;
    }
    
    
    TCC4_INTFLAGS = TC4_CCBIF_bm; //clear interrupt flag
    CPU_SREG = sreg;
}

Any ideas how I can achieve the same effect with XMEGA A1U?

 

P.S. Another difference I noticed is that turning off a CCExEN for a specific pin runtime behaves differently:

 - timer 0/1 (XMEGA A1U) - TCC0_CTRLB waveform control disable does nothing, until the next timer update event - output state is still controlled by the PWM, even if CCxBV and CCxIF are cleared and CTRLFSET is used for update command - nothing resets that pin

 - timer 4/5 (XMEGA E5) - TCC0_CTRLB waveform control disable immediately returns the standart control of the output - (PORTx_OUT)