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