Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAN termination GPIO support #83422

Conversation

KozhinovAlexander
Copy link
Collaborator

@KozhinovAlexander KozhinovAlexander commented Dec 27, 2024

The functionality for termination gpio is used on
some boards like ST's b-g431b-esc1 motor controller board. This feature is also supported by SocketCAN in linux.

UPD:
There is only one open question regarding implementation: Would be can_mcan API the best way to propagate this functionality to the application?

* @brief Callback API upon setting CAN transceiver termination
* See @a can_transceiver_term() for argument description
*/
typedef int (*can_transceiver_term_t)(const struct device *dev, bool state);
Copy link
Member

Choose a reason for hiding this comment

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

should this be something like temination_enable and termination_disable? for symmetry with the two above

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Could be done, but ends up with one function more in the API. Except the "cosmetic" symmetry would be here another reason for it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@KozhinovAlexander KozhinovAlexander force-pushed the can_transceiver_term_gpio branch from 95a6406 to 3cbfa29 Compare December 27, 2024 18:58
@KozhinovAlexander
Copy link
Collaborator Author

KozhinovAlexander commented Dec 27, 2024

With the last commit I've added now can_term_set() function to can.h s.t. an application can access corresponding gpios functionality if available.

@alexanderwachter
Copy link
Member

alexanderwachter commented Dec 27, 2024

I don't see a reason for a disable in the API. To be honest, I don't even see a benefit over a gpio hog. This node is the last one on the bus, it needs to enable the termination immediately or the other nodes on the bus cannot communicate. If you disable the termination, you stop the whole bus.

Edit:
Ok, the enable could come from a setting.

@KozhinovAlexander KozhinovAlexander force-pushed the can_transceiver_term_gpio branch from 3cbfa29 to 5cdcb2a Compare December 27, 2024 19:26
@alexanderwachter
Copy link
Member

alexanderwachter commented Dec 27, 2024

UPD:
There is only one open question regarding implementation: Would be can_mcan API the best way to propagate this functionality to the application?

The only useful application I see at the moment is some nonvolatile configuration check at runtime.
If it is board specific (device tree, always on) you can hard wire.

* @retval 0 if successful.
* @retval -EIO General input/output error, failed to toggle GPIO device.
*/
__syscall int can_termination_enable(const struct device *dev);
Copy link
Member

Choose a reason for hiding this comment

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

In my opinion, termination is not a property of the can controller, but from the bus. There is no need to enable/disable on a state change of the controller.

I would only add an enable to the can transceiver if we agree to add a gpio controlled termination.

The termination is most probably not even part of the transceiver.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thank you. I could remove it from API of course.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I removed it from can.h (e.g. CAN API)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The termination is most probably not even part of the transceiver.

Good point. I see termination as part of physical transport layer and transceiver a tool to control it. Thus maybe it is not wrong to have termination gpis control within phy.

@KozhinovAlexander
Copy link
Collaborator Author

UPD:
There is only one open question regarding implementation: Would be can_mcan API the best way to propagate this functionality to the application?

The only useful application I see at the moment is some nonvolatile configuration check at runtime.
If it is board specific (device tree, always on) you can hard wire.

Thanks. It is a good point with hard-wire. I missed it. I will remove the functionality from can.h (e.g. CAN API).
I think my first implementation would be leaving it inside transceiver within init function.
But I still have a question about termination behavior: SocketCAN in Linux allows enabling/disabling CAN bus termination. I understand it is maybe not standardized CAN bus behavior. But how to handle such scenarios?

The functionality for termination gpio is used on
some boards like ST's b-g431b-esc1 motor controller board.
This feature is also supported by SocketCAN in linux.

Signed-off-by: Alexander Kozhinov <[email protected]>
@KozhinovAlexander KozhinovAlexander force-pushed the can_transceiver_term_gpio branch from 5cdcb2a to 502e76c Compare December 27, 2024 21:17
Copy link
Member

@henrikbrixandersen henrikbrixandersen left a comment

Choose a reason for hiding this comment

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

In my opinion, termination is not a property of the can controller, but from the bus. There is no need to enable/disable on a state change of the controller.

I wholeheartedly agree.

The termination is most probably not even part of the transceiver.

Again, I wholeheartedly agree.

CAN termination resistors are not physically controlled via the CAN controller, nor via the CAN transceiver (and certainly not via the group of GPIOs used for controlling a GPIO-controlled CAN transceiver, which is just a subset of the available CAN transceiver types out there).

The CAN bus termination resistors are a property of the CAN bus. If a board allows turning CAN termination resistors on/off - or even allow selecting their resistance value, which is not covered by your proposal here - that would be a function of the board, not the board's CAN controller, not the board's CAN transceiver. One way to reflect this on the board-level in Zephyr could be to use a dedicated, board-specific GPIO hog or even represent it as a GPIO-controlled regulator. Control of these resistors does not belong in the CAN controller/tranceiver APIs (I know the Linux kernel put it there, but it is misplaced, if you ask me - and Zephyr is not Linux).

@KozhinovAlexander I appreciate your eagerness in wanting to contribute to the Zephyr CAN subsystem, but I really wish you would start by opening an RFC instead of sketching up a solution based on immediate PR review comments. The RFC process often leads to a better solution and can save both your and the reviewer's time compared to the many back and forth changes, that has already happened on this PR during the last 10 hours.

@KozhinovAlexander
Copy link
Collaborator Author

In my opinion, termination is not a property of the can controller, but from the bus. There is no need to enable/disable on a state change of the controller.

I wholeheartedly agree.

The termination is most probably not even part of the transceiver.

Again, I wholeheartedly agree.

CAN termination resistors are not physically controlled via the CAN controller, nor via the CAN transceiver (and certainly not via the group of GPIOs used for controlling a GPIO-controlled CAN transceiver, which is just a subset of the available CAN transceiver types out there).

The CAN bus termination resistors are a property of the CAN bus. If a board allows turning CAN termination resistors on/off - or even allow selecting their resistance value, which is not covered by your proposal here - that would be a function of the board, not the board's CAN controller, not the board's CAN transceiver. One way to reflect this on the board-level in Zephyr could be to use a dedicated, board-specific GPIO hog or even represent it as a GPIO-controlled regulator. Control of these resistors does not belong in the CAN controller/tranceiver APIs (I know the Linux kernel put it there, but it is misplaced, if you ask me - and Zephyr is not Linux).

@KozhinovAlexander I appreciate your eagerness in wanting to contribute to the Zephyr CAN subsystem, but I really wish you would start by opening an RFC instead of sketching up a solution based on immediate PR review comments. The RFC process often leads to a better solution and can save both your and the reviewer's time compared to the many back and forth changes, that has already happened on this PR during the last 10 hours.

Thanks for bringing it to together. I am fine with an RFC. Will do it next time first :)

@KozhinovAlexander
Copy link
Collaborator Author

@alexanderwachter @henrikbrixandersen Thank you for your time and reviews. I close this PR, since the functionality is not a part of CAN-Controller and CAN-Transceiver.

@KozhinovAlexander KozhinovAlexander deleted the can_transceiver_term_gpio branch December 27, 2024 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants