1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include "step_dir_stepper_timing_source.h"
7 #include "step_dir_stepper_common.h"
8
stepper_movement_delay(const struct device * dev)9 static k_timeout_t stepper_movement_delay(const struct device *dev)
10 {
11 const struct step_dir_stepper_common_data *data = dev->data;
12
13 if (data->microstep_interval_ns == 0) {
14 return K_FOREVER;
15 }
16
17 return K_NSEC(data->microstep_interval_ns);
18 }
19
stepper_work_step_handler(struct k_work * work)20 static void stepper_work_step_handler(struct k_work *work)
21 {
22 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
23 struct step_dir_stepper_common_data *data =
24 CONTAINER_OF(dwork, struct step_dir_stepper_common_data, stepper_dwork);
25
26 stepper_handle_timing_signal(data->dev);
27 }
28
step_work_timing_source_init(const struct device * dev)29 int step_work_timing_source_init(const struct device *dev)
30 {
31 struct step_dir_stepper_common_data *data = dev->data;
32
33 k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler);
34
35 return 0;
36 }
37
step_work_timing_source_update(const struct device * dev,const uint64_t microstep_interval_ns)38 int step_work_timing_source_update(const struct device *dev, const uint64_t microstep_interval_ns)
39 {
40 ARG_UNUSED(dev);
41 ARG_UNUSED(microstep_interval_ns);
42 return 0;
43 }
44
step_work_timing_source_start(const struct device * dev)45 int step_work_timing_source_start(const struct device *dev)
46 {
47 struct step_dir_stepper_common_data *data = dev->data;
48
49 return k_work_reschedule(&data->stepper_dwork, stepper_movement_delay(dev));
50 }
51
step_work_timing_source_stop(const struct device * dev)52 int step_work_timing_source_stop(const struct device *dev)
53 {
54 struct step_dir_stepper_common_data *data = dev->data;
55
56 return k_work_cancel_delayable(&data->stepper_dwork);
57 }
58
step_work_timing_source_needs_reschedule(const struct device * dev)59 bool step_work_timing_source_needs_reschedule(const struct device *dev)
60 {
61 ARG_UNUSED(dev);
62 return true;
63 }
64
step_work_timing_source_is_running(const struct device * dev)65 bool step_work_timing_source_is_running(const struct device *dev)
66 {
67 struct step_dir_stepper_common_data *data = dev->data;
68
69 return k_work_delayable_is_pending(&data->stepper_dwork);
70 }
71
72 const struct stepper_timing_source_api step_work_timing_source_api = {
73 .init = step_work_timing_source_init,
74 .update = step_work_timing_source_update,
75 .start = step_work_timing_source_start,
76 .needs_reschedule = step_work_timing_source_needs_reschedule,
77 .stop = step_work_timing_source_stop,
78 .is_running = step_work_timing_source_is_running,
79 };
80