PWM and Counter

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

cross mob
Not applicable
Hi All,

I would like to switch on a PWM after a counter has reached a certain count without using interrupts, but using the direct events from the CCU4/8 units. How can this be done? I can find no example nor anything about it in the documentation, although it seems that it should be simple and possible.

I would appreciated any input or comment about this.

Regards
Enigma
0 Likes
3 Replies
User10215
Level 4
Level 4
First like received
Hi Enigma,

I can't give you a detailed answer, however have a look at the "Interconnects"-section in the reference manual of the CCU-unit of the controller you are using.
For instance for the XMC4500 reference manual v1.5 starting at page 22-131 gives you a list of how the CCU-channels connect to other peripherals.
For example in the XMC4500 the Service request line 3 of CCU40 (also called CCU40.SR3) can be connected to an input of either CCU80.CC80 or CCU81.CC80. This means, if you activate the match-interrupt of one of the CCU40-channels and route it to its service request line 3 you can use that to trigger some event in CCU80 (for instance starting a PWM).
The configuration of CCU80.CC80 would be the same as if you use a GPIO to trigger an event in that channel.For this to work you don't have to enable the interrupt in the NVIC, which means the CPU isn't affected.

Furthermore, each CCU-channel has a status signal. Using CCU40.CC40 as an example, that status signal is referenced as CCU40.ST0 in the reference manual. Having a look into the interconnects section again tells me that those status signals can also be used as input to other CCU4-channels, which also means they can trigger an event in the CCU-channel they are connected to (i.e. starting a PWM).
If I'm not mistaken these status signals correspond to the "compare"-state of a channel. So each time a CCU-channel reaches its compare value the status-signal changes and, if connected to another channel, can trigger an event.
However it's best if you have a look in the reference manual if you want to know how the status-signal of a CCU-channel works.

Regards,
Niclas
0 Likes
Not applicable
Hi Niclas,

Thanks for the tips, I will definitively have a look now at this.

Regards,
Enigma
0 Likes
Not applicable
Hi Enigma,

the method as proposed by Niclas works very good. I used it with the XMC1100 to drive CC41,CC42 and CC43 counter via the output from CC40.
The output pad of CC40 (CCU40.OUT1) has to be wired to the inputs (CCU40.IN1C,CCU40.IN2C,CCU40.IN3C)
I hope the my code example helps you to find your way the all the settings.

//CCU4
switch_on(usic0);
IOFunktion(mainclock,PushPull+Alt4); //sets CCU40.OUT1 PWM
//IOFunction sets P0/0 to push pull Alt4
//mainclock is an array that holds the PinPad e.g. uint32_t mainclock[2]={0,0};
//PushPull+Alt4 is the PCxCoding
IOFunktion(x_Takt,InputToOUTx); //CCU40.IN1C
IOFunktion(y_Takt,InputToOUTx); //CCU40.IN2C
IOFunktion(z_Takt,InputToOUTx); //CCU40.IN3C

IOFunktion(x_Step,PushPull+Alt4); //CCU40.OUT1 PWM
IOFunktion(y_Step,PushPull+Alt4); //CCU40.OUT2 PWM
IOFunktion(z_Step,PushPull+Alt4); //CCU40.OUT3 PWM

//connections
CCU40_CC41->INS |= (1<<16) + (1<<1); //Event0, rising edge
CCU40_CC42->INS |= (1<<16) + (1<<1); //Event0, rising edge
CCU40_CC43->INS |= (1<<16) + (1<<1); //Event0, rising edge
CCU40_CC41->CMC |= (1<<14); //Event0, rising edge
CCU40_CC42->CMC |= (1<<14); //Event0, rising edge
CCU40_CC43->CMC |= (1<<14); //Event0, rising edge


CC4yInit(CC40);
CC4yInit(CC41);
CC4yInit(CC42);
CC4yInit(CC43);

uint32_t P0=18,Px =65336, Py=3284, Pz=1641;
CC4yPWM(CC40,P0,P0>>1); //set counter CC40, P0 -> periode, P0/2 -> compare
CC4yPWM(CC41,Px,Px>>1);
CC4yPWM(CC42,Py,Py>>1);
CC4yPWM(CC43,Pz,Pz>>1);

CCU40->GIDLC |= 0x1<<8; // Sets Run bit of the Prescaler

Felix
0 Likes