- Configuring LinuxCNC
- Advanced Configuration
- EtherCAT
- Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
- Marcos DC
-
Topic Author
- Offline
- Senior Member
-
Less
More
- Posts: 54
- Thank you received: 29
27 Feb 2026 11:56 - 27 Feb 2026 12:16 #343595
by Marcos DC
Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid was created by Marcos DC
I’m currently restructuring my CiA402 integration to make it more modular and deterministic before going back to real EtherCAT hardware.
Instead of debugging everything at once (LinuxCNC motion + EtherCAT + CiA402 + drive behavior), I decided to isolate the CiA402 logic layer and validate it independently inside AXIS SIM.
Overall Structure (3 Layers)
I’m organizing the system into three logical layers:
1) Motion Layer (LinuxCNC)
Standard LinuxCNC motion/joint layer. No changes here.
2) CiA402 Adapter Layer (custom HAL component)
This is a dedicated HAL component responsible for:
It only works with abstract CiA402 objects (6040, 6041, 6060, 6061, 6064).The idea is that this logic should work identically whether the transport is:
Since I don’t have EtherCAT hardware connected right now, I implemented a simple CiA402 drive stub as a HAL component.
It simulates:
Relation to Existing Work (rodw, dbraun, EL8)I’ve reviewed:
Why Mask-Based Statusword Evaluation?
Instead of hard-coding something like “bit 12 = homing done”, I’m using:(statusword & mask) == valueExample:0x1400 (bits 10 + 12)The reason is simple:CiA402 allows vendor-specific interpretation and combination of bits.
Different drives report homing completion differently (sometimes bit 12 only, sometimes 10+12, sometimes additional bits).A mask/value approach allows:
Long-Term GoalThe final architecture should support:
Instead of debugging everything at once (LinuxCNC motion + EtherCAT + CiA402 + drive behavior), I decided to isolate the CiA402 logic layer and validate it independently inside AXIS SIM.
Overall Structure (3 Layers)
I’m organizing the system into three logical layers:
1) Motion Layer (LinuxCNC)
Standard LinuxCNC motion/joint layer. No changes here.
2) CiA402 Adapter Layer (custom HAL component)
This is a dedicated HAL component responsible for:
- Mode request (6060), e.g. Homing = 6, CSP = 8
- Waiting for 6061 (opmode_display) confirmation before proceeding
- Generating controlword transitions (6040), including homing start (bit 4)
- Mask/value-based evaluation of statusword (6041) for homing done
- Optional mask/value error detection
- Slaving pos_cmd to pos_fb during internal drive homing
It only works with abstract CiA402 objects (6040, 6041, 6060, 6061, 6064).The idea is that this logic should work identically whether the transport is:
- lcec (EtherCAT)
- some other fieldbus
- or a simulated drive
Since I don’t have EtherCAT hardware connected right now, I implemented a simple CiA402 drive stub as a HAL component.
It simulates:
- Opmode request → opmode_display with delay
- Rising edge detection of controlword bit 4
- Homing runtime (configurable cycles)
- Statusword “homing done” pattern (e.g. 0x1400 by default)
- Actual position feedback
- Proper gating on 6061
- Correct controlword sequencing
- Deterministic servo-thread behavior
- Statusword mask handling
- HAL wiring correctness
Relation to Existing Work (rodw, dbraun, EL8)I’ve reviewed:
- dbraun’s hal-cia402 implementation
- rodw’s cia402 component used with lcec
- The Leadshine EL8 integration example
- Can be tested without EtherCAT
- Is not tightly coupled to lcec internals
- Can support both internal drive homing and CSP cleanly
- Can later be extended for tandem gantry supervision (Y/Y0 squaring)
Why Mask-Based Statusword Evaluation?
Instead of hard-coding something like “bit 12 = homing done”, I’m using:(statusword & mask) == valueExample:0x1400 (bits 10 + 12)The reason is simple:CiA402 allows vendor-specific interpretation and combination of bits.
Different drives report homing completion differently (sometimes bit 12 only, sometimes 10+12, sometimes additional bits).A mask/value approach allows:
- Drive-specific configuration
- Future-proofing
- Cleaner abstraction
Long-Term GoalThe final architecture should support:
- CSP as primary motion mode
- Internal drive homing
- Tandem gantry (Y/Y0) with squaring
- Optional gantry delta supervision during homing
- Clear separation between CiA402 state logic and EtherCAT transport
- Best practices for controlword sequencing in CSP
- Clean homing mode transitions
- Gantry homing supervision patterns
- Mask-based statusword handling
Last edit: 27 Feb 2026 12:16 by Marcos DC.
The following user(s) said Thank You: andrax, NWE
Please Log in or Create an account to join the conversation.
- NWE
-
- Offline
- Elite Member
-
Less
More
- Posts: 171
- Thank you received: 44
27 Feb 2026 20:54 #343623
by NWE
Replied by NWE on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
Thanks!
I have not studied internals of CiA402 very deeply. However, I have some EtherCAT hardware here, I'd be willing to test your component on my drives once you get to that stage of the project.
I have not studied internals of CiA402 very deeply. However, I have some EtherCAT hardware here, I'd be willing to test your component on my drives once you get to that stage of the project.
Please Log in or Create an account to join the conversation.
- rodw
-
- Offline
- Platinum Member
-
Less
More
- Posts: 11729
- Thank you received: 3973
28 Feb 2026 02:32 #343631
by rodw
Replied by rodw on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
The bare bones CIA402 state machine looks like this:
You should add some timeouts for error handling
// uncomment pins if enabled
/* --- CiA 402 Controlword Commands --- */
#define CMD_SHUTDOWN 0x0006 // Transition to Ready to Switch On
#define CMD_SWITCH_ON 0x0007 // Transition to Switched On
#define CMD_DISABLE_VOLTAGE 0x0000 // Disable power stage
#define CMD_QUICK_STOP 0x0002 // Emergency deceleration
#define CMD_DISABLE_OPERATION 0x0007 // Disable motor drive
#define CMD_ENABLE_OPERATION 0x000F // Enable motor drive (Power On)
#define CMD_FAULT_RESET 0x0080 // Reset fault on rising edge
/* --- CiA 402 Statusword States --- */
// Masked with 0x006F to extract the specific state bits
#define STATE_NOT_READY 0x0000
#define STATE_SWITCH_ON_DISABLED 0x0040
#define STATE_READY_TO_SWITCH_ON 0x0021
#define STATE_SWITCHED_ON 0x0023
#define STATE_OPERATION_ENABLED 0x0027
#define STATE_QUICK_STOP_ACTIVE 0x0007
#define STATE_FAULT_REACTION_ACTIVE 0x000F
#define STATE_FAULT 0x0008
uint16_t update_cia402_state(config_data_t *d) { // receives status.word ( d->status.raw)
unsigned short currentState = d->status.raw & 0x006F; // removes all the bits we are not interested in
switch (currentState) {
case STATE_SWITCH_ON_DISABLED:
d->control.raw = CMD_SHUTDOWN;
break;
case STATE_READY_TO_SWITCH_ON:
d->control.raw = CMD_SWITCH_ON;
break;
case STATE_SWITCHED_ON:
d->control.raw = CMD_ENABLE_OPERATION;
break;
case STATE_OPERATION_ENABLED:
// Drive is active. Keep it enabled.
d->control.raw = CMD_ENABLE_OPERATION;
return 1;
break;
case STATE_FAULT:
// Attempt to clear the fault
d->control.raw = CMD_FAULT_RESET;
break;
case STATE_QUICK_STOP_ACTIVE:
// Move back to disabled if quick stop was triggered
d->control.raw = CMD_DISABLE_VOLTAGE;
break;
default:
// For any unknown or intermediate state, default to a safe "Voltage Disable"
d->control.raw = CMD_DISABLE_VOLTAGE;
break;
}
return 0;
}
You should add some timeouts for error handling
The following user(s) said Thank You: Marcos DC
Please Log in or Create an account to join the conversation.
- Hakan
- Offline
- Platinum Member
-
Less
More
- Posts: 1240
- Thank you received: 436
28 Feb 2026 08:38 #343641
by Hakan
Replied by Hakan on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
Have you looked at splitting the function one more step?
state-machine (bringing to op-enabled) : One component
op-mode module: Several components, csp, csv, homing, pv, pp, probing etc.
Looks appealing at first thought. Maybe switching between op-modes
and restoring position kills it though
state-machine (bringing to op-enabled) : One component
op-mode module: Several components, csp, csv, homing, pv, pp, probing etc.
Looks appealing at first thought. Maybe switching between op-modes
and restoring position kills it though
Please Log in or Create an account to join the conversation.
- Marcos DC
-
Topic Author
- Offline
- Senior Member
-
Less
More
- Posts: 54
- Thank you received: 29
28 Feb 2026 11:47 - 28 Feb 2026 11:54 #343647
by Marcos DC
Replied by Marcos DC on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
Hi @rodw, @Hakan and everyone,
Thanks a lot for the input — this is really helpful.
@rodw, your barebone CiA402 state handler is exactly what I needed to properly structure the lower layer. The statusword & 0x006F decoding and the minimal enable sequence up to Operation Enabled fit perfectly as a clean PDS manager.
@Hakan, yes — I’m now looking at splitting things one step further, exactly as you suggest.
The structure I’m converging to is:
To make sure I’m not inventing behavior, I’m using these two documents as formal references for the machine state and execution semantics:
Also, just a small note: during the week I mostly work on this code at my job — evenings are usually family time (kids at home), so progress sometimes comes in structured blocks rather than daily updates. But I’m moving forward steadily.
If anyone has suggestions on best practices for mode handover (especially CSP ⇄ Homing) or additional references worth reading, I’d really appreciate it. [/code][/code][/b][/code][/b][/code][/i][/i][/b][/b][/i][/code]
Thanks a lot for the input — this is really helpful.
@rodw, your barebone CiA402 state handler is exactly what I needed to properly structure the lower layer. The statusword & 0x006F decoding and the minimal enable sequence up to Operation Enabled fit perfectly as a clean PDS manager.
@Hakan, yes — I’m now looking at splitting things one step further, exactly as you suggest.
The structure I’m converging to is:
- PDS manager (CiA402 FSA layer)
- Based on rodw’s barebone logic
- Responsible only for bringing the drive from Switch On Disabled to Operation Enabled
- No homing, no CSP logic inside
- Exposes something like op_enabled
- Op-mode layer (separate modules)
- CSP
- CSV
- Homing
- PP / PV
- Probing, etc.
Each module only runs when op_enabled == true and after 6060/6061 handshake is confirmed.
- Application layer (drive-agnostic)
- Homing bit4 pulse generation
- done_mask / done_value evaluation
- Error mask/value
- All configurable via parameters (no hardcoded drive values)
- On mode entry: temporarily slave pos_cmd := pos_fb (freeze target) until the drive confirms the new mode via 6061
- Only then release control to avoid position jumps
- Same approach on exit back to CSP
To make sure I’m not inventing behavior, I’m using these two documents as formal references for the machine state and execution semantics:
- CiA 402 – Part 2 (Operation Modes & PDS Finite State Automaton)
- PLCopen Motion Control – Part 1 (FB Model & State Diagram)
Also, just a small note: during the week I mostly work on this code at my job — evenings are usually family time (kids at home), so progress sometimes comes in structured blocks rather than daily updates. But I’m moving forward steadily.
If anyone has suggestions on best practices for mode handover (especially CSP ⇄ Homing) or additional references worth reading, I’d really appreciate it.
[i][b][b][i][i][code][b][code][b][code][code][code][b][b] [/b][/b]
Last edit: 28 Feb 2026 11:54 by Marcos DC.
The following user(s) said Thank You: rodw, NWE
Please Log in or Create an account to join the conversation.
- rodw
-
- Offline
- Platinum Member
-
Less
More
- Posts: 11729
- Thank you received: 3973
28 Feb 2026 13:53 #343651
by rodw
Replied by rodw on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
I don;t know if you noticed but that procedure returns 1 when the machine s turned on so until it does that, you just wait... Then you do all the homing and other things
The following user(s) said Thank You: NWE
Please Log in or Create an account to join the conversation.
- Hakan
- Offline
- Platinum Member
-
Less
More
- Posts: 1240
- Thank you received: 436
28 Feb 2026 20:28 #343669
by Hakan
Replied by Hakan on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
How about if we don't blame the drive for moving by itself during homing,
and instead make "motion" understand that it should follow the position feedback?
and instead make "motion" understand that it should follow the position feedback?
Please Log in or Create an account to join the conversation.
- Marcos DC
-
Topic Author
- Offline
- Senior Member
-
Less
More
- Posts: 54
- Thank you received: 29
28 Feb 2026 23:37 #343671
by Marcos DC
Replied by Marcos DC on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
I already have a pure SIM validation setup working (HAL adapter + drive stub). The goals there were to make the logic deterministic and debug wiring/handshake issues before touching real EtherCAT hardware. In SIM I’ve validated:
6060/6061 opmode handshake
bit4 start pulse generation
done mask/value detection
stable statusword behavior (no flicker)
basic “homed” behavior (latched)
So the current work is no longer “does it wire up?”, but refining the architecture to match industrial semantics.
@rodw — yes, exactly: your procedure returning 1 at Operation Enabled is the clean gate. I’m using your barebone logic as the base for a dedicated PDS manager layer: until op_enabled == 1, nothing else (homing or motion modes) is allowed to run. Once op-enabled is reached, then we proceed with homing / CSP.
@Hakan — I also really like your point about not blaming the drive for moving during internal homing. That’s actually the main remaining behavior I’m refining now: instead of freezing targets in a hacky way, it seems cleaner to make the controller follow feedback during drive-internal homing.
So while homing is active:
motion/target follows feedback (pos_cmd := pos_fb)
when homing completes, CSP can resume with zero discontinuity (no jump)
Next steps:
implement the separate PDS manager (based on rodw’s barebone + timeouts + fault reset pulse)
implement mode modules (homing/CSP/etc.) gated by op_enabled and 6060/6061 confirmation
once the layers are solid in SIM, re-integrate with lcec + real hardware
If either of you sees a pitfall in the “motion follows feedback during internal homing” approach, I’d love to hear it — but it looks like the cleanest way to avoid discontinuities when returning to CSP.
6060/6061 opmode handshake
bit4 start pulse generation
done mask/value detection
stable statusword behavior (no flicker)
basic “homed” behavior (latched)
So the current work is no longer “does it wire up?”, but refining the architecture to match industrial semantics.
@rodw — yes, exactly: your procedure returning 1 at Operation Enabled is the clean gate. I’m using your barebone logic as the base for a dedicated PDS manager layer: until op_enabled == 1, nothing else (homing or motion modes) is allowed to run. Once op-enabled is reached, then we proceed with homing / CSP.
@Hakan — I also really like your point about not blaming the drive for moving during internal homing. That’s actually the main remaining behavior I’m refining now: instead of freezing targets in a hacky way, it seems cleaner to make the controller follow feedback during drive-internal homing.
So while homing is active:
motion/target follows feedback (pos_cmd := pos_fb)
when homing completes, CSP can resume with zero discontinuity (no jump)
Next steps:
implement the separate PDS manager (based on rodw’s barebone + timeouts + fault reset pulse)
implement mode modules (homing/CSP/etc.) gated by op_enabled and 6060/6061 confirmation
once the layers are solid in SIM, re-integrate with lcec + real hardware
If either of you sees a pitfall in the “motion follows feedback during internal homing” approach, I’d love to hear it — but it looks like the cleanest way to avoid discontinuities when returning to CSP.
The following user(s) said Thank You: rodw, NWE
Please Log in or Create an account to join the conversation.
- Hakan
- Offline
- Platinum Member
-
Less
More
- Posts: 1240
- Thank you received: 436
01 Mar 2026 08:17 #343682
by Hakan
Replied by Hakan on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
A new homing method, external_homing. Can box in motion with limits and time.
A variant could be external_synchronized_homing for gantry homing.
With additional limits on start positions maybe and max difference in position.
And so on. Done by motion/motmod. Communicates with pins to the drive component as usual.
Maybe also a new freewheeling mode and pin for motion/motmod.
For opmodes that disconnects the position.
Position is usually right from the drive even when opmode changes.
But you don't need to control the position, just follow it.
I think one need to go over all opmode switches and see which situations can appear.
A variant could be external_synchronized_homing for gantry homing.
With additional limits on start positions maybe and max difference in position.
And so on. Done by motion/motmod. Communicates with pins to the drive component as usual.
Maybe also a new freewheeling mode and pin for motion/motmod.
For opmodes that disconnects the position.
Position is usually right from the drive even when opmode changes.
But you don't need to control the position, just follow it.
I think one need to go over all opmode switches and see which situations can appear.
Please Log in or Create an account to join the conversation.
- Marcos DC
-
Topic Author
- Offline
- Senior Member
-
Less
More
- Posts: 54
- Thank you received: 29
01 Mar 2026 10:10 - 01 Mar 2026 10:20 #343684
by Marcos DC
Replied by Marcos DC on topic Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
Hi Hakan,
That’s a very interesting direction.
An external_homing method handled by motion/motmod — with limits, time supervision and synchronized gantry constraints — would definitely be a robust long-term solution. The idea of a freewheeling/follow-feedback mode in motion is also conceptually very clean.
However, changes in motion/motmod are a much larger step. They require core discussion, review and consensus, and can easily turn into a longer-term architectural effort.
Right now my plan is to stay focused on the original scope of this thread:
That’s a very interesting direction.
An external_homing method handled by motion/motmod — with limits, time supervision and synchronized gantry constraints — would definitely be a robust long-term solution. The idea of a freewheeling/follow-feedback mode in motion is also conceptually very clean.
However, changes in motion/motmod are a much larger step. They require core discussion, review and consensus, and can easily turn into a longer-term architectural effort.
Right now my plan is to stay focused on the original scope of this thread:
- ]Finalize a clean modular CiA402 stack (PDS manager + opmode modules + drive-agnostic app layer)
- Validate everything in SIM
- Then test and stabilize it on real hardware
My short-term goal is to get it to the point where it becomes “boringly stable” on at least one real drive. Once that is achieved, I think it makes much more sense to revisit motion-level enhancements like external_homing or a freewheeling mode.
Otherwise we risk expanding the scope too early and spending a lot of time discussing architecture before finishing the current layer separation.
If we decide to explore motion-level changes seriously, I think it would be better to open a dedicated thread for that topic, since it would likely require deeper discussion and take some time.
For now, I’d prefer to close the CiA402 separation work first and build from there.
— Marcos
- Then test and stabilize it on real hardware
- Validate everything in SIM
Last edit: 01 Mar 2026 10:20 by Marcos DC.
Please Log in or Create an account to join the conversation.
- Configuring LinuxCNC
- Advanced Configuration
- EtherCAT
- Separating CiA402 Logic from EtherCAT (lcec): Modular Adapter + Drive Stub Valid
Time to create page: 0.169 seconds