diff --git a/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c b/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c index df2daa69181..a9fef0a6e44 100644 --- a/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c +++ b/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c @@ -71,7 +71,7 @@ static int tmc22xx_stepper_set_micro_step_res(const struct device *dev, } LOG_ERR("Unsupported microstep resolution: %d", micro_step_res); - return -EINVAL; + return -ENOTSUP; } static int tmc22xx_stepper_get_micro_step_res(const struct device *dev, diff --git a/drivers/stepper/gpio_stepper_controller.c b/drivers/stepper/gpio_stepper_controller.c index d71ccca778c..8ce60fefc8c 100644 --- a/drivers/stepper/gpio_stepper_controller.c +++ b/drivers/stepper/gpio_stepper_controller.c @@ -289,6 +289,7 @@ static int gpio_stepper_set_micro_step_res(const struct device *dev, enum stepper_micro_step_resolution micro_step_res) { struct gpio_stepper_data *data = dev->data; + int err = 0; K_SPINLOCK(&data->lock) { switch (micro_step_res) { @@ -298,10 +299,10 @@ static int gpio_stepper_set_micro_step_res(const struct device *dev, break; default: LOG_ERR("Unsupported micro step resolution %d", micro_step_res); - return -ENOTSUP; + err = -ENOTSUP; } } - return 0; + return err; } static int gpio_stepper_get_micro_step_res(const struct device *dev, diff --git a/drivers/stepper/ti/drv8424.c b/drivers/stepper/ti/drv8424.c index 9fd172fc0ec..a77d2a5bc3f 100644 --- a/drivers/stepper/ti/drv8424.c +++ b/drivers/stepper/ti/drv8424.c @@ -212,7 +212,7 @@ static int drv8424_set_micro_step_res(const struct device *dev, m1_value = 2; break; default: - return -EINVAL; + return -ENOTSUP; }; ret = drv8424_set_microstep_pin(dev, &config->m0_pin, m0_value); diff --git a/tests/drivers/stepper/drv8424/api/src/main.c b/tests/drivers/stepper/drv8424/api/src/main.c index ca0674ad5af..fc85f45b695 100644 --- a/tests/drivers/stepper/drv8424/api/src/main.c +++ b/tests/drivers/stepper/drv8424/api/src/main.c @@ -79,15 +79,6 @@ ZTEST_F(drv8424_api, test_micro_step_res_set) res); } -ZTEST_F(drv8424_api, test_micro_step_res_set_incorrect_value_detection) -{ - int ret = 0; - - ret = stepper_set_micro_step_res(fixture->dev, 3); - zassert_equal(ret, -EINVAL, "Command should fail with error %d but returned %d", -EINVAL, - ret); -} - ZTEST_F(drv8424_api, test_actual_position_set) { int32_t pos = 100u; diff --git a/tests/drivers/stepper/stepper_api/src/main.c b/tests/drivers/stepper/stepper_api/src/main.c index 5138d7219a8..a2d61185088 100644 --- a/tests/drivers/stepper/stepper_api/src/main.c +++ b/tests/drivers/stepper/stepper_api/src/main.c @@ -1,6 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya - * + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +18,18 @@ struct k_poll_signal stepper_signal; struct k_poll_event stepper_event; void *user_data_received; +#define POLL_AND_CHECK_SIGNAL(signal, event, expected_event, timeout) \ + ({ \ + do { \ + (void)k_poll(&(event), 1, timeout); \ + unsigned int signaled; \ + int result; \ + k_poll_signal_check(&(signal), &signaled, &result); \ + zassert_equal(signaled, 1, "Signal not set"); \ + zassert_equal(result, (expected_event), "Signal not set"); \ + } while (0); \ + }) + static void stepper_print_event_callback(const struct device *dev, enum stepper_event event, void *user_data) { @@ -38,12 +49,15 @@ static void stepper_print_event_callback(const struct device *dev, enum stepper_ case STEPPER_EVENT_STALL_DETECTED: k_poll_signal_raise(&stepper_signal, STEPPER_EVENT_STALL_DETECTED); break; + case STEPPER_EVENT_STOPPED: + k_poll_signal_raise(&stepper_signal, STEPPER_EVENT_STOPPED); + break; default: break; } LOG_DBG("Event %d, %s called for %s, expected for %s\n", event, __func__, - dev_callback->name, dev->name); + dev_callback->name, dev->name); } static void *stepper_setup(void) @@ -56,7 +70,7 @@ static void *stepper_setup(void) k_poll_signal_init(&stepper_signal); k_poll_event_init(&stepper_event, K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &stepper_signal); - user_data_received = NULL; + zassert_not_null(fixture.dev); (void)stepper_enable(fixture.dev, true); return &fixture; @@ -66,12 +80,22 @@ static void stepper_before(void *f) { struct stepper_fixture *fixture = f; (void)stepper_set_reference_position(fixture->dev, 0); + k_poll_signal_reset(&stepper_signal); + + user_data_received = NULL; } ZTEST_SUITE(stepper, NULL, stepper_setup, stepper_before, NULL, NULL); -ZTEST_F(stepper, test_micro_step_res) +ZTEST_F(stepper, test_set_micro_step_res_incorrect) +{ + int ret = stepper_set_micro_step_res(fixture->dev, 127); + + zassert_equal(ret, -ENOTSUP, "Incorrect micro step resolution should return -ENOTSUP"); +} + +ZTEST_F(stepper, test_get_micro_step_res) { enum stepper_micro_step_resolution res; (void)stepper_get_micro_step_res(fixture->dev, &res); @@ -79,33 +103,66 @@ ZTEST_F(stepper, test_micro_step_res) "Micro step resolution not set correctly"); } +ZTEST_F(stepper, test_set_micro_step_interval_invalid_zero) +{ + int err = stepper_set_microstep_interval(fixture->dev, 0); + + zassert_equal(err, -EINVAL, "ustep interval cannot be zero"); +} + ZTEST_F(stepper, test_actual_position) { int32_t pos = 100u; + (void)stepper_set_reference_position(fixture->dev, pos); (void)stepper_get_actual_position(fixture->dev, &pos); zassert_equal(pos, 100u, "Actual position not set correctly"); } -ZTEST_F(stepper, test_target_position) +ZTEST_F(stepper, test_target_position_w_fixed_step_interval) { - int32_t pos = 100u; + int32_t pos = 10u; - (void)stepper_set_microstep_interval(fixture->dev, 10000); + (void)stepper_set_microstep_interval(fixture->dev, 100 * USEC_PER_SEC); /* Pass the function name as user data */ (void)stepper_set_event_callback(fixture->dev, fixture->callback, (void *)fixture->dev); (void)stepper_move_to(fixture->dev, pos); - (void)k_poll(&stepper_event, 1, K_SECONDS(5)); - unsigned int signaled; - int result; + /* timeout is set with 20% tolerance */ + POLL_AND_CHECK_SIGNAL(stepper_signal, stepper_event, STEPPER_EVENT_STEPS_COMPLETED, + K_MSEC(pos * 120)); - k_poll_signal_check(&stepper_signal, &signaled, &result); - zassert_equal(signaled, 1, "Signal not set"); - zassert_equal(result, STEPPER_EVENT_STEPS_COMPLETED, "Signal not set"); (void)stepper_get_actual_position(fixture->dev, &pos); - zassert_equal(pos, 100u, "Target position should be %d but is %d", 100u, pos); + zassert_equal(pos, 10u, "Target position should be %d but is %d", 10u, pos); zassert_equal(user_data_received, fixture->dev, "User data not received"); } + +ZTEST_F(stepper, test_stop) +{ + (void)stepper_set_event_callback(fixture->dev, fixture->callback, (void *)fixture->dev); + + /* Run the stepper in positive direction */ + (void)stepper_run(fixture->dev, STEPPER_DIRECTION_POSITIVE); + + /* Stop the stepper */ + int ret = stepper_stop(fixture->dev); + bool is_moving; + + if (ret == 0) { + POLL_AND_CHECK_SIGNAL(stepper_signal, stepper_event, STEPPER_EVENT_STOPPED, + K_NO_WAIT); + zassert_equal(user_data_received, fixture->dev, "User data not received"); + + /* Check if the stepper is stopped */ + stepper_is_moving(fixture->dev, &is_moving); + zassert_equal(is_moving, false, "Stepper is still moving"); + } else if (ret == -ENOSYS) { + stepper_is_moving(fixture->dev, &is_moving); + zassert_equal(is_moving, true, + "Stepper should be moving since stop is not implemented"); + } else { + zassert_unreachable("Stepper stop failed"); + } +}