56 uint16_t run_current_ma, uint16_t hold_current_ma, uint8_t& irun, uint8_t& ihold,
59 if (sense_resistor_mohm == 0 || supply_voltage_mv == 0) {
64 if (run_current_ma == 0) {
65 run_current_ma = motor_spec.rated_current_ma;
67 if (run_current_ma == 0) {
70 if (hold_current_ma == 0) {
71 hold_current_ma =
static_cast<uint16_t
>(
static_cast<float>(run_current_ma) * 0.3F);
77 if (
static_cast<float>(run_current_ma) > i_max_ma * 1.1F) {
81 auto cs_for = [i_max_ma](uint16_t ma) -> uint8_t {
82 const float cs = (
static_cast<float>(ma) * 32.0F / i_max_ma) - 1.0F;
86 return static_cast<uint8_t
>(std::min(31.0F, std::floor(cs + 1e-3F)));
88 irun = cs_for(run_current_ma);
89 ihold = cs_for(hold_current_ma);
91 ihold = (irun > 0) ?
static_cast<uint8_t
>(irun - 1) : 0;
98 if (run_current_ma == 0) {
99 run_current_ma = motor_spec.rated_current_ma;
101 if (run_current_ma == 0) {
106 if (hold_current_ma == 0) {
107 float hold_current_float = run_current_ma * 0.3F;
108 hold_current_ma =
static_cast<uint16_t
>(hold_current_float);
120 float i_rms_max_ma = ((VFS_MV /
static_cast<float>(sense_resistor_mohm)) / SQRT2) * 1000.0F;
123 if (
static_cast<float>(run_current_ma) > i_rms_max_ma * 1.1F) {
142 float global_scaler_float =
143 (
static_cast<float>(run_current_ma) * 256.0F) / std::max(i_rms_max_ma, 1.0F);
146 auto calculated_scaler =
static_cast<uint16_t
>(std::round(global_scaler_float));
147 calculated_scaler = std::max<uint16_t>(calculated_scaler, 32);
148 calculated_scaler = std::min<uint16_t>(calculated_scaler, 256);
152 uint8_t optimal_irun = 31;
153 uint16_t optimal_scaler = calculated_scaler;
155 if (calculated_scaler >= 200) {
157 for (uint8_t test_irun = 30; test_irun >= 16; --test_irun) {
159 float test_scaler_float =
160 (
static_cast<float>(run_current_ma) * 256.0F * 32.0F) /
161 (
static_cast<float>(test_irun + 1) * std::max(i_rms_max_ma, 1.0F));
162 auto test_scaler =
static_cast<uint16_t
>(std::round(test_scaler_float));
164 if (test_scaler >= 32 && test_scaler <= 200) {
165 optimal_irun = test_irun;
166 optimal_scaler = test_scaler;
173 if (optimal_irun < 8) {
177 (
static_cast<float>(run_current_ma) * 256.0F * 32.0F) / (9.0F * std::max(i_rms_max_ma, 1.0F));
178 optimal_scaler =
static_cast<uint16_t
>(std::round(scaler_float));
179 optimal_scaler = std::max<uint16_t>(optimal_scaler, 32);
180 optimal_scaler = std::min<uint16_t>(optimal_scaler, 256);
189 ((
static_cast<float>(hold_current_ma) * 256.0F * 32.0F) /
190 (
static_cast<float>(optimal_scaler) * std::max(i_rms_max_ma, 1.0F))) -
193 auto calculated_ihold =
static_cast<uint8_t
>(std::round(ihold_float));
196 calculated_ihold = std::min<uint8_t>(calculated_ihold, 31);
197 if (calculated_ihold >= optimal_irun) {
198 calculated_ihold = (optimal_irun > 0) ? (optimal_irun - 1) : 0;
202 ihold = calculated_ihold;
203 global_scaler = optimal_scaler;
226 uint8_t pwm_freq, uint32_t f_clk = 12000000U) noexcept {
232 constexpr std::array<uint8_t, 4> blank_times = {16, 24, 36, 54};
233 const uint8_t tbl_index = std::min(tbl,
static_cast<uint8_t
>(3));
234 uint8_t t_blank = blank_times[tbl_index];
237 constexpr std::array<uint32_t, 4> pwm_divisors = {1024, 683, 512, 410};
238 const uint8_t pwm_freq_index = std::min(pwm_freq,
static_cast<uint8_t
>(3));
239 uint32_t pwm_divisor = pwm_divisors[pwm_freq_index];
243 float f_pwm = (2.0F *
static_cast<float>(f_clk)) /
static_cast<float>(pwm_divisor);
250 float t_blank_sec =
static_cast<float>(t_blank) /
static_cast<float>(f_clk);
251 float i_lower_ma = (t_blank_sec * f_pwm *
static_cast<float>(supply_voltage_mv)) /
254 return static_cast<uint16_t
>(i_lower_ma);
bool CalculateMotorCurrent(const MotorSpec &motor_spec, uint32_t sense_resistor_mohm, uint32_t supply_voltage_mv, uint16_t run_current_ma, uint16_t hold_current_ma, uint8_t &irun, uint8_t &ihold, uint16_t &global_scaler, uint8_t chip_version=ChipVersion::TMC5160) noexcept
Calculate motor current settings from physical parameters.
Definition tmc51x0_motor_calc.hpp:55
uint16_t CalculateStealthChopLowerLimit(const MotorSpec &motor_spec, uint32_t supply_voltage_mv, uint8_t tbl, uint8_t pwm_freq, uint32_t f_clk=12000000U) noexcept
Calculate StealthChop lower current limit.
Definition tmc51x0_motor_calc.hpp:225