From 242e6ea12afaea255348660c1ced21054f076cfa Mon Sep 17 00:00:00 2001 From: Anders Nielsen Date: Tue, 15 Apr 2025 15:27:01 +0200 Subject: [PATCH] drivers: stepper: adi_tmc: Prepare for tmc51xx support Add Kconfig option. Find common regs. Update ramp generator data. Signed-off-by: Anders Nielsen --- drivers/stepper/adi_tmc/Kconfig | 1 + drivers/stepper/adi_tmc/Kconfig.tmc51xx | 12 +++ .../adi_tmc/adi_tmc50xx_stepper_controller.c | 3 +- drivers/stepper/adi_tmc/adi_tmc_reg.h | 81 ++++++++++++----- dts/bindings/stepper/adi/adi,tmc50xx.yaml | 4 +- .../zephyr/drivers/stepper/stepper_trinamic.h | 87 +++++++++++++++---- 6 files changed, 143 insertions(+), 45 deletions(-) create mode 100644 drivers/stepper/adi_tmc/Kconfig.tmc51xx diff --git a/drivers/stepper/adi_tmc/Kconfig b/drivers/stepper/adi_tmc/Kconfig index b214be92963..e8a86e6a439 100644 --- a/drivers/stepper/adi_tmc/Kconfig +++ b/drivers/stepper/adi_tmc/Kconfig @@ -21,5 +21,6 @@ comment "Trinamic Stepper Drivers" rsource "Kconfig.tmc22xx" rsource "Kconfig.tmc50xx" +rsource "Kconfig.tmc51xx" endif # STEPPER_ADI_TMC diff --git a/drivers/stepper/adi_tmc/Kconfig.tmc51xx b/drivers/stepper/adi_tmc/Kconfig.tmc51xx new file mode 100644 index 00000000000..99e88ac1143 --- /dev/null +++ b/drivers/stepper/adi_tmc/Kconfig.tmc51xx @@ -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" diff --git a/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c b/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c index e5be15f3c1d..38224aa33a8 100644 --- a/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c +++ b/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c @@ -15,7 +15,6 @@ #include "adi_tmc5xxx_common.h" #include - 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 = { \ diff --git a/drivers/stepper/adi_tmc/adi_tmc_reg.h b/drivers/stepper/adi_tmc/adi_tmc_reg.h index 7dc3fc66533..616b405442c 100644 --- a/drivers/stepper/adi_tmc/adi_tmc_reg.h +++ b/drivers/stepper/adi_tmc/adi_tmc_reg.h @@ -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 */ + /** * @} */ diff --git a/dts/bindings/stepper/adi/adi,tmc50xx.yaml b/dts/bindings/stepper/adi/adi,tmc50xx.yaml index a20e680e3ae..eba9cd3f664 100644 --- a/dts/bindings/stepper/adi/adi,tmc50xx.yaml +++ b/dts/bindings/stepper/adi/adi,tmc50xx.yaml @@ -13,7 +13,7 @@ description: | tmc50xx: tmc50xx@0 { compatible = "adi,tmc50xx"; reg = <0>; - spi-max-frequency = ; /* Maximum SPI bus frequency */ + spi-max-frequency = ; /* 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 diff --git a/include/zephyr/drivers/stepper/stepper_trinamic.h b/include/zephyr/drivers/stepper/stepper_trinamic.h index f42032fe984..691eac73be6 100644 --- a/include/zephyr/drivers/stepper/stepper_trinamic.h +++ b/include/zephyr/drivers/stepper/stepper_trinamic.h @@ -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), \ } /**