ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
tmc22xx.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cmath>
5
9#include "esphome/core/hal.h"
11
12namespace esphome::tmc22xx {
13
16 uint8_t reg;
17 uint8_t shift;
18 uint8_t width;
20
21 constexpr uint32_t mask() const { return ((width >= 32) ? 0xFFFFFFFFu : ((1u << width) - 1u)) << shift; }
22};
23
24// Registers shared by the TMC22xx family (TMC2202, TMC2208, TMC2209, TMC2224, TMC2225, TMC2226)
25static constexpr uint8_t REG_GCONF = 0x00;
26static constexpr uint8_t REG_GSTAT = 0x01;
27static constexpr uint8_t REG_IOIN = 0x06;
28static constexpr uint8_t REG_FACTORY_CONF = 0x07;
29static constexpr uint8_t REG_IHOLD_IRUN = 0x10;
30static constexpr uint8_t REG_TPOWERDOWN = 0x11;
31static constexpr uint8_t REG_TPWMTHRS = 0x13;
32static constexpr uint8_t REG_VACTUAL = 0x22;
33static constexpr uint8_t REG_CHOPCONF = 0x6C;
34static constexpr uint8_t REG_DRV_STATUS = 0x6F;
35static constexpr uint8_t REG_PWMCONF = 0x70;
36static constexpr uint8_t REG_PWM_SCALE = 0x71;
37static constexpr uint8_t REG_PWM_AUTO = 0x72;
38
39// Readable registers that a driver reset sets back to their defaults; the last written values are restored
40static constexpr std::array<uint8_t, 4> RESTORED_REGISTERS{REG_GCONF, REG_FACTORY_CONF, REG_CHOPCONF, REG_PWMCONF};
41
42static constexpr RegisterField I_SCALE_ANALOG{REG_GCONF, 0, 1, false};
43static constexpr RegisterField INTERNAL_RSENSE{REG_GCONF, 1, 1, false};
44static constexpr RegisterField EN_SPREADCYCLE{REG_GCONF, 2, 1, false};
45static constexpr RegisterField SHAFT{REG_GCONF, 3, 1, false};
46static constexpr RegisterField INDEX_OTPW{REG_GCONF, 4, 1, false};
47static constexpr RegisterField INDEX_STEP{REG_GCONF, 5, 1, false};
48static constexpr RegisterField PDN_DISABLE{REG_GCONF, 6, 1, false};
49static constexpr RegisterField MSTEP_REG_SELECT{REG_GCONF, 7, 1, false};
50static constexpr RegisterField MULTISTEP_FILT{REG_GCONF, 8, 1, false};
51static constexpr RegisterField VERSION{REG_IOIN, 24, 8, false};
52static constexpr RegisterField OTTRIM{REG_FACTORY_CONF, 8, 2, false};
53static constexpr RegisterField IHOLD{REG_IHOLD_IRUN, 0, 5, false};
54static constexpr RegisterField IRUN{REG_IHOLD_IRUN, 8, 5, false};
55static constexpr RegisterField IHOLDDELAY{REG_IHOLD_IRUN, 16, 4, false};
56static constexpr RegisterField TPOWERDOWN{REG_TPOWERDOWN, 0, 8, false};
57static constexpr RegisterField TPWMTHRS{REG_TPWMTHRS, 0, 20, false};
58static constexpr RegisterField VACTUAL{REG_VACTUAL, 0, 24, true};
59static constexpr RegisterField TOFF{REG_CHOPCONF, 0, 4, false};
60static constexpr RegisterField HSTRT{REG_CHOPCONF, 4, 3, false};
61static constexpr RegisterField HEND{REG_CHOPCONF, 7, 4, false};
62static constexpr RegisterField TBL{REG_CHOPCONF, 15, 2, false};
63static constexpr RegisterField VSENSE{REG_CHOPCONF, 17, 1, false};
64static constexpr RegisterField MRES{REG_CHOPCONF, 24, 4, false};
65static constexpr RegisterField INTPOL{REG_CHOPCONF, 28, 1, false};
66static constexpr RegisterField DEDGE{REG_CHOPCONF, 29, 1, false};
67static constexpr RegisterField CS_ACTUAL{REG_DRV_STATUS, 16, 5, false};
68static constexpr RegisterField PWM_OFS{REG_PWMCONF, 0, 8, false};
69static constexpr RegisterField PWM_GRAD{REG_PWMCONF, 8, 8, false};
70static constexpr RegisterField PWM_FREQ{REG_PWMCONF, 16, 2, false};
71static constexpr RegisterField PWM_AUTOSCALE{REG_PWMCONF, 18, 1, false};
72static constexpr RegisterField PWM_AUTOGRAD{REG_PWMCONF, 19, 1, false};
73static constexpr RegisterField FREEWHEEL{REG_PWMCONF, 20, 2, false};
74static constexpr RegisterField PWM_REG{REG_PWMCONF, 24, 4, false};
75static constexpr RegisterField PWM_LIM{REG_PWMCONF, 28, 4, false};
76static constexpr RegisterField PWM_SCALE_SUM{REG_PWM_SCALE, 0, 8, false};
77static constexpr RegisterField PWM_SCALE_AUTO{REG_PWM_SCALE, 16, 9, true};
78static constexpr RegisterField PWM_OFS_AUTO{REG_PWM_AUTO, 0, 8, false};
79static constexpr RegisterField PWM_GRAD_AUTO{REG_PWM_AUTO, 16, 8, false};
80
87
108
111 volatile bool triggered{false};
112 static void gpio_intr(DiagPinStore *arg);
113};
114
117 volatile int32_t pulses{0};
118 volatile int8_t direction{0};
119 static void gpio_intr(IndexPulseStore *arg);
120};
121
124 public:
125 void setup() override;
126 void loop() override;
127 void dump_config() override;
128 void on_shutdown() override;
129 float get_setup_priority() const override { return setup_priority::HARDWARE; }
130
131 void set_address(uint8_t address) { this->address_ = address; }
132 void set_enn_pin(GPIOPin *pin) { this->enn_pin_ = pin; }
133 void set_step_pin(GPIOPin *pin) { this->step_pin_ = pin; }
134 void set_dir_pin(GPIOPin *pin) { this->dir_pin_ = pin; }
135 void set_index_pin(InternalGPIOPin *pin) { this->index_pin_ = pin; }
136 void set_diag_pin(InternalGPIOPin *pin) { this->diag_pin_ = pin; }
138 void set_rsense(float rsense) { this->rsense_ = rsense; }
139 void set_vsense(bool vsense) { this->vsense_ = vsense; }
140 void set_ottrim(uint8_t ottrim) { this->ottrim_ = ottrim; }
141 void set_analog_current_scale(bool enable) { this->analog_current_scale_ = enable; }
142 void set_initial_run_current(float current) { this->initial_run_current_ = current; }
143 void set_initial_hold_current(float current) { this->initial_hold_current_ = current; }
144 void set_initial_microsteps(uint16_t microsteps) { this->initial_microsteps_ = microsteps; }
145
147 void set_enabled(bool enabled);
148 bool is_enabled() const { return this->enabled_; }
150 bool is_unreachable() const { return this->status_poll_skip_ > 0; }
151
153 template<typename F> void add_on_status_callback(F &&callback) {
154 this->status_callback_.add(std::forward<F>(callback));
155 }
156
157 void set_microsteps(uint16_t microsteps);
158 uint16_t get_microsteps();
159 void set_interpolation(bool enable) { this->write_field(INTPOL, enable); }
160 void set_spreadcycle(bool enable) { this->write_field(EN_SPREADCYCLE, enable); }
161 void set_inverse_direction(bool inverse) { this->write_field(SHAFT, inverse); }
162 void set_tpwm_threshold(uint32_t threshold) { this->write_field(TPWMTHRS, threshold); }
163
166 void set_run_current(float current);
167 void set_hold_current(float current);
168 void set_irun(uint8_t irun) { this->write_field(IRUN, irun); }
169 void set_ihold(uint8_t ihold) { this->write_field(IHOLD, ihold); }
170 void set_iholddelay(uint8_t delay) { this->write_field(IHOLDDELAY, delay); }
171 void set_tpowerdown(uint8_t tpowerdown) { this->write_field(TPOWERDOWN, tpowerdown); }
173
175 void set_toff(uint8_t toff);
176 void set_tbl(uint8_t tbl) { this->write_field(TBL, tbl); }
177 void set_hend(uint8_t hend) { this->write_field(HEND, hend); }
178 void set_hstrt(uint8_t hstrt) { this->write_field(HSTRT, hstrt); }
179
180 void set_pwm_ofs(uint8_t ofs) { this->write_field(PWM_OFS, ofs); }
181 void set_pwm_grad(uint8_t grad) { this->write_field(PWM_GRAD, grad); }
182 void set_pwm_freq(uint8_t freq) { this->write_field(PWM_FREQ, freq); }
183 void set_pwm_autoscale(bool enable) { this->write_field(PWM_AUTOSCALE, enable); }
184 void set_pwm_autograd(bool enable) { this->write_field(PWM_AUTOGRAD, enable); }
185 void set_pwm_reg(uint8_t reg) { this->write_field(PWM_REG, reg); }
186 void set_pwm_lim(uint8_t lim) { this->write_field(PWM_LIM, lim); }
188 float scale_to_current(uint8_t scale);
189
190 bool write_register(uint8_t reg, uint32_t value);
191 optional<uint32_t> read_register(uint8_t reg);
192 bool write_field(const RegisterField &field, uint32_t value);
193 optional<uint32_t> read_field(const RegisterField &field);
194 static uint32_t extract_field(uint32_t data, const RegisterField &field);
195
196 protected:
198 virtual uint8_t expected_version() const = 0;
200 virtual uint32_t *shadow_register(uint8_t reg);
203 virtual void restore_registers();
205 void apply_config_();
207 virtual void on_diag_without_error() {}
209 bool update_status_();
210 optional<uint8_t> current_to_scale_(float current);
211 float full_scale_current_();
212 int32_t get_vactual_() const { return static_cast<int32_t>(extract_field(this->vactual_reg_, VACTUAL)); }
213 int32_t speed_to_vactual_(float speed) const;
214 void add_index_pulses_();
215 void loop_serial_();
216 void loop_step_dir_();
217
218 GPIOPin *enn_pin_{nullptr};
220 GPIOPin *dir_pin_{nullptr};
225 // Write-only registers shared by all family members, with their power-on values
230 std::array<uint32_t, RESTORED_REGISTERS.size()> restored_values_{};
231 // NaN while not configured
232 float rsense_{NAN};
237 uint16_t status_{0};
238 optional<bool> vsense_{};
239 optional<uint8_t> ottrim_{};
240 uint8_t address_{0};
241 uint8_t toff_{3};
242 uint8_t version_{0};
243 uint8_t restored_written_{0}; // Bit per RESTORED_REGISTERS entry that has been written
245 int8_t direction_{0};
248 bool enabled_{false};
249 bool vsense_active_{false};
250 bool step_state_{false};
251 bool moving_{false};
253};
254
255} // namespace esphome::tmc22xx
BedjetMode mode
BedJet operating mode.
uint8_t address
Definition bl0906.h:4
uint16_le_t frequency
Definition bl0942.h:6
Helper class to request loop() to be called as fast as possible.
Definition helpers.h:2155
Base class for Trinamic stepper drivers that are configured over the single wire UART interface.
Definition tmc22xx.h:123
void set_step_pin(GPIOPin *pin)
Definition tmc22xx.h:133
int32_t speed_to_vactual_(float speed) const
Definition tmc22xx.cpp:421
void set_address(uint8_t address)
Definition tmc22xx.h:131
void set_ottrim(uint8_t ottrim)
Definition tmc22xx.h:140
void set_enn_pin(GPIOPin *pin)
Definition tmc22xx.h:132
void apply_config_()
Write the settings from the configuration to the readable registers.
Definition tmc22xx.cpp:157
void set_irun(uint8_t irun)
Definition tmc22xx.h:168
void set_dir_pin(GPIOPin *pin)
Definition tmc22xx.h:134
void set_pwm_freq(uint8_t freq)
Definition tmc22xx.h:182
void set_tpowerdown(uint8_t tpowerdown)
Definition tmc22xx.h:171
std::array< uint32_t, RESTORED_REGISTERS.size()> restored_values_
Definition tmc22xx.h:230
bool write_register(uint8_t reg, uint32_t value)
Definition tmc22xx.cpp:441
static uint32_t extract_field(uint32_t data, const RegisterField &field)
Definition tmc22xx.cpp:526
void set_microsteps(uint16_t microsteps)
Definition tmc22xx.cpp:372
void set_toff(uint8_t toff)
Chopper off time (1-15). TOFF=0 is used to disable the outputs, so this is applied on the next enable...
Definition tmc22xx.cpp:365
void add_on_status_callback(F &&callback)
Called with the condition and whether it became active or cleared.
Definition tmc22xx.h:153
optional< uint8_t > current_to_scale_(float current)
Definition tmc22xx.cpp:408
void set_pwm_grad(uint8_t grad)
Definition tmc22xx.h:181
void set_pwm_lim(uint8_t lim)
Definition tmc22xx.h:186
void set_vsense(bool vsense)
Definition tmc22xx.h:139
virtual uint32_t * shadow_register(uint8_t reg)
Return the cached value of a write-only register, or nullptr when the register is readable.
Definition tmc22xx.cpp:426
void set_ihold(uint8_t ihold)
Definition tmc22xx.h:169
virtual void restore_registers()
Write the cached write-only registers and the last written configuration registers to the driver,...
Definition tmc22xx.cpp:146
void set_pwm_ofs(uint8_t ofs)
Definition tmc22xx.h:180
void set_hstrt(uint8_t hstrt)
Definition tmc22xx.h:178
void set_analog_current_scale(bool enable)
Definition tmc22xx.h:141
void set_iholddelay(uint8_t delay)
Definition tmc22xx.h:170
void set_enabled(bool enabled)
Enable or disable the motor outputs, using the ENN pin when configured and TOFF otherwise.
Definition tmc22xx.cpp:344
void set_initial_hold_current(float current)
Definition tmc22xx.h:143
void set_standstill_mode(StandstillMode mode)
Definition tmc22xx.h:172
bool is_unreachable() const
True while the driver does not answer, until the status poll reads it again (every 10 s).
Definition tmc22xx.h:150
optional< uint32_t > read_register(uint8_t reg)
Definition tmc22xx.cpp:474
HighFrequencyLoopRequester high_freq_
Definition tmc22xx.h:252
optional< uint32_t > read_field(const RegisterField &field)
Definition tmc22xx.cpp:519
void set_diag_pin(InternalGPIOPin *pin)
Definition tmc22xx.h:136
void set_clock_frequency(uint32_t frequency)
Definition tmc22xx.h:137
InternalGPIOPin * diag_pin_
Definition tmc22xx.h:222
void set_spreadcycle(bool enable)
Definition tmc22xx.h:160
void set_hold_current(float current)
Definition tmc22xx.cpp:394
void set_index_pin(InternalGPIOPin *pin)
Definition tmc22xx.h:135
LazyCallbackManager< void(DriverEvent, bool)> status_callback_
Definition tmc22xx.h:223
virtual uint8_t expected_version() const =0
IC version reported in IOIN by the supported chip.
float scale_to_current(uint8_t scale)
Convert a current scale (0-31) to A RMS, without analog current scale.
Definition tmc22xx.cpp:404
void set_hend(uint8_t hend)
Definition tmc22xx.h:177
float get_setup_priority() const override
Definition tmc22xx.h:129
void set_initial_microsteps(uint16_t microsteps)
Definition tmc22xx.h:144
void set_pwm_autoscale(bool enable)
Definition tmc22xx.h:183
void set_tbl(uint8_t tbl)
Definition tmc22xx.h:176
void set_pwm_reg(uint8_t reg)
Definition tmc22xx.h:185
InternalGPIOPin * index_pin_
Definition tmc22xx.h:221
void set_interpolation(bool enable)
Definition tmc22xx.h:159
bool update_status_()
Read GSTAT and DRV_STATUS and report changes. Returns false when the status could not be read.
Definition tmc22xx.cpp:186
optional< uint8_t > ottrim_
Definition tmc22xx.h:239
void set_run_current(float current)
Set the motor run or hold current in A RMS.
Definition tmc22xx.cpp:389
void set_tpwm_threshold(uint32_t threshold)
Definition tmc22xx.h:162
bool write_field(const RegisterField &field, uint32_t value)
Definition tmc22xx.cpp:500
void set_pwm_autograd(bool enable)
Definition tmc22xx.h:184
virtual void on_diag_without_error()
Called when DIAG rises without a driver error.
Definition tmc22xx.h:207
void set_initial_run_current(float current)
Definition tmc22xx.h:142
void set_rsense(float rsense)
Definition tmc22xx.h:138
void set_inverse_direction(bool inverse)
Definition tmc22xx.h:161
constexpr uint16_t VERSION
constexpr float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.h:43
@ STANDSTILL_MODE_COIL_SHORT_HS
Definition tmc22xx.h:85
@ STANDSTILL_MODE_FREEWHEELING
Definition tmc22xx.h:83
@ STANDSTILL_MODE_COIL_SHORT_LS
Definition tmc22xx.h:84
@ STANDSTILL_MODE_NORMAL
Definition tmc22xx.h:82
DriverEvent
Driver conditions reported to on_status, in the order of their status bits: GSTAT bits 0-2,...
Definition tmc22xx.h:90
@ DRIVER_EVENT_TEMPERATURE_157C
Definition tmc22xx.h:105
@ DRIVER_EVENT_SHORT_TO_GROUND_B
Definition tmc22xx.h:97
@ DRIVER_EVENT_LOW_SIDE_SHORT_A
Definition tmc22xx.h:98
@ DRIVER_EVENT_CHARGE_PUMP_UNDERVOLTAGE
Definition tmc22xx.h:93
@ DRIVER_EVENT_DRIVER_ERROR
Definition tmc22xx.h:92
@ DRIVER_EVENT_TEMPERATURE_120C
Definition tmc22xx.h:102
@ DRIVER_EVENT_SHORT_TO_GROUND_A
Definition tmc22xx.h:96
@ DRIVER_EVENT_OVERTEMPERATURE_PREWARNING
Definition tmc22xx.h:94
@ DRIVER_EVENT_OPEN_LOAD_A
Definition tmc22xx.h:100
@ DRIVER_EVENT_TEMPERATURE_143C
Definition tmc22xx.h:103
@ DRIVER_EVENT_OVERTEMPERATURE
Definition tmc22xx.h:95
@ DRIVER_EVENT_TEMPERATURE_150C
Definition tmc22xx.h:104
@ DRIVER_EVENT_LOW_SIDE_SHORT_B
Definition tmc22xx.h:99
@ DRIVER_EVENT_OPEN_LOAD_B
Definition tmc22xx.h:101
void HOT delay(uint32_t ms)
Definition hal.cpp:85
static void uint32_t
Set by a rising edge on DIAG, which signals a driver error or, on chips that support it,...
Definition tmc22xx.h:110
static void gpio_intr(DiagPinStore *arg)
Definition tmc22xx.cpp:91
Counts the step pulses the driver reports on INDEX while it runs from VACTUAL.
Definition tmc22xx.h:116
static void gpio_intr(IndexPulseStore *arg)
Definition tmc22xx.cpp:89
A bit field inside one register.
Definition tmc22xx.h:15
constexpr uint32_t mask() const
Definition tmc22xx.h:21