Prusa3d Marlin fork
tmc2130.h
1 #ifndef TMC2130_H
2 #define TMC2130_H
3 
4 #include <stdint.h>
5 #include "Configuration_var.h"
6 
7 //mode
8 extern uint8_t tmc2130_mode;
9 //microstep resolution (0 means 256usteps, 8 means 1ustep
10 extern uint8_t tmc2130_mres[4];
11 
12 //flags for axis stall detection
13 extern uint8_t tmc2130_sg_thr[4];
14 
15 extern bool tmc2130_sg_stop_on_crash;
16 extern uint8_t tmc2130_sg_crash; //crash mask
17 
18 extern uint8_t tmc2130_sg_homing_axes_mask;
19 
20 extern const char eMotorCurrentScalingEnabled[];
21 
22 #define TMC2130_MODE_NORMAL 0
23 #define TMC2130_MODE_SILENT 1
24 
25 #define TMC2130_WAVE_FAC1000_MIN 30
26 #define TMC2130_WAVE_FAC1000_MAX 200
27 #define TMC2130_WAVE_FAC1000_STP 1
28 
29 #define TMC2130_MINIMUM_PULSE 0 // minimum pulse width in uS
30 #define TMC2130_SET_DIR_DELAY 20 // minimum delay after setting direction in uS
31 #define TMC2130_SET_PWR_DELAY 0 // minimum delay after changing pwr mode in uS
32 
33 #ifdef TMC2130_DEDGE_STEPPING
34 #define TMC2130_MINIMUM_DELAY //NOP
35 #elif TMC2130_MINIMUM_PULSE == 0
36 #define TMC2130_MINIMUM_DELAY asm("nop")
37 #else
38 #define TMC2130_MINIMUM_DELAY delayMicroseconds(TMC2130_MINIMUM_PULSE)
39 #endif
40 
41 extern uint8_t tmc2130_home_enabled;
42 extern uint8_t tmc2130_home_origin[2];
43 extern uint8_t tmc2130_home_bsteps[2];
44 extern uint8_t tmc2130_home_fsteps[2];
45 
46 extern uint8_t tmc2130_wave_fac[4];
47 
48 #pragma pack(push)
49 #pragma pack(1)
50 typedef struct
51 {
52  uint8_t toff:4;
53  uint8_t hstr:3;
54  uint8_t hend:4;
55  uint8_t tbl:2;
56  uint8_t res:3;
58 #pragma pack(pop)
59 
60 extern tmc2130_chopper_config_t tmc2130_chopper_config[NUM_AXIS];
61 
62 struct MotorCurrents {
63  // Refresh the vSense flag
64  // If the vSense flag changes then both Run and Hold current values
65  // must be shifted accordingly. This is done especially to handle
66  // the edge case where only either of the current values are changed at runtime.
67  // See M911 and M912
68  void refreshCurrentScaling() {
69  // IMPORTANT: iRun must have range 0 to 63 (2^6) so we can properly
70  // update the current scaling back and forth
71 
72  // Detect new vSense value
73  const bool newvSense = (iRun < 32);
74  if (vSense != newvSense) {
75  // Update currents to match current scaling
76  if (vSense) {
77  // vSense was 1 [V_FS = 0.32V] but is changing to 0 [V_FS = 0.18V]
78  // Half both current values to be in sync with current scale range
79  iHold >>= 1;
80  iRun >>= 1;
81  } else {
82  // vSense was 0 [V_FS = 0.18V], but is changing to 1 [V_FS = 0.32V]
83  // double the Hold current value
84  // iRun is expected to already be correct so no shift needed.
85  // Keep in mind, only a change in iRun can change vSense.
86  iHold <<= 1;
87  }
88 
89  // Update vSense
90  vSense = newvSense;
91  } else if (!vSense) {
92  // No change in vSense, but vSense = 0, which means we must scale down the iRun value
93  // from range [0, 63] to range [0, 31]
94  iRun >>= 1;
95  }
96  }
97 
98  // PROGMEM initializer
99  inline __attribute__((always_inline)) MotorCurrents(const MotorCurrents &curr_P) { memcpy_P(this, &curr_P, sizeof(*this)); }
100 
101  constexpr inline __attribute__((always_inline)) MotorCurrents(uint8_t ir, uint8_t ih)
102  : vSense((ir < 32) ? 1 : 0)
103  , iRun((ir < 32) ? ir : (ir >> 1))
104  , iHold((ir < 32) ? ih : (ih >> 1)) {}
105 
106  inline uint8_t getiRun() const { return iRun; }
107  inline uint8_t getiHold() const { return min(iHold, iRun); }
108  inline uint8_t getOriginaliRun() const { return vSense ? iRun : iRun << 1; }
109  inline uint8_t getOriginaliHold() const { return min(vSense ? iHold : iHold << 1, getOriginaliRun()); }
110  inline bool iHoldIsClamped() const { return iHold > iRun; }
111  inline uint8_t getvSense() const { return vSense; }
112 
113  void __attribute__((noinline)) setiRun(uint8_t ir) {
114  iRun = ir;
115 
116  // Refresh the vSense bit and take care of updating Hold/Run currents
117  // accordingly
118  refreshCurrentScaling();
119  }
120 
121  void __attribute__((noinline)) setiHold(uint8_t ih) {
122  iHold = vSense ? ih : ih >> 1;
123  // Note that iHold cannot change the vSense bit. If iHold is larger
124  // than iRun, then iHold is truncated later in SetCurrents()
125  }
126 
127  private:
128  // These members are protected in order to ensure that
129  // the struct methods are used always to update these values at runtime.
130  bool vSense;
131  uint8_t iRun;
132  uint8_t iHold;
133 };
134 
135 extern MotorCurrents currents[NUM_AXIS];
136 
137 //initialize tmc2130
138 
140  uint8_t bSuppressFlag : 1; // only relevant on MK3S with PSU_Delta
141  uint8_t enableECool : 1; // experimental support for E-motor cooler operation
142  inline TMCInitParams():bSuppressFlag(0), enableECool(0) { }
143  inline explicit TMCInitParams(bool bSuppressFlag, bool enableECool):bSuppressFlag(bSuppressFlag), enableECool(enableECool) { }
144  inline explicit TMCInitParams(bool enableECool)
145  : bSuppressFlag(
146 #ifdef PSU_Delta
147  1
148 #else
149  0
150 #endif
151  )
152  , enableECool(enableECool) { }
153 };
154 extern void tmc2130_init(TMCInitParams params);
155 //check diag pins (called from stepper isr)
156 extern void tmc2130_st_isr();
157 //update stall guard (called from st_synchronize inside the loop)
158 extern bool tmc2130_update_sg();
159 //temperature watching (called from )
160 extern void tmc2130_check_overtemp();
161 //enter homing (called from homeaxis before homing starts)
162 extern void tmc2130_home_enter(uint8_t axes_mask);
163 //exit homing (called from homeaxis after homing ends)
164 extern void tmc2130_home_exit();
165 
166 //start stallguard measuring for single axis
167 extern void tmc2130_sg_measure_start(uint8_t axis);
168 //stop current stallguard measuring and report result
169 extern uint16_t tmc2130_sg_measure_stop();
170 
171 // Enable or Disable crash detection according to EEPROM
172 void crashdet_use_eeprom_setting();
173 
174 extern void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, const MotorCurrents *curr = nullptr);
175 
176 //print currents (M913)
177 extern void tmc2130_print_currents();
178 
179 //set PWM_AMPL for any axis (M917)
180 extern void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl);
181 //set PWM_GRAD for any axis (M918)
182 extern void tmc2130_set_pwm_grad(uint8_t axis, uint8_t pwm_ampl);
183 
184 
185 extern uint16_t tmc2130_rd_MSCNT(uint8_t axis);
186 extern uint32_t tmc2130_rd_MSCURACT(uint8_t axis);
187 
188 extern uint8_t tmc2130_usteps2mres(uint16_t usteps);
189 #define tmc2130_mres2usteps(mres) ((uint16_t)256 >> mres)
190 
191 extern bool tmc2130_wait_standstill_xy(int timeout);
192 
193 extern uint16_t tmc2130_get_res(uint8_t axis);
194 extern void tmc2130_set_res(uint8_t axis, uint16_t res);
195 extern uint8_t tmc2130_get_pwr(uint8_t axis);
196 extern void tmc2130_set_pwr(uint8_t axis, uint8_t pwr);
197 extern uint8_t tmc2130_get_inv(uint8_t axis);
198 extern uint8_t tmc2130_get_dir(uint8_t axis);
199 extern void tmc2130_set_dir(uint8_t axis, uint8_t dir);
200 extern void tmc2130_do_step(uint8_t axis);
201 extern void tmc2130_do_steps(uint8_t axis, uint16_t steps, uint8_t dir, uint16_t delay_us);
202 extern void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_us, uint16_t microstep_resolution);
203 extern void tmc2130_get_wave(uint8_t axis, uint8_t* data);
204 extern void tmc2130_set_wave(uint8_t axis, uint8_t amp, uint8_t fac1000);
205 
206 extern bool tmc2130_home_calibrate(uint8_t axis);
207 
208 extern uint8_t tmc2130_cur2val(float cur);
209 extern float tmc2130_val2cur(uint8_t val);
210 
211 #endif //TMC2130_H
Definition: tmc2130.h:62
Definition: tmc2130.h:139
Definition: tmc2130.h:51
uint8_t tmc2130_cur2val(float cur)
Translate current to tmc2130 vsense and IHOLD or IRUN.
Definition: tmc2130.cpp:1113
void tmc2130_set_pwr(uint8_t axis, uint8_t pwr)
Definition: tmc2130.cpp:759