Skip to content

Await acks for write SDO, filter endpoint IDs#22

Open
solomondg wants to merge 1 commit into
masterfrom
feature/await-sdo-acks
Open

Await acks for write SDO, filter endpoint IDs#22
solomondg wants to merge 1 commit into
masterfrom
feature/await-sdo-acks

Conversation

@solomondg

Copy link
Copy Markdown
Contributor

The ODrive sends a TxSdo in response to any RxSdo, writes included. setEndpoint() was firing the write and returning true unconditionally, with no confirmation it landed.

This makes setEndpoint() wait for that ACK. Mirrors getEndpoint(): it gains an optional timeout_ms = 10 param and returns true only when an acknowledgment arrives whose echoed Endpoint_ID matches the write (timeout_ms = 0 keeps the old behavior).

getEndpoint() now also discards any TxSdo that echoes a different endpoint than requested.

@solomondg solomondg requested a review from samuelsadok June 19, 2026 06:43
@solomondg solomondg force-pushed the feature/await-sdo-acks branch from 2996d1f to 3c70a7f Compare June 19, 2026 06:53

@samuelsadok samuelsadok left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/ODriveCAN.h
// Value to write
memcpy(&data[4], &value, sizeof(T));

requested_msg_id_ = 0x005; // Await TxSdo acknowledgment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's only write this when timeout_ms != 0. Then we don't have to reset it below. Feels cleaner not to touch the state at all if we don't have to.

Comment thread src/ODriveCAN.h
* @return true if the ODrive acknowledged the write (or timeout_ms == 0),
* false if no matching TxSdo was received before the timeout.
*
* The ODrive replies with a TxSdo message in response to any RxSdo,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TxSdo ack was introduced in fw 0.6.11. From changelog:

CANSimple: confirmation messages for write SDO messages

So we should mention here that this requires fw 0.6.11, and that for older firmware, fire-and-forget can be used.

Comment thread src/ODriveHardwareCAN.hpp
// Flush pending RX messages before writing. On polling-based platforms (e.g.
// Arduino Uno R4) the single TX mailbox may report busy if the CAN
// controller hasn't had a chance to process events. This mirrors the
// can_intf.events() call in the FlexCAN (Teensy) adapter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The can_intf.events() call says // TODO: is this really needed?. So we should remove that TODO and reference here.

But I have to say I find it a bit unclean in both cases, and a bit weird that the RX path is so entangled with the TX path. Was this experimentally confirmed (plz link)? Can you point to the relevant code in the platform driver stack that shows this behavior?

Comment thread src/ODriveHardwareCAN.hpp
data,
};
return can_intf.write(msg) >= 0;
return can_intf.write(msg) > 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this change is unnecessary?
https://github.com/arduino/ArduinoCore-API/blob/master/api/HardwareCAN.h#L90C6-L90C109

@return 1 if the message was enqueued, an _implementation defined_ error code < 0 if there was an error

So we should leave it as-is, unless this is confirmed to fix an issue with a non-compliant platform (lest we break another non-compliant platform).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants