Skip to content

drivers: stepper: introduce step-dir functions in stepper api to facilitate implementing motion controllers as device drivers #91979

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jilaypandya
Copy link
Member

@jilaypandya jilaypandya commented Jun 21, 2025

This PR aims to facilitate implementation of stepper motion controllers as device drivers. Hence two new functions as added, namely step and dir.

Note:

  • This is an intermediate step. The next step would be to create a stepper_step_dir_api with functions (enable/disable, step/dir, set_microstep_resolution) as mentioned in the RFC.
  • Test suite has been updated
    1. Multiple Stepper drivers have been dropped from the stepper api test suite, since the concern is to test zephyr_stepper_motion_controller with stepper_api which consumes the "step-dir" interface in the future.

Side effects:

  1. A lot of common code is refactored out and the stepper step-dir or h-bridge based drivers only do what the ic supports. i.e. enable/disable, set/get us resolution, step/dir.

  2. Drv84xx handles fault events as of now, which is good. However, handling of fault event has to be refactored as mentioned in the RFC Split Stepper Motion Controller <-> Stepper Driver #89786 .
    Introduce set_fault_event_callback, remove fault_event from the current stepper_event enum and rename stepper_event_callback to stepper_motion_control_event_callback.

This will have to be rebased on main, once this PR #91909 is merged.

@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch from 0429ffb to 5c9c369 Compare June 21, 2025 22:35
@jilaypandya jilaypandya changed the title wip drivers: stepper: introduce step-dir functions in stepper api to facilitate implementing motion controllers as device drivers Jun 21, 2025
@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch 9 times, most recently from 676d5fd to 1d51595 Compare June 22, 2025 12:25
Copy link
Collaborator

@faxe1008 faxe1008 left a comment

Choose a reason for hiding this comment

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

Small little pass, will do some in depth review later on :^)


static int tmc22xx_stepper_enable(const struct device *dev)
{
const struct tmc22xx_config *config = dev->config;

LOG_DBG("Enabling Stepper motor controller %s", dev->name);
return gpio_pin_set_dt(&config->enable_pin, 1);
return gpio_pin_set_dt(&config->enable_pin, 0);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Generally you would set this to 1 and change the actual output to be active low via devicetree

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah that makes sense :) Thanks :^)

Ping @andre-stefanov

Choose a reason for hiding this comment

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

yes this is exactly what i came up with in my implementation in the end. It is a bit inconvenient because the user of e.g. tmc2209 has to know this inverted EN logic during DTS definition instead of just saying "i define the pins, the driver knows which level has to be used for enable/disable". But unfortunately i could not provide gpio port/pin references without output level flag in DTS so i left it as faxe is proposing.

}

static int tmc22xx_stepper_disable(const struct device *dev)
{
const struct tmc22xx_config *config = dev->config;

LOG_DBG("Disabling Stepper motor controller %s", dev->name);
return gpio_pin_set_dt(&config->enable_pin, 0);
return gpio_pin_set_dt(&config->enable_pin, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@@ -121,7 +120,6 @@ static int a4979_stepper_set_micro_step_res(const struct device *dev,
case STEPPER_MICRO_STEP_4:
m0_value = 0;
m1_value = 1;
break;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this was an accident

Copy link
Member Author

Choose a reason for hiding this comment

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

yep :)

const struct gpio_stepper_config *config = dev->config;

LOG_DBG("Initializing %s gpio_stepper with %d pin", dev->name, NUM_CONTROL_PINS);
for (uint8_t n_pin = 0; n_pin < NUM_CONTROL_PINS; n_pin++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Checking readyness via gpio_ready_dt

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch 2 times, most recently from 9ebf11f to d3c27b5 Compare June 22, 2025 13:17
@jilaypandya jilaypandya added this to the v4.3.0 milestone Jun 22, 2025
@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch 2 times, most recently from 3b94e61 to 703d030 Compare June 22, 2025 14:16
#include <zephyr/sys/__assert.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(gpio_stepper_motor_controller, CONFIG_STEPPER_LOG_LEVEL);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: gpio_stepper_motor_controller, just a bit too long :)

@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch 4 times, most recently from 4a60ace to e4b6c2d Compare June 22, 2025 15:31
@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch 4 times, most recently from 84392f5 to 060b707 Compare June 22, 2025 17:35

Choose a reason for hiding this comment

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

since the step/dir interface is extracted as a reusable component by now, we could also extract the corresponding bindings for gpio phandles into zephyr,stepper-step-dir.yaml

Copy link
Member Author

Choose a reason for hiding this comment

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

that would be en-pin, step-pin, dir-pin, m0/m1/m2-gpios and maybe fault pin as well. Hmm sounds fair. Is it okay if we do this in an upcoming patch, since I am going to separate the relevant functions in stepper-step-dir-api :)?

Copy link
Member Author

Choose a reason for hiding this comment

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

we might need a patch in between for tmc22xx as well, since it handles the mix-gpios in a slight different pattern, but we can do it.

Comment on lines +255 to +261
update_remaining_steps(dev);
stepper_step(config->stepper);

Choose a reason for hiding this comment

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

call of stepper_step should be executed as early as possible during the ISR callback to avoid jitter due to different calculation overhead of update_remaining_steps.

Suggested change
update_remaining_steps(dev);
stepper_step(config->stepper);
stepper_step(config->stepper);
update_remaining_steps(dev);


data->dev = dev;

if (config->timing_source->init) {

Choose a reason for hiding this comment

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

we should return an error if config->timing_source->init evaluates to false because in this case the controller wont be usable (and we have the worker timing source as fallback for that reason).

@@ -85,7 +85,7 @@ properties:

child-binding:
include:
- name: stepper-controller.yaml
- name: stepper.yaml

Choose a reason for hiding this comment

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

i think only en-gpios and invert-direction should be allowed for this driver. Looking into the specs i dont see other features available over gpio (microstep config, step/dir etc)

Copy link
Member Author

Choose a reason for hiding this comment

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

you can use the tmc50xx with step-dir as well.
and micro step config doesn't necessarily have to be via gpios :). For instance, in h-bridge drivers we kinda control It using the half-step-lut.

Choose a reason for hiding this comment

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

oh ok. probably the model i checked was an exception and did not have those pins exposed

Comment on lines 310 to 311
* Counting the number of steps is the responsibility of the stepper motion controller,
* which will call this function for each step.

Choose a reason for hiding this comment

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

Suggested change
* Counting the number of steps is the responsibility of the stepper motion controller,
* which will call this function for each step.
* This function will not increment/decrement any position related data. Doing so
* is responsibility of the caller (e.g. stepper motion controller).

Copy link
Member Author

Choose a reason for hiding this comment

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

your text sounds better :)

Copy link
Member Author

Choose a reason for hiding this comment

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

done

* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_set_fault_callback(const struct device *dev,

Choose a reason for hiding this comment

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

how is this different from set_event_callback ? also i don't see this API being implemented or used anywhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

I have implemented in drv84xx, so quite a few step drivers have fault pin, this is to accommodate that particular use-case for now, we can maybe handle this more gracefully in the next patch :)

Choose a reason for hiding this comment

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

would that really be a separate callback then or can we define just another stepper event for this? (similar to endstops, stallguard etc)

Copy link
Member Author

Choose a reason for hiding this comment

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

This is what I am aiming for :) #89786 (comment)

@@ -14,4 +22,12 @@
<&gpiob 0 GPIO_ACTIVE_HIGH>, /* D10 */
<&gpioa 7 GPIO_ACTIVE_HIGH>; /* D11 */
};

stepper_motion_control: stepper_motion_control {

Choose a reason for hiding this comment

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

Suggested change
stepper_motion_control: stepper_motion_control {
gpio_stepper_motion_control: stepper_motion_control {

Copy link
Member Author

Choose a reason for hiding this comment

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

because it toggles step pin?

Choose a reason for hiding this comment

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

it's just because it is a motion controller for the gpio stepper. if you have multiple steppers in a project, you will have to distinguish them. so i proposed to name them after the stepper they control.

Copy link
Member Author

Choose a reason for hiding this comment

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

I will be naming it as the driver itself zephyr_stepper_motion_control.

@@ -1,11 +1,19 @@
/ {
aliases {
stepper = &gpio_stepper;
stepper-motion-control = &stepper_motion_control;

Choose a reason for hiding this comment

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

Suggested change
stepper-motion-control = &stepper_motion_control;
stepper-motion-control = &gpio_stepper_motion_control;

Copy link
Member Author

Choose a reason for hiding this comment

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

I will be naming it as zephyr_stepper_motion_control to reflect the device driver.

@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch from 060b707 to e2dd143 Compare June 22, 2025 19:16
@jilaypandya jilaypandya marked this pull request as ready for review June 22, 2025 19:21
@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch 2 times, most recently from 24fc13e to ba6069e Compare June 22, 2025 20:44
With the introduction of these two functions, now
motion controllers can be directly implemented on the
device driver level. This allows different motion
controllers to consume various stepper drivers allowing
for further upstream as well as downstream stepper
motion controllers to be implemented

Signed-off-by: Jilay Pandya <[email protected]>
Add fault handling in drv84xx using a fault cb mechanism

Signed-off-by: Jilay Pandya <[email protected]>
@jilaypandya jilaypandya force-pushed the feature/introduce-step-dir-functions branch from ba6069e to 89f019b Compare June 22, 2025 21:23
Removing tests which are already covered in stepper api test
suite or are outdated and have no relevance in accordance to
the recent changes in the api

Signed-off-by: Jilay Pandya <[email protected]>
Copy link

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.

4 participants