Repository: jilaypandya/zephyr
Pull request #3: drivers: stepper_control: integrate timing source
Author: login: jilaypandya
Created: 2025-05-13T20:52:44Z | Merged: 2025-05-14T21:21:29Z

This commit integrates timing source from by refactoring it out from step_dir lib

ping @faxe1008 @dipakgmx @andre-stefanov 


Diff:
diff --git a/drivers/stepper/adi_tmc/tmc22xx.c b/drivers/stepper/adi_tmc/tmc22xx.c
index fb73dc35fc28d..e0d65b95bbf08 100644
--- a/drivers/stepper/adi_tmc/tmc22xx.c
+++ b/drivers/stepper/adi_tmc/tmc22xx.c
@@ -150,15 +150,8 @@ static int tmc22xx_stepper_init(const struct device *dev)
 static DEVICE_API(stepper, tmc22xx_stepper_api) = {
 	.enable = tmc22xx_stepper_enable,
 	.disable = tmc22xx_stepper_disable,
-	.move_by = step_dir_stepper_common_move_by,
-	.is_moving = step_dir_stepper_common_is_moving,
-	.set_reference_position = step_dir_stepper_common_set_reference_position,
-	.get_actual_position = step_dir_stepper_common_get_actual_position,
-	.move_to = step_dir_stepper_common_move_to,
-	.set_microstep_interval = step_dir_stepper_common_set_microstep_interval,
-	.run = step_dir_stepper_common_run,
-	.stop = step_dir_stepper_common_stop,
-	.set_event_callback = step_dir_stepper_common_set_event_callback,
+	.step = step_dir_stepper_common_step,
+	.set_direction = step_dir_stepper_common_set_direction,
 	.set_micro_step_res = tmc22xx_stepper_set_micro_step_res,
 	.get_micro_step_res = tmc22xx_stepper_get_micro_step_res,
 };
diff --git a/drivers/stepper/allegro/a4979.c b/drivers/stepper/allegro/a4979.c
index f08dbd61d37bf..8aa31d7bd6920 100644
--- a/drivers/stepper/allegro/a4979.c
+++ b/drivers/stepper/allegro/a4979.c
@@ -93,7 +93,6 @@ static int a4979_stepper_disable(const struct device *dev)
 		return ret;
 	}
 
-	config->common.timing_source->stop(dev);
 	data->enabled = false;
 
 	return 0;
@@ -152,42 +151,6 @@ static int a4979_stepper_get_micro_step_res(const struct device *dev,
 	return 0;
 }
 
-static int a4979_move_to(const struct device *dev, int32_t target)
-{
-	struct a4979_data *data = dev->data;
-
-	if (!data->enabled) {
-		LOG_ERR("Failed to move to target position, device is not enabled");
-		return -ECANCELED;
-	}
-
-	return step_dir_stepper_common_move_to(dev, target);
-}
-
-static int a4979_stepper_move_by(const struct device *dev, const int32_t micro_steps)
-{
-	struct a4979_data *data = dev->data;
-
-	if (!data->enabled) {
-		LOG_ERR("Failed to move by delta, device is not enabled");
-		return -ECANCELED;
-	}
-
-	return step_dir_stepper_common_move_by(dev, micro_steps);
-}
-
-static int a4979_run(const struct device *dev, enum stepper_direction direction)
-{
-	struct a4979_data *data = dev->data;
-
-	if (!data->enabled) {
-		LOG_ERR("Failed to run stepper, device is not enabled");
-		return -ECANCELED;
-	}
-
-	return step_dir_stepper_common_run(dev, direction);
-}
-
 static int a4979_init(const struct device *dev)
 {
 	const struct a4979_config *config = dev->config;
@@ -268,17 +231,10 @@ static int a4979_init(const struct device *dev)
 static DEVICE_API(stepper, a4979_stepper_api) = {
 	.enable = a4979_stepper_enable,
 	.disable = a4979_stepper_disable,
-	.move_by = a4979_stepper_move_by,
-	.move_to = a4979_move_to,
-	.is_moving = step_dir_stepper_common_is_moving,
-	.set_reference_position = step_dir_stepper_common_set_reference_position,
-	.get_actual_position = step_dir_stepper_common_get_actual_position,
-	.set_microstep_interval = step_dir_stepper_common_set_microstep_interval,
-	.run = a4979_run,
-	.stop = step_dir_stepper_common_stop,
 	.set_micro_step_res = a4979_stepper_set_micro_step_res,
 	.get_micro_step_res = a4979_stepper_get_micro_step_res,
-	.set_event_callback = step_dir_stepper_common_set_event_callback,
+	.step = step_dir_stepper_common_step,
+	.set_direction = step_dir_stepper_common_set_direction,
 };
 
 #define A4979_DEVICE(inst)                                                                         \
diff --git a/drivers/stepper/step_dir/CMakeLists.txt b/drivers/stepper/step_dir/CMakeLists.txt
index 7daa4cc04d5b2..6bb451e000676 100644
--- a/drivers/stepper/step_dir/CMakeLists.txt
+++ b/drivers/stepper/step_dir/CMakeLists.txt
@@ -4,5 +4,3 @@
 zephyr_library()
 
 zephyr_library_sources(step_dir_stepper_common.c)
-zephyr_library_sources(step_dir_stepper_work_timing.c)
-zephyr_library_sources_ifdef(CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING step_dir_stepper_counter_timing.c)
diff --git a/drivers/stepper/step_dir/Kconfig b/drivers/stepper/step_dir/Kconfig
index d8629c649ffd2..039143c632527 100644
--- a/drivers/stepper/step_dir/Kconfig
+++ b/drivers/stepper/step_dir/Kconfig
@@ -5,18 +5,3 @@ config STEP_DIR_STEPPER
 	bool
 	help
 	  Enable library used for step direction stepper drivers.
-
-if STEP_DIR_STEPPER
-
-config STEP_DIR_STEPPER_COUNTER_TIMING
-	bool "Counter use for stepping"
-	select COUNTER
-	default y
-	help
-	  Enable usage of a counter device for accurate stepping.
-
-module = STEP_DIR
-module-str = step_dir
-rsource "../Kconfig.stepper_event_template"
-
-endif # STEP_DIR_STEPPER
diff --git a/drivers/stepper/step_dir/step_dir_stepper_common.c b/drivers/stepper/step_dir/step_dir_stepper_common.c
index b6b7566f07fbd..272361fa783c3 100644
--- a/drivers/stepper/step_dir/step_dir_stepper_common.c
+++ b/drivers/stepper/step_dir/step_dir_stepper_common.c
@@ -8,29 +8,10 @@
 #include <zephyr/logging/log.h>
 LOG_MODULE_REGISTER(step_dir_stepper, CONFIG_STEPPER_LOG_LEVEL);
 
-static inline int step_dir_stepper_perform_step(const struct device *dev)
+int step_dir_stepper_common_step(const struct device *dev)
 {
 	const struct step_dir_stepper_common_config *config = dev->config;
-	struct step_dir_stepper_common_data *data = dev->data;
-	int ret;
-
-	switch (data->direction) {
-	case STEPPER_DIRECTION_POSITIVE:
-		ret = gpio_pin_set_dt(&config->dir_pin, 1 ^ config->invert_direction);
-		break;
-	case STEPPER_DIRECTION_NEGATIVE:
-		ret = gpio_pin_set_dt(&config->dir_pin, 0 ^ config->invert_direction);
-		break;
-	default:
-		LOG_ERR("Unsupported direction: %d", data->direction);
-		return -ENOTSUP;
-	}
-	if (ret < 0) {
-		LOG_ERR("Failed to set direction: %d", ret);
-		return ret;
-	}
-
-	ret = gpio_pin_toggle_dt(&config->step_pin);
+	int ret = gpio_pin_toggle_dt(&config->step_pin);
 	if (ret < 0) {
 		LOG_ERR("Failed to toggle step pin: %d", ret);
 		return ret;
@@ -44,142 +25,28 @@ static inline int step_dir_stepper_perform_step(const struct device *dev)
 		}
 	}
 
-	if (data->direction == STEPPER_DIRECTION_POSITIVE) {
-		data->actual_position++;
-	} else {
-		data->actual_position--;
-	}
-
 	return 0;
 }
 
-void stepper_trigger_callback(const struct device *dev, enum stepper_event event)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	if (!data->callback) {
-		LOG_WRN_ONCE("No callback set");
-		return;
-	}
-
-	if (!k_is_in_isr()) {
-		data->callback(dev, event, data->event_cb_user_data);
-		return;
-	}
-
-#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS
-	/* Dispatch to msgq instead of raising directly */
-	int ret = k_msgq_put(&data->event_msgq, &event, K_NO_WAIT);
-
-	if (ret != 0) {
-		LOG_WRN("Failed to put event in msgq: %d", ret);
-	}
-
-	ret = k_work_submit(&data->event_callback_work);
-	if (ret < 0) {
-		LOG_ERR("Failed to submit work item: %d", ret);
-	}
-#else
-	LOG_WRN_ONCE("Event callback called from ISR context without ISR safe events enabled");
-#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
-}
-
-#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS
-static void stepper_work_event_handler(struct k_work *work)
+int step_dir_stepper_common_set_direction(const struct device *dev,
+					  const enum stepper_direction dir)
 {
-	struct step_dir_stepper_common_data *data =
-		CONTAINER_OF(work, struct step_dir_stepper_common_data, event_callback_work);
-	enum stepper_event event;
-	int ret;
-
-	ret = k_msgq_get(&data->event_msgq, &event, K_NO_WAIT);
-	if (ret != 0) {
-		return;
-	}
-
-	/* Run the callback */
-	if (data->callback != NULL) {
-		data->callback(data->dev, event, data->event_cb_user_data);
-	}
-
-	/* If there are more pending events, resubmit this work item to handle them */
-	if (k_msgq_num_used_get(&data->event_msgq) > 0) {
-		k_work_submit(work);
-	}
-}
-#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
-
-static void update_remaining_steps(struct step_dir_stepper_common_data *data)
-{
-	const struct step_dir_stepper_common_config *config = data->dev->config;
-
-	if (data->step_count > 0) {
-		data->step_count--;
-	} else if (data->step_count < 0) {
-		data->step_count++;
-	} else {
-		stepper_trigger_callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED);
-		config->timing_source->stop(data->dev);
-	}
-}
-
-static void update_direction_from_step_count(const struct device *dev)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	if (data->step_count > 0) {
-		data->direction = STEPPER_DIRECTION_POSITIVE;
-	} else if (data->step_count < 0) {
-		data->direction = STEPPER_DIRECTION_NEGATIVE;
-	} else {
-		LOG_ERR("Step count is zero");
-	}
-}
-
-static void position_mode_task(const struct device *dev)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
 	const struct step_dir_stepper_common_config *config = dev->config;
+	int ret;
 
-	if (data->step_count) {
-		(void)step_dir_stepper_perform_step(dev);
-	}
-
-	if (config->timing_source->needs_reschedule(dev) && data->step_count != 0) {
-		(void)config->timing_source->start(dev);
-	}
-
-	update_remaining_steps(dev->data);
-}
-
-static void velocity_mode_task(const struct device *dev)
-{
-	const struct step_dir_stepper_common_config *config = dev->config;
-
-	(void)step_dir_stepper_perform_step(dev);
-
-	if (config->timing_source->needs_reschedule(dev)) {
-		(void)config->timing_source->start(dev);
+	switch (dir) {
+	case STEPPER_DIRECTION_POSITIVE:
+		ret = gpio_pin_set_dt(&config->dir_pin, 1 ^ config->invert_direction);
+		break;
+	case STEPPER_DIRECTION_NEGATIVE:
+		ret = gpio_pin_set_dt(&config->dir_pin, 0 ^ config->invert_direction);
+		break;
+	default:
+		LOG_ERR("Unsupported direction: %d", dir);
+		return -ENOTSUP;
 	}
-}
 
-void stepper_handle_timing_signal(const struct device *dev)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	K_SPINLOCK(&data->lock) {
-		switch (data->run_mode) {
-		case STEPPER_RUN_MODE_POSITION:
-			position_mode_task(dev);
-			break;
-		case STEPPER_RUN_MODE_VELOCITY:
-			velocity_mode_task(dev);
-			break;
-		default:
-			LOG_WRN("Unsupported run mode: %d", data->run_mode);
-			break;
-		}
-	}
+	return ret;
 }
 
 int step_dir_stepper_common_init(const struct device *dev)
@@ -204,144 +71,5 @@ int step_dir_stepper_common_init(const struct device *dev)
 		return ret;
 	}
 
-	if (config->timing_source->init) {
-		ret = config->timing_source->init(dev);
-		if (ret < 0) {
-			LOG_ERR("Failed to initialize timing source: %d", ret);
-			return ret;
-		}
-	}
-
-#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	k_msgq_init(&data->event_msgq, data->event_msgq_buffer, sizeof(enum stepper_event),
-		    CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN);
-	k_work_init(&data->event_callback_work, stepper_work_event_handler);
-#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
-
-	return 0;
-}
-
-int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-	const struct step_dir_stepper_common_config *config = dev->config;
-
-	if (data->microstep_interval_ns == 0) {
-		LOG_ERR("Step interval not set or invalid step interval set");
-		return -EINVAL;
-	}
-
-	K_SPINLOCK(&data->lock) {
-		data->run_mode = STEPPER_RUN_MODE_POSITION;
-		data->step_count = micro_steps;
-		config->timing_source->update(dev, data->microstep_interval_ns);
-		update_direction_from_step_count(dev);
-		config->timing_source->start(dev);
-	}
-
-	return 0;
-}
-
-int step_dir_stepper_common_set_microstep_interval(const struct device *dev,
-					      const uint64_t microstep_interval_ns)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-	const struct step_dir_stepper_common_config *config = dev->config;
-
-	if (microstep_interval_ns == 0) {
-		LOG_ERR("Step interval cannot be zero");
-		return -EINVAL;
-	}
-
-	K_SPINLOCK(&data->lock) {
-		data->microstep_interval_ns = microstep_interval_ns;
-		config->timing_source->update(dev, microstep_interval_ns);
-	}
-
-	return 0;
-}
-
-int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	K_SPINLOCK(&data->lock) {
-		data->actual_position = value;
-	}
-
-	return 0;
-}
-
-int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	K_SPINLOCK(&data->lock) {
-		*value = data->actual_position;
-	}
-
-	return 0;
-}
-
-int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-	int32_t steps_to_move;
-
-	/* Calculate the relative movement required */
-	K_SPINLOCK(&data->lock) {
-		steps_to_move = value - data->actual_position;
-	}
-
-	return step_dir_stepper_common_move_by(dev, steps_to_move);
-}
-
-int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving)
-{
-	const struct step_dir_stepper_common_config *config = dev->config;
-
-	*is_moving = config->timing_source->is_running(dev);
-	return 0;
-}
-
-int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-	const struct step_dir_stepper_common_config *config = dev->config;
-
-	K_SPINLOCK(&data->lock) {
-		data->run_mode = STEPPER_RUN_MODE_VELOCITY;
-		data->direction = direction;
-		config->timing_source->update(dev, data->microstep_interval_ns);
-		config->timing_source->start(dev);
-	}
-
-	return 0;
-}
-
-int step_dir_stepper_common_stop(const struct device *dev)
-{
-	const struct step_dir_stepper_common_config *config = dev->config;
-	int ret;
-
-	ret = config->timing_source->stop(dev);
-	if (ret != 0) {
-		LOG_ERR("Failed to stop timing source: %d", ret);
-		return ret;
-	}
-
-	stepper_trigger_callback(dev, STEPPER_EVENT_STOPPED);
-	return 0;
-}
-
-int step_dir_stepper_common_set_event_callback(const struct device *dev,
-					       stepper_event_callback_t callback, void *user_data)
-{
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	data->callback = callback;
-	data->event_cb_user_data = user_data;
 	return 0;
 }
diff --git a/drivers/stepper/step_dir/step_dir_stepper_common.h b/drivers/stepper/step_dir/step_dir_stepper_common.h
index b345cf5d68a5d..abc59ad666205 100644
--- a/drivers/stepper/step_dir/step_dir_stepper_common.h
+++ b/drivers/stepper/step_dir/step_dir_stepper_common.h
@@ -17,9 +17,6 @@
 #include <zephyr/device.h>
 #include <zephyr/drivers/gpio.h>
 #include <zephyr/drivers/stepper.h>
-#include <zephyr/drivers/counter.h>
-
-#include "step_dir_stepper_timing_source.h"
 
 /**
  * @brief Common step direction stepper config.
@@ -30,8 +27,6 @@ struct step_dir_stepper_common_config {
 	const struct gpio_dt_spec step_pin;
 	const struct gpio_dt_spec dir_pin;
 	bool dual_edge;
-	const struct stepper_timing_source_api *timing_source;
-	const struct device *counter;
 	bool invert_direction;
 };
 
@@ -47,11 +42,7 @@ struct step_dir_stepper_common_config {
 		.step_pin = GPIO_DT_SPEC_GET(node_id, step_gpios),                                 \
 		.dir_pin = GPIO_DT_SPEC_GET(node_id, dir_gpios),                                   \
 		.dual_edge = DT_PROP_OR(node_id, dual_edge_step, false),                           \
-		.counter = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, counter)),                    \
 		.invert_direction = DT_PROP(node_id, invert_direction),                            \
-		.timing_source = COND_CODE_1(DT_NODE_HAS_PROP(node_id, counter),                   \
-						(&step_counter_timing_source_api),                 \
-						(&step_work_timing_source_api)),                   \
 	}
 
 /**
@@ -67,47 +58,14 @@ struct step_dir_stepper_common_config {
  * This structure **must** be placed first in the driver's data structure.
  */
 struct step_dir_stepper_common_data {
-	const struct device *dev;
-	struct k_spinlock lock;
-	enum stepper_direction direction;
-	enum stepper_run_mode run_mode;
-	int32_t actual_position;
-	uint64_t microstep_interval_ns;
-	int32_t step_count;
-	stepper_event_callback_t callback;
-	void *event_cb_user_data;
-
-	struct k_work_delayable stepper_dwork;
-
-#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
-	struct counter_top_cfg counter_top_cfg;
-	bool counter_running;
-#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
 
-#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS
-	struct k_work event_callback_work;
-	struct k_msgq event_msgq;
-	uint8_t event_msgq_buffer[CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN *
-				  sizeof(enum stepper_event)];
-#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
 };
 
-/**
- * @brief Initialize common step direction stepper data from devicetree instance.
- *
- * @param node_id The devicetree node identifier.
- */
-#define STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(node_id)                                              \
-	{                                                                                          \
-		.dev = DEVICE_DT_GET(node_id),                                                     \
-	}
-
 /**
  * @brief Initialize common step direction stepper data from devicetree instance.
  * @param inst Instance.
  */
-#define STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst)                                            \
-	STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(DT_DRV_INST(inst))
+#define STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst) {}
 
 /**
  * @brief Validate the offset of the common data structures.
@@ -134,103 +92,30 @@ struct step_dir_stepper_common_data {
 int step_dir_stepper_common_init(const struct device *dev);
 
 /**
- * @brief Move the stepper motor by a given number of micro_steps.
- *
- * @param dev Pointer to the device structure.
- * @param micro_steps Number of micro_steps to move. Can be positive or negative.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps);
-
-/**
- * @brief Set the step interval of the stepper motor.
- *
- * @param dev Pointer to the device structure.
- * @param microstep_interval_ns The step interval in nanoseconds.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_set_microstep_interval(const struct device *dev,
-					      const uint64_t microstep_interval_ns);
-
-/**
- * @brief Set the reference position of the stepper motor.
- *
- * @param dev Pointer to the device structure.
- * @param value The reference position value to set.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value);
-
-/**
- * @brief Get the actual (reference) position of the stepper motor.
+ * @brief Common function to perform a step on a step direction stepper device.
  *
- * @param dev Pointer to the device structure.
- * @param value Pointer to a variable where the position value will be stored.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value);
-
-/**
- * @brief Set the absolute target position of the stepper motor.
+ * This function must be called to perform a step.
  *
- * @param dev Pointer to the device structure.
- * @param value The target position to set.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value);
-
-/**
- * @brief Check if the stepper motor is still moving.
+ * @param dev Step direction stepper device instance.
  *
- * @param dev Pointer to the device structure.
- * @param is_moving Pointer to a boolean where the movement status will be stored.
- * @return 0 on success, or a negative error code on failure.
+ * @retval 0 If step performed successfully.
+ * @retval -errno Negative errno in case of failure.
  */
-int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving);
+int step_dir_stepper_common_step(const struct device *dev);
 
 /**
- * @brief Run the stepper with a given direction and step interval.
+ * @brief Common function to set the direction of a step direction stepper device.
  *
- * @param dev Pointer to the device structure.
- * @param direction The direction of movement (positive or negative).
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction);
-
-/**
- * @brief Stop the stepper motor.
+ * This function must be called to set the direction.
  *
- * @param dev Pointer to the device structure.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_stop(const struct device *dev);
-
-/**
- * @brief Set a callback function for stepper motor events.
- *
- * This function sets a user-defined callback that will be invoked when a stepper motor event
- * occurs.
+ * @param dev Step direction stepper device instance.
+ * @param dir Direction to set.
  *
- * @param dev Pointer to the device structure.
- * @param callback The callback function to set.
- * @param user_data Pointer to user-defined data that will be passed to the callback.
- * @return 0 on success, or a negative error code on failure.
- */
-int step_dir_stepper_common_set_event_callback(const struct device *dev,
-					       stepper_event_callback_t callback, void *user_data);
-
-/**
- * @brief Handle a timing signal and update the stepper position.
- * @param dev Pointer to the device structure.
- */
-void stepper_handle_timing_signal(const struct device *dev);
-
-/**
- * @brief Trigger callback function for stepper motor events.
- * @param dev Pointer to the device structure.
- * @param event The stepper_event to rigger the callback for.
+ * @retval 0 If direction set successfully.
+ * @retval -errno Negative errno in case of failure.
  */
-void stepper_trigger_callback(const struct device *dev, enum stepper_event event);
+int step_dir_stepper_common_set_direction(const struct device *dev,
+					  const enum stepper_direction dir);
 
 /** @} */
 
diff --git a/drivers/stepper/ti/Kconfig.drv84xx b/drivers/stepper/ti/Kconfig.drv84xx
index e5466890c66da..10cdd06433ee4 100644
--- a/drivers/stepper/ti/Kconfig.drv84xx
+++ b/drivers/stepper/ti/Kconfig.drv84xx
@@ -7,6 +7,5 @@ config DRV84XX
 	depends on DT_HAS_TI_DRV84XX_ENABLED
 	select STEPPER_TI
 	select STEP_DIR_STEPPER
-	select STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS
 	help
 	  Enable driver for TI DRV84XX stepper motor driver.
diff --git a/drivers/stepper/ti/drv84xx.c b/drivers/stepper/ti/drv84xx.c
index cc4a8651e8aa5..9c46de7bd0e0b 100644
--- a/drivers/stepper/ti/drv84xx.c
+++ b/drivers/stepper/ti/drv84xx.c
@@ -255,8 +255,6 @@ static int drv84xx_disable(const struct device *dev)
 		}
 	}
 
-	config->common.timing_source->stop(dev);
-
 	data->enabled = false;
 
 	return ret;
@@ -351,42 +349,6 @@ static int drv84xx_get_micro_step_res(const struct device *dev,
 	return 0;
 }
 
-static int drv84xx_move_to(const struct device *dev, int32_t target)
-{
-	struct drv84xx_data *data = dev->data;
-
-	if (!data->enabled) {
-		LOG_ERR("Failed to move to target position, device is not enabled");
-		return -ECANCELED;
-	}
-
-	return step_dir_stepper_common_move_to(dev, target);
-}
-
-static int drv84xx_move_by(const struct device *dev, int32_t steps)
-{
-	struct drv84xx_data *data = dev->data;
-
-	if (!data->enabled) {
-		LOG_ERR("Failed to move by delta, device is not enabled");
-		return -ECANCELED;
-	}
-
-	return step_dir_stepper_common_move_by(dev, steps);
-}
-
-static int drv84xx_run(const struct device *dev, enum stepper_direction direction)
-{
-	struct drv84xx_data *data = dev->data;
-
-	if (!data->enabled) {
-		LOG_ERR("Failed to run stepper, device is not enabled");
-		return -ECANCELED;
-	}
-
-	return step_dir_stepper_common_run(dev, direction);
-}
-
 void fault_event(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
 {
 	struct drv84xx_data *data = CONTAINER_OF(cb, struct drv84xx_data, fault_cb_data);
@@ -478,17 +440,10 @@ static int drv84xx_init(const struct device *dev)
 static DEVICE_API(stepper, drv84xx_stepper_api) = {
 	.enable = drv84xx_enable,
 	.disable = drv84xx_disable,
-	.move_by = drv84xx_move_by,
-	.move_to = drv84xx_move_to,
-	.is_moving = step_dir_stepper_common_is_moving,
-	.set_reference_position = step_dir_stepper_common_set_reference_position,
-	.get_actual_position = step_dir_stepper_common_get_actual_position,
-	.set_microstep_interval = step_dir_stepper_common_set_microstep_interval,
-	.run = drv84xx_run,
-	.stop = step_dir_stepper_common_stop,
 	.set_micro_step_res = drv84xx_set_micro_step_res,
 	.get_micro_step_res = drv84xx_get_micro_step_res,
-	.set_event_callback = step_dir_stepper_common_set_event_callback,
+	.step = step_dir_stepper_common_step,
+	.set_direction = step_dir_stepper_common_set_direction,
 };
 
 #define DRV84XX_DEVICE(inst)                                                                       \
diff --git a/drivers/stepper/Kconfig.stepper_event_template b/drivers/stepper_control/Kconfig.stepper_event_template
similarity index 79%
rename from drivers/stepper/Kconfig.stepper_event_template
rename to drivers/stepper_control/Kconfig.stepper_event_template
index fb29a1e91e0e2..2fdd942f92a74 100644
--- a/drivers/stepper/Kconfig.stepper_event_template
+++ b/drivers/stepper_control/Kconfig.stepper_event_template
@@ -1,7 +1,7 @@
 # Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
 # SPDX-License-Identifier: Apache-2.0
 
-config STEPPER_$(module)_GENERATE_ISR_SAFE_EVENTS
+config $(module)_GENERATE_ISR_SAFE_EVENTS
 	bool "$(module-str) guarantee non ISR callbacks upon stepper events"
 	help
 	  Enable the dispatch of stepper generated events via
@@ -9,10 +9,10 @@ config STEPPER_$(module)_GENERATE_ISR_SAFE_EVENTS
 	  code is not run inside of an ISR. Can be disabled, but
 	  then registered stepper event callback must be ISR safe.
 
-config STEPPER_$(module)_EVENT_QUEUE_LEN
+config $(module)_EVENT_QUEUE_LEN
 	int "$(module-str) maximum number of pending stepper events"
 	default 4
-	depends on STEPPER_$(module)_GENERATE_ISR_SAFE_EVENTS
+	depends on $(module)_GENERATE_ISR_SAFE_EVENTS
 	help
 	  The maximum number of stepper events that can be pending before new events
 	  are dropped.
diff --git a/drivers/stepper_control/zephyr_stepper_motion_control/CMakeLists.txt b/drivers/stepper_control/zephyr_stepper_motion_control/CMakeLists.txt
index 0b6ceb428c282..ddc177135b506 100644
--- a/drivers/stepper_control/zephyr_stepper_motion_control/CMakeLists.txt
+++ b/drivers/stepper_control/zephyr_stepper_motion_control/CMakeLists.txt
@@ -3,4 +3,6 @@
 
 zephyr_library()
 
-zephyr_library_sources(stepper_control.c)
\ No newline at end of file
+zephyr_library_sources(stepper_control.c)
+zephyr_library_sources(stepper_motion_control_work_timing.c)
+zephyr_library_sources_ifdef(CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING stepper_motion_control_counter_timing.c)
diff --git a/drivers/stepper_control/zephyr_stepper_motion_control/Kconfig b/drivers/stepper_control/zephyr_stepper_motion_control/Kconfig
index 085dcc97ffe23..f9568231dbfa8 100644
--- a/drivers/stepper_control/zephyr_stepper_motion_control/Kconfig
+++ b/drivers/stepper_control/zephyr_stepper_motion_control/Kconfig
@@ -5,3 +5,19 @@ config ZEPHYR_STEPPER_MOTION_CONTROL
 	bool "Zephyr SW based Stepper motor control"
 	depends on DT_HAS_ZEPHYR_STEPPER_CONTROL_ENABLED
 	default y
+
+if ZEPHYR_STEPPER_MOTION_CONTROL
+
+config ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
+	bool "Counter use for stepping"
+	select COUNTER
+	default y
+	help
+	  Enable usage of a counter device for accurate stepping.
+
+module = ZEPHYR_STEPPER_MOTION_CONTROL
+module-str = zephyr_stepper_motion_control
+
+rsource "../Kconfig.stepper_event_template"
+
+endif
diff --git a/drivers/stepper_control/zephyr_stepper_motion_control/stepper_control.c b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_control.c
index 83737e65cfa76..5af02096eee28 100644
--- a/drivers/stepper_control/zephyr_stepper_motion_control/stepper_control.c
+++ b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_control.c
@@ -9,11 +9,15 @@
 #include <zephyr/device.h>
 #include <zephyr/drivers/stepper_control.h>
 
+#include "stepper_motion_control_timing_source.h"
+
 #include <zephyr/logging/log.h>
 LOG_MODULE_REGISTER(stepper_control, CONFIG_STEPPER_CONTROL_LOG_LEVEL);
 
 struct stepper_control_config {
 	const struct device *stepper;
+	const struct timing_source_config timing_config;
+	const struct stepper_timing_source_api *timing_source;
 };
 
 struct stepper_control_data {
@@ -25,23 +29,81 @@ struct stepper_control_data {
 	int32_t actual_position;
 	int32_t reference_position;
 	enum stepper_control_mode mode;
-	uint64_t step_interval;
-	struct k_work_delayable stepper_control_dwork;
 	stepper_control_event_callback_t callback;
 	void *event_cb_user_data;
+	struct timing_source_data timing_data;
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS
+	struct k_work event_callback_work;
+	struct k_msgq event_msgq;
+	uint8_t event_msgq_buffer[CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_EVENT_QUEUE_LEN *
+				  sizeof(enum stepper_control_event)];
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS */
 };
 
+void stepper_trigger_callback(const struct device *dev, enum stepper_control_event event)
+{
+	struct stepper_control_data *data = dev->data;
+
+	if (!data->callback) {
+		LOG_WRN_ONCE("No callback set");
+		return;
+	}
+
+	if (!k_is_in_isr()) {
+		data->callback(dev, event, data->event_cb_user_data);
+		return;
+	}
+
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS
+	/* Dispatch to msgq instead of raising directly */
+	int ret = k_msgq_put(&data->event_msgq, &event, K_NO_WAIT);
+
+	if (ret != 0) {
+		LOG_WRN("Failed to put event in msgq: %d", ret);
+	}
+
+	ret = k_work_submit(&data->event_callback_work);
+	if (ret < 0) {
+		LOG_ERR("Failed to submit work item: %d", ret);
+	}
+#else
+	LOG_WRN_ONCE("Event callback called from ISR context without ISR safe events enabled");
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS */
+}
+
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS
+static void stepper_work_event_handler(struct k_work *work)
+{
+	struct stepper_control_data *data =
+		CONTAINER_OF(work, struct stepper_control_data, event_callback_work);
+	enum stepper_control_event event;
+	int ret;
+
+	ret = k_msgq_get(&data->event_msgq, &event, K_NO_WAIT);
+	if (ret != 0) {
+		return;
+	}
+
+	/* Run the callback */
+	if (data->callback != NULL) {
+		data->callback(data->dev, event, data->event_cb_user_data);
+	}
+
+	/* If there are more pending events, resubmit this work item to handle them */
+	if (k_msgq_num_used_get(&data->event_msgq) > 0) {
+		k_work_submit(work);
+	}
+}
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS */
+
 static void update_direction_from_step_count(const struct device *dev)
 {
-	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
 
 	if (data->step_count > 0) {
 		data->direction = STEPPER_DIRECTION_POSITIVE;
-		stepper_set_direction(config->stepper, STEPPER_DIRECTION_POSITIVE);
 	} else if (data->step_count < 0) {
 		data->direction = STEPPER_DIRECTION_NEGATIVE;
-		stepper_set_direction(config->stepper, STEPPER_DIRECTION_NEGATIVE);
 	} else {
 		LOG_ERR("Step count is zero");
 	}
@@ -49,13 +111,14 @@ static void update_direction_from_step_count(const struct device *dev)
 
 static int z_stepper_control_move_by(const struct device *dev, int32_t micro_steps)
 {
+	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
 
 	/** Todo: Introduce a stepper driver call to check if the motor is enabled, if stepper is
 	 * not enabled return -ECANCELED
 	 */
 
-	if (data->step_interval == 0) {
+	if (data->timing_data.microstep_interval_ns == 0) {
 		LOG_ERR("Step interval not set or invalid step interval set");
 		return -EINVAL;
 	}
@@ -63,8 +126,11 @@ static int z_stepper_control_move_by(const struct device *dev, int32_t micro_ste
 	K_SPINLOCK(&data->lock) {
 		data->run_mode = STEPPER_RUN_MODE_POSITION;
 		data->step_count = micro_steps;
+		config->timing_source->update(&config->timing_config, &data->timing_data,
+					      data->timing_data.microstep_interval_ns);
 		update_direction_from_step_count(dev);
-		(void)k_work_reschedule(&data->stepper_control_dwork, K_NO_WAIT);
+		stepper_set_direction(config->stepper, data->direction);
+		config->timing_source->start(&config->timing_config, &data->timing_data);
 	}
 	return 0;
 }
@@ -96,24 +162,27 @@ static int z_stepper_control_run(const struct device *dev, const enum stepper_di
 	K_SPINLOCK(&data->lock) {
 		data->run_mode = STEPPER_RUN_MODE_VELOCITY;
 		data->direction = direction;
+		config->timing_source->update(&config->timing_config, &data->timing_data,
+					      data->timing_data.microstep_interval_ns);
 		stepper_set_direction(config->stepper, direction);
-		(void)k_work_reschedule(&data->stepper_control_dwork, K_NO_WAIT);
+		config->timing_source->start(&config->timing_config, &data->timing_data);
 	}
 	return 0;
 }
 
 static int z_stepper_control_stop(const struct device *dev)
 {
+	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
+	int ret;
 
-	K_SPINLOCK(&data->lock) {
-		(void)k_work_cancel_delayable(&data->stepper_control_dwork);
-
-		if (data->callback) {
-			data->callback(data->dev, STEPPER_CONTROL_EVENT_STOPPED,
-				       data->event_cb_user_data);
-		}
+	ret = config->timing_source->stop(&config->timing_config, &data->timing_data);
+	if (ret != 0) {
+		LOG_ERR("Failed to stop timing source: %d", ret);
+		return ret;
 	}
+	stepper_trigger_callback(dev, STEPPER_CONTROL_EVENT_STOPPED);
+
 	return 0;
 }
 
@@ -140,6 +209,7 @@ static int z_stepper_control_get_actual_position(const struct device *dev, int32
 static int z_stepper_control_set_step_interval(const struct device *dev,
 					       uint64_t microstep_interval_ns)
 {
+	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
 
 	if (microstep_interval_ns == 0) {
@@ -148,7 +218,9 @@ static int z_stepper_control_set_step_interval(const struct device *dev,
 	}
 
 	K_SPINLOCK(&data->lock) {
-		data->step_interval = microstep_interval_ns;
+		data->timing_data.microstep_interval_ns = microstep_interval_ns;
+		config->timing_source->update(&config->timing_config, &data->timing_data,
+					      microstep_interval_ns);
 	}
 	LOG_DBG("Setting Motor step interval to %llu", microstep_interval_ns);
 	return 0;
@@ -156,9 +228,10 @@ static int z_stepper_control_set_step_interval(const struct device *dev,
 
 static int z_stepper_control_is_moving(const struct device *dev, bool *is_moving)
 {
+	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
 
-	*is_moving = k_work_delayable_is_pending(&data->stepper_control_dwork);
+	*is_moving = config->timing_source->is_running(&data->timing_data);
 	LOG_DBG("Motor is %s moving", *is_moving ? "" : "not");
 	return 0;
 }
@@ -190,18 +263,17 @@ static void position_mode_task(const struct device *dev)
 	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
 
-	update_remaining_steps(dev);
 	stepper_step(config->stepper);
 	update_actual_position(dev);
-	if (data->step_count) {
-		(void)k_work_reschedule(&data->stepper_control_dwork, K_NSEC(data->step_interval));
-	} else {
-		if (data->callback) {
-			data->callback(dev, STEPPER_CONTROL_EVENT_STEPS_COMPLETED,
-				       data->event_cb_user_data);
-		}
-		(void)k_work_cancel_delayable(&data->stepper_control_dwork);
+
+	if (config->timing_source->needs_reschedule(dev) && data->step_count != 0) {
+		config->timing_source->start(&config->timing_config, &data->timing_data);
+	} else if (data->step_count == 0) {
+		stepper_trigger_callback(data->dev, STEPPER_CONTROL_EVENT_STEPS_COMPLETED);
+		config->timing_source->stop(&config->timing_config, &data->timing_data);
 	}
+
+	update_remaining_steps(dev);
 }
 
 static void velocity_mode_task(const struct device *dev)
@@ -211,7 +283,10 @@ static void velocity_mode_task(const struct device *dev)
 
 	stepper_step(config->stepper);
 	update_actual_position(dev);
-	(void)k_work_reschedule(&data->stepper_control_dwork, K_NSEC(data->step_interval));
+
+	if (config->timing_source->needs_reschedule(dev)) {
+		(void)config->timing_source->start(&config->timing_config, &data->timing_data);
+	}
 }
 
 static int z_stepper_control_set_mode(const struct device *dev, enum stepper_control_mode mode)
@@ -222,52 +297,61 @@ static int z_stepper_control_set_mode(const struct device *dev, enum stepper_con
 	return 0;
 }
 
-static void stepper_control_work_step_handler(struct k_work *work)
+static int z_stepper_control_set_event_callback(const struct device *dev,
+						stepper_control_event_callback_t cb,
+						void *user_data)
 {
-	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
-	struct stepper_control_data *data =
-		CONTAINER_OF(dwork, struct stepper_control_data, stepper_control_dwork);
+	struct stepper_control_data *data = dev->data;
+
+	K_SPINLOCK(&data->lock) {
+		data->callback = cb;
+	}
+	data->event_cb_user_data = user_data;
+	return 0;
+}
+
+void stepper_handle_timing_signal(const struct device *dev)
+{
+	struct stepper_control_data *data = dev->data;
 
 	K_SPINLOCK(&data->lock) {
 		switch (data->run_mode) {
 		case STEPPER_RUN_MODE_POSITION:
-			position_mode_task(data->dev);
+			position_mode_task(dev);
 			break;
 		case STEPPER_RUN_MODE_VELOCITY:
-			velocity_mode_task(data->dev);
+			velocity_mode_task(dev);
 			break;
 		default:
-			LOG_WRN("Unsupported run mode %d", data->run_mode);
+			LOG_WRN("Unsupported run mode: %d", data->run_mode);
 			break;
 		}
 	}
 }
 
-static int z_stepper_control_set_event_callback(const struct device *dev,
-						stepper_control_event_callback_t cb,
-						void *user_data)
-{
-	struct stepper_control_data *data = dev->data;
-
-	K_SPINLOCK(&data->lock) {
-		data->callback = cb;
-	}
-	data->event_cb_user_data = user_data;
-	return 0;
-}
-
 static int stepper_control_init(const struct device *dev)
 {
 	const struct stepper_control_config *config = dev->config;
 	struct stepper_control_data *data = dev->data;
+	int ret;
 
 	data->dev = dev;
-	if (!device_is_ready(config->stepper)) {
-		LOG_ERR("Stepper device %s is not ready", config->stepper->name);
-		return -ENODEV;
+
+	if (config->timing_source->init) {
+		ret = config->timing_source->init(&config->timing_config, &data->timing_data);
+		if (ret < 0) {
+			LOG_ERR("Failed to initialize timing source: %d", ret);
+			return ret;
+		}
 	}
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS
+
+	k_msgq_init(&data->event_msgq, data->event_msgq_buffer, sizeof(enum stepper_control_event),
+		    CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_EVENT_QUEUE_LEN);
+	k_work_init(&data->event_callback_work, stepper_work_event_handler);
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS */
+
 	LOG_DBG("Stepper Control initialized for stepper driver %s", config->stepper->name);
-	k_work_init_delayable(&data->stepper_control_dwork, stepper_control_work_step_handler);
 	return 0;
 }
 
@@ -286,10 +370,16 @@ static DEVICE_API(stepper_control, stepper_control_api) = {
 
 #define STEPPER_CONTROL_DEFINE(inst)                                                               \
 	static const struct stepper_control_config stepper_control_config_##inst = {               \
-		.stepper = DEVICE_DT_GET(DT_INST_PHANDLE(inst, stepper)),                          \
+		.stepper = DEVICE_DT_GET(DT_INST_CHILD(inst, stepper)),                            \
+		.timing_config.counter =                                                           \
+			DEVICE_DT_GET_OR_NULL(DT_PHANDLE(DT_DRV_INST(inst), counter)),             \
+		.timing_source = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, counter),                 \
+			(&step_counter_timing_source_api), (&step_work_timing_source_api)),        \
 	};                                                                                         \
 	struct stepper_control_data stepper_control_data_##inst = {                                \
-		.step_interval = DT_INST_PROP(inst, step_tick_ns),                                 \
+		.timing_data.microstep_interval_ns = DT_INST_PROP(inst, step_tick_ns),             \
+		.timing_data.motion_control_dev = DEVICE_DT_GET(DT_DRV_INST(inst)),                \
+		.timing_data.stepper_handle_timing_signal_cb = stepper_handle_timing_signal,       \
 	};                                                                                         \
 	DEVICE_DT_INST_DEFINE(inst, stepper_control_init, NULL, &stepper_control_data_##inst,      \
 			      &stepper_control_config_##inst, POST_KERNEL,                         \
diff --git a/drivers/stepper/step_dir/step_dir_stepper_counter_timing.c b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_counter_timing.c
similarity index 63%
rename from drivers/stepper/step_dir/step_dir_stepper_counter_timing.c
rename to drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_counter_timing.c
index bad216961e575..b0e0baa645166 100644
--- a/drivers/stepper/step_dir/step_dir_stepper_counter_timing.c
+++ b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_counter_timing.c
@@ -3,25 +3,23 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-#include <zephyr/drivers/counter.h>
-#include "step_dir_stepper_common.h"
+#include "stepper_motion_control_timing_source.h"
 
 #include <zephyr/logging/log.h>
-LOG_MODULE_DECLARE(step_dir_stepper);
+LOG_MODULE_REGISTER(stepper_counter_timing, CONFIG_STEPPER_CONTROL_LOG_LEVEL);
 
 static void step_counter_top_interrupt(const struct device *dev, void *user_data)
 {
 	ARG_UNUSED(dev);
-	struct step_dir_stepper_common_data *data = user_data;
+	struct timing_source_data *data = user_data;
 
-	stepper_handle_timing_signal(data->dev);
+	data->stepper_handle_timing_signal_cb(data->motion_control_dev);
 }
 
-int step_counter_timing_source_update(const struct device *dev,
+int step_counter_timing_source_update(const struct timing_source_config *config,
+				      struct timing_source_data *data,
 				      const uint64_t microstep_interval_ns)
 {
-	const struct step_dir_stepper_common_config *config = dev->config;
-	struct step_dir_stepper_common_data *data = dev->data;
 	int ret;
 
 	if (microstep_interval_ns == 0) {
@@ -39,17 +37,17 @@ int step_counter_timing_source_update(const struct device *dev,
 	irq_unlock(key);
 
 	if (ret != 0) {
-		LOG_ERR("%s: Failed to set counter top value (error: %d)", dev->name, ret);
+		LOG_ERR("%s: Failed to set counter top value (error: %d)",
+			data->motion_control_dev->name, ret);
 		return ret;
 	}
 
 	return 0;
 }
 
-int step_counter_timing_source_start(const struct device *dev)
+int step_counter_timing_source_start(const struct timing_source_config *config,
+				     struct timing_source_data *data)
 {
-	const struct step_dir_stepper_common_config *config = dev->config;
-	struct step_dir_stepper_common_data *data = dev->data;
 	int ret;
 
 	ret = counter_start(config->counter);
@@ -63,10 +61,9 @@ int step_counter_timing_source_start(const struct device *dev)
 	return 0;
 }
 
-int step_counter_timing_source_stop(const struct device *dev)
+int step_counter_timing_source_stop(const struct timing_source_config *config,
+				    struct timing_source_data *data)
 {
-	const struct step_dir_stepper_common_config *config = dev->config;
-	struct step_dir_stepper_common_data *data = dev->data;
 	int ret;
 
 	ret = counter_stop(config->counter);
@@ -86,18 +83,14 @@ bool step_counter_timing_source_needs_reschedule(const struct device *dev)
 	return false;
 }
 
-bool step_counter_timing_source_is_running(const struct device *dev)
+bool step_counter_timing_source_is_running(struct timing_source_data *data)
 {
-	struct step_dir_stepper_common_data *data = dev->data;
-
 	return data->counter_running;
 }
 
-int step_counter_timing_source_init(const struct device *dev)
+int step_counter_timing_source_init(const struct timing_source_config *config,
+				    struct timing_source_data *data)
 {
-	const struct step_dir_stepper_common_config *config = dev->config;
-	struct step_dir_stepper_common_data *data = dev->data;
-
 	if (!device_is_ready(config->counter)) {
 		LOG_ERR("Counter device is not ready");
 		return -ENODEV;
diff --git a/drivers/stepper/step_dir/step_dir_stepper_timing_source.h b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
similarity index 50%
rename from drivers/stepper/step_dir/step_dir_stepper_timing_source.h
rename to drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
index 4c77993614afc..5859f2b496179 100644
--- a/drivers/stepper/step_dir/step_dir_stepper_timing_source.h
+++ b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
@@ -7,32 +7,56 @@
 #define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
 
 #include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+};
+
+struct timing_source_data {
+	const struct device *motion_control_dev;
+	uint64_t microstep_interval_ns;
+	struct k_work_delayable stepper_dwork;
+	void (*stepper_handle_timing_signal_cb)(const struct device *dev);;
+
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
+	struct counter_top_cfg counter_top_cfg;
+	bool counter_running;
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+};
 
 /**
  * @brief Initialize the stepper timing source.
  *
- * @param dev Pointer to the device structure.
+ * @param config Pointer to the timing source configuration structure.
+ * @param data Pointer to the timing source data structure.
  * @return 0 on success, or a negative error code on failure.
  */
-typedef int (*stepper_timing_source_init)(const struct device *dev);
+typedef int (*stepper_timing_source_init)(const struct timing_source_config *config,
+					  struct timing_source_data *data);
 
 /**
  * @brief Update the stepper timing source.
  *
- * @param dev Pointer to the device structure.
+ * @param config Pointer to the timing source configuration structure.
+ * @param data Pointer to the timing source data structure.
  * @param microstep_interval_ns Step interval in nanoseconds.
  * @return 0 on success, or a negative error code on failure.
  */
-typedef int (*stepper_timing_source_update)(const struct device *dev,
+typedef int (*stepper_timing_source_update)(const struct timing_source_config *config,
+					    struct timing_source_data *data,
 					    uint64_t microstep_interval_ns);
 
 /**
  * @brief Start the stepper timing source.
  *
- * @param dev Pointer to the device structure.
+ * @param config Pointer to the timing source configuration structure.
+ * @param data Pointer to the timing source data structure.
  * @return 0 on success, or a negative error code on failure.
  */
-typedef int (*stepper_timing_source_start)(const struct device *dev);
+typedef int (*stepper_timing_source_start)(const struct timing_source_config *config,
+					   struct timing_source_data *data);
 
 /**
  * @brief Whether the stepper timing source requires rescheduling (keeps running
@@ -46,18 +70,20 @@ typedef bool (*stepper_timing_sources_requires_reschedule)(const struct device *
 /**
  * @brief Stop the stepper timing source.
  *
- * @param dev Pointer to the device structure.
+ * @param config Pointer to the timing source configuration structure.
+ * @param data Pointer to the timing source data structure.
  * @return 0 on success, or a negative error code on failure.
  */
-typedef int (*stepper_timing_source_stop)(const struct device *dev);
+typedef int (*stepper_timing_source_stop)(const struct timing_source_config *config,
+					  struct timing_source_data *data);
 
 /**
  * @brief Check if the stepper timing source is running.
  *
- * @param dev Pointer to the device structure.
+ * @param data Pointer to the timing source data structure.
  * @return true if the timing source is running, false otherwise.
  */
-typedef bool (*stepper_timing_source_is_running)(const struct device *dev);
+typedef bool (*stepper_timing_source_is_running)(struct timing_source_data *data);
 
 /**
  * @brief Stepper timing source API.
@@ -72,8 +98,8 @@ struct stepper_timing_source_api {
 };
 
 extern const struct stepper_timing_source_api step_work_timing_source_api;
-#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
 extern const struct stepper_timing_source_api step_counter_timing_source_api;
-#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
 
 #endif /* ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ */
diff --git a/drivers/stepper/step_dir/step_dir_stepper_work_timing.c b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_work_timing.c
similarity index 54%
rename from drivers/stepper/step_dir/step_dir_stepper_work_timing.c
rename to drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_work_timing.c
index ac605f1f49727..df7bd5a916060 100644
--- a/drivers/stepper/step_dir/step_dir_stepper_work_timing.c
+++ b/drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_work_timing.c
@@ -3,13 +3,10 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-#include "step_dir_stepper_timing_source.h"
-#include "step_dir_stepper_common.h"
+#include "stepper_motion_control_timing_source.h"
 
-static k_timeout_t stepper_movement_delay(const struct device *dev)
+static k_timeout_t stepper_movement_delay(const struct timing_source_data *data)
 {
-	const struct step_dir_stepper_common_data *data = dev->data;
-
 	if (data->microstep_interval_ns == 0) {
 		return K_FOREVER;
 	}
@@ -20,39 +17,40 @@ static k_timeout_t stepper_movement_delay(const struct device *dev)
 static void stepper_work_step_handler(struct k_work *work)
 {
 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
-	struct step_dir_stepper_common_data *data =
-		CONTAINER_OF(dwork, struct step_dir_stepper_common_data, stepper_dwork);
+	struct timing_source_data *data =
+		CONTAINER_OF(dwork, struct timing_source_data, stepper_dwork);
 
-	stepper_handle_timing_signal(data->dev);
+	data->stepper_handle_timing_signal_cb(data->motion_control_dev);
 }
 
-int step_work_timing_source_init(const struct device *dev)
+int step_work_timing_source_init(const struct timing_source_config *config,
+				 struct timing_source_data *data)
 {
-	struct step_dir_stepper_common_data *data = dev->data;
-
 	k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler);
 
 	return 0;
 }
 
-int step_work_timing_source_update(const struct device *dev, const uint64_t microstep_interval_ns)
+int step_work_timing_source_update(const struct timing_source_config *config,
+				   struct timing_source_data *data,
+				   const uint64_t microstep_interval_ns)
 {
-	ARG_UNUSED(dev);
+	ARG_UNUSED(config);
+	ARG_UNUSED(data);
 	ARG_UNUSED(microstep_interval_ns);
 	return 0;
 }
 
-int step_work_timing_source_start(const struct device *dev)
+int step_work_timing_source_start(const struct timing_source_config *config,
+				  struct timing_source_data *data)
 {
-	struct step_dir_stepper_common_data *data = dev->data;
-
-	return k_work_reschedule(&data->stepper_dwork, stepper_movement_delay(dev));
+	ARG_UNUSED(config);
+	return k_work_reschedule(&data->stepper_dwork, stepper_movement_delay(data));
 }
 
-int step_work_timing_source_stop(const struct device *dev)
+int step_work_timing_source_stop(const struct timing_source_config *config,
+				 struct timing_source_data *data)
 {
-	struct step_dir_stepper_common_data *data = dev->data;
-
 	return k_work_cancel_delayable(&data->stepper_dwork);
 }
 
@@ -62,10 +60,8 @@ bool step_work_timing_source_needs_reschedule(const struct device *dev)
 	return true;
 }
 
-bool step_work_timing_source_is_running(const struct device *dev)
+bool step_work_timing_source_is_running(struct timing_source_data *data)
 {
-	struct step_dir_stepper_common_data *data = dev->data;
-
 	return k_work_delayable_is_pending(&data->stepper_dwork);
 }
 
diff --git a/dts/bindings/stepper/stepper.yaml b/dts/bindings/stepper/stepper.yaml
index a73037bb6b975..eae57a18a25c9 100644
--- a/dts/bindings/stepper/stepper.yaml
+++ b/dts/bindings/stepper/stepper.yaml
@@ -40,7 +40,3 @@ properties:
     description: |
       The GPIO pins used to send direction signals to the stepper motor.
       Pin will be driven high for forward direction and low for reverse direction.
-
-  counter:
-    type: phandle
-    description: Counter used for generating step-accurate pulse signals.
diff --git a/dts/bindings/stepper_control/zephyr,stepper-control.yaml b/dts/bindings/stepper_control/zephyr,stepper-control.yaml
index 97a9a2a3a4a6d..5dec8f82bdcde 100644
--- a/dts/bindings/stepper_control/zephyr,stepper-control.yaml
+++ b/dts/bindings/stepper_control/zephyr,stepper-control.yaml
@@ -15,14 +15,12 @@ description: |
 compatible: "zephyr,stepper-control"
 
 properties:
-  stepper:
-    type: phandle
-    required: true
-    description: |
-      The phandle to the stepper motor driver node.
-
   step-tick-ns:
     type: int
     required: true
     description: |
       The time in nanoseconds between each step signal.
+
+  counter:
+    type: phandle
+    description: Counter used for generating step-accurate pulse signals.
diff --git a/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay b/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay
index b965467f2e31a..823cb6445c741 100644
--- a/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay
+++ b/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay
@@ -5,15 +5,10 @@
 	};
 };
 
-/ {
-	gpio_stepper: gpio_stepper {
-		compatible = "zephyr,gpio-stepper";
+&timers7 {
+	st,prescaler = <79>;
+	counter: counter {
 		status = "okay";
-		micro-step-res = <2>;
-		gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>,	/* D8 */
-			<&gpioc 7 GPIO_ACTIVE_HIGH>,	/* D9 */
-			<&gpiob 0 GPIO_ACTIVE_HIGH>,	/* D10 */
-			<&gpioa 7 GPIO_ACTIVE_HIGH>;	/* D11 */
 	};
 };
 
@@ -21,7 +16,16 @@
 	stepper_control: stepper_control {
 		compatible = "zephyr,stepper-control";
 		status = "okay";
-		stepper = <&gpio_stepper>;
 		step-tick-ns = <1000000>;
+		counter = <&counter>;
+		gpio_stepper: stepper {
+			compatible = "zephyr,gpio-stepper";
+			status = "okay";
+			micro-step-res = <2>;
+			gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>,	/* D8 */
+					<&gpioc 7 GPIO_ACTIVE_HIGH>,	/* D9 */
+					<&gpiob 0 GPIO_ACTIVE_HIGH>,	/* D10 */
+					<&gpioa 7 GPIO_ACTIVE_HIGH>;	/* D11 */
+		};
 	};
 };
diff --git a/samples/drivers/stepper/generic/prj.conf b/samples/drivers/stepper/generic/prj.conf
index 005ff7961ca71..c9151d72b4b5e 100644
--- a/samples/drivers/stepper/generic/prj.conf
+++ b/samples/drivers/stepper/generic/prj.conf
@@ -1,3 +1,4 @@
+CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_GENERATE_ISR_SAFE_EVENTS=y
 CONFIG_STEPPER_CONTROL=y
 CONFIG_LOG=y
 CONFIG_INPUT=y


Reviews:
user: login: andre-stefanov
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-13T21:17:03Z
user: login: andre-stefanov
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-13T21:35:36Z
user: login: jilaypandya
state: COMMENTED
author_association: OWNER
submitted_at: 2025-05-13T21:39:59Z
user: login: jilaypandya
state: COMMENTED
author_association: OWNER
submitted_at: 2025-05-13T21:40:41Z
user: login: andre-stefanov
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-13T21:42:58Z
user: login: jilaypandya
state: COMMENTED
author_association: OWNER
submitted_at: 2025-05-13T21:45:39Z

Review comments:
diff_hunk: @@ -0,0 +1,114 @@
+/*
+ * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
+#define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
+
+#include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+	const struct device *step_pin;
+	const struct device *dir_pin;
+	bool dual_edge;
+	bool invert_direction;
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: i think this should not be part of timing source
created_at: 2025-05-13T21:16:56Z
author_association: NONE
diff_hunk: @@ -7,32 +7,55 @@
 #define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
 
 #include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+};
+
+struct timing_source_data {
+	const struct device *motion_control_dev;
+	uint64_t microstep_interval_ns;
+	struct k_work_delayable stepper_dwork;
+
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
+	struct counter_top_cfg counter_top_cfg;
+	bool counter_running;
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+};
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: At the moment counter specific data is guarded by `CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING` while counter device is not. 

I think we should have separate structs for config and data per timing source type. This way we keep this interface clean of specific implementations and also allow other types of timing sources in the future without bloating the generic structs.

```C
struct stepper_timing_source_counter_config
{
	const struct device *counter;
};

struct stepper_timing_source_counter_data
{
	struct counter_top_cfg counter_top_cfg;
};

struct stepper_timing_source_work_cfg
{
};

struct stepper_timing_source_work_data
{
	struct k_work_delayable stepper_dwork;
};
```
created_at: 2025-05-13T21:22:58Z
author_association: NONE
diff_hunk: @@ -7,32 +7,55 @@
 #define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
 
 #include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+};
+
+struct timing_source_data {
+	const struct device *motion_control_dev;
+	uint64_t microstep_interval_ns;
+	struct k_work_delayable stepper_dwork;
+
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
+	struct counter_top_cfg counter_top_cfg;
+	bool counter_running;
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: counter_running is not needed because `is_running` api function does not seem to be used. also i don't know why we would want to use it from motion controller since motion controller is aware of the current running status itself.
created_at: 2025-05-13T21:27:57Z
author_association: NONE
diff_hunk: @@ -7,32 +7,55 @@
 #define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
 
 #include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+};
+
+struct timing_source_data {
+	const struct device *motion_control_dev;
+	uint64_t microstep_interval_ns;
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: do we really need to store the interval in the counter source data? after it was passed to the k_work api or counter api, we are not interested in this value anymore.
created_at: 2025-05-13T21:30:23Z
author_association: NONE
diff_hunk: @@ -7,32 +7,55 @@
 #define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
 
 #include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+};
+
+struct timing_source_data {
+	const struct device *motion_control_dev;
+	uint64_t microstep_interval_ns;
+	struct k_work_delayable stepper_dwork;
+
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
+	struct counter_top_cfg counter_top_cfg;
+	bool counter_running;
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+};
 
 /**
  * @brief Initialize the stepper timing source.
  *
- * @param dev Pointer to the device structure.
+ * @param config Pointer to the timing source configuration structure.
+ * @param data Pointer to the timing source data structure.
  * @return 0 on success, or a negative error code on failure.
  */
-typedef int (*stepper_timing_source_init)(const struct device *dev);
+typedef int (*stepper_timing_source_init)(const struct timing_source_config *config,
+					  struct timing_source_data *data);
 
 /**
  * @brief Update the stepper timing source.
  *
- * @param dev Pointer to the device structure.
+ * @param config Pointer to the timing source configuration structure.
+ * @param data Pointer to the timing source data structure.
  * @param microstep_interval_ns Step interval in nanoseconds.
  * @return 0 on success, or a negative error code on failure.
  */
-typedef int (*stepper_timing_source_update)(const struct device *dev,
+typedef int (*stepper_timing_source_update)(const struct timing_source_config *config,
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: the `stepper_timing_source_update` function can be actually completely replaced by the `stepper_timing_source_start` function or do i miss something?
created_at: 2025-05-13T21:32:43Z
author_association: NONE
diff_hunk: @@ -72,8 +97,14 @@ struct stepper_timing_source_api {
 };
 
 extern const struct stepper_timing_source_api step_work_timing_source_api;
-#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
 extern const struct stepper_timing_source_api step_counter_timing_source_api;
-#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+
+/**
+ * @brief Handle a timing signal and update the stepper position.
+ * @param dev Pointer to the device structure.
+ */
+void stepper_handle_timing_signal(const struct device *dev);
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: this looks like timing api is declaring a function which is then defined by stepper_controller. I would rather declare a callback type here and pass it to the timing_source as either config property (in case it wont ever change) or as data property.
created_at: 2025-05-13T21:35:20Z
author_association: NONE
diff_hunk: @@ -72,8 +97,14 @@ struct stepper_timing_source_api {
 };
 
 extern const struct stepper_timing_source_api step_work_timing_source_api;
-#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
 extern const struct stepper_timing_source_api step_counter_timing_source_api;
-#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+
+/**
+ * @brief Handle a timing signal and update the stepper position.
+ * @param dev Pointer to the device structure.
+ */
+void stepper_handle_timing_signal(const struct device *dev);
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: jilaypandya
body: I have just copy pasted or refactored the code out :) from the existing implementation. We can subsequently change all of this logic. Right now the goal is just refactoring without any logical changes and the idea is to refactor the code as is.

Coz right now while refactoring if we do any logical changes chances are high that we might introduce a bug
created_at: 2025-05-13T21:39:59Z
author_association: OWNER
diff_hunk: @@ -7,32 +7,55 @@
 #define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_
 
 #include <zephyr/device.h>
+#include <zephyr/kernel.h>
+#include <zephyr/drivers/counter.h>
+
+struct timing_source_config {
+	const struct device *counter;
+};
+
+struct timing_source_data {
+	const struct device *motion_control_dev;
+	uint64_t microstep_interval_ns;
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: jilaypandya
body: Yep we check the intervals value in move_by function 
created_at: 2025-05-13T21:40:41Z
author_association: OWNER
diff_hunk: @@ -72,8 +97,14 @@ struct stepper_timing_source_api {
 };
 
 extern const struct stepper_timing_source_api step_work_timing_source_api;
-#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
 extern const struct stepper_timing_source_api step_counter_timing_source_api;
-#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+
+/**
+ * @brief Handle a timing signal and update the stepper position.
+ * @param dev Pointer to the device structure.
+ */
+void stepper_handle_timing_signal(const struct device *dev);
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: andre-stefanov
body: alright :) then you can ignore most of my comments. but this particular one actually makes sense to be solved here because i think this method should not be migrated to the timing_source api and implemented by another module
created_at: 2025-05-13T21:42:58Z
author_association: NONE
diff_hunk: @@ -72,8 +97,14 @@ struct stepper_timing_source_api {
 };
 
 extern const struct stepper_timing_source_api step_work_timing_source_api;
-#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
+#ifdef CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING
 extern const struct stepper_timing_source_api step_counter_timing_source_api;
-#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
+#endif /* CONFIG_ZEPHYR_STEPPER_MOTION_CONTROL_COUNTER_TIMING */
+
+/**
+ * @brief Handle a timing signal and update the stepper position.
+ * @param dev Pointer to the device structure.
+ */
+void stepper_handle_timing_signal(const struct device *dev);
path: drivers/stepper_control/zephyr_stepper_motion_control/stepper_motion_control_timing_source.h
user: login: jilaypandya
body: I'll replace this with a callback
created_at: 2025-05-13T21:45:39Z
author_association: OWNER

PR comments:
user: login: jilaypandya
created_at: 2025-05-13T21:32:50Z
body: I tried this out with the gpio h bridge driver i have, @andre-stefanov could you probably test this out with the tmc2209 driver  with your board?
author_association: OWNER
user: login: andre-stefanov
created_at: 2025-05-13T22:03:08Z
body: > I tried this out with the gpio h bridge driver i have, @andre-stefanov could you probably test this out with the tmc2209 driver with your board?

sure i will take a look into this tomorrow with worker and counter
author_association: NONE