HF-TMC9660 Driver 0.1.0-dev
Hardware Agnostic C++ Driver for the TMC9660
Loading...
Searching...
No Matches
tmc9660::TMC9660< CommType >::CurrentSensing Struct Reference

Subsystem for configuring ADC-based current measurement. More...

#include <tmc9660.hpp>

Collaboration diagram for tmc9660::TMC9660< CommType >::CurrentSensing:
[legend]

Classes

struct  AutoConfig
 Configuration structure for auto-configuring current sensing. More...
 

Public Member Functions

bool setShuntType (tmc9660::tmcl::AdcShuntType shuntType) noexcept
 Set the ADC shunt type (Parameter 12: ADC_SHUNT_TYPE).
 
bool getShuntType (tmc9660::tmcl::AdcShuntType &shuntType) noexcept
 Get the ADC shunt type (Parameter 12: ADC_SHUNT_TYPE).
 
bool readRaw (int16_t &adc0, int16_t &adc1, int16_t &adc2, int16_t &adc3) noexcept
 Read raw ADC values (Parameters 13-16: ADC_I0_RAW ... ADC_I3_RAW).
 
bool setCSAGain (tmc9660::tmcl::CsaGain gain012, tmc9660::tmcl::CsaGain gain3) noexcept
 Set current sense amplifier gain (Parameters 17/18: CSA_GAIN_ADC_I0_TO_ADC_I2, CSA_GAIN_ADC_I3).
 
bool getCSAGain (tmc9660::tmcl::CsaGain &gain012, tmc9660::tmcl::CsaGain &gain3) noexcept
 Get current sense amplifier gain (Parameters 17/18: CSA_GAIN_ADC_I0_TO_ADC_I2, CSA_GAIN_ADC_I3).
 
bool setCSAFilter (tmc9660::tmcl::CsaFilter filter012, tmc9660::tmcl::CsaFilter filter3) noexcept
 Set current sense amplifier filter (Parameters 19/20: CSA_FILTER_ADC_I0_TO_ADC_I2, CSA_FILTER_ADC_I3).
 
bool getCSAFilter (tmc9660::tmcl::CsaFilter &filter012, tmc9660::tmcl::CsaFilter &filter3) noexcept
 Get current sense amplifier filter (Parameters 19/20: CSA_FILTER_ADC_I0_TO_ADC_I2, CSA_FILTER_ADC_I3).
 
bool setScalingFactor (uint16_t scaling_factor) noexcept
 Set current scaling factor (Parameter 21: CURRENT_SCALING_FACTOR).
 
bool getScalingFactor (uint16_t &scaling_factor) noexcept
 Get current scaling factor (Parameter 21: CURRENT_SCALING_FACTOR).
 
bool setPhaseAdcMapping (tmc9660::tmcl::AdcMapping ux1, tmc9660::tmcl::AdcMapping vx2, tmc9660::tmcl::AdcMapping wy1, tmc9660::tmcl::AdcMapping y2) noexcept
 Set ADC mapping for each phase (Parameters 22-25: PHASE_UX1_ADC_MAPPING ... PHASE_Y2_ADC_MAPPING).
 
bool getPhaseAdcMapping (tmc9660::tmcl::AdcMapping &ux1, tmc9660::tmcl::AdcMapping &vx2, tmc9660::tmcl::AdcMapping &wy1, tmc9660::tmcl::AdcMapping &y2) noexcept
 Get ADC mapping for each phase (Parameters 22-25: PHASE_UX1_ADC_MAPPING ... PHASE_Y2_ADC_MAPPING).
 
bool setScalingFactors (uint16_t scale0, uint16_t scale1, uint16_t scale2, uint16_t scale3) noexcept
 Set individual ADC scaling factors (Parameters 26-29: ADC_I0_SCALE ... ADC_I3_SCALE).
 
bool getScalingFactors (uint16_t &scale0, uint16_t &scale1, uint16_t &scale2, uint16_t &scale3) noexcept
 Get individual ADC scaling factors (Parameters 26-29: ADC_I0_SCALE ... ADC_I3_SCALE).
 
bool setInversion (tmc9660::tmcl::AdcInversion inv0, tmc9660::tmcl::AdcInversion inv1, tmc9660::tmcl::AdcInversion inv2, tmc9660::tmcl::AdcInversion inv3) noexcept
 Set ADC inversion (Parameters 30-33: ADC_I0_INVERTED ... ADC_I3_INVERTED).
 
bool getInversion (tmc9660::tmcl::AdcInversion &inv0, tmc9660::tmcl::AdcInversion &inv1, tmc9660::tmcl::AdcInversion &inv2, tmc9660::tmcl::AdcInversion &inv3) noexcept
 Get ADC inversion (Parameters 30-33: ADC_I0_INVERTED ... ADC_I3_INVERTED).
 
bool setOffsets (int16_t offset0, int16_t offset1, int16_t offset2, int16_t offset3) noexcept
 Set ADC offset (Parameters 34-37: ADC_I0_OFFSET ... ADC_I3_OFFSET).
 
bool getOffsets (int16_t &offset0, int16_t &offset1, int16_t &offset2, int16_t &offset3) noexcept
 Get ADC offset (Parameters 34-37: ADC_I0_OFFSET ... ADC_I3_OFFSET).
 
bool readScaledAndOffset (int16_t &adc0, int16_t &adc1, int16_t &adc2, int16_t &adc3) noexcept
 Read scaled and offset-compensated ADC values (Parameters 38-41: ADC_I0 ... ADC_I3).
 
bool calibrateOffsets (bool waitForCompletion=false, uint32_t timeoutMs=1000) noexcept
 Calibrate the ADC offsets for current measurement.
 
bool getCalibrationStatus (bool &is_calibrated) noexcept
 Check if ADC offset calibration has been completed.
 
bool configureAuto (const AutoConfig &config) noexcept
 Auto-configure current sensing based on shunt resistance and expected current.
 

Private Member Functions

 CurrentSensing (TMC9660 &parent) noexcept
 

Private Attributes

TMC9660driver
 

Friends

class TMC9660
 

Detailed Description

template<typename CommType>
struct tmc9660::TMC9660< CommType >::CurrentSensing

Subsystem for configuring ADC-based current measurement.

Constructor & Destructor Documentation

◆ CurrentSensing()

template<typename CommType >
tmc9660::TMC9660< CommType >::CurrentSensing::CurrentSensing ( TMC9660 & parent)
inlineexplicitprivatenoexcept

Member Function Documentation

◆ calibrateOffsets()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::calibrateOffsets ( bool waitForCompletion = false,
uint32_t timeoutMs = 1000 )
noexcept

Calibrate the ADC offsets for current measurement.

Initiates a calibration sequence for the ADCs. This should be done:

  1. With the motor stationary
  2. With the commutation mode set to off
Parameters
wait_for_completionIf true, wait until calibration is completed
timeout_msTimeout in milliseconds if waiting for completion
Returns
true if calibration was started (and completed if wait_for_completion is true)

◆ configureAuto()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::configureAuto ( const AutoConfig & config)
noexcept

Auto-configure current sensing based on shunt resistance and expected current.

This method automatically selects the optimal CSA gain and calculates the current scaling factor to enable direct m_a units for torque/flux commands.

The function:

  • Selects the smallest CSA gain that provides ≥1.5x headroom above expected peak current
  • Calculates CURRENT_SCALING_FACTOR using the formula from the datasheet:
    • Peak: Factor = 39.06 / (G_CSA * R_shunt_Ohm)
    • RMS: Factor = 27.62 / (G_CSA * R_shunt_Ohm)
  • Configures shunt type, CSA gain, filter, scaling factor, and ADC inversion
  • Optionally calculates per-ADC scaling factors if actual shunt resistances are provided

After calling this, torque/flux commands (MAX_TORQUE, TARGET_TORQUE, etc.) can be specified directly in m_a. For example, MAX_TORQUE = 3000 means 3.0 A.

Two-Level Scaling System

The TMC9660 uses a two-level scaling system:

  1. ADC_Ix_SCALE (per-phase trim): Compensates for physical mismatch in shunt resistors and CSA amplifier tolerances. Default: 1024 (1.000×). If actual shunt resistances are provided, this is automatically calculated to equalize all phases.
  2. CURRENT_SCALING_FACTOR (global unit conversion): Converts normalized ADC currents to m_a units for the torque/flux control system. This is automatically calculated based on nominal shunt resistance and CSA gain.

Signal flow:

SPI status codes as per TMC9660 Parameter Mode.
Definition tmc9660_comm_interface.hpp:514

Per-ADC Shunt Resistance Compensation

If you have measured the actual shunt resistance for each ADC channel, you can provide them to automatically calculate ADC_Ix_SCALE. The formula used is:

This ensures all phases report the same current for the same real current, compensating for shunt resistor tolerances.

Parameters
configConfiguration structure containing all current sensing parameters. See AutoConfig for details on all available options.
Returns
true if configuration was successful (and calibration succeeded if autoCalibrate=true)
Note
ADC inversion defaults are set according to Table 24 for the specified motor type, but can be overridden via config.adc0_inverted, etc. Verify in open-loop voltage mode and adjust if phases are 180° out of phase.
ADC offset calibration is required before using current sensing. If config.autoCalibrate is false, you must call calibrateOffsets() manually. The motor must be stationary and commutation must be off (SYSTEM_OFF) during calibration.
// Example 1: Basic configuration (minimal setup)
config.shuntResistance_mOhm = 3.0;
config.expectedPeakCurrent_A = 3.0;
config.motorType = tmc9660::tmcl::MotorType::BLDC_MOTOR;
driver.currentSensing.configureAuto(config);
// Example 2: With measured shunt resistances for automatic ADC_Ix_SCALE compensation
// Measured: U=2.97 mΩ, V=3.01 mΩ, W=3.02 mΩ (nominal = 3.00 mΩ)
config.actualShuntR_adc0_mOhm = 2.97; // ADC_I0 (Phase U)
config.actualShuntR_adc1_mOhm = 3.01; // ADC_I1 (Phase V)
config.actualShuntR_adc2_mOhm = 3.02; // ADC_I2 (Phase W)
driver.currentSensing.configureAuto(config);
// Example 3: With custom ADC mapping and inversion
config.phaseU_adcMapping = tmc9660::tmcl::AdcMapping::ADC_I0;
config.phaseV_adcMapping = tmc9660::tmcl::AdcMapping::ADC_I1;
config.phaseW_adcMapping = tmc9660::tmcl::AdcMapping::ADC_I2;
config.adc0_inverted = tmc9660::tmcl::AdcInversion::INVERTED;
config.adc1_inverted = tmc9660::tmcl::AdcInversion::INVERTED;
config.adc2_inverted = tmc9660::tmcl::AdcInversion::INVERTED;
config.autoCalibrate = true;
driver.currentSensing.configureAuto(config);
// Now use m_a directly:
driver.motorConfig.setMaxTorqueCurrent(3000); // 3.0 A
driver.focControl.setTargetTorque(2500); // 2.5 A
Configuration structure for auto-configuring current sensing.
Definition tmc9660.hpp:888
TMC9660 & driver
Definition tmc9660.hpp:1038

◆ getCalibrationStatus()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getCalibrationStatus ( bool & is_calibrated)
noexcept

Check if ADC offset calibration has been completed.

Parameters
[out]is_calibratedSet to true if calibration is complete
Returns
true if the status was read successfully

◆ getCSAFilter()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getCSAFilter ( tmc9660::tmcl::CsaFilter & filter012,
tmc9660::tmcl::CsaFilter & filter3 )
noexcept

Get current sense amplifier filter (Parameters 19/20: CSA_FILTER_ADC_I0_TO_ADC_I2, CSA_FILTER_ADC_I3).

Parameters
[out]filter012CsaFilter enum value for ADC I0/I1/I2
[out]filter3CsaFilter enum value for ADC I3
Returns
true if successful

◆ getCSAGain()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getCSAGain ( tmc9660::tmcl::CsaGain & gain012,
tmc9660::tmcl::CsaGain & gain3 )
noexcept

Get current sense amplifier gain (Parameters 17/18: CSA_GAIN_ADC_I0_TO_ADC_I2, CSA_GAIN_ADC_I3).

Parameters
[out]gain012CsaGain enum value for ADC I0/I1/I2
[out]gain3CsaGain enum value for ADC I3
Returns
true if successful

◆ getInversion()

Get ADC inversion (Parameters 30-33: ADC_I0_INVERTED ... ADC_I3_INVERTED).

Parameters
[out]inv0AdcInversion enum value for ADC I0
[out]inv1AdcInversion enum value for ADC I1
[out]inv2AdcInversion enum value for ADC I2
[out]inv3AdcInversion enum value for ADC I3
Returns
true if all inversion flags were retrieved successfully

◆ getOffsets()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getOffsets ( int16_t & offset0,
int16_t & offset1,
int16_t & offset2,
int16_t & offset3 )
noexcept

Get ADC offset (Parameters 34-37: ADC_I0_OFFSET ... ADC_I3_OFFSET).

Parameters
[out]offset0Offset for ADC I0 (-32768...32767)
[out]offset1Offset for ADC I1 (-32768...32767)
[out]offset2Offset for ADC I2 (-32768...32767)
[out]offset3Offset for ADC I3 (-32768...32767)
Returns
true if all offsets were retrieved successfully

◆ getPhaseAdcMapping()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getPhaseAdcMapping ( tmc9660::tmcl::AdcMapping & ux1,
tmc9660::tmcl::AdcMapping & vx2,
tmc9660::tmcl::AdcMapping & wy1,
tmc9660::tmcl::AdcMapping & y2 )
noexcept

Get ADC mapping for each phase (Parameters 22-25: PHASE_UX1_ADC_MAPPING ... PHASE_Y2_ADC_MAPPING).

Parameters
[out]ux1AdcMapping enum value for UX1
[out]vx2AdcMapping enum value for VX2
[out]wy1AdcMapping enum value for WY1
[out]y2AdcMapping enum value for Y2
Returns
true if all mappings were retrieved successfully

◆ getScalingFactor()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getScalingFactor ( uint16_t & scaling_factor)
noexcept

Get current scaling factor (Parameter 21: CURRENT_SCALING_FACTOR).

Parameters
[out]scaling_factorScaling factor (1...65535)
Returns
true if successful

◆ getScalingFactors()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getScalingFactors ( uint16_t & scale0,
uint16_t & scale1,
uint16_t & scale2,
uint16_t & scale3 )
noexcept

Get individual ADC scaling factors (Parameters 26-29: ADC_I0_SCALE ... ADC_I3_SCALE).

Parameters
[out]scale0Scaling factor for ADC I0 (1...32767)
[out]scale1Scaling factor for ADC I1 (1...32767)
[out]scale2Scaling factor for ADC I2 (1...32767)
[out]scale3Scaling factor for ADC I3 (1...32767)
Returns
true if all scales were retrieved successfully

◆ getShuntType()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::getShuntType ( tmc9660::tmcl::AdcShuntType & shuntType)
noexcept

Get the ADC shunt type (Parameter 12: ADC_SHUNT_TYPE).

Parameters
[out]shuntTypeAdcShuntType enum value
Returns
true if successful

◆ readRaw()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::readRaw ( int16_t & adc0,
int16_t & adc1,
int16_t & adc2,
int16_t & adc3 )
noexcept

Read raw ADC values (Parameters 13-16: ADC_I0_RAW ... ADC_I3_RAW).

Parameters
[out]adc0Raw ADC I0
[out]adc1Raw ADC I1
[out]adc2Raw ADC I2
[out]adc3Raw ADC I3
Returns
true if all values were read successfully

◆ readScaledAndOffset()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::readScaledAndOffset ( int16_t & adc0,
int16_t & adc1,
int16_t & adc2,
int16_t & adc3 )
noexcept

Read scaled and offset-compensated ADC values (Parameters 38-41: ADC_I0 ... ADC_I3).

Parameters
[out]adc0Scaled/offset ADC I0
[out]adc1Scaled/offset ADC I1
[out]adc2Scaled/offset ADC I2
[out]adc3Scaled/offset ADC I3
Returns
true if all values were read successfully

◆ setCSAFilter()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::setCSAFilter ( tmc9660::tmcl::CsaFilter filter012,
tmc9660::tmcl::CsaFilter filter3 )
noexcept

Set current sense amplifier filter (Parameters 19/20: CSA_FILTER_ADC_I0_TO_ADC_I2, CSA_FILTER_ADC_I3).

Parameters
filter012CsaFilter enum value for ADC I0/I1/I2
filter3CsaFilter enum value for ADC I3
Returns
true if successful

◆ setCSAGain()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::setCSAGain ( tmc9660::tmcl::CsaGain gain012,
tmc9660::tmcl::CsaGain gain3 )
noexcept

Set current sense amplifier gain (Parameters 17/18: CSA_GAIN_ADC_I0_TO_ADC_I2, CSA_GAIN_ADC_I3).

Parameters
gain012CsaGain enum value for ADC I0/I1/I2
gain3CsaGain enum value for ADC I3
Returns
true if successful

◆ setInversion()

Set ADC inversion (Parameters 30-33: ADC_I0_INVERTED ... ADC_I3_INVERTED).

Parameters
inv0AdcInversion enum value for ADC I0
inv1AdcInversion enum value for ADC I1
inv2AdcInversion enum value for ADC I2
inv3AdcInversion enum value for ADC I3
Returns
true if all inversion flags were set successfully

◆ setOffsets()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::setOffsets ( int16_t offset0,
int16_t offset1,
int16_t offset2,
int16_t offset3 )
noexcept

Set ADC offset (Parameters 34-37: ADC_I0_OFFSET ... ADC_I3_OFFSET).

Parameters
offset0Offset for ADC I0 (-32768...32767)
offset1Offset for ADC I1 (-32768...32767)
offset2Offset for ADC I2 (-32768...32767)
offset3Offset for ADC I3 (-32768...32767)
Returns
true if all offsets were set successfully

◆ setPhaseAdcMapping()

Set ADC mapping for each phase (Parameters 22-25: PHASE_UX1_ADC_MAPPING ... PHASE_Y2_ADC_MAPPING).

Parameters
ux1AdcMapping enum value for UX1
vx2AdcMapping enum value for VX2
wy1AdcMapping enum value for WY1
y2AdcMapping enum value for Y2
Returns
true if all mappings were set successfully

◆ setScalingFactor()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::setScalingFactor ( uint16_t scaling_factor)
noexcept

Set current scaling factor (Parameter 21: CURRENT_SCALING_FACTOR).

Parameters
scaling_factorScaling factor (1...65535)
Returns
true if successful

◆ setScalingFactors()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::setScalingFactors ( uint16_t scale0,
uint16_t scale1,
uint16_t scale2,
uint16_t scale3 )
noexcept

Set individual ADC scaling factors (Parameters 26-29: ADC_I0_SCALE ... ADC_I3_SCALE).

Parameters
scale0Scaling factor for ADC I0 (1...32767)
scale1Scaling factor for ADC I1 (1...32767)
scale2Scaling factor for ADC I2 (1...32767)
scale3Scaling factor for ADC I3 (1...32767)
Returns
true if all scales were set successfully

◆ setShuntType()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::CurrentSensing::setShuntType ( tmc9660::tmcl::AdcShuntType shuntType)
noexcept

Set the ADC shunt type (Parameter 12: ADC_SHUNT_TYPE).

Parameters
shuntTypeAdcShuntType enum value
Returns
true if successful

Friends And Related Symbol Documentation

◆ TMC9660

template<typename CommType >
friend class TMC9660
friend

Member Data Documentation

◆ driver

template<typename CommType >
TMC9660& tmc9660::TMC9660< CommType >::CurrentSensing::driver
private

The documentation for this struct was generated from the following file: