/** * @file drivers/stepper/stepper_trinamic.h * * @brief Public API for Trinamic Stepper Controller Specific Functions * */ /* * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_DRIVERS_STEPPER_STEPPER_TRINAMIC_H_ #define ZEPHYR_INCLUDE_DRIVERS_STEPPER_STEPPER_TRINAMIC_H_ /** * @brief Trinamic Stepper Controller Interface * @defgroup trinamic_stepper_interface Trinamic Stepper Controller Interface * @ingroup stepper_interface * @{ */ #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief Trinamic stepper controller ramp generator data limits */ #define TMC_RAMP_VSTART_MAX GENMASK(17, 0) #define TMC_RAMP_VSTART_MIN 0 #define TMC_RAMP_V1_MAX GENMASK(19, 0) #define TMC_RAMP_V1_MIN 0 #define TMC_RAMP_VMAX_MAX (GENMASK(22, 0) - 512) #define TMC_RAMP_VMAX_MIN 0 #define TMC_RAMP_A1_MAX GENMASK(15, 0) #define TMC_RAMP_A1_MIN 0 #define TMC_RAMP_AMAX_MAX GENMASK(15, 0) #define TMC_RAMP_AMAX_MIN 0 #define TMC_RAMP_D1_MAX GENMASK(15, 0) #define TMC_RAMP_D1_MIN 1 #define TMC_RAMP_DMAX_MAX GENMASK(15, 0) #define TMC_RAMP_DMAX_MIN 0 #define TMC_RAMP_VSTOP_MAX GENMASK(17, 0) #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 /** * @brief Trinamic Stepper Ramp Generator data */ struct tmc_ramp_generator_data { uint32_t vstart; uint32_t v1; uint32_t vmax; uint16_t a1; uint16_t amax; uint16_t d1; uint16_t dmax; uint32_t vstop; uint16_t tzerowait; uint32_t vcoolthrs; uint32_t vhigh; uint32_t iholdrun; }; /** * @brief Check if Ramp DT data is within limits */ #define CHECK_RAMP_DT_DATA(node) \ COND_CODE_1(DT_PROP_EXISTS(node, vstart), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, vstart), TMC_RAMP_VSTART_MIN, \ TMC_RAMP_VSTART_MAX), "vstart out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, v1), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, v1), TMC_RAMP_V1_MIN, \ TMC_RAMP_V1_MAX), "v1 out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, vmax), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, vmax), TMC_RAMP_VMAX_MIN, \ TMC_RAMP_VMAX_MAX), "vmax out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, a1), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, a1), TMC_RAMP_A1_MIN, \ TMC_RAMP_A1_MAX), "a1 out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, amax), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, amax), TMC_RAMP_AMAX_MIN, \ TMC_RAMP_AMAX_MAX), "amax out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, d1), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, d1), TMC_RAMP_D1_MIN, \ TMC_RAMP_D1_MAX), "d1 out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, dmax), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, dmax), TMC_RAMP_DMAX_MIN, \ TMC_RAMP_DMAX_MAX), "dmax out of range"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, vstop), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, vstop), TMC_RAMP_VSTOP_MIN, \ TMC_RAMP_VSTOP_MAX), "vstop out of range"), ()); \ 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"), ()); \ COND_CODE_1(DT_PROP_EXISTS(node, irun), \ BUILD_ASSERT(IN_RANGE(DT_PROP(node, irun), TMC_RAMP_IHOLD_IRUN_MIN, \ 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"), ()); /** * @brief Get Trinamic Stepper Ramp Generator data from DT * * @param node DT node identifier * * @return struct tmc_ramp_generator_data */ #define TMC_RAMP_DT_SPEC_GET(node) \ { \ .vstart = DT_PROP(node, vstart), \ .v1 = DT_PROP(node, v1), \ .vmax = DT_PROP(node, vmax), \ .a1 = DT_PROP(node, a1), \ .amax = DT_PROP(node, amax), \ .d1 = DT_PROP(node, d1), \ .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))), \ } /** * @brief Configure Trinamic Stepper Ramp Generator * * @param dev Pointer to the stepper motor controller instance * @param ramp_data Pointer to a struct containing the required ramp parameters * * @retval -EIO General input / output error * @retval -ENOSYS If not implemented by device driver * @retval 0 Success */ int tmc5041_stepper_set_ramp(const struct device *dev, const struct tmc_ramp_generator_data *ramp_data); /** * @} */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_DRIVERS_STEPPER_STEPPER_TRINAMIC_H_ */