CCU4 timer phase shift

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User15087
Level 2
Level 2
First like received
I am trying to output two square waves with 90 degree phase shift using CCU4 on the XMC1100 Boot Kit. For this I am using two slices CCU40_CC40 and CCU40_CC41.

I am starting both slices simultaneously using event triggering:

XMC_CCU4_SLICE_StartConfig(SLICE1_PTR, XMC_CCU4_SLICE_EVENT_0, XMC_CCU4_SLICE_START_MODE_TIMER_START);


My idea was to add a phase shift to one of the timers by preloading the timer value, before I trigger the start:

XMC_CCU4_SLICE_SetTimerValue(SLICE1_PTR, 32);


This does not work; once triggered the timers start and do not have the desired phase shift.

The XMCLib documentation notes that "Request to load is ignored if the timer is running." This is confirmed by the return value of XMC_CCU4_SLICE_IsTimerRunning(SLICE1_PTR). However the timer is not running (no PWM output on pin) and 'stopping' the timer using XMC_CCU4_SLICE_StopTimer(SLICE1_PTR); has no effect.


What am I doing wrong?
0 Likes
5 Replies
User15087
Level 2
Level 2
First like received
It seems that the solution is to set the timer value _after_ the call to XMC_CCU4_EnableClock().
0 Likes
User15087
Level 2
Level 2
First like received
I had another issue trying to synchronise two timers with a different prescaler. The slower timer will have a phase delay that is increasing with difference in prescaler.

A small test using CCU8 on XMC1400 Boot Kit showed the following:

SLICE0_PR = 8191
SLICE1_PR adjusted w/ prescaler to keep frequency constant.

Prescaler SLICE0 0 0 0 0 0 0 0 0 0 0
Prescaler SLICE1 1 2 3 4 5 6 7 8 9 10
Phase shift 1 5 9 17 55 87 151 279 535 1047
TIMER_R 8190 8186 8182 8174 8136 8104 8040 7912 7656 7144


Note that the phase shift is equal to 2^Prescaler + offset; where this offset is -1 (Prescaler=1), +1 (Prescaler=2..4), +23 (Prescaler=5..10). I don't know where this originates from. Probably it's just easier to concatenate two slices for the slower timer so that they can have the same prescaler setting.
0 Likes
User15087
Level 2
Level 2
First like received
I gave up on the idea of having synchronised PWM from multiple timer slices with different prescalers and instead used two concatenated timer slices to get the same end result. This sort-of works, but I am now struggling to get the timer dead-time working on the concatenated timer.

The rising-edge dead-time is applied; but the falling-edge dead-time is not. Could it be possible that this is artefact of working with a concatenated timer?
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi andrew,

I see you´re trying various approaches to achieve 90 degree phase shift, but I will suggest you another one and it seems to be the easiest one.

I´ve made an example using DAVE APPs while it was the fastest way but you can make it just with XMCLibs if you prefer. So, two CCU4 slices, namely CCU40_40 and CCU40_41. They have exactly the same values except one has "Timer initial value" set to Timer period value/4 (to get that phase shift). I noticed that code generation for this initial value is wrong while the SetTimerValue function should be called after the clocks are enabled as you noticed too already. However, that´s easy to fix. Another important aspect is to have both timers started synchronously at the same time. For this reason,I added input event for each slice. That looks something like this:
3130.attach

Main function is very simple and it calls just DAVE APP initialization and triggers the start of the timers:
int main(void)
{
DAVE_STATUS_t status;

status = DAVE_Init(); /* Initialization of DAVE APPs */

GLOBAL_CCU4_SyncStartTriggerHigh(GLOBAL_CCU4_CCUCON_Msk); // <== trigger both CCU4 slices

while(1U)
{

}
}


If I place the scope probes on the outputs of the CCU4 slices, I get something like this that seems to be exactly what are you trying to achieve:
3131.attach

Best regards,
Deni
0 Likes
User15087
Level 2
Level 2
First like received
Hi Deni,

Thanks for your answer. The method that you describe is the one of the methods that I used to get my code working. It is a fairly complicated setup to generate 4 timing / clock signals for a sensor module. With a single CCU8 timer module I used:
- Slice #0 and slice #1 as 2 MHz clock signals with 90deg phase shift via the method above
- Slice #2 and #3 as a concatenated timer. Slice #2 generates the clock for slice #3 at 500us period. The dual output PWM capability is used to create 2 trigger pulses. I use the dead time generator to create a phase delay between the two outputs here.
- Everything is started synchronously via event trigger.

I'm still learning the XMC mcu's and they allow complex configurations such as these. Unfortunately this also means that it has a steep learning curve; and that can be a bit frustrating at times. Right now I am working on getting the VADC and DMA up and running.
0 Likes