Syncronizing a PWM to the EtherCAT distributed clock

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

cross mob
User17351
Level 1
Level 1
Hi,

I have an XMC4800 Auotmation Board V2 running an EtherCAT application controlling a thirdparty component via the eth port at a high data rate (125kHz). I'm using the PWM_CCU8 interrupt with a high priority to send the eth frames. I started and modified the ETHCAT_SSC_AUT_BASE_XMC48 example project.

I have the PWM_CCU8_0 component set with:
- PWM resolution [nsec]: 16
- Frequency [Hz]: 125000
- Channel 1 Duty Cycle [%]: 50

I am synchronizing the PWM to the Distributed clock by setting the PWM_CCU8_0 Event 0 parameters to:
- Function: External Start
- Trigger edge: Rising
And setting External Start to:
- Function control: Clear And Start Timer

I have also updated the EG_SYNC0 HW Signal Connections by adding a connection from iout to PWM_CCU8_0.ext_event0 so that the DC event will call both the SYNC0 handler and restart the PWM.


1) So as far as I can tell, the PWM signal clear/restart gets synced to the SYNC0 interrupt but I would like to confirm this with an oscilliscope. I tried to use the ISOFACE outputs to monitor the events, but as I suspected they are too slow. Are there any general purpose IO pins that I can use to monitor these?

I was thinking of using pin P4.3 which maps to pin 1 on the 6 pin user header, but I really need two pins (one for the sync0 event and another for the PWM event). Would it be possible to use the CAN TX/RX pins (P2.7 / P2.6)?


2) The EtherCAT master DC cycle period seems to be slightly faster than the XMC PWM pulse train, so I'm only getting 124 interrups per millisecond rather than 125. And of course that will change depending on the system the XMC4800 is connnected to. Has anyone got any ideas on how I can adjust the PWM_CCU8 frequency to match the DC cycle period?


Regards,
Graeme.
0 Likes
7 Replies
User17351
Level 1
Level 1
Hi,

I decided that since I wasn't using any SPI components I would suck it and see, so I configured and connected to pins 4.3 (user header select) and 3.11 (user header DOut / MOSI). It looks like my PWM is resetting nicely at the SYNC0 DC event.

I have changed the PWM_CCU8_0 event from "Period match" to "Compare 1 match while counting up" so that the event occurs 1/2 way through the PWM period rather than at the end and this helped stop the last IRQ being missed, but the last period is still short. So I'll still need to find a way to adjust the PWM frequency to match the DC cycle period.

Regards,
Graeme.
0 Likes
User17351
Level 1
Level 1
After a bit of time checking with the oscilloscope (and checking EtherCAT register 0x92C, System Time Difference) it looks like the variance is in the 10's of nano seconds, so I probably don't need to worry about adjusting the PWM frequency.
0 Likes
User18526
Level 2
Level 2
GraemeF wrote:
Hi,

I have an XMC4800 Auotmation Board V2 running an EtherCAT application controlling a thirdparty component via the eth port at a high data rate (125kHz). I'm using the PWM_CCU8 interrupt with a high priority to send the eth frames. I started and modified the ETHCAT_SSC_AUT_BASE_XMC48 example project.

I have the PWM_CCU8_0 component set with:
- PWM resolution [nsec]: 16
- Frequency [Hz]: 125000
- Channel 1 Duty Cycle [%]: 50

I am synchronizing the PWM to the Distributed clock by setting the PWM_CCU8_0 Event 0 parameters to:
- Function: External Start
- Trigger edge: Rising
And setting External Start to:
- Function control: Clear And Start Timer

I have also updated the EG_SYNC0 HW Signal Connections by adding a connection from iout to PWM_CCU8_0.ext_event0 so that the DC event will call both the SYNC0 handler and restart the PWM.


1) So as far as I can tell, the PWM signal clear/restart gets synced to the SYNC0 interrupt but I would like to confirm this with an oscilliscope. I tried to use the ISOFACE outputs to monitor the events, but as I suspected they are too slow. Are there any general purpose IO pins that I can use to monitor these?

I was thinking of using pin P4.3 which maps to pin 1 on the 6 pin user header, but I really need two pins (one for the sync0 event and another for the PWM event). Would it be possible to use the CAN TX/RX pins (P2.7 / P2.6)?


2) The EtherCAT master DC cycle period seems to be slightly faster than the XMC PWM pulse train, so I'm only getting 124 interrups per millisecond rather than 125. And of course that will change depending on the system the XMC4800 is connnected to. Has anyone got any ideas on how I can adjust the PWM_CCU8 frequency to match the DC cycle period?


Regards,
Graeme.


Hello,
See I'm trying to sync Pwm on 12 XMC4800 EtherCAT Relax Kit.
I currently have 3 PWMs generated on each card. But the goal is to get the Pwm synchronization of the 12 cards.
Understand how it's done, basically.
Perhaps, even though I am in Spain and you are just on the other side of the globe, you can give me an explanation or an example of how you have achieved it.
I would really appreciate it since I've been fighting with this for a few days.
Thank you very much for everything beforehand.
A greeting.
Roman
0 Likes
User17351
Level 1
Level 1
Hi,

Sorry, I have to go from memory here (our building had a fire recently and I lost my development computer and have not set up a new one yet).

The 12 XMC4800's will need to sync between each other by using Distributed Clocks. I don't know if the examples have been updated yet, the ones I downloaded were for SSC v5.11 but I was building for SSC v5.12 and some of the distributed clock configuration needed changing. Here is a forum entry where I mention what I did to get the distributed clock configuration correct for v5.12:
https://www.infineonforums.com/threads/10303-XMC4800-EtherCAT-Fatal-Sync-Error


Syncing the local PWMs to the distributed clock sync0 should occur by the settings I stated above:


I am synchronizing the PWM to the Distributed clock by setting the PWM_CCU8_0 Event 0 parameters to:
- Function: External Start
- Trigger edge: Rising
And setting External Start to:
- Function control: Clear And Start Timer

I have also updated the EG_SYNC0 HW Signal Connections by adding a connection from iout to PWM_CCU8_0.ext_event0 so that the DC event will call both the SYNC0 handler and restart the PWM.


I can't remember any more beyond that.


Regards,
Graeme.
0 Likes
User18526
Level 2
Level 2
GraemeF wrote:
Hi,

Sorry, I have to go from memory here (our building had a fire recently and I lost my development computer and have not set up a new one yet).

The 12 XMC4800's will need to sync between each other by using Distributed Clocks. I don't know if the examples have been updated yet, the ones I downloaded were for SSC v5.11 but I was building for SSC v5.12 and some of the distributed clock configuration needed changing. Here is a forum entry where I mention what I did to get the distributed clock configuration correct for v5.12:
https://www.infineonforums.com/threads/10303-XMC4800-EtherCAT-Fatal-Sync-Error


Syncing the local PWMs to the distributed clock sync0 should occur by the settings I stated above:



I can't remember any more beyond that.


Regards,
Graeme.


Hello,
I have tried that configuration of the external event but I find that the synchronization for the PWMs does not work. I don't understand why the clocks distributed in synchronization work in the Input / Outputs (I can observe it with an oscilloscope on a led).
Thank you very much for everything beforehand.
Your answers are very useful to me.
I am waiting.
A greeting.
0 Likes
User17351
Level 1
Level 1
Hi,

I don't recall anything else. Here is my generated pwm_ccu8_conf.c file. There maybe something in there you can compare to, otherwise you will probably need to start a new forum question.

pwm_ccu8_conf.c


#include "pwm_ccu8.h"

const XMC_CCU8_SLICE_COMPARE_CONFIG_t PWM_CCU8_0_timer_handle =
{
.timer_mode = (uint32_t)XMC_CCU8_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = (uint32_t)XMC_CCU8_SLICE_TIMER_REPEAT_MODE_REPEAT,
.shadow_xfer_clear = 0U,
.dither_timer_period = 0U,
.dither_duty_cycle = 0U,

.prescaler_mode = (uint32_t)XMC_CCU8_SLICE_PRESCALER_MODE_NORMAL,

.mcm_ch1_enable = 0U,
.mcm_ch2_enable = 0U,

.slice_status = (uint32_t)XMC_CCU8_SLICE_STATUS_CHANNEL_1,

.passive_level_out0 = (uint32_t)XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.passive_level_out1 = (uint32_t)XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.passive_level_out2 = (uint32_t)XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.passive_level_out3 = (uint32_t)XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,

.asymmetric_pwm = 0U,
#if !defined(CCU8V3)
.invert_out0 = 0U,
.invert_out1 = 0U,
.invert_out2 = 0U,
.invert_out3 = 1U,
#else
.selector_out0 = XMC_CCU8_SOURCE_OUT0_ST1,
.selector_out1 = XMC_CCU8_SOURCE_OUT1_ST1,
.selector_out2 = XMC_CCU8_SOURCE_OUT2_ST2,
.selector_out3 = XMC_CCU8_SOURCE_OUT3_INV_ST2,
#endif
.prescaler_initval = 1U,
.float_limit = 0U,
.dither_limit = 0U,
.timer_concatenation = 0U,
};


const XMC_CCU8_SLICE_EVENT_CONFIG_t PWM_CCU8_0_event0_config =
{
.mapped_input = XMC_CCU8_SLICE_INPUT_G,
.edge = XMC_CCU8_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE,
.level = XMC_CCU8_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_LOW,
.duration = XMC_CCU8_SLICE_EVENT_FILTER_DISABLED,
};

const XMC_CCU8_SLICE_EVENT_CONFIG_t PWM_CCU8_0_event1_config =
{
.mapped_input = XMC_CCU8_SLICE_INPUT_A,
.edge = XMC_CCU8_SLICE_EVENT_EDGE_SENSITIVITY_NONE,
.level = XMC_CCU8_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_LOW,
.duration = XMC_CCU8_SLICE_EVENT_FILTER_DISABLED,
};

const XMC_CCU8_SLICE_EVENT_CONFIG_t PWM_CCU8_0_event2_config =
{
.mapped_input = XMC_CCU8_SLICE_INPUT_A,
.edge = XMC_CCU8_SLICE_EVENT_EDGE_SENSITIVITY_NONE,
.level = XMC_CCU8_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_LOW,
.duration = XMC_CCU8_SLICE_EVENT_FILTER_DISABLED,
};

const XMC_CCU8_SLICE_DEAD_TIME_CONFIG_t PWM_CCU8_0_dt_config =
{
.enable_dead_time_channel1 = 0U,
.enable_dead_time_channel2 = 0U,
.channel1_st_path = 0U,
.channel1_inv_st_path = 0U,
.channel2_st_path = 0U,
.channel2_inv_st_path = 0U,
.div = (uint32_t)XMC_CCU8_SLICE_DTC_DIV_1,

.channel1_st_rising_edge_counter = 0U,
.channel1_st_falling_edge_counter = 0U,

.channel2_st_rising_edge_counter = 0U,
.channel2_st_falling_edge_counter = 0U,
};


const PWM_CCU8_CONFIG_t PWM_CCU8_0_config_handle =
{
.start_control = true,
.period_value = 575U,
.compare1_value = 288U,
.compare2_value = 288U,

.int_per_match = false,
.int_cmp1_match_up = true,
.int_cmp1_match_down = false,
.int_cmp2_match_up = false,
.int_cmp2_match_down = false,
.int_one_match_down = false,
.int_e0 = false,
.int_e1 = false,
.int_e2 = false,

.sr_per_match = XMC_CCU8_SLICE_SR_ID_0,
.sr_cmp1_match_up = XMC_CCU8_SLICE_SR_ID_3,
.sr_cmp1_match_down = XMC_CCU8_SLICE_SR_ID_3,
.sr_cmp2_match_up = XMC_CCU8_SLICE_SR_ID_0,
.sr_cmp2_match_down = XMC_CCU8_SLICE_SR_ID_0,
.sr_one_match_down = XMC_CCU8_SLICE_SR_ID_0,
.sr_e0 = XMC_CCU8_SLICE_SR_ID_0,
.sr_e1 = XMC_CCU8_SLICE_SR_ID_0,
.sr_e2 = XMC_CCU8_SLICE_SR_ID_0,

.event0_config_ptr = &PWM_CCU8_0_event0_config,
.event1_config_ptr = &PWM_CCU8_0_event1_config,
.event2_config_ptr = &PWM_CCU8_0_event2_config,

.ext_start_event = XMC_CCU8_SLICE_EVENT_0,
.ext_start_mode = XMC_CCU8_SLICE_START_MODE_TIMER_START_CLEAR,

.ext_stop_event = XMC_CCU8_SLICE_EVENT_NONE,
.ext_stop_mode = XMC_CCU8_SLICE_END_MODE_TIMER_STOP,

.ext_count_dir_event = XMC_CCU8_SLICE_EVENT_NONE,

.ext_gate_event = XMC_CCU8_SLICE_EVENT_NONE,

.ext_count_event = XMC_CCU8_SLICE_EVENT_NONE,

.ext_load_event = XMC_CCU8_SLICE_EVENT_NONE,
.ext_load_selector = XMC_CCU8_SLICE_COMPARE_CHANNEL_1,

.ext_mod_event = XMC_CCU8_SLICE_EVENT_NONE,
.ext_mod_mode = XMC_CCU8_SLICE_MODULATION_MODE_CLEAR_ST_OUT,
.ext_mod_sync = false,

.ext_override_edge_event = XMC_CCU8_SLICE_EVENT_NONE,

.ext_override_level_event = XMC_CCU8_SLICE_EVENT_NONE,

.ext_trap_enable = false,
.ext_trap_event = XMC_CCU8_SLICE_EVENT_NONE,
.ext_trap_sync = true,
.ext_trap_exit = XMC_CCU8_SLICE_TRAP_EXIT_MODE_AUTOMATIC,

.mcm_shadow_txfr_mode = XMC_CCU8_MULTI_CHANNEL_SHADOW_TRANSFER_SW_SLICE3,

.dt_config_ptr = &PWM_CCU8_0_dt_config,

#if (UC_SERIES != XMC45) /*STC register not available on XMC45xx devices */
.shadow_transfer_mode = XMC_CCU8_SLICE_SHADOW_TRANSFER_MODE_ONLY_IN_PERIOD_MATCH,
#endif

#if (UC_SERIES == XMC14) /*below feature available in XMC14xx devices */
.immediate_write = 0U,

.automatic_shadow_transfer = 0U,

.cascaded_shadow_txfr_enable = false,
#endif
.ccu8_cc8_slice_timer_ptr = &PWM_CCU8_0_timer_handle,

.gpio_ch1_out0_enable = false,
.gpio_ch1_out0_ptr = (XMC_GPIO_PORT_t *) NULL,
.gpio_ch1_out0_pin = 0U,
.gpio_ch1_out0_config_ptr = NULL,

.gpio_ch1_out1_enable = false,
.gpio_ch1_out1_ptr = (XMC_GPIO_PORT_t *) NULL,
.gpio_ch1_out1_pin = 0U,
.gpio_ch1_out1_config_ptr = NULL,

.gpio_ch2_out2_enable = false,
.gpio_ch2_out2_ptr = (XMC_GPIO_PORT_t *) NULL,
.gpio_ch2_out2_pin = 0U,
.gpio_ch2_out2_config_ptr = NULL,

.gpio_ch2_out3_enable = false,
.gpio_ch2_out3_ptr = (XMC_GPIO_PORT_t *) NULL,
.gpio_ch2_out3_pin = 0U,
.gpio_ch2_out3_config_ptr = NULL,
.global_ccu8_handle = (GLOBAL_CCU8_t*) &GLOBAL_CCU8_0,
};

PWM_CCU8_t PWM_CCU8_0 =
{
.config_ptr = &PWM_CCU8_0_config_handle,
.ccu8_module_ptr = (XMC_CCU8_MODULE_t*) CCU80_BASE,
.ccu8_slice_ptr = (XMC_CCU8_SLICE_t*) CCU80_CC83,
.kernel_number = 0U,
.slice_number = 3U,
.shadow_txfr_msk = (uint32_t)XMC_CCU8_SHADOW_TRANSFER_SLICE_3,
.dither_shadow_txfr_msk = (uint32_t)XMC_CCU8_SHADOW_TRANSFER_DITHER_SLICE_3,
.prescaler_shadow_txfr_msk = (uint32_t)XMC_CCU8_SHADOW_TRANSFER_PRESCALER_SLICE_3,

.state = PWM_CCU8_STATE_UNINITIALIZED,
.sym_duty1 = 5000U,
.sym_duty2 = 5000U,
.asym_duty = 0U,
.asym_shift = 0U,
};



Regards,
Graeme.
0 Likes
User18526
Level 2
Level 2
Hi GraemeF,

I have tried with the configuration you have sent me for pwm_ccu8_conf.c. However the following happens to me:
-I have observed that the pwm with that configuration does not work. I have detected what happens:
1. If I do not put the tick of start during initialization, the pwm does not work (attached capture).
2. Also, if I put this configuration of the external event as you mentioned in the first message, it doesn't work either (attached screenshot).
3. I also attach a screenshot of the HW Signal Connections, which in my opinion are as indicated in the second message.

Thanks for all beforehand.
I have tried in another line of the forum for someone to answer me, but unfortunately it has not been like that.4683.attach4684.attach4685.attach4683.attach4684.attach4685.attach
Your answers are being a great help to me.
I am awaiting your humble reply.
A greeting.
0 Likes