diff --git a/samples/drivers/stepper/index.rst b/samples/drivers/stepper/index.rst new file mode 100644 index 00000000000..7592d15577c --- /dev/null +++ b/samples/drivers/stepper/index.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: stepper + :name: Stepper + :show-listing: + + These samples demonstrate how to use the :ref:`stepper ` driver API. diff --git a/samples/drivers/stepper/tmc50xx/CMakeLists.txt b/samples/drivers/stepper/tmc50xx/CMakeLists.txt new file mode 100644 index 00000000000..7d5a7d600f2 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/CMakeLists.txt @@ -0,0 +1,10 @@ + # SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + # SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(tmc50xx) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/drivers/stepper/tmc50xx/Kconfig b/samples/drivers/stepper/tmc50xx/Kconfig new file mode 100644 index 00000000000..59e2cc9f8d6 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/Kconfig @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "TMC50XX sample application" + +config STEPS_PER_REV + int "Steps per revolution" + default 200 + +config PING_PONG_N_REV + int "Change direction every N revolutions" + default 1 + +config MAX_VELOCITY_MULTIPLIER + int "Max velocity multiplier" + default 1 + +source "Kconfig.zephyr" diff --git a/samples/drivers/stepper/tmc50xx/README.rst b/samples/drivers/stepper/tmc50xx/README.rst new file mode 100644 index 00000000000..17191c3f374 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/README.rst @@ -0,0 +1,49 @@ +.. zephyr:code-sample:: tmc50xx + :name: TMC50XX stepper + :relevant-api: stepper_interface + + + Rotate a TMC50XX stepper motor and change velocity at runtime. + +Description +*********** + +This sample application periodically spins the stepper clockwise and counterclockwise depending on +the :kconfig:option:`CONFIG_PING_PONG_N_REV` configuration. + +References +********** + + - TMC5041: https://www.analog.com/media/en/technical-documentation/data-sheets/TMC5041_datasheet_rev1.16.pdf + - TMC5072: https://www.analog.com/media/en/technical-documentation/data-sheets/TMC5072_datasheet_rev1.26.pdf + +Wiring +******* + +This sample uses the TMC5072 BOB controlled using the SPI interface. The board's Devicetree must define +a ``stepper`` alias for the stepper motor node. + +Building and Running +******************** + +This project spins the stepper and outputs the events to the console. It requires an TMC50XX stepper +driver. It should work with any platform featuring a SPI peripheral interface. +It does not work on QEMU. + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/stepper/tmc50xx + :board: nucleo_g071rb + :goals: build flash + +Sample Output +============= + +.. code-block:: console + + Starting tmc50xx stepper sample + stepper is 0x8007240, name is tmc_stepper@0 + stepper_callback steps completed changing direction + stepper_callback steps completed changing direction + stepper_callback steps completed changing direction + + diff --git a/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay b/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay new file mode 100644 index 00000000000..e3b70a35531 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay @@ -0,0 +1,52 @@ +/ { + aliases { + stepper = &tmc_stepper; + }; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; + status = "okay"; + tmc50xx: tmc50xx@0 { + compatible = "adi,tmc50xx"; + reg = <0>; + spi-max-frequency = ; /* Maximum SPI bus frequency */ + + #address-cells = <1>; + #size-cells = <0>; + + clock-frequency = ; /* Internal/External Clock frequency */ + + tmc_stepper: tmc_stepper@0 { + status = "okay"; + reg = <0>; + + /* common stepper controller settings */ + micro-step-res = <256>; + + /* ADI TMC stallguard settings specific to TMC50XX */ + activate-stallguard2; + stallguard-velocity-check-interval-ms=<1000>; + stallguard2-threshold=<30>; + stallguard-threshold-velocity=<200000>; + + /* ADI TMC ramp generator as well as current settings */ + vstart = <1000>; + vstop = <10>; + a1 = <10000>; + v1 = <50000>; + d1 = <14000>; + vmax = <900000>; + amax = <50000>; + dmax = <7000>; + tzerowait = <100>; + vhigh = <900000>; + vcoolthrs = <900000>; + ihold = <1>; + irun = <10>; + iholddelay = <1>; + }; + }; +}; diff --git a/samples/drivers/stepper/tmc50xx/prj.conf b/samples/drivers/stepper/tmc50xx/prj.conf new file mode 100644 index 00000000000..f17d0707cf5 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/prj.conf @@ -0,0 +1,2 @@ +CONFIG_STEPPER=y +CONFIG_LOG=y diff --git a/samples/drivers/stepper/tmc50xx/sample.yaml b/samples/drivers/stepper/tmc50xx/sample.yaml new file mode 100644 index 00000000000..fd600756c0d --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/sample.yaml @@ -0,0 +1,8 @@ +sample: + name: TMC50XX Stepper Sample +tests: + sample.stepper.tmc50xx: + harness: stepper + tags: stepper + platform_allow: nucleo_g071rb + depends_on: spi diff --git a/samples/drivers/stepper/tmc50xx/src/main.c b/samples/drivers/stepper/tmc50xx/src/main.c new file mode 100644 index 00000000000..b5cb96632a1 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/src/main.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +const struct device *stepper = DEVICE_DT_GET(DT_ALIAS(stepper)); + +int32_t ping_pong_target_position = CONFIG_STEPS_PER_REV * CONFIG_PING_PONG_N_REV * + DT_PROP(DT_ALIAS(stepper), micro_step_res); + +K_SEM_DEFINE(steps_completed_sem, 0, 1); + +void stepper_callback(const struct device *dev, const enum stepper_event event, void *user_data) +{ + switch (event) { + case STEPPER_EVENT_STEPS_COMPLETED: + k_sem_give(&steps_completed_sem); + break; + default: + break; + } +} + +int main(void) +{ + printf("Starting tmc50xx stepper sample\n"); + if (!device_is_ready(stepper)) { + printf("Device %s is not ready\n", stepper->name); + return -ENODEV; + } + printf("stepper is %p, name is %s\n", stepper, stepper->name); + + stepper_set_event_callback(stepper, stepper_callback, NULL); + stepper_enable(stepper, true); + stepper_set_reference_position(stepper, 0); + stepper_move_by(stepper, ping_pong_target_position); + + /* Change Max Velocity during runtime */ + int32_t tmc_velocity = DT_PROP(DT_ALIAS(stepper), vmax) * CONFIG_MAX_VELOCITY_MULTIPLIER; + (void)tmc50xx_stepper_set_max_velocity(stepper, tmc_velocity); + + for (;;) { + if (k_sem_take(&steps_completed_sem, K_FOREVER) == 0) { + ping_pong_target_position *= -1; + stepper_move_by(stepper, ping_pong_target_position); + } + } + return 0; +}