88#include <zephyr/logging/log.h>
99LOG_MODULE_REGISTER (step_dir_stepper , CONFIG_STEPPER_LOG_LEVEL );
1010
11- static inline int step_dir_stepper_perform_step (const struct device * dev )
12- {
13- const struct step_dir_stepper_common_config * config = dev -> config ;
14- int ret ;
15-
16- ret = gpio_pin_toggle_dt (& config -> step_pin );
17- if (ret < 0 ) {
18- LOG_ERR ("Failed to toggle step pin: %d" , ret );
19- return ret ;
20- }
21-
22- if (!config -> dual_edge ) {
23- ret = gpio_pin_toggle_dt (& config -> step_pin );
24- if (ret < 0 ) {
25- LOG_ERR ("Failed to toggle step pin: %d" , ret );
26- return ret ;
27- }
28- }
29-
30- return 0 ;
31- }
32-
3311static inline int update_dir_pin (const struct device * dev )
3412{
3513 const struct step_dir_stepper_common_config * config = dev -> config ;
@@ -111,8 +89,38 @@ static void stepper_work_event_handler(struct k_work *work)
11189}
11290#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
11391
114- static void update_remaining_steps ( struct step_dir_stepper_common_data * data )
92+ static int start_stepping ( const struct device * dev )
11593{
94+ const struct step_dir_stepper_common_config * config = dev -> config ;
95+ struct step_dir_stepper_common_data * data = dev -> data ;
96+ int ret ;
97+
98+ ret = config -> timing_source -> update (dev , config -> dual_edge
99+ ? data -> microstep_interval_ns
100+ : data -> microstep_interval_ns / 2 );
101+ if (ret < 0 ) {
102+ LOG_ERR ("Failed to update timing source: %d" , ret );
103+ return ret ;
104+ }
105+
106+ ret = config -> timing_source -> start (dev );
107+ if (ret < 0 ) {
108+ LOG_ERR ("Failed to start timing source: %d" , ret );
109+ return ret ;
110+ }
111+
112+ stepper_handle_timing_signal (dev );
113+ return ret ;
114+ }
115+
116+ static void update_remaining_steps (const struct device * dev )
117+ {
118+ const struct step_dir_stepper_common_config * config = dev -> config ;
119+ struct step_dir_stepper_common_data * data = dev -> data ;
120+
121+ if (data -> step_high && !config -> dual_edge ) {
122+ return ;
123+ }
116124 if (atomic_get (& data -> step_count ) > 0 ) {
117125 atomic_dec (& data -> step_count );
118126 } else if (atomic_get (& data -> step_count ) < 0 ) {
@@ -138,7 +146,7 @@ static void position_mode_task(const struct device *dev)
138146 struct step_dir_stepper_common_data * data = dev -> data ;
139147 const struct step_dir_stepper_common_config * config = dev -> config ;
140148
141- update_remaining_steps (dev -> data );
149+ update_remaining_steps (dev );
142150
143151 if (config -> timing_source -> needs_reschedule (dev ) && atomic_get (& data -> step_count ) != 0 ) {
144152 (void )config -> timing_source -> start (dev );
@@ -159,13 +167,24 @@ static void velocity_mode_task(const struct device *dev)
159167
160168void stepper_handle_timing_signal (const struct device * dev )
161169{
170+ const struct step_dir_stepper_common_config * config = dev -> config ;
162171 struct step_dir_stepper_common_data * data = dev -> data ;
172+ int ret ;
163173
164- (void )step_dir_stepper_perform_step (dev );
165- if (data -> direction == STEPPER_DIRECTION_POSITIVE ) {
166- atomic_inc (& data -> actual_position );
167- } else {
168- atomic_dec (& data -> actual_position );
174+ atomic_val_t step_pin_status = atomic_xor (& data -> step_high , 1 ) ^ 1 ;
175+
176+ ret = gpio_pin_set_dt (& config -> step_pin , atomic_get (& step_pin_status ));
177+ if (ret < 0 ) {
178+ LOG_ERR ("Failed to set step pin: %d" , ret );
179+ return ;
180+ }
181+
182+ if (!atomic_get (& step_pin_status ) || config -> dual_edge ) {
183+ if (data -> direction == STEPPER_DIRECTION_POSITIVE ) {
184+ atomic_inc (& data -> actual_position );
185+ } else {
186+ atomic_dec (& data -> actual_position );
187+ }
169188 }
170189
171190 switch (data -> run_mode ) {
@@ -218,7 +237,6 @@ int step_dir_stepper_common_init(const struct device *dev)
218237 CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN );
219238 k_work_init (& data -> event_callback_work , stepper_work_event_handler );
220239#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
221-
222240 return 0 ;
223241}
224242
@@ -247,8 +265,8 @@ int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micr
247265 if (ret < 0 ) {
248266 K_SPINLOCK_BREAK ;
249267 }
250- config -> timing_source -> update ( dev , data -> microstep_interval_ns );
251- config -> timing_source -> start (dev );
268+
269+ ret = start_stepping (dev );
252270 }
253271
254272 return ret ;
@@ -265,9 +283,21 @@ int step_dir_stepper_common_set_microstep_interval(const struct device *dev,
265283 return - EINVAL ;
266284 }
267285
286+ if (config -> dual_edge && (microstep_interval_ns < config -> step_width_ns )) {
287+ LOG_ERR ("Step interval too small for configured step width" );
288+ return - EINVAL ;
289+ }
290+
291+ if (microstep_interval_ns < 2 * config -> step_width_ns ) {
292+ LOG_ERR ("Step interval too small for configured step width" );
293+ return - EINVAL ;
294+ }
295+
268296 K_SPINLOCK (& data -> lock ) {
269297 data -> microstep_interval_ns = microstep_interval_ns ;
270- config -> timing_source -> update (dev , microstep_interval_ns );
298+ config -> timing_source -> update (dev , config -> dual_edge
299+ ? data -> microstep_interval_ns
300+ : data -> microstep_interval_ns / 2 );
271301 }
272302
273303 return 0 ;
@@ -315,7 +345,6 @@ int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving)
315345int step_dir_stepper_common_run (const struct device * dev , const enum stepper_direction direction )
316346{
317347 struct step_dir_stepper_common_data * data = dev -> data ;
318- const struct step_dir_stepper_common_config * config = dev -> config ;
319348 int ret ;
320349
321350 K_SPINLOCK (& data -> lock ) {
@@ -325,8 +354,8 @@ int step_dir_stepper_common_run(const struct device *dev, const enum stepper_dir
325354 if (ret < 0 ) {
326355 K_SPINLOCK_BREAK ;
327356 }
328- config -> timing_source -> update ( dev , data -> microstep_interval_ns );
329- config -> timing_source -> start (dev );
357+
358+ ret = start_stepping (dev );
330359 }
331360
332361 return ret ;
@@ -335,6 +364,7 @@ int step_dir_stepper_common_run(const struct device *dev, const enum stepper_dir
335364int step_dir_stepper_common_stop (const struct device * dev )
336365{
337366 const struct step_dir_stepper_common_config * config = dev -> config ;
367+ struct step_dir_stepper_common_data * data = dev -> data ;
338368 int ret ;
339369
340370 ret = config -> timing_source -> stop (dev );
@@ -343,7 +373,18 @@ int step_dir_stepper_common_stop(const struct device *dev)
343373 return ret ;
344374 }
345375
376+ if (!config -> dual_edge && atomic_cas (& data -> step_high , 1 , 0 )) {
377+ gpio_pin_set_dt (& config -> step_pin , 0 );
378+ /* If we are in the high state, we need to account for that step */
379+ if (data -> direction == STEPPER_DIRECTION_POSITIVE ) {
380+ atomic_inc (& data -> actual_position );
381+ } else {
382+ atomic_dec (& data -> actual_position );
383+ }
384+ }
385+
346386 stepper_trigger_callback (dev , STEPPER_EVENT_STOPPED );
387+
347388 return 0 ;
348389}
349390
0 commit comments