1 /** 2 * @file drivers/stepper/stepper_trinamic.h 3 * 4 * @brief Public API for Trinamic Stepper Controller Specific Functions 5 * 6 */ 7 8 /* 9 * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG 10 * 11 * SPDX-License-Identifier: Apache-2.0 12 */ 13 14 #ifndef ZEPHYR_INCLUDE_DRIVERS_STEPPER_STEPPER_TRINAMIC_H_ 15 #define ZEPHYR_INCLUDE_DRIVERS_STEPPER_STEPPER_TRINAMIC_H_ 16 17 /** 18 * @brief Trinamic Stepper Controller Interface 19 * @defgroup trinamic_stepper_interface Trinamic Stepper Controller Interface 20 * @ingroup stepper_interface 21 * @{ 22 */ 23 24 #include <stdint.h> 25 #include <zephyr/drivers/stepper.h> 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 /** 32 * @brief Trinamic stepper controller ramp generator data limits 33 */ 34 #define TMC_RAMP_VSTART_MAX GENMASK(17, 0) 35 #define TMC_RAMP_VSTART_MIN 0 36 #define TMC_RAMP_V1_MAX GENMASK(19, 0) 37 #define TMC_RAMP_V1_MIN 0 38 #define TMC_RAMP_VMAX_MAX (GENMASK(22, 0) - 512) 39 #define TMC_RAMP_VMAX_MIN 0 40 #define TMC_RAMP_A1_MAX GENMASK(15, 0) 41 #define TMC_RAMP_A1_MIN 0 42 #define TMC_RAMP_AMAX_MAX GENMASK(15, 0) 43 #define TMC_RAMP_AMAX_MIN 0 44 #define TMC_RAMP_D1_MAX GENMASK(15, 0) 45 #define TMC_RAMP_D1_MIN 1 46 #define TMC_RAMP_DMAX_MAX GENMASK(15, 0) 47 #define TMC_RAMP_DMAX_MIN 0 48 #define TMC_RAMP_VSTOP_MAX GENMASK(17, 0) 49 #define TMC_RAMP_VSTOP_MIN 1 50 #define TMC_RAMP_TZEROWAIT_MAX (GENMASK(15, 0) - 512) 51 #define TMC_RAMP_TZEROWAIT_MIN 0 52 #define TMC_RAMP_VCOOLTHRS_MAX GENMASK(22, 0) 53 #define TMC_RAMP_VCOOLTHRS_MIN 0 54 #define TMC_RAMP_VHIGH_MAX GENMASK(22, 0) 55 #define TMC_RAMP_VHIGH_MIN 0 56 #define TMC_RAMP_IHOLD_IRUN_MAX GENMASK(4, 0) 57 #define TMC_RAMP_IHOLD_IRUN_MIN 0 58 #define TMC_RAMP_IHOLDDELAY_MAX GENMASK(3, 0) 59 #define TMC_RAMP_IHOLDDELAY_MIN 0 60 #define TMC_RAMP_VACTUAL_SHIFT 22 61 62 /** 63 * @brief Trinamic Stepper Ramp Generator data 64 */ 65 struct tmc_ramp_generator_data { 66 uint32_t vstart; 67 uint32_t v1; 68 uint32_t vmax; 69 uint16_t a1; 70 uint16_t amax; 71 uint16_t d1; 72 uint16_t dmax; 73 uint32_t vstop; 74 uint16_t tzerowait; 75 uint32_t vcoolthrs; 76 uint32_t vhigh; 77 uint32_t iholdrun; 78 }; 79 80 /** 81 * @brief Check if Ramp DT data is within limits 82 */ 83 #define CHECK_RAMP_DT_DATA(node) \ 84 COND_CODE_1(DT_PROP_EXISTS(node, vstart), \ 85 BUILD_ASSERT(IN_RANGE(DT_PROP(node, vstart), TMC_RAMP_VSTART_MIN, \ 86 TMC_RAMP_VSTART_MAX), "vstart out of range"), ()); \ 87 COND_CODE_1(DT_PROP_EXISTS(node, v1), \ 88 BUILD_ASSERT(IN_RANGE(DT_PROP(node, v1), TMC_RAMP_V1_MIN, \ 89 TMC_RAMP_V1_MAX), "v1 out of range"), ()); \ 90 COND_CODE_1(DT_PROP_EXISTS(node, vmax), \ 91 BUILD_ASSERT(IN_RANGE(DT_PROP(node, vmax), TMC_RAMP_VMAX_MIN, \ 92 TMC_RAMP_VMAX_MAX), "vmax out of range"), ()); \ 93 COND_CODE_1(DT_PROP_EXISTS(node, a1), \ 94 BUILD_ASSERT(IN_RANGE(DT_PROP(node, a1), TMC_RAMP_A1_MIN, \ 95 TMC_RAMP_A1_MAX), "a1 out of range"), ()); \ 96 COND_CODE_1(DT_PROP_EXISTS(node, amax), \ 97 BUILD_ASSERT(IN_RANGE(DT_PROP(node, amax), TMC_RAMP_AMAX_MIN, \ 98 TMC_RAMP_AMAX_MAX), "amax out of range"), ()); \ 99 COND_CODE_1(DT_PROP_EXISTS(node, d1), \ 100 BUILD_ASSERT(IN_RANGE(DT_PROP(node, d1), TMC_RAMP_D1_MIN, \ 101 TMC_RAMP_D1_MAX), "d1 out of range"), ()); \ 102 COND_CODE_1(DT_PROP_EXISTS(node, dmax), \ 103 BUILD_ASSERT(IN_RANGE(DT_PROP(node, dmax), TMC_RAMP_DMAX_MIN, \ 104 TMC_RAMP_DMAX_MAX), "dmax out of range"), ()); \ 105 COND_CODE_1(DT_PROP_EXISTS(node, vstop), \ 106 BUILD_ASSERT(IN_RANGE(DT_PROP(node, vstop), TMC_RAMP_VSTOP_MIN, \ 107 TMC_RAMP_VSTOP_MAX), "vstop out of range"), ()); \ 108 COND_CODE_1(DT_PROP_EXISTS(node, tzerowait), \ 109 BUILD_ASSERT(IN_RANGE(DT_PROP(node, tzerowait), TMC_RAMP_TZEROWAIT_MIN, \ 110 TMC_RAMP_TZEROWAIT_MAX), "tzerowait out of range"), ()); \ 111 COND_CODE_1(DT_PROP_EXISTS(node, vcoolthrs), \ 112 BUILD_ASSERT(IN_RANGE(DT_PROP(node, vcoolthrs), TMC_RAMP_VCOOLTHRS_MIN, \ 113 TMC_RAMP_VCOOLTHRS_MAX), "vcoolthrs out of range"), ()); \ 114 COND_CODE_1(DT_PROP_EXISTS(node, vhigh), \ 115 BUILD_ASSERT(IN_RANGE(DT_PROP(node, vhigh), TMC_RAMP_VHIGH_MIN, \ 116 TMC_RAMP_VHIGH_MAX), "vhigh out of range"), ()); \ 117 COND_CODE_1(DT_PROP_EXISTS(node, ihold), \ 118 BUILD_ASSERT(IN_RANGE(DT_PROP(node, ihold), TMC_RAMP_IHOLD_IRUN_MIN, \ 119 TMC_RAMP_IHOLD_IRUN_MAX), "ihold out of range"), ()); \ 120 COND_CODE_1(DT_PROP_EXISTS(node, irun), \ 121 BUILD_ASSERT(IN_RANGE(DT_PROP(node, irun), TMC_RAMP_IHOLD_IRUN_MIN, \ 122 TMC_RAMP_IHOLD_IRUN_MAX), "irun out of range"), ()); \ 123 COND_CODE_1(DT_PROP_EXISTS(node, iholddelay), \ 124 BUILD_ASSERT(IN_RANGE(DT_PROP(node, iholddelay), TMC_RAMP_IHOLDDELAY_MIN, \ 125 TMC_RAMP_IHOLDDELAY_MAX), "iholddelay out of range"), ()); 126 127 /** 128 * @brief Get Trinamic Stepper Ramp Generator data from DT 129 * 130 * @param node DT node identifier 131 * 132 * @return struct tmc_ramp_generator_data 133 */ 134 #define TMC_RAMP_DT_SPEC_GET(node) \ 135 { \ 136 .vstart = DT_PROP(node, vstart), \ 137 .v1 = DT_PROP(node, v1), \ 138 .vmax = DT_PROP(node, vmax), \ 139 .a1 = DT_PROP(node, a1), \ 140 .amax = DT_PROP(node, amax), \ 141 .d1 = DT_PROP(node, d1), \ 142 .dmax = DT_PROP(node, dmax), \ 143 .vstop = DT_PROP(node, vstop), \ 144 .tzerowait = DT_PROP(node, tzerowait), \ 145 .vcoolthrs = DT_PROP(node, vcoolthrs), \ 146 .vhigh = DT_PROP(node, vhigh), \ 147 .iholdrun = (TMC5XXX_IRUN(DT_PROP(node, irun)) | \ 148 TMC5XXX_IHOLD(DT_PROP(node, ihold)) | \ 149 TMC5XXX_IHOLDDELAY(DT_PROP(node, iholddelay))), \ 150 } 151 152 /** 153 * @brief Configure Trinamic Stepper Ramp Generator 154 * 155 * @param dev Pointer to the stepper motor controller instance 156 * @param ramp_data Pointer to a struct containing the required ramp parameters 157 * 158 * @retval -EIO General input / output error 159 * @retval -ENOSYS If not implemented by device driver 160 * @retval 0 Success 161 */ 162 int tmc5041_stepper_set_ramp(const struct device *dev, 163 const struct tmc_ramp_generator_data *ramp_data); 164 165 /** 166 * @} 167 */ 168 169 #ifdef __cplusplus 170 } 171 #endif 172 173 #endif /* ZEPHYR_INCLUDE_DRIVERS_STEPPER_STEPPER_TRINAMIC_H_ */ 174