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

Main class representing a TMC9660 motor driver in Parameter Mode. More...

#include <tmc9660.hpp>

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

Classes

struct  Brake
 Subsystem controlling the brake chopper and mechanical brake features. More...
 
struct  CurrentSensing
 Subsystem for configuring ADC-based current measurement. More...
 
struct  FeedbackSense
 Subsystem for feedback sensor configuration. More...
 
struct  GateDriver
 Subsystem for configuring the MOSFET gate driver. More...
 
struct  Globals
 Convenience helpers for reading and writing global parameters. More...
 
struct  GPIO
 Subsystem for configuring general-purpose IOs (GPIOs). More...
 
struct  Heartbeat
 Subsystem for configuring the communication watchdog (heartbeat). More...
 
struct  IIT
 Subsystem for motor thermal overload protection via I²t integration. More...
 
struct  MotorConfig
 Motor configuration and control subsystem. More...
 
struct  NvmStorage
 Subsystem for storing and recalling parameters from nonvolatile flash. More...
 
struct  PositionControl
 Subsystem for position control (FOC outer loop). More...
 
struct  Power
 Subsystem for entering low-power hibernation mode and configuring wake. More...
 
struct  Protection
 Subsystem for motor protection features. More...
 
struct  RamDebug
 Subsystem for debug and data logging features. More...
 
struct  Ramp
 Hardware 8-segment acceleration/dec-acc profile controller. More...
 
struct  ReferenceSearch
 Subsystem for executing a reference search (homing) routine. More...
 
struct  Script
 Subsystem for TMCL script execution control. More...
 
struct  StepDir
 Subsystem for controlling the STEP/DIR pulse input interface. More...
 
struct  StopEvents
 Configure automatic stop/latch behaviour for deviation, switches. More...
 
struct  Telemetry
 Subsystem for reading various telemetry and status information from the driver. More...
 
struct  TorqueFluxControl
 Subsystem for torque and flux current control (FOC inner loop). More...
 
struct  VelocityControl
 Subsystem for velocity control (FOC middle loop). More...
 

Public Types

enum class  BootloaderInitResult { Success , NoConfig , Failure }
 Bootloader initialization result codes. More...
 
using GlobalParamBankVariant
 

Public Member Functions

 TMC9660 (CommType &comm, uint8_t address=0, const tmc9660::BootloaderConfig *bootCfg=nullptr) noexcept
 Construct a TMC9660 driver instance.
 
 ~TMC9660 () noexcept
 Destructor for TMC9660, cleans up resources.
 
CommTypecomm () noexcept
 Get the communication interface used by this TMC9660 instance.
 
bool GpioSet (TMC9660CtrlPin pin, GpioSignal signal) noexcept
 
bool GpioRead (TMC9660CtrlPin pin, GpioSignal &signal) noexcept
 
bool GpioSetActive (TMC9660CtrlPin pin) noexcept
 
bool GpioSetInactive (TMC9660CtrlPin pin) noexcept
 
TMC9660::BootloaderInitResult bootloaderInit (const tmc9660::BootloaderConfig *cfg=nullptr, bool performReset=true, bool retrieveBootloaderInfo=false, bool failOnVerifyError=true) noexcept
 Complete bootloader initialization and transition to parameter mode.
 
tmc9660::TMC9660Bootloader< CommType > * getBootloader () noexcept
 Get direct access to the bootloader instance.
 
bool enterBootloaderMode () noexcept
 Exit parameter mode and return to bootloader mode.
 
bool writeParameter (tmc9660::tmcl::Parameters id, uint32_t value, uint8_t motorIndex=0) noexcept
 Set (write) an axis (motor-specific) parameter on the TMC9660.
 
bool readParameter (tmc9660::tmcl::Parameters id, uint32_t &value, uint8_t motorIndex=0) noexcept
 Read an axis (motor-specific) parameter from the TMC9660.
 
bool writeGlobalParameter (GlobalParamBankVariant id, uint8_t bank, uint32_t value) noexcept
 Set (write) a global parameter on the TMC9660.
 
bool readGlobalParameter (GlobalParamBankVariant id, uint8_t bank, uint32_t &value) noexcept
 Read a global parameter from the TMC9660.
 
bool sendCommand (tmc9660::tmcl::Op opcode, uint16_t type=0, uint8_t motor=0, uint32_t value=0, uint32_t *reply=nullptr) noexcept
 Send a TMCL command. Optionally return the 32-bit reply value.
 

Static Public Member Functions

static constexpr const charGetDriverVersion () noexcept
 Get the compiled driver version string.
 
static constexpr uint8_t GetDriverVersionMajor () noexcept
 Get the compiled driver major version number.
 
static constexpr uint8_t GetDriverVersionMinor () noexcept
 Get the compiled driver minor version number.
 
static constexpr uint8_t GetDriverVersionPatch () noexcept
 Get the compiled driver patch version number.
 

Public Attributes

struct tmc9660::TMC9660::MotorConfigthis
 
struct tmc9660::TMC9660::CurrentSensingthis
 
struct tmc9660::TMC9660::GateDriverthis
 
struct tmc9660::TMC9660::FeedbackSensethis
 
struct tmc9660::TMC9660::TorqueFluxControlthis
 
struct tmc9660::TMC9660::VelocityControlthis
 
struct tmc9660::TMC9660::PositionControlthis
 
struct tmc9660::TMC9660::Rampthis
 
struct tmc9660::TMC9660::StepDirthis
 
struct tmc9660::TMC9660::ReferenceSearchthis
 
struct tmc9660::TMC9660::Brakethis
 
struct tmc9660::TMC9660::IITthis
 
struct tmc9660::TMC9660::Telemetrythis
 
struct tmc9660::TMC9660::StopEventsthis
 
struct tmc9660::TMC9660::Protectionthis
 
struct tmc9660::TMC9660::Scriptthis
 
struct tmc9660::TMC9660::RamDebugthis
 
struct tmc9660::TMC9660::NvmStoragethis
 
struct tmc9660::TMC9660::Heartbeatthis
 
struct tmc9660::TMC9660::Globalsthis
 
struct tmc9660::TMC9660::GPIOthis
 
struct tmc9660::TMC9660::Powerthis
 

Private Attributes

CommTypecomm_
 sending/receiving data.
 
uint8_t address_
 
std::unique_ptr< tmc9660::TMC9660Bootloader< CommType > > bootloader_
 Bootloader helper.
 
const tmc9660::BootloaderConfigbootCfg_
 
const uint8_t tmcCRCTable_Poly7Reflected [256]
 

Detailed Description

template<typename CommType>
class tmc9660::TMC9660< CommType >

Main class representing a TMC9660 motor driver in Parameter Mode.

The TMC9660 class provides a comprehensive high-level interface for configuring and controlling the TMC9660 motor driver chip. This class abstracts the complex low-level register operations into intuitive, easy-to-use methods for motor control applications.

Key Features

The TMC9660 class supports a wide range of motor control features:

  • Motor Type Support: DC, BLDC/PMSM, and Stepper motors
  • Control Algorithms: Field-Oriented Control (FOC), open-loop, and closed-loop control
  • Sensor Integration: Hall sensors, incremental encoders, SPI encoders
  • Protection Systems: Overcurrent, overtemperature, overvoltage protection
  • Communication: TMCL command-based parameter access
  • Scripting: Execute custom scripts on the device's microcontroller
  • Telemetry: Real-time monitoring of temperature, current, voltage, and position

Communication Interface

The class uses a CRTP-based communication interface for communication, making it completely agnostic to the physical communication layer. This allows the same code to work with SPI, UART, or other communication methods by simply providing the appropriate communication interface implementation.

The driver is a template class that takes the communication interface type as a template parameter, providing compile-time polymorphism with zero runtime overhead.

Parameter Mode Operation

All configuration and control is performed by sending TMCL (Trinamic Motion Control Language) commands to read and write parameter values. This provides a standardized interface that is consistent across different Trinamic motor drivers.

Initialization Requirements

Warning
CRITICAL: Before using any motor control functions, you MUST initialize the bootloader for parameter mode operation:
cfg.boot.boot_mode = tmc9660::bootcfg::BootMode::Parameter; // Essential!
cfg.boot.startMotorControl = true;
auto result = driver.bootloaderInit(&cfg);
// Handle initialization failure
}
SPI status codes as per TMC9660 Parameter Mode.
Definition tmc9660_comm_interface.hpp:514
@ Success
Successfully initialized the bootloader.
@ Parameter
Parameter mode - TMCL command-based motor control (recommended)
Complete bootloader configuration structure.
Definition bootloader_config.hpp:998

Without proper bootloader initialization, the TMC9660 will not respond to TMCL commands and motor control will not function.

Usage Example

// Create communication interface (SPI example)
class MySPI : public tmc9660::SpiCommInterface<MySPI> {
// ... implement required methods
};
MySPI spiComm;
// Create TMC9660 driver with template parameter
// Initialize bootloader
cfg.boot.startMotorControl = true;
driver.bootloaderInit(&cfg);
// Configure motor
driver.motor.setType(tmc9660::tmcl::MotorType::BLDC, 7); // 7 pole pairs
driver.motor.setPWMFrequency(20000); // 20 kHz PWM
// Start motor control
driver.motor.setCommutationMode(tmc9660::tmcl::CommutationMode::FOC_HALL);
driver.motor.enable();
CRTP-based SPI implementation of TMC9660CommInterface.
Definition tmc9660_comm_interface.hpp:855
Template Parameters
CommTypeThe communication interface type (must inherit from SpiCommInterface<CommType> or UartCommInterface<CommType>)

Member Typedef Documentation

◆ GlobalParamBankVariant

template<typename CommType >
using tmc9660::TMC9660< CommType >::GlobalParamBankVariant
Initial value:
GlobalParamBank3
Definition tmc9660_param_mode_tmcl.hpp:568
GlobalParamBank0
Definition tmc9660_param_mode_tmcl.hpp:479
GlobalParamBank2
Definition tmc9660_param_mode_tmcl.hpp:519

Member Enumeration Documentation

◆ BootloaderInitResult

Bootloader initialization result codes.

These indicate the outcome of the bootloaderInit() method.

Enumerator
Success 

Successfully initialized the bootloader.

NoConfig 

No bootloader configuration provided.

Failure 

Failed to initialize the bootloader.

Constructor & Destructor Documentation

◆ TMC9660()

template<typename CommType >
tmc9660::TMC9660< CommType >::TMC9660 ( CommType & comm,
uint8_t address = 0,
const tmc9660::BootloaderConfig * bootCfg = nullptr )
noexcept

Construct a TMC9660 driver instance.

Parameters
commReference to a user-implemented communication interface (SPI, UART, etc).
address(Optional) Module address if multiple TMC9660 devices are on one bus. For SPI, this is typically 0.

◆ ~TMC9660()

template<typename CommType >
tmc9660::TMC9660< CommType >::~TMC9660 ( )
noexcept

Destructor for TMC9660, cleans up resources.

Member Function Documentation

◆ bootloaderInit()

template<typename CommType >
TMC9660::BootloaderInitResult tmc9660::TMC9660< CommType >::bootloaderInit ( const tmc9660::BootloaderConfig * cfg = nullptr,
bool performReset = true,
bool retrieveBootloaderInfo = false,
bool failOnVerifyError = true )
noexcept

Complete bootloader initialization and transition to parameter mode.

This method performs the complete initialization sequence:

  1. Hardware reset (if performReset =true)
  2. Mode detection (bootloader vs parameter)
  3. Bootloader configuration (if needed)
  4. Motor control startup (if startMotorControl =true)
  5. SESSION_START consumption (if startMotorControl =true)
  6. TMCL communication verification (if startMotorControl =true)
Parameters
cfgBootloader configuration. MUST set cfg.boot.boot_mode = BootMode::Parameter for motor control functionality. If nullptr, uses configuration provided during construction.
perform_resetIf true (default), performs hardware reset sequence (RST pin toggle
  • FAULTN monitoring) to ensure chip enters bootloader mode. Set to false if you've already performed reset externally.
retrieveBootloaderInfoIf true, retrieves and logs all available bootloader information (version, features, git info, etc) for debugging.
failOnVerifyErrorIf true (default), initialization fails on read-back verification errors. If false, logs warnings but continues despite verification failures (useful for debugging or when some configs are expected to fail).
Returns
BootloaderInitResult indicating success, no config, or failure.
Warning
This method MUST be called successfully before any motor control operations.
Note
Complete Initialization (Recommended): Set cfg.boot.startMotorControl=true for a fully initialized, communication-verified chip ready for motor control commands.
Bootloader-Only Initialization: Set cfg.boot.startMotorControl=false if you need to stay in bootloader mode (e.g., for firmware flashing or custom configuration).
Typical usage:
cfg.boot.startMotorControl = true; // Start motor control after configuration
// Complete initialization (recommended)
if (driver.bootloaderInit(&cfg) != TMC9660::BootloaderInitResult::Success) {
// Handle initialization failure
}
// Driver is now ready for motor control commands!
// Bootloader-only initialization
cfg.boot.startMotorControl = false; // Stay in bootloader mode
if (driver.bootloaderInit(&cfg) != TMC9660::BootloaderInitResult::Success) {
// Handle initialization failure
}
// Chip is in bootloader mode, call bootloader_->startMotorControl() later

◆ comm()

template<typename CommType >
CommType & tmc9660::TMC9660< CommType >::comm ( )
inlinenoexcept

Get the communication interface used by this TMC9660 instance.

Returns
Reference to the communication interface (SPI, UART, etc).

◆ enterBootloaderMode()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::enterBootloaderMode ( )
inlinenoexcept

Exit parameter mode and return to bootloader mode.

This sends the special Boot command (0xF2 / 242) with magic values to trigger the motor control system to exit and return to bootloader mode.

Returns
true if command sent successfully
Note
After this command, wait 100-200ms for transition to complete
The chip will be in bootloader mode after transition
You can then use bootloader commands for reconfiguration
// Return to bootloader from parameter mode
driver.enterBootloaderMode();
vTaskDelay(pdMS_TO_TICKS(150)); // Wait for transition
// Now use bootloader commands
auto* bootloader = driver.getBootloader();
bootloader->setBank(5);
bootloader->setAddress(0x00020018);
bootloader->startMotorControl(); // Return to motor control
Here is the call graph for this function:

◆ getBootloader()

template<typename CommType >
tmc9660::TMC9660Bootloader< CommType > * tmc9660::TMC9660< CommType >::getBootloader ( )
inlinenoexcept

Get direct access to the bootloader instance.

Allows advanced users to send custom bootloader commands after using applyConfiguration() with startMotorControl =false.

Returns
Pointer to bootloader instance, or nullptr if not initialized or interface mode doesn't support bootloader (e.g., not SPI/UART).
Note
Typical usage pattern:
// 1. Apply configuration without starting motor control
cfg.boot.startMotorControl = false; // Stay in bootloader
driver.bootloaderInit(&cfg);
// 2. Get bootloader access for custom operations
auto* bootloader = driver.getBootloader();
if (bootloader) {
// Program OTP
bootloader->setBank(1);
bootloader->write32Inc(otp_data);
bootloader->otpBurn(0, 4);
// When done, start motor control
bootloader->startMotorControl();
}
Warning
Only call bootloader methods BEFORE calling start_motor_control(). After start_motor_control(), the bootloader exits and commands will fail.

◆ GetDriverVersion()

template<typename CommType >
static constexpr const char * tmc9660::TMC9660< CommType >::GetDriverVersion ( )
inlinestaticconstexprnoexcept

Get the compiled driver version string.

◆ GetDriverVersionMajor()

template<typename CommType >
static constexpr uint8_t tmc9660::TMC9660< CommType >::GetDriverVersionMajor ( )
inlinestaticconstexprnoexcept

Get the compiled driver major version number.

◆ GetDriverVersionMinor()

template<typename CommType >
static constexpr uint8_t tmc9660::TMC9660< CommType >::GetDriverVersionMinor ( )
inlinestaticconstexprnoexcept

Get the compiled driver minor version number.

◆ GetDriverVersionPatch()

template<typename CommType >
static constexpr uint8_t tmc9660::TMC9660< CommType >::GetDriverVersionPatch ( )
inlinestaticconstexprnoexcept

Get the compiled driver patch version number.

◆ GpioRead()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::GpioRead ( TMC9660CtrlPin pin,
GpioSignal & signal )
noexcept

◆ GpioSet()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::GpioSet ( TMC9660CtrlPin pin,
GpioSignal signal )
noexcept

◆ GpioSetActive()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::GpioSetActive ( TMC9660CtrlPin pin)
noexcept

◆ GpioSetInactive()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::GpioSetInactive ( TMC9660CtrlPin pin)
noexcept

◆ readGlobalParameter()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::readGlobalParameter ( GlobalParamBankVariant id,
uint8_t bank,
uint32_t & value )
noexcept

Read a global parameter from the TMC9660.

Parameters
idGlobal parameter ID number.
bankBank number or index associated with the parameter (can be Bank1, Bank2, or Bank3 enum).
[out]valueReference to store the read 32-bit value.
Returns
true if read successfully, false on error.

◆ readParameter()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::readParameter ( tmc9660::tmcl::Parameters id,
uint32_t & value,
uint8_t motorIndex = 0 )
noexcept

Read an axis (motor-specific) parameter from the TMC9660.

Parameters
idParameter ID number to read.
[out]valueReference to store the 32-bit parameter value read.
motor_indexIndex of the motor/axis (0 or 1).
Returns
true if the parameter was successfully read (device responded), false on error.

◆ sendCommand()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::sendCommand ( tmc9660::tmcl::Op opcode,
uint16_t type = 0,
uint8_t motor = 0,
uint32_t value = 0,
uint32_t * reply = nullptr )
noexcept

Send a TMCL command. Optionally return the 32-bit reply value.

Here is the caller graph for this function:

◆ writeGlobalParameter()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::writeGlobalParameter ( GlobalParamBankVariant id,
uint8_t bank,
uint32_t value )
noexcept

Set (write) a global parameter on the TMC9660.

Parameters
idGlobal parameter ID number.
bankBank number for global parameter (can be Bank1, Bank2, or Bank3 enum).
value32-bit value to write.
Returns
true if successfully written, false if an error occurred.

◆ writeParameter()

template<typename CommType >
bool tmc9660::TMC9660< CommType >::writeParameter ( tmc9660::tmcl::Parameters id,
uint32_t value,
uint8_t motorIndex = 0 )
noexcept

Set (write) an axis (motor-specific) parameter on the TMC9660.

Parameters
idParameter ID number (see TMC9660 documentation for the full list).
value32-bit value to write to the parameter.
motor_indexIndex of the motor/axis (0 or 1). Typically 0 unless the device controls multiple axes.
Returns
true if the parameter was successfully written (acknowledged by the device), false if an error occurred.

Member Data Documentation

◆ address_

template<typename CommType >
uint8_t tmc9660::TMC9660< CommType >::address_
private

Module address (0-127). Used primarily for UART multi-drop addressing.

◆ bootCfg_

◆ bootloader_

template<typename CommType >
std::unique_ptr<tmc9660::TMC9660Bootloader<CommType> > tmc9660::TMC9660< CommType >::bootloader_
private

Bootloader helper.

◆ comm_

template<typename CommType >
CommType& tmc9660::TMC9660< CommType >::comm_
private

sending/receiving data.

Communication interface (transport) for

◆ this [1/21]

◆ this [2/21]

◆ this [3/21]

◆ this [4/21]

◆ this [5/21]

◆ this [6/21]

◆ this [7/21]

◆ this [8/21]

◆ this [9/21]

◆ this [10/21]

◆ this [11/21]

◆ this [12/21]

◆ this [13/21]

◆ this [14/21]

◆ this [15/21]

◆ this [16/21]

◆ this [17/21]

◆ this [18/21]

◆ this [19/21]

◆ this [20/21]

◆ this [21/21]

◆ tmcCRCTable_Poly7Reflected

template<typename CommType >
const uint8_t tmc9660::TMC9660< CommType >::tmcCRCTable_Poly7Reflected[256]
private
Initial value:
= {
0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA,
0x7B, 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84,
0xF6, 0x67, 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31,
0xA0, 0xD2, 0x43, 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58,
0x2D, 0xBC, 0xCE, 0x5F, 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D,
0x0C, 0x79, 0xE8, 0x9A, 0x0B, 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3,
0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46,
0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21,
0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04,
0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A,
0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, 0xD8, 0x49, 0x3B, 0xAA, 0xDF,
0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, 0xC4, 0x55, 0x27, 0xB6,
0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, 0x90, 0x01, 0x73,
0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, 0x8C, 0x1D,
0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, 0xA8,
0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E,
0xCF,
}

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