Announcements

Help us improve the Power & Sensing Selection Guide. Share feedback

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

cross mob
robs1
Level 4
Level 4
100 sign-ins 50 replies posted First solution authored

Hi,

I need a code for realize a PWM signal with its inverse PWM with a delay of 100 ns between them. 

I need to use ATOM module and I already checked the code linked in this forum but they don't work.

I really don't know how to use in a simple way for my purpose the DTM because no examples are available about it in the aurix ide. 

Thank you in advance. 

0 Likes
9 Replies
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

The following are the basic register configuration to enable the DTM, please refer the UM for the specific details.

/* Configure dead time */
MODULE_GTM.CDTM[1].DTM[0].CTRL.B.CLK_SEL = 1; // select CMU_CLK0 as dead timer clock
MODULE_GTM.CDTM[1].DTM[0].CH[0].DTV.B.RELFALL = 200; // falling edge dead time
MODULE_GTM.CDTM[1].DTM[0].CH[0].DTV.B.RELRISE = 200; // rising edge dead time
MODULE_GTM.CDTM[1].DTM[0].CH_CTRL2.B.DT0_0 = 1; // OUT0 dead time enable
MODULE_GTM.CDTM[1].DTM[0].CH_CTRL2.B.DT1_0 = 1; // OUT1 dead time enable

Thanks.

0 Likes
robs1
Level 4
Level 4
100 sign-ins 50 replies posted First solution authored

ok thank you but how I can see on the oscilloscope the PWM and its inverse? I think I have to write some lines of code for pin but how?

0 Likes
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

You can refer to the ATOM PWM example in the github and additionally configure DTM to have PWM and its inverse with dead time.

Thanks.

0 Likes
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

If you don't want to use DTM, the dead time has to be implemented in firmware. We do have an example in the iLLD demo 'GtmAtomPwmHlDemo', which can create multiple pairs of complementary PWM signals with configurable dead time. By default the cluster clock is 100 MHz as CLS0_CLK_DIV is enabled with divider, you need to make CLS0_CLK_DIV as 01b to have 200 MHz. This already creates center-aligned PWM with the master-slave trigger. You may need to change the logic to update the compare values in the ISR for the desired phase shift.

Thanks.

robs1
Level 4
Level 4
100 sign-ins 50 replies posted First solution authored

Sorry but I can t open that link! How can I open it? Said to me I am not autorized 

0 Likes
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

This is part of myICP, you can follow the below link for the instructions to get access

https://www.infineon.com/dgdl/Infineon-MyICP_Platform_For_Microcontrollers-Presentations-v01_00-EN.p...

Thanks.

robs1
Level 4
Level 4
100 sign-ins 50 replies posted First solution authored

ok Thank you. I prove with this codes but it seems to create me a 5 Hz pwm but I need a 100 kHz one... it seems like the counter of atoms count until very high value and the timer doesn't reset it. What is wrong? 

 

IfxGtm_enable(&MODULE_GTM); /* Enable GTM */
IfxGtm_Cmu_setClkFrequency(&MODULE_GTM, IfxGtm_Cmu_Clk_0, 100000000); // Set the CMU clock 0 frequency - ATOM
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0); // Enable the CMU clock 0 - ATOM


//Configuration of the timer reset of atom counters

IfxGtm_Atom_Timer_initConfig(&g_timerConfig,&MODULE_GTM);//To set default parameters for timer
g_timerConfig.atom = PIN_CLOCK.atom;
g_timerConfig.timerChannel = PIN_CLOCK.channel;
g_timerConfig.triggerOut = &PIN_CLOCK;
g_timerConfig.base.frequency = 10000; // CM0: clock reset
g_timerConfig.base.countDir = IfxStdIf_Timer_CountDir_up;
// g_timerConfig.base.countDir = IfxStdIf_Timer_CountDir_upAndDown;
g_timerConfig.base.trigger.enabled = TRUE;
g_timerConfig.base.trigger.outputEnabled = TRUE;
g_timerConfig.base.trigger.triggerPoint = 500; // CM1: triggera a mezzo periodo
g_timerConfig.initPins = TRUE;
g_timerConfig.clock=IfxGtm_Cmu_Clk_0;

// g_timerConfig.base.minResolution = (1.0 / g_timerConfig.base.frequency) / 1000;
// g_timerConfig.base.trigger.risingEdgeAtPeriod = TRUE;


//IfxGtm_Atom_Timer_setFrequency(&g_timerDriver, 100000);

IfxGtm_Atom_Timer_init(&g_timerDriver, &g_timerConfig);
IfxGtm_Atom_Timer_run(&g_timerDriver);

 

// create ATOM configuration

IfxGtm_Atom_ToutMapP ccx[] = {&IfxGtm_ATOM0_0_TOUT48_P22_1_OUT};//output pin pwm
IfxGtm_Atom_ToutMapP coutx[] = {&IfxGtm_ATOM0_1_TOUT47_P22_0_OUT};//output pin pwm inverse


IfxGtm_Atom_PwmHl_Config pwmHlConfig;
IfxGtm_Atom_PwmHl g_pwm;
IfxStdIf_PwmHl pwmhl;


IfxGtm_Atom_PwmHl_initConfig(&pwmHlConfig); //For default configurations

//For configurations

pwmHlConfig.timer=&g_timerDriver;

//BASE DA CONTINUARE forse non c'è bisogno
pwmHlConfig.base.outputMode = IfxPort_OutputMode_pushPull;
pwmHlConfig.base.channelCount=1;
pwmHlConfig.base.deadtime=0;

pwmHlConfig.ccx = ccx;
pwmHlConfig.coutx = coutx;

pwmHlConfig.base.emergencyEnabled = FALSE;
pwmHlConfig.base.ccxActiveState = Ifx_ActiveState_high;
pwmHlConfig.base.coutxActiveState = Ifx_ActiveState_low;
pwmHlConfig.base.ccxOutputEnabled=TRUE;
pwmHlConfig.base.coutxOutputEnabled=TRUE;
// initialize the ATOM
IfxGtm_Atom_PwmHl_init(&g_pwm, &pwmHlConfig);
IfxGtm_Atom_PwmHl_stdIfPwmHlInit(&pwmhl, &g_pwm);

 

// IfxGtm_Atom_Timer_run(&g_timerDriver);

 

IfxStdIf_Timer* timer = IfxStdIf_PwmHl_getTimer(&pwmhl);
Ifx_TimerValue onTime[1]; // assume configured for 1 HL channel

onTime[0] = 200; //dovrebbe essere in ticks
// onTime[1] = 20;


IfxGtm_Atom_PwmHl_setMode(&g_pwm, Ifx_Pwm_Mode_centerAligned);
IfxStdIf_Timer_disableUpdate(timer);
//IfxStdIf_Timer_setPeriod(timer, period);
IfxStdIf_PwmHl_setOnTime(&pwmhl, onTime);
IfxStdIf_Timer_applyUpdate(timer);

0 Likes
Yuva
Moderator
Moderator
Moderator
250 replies posted 250 sign-ins 100 solutions authored

Hello,

g_timerConfig.base.frequency = 10000 is used for the frequency configuration, this can be changed for the required frequency. For 100 KHz, change to 100000 and check the behavior. 

Thanks.

robs1
Level 4
Level 4
100 sign-ins 50 replies posted First solution authored

Hi, thank you, you are right but my main error was that the trigger timer must be part of the same atom (all channels must be of atom0).

Now I am searching for translate this code for up down counter, but in all my codes of up down counting I have problems of synchronization.

Maybe I set the "up down mode" in a part of code that creates a delay between counters (indeed my counter doesn't count until 1000 but 800)...

 

 

void ATomPwmUpDowncounter(){


IfxGtm_enable(&MODULE_GTM); /* Enable GTM */
//SET THE CLOCK SOURCE TO ITS MAXIMUM SO 200 MHZ
//RF_PROT bit cleared in order to set CLK_DIV
gtm_ptr->CTRL.B.RF_PROT=0;
//Set cluster enable without clock divider
gtm_ptr->CLS_CLK_CFG.B.CLS0_CLK_DIV=01;
IfxGtm_Cmu_setClkFrequency(&MODULE_GTM, IfxGtm_Cmu_Clk_0, 200000000); // Set the CMU clock 0 frequency - ATOM
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0); // Enable the CMU clock 0 - ATOM


//Configuration of the timer reset of atom counters

IfxGtm_Atom_Timer_initConfig(&g_timerConfig,&MODULE_GTM);//To set default parameters for timer
g_timerConfig.atom = PIN_CLOCK.atom;
g_timerConfig.timerChannel = PIN_CLOCK.channel;
g_timerConfig.triggerOut = &PIN_CLOCK;
//Change this parameter to change the frequency of pwms displayed
g_timerConfig.base.frequency = PWM_FREQUENCY*2; // CM0: clock reset
g_timerConfig.base.countDir = IfxStdIf_Timer_CountDir_up;
// g_timerConfig.base.countDir =IfxStdIf_Timer_CountDir_upAndDown;
g_timerConfig.base.trigger.enabled = TRUE;
g_timerConfig.base.trigger.outputEnabled = TRUE;
g_timerConfig.base.trigger.triggerPoint = 1000; // CM1: trigger at half period
g_timerConfig.initPins = TRUE;
g_timerConfig.clock=IfxGtm_Cmu_Clk_0;
g_timerConfig.base.minResolution = (1.0 / g_timerConfig.base.frequency) / 1000;
g_timerConfig.base.trigger.risingEdgeAtPeriod = TRUE;


IfxGtm_Atom_Timer_init(&g_timerDriver, &g_timerConfig);


//To start at zero value the timer
gtm_ptr->ATOM[0].CH2.CN0.B.CN0=0;


// create ATOM configuration
IfxGtm_Atom_PwmHl_initConfig(&pwmHlConfig); //For default configurations

//For configurations

pwmHlConfig.timer=&g_timerDriver;
pwmHlConfig.base.outputMode = IfxPort_OutputMode_pushPull;
pwmHlConfig.base.channelCount=1;
pwmHlConfig.base.deadtime=0;//100e-9;
pwmHlConfig.ccx = ccx;
pwmHlConfig.coutx = coutx;
pwmHlConfig.base.emergencyEnabled = FALSE;
pwmHlConfig.base.ccxActiveState = Ifx_ActiveState_high;
pwmHlConfig.base.coutxActiveState = Ifx_ActiveState_high;
pwmHlConfig.base.ccxOutputEnabled=TRUE;
pwmHlConfig.base.coutxOutputEnabled=TRUE;
pwmHlConfig.initPins=TRUE;

 

 

// initialize the ATOM
IfxGtm_Atom_PwmHl_init(&g_pwm, &pwmHlConfig);
IfxGtm_Atom_PwmHl_stdIfPwmHlInit(&pwmhl, &g_pwm);

//To set up down counting
gtm_ptr->ATOM[0].CH0.CTRL.B.UDMODE=0x3;
gtm_ptr->ATOM[0].CH1.CTRL.B.UDMODE=3;


//Counters all have to start from 0
gtm_ptr->ATOM[0].CH0.CN0.B.CN0=0;
gtm_ptr->ATOM[0].CH1.CN0.B.CN0=0;


IfxGtm_Atom_Timer_run(&g_timerDriver);

 

//To set duty cycle of PWMs Ton must be set in ticks

IfxStdIf_Timer* timer = IfxStdIf_PwmHl_getTimer(&pwmhl);
Ifx_TimerValue onTime[1]; // assume configured for 1 HL channel

onTime[0] = 600;

IfxGtm_Atom_PwmHl_setMode(&g_pwm, Ifx_Pwm_Mode_centerAligned);
IfxStdIf_Timer_disableUpdate(timer);
IfxStdIf_PwmHl_setOnTime(&pwmhl, onTime);
IfxStdIf_Timer_applyUpdate(timer);

 

}

 

 

 

The counters count firstly until 1200, then until 800 and then change direction so I have problems about setting of tON.

Where I can insert the command 

//To set up down counting
gtm_ptr->ATOM[0].CH0.CTRL.B.UDMODE=0x3;
gtm_ptr->ATOM[0].CH1.CTRL.B.UDMODE=3;

in order not to have delays between counters?(ccx and coutx)

 

For shift ccx channels how can I do (with all of them up down counters)?

0 Likes