Announcements

Equip yourself to optimize AURIX™ MCUs for Evs at the EV Webinar. Click here to register.

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

AURIX™ Forum Discussions

User22142
Level 2
Level 2
First solution authored
Hi everyone!

I have been trying to create 3 complementary pairs of PWM outputs with a high and low channel using the IfxGtm_Atom_PwmHl driver. The functionalities I need are deadtime and shifted output.
Before, I managed to create 3 complementary pairs of PWM output with deadtime using the CCU6 library, but since I also need to be able to shift the output relative to other channels, I believe this module is not suited anymore.
Thus, I land at the IfxGtm_Atom_PwmHl driver. Sadly, I can not generate PWM outputs at all. Can someone point me in the right direction?

Using only IfxGtm_Atom_PwmHl

#include "Ifx_Types.h"
#include "IfxGtm_Atom_PwmHl.h"
// #include "IfxGtm_Atom_Dtm_PwmHl.h"
#include "PWM_Atom.h"


// Configuration
#define FXUCLK_FREQUENCY 100e6 // FXU Clock base frequency, in Hertz
#define PWM_FREQUENCY 105e3 // PWM signal frequency, in Hertz
#define PWM_PERIOD (FXUCLK_FREQUENCY / PWM_FREQUENCY) // PWM signal period, in ticks
//#define DEADTIME 200e-9 // Dead time in seconds - 200 ns. When an
// unexpected deadtime of 2.55e-x occurs,
// the deadtime is bigger than allowed.

#define NUMBER_OF_CHANNELS 1

void init_stdif_pwmhl(void)
{
// prepare ccx coutx in advance
IfxGtm_Atom_ToutMapP ccx[NUMBER_OF_CHANNELS];
IfxGtm_Atom_ToutMapP coutx[NUMBER_OF_CHANNELS];

ccx[0] = &IfxGtm_ATOM0_0_TOUT0_P02_0_OUT;
coutx[0] = &IfxGtm_ATOM0_1_TOUT1_P02_1_OUT;

// init
// - clock
IfxGtm_enable(&MODULE_GTM); /* Enable GTM */
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_FXCLK); /* Enable the FXU clock */

// - timer
IfxGtm_Atom_Timer timer;
IfxGtm_Atom_Timer_Config timerConfig;
IfxGtm_Atom_Timer_initConfig(&timerConfig, &MODULE_GTM);

// g_atomConfig.pin.outputPin = &LED; /* Set LED as output */
// g_atomConfig.synchronousUpdateEnabled = TRUE; /* Enable synchronous update */
timerConfig.atom = ccx[0]->atom;
timerConfig.timerChannel = ccx[0]->channel; // but the channel of coutx[0] is also used! How to tell the driver?
// timerConfig.initPins = FALSE; // No idea what to use
timerConfig.base.frequency = PWM_FREQUENCY;
timerConfig.base.countDir = IfxStdIf_Timer_CountDir_up;
// timerConfig.base.trigger.enabled = TRUE; // 1/2 IfxCpu_Trap_busError
// timerConfig.base.trigger.outputEnabled = TRUE; // 2/2 IfxCpu_Trap_busError

IfxGtm_Atom_Timer_init(&timer, &timerConfig);
IfxGtm_Atom_Timer_run(&timer);

// - pwmHl
// IfxGtm_AtomDtm_PwmHl pwmHl;
// IfxGtm_Atom_Dtm_PwmHl_Config pwmHlConfig;
// IfxGtm_Atom_Dtm_PwmHl_initConfig(&pwmHlConfig);
IfxGtm_Atom_PwmHl pwmHl;
IfxGtm_Atom_PwmHl_Config pwmHlConfig;
IfxGtm_Atom_PwmHl_initConfig(&pwmHlConfig);

// pwmHlConfig.base.deadtime = 200e-9;
// pwmHlConfig.base.minPulse = 100e-9;
pwmHlConfig.base.channelCount = NUMBER_OF_CHANNELS;
// pwmHlConfig.base.emergencyEnabled = FALSE;
pwmHlConfig.base.outputMode = IfxPort_OutputMode_pushPull;
pwmHlConfig.base.outputDriver = IfxPort_PadDriver_cmosAutomotiveSpeed3;
pwmHlConfig.base.ccxOutputEnabled = TRUE;
pwmHlConfig.base.coutxOutputEnabled = TRUE;
// pwmHlConfig.base.ccxActiveState = Ifx_ActiveState_high;
// pwmHlConfig.base.coutxActiveState = Ifx_ActiveState_high;

// ccx and coutx configuration moved upwards

pwmHlConfig.timer = &timer;
pwmHlConfig.atom = timer.atomIndex;
pwmHlConfig.ccx = ccx;
pwmHlConfig.coutx = coutx;
// IfxGtm_Atom_Dtm_PwmHl_init(&pwmHl, &pwmHlConfig);
// IfxGtm_Atom_Dtm_PwmHl_setMode(&pwmHl, Ifx_Pwm_Mode_leftAligned);
IfxGtm_Atom_PwmHl_init(&pwmHl, &pwmHlConfig);
IfxGtm_Atom_PwmHl_setMode(&pwmHl, Ifx_Pwm_Mode_leftAligned);

// run
IfxGtm_Atom_Timer_run(&timer);

IfxGtm_Atom_Timer_disableUpdate(&timer);
IfxGtm_Atom_Timer_setSingleMode(&timer, FALSE);
IfxGtm_Atom_Timer_applyUpdate(&timer);

Ifx_TimerValue tOn = (uint32) PWM_PERIOD/2;
// Ifx_TimerValue tOn[2] = {PWM_PERIOD/2, PWM_PERIOD/2};
IfxGtm_Atom_PwmHl_setOnTime(&pwmHl, &tOn);
}



Using standard interface:

#include "Ifx_Types.h"
#include "IfxGtm_Atom_PwmHl.h"
// #include "IfxGtm_Atom_Dtm_PwmHl.h"
#include "PWM_Atom.h"


// Configuration
#define FXUCLK_FREQUENCY 100e6 // FXU Clock base frequency, in Hertz
#define PWM_FREQUENCY 105e3 // PWM signal frequency, in Hertz
#define PWM_PERIOD (FXUCLK_FREQUENCY / PWM_FREQUENCY) // PWM signal period, in ticks
//#define DEADTIME 200e-9 // Dead time in seconds - 200 ns. When an
// unexpected deadtime of 2.55e-x occurs,
// the deadtime is bigger than allowed.

#define NUMBER_OF_CHANNELS 1

void init_stdif_pwmhl(void)
{
// prepare ccx coutx in advance
IfxGtm_Atom_ToutMapP ccx[NUMBER_OF_CHANNELS];
IfxGtm_Atom_ToutMapP coutx[NUMBER_OF_CHANNELS];

ccx[0] = &IfxGtm_ATOM0_0_TOUT0_P02_0_OUT;
coutx[0] = &IfxGtm_ATOM0_1_TOUT1_P02_1_OUT;

// init
// - clock
IfxGtm_enable(&MODULE_GTM); /* Enable GTM */
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_FXCLK); /* Enable the FXU clock */

// - timer
IfxGtm_Atom_Timer timer;
IfxGtm_Atom_Timer_Config timerConfig;
IfxGtm_Atom_Timer_initConfig(&timerConfig, &MODULE_GTM);

// g_atomConfig.pin.outputPin = &LED; /* Set LED as output */
// g_atomConfig.synchronousUpdateEnabled = TRUE; /* Enable synchronous update */
timerConfig.atom = ccx[0]->atom;
timerConfig.timerChannel = ccx[0]->channel; // but the channel of coutx[0] is also used! How to tell the driver?
// timerConfig.initPins = FALSE; // No idea what to use
timerConfig.base.frequency = PWM_FREQUENCY;
timerConfig.base.countDir = IfxStdIf_Timer_CountDir_up;
// timerConfig.base.trigger.enabled = TRUE; // 1/2 IfxCpu_Trap_busError
// timerConfig.base.trigger.outputEnabled = TRUE; // 2/2 IfxCpu_Trap_busError

IfxGtm_Atom_Timer_init(&timer, &timerConfig);
IfxGtm_Atom_Timer_run(&timer);

// - pwmHl
// IfxGtm_AtomDtm_PwmHl pwmHl;
// IfxGtm_Atom_Dtm_PwmHl_Config pwmHlConfig;
// IfxGtm_Atom_Dtm_PwmHl_initConfig(&pwmHlConfig);
IfxGtm_Atom_PwmHl pwmHl;
IfxGtm_Atom_PwmHl_Config pwmHlConfig;
IfxGtm_Atom_PwmHl_initConfig(&pwmHlConfig);

// pwmHlConfig.base.deadtime = 200e-9;
// pwmHlConfig.base.minPulse = 100e-9;
pwmHlConfig.base.channelCount = NUMBER_OF_CHANNELS;
// pwmHlConfig.base.emergencyEnabled = FALSE;
pwmHlConfig.base.outputMode = IfxPort_OutputMode_pushPull;
pwmHlConfig.base.outputDriver = IfxPort_PadDriver_cmosAutomotiveSpeed3;
pwmHlConfig.base.ccxOutputEnabled = TRUE;
pwmHlConfig.base.coutxOutputEnabled = TRUE;
// pwmHlConfig.base.ccxActiveState = Ifx_ActiveState_high;
// pwmHlConfig.base.coutxActiveState = Ifx_ActiveState_high;

// ccx and coutx configuration moved upwards

pwmHlConfig.timer = &timer;
pwmHlConfig.atom = timer.atomIndex;
pwmHlConfig.ccx = ccx;
pwmHlConfig.coutx = coutx;
// IfxGtm_Atom_Dtm_PwmHl_init(&pwmHl, &pwmHlConfig);
// IfxGtm_Atom_Dtm_PwmHl_setMode(&pwmHl, Ifx_Pwm_Mode_leftAligned);
IfxGtm_Atom_PwmHl_init(&pwmHl, &pwmHlConfig);
IfxGtm_Atom_PwmHl_setMode(&pwmHl, Ifx_Pwm_Mode_leftAligned);

// run
// - setup stdif
IfxStdIf_Timer timer_stdif;
IfxGtm_Atom_Timer_stdIfTimerInit(&timer_stdif, &timer);
// IfxStdIf_Timer *timer_stdif = IfxStdIf_PwmHl_getTimer(&pwmHl_stdif);

IfxStdIf_PwmHl pwmHl_stdif;
IfxGtm_Atom_Dtm_PwmHl_stdIfPwmHlInit(&pwmHl_stdif, &pwmHl);

// - run stdif
IfxStdIf_Timer_run(&timer_stdif);

IfxStdIf_Timer_disableUpdate(&timer_stdif); // To allow timer changes

Ifx_TimerValue tOn = (uint32) PWM_PERIOD/2;

// Set trigger point
// IfxStdIf_Timer_setTrigger(&timer_stdif, tOn);

// Set period of cycle
Ifx_TimerValue period = (uint32) PWM_PERIOD;
IfxStdIf_Timer_setPeriod(&timer_stdif, period);

// Set duty cycle on time
IfxStdIf_PwmHl_setOnTime(&pwmHl_stdif, &tOn);

IfxStdIf_Timer_applyUpdate(&timer_stdif); // To implement timer changes
IfxStdIf_Timer_run(&timer_stdif);
}


Alternatively, the full source is attached.
0 Likes
1 Solution
User22142
Level 2
Level 2
First solution authored
For anyone trying themselves, I've uploaded an example project to learn from.

1. It uses a PWM timer channel for the counter reset in PWM output channels (IfxGtm_Atom_Timer),
2. allows to set phase-shifted signals in PWM output channels (IfxGtm_Atom_Pwm),
3. uses the deadtime module to create complementary signals with deadtime between the signals from the PWM output channels (IfxGtm_Atom_Dtm_PwmHl),
4. uses on-board LEDs for visual debugging.

The pins are configured for the TC367.

Good luck with your goal!

View solution in original post

0 Likes
4 Replies
teoBits
Employee
Employee
100 replies posted 50 replies posted 25 replies posted
Hello,

did you try using one of the trainings for GTM? I believe you have the TC367 device, therefore this should be fine for you: GTM_TOM_PWM_1_KIT_TC367_TFT with its tutorial

there are more trainings for GTM, you can search them with AURIX Development Studio when you import an AURIX project.
0 Likes
User22142
Level 2
Level 2
First solution authored
Hi teoBits, thanks for your response.

I have indeed tried the GTM_TOM_PWM_1_KIT_TC367_TFT tutorial, but sadly it only allowed me to set the frequency of a module and the duty cycle of a channel.
I based my work partly on this tutorial, but since I also need complementary channels, deadtime and a shifted output between different channels, this tutorial did not suffice for me.

Do you know of a tutorial which does this all? I believe there are none, sadly, so I was trying to create my own work using the iLLD documentation.
0 Likes
User22142
Level 2
Level 2
First solution authored
Perhaps Application Note AP32356, PWMAC (PWM Master of AC motor) would help, but we could not find the location of the project (GLT_PWMMAC_TC39x_golden). Could you provide us with a link toward myicp containing the project folder?
0 Likes
User22142
Level 2
Level 2
First solution authored
For anyone trying themselves, I've uploaded an example project to learn from.

1. It uses a PWM timer channel for the counter reset in PWM output channels (IfxGtm_Atom_Timer),
2. allows to set phase-shifted signals in PWM output channels (IfxGtm_Atom_Pwm),
3. uses the deadtime module to create complementary signals with deadtime between the signals from the PWM output channels (IfxGtm_Atom_Dtm_PwmHl),
4. uses on-board LEDs for visual debugging.

The pins are configured for the TC367.

Good luck with your goal!

0 Likes