fwt_software/include/fgc/TmcCurrent.h

51 lines
2.2 KiB
C++

#pragma once
//
// TmcCurrent — milliamps to TMC5160 register fields.
//
// The driver expresses coil current as two dimensionless knobs: GLOBALSCALER
// (0x0B) scales the whole bridge, and IRUN (a field of IHOLD_IRUN, 0x10) scales
// within that. What a given pair actually delivers depends on the sense resistor
// soldered to the board, which is why this lives on the host: hardware.ini knows
// the resistor, the firmware does not.
//
// I_rms = (GLOBALSCALER/256) * ((IRUN+1)/32) * (V_FS / (R_SENSE + 0.02)) / sqrt(2)
//
// V_FS is 0.325 V for the DRVCONF the firmware writes, and the 0.02 ohm is the
// TMC5160's internal contribution in series with the external resistor.
//
#include <string>
#include <vector>
namespace fgc {
// RMS phase current in milliamps for a given register pair. Returns 0 for a
// non-positive sense resistor rather than dividing by something meaningless.
double tmcRmsCurrentMa(int global_scaler, int irun, double r_sense_ohm,
double v_fs = 0.325);
struct TmcCurrentPlan {
bool ok = false;
int global_scaler = 0; // 32..255. Never 0: on the TMC that means 256, i.e.
// FULL SCALE, so a defaulted or truncated zero would
// silently mean maximum current.
int run_irun = 0; // 0..31, normal motion
int homing_irun = 0; // 0..31, endstop search only
// What the chosen registers actually deliver — always recomputed, never the
// requested value echoed back, so the log cannot flatter the result.
double run_ma = 0.0;
double homing_ma = 0.0;
std::vector<std::string> warnings; // caller logs each at WARN
};
// One GLOBALSCALER serves both currents: it is chosen so the RUN current lands at
// IRUN = 31 (microstep resolution is best at the top of the IRUN range, and that
// is where the axis spends its working life), and the homing IRUN is then derived
// at that same scaler. The firmware therefore switches modes with a single
// register write, and never re-scales a moving motor.
TmcCurrentPlan planTmcCurrent(double r_sense_ohm, double run_ma, double homing_ma,
double v_fs = 0.325);
} // namespace fgc