drivers: stepper: adi_tmc: Prepare for tmc51xx support

Add Kconfig option. Find common regs. Update ramp generator data.

Signed-off-by: Anders Nielsen <anders.nielsen@prevas.dk>
This commit is contained in:
Anders Nielsen 2025-04-15 15:27:01 +02:00 committed by Benjamin Cabé
commit 242e6ea12a
6 changed files with 143 additions and 45 deletions

View file

@ -21,5 +21,6 @@ comment "Trinamic Stepper Drivers"
rsource "Kconfig.tmc22xx"
rsource "Kconfig.tmc50xx"
rsource "Kconfig.tmc51xx"
endif # STEPPER_ADI_TMC

View file

@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 Prevas A/S
# SPDX-License-Identifier: Apache-2.0
config STEPPER_ADI_TMC51XX
bool "Activate trinamic tmc51xx stepper driver"
depends on DT_HAS_ADI_TMC51XX_ENABLED && STEPPER_ADI_TMC
select STEPPER_ADI_TMC_SPI
default y
module = TMC51XX
module-str = tmc51xx
rsource "Kconfig.tmc_rampgen_template"

View file

@ -15,7 +15,6 @@
#include "adi_tmc5xxx_common.h"
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(tmc50xx, CONFIG_STEPPER_LOG_LEVEL);
struct tmc50xx_data {
@ -730,7 +729,7 @@ static DEVICE_API(stepper, tmc50xx_stepper_api) = {
stallguard_velocity_check_interval_ms), \
.is_sg_enabled = DT_PROP(child, activate_stallguard2), \
IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, \
(.default_ramp_config = TMC_RAMP_DT_SPEC_GET(child))) };
(.default_ramp_config = TMC_RAMP_DT_SPEC_GET_TMC50XX(child))) };
#define TMC50XX_STEPPER_DATA_DEFINE(child) \
static struct tmc50xx_stepper_data tmc50xx_stepper_data_##child = { \

View file

@ -7,6 +7,7 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG
* SPDX-FileCopyrightText: Copyright (c) 2025 Prevas A/S
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,12 +19,12 @@ extern "C" {
#endif
/** Common Registers for TMC50XX and TMC51XX */
#if defined(CONFIG_STEPPER_ADI_TMC50XX)
#if defined(CONFIG_STEPPER_ADI_TMC50XX) || defined(CONFIG_STEPPER_ADI_TMC51XX)
#define TMC5XXX_WRITE_BIT 0x80U
#define TMC5XXX_ADDRESS_MASK 0x7FU
#define TMC5XXX_CLOCK_FREQ_SHIFT 24
#define TMC5XXX_CLOCK_FREQ_SHIFT 24
#define TMC5XXX_GCONF 0x00
#define TMC5XXX_GSTAT 0x01
@ -79,12 +80,32 @@ extern "C" {
#define TMC5XXX_DRV_STATUS_SG_STATUS_MASK BIT(24)
#define TMC5XXX_DRV_STATUS_SG_STATUS_SHIFT 24
#define TMC50XX_MOTOR_ADDR(m) (0x20 << (m))
#define TMC50XX_MOTOR_ADDR_DRV(m) ((m) << 4)
#define TMC50XX_RAMPMODE(motor) (0x00 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_XACTUAL(motor) (0x01 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VACTUAL(motor) (0x02 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VSTART(motor) (0x03 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_A1(motor) (0x04 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_V1(motor) (0x05 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_AMAX(motor) (0x06 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VMAX(motor) (0x07 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_DMAX(motor) (0x08 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_D1(motor) (0x0A | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VSTOP(motor) (0x0B | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_TZEROWAIT(motor) (0x0C | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_XTARGET(motor) (0x0D | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_SWMODE(motor) (0x14 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_RAMPSTAT(motor) (0x15 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_CHOPCONF(motor) (0x6C | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_COOLCONF(motor) (0x6D | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_DRVSTATUS(motor) (0x6F | TMC50XX_MOTOR_ADDR_DRV(motor))
#endif
#ifdef CONFIG_STEPPER_ADI_TMC50XX
#define TMC50XX_MOTOR_ADDR(m) (0x20 << (m))
#define TMC50XX_MOTOR_ADDR_DRV(m) ((m) << 4)
#define TMC50XX_MOTOR_ADDR_PWM(m) ((m) << 3)
/**
@ -102,24 +123,9 @@ extern "C" {
#define TMC50XX_PWMCONF(motor) (0x10 | TMC50XX_MOTOR_ADDR_PWM(motor))
#define TMC50XX_PWM_STATUS(motor) (0x11 | TMC50XX_MOTOR_ADDR_PWM(motor))
#define TMC50XX_RAMPMODE(motor) (0x00 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_XACTUAL(motor) (0x01 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VACTUAL(motor) (0x02 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VSTART(motor) (0x03 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_A1(motor) (0x04 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_V1(motor) (0x05 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_AMAX(motor) (0x06 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VMAX(motor) (0x07 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_DMAX(motor) (0x08 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_D1(motor) (0x0A | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VSTOP(motor) (0x0B | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_TZEROWAIT(motor) (0x0C | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_XTARGET(motor) (0x0D | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_IHOLD_IRUN(motor) (0x10 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VCOOLTHRS(motor) (0x11 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_VHIGH(motor) (0x12 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_SWMODE(motor) (0x14 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_RAMPSTAT(motor) (0x15 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_XLATCH(motor) (0x16 | TMC50XX_MOTOR_ADDR(motor))
#define TMC50XX_MSLUT0(motor) (0x60 | TMC50XX_MOTOR_ADDR_DRV(motor))
@ -134,12 +140,43 @@ extern "C" {
#define TMC50XX_MSLUTSTART(motor) (0x69 | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_MSCNT(motor) (0x6A | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_MSCURACT(motor) (0x6B | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_CHOPCONF(motor) (0x6C | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_COOLCONF(motor) (0x6D | TMC50XX_MOTOR_ADDR_DRV(motor))
#define TMC50XX_DRVSTATUS(motor) (0x6F | TMC50XX_MOTOR_ADDR_DRV(motor))
#endif /* CONFIG_STEPPER_ADI_TMC50XX */
#ifdef CONFIG_STEPPER_ADI_TMC51XX
#define TMC51XX_GCONF_EN_PWM_MODE_SHIFT 2
#define TMC51XX_GCONF_SHAFT_SHIFT 4
#define TMC51XX_GCONF_TEST_MODE_SHIFT 17
#define TMC51XX_IHOLD_IRUN 0x10
#define TMC51XX_TPOWER_DOWN 0x11
#define TMC51XX_TSTEP 0x12
#define TMC51XX_TPWMTHRS 0x13
#define TMC51XX_TCOOLTHRS 0x14
#define TMC51XX_THIGH 0x15
#define TMC51XX_RAMPMODE TMC50XX_RAMPMODE(0)
#define TMC51XX_XACTUAL TMC50XX_XACTUAL(0)
#define TMC51XX_VACTUAL TMC50XX_VACTUAL(0)
#define TMC51XX_VSTART TMC50XX_VSTART(0)
#define TMC51XX_A1 TMC50XX_A1(0)
#define TMC51XX_V1 TMC50XX_V1(0)
#define TMC51XX_AMAX TMC50XX_AMAX(0)
#define TMC51XX_VMAX TMC50XX_VMAX(0)
#define TMC51XX_DMAX TMC50XX_DMAX(0)
#define TMC51XX_D1 TMC50XX_D1(0)
#define TMC51XX_VSTOP TMC50XX_VSTOP(0)
#define TMC51XX_TZEROWAIT TMC50XX_TZEROWAIT(0)
#define TMC51XX_XTARGET TMC50XX_XTARGET(0)
#define TMC51XX_SWMODE TMC50XX_SWMODE(0)
#define TMC51XX_RAMPSTAT TMC50XX_RAMPSTAT(0)
#define TMC51XX_CHOPCONF TMC50XX_CHOPCONF(0)
#define TMC51XX_COOLCONF TMC50XX_COOLCONF(0)
#define TMC51XX_DRVSTATUS TMC50XX_DRVSTATUS(0)
#endif /* CONFIG_STEPPER_ADI_TMC51XX */
/**
* @}
*/

View file

@ -13,7 +13,7 @@ description: |
tmc50xx: tmc50xx@0 {
compatible = "adi,tmc50xx";
reg = <0>;
spi-max-frequency = <DT_FREQ_M(24)>; /* Maximum SPI bus frequency */
spi-max-frequency = <DT_FREQ_M(8)>; /* Maximum SPI bus frequency */
#address-cells = <1>;
#size-cells = <0>;
@ -61,8 +61,6 @@ include:
- name: adi,trinamic-gconf.yaml
property-allowlist:
- poscmp-enable
- shaft1
- shaft2
- test-mode
- lock-gconf

View file

@ -7,6 +7,7 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG
* SPDX-FileCopyrightText: Copyright (c) 2025 Prevas A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -49,16 +50,28 @@ extern "C" {
#define TMC_RAMP_VSTOP_MIN 1
#define TMC_RAMP_TZEROWAIT_MAX (GENMASK(15, 0) - 512)
#define TMC_RAMP_TZEROWAIT_MIN 0
#define TMC_RAMP_VCOOLTHRS_MAX GENMASK(22, 0)
#define TMC_RAMP_VCOOLTHRS_MIN 0
#define TMC_RAMP_VHIGH_MAX GENMASK(22, 0)
#define TMC_RAMP_VHIGH_MIN 0
#define TMC_RAMP_IHOLD_IRUN_MAX GENMASK(4, 0)
#define TMC_RAMP_IHOLD_IRUN_MIN 0
#define TMC_RAMP_IHOLDDELAY_MAX GENMASK(3, 0)
#define TMC_RAMP_IHOLDDELAY_MIN 0
#define TMC_RAMP_VACTUAL_SHIFT 22
/* TMC50XX specific */
#define TMC_RAMP_VCOOLTHRS_MAX GENMASK(22, 0)
#define TMC_RAMP_VCOOLTHRS_MIN 0
#define TMC_RAMP_VHIGH_MAX GENMASK(22, 0)
#define TMC_RAMP_VHIGH_MIN 0
/* TMC51XX specific */
#define TMC_RAMP_TPOWERDOWN_MAX GENMASK(7, 0)
#define TMC_RAMP_TPOWERDOWN_MIN 0
#define TMC_RAMP_TPWMTHRS_MAX GENMASK(19, 0)
#define TMC_RAMP_TPWMTHRS_MIN 0
#define TMC_RAMP_TCOOLTHRS_MAX GENMASK(19, 0)
#define TMC_RAMP_TCOOLTHRS_MIN 0
#define TMC_RAMP_THIGH_MAX GENMASK(19, 0)
#define TMC_RAMP_THIGH_MIN 0
/**
* @brief Trinamic Stepper Ramp Generator data
*/
@ -72,9 +85,21 @@ struct tmc_ramp_generator_data {
uint16_t dmax;
uint32_t vstop;
uint16_t tzerowait;
uint32_t vcoolthrs;
uint32_t vhigh;
uint32_t iholdrun;
union {
/* TMC50XX specific */
struct {
uint32_t vcoolthrs;
uint32_t vhigh;
};
/* TMC51XX specific */
struct {
uint32_t tpowerdown;
uint32_t tpwmthrs;
uint32_t tcoolthrs;
uint32_t thigh;
};
};
};
/**
@ -108,12 +133,6 @@ struct tmc_ramp_generator_data {
COND_CODE_1(DT_PROP_EXISTS(node, tzerowait), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, tzerowait), TMC_RAMP_TZEROWAIT_MIN, \
TMC_RAMP_TZEROWAIT_MAX), "tzerowait out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, vcoolthrs), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, vcoolthrs), TMC_RAMP_VCOOLTHRS_MIN, \
TMC_RAMP_VCOOLTHRS_MAX), "vcoolthrs out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, vhigh), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, vhigh), TMC_RAMP_VHIGH_MIN, \
TMC_RAMP_VHIGH_MAX), "vhigh out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, ihold), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, ihold), TMC_RAMP_IHOLD_IRUN_MIN, \
TMC_RAMP_IHOLD_IRUN_MAX), "ihold out of range"), ()); \
@ -122,7 +141,27 @@ struct tmc_ramp_generator_data {
TMC_RAMP_IHOLD_IRUN_MAX), "irun out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, iholddelay), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, iholddelay), TMC_RAMP_IHOLDDELAY_MIN, \
TMC_RAMP_IHOLDDELAY_MAX), "iholddelay out of range"), ());
TMC_RAMP_IHOLDDELAY_MAX), "iholddelay out of range"), ());\
/* TMC50XX specific */ \
COND_CODE_1(DT_PROP_EXISTS(node, vcoolthrs), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, vcoolthrs), TMC_RAMP_VCOOLTHRS_MIN, \
TMC_RAMP_VCOOLTHRS_MAX), "vcoolthrs out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, vhigh), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, vhigh), TMC_RAMP_VHIGH_MIN, \
TMC_RAMP_VHIGH_MAX), "vhigh out of range"), ()); \
/* TMC51XX specific */ \
COND_CODE_1(DT_PROP_EXISTS(node, tpowerdown), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, tpowerdown), TMC_RAMP_TPOWERDOWN_MIN, \
TMC_RAMP_TPOWERDOWN_MAX), "tpowerdown out of range"), ());\
COND_CODE_1(DT_PROP_EXISTS(node, tpwmthrs), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, tpwmthrs), TMC_RAMP_TPWMTHRS_MIN, \
TMC_RAMP_TPWMTHRS_MAX), "tpwmthrs out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, tcoolthrs), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, tcoolthrs), TMC_RAMP_TCOOLTHRS_MIN, \
TMC_RAMP_TCOOLTHRS_MAX), "tcoolthrs out of range"), ()); \
COND_CODE_1(DT_PROP_EXISTS(node, thigh), \
BUILD_ASSERT(IN_RANGE(DT_PROP(node, thigh), TMC_RAMP_THIGH_MIN, \
TMC_RAMP_THIGH_MAX), "thigh out of range"), ());
/**
* @brief Get Trinamic Stepper Ramp Generator data from DT
@ -131,8 +170,7 @@ struct tmc_ramp_generator_data {
*
* @return struct tmc_ramp_generator_data
*/
#define TMC_RAMP_DT_SPEC_GET(node) \
{ \
#define TMC_RAMP_DT_SPEC_GET_COMMON(node) \
.vstart = DT_PROP(node, vstart), \
.v1 = DT_PROP(node, v1), \
.vmax = DT_PROP(node, vmax), \
@ -142,11 +180,24 @@ struct tmc_ramp_generator_data {
.dmax = DT_PROP(node, dmax), \
.vstop = DT_PROP(node, vstop), \
.tzerowait = DT_PROP(node, tzerowait), \
.vcoolthrs = DT_PROP(node, vcoolthrs), \
.vhigh = DT_PROP(node, vhigh), \
.iholdrun = (TMC5XXX_IRUN(DT_PROP(node, irun)) | \
TMC5XXX_IHOLD(DT_PROP(node, ihold)) | \
TMC5XXX_IHOLDDELAY(DT_PROP(node, iholddelay))), \
TMC5XXX_IHOLDDELAY(DT_PROP(node, iholddelay))),
#define TMC_RAMP_DT_SPEC_GET_TMC50XX(node) \
{ \
TMC_RAMP_DT_SPEC_GET_COMMON(node) \
.vhigh = DT_PROP(node, vhigh), \
.vcoolthrs = DT_PROP(node, vcoolthrs), \
}
#define TMC_RAMP_DT_SPEC_GET_TMC51XX(node) \
{ \
TMC_RAMP_DT_SPEC_GET_COMMON(DT_DRV_INST(node)) \
.tpowerdown = DT_INST_PROP(node, tpowerdown), \
.tpwmthrs = DT_INST_PROP(node, tpwmthrs), \
.tcoolthrs = DT_INST_PROP(node, tcoolthrs), \
.thigh = DT_INST_PROP(node, thigh), \
}
/**