- Configuring LinuxCNC
- Advanced Configuration
- EtherCAT
- Ethercat compatible Encoder board tentative STM32F4 + LAN9252
Ethercat compatible Encoder board tentative STM32F4 + LAN9252
- Hakan
- Away
- Platinum Member
-
Less
More
- Posts: 1156
- Thank you received: 408
18 Dec 2025 09:44 - 18 Dec 2025 10:05 #340277
by Hakan
Replied by Hakan on topic Ethercat compatible Encoder board tentative STM32F4 + LAN9252
Dc synchronization for the slave is at the same time very simple and complex.
Your slave is now running in free run mode. As fast and frequently as possible it executes the ecat_slv()This function does the following
ecat_slv_poll() checks with the LAN9252 for events, mailboxes and other housekeeping things.
DIG_process() reads from the LAN9252 all pdos, sets user variables to the value of the pdos in cb_set_outputs(), calls a processing function if defined in application_hook, and finally captures user variables into pdos cb_get_inputs() and uploads them to the LAN9252.
The data is then sent to the ethercat master with the next packet passing by.
In free-run this happens at the speed of the processor and one can expect the read value to have been read inside some 0-300 microseconds of the packet passing by. Sometime this is enough, sometimes not. For my plasma cutter it is definitely enough with a voltage reading every so often. For precise motion control this normally is not enough. Predictability of exactly when the value is read is important here.
That's where DC synchronization comes in. In DC sync the LAN9252 will tell you the exact reference time by setting the SYNC0 line high (or low).
That's all actually.
It is now up to you to do something useful with that signal.
There isn't one and only one way to handle this. For the stepper generator cards I have a somewhat elaborate time measurement built in and there is quite a bit of processing at every cycle when the target position changes.
In this case though I think it is as easy as it can be. Just read the encoder counter, store it in a value. Kick off the DIG_process are quickly as possible to have the data sent over to linuxcnc. Hal should have the read value next servo cycle.
To do this, set up an interrupt handler on the SYNC0 line and read the encoder value. Set a flag to start the DIG_process.
Start with the config structure
So there are many changes. Make good use of git so you can come back.
In loop() I have tried to make it work with both Dc sync and free run by waiting for 5 cycles without sync0 interrupts and then start polling.
You can find this code in E3000 main.cpp that's where I copied it from.
Your slave is now running in free run mode. As fast and frequently as possible it executes the ecat_slv()
void loop(void)
{
ecat_slv();
}void ecat_slv(void)
{
ecat_slv_poll();
DIG_process(ESC_ALeventread(), DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
}ecat_slv_poll() checks with the LAN9252 for events, mailboxes and other housekeeping things.
DIG_process() reads from the LAN9252 all pdos, sets user variables to the value of the pdos in cb_set_outputs(), calls a processing function if defined in application_hook, and finally captures user variables into pdos cb_get_inputs() and uploads them to the LAN9252.
The data is then sent to the ethercat master with the next packet passing by.
In free-run this happens at the speed of the processor and one can expect the read value to have been read inside some 0-300 microseconds of the packet passing by. Sometime this is enough, sometimes not. For my plasma cutter it is definitely enough with a voltage reading every so often. For precise motion control this normally is not enough. Predictability of exactly when the value is read is important here.
That's where DC synchronization comes in. In DC sync the LAN9252 will tell you the exact reference time by setting the SYNC0 line high (or low).
That's all actually.
It is now up to you to do something useful with that signal.
There isn't one and only one way to handle this. For the stepper generator cards I have a somewhat elaborate time measurement built in and there is quite a bit of processing at every cycle when the target position changes.
In this case though I think it is as easy as it can be. Just read the encoder counter, store it in a value. Kick off the DIG_process are quickly as possible to have the data sent over to linuxcnc. Hal should have the read value next servo cycle.
To do this, set up an interrupt handler on the SYNC0 line and read the encoder value. Set a flag to start the DIG_process.
Start with the config structure
static esc_cfg_t config = {
.user_arg = NULL,
.use_interrupt = 0,
.watchdog_cnt = 150,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = NULL,
.esc_check_dc_handler = dc_checker,
};// Enable interrupts
void ESC_interrupt_enable(uint32_t mask)
{
// Enable interrupt for SYNC0 or SM2 or SM3
uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 | ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3;
if (mask & user_int_mask) {
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | (mask & user_int_mask));
ESC_ALeventmaskwrite(ESC_ALeventmaskread() &
~(ESCREG_ALEVENT_DC_SYNC0 | ESCREG_ALEVENT_SM3));
attachInterrupt(digitalPinToInterrupt(SYNC0), sync0Handler, RISING);
// Set LAN9252 interrupt pin driver as push-pull active high
uint32_t bits = 0x00000111;
ESC_write(0x54, &bits, 4);
// Enable LAN9252 interrupt
bits = 0x00000001;
ESC_write(0x5c, &bits, 4);
}
}// Disable interrupts
void ESC_interrupt_disable(uint32_t mask)
{
// Enable interrupt for SYNC0 or SM2 or SM3
uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 | ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3;
if (mask & user_int_mask) { // Disable interrupt from SYNC0 etc
ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(mask & user_int_mask));
detachInterrupt(digitalPinToInterrupt(SYNC0));
// Disable LAN9252 interrupt
uint32_t bits = 0x00000000;
ESC_write(0x5c, &bits, 4);
}
}// Setup of DC
uint16_t dc_checker(void)
{
// Indicate we run DC
ESCvar.dcsync = 1;
return 0;
}void sync0Handler(void)
{
ALEventIRQ = ESC_ALeventread();
serveIRQ = 1;
encoderCounter = <read encoder counter value here>;
}void loop(void)
{
uint64_t dTime;
if (serveIRQ) {
DIG_process(DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
serveIRQ = 0;
ESCvar.PrevTime = ESCvar.Time;
ecat_slv_poll();
}
dTime = longTime.extendTime(micros()) - irqTime;
if (dTime > 5000) // Don't run ecat_slv_poll when expecting to serve interrupt
ecat_slv();
}So there are many changes. Make good use of git so you can come back.
In loop() I have tried to make it work with both Dc sync and free run by waiting for 5 cycles without sync0 interrupts and then start polling.
You can find this code in E3000 main.cpp that's where I copied it from.
Last edit: 18 Dec 2025 10:05 by Hakan. Reason: Worst bbcode disaster yet
The following user(s) said Thank You: tommylight, vibram
Please Log in or Create an account to join the conversation.
- vibram
- Offline
- Premium Member
-
Less
More
- Posts: 82
- Thank you received: 1
19 Dec 2025 13:54 - 19 Dec 2025 13:54 #340303
by vibram
Replied by vibram on topic Ethercat compatible Encoder board tentative STM32F4 + LAN9252
I will not use DC yet as it sounds too complicated at this stage
I setup a Linuxcnc on my personal server. Everything is recognized but the counter is not working.
Its in PRE OP, maybe this is the issue
I setup a Linuxcnc on my personal server. Everything is recognized but the counter is not working.
Its in PRE OP, maybe this is the issue
Last edit: 19 Dec 2025 13:54 by vibram.
Please Log in or Create an account to join the conversation.
- Hakan
- Away
- Platinum Member
-
Less
More
- Posts: 1156
- Thank you received: 408
19 Dec 2025 23:54 #340323
by Hakan
Replied by Hakan on topic Ethercat compatible Encoder board tentative STM32F4 + LAN9252
Preop is fine, preop E is not.
General debug tool is to look at the last 10-20 or so lines from "sudo dmesg". Ethercat master always says there what is the problem. Not always easy to decode, still it gives some clues.
Many many times the eeprom and firmware have come out of sync. Like added something with eeprom_generator and didn't upload eeprom.
Also, does the counter update in Twincat?
If you get stuck and it won't work, please push the updated code to github and I can have a look.
General debug tool is to look at the last 10-20 or so lines from "sudo dmesg". Ethercat master always says there what is the problem. Not always easy to decode, still it gives some clues.
Many many times the eeprom and firmware have come out of sync. Like added something with eeprom_generator and didn't upload eeprom.
Also, does the counter update in Twincat?
If you get stuck and it won't work, please push the updated code to github and I can have a look.
The following user(s) said Thank You: vibram
Please Log in or Create an account to join the conversation.
- vibram
- Offline
- Premium Member
-
Less
More
- Posts: 82
- Thank you received: 1
20 Dec 2025 07:48 #340331
by vibram
Replied by vibram on topic Ethercat compatible Encoder board tentative STM32F4 + LAN9252
strange, i unplug everything and replug and itw works in linuxcnc too 
very happy about this
i will continue to see what can I achieve
thanks again !!!
I uploaded the github
very happy about this
i will continue to see what can I achieve
thanks again !!!
I uploaded the github
Please Log in or Create an account to join the conversation.
- Hakan
- Away
- Platinum Member
-
Less
More
- Posts: 1156
- Thank you received: 408
20 Dec 2025 09:21 #340334
by Hakan
Replied by Hakan on topic Ethercat compatible Encoder board tentative STM32F4 + LAN9252
Good. Has happened before. A total reset after eeprom update is usually a good idea.
I normally upload firmware on the fly, even when connected to linuxcnc. Much less sensitive.
I normally upload firmware on the fly, even when connected to linuxcnc. Much less sensitive.
The following user(s) said Thank You: vibram
Please Log in or Create an account to join the conversation.
- Configuring LinuxCNC
- Advanced Configuration
- EtherCAT
- Ethercat compatible Encoder board tentative STM32F4 + LAN9252
Time to create page: 0.072 seconds