forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: stepper: Add adi,tmc2209 driver
Adds the tmc2209 driver using the step dir interface. Signed-off-by: Fabian Blatz <[email protected]>
- Loading branch information
1 parent
ba2aee2
commit 6e79997
Showing
7 changed files
with
283 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <[email protected]> | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config STEPPER_ADI_TMC2209 | ||
bool "Activate trinamic tmc2209 stepper driver" | ||
depends on DT_HAS_ADI_TMC2209_ENABLED | ||
select STEP_DIR_STEPPER | ||
default y | ||
help | ||
Stepper driver for TMC2209. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <[email protected]> | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config STEPPER_ADI_TMC5041 | ||
bool "Activate trinamic tmc5041 stepper driver" | ||
depends on DT_HAS_ADI_TMC5041_ENABLED && STEPPER_ADI_TMC | ||
select STEPPER_ADI_TMC_SPI | ||
default y | ||
help | ||
Stepper driver for TMC5041. | ||
|
||
config STEPPER_ADI_TMC5041_RAMPSTAT_POLL | ||
bool "TMC5041 poll ramp status" | ||
depends on STEPPER_ADI_TMC5041 | ||
default y | ||
help | ||
When enabled, the ramp status will be polled on TMC5041, to check for events: | ||
- TMC5041_POS_REACHED_EVENT | ||
- TMC5041_STOP_SG_EVENT | ||
- TMC5041_STOP_LEFT_EVENT | ||
- TMC5041_STOP_RIGHT_EVENT | ||
|
||
config STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC | ||
int "TMC5041 poll ramp status interval in ms" | ||
depends on STEPPER_ADI_TMC5041_RAMPSTAT_POLL | ||
default 100 | ||
help | ||
The interval in ms to poll the ramp status on TMC5041. |
196 changes: 196 additions & 0 deletions
196
drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
/* | ||
* SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <[email protected]> | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "../step_dir_stepper_common.h" | ||
|
||
#include <zephyr/logging/log.h> | ||
LOG_MODULE_REGISTER(tmc22xx, CONFIG_STEPPER_LOG_LEVEL); | ||
|
||
#define MSX_PIN_COUNT 2 | ||
#define MSX_PIN_STATE_COUNT 4 | ||
|
||
struct tmc22xx_config { | ||
struct step_dir_stepper_common_config common; | ||
const struct gpio_dt_spec enable_pin; | ||
const struct gpio_dt_spec *msx_pins; | ||
enum stepper_micro_step_resolution *msx_resolutions; | ||
}; | ||
|
||
struct tmc22xx_data { | ||
struct step_dir_stepper_common_data common; | ||
enum stepper_micro_step_resolution resolution; | ||
}; | ||
|
||
STEP_DIR_STEPPER_STRUCT_CHECK(struct tmc22xx_config, struct tmc22xx_data); | ||
|
||
static int tmc22xx_stepper_enable(const struct device *dev, const bool enable) | ||
{ | ||
const struct tmc22xx_config *config = dev->config; | ||
|
||
LOG_DBG("Stepper motor controller %s %s", dev->name, enable ? "enabled" : "disabled"); | ||
if (enable) { | ||
return gpio_pin_set_dt(&config->enable_pin, 1); | ||
} else { | ||
return gpio_pin_set_dt(&config->enable_pin, 0); | ||
} | ||
} | ||
|
||
static int tmc22xx_stepper_set_micro_step_res(const struct device *dev, | ||
enum stepper_micro_step_resolution micro_step_res) | ||
{ | ||
struct tmc22xx_data *data = dev->data; | ||
const struct tmc22xx_config *config = dev->config; | ||
int ret; | ||
|
||
if (!config->msx_pins) { | ||
LOG_ERR("Microstep resolution pins are not configured"); | ||
return -ENODEV; | ||
} | ||
|
||
for (uint8_t i = 0; i < MSX_PIN_STATE_COUNT; i++) { | ||
if (micro_step_res != config->msx_resolutions[i]) { | ||
continue; | ||
} | ||
|
||
ret = gpio_pin_set_dt(&config->msx_pins[0], i & 0x01); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to set MS1 pin: %d", ret); | ||
return ret; | ||
} | ||
|
||
ret = gpio_pin_set_dt(&config->msx_pins[1], (i & 0x02) >> 1); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to set MS2 pin: %d", ret); | ||
return ret; | ||
} | ||
|
||
data->resolution = micro_step_res; | ||
return 0; | ||
} | ||
|
||
LOG_ERR("Unsupported microstep resolution: %d", micro_step_res); | ||
return -EINVAL; | ||
} | ||
|
||
static int tmc22xx_stepper_get_micro_step_res(const struct device *dev, | ||
enum stepper_micro_step_resolution *micro_step_res) | ||
{ | ||
struct tmc22xx_data *data = dev->data; | ||
|
||
*micro_step_res = data->resolution; | ||
return 0; | ||
} | ||
|
||
static int tmc22xx_stepper_configure_msx_pins(const struct device *dev) | ||
{ | ||
const struct tmc22xx_config *config = dev->config; | ||
int ret; | ||
|
||
for (uint8_t i = 0; i < MSX_PIN_COUNT; i++) { | ||
if (!gpio_is_ready_dt(&config->msx_pins[i])) { | ||
LOG_ERR("MSX pin %u are not ready", i); | ||
return -ENODEV; | ||
} | ||
|
||
ret = gpio_pin_configure_dt(&config->msx_pins[i], GPIO_OUTPUT); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to configure msx pin %u", i); | ||
return ret; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
static int tmc22xx_stepper_init(const struct device *dev) | ||
{ | ||
const struct tmc22xx_config *config = dev->config; | ||
struct tmc22xx_data *data = dev->data; | ||
int ret; | ||
|
||
if (!gpio_is_ready_dt(&config->enable_pin)) { | ||
LOG_ERR("GPIO pins are not ready"); | ||
return -ENODEV; | ||
} | ||
|
||
ret = gpio_pin_configure_dt(&config->enable_pin, GPIO_OUTPUT); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to configure enable pin: %d", ret); | ||
return ret; | ||
} | ||
|
||
if (config->msx_pins) { | ||
ret = tmc22xx_stepper_configure_msx_pins(dev); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to configure MSX pins: %d", ret); | ||
return ret; | ||
} | ||
|
||
ret = tmc22xx_stepper_set_micro_step_res(dev, data->resolution); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to set microstep resolution: %d", ret); | ||
return ret; | ||
} | ||
} | ||
|
||
ret = step_dir_stepper_common_init(dev); | ||
if (ret < 0) { | ||
LOG_ERR("Failed to init step dir common stepper: %d", ret); | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static DEVICE_API(stepper, tmc22xx_stepper_api) = { | ||
.enable = tmc22xx_stepper_enable, | ||
.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_max_velocity = step_dir_stepper_common_set_max_velocity, | ||
.run = step_dir_stepper_common_run, | ||
.set_event_callback = step_dir_stepper_common_set_event_callback, | ||
.set_micro_step_res = tmc22xx_stepper_set_micro_step_res, | ||
.get_micro_step_res = tmc22xx_stepper_get_micro_step_res, | ||
}; | ||
|
||
#define TMC22XX_STEPPER_DEFINE(inst, msx_table) \ | ||
IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, msx_gpios), ( \ | ||
static const struct gpio_dt_spec tmc22xx_stepper_msx_pins_##inst[] = { \ | ||
DT_INST_FOREACH_PROP_ELEM_SEP( \ | ||
inst, msx_gpios, GPIO_DT_SPEC_GET_BY_IDX, (,) \ | ||
), \ | ||
}; \ | ||
BUILD_ASSERT( \ | ||
ARRAY_SIZE(tmc22xx_stepper_msx_pins_##inst) == MSX_PIN_COUNT, \ | ||
"Two microstep config pins needed"); \ | ||
)) \ | ||
\ | ||
static const struct tmc22xx_config tmc22xx_config_##inst = { \ | ||
.common = STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst), \ | ||
.enable_pin = GPIO_DT_SPEC_INST_GET(inst, enable_gpios), \ | ||
.msx_pins = DT_INST_NODE_HAS_PROP(inst, msx_gpios) \ | ||
? tmc22xx_stepper_msx_pins_##inst \ | ||
: NULL, \ | ||
.msx_resolutions = msx_table, \ | ||
}; \ | ||
static struct tmc22xx_data tmc22xx_data_##inst = { \ | ||
.common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ | ||
.resolution = DT_INST_PROP(inst, micro_step_res), \ | ||
}; \ | ||
DEVICE_DT_INST_DEFINE(inst, tmc22xx_stepper_init, NULL, &tmc22xx_data_##inst, \ | ||
&tmc22xx_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ | ||
&tmc22xx_stepper_api); | ||
|
||
#define DT_DRV_COMPAT adi_tmc2209 | ||
static enum stepper_micro_step_resolution tmc2209_msx_resolutions[MSX_PIN_STATE_COUNT] = { | ||
STEPPER_MICRO_STEP_8, | ||
STEPPER_MICRO_STEP_32, | ||
STEPPER_MICRO_STEP_64, | ||
STEPPER_MICRO_STEP_16, | ||
}; | ||
DT_INST_FOREACH_STATUS_OKAY_VARGS(TMC22XX_STEPPER_DEFINE, tmc2209_msx_resolutions) | ||
#undef DT_DRV_COMPAT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <[email protected]> | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
description: | | ||
Analog Devices TMC2209 stepper motor driver. | ||
Example: | ||
tmc2209: tmc2209 { | ||
compatible = "adi,tmc2209"; | ||
enable-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; | ||
msx-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>, | ||
<&gpio0 2 GPIO_ACTIVE_HIGH>; | ||
step-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; | ||
direction-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; | ||
dual-edge-step; | ||
} | ||
compatible: "adi,tmc2209" | ||
|
||
include: | ||
- name: stepper-controller.yaml | ||
property-allowlist: | ||
- micro-step-res | ||
- step-gpios | ||
- direction-gpios | ||
|
||
properties: | ||
enable-gpios: | ||
type: phandle-array | ||
description: | | ||
GPIO pins used to control the enable signal of the motor driver. | ||
msx-gpios: | ||
type: phandle-array | ||
description: | | ||
An array of GPIO pins for configuring the microstep resolution of the driver. | ||
The pins should be listed in the following order: | ||
- MS1 | ||
- MS2 | ||
dual-edge-step: | ||
type: boolean | ||
description: | | ||
If present, the stepper motor controller supports dual edge step signals. | ||
This means that the step signal can be toggled on both the rising and falling edge. |