HF-TMC51x0 Driver (TMC5130 & TMC5160) 0.1.0-dev
Hardware Agnostic C++ Driver for the TMC51x0 (TMC5130 & TMC5160)
Loading...
Searching...
No Matches
tmc51x0::SpiCommInterface< Derived > Class Template Reference

CRTP-based SPI implementation of TMC5160CommInterface. More...

#include <tmc51x0_comm_interface.hpp>

Inheritance diagram for tmc51x0::SpiCommInterface< Derived >:
[legend]
Collaboration diagram for tmc51x0::SpiCommInterface< Derived >:
[legend]

Public Member Functions

 SpiCommInterface () noexcept
 Construct SPI communication interface.
 
void SetDaisyChainLength (uint8_t total_length) noexcept
 Set the total number of devices in the daisy chain.
 
uint8_t GetDaisyChainLength () const noexcept
 Get the total number of devices in the daisy chain.
 
uint8_t AutoDetectChainLength (uint8_t max_devices=8) noexcept
 Auto-detect the daisy chain length by sending a unique command that loops back.
 
CommMode GetMode () const noexcept
 Get communication mode (always SPI for this interface)
 
Result< void > SpiTransfer (const uint8_t *tx, uint8_t *rx, size_t length) noexcept
 Low-level SPI transfer for register read/write.
 
Result< uint32_t > ReadRegister (uint8_t address, uint8_t daisy_chain_position=0) noexcept
 Read a 32-bit register via SPI.
 
Result< void > WriteRegister (uint8_t address, uint32_t value, uint8_t daisy_chain_position=0) noexcept
 Write a 32-bit register via SPI.
 
 SpiCommInterface (const SpiCommInterface &)=delete
 
SpiCommInterfaceoperator= (const SpiCommInterface &)=delete
 
- Public Member Functions inherited from tmc51x0::CommInterface< Derived >
 CommInterface () noexcept=default
 Construct communication interface.
 
CommMode GetMode () const noexcept
 Get the underlying communication mode used by this interface.
 
Result< uint32_t > ReadRegister (uint8_t address, uint8_t address_param=0) noexcept
 Read a 32-bit register from the TMC5160.
 
Result< void > WriteRegister (uint8_t address, uint32_t value, uint8_t address_param=0) noexcept
 Write a 32-bit register to the TMC5160.
 
Result< void > GpioSet (TMC51x0CtrlPin pin, GpioSignal signal) noexcept
 Set GPIO pin signal state (output control)
 
Result< GpioSignalGpioRead (TMC51x0CtrlPin pin) noexcept
 Read GPIO pin signal state (input state)
 
Result< void > GpioSetActive (TMC51x0CtrlPin pin) noexcept
 Set GPIO pin to active state (convenience method)
 
Result< void > GpioSetInactive (TMC51x0CtrlPin pin) noexcept
 Set GPIO pin to inactive state (convenience method)
 
void DelayMs (uint32_t ms) noexcept
 Delay execution for specified milliseconds.
 
void DelayUs (uint32_t us) noexcept
 Delay execution for specified microseconds.
 
Result< void > SetPowerEnabled (bool enabled) noexcept
 Enable/disable power to the TMC51x0 (optional)
 
Result< void > PowerCycle (uint32_t power_off_ms=20, uint32_t power_on_settle_ms=20) noexcept
 Power-cycle the TMC51x0 (optional)
 
Result< void > SetClkFreq (uint32_t frequency_hz) noexcept
 Set external clock frequency on CLK pin (optional)
 
 CommInterface (const CommInterface &)=delete
 
CommInterfaceoperator= (const CommInterface &)=delete
 
void LogDebug (int level, const char *tag, const char *format,...) noexcept
 Public debug logging wrapper for external classes.
 
void LogDebug (LogLevel level, const char *tag, const char *format,...) noexcept
 LogDebug overload that accepts the driver-native LogLevel enum.
 

Static Public Attributes

static constexpr size_t kSpiScratchBytes
 

Protected Member Functions

 ~SpiCommInterface ()=default
 Protected destructor.
 
 SpiCommInterface (SpiCommInterface &&)=default
 
SpiCommInterfaceoperator= (SpiCommInterface &&)=default
 
- Protected Member Functions inherited from tmc51x0::CommInterface< Derived >
void DebugLog (int level, const char *tag, const char *format, va_list args) noexcept
 Debug logging function for detailed debugging information.
 
 ~CommInterface ()=default
 Protected destructor.
 
 CommInterface (CommInterface &&)=default
 
CommInterfaceoperator= (CommInterface &&)=default
 

Protected Attributes

uint8_t total_chain_length_
 Total number of devices in the daisy chain.
 
uint8_t user_specified_chain_length_ {0}
 
bool chain_length_verified_ {false}
 

Private Member Functions

Result< void > EnsureChainLengthKnown (uint8_t daisy_chain_position, const char *context) noexcept
 Ensure chain length is known and verified for daisy-chain operations.
 

Private Attributes

std::array< uint8_t, kSpiScratchBytestx_scratch_ {}
 
std::array< uint8_t, kSpiScratchBytesrx_scratch_ {}
 
uint32_t drv_err_log_count_ {0}
 

Detailed Description

template<typename Derived>
class tmc51x0::SpiCommInterface< Derived >

CRTP-based SPI implementation of TMC5160CommInterface.

Uses a 4-wire SPI bus (mode 3) to exchange 40-bit datagrams per datasheet section 4.1. The implementation uses 8 bytes (64 bits) for convenience, which is acceptable per datasheet as additional bits beyond 40 are shifted through an internal shift register for daisy-chaining. Data is sent MSB-first, big-endian.

SPI Datagram Structure (40 bits):

  • Bit 39: W (WRITE_notREAD bit) - 0 for read, 1 for write
  • Bits 38-32: 7-bit register address
  • Bits 31-0: 32-bit data (right-aligned)

Byte structure (MSB transmitted first):

  • Byte 0: W bit (bit 7) + 7-bit address (bits 6-0)
    • Read: address & 0x7F (bit 7 = 0)
    • Write: (address & 0x7F) | 0x80 (bit 7 = 1, add 0x80 to address)
  • Bytes 1-4: 32-bit data (MSB-first)
  • Bytes 5-7: Optional, unused (for daisy-chaining)

Response (40 bits):

  • Byte 0: SPI_STATUS (bits 39-32) - 8 status flags
  • Bytes 1-4: 32-bit data (bits 31-0)

Read access (pipelined per datasheet section 4.1.1):

  • Uses dummy write data (can be 0)
  • Read data is transferred back with the subsequent access
  • Requires two transfers: first sends address, second receives data

Write access:

  • Address | 0x80, then 4 bytes of data
  • Response mirrors previously written data

SPI Signals (per datasheet section 4.2):

  • SCK: Bus clock input
  • SDI: Serial data input (latched on rising edge of SCK)
  • SDO: Serial data output (driven following falling edge of SCK)
  • CSN: Chip select input (active low, must stay low during entire transaction)

Timing (per datasheet section 4.3):

  • Minimum 40 SCK clock cycles required
  • SPI Mode 3 (CPOL=1, CPHA=1)
  • MSB transmitted first

Daisy-Chaining Support

The TMC5160 supports daisy-chaining multiple chips on a single SPI bus per datasheet section 4.2. Each chip has an internal 40-bit shift register. Data on SDI is continuously shifted out on SDO with a 40-clock cycle delay, allowing data to propagate through the chain.

Hardware Setup for Daisy-Chaining:

  • All chips share: CSN (tied together), SCK, and SDI (MOSI)
  • MISO is daisy-chained: Master -> Chip0 SDO -> Chip1 SDI, Chip1 SDO -> Chip2 SDI, etc.
  • Last chip's SDO connects back to Master MISO
  • CS must be held low during the entire transfer (all bits must be sent while CS is low)

How Daisy-Chaining Works:

  • Data shifts continuously through the chain as long as CS is low and SCK is active
  • Each chip's SDO outputs data with a 40-clock delay (data clocked into SDI appears on SDO after 40 clock cycles)
  • Commands are latched when CS goes HIGH (rising edge) - each chip latches the 40 bits currently in its internal shift register at that moment
  • To address chip k (where k=0 is first chip, k=1 is second chip, etc.):
    • Send 40 bits of command (first)
    • Then send 40·k bits of padding (dummy zeros) to shift the command to chip k
    • Total bits = 40·(k+1)
    • The command for chip k must be the FIRST 40 bits sent, which will propagate to chip k's shift register after (k+1)*40 clock cycles

Response Reading (per datasheet):

  • Response from chip k in a chain of n devices requires sending 40·(n-k) dummy bits total Formula: 40·(n-k) bits of padding + 40 bits of command = 40·(n-k) bits (command included in total)
  • CRITICAL: Responses come back in REVERSE order (last device first, first device last)
    • Device n-1's response appears FIRST (at byte 0)
    • Device n-2's response appears second (at byte 5)
    • ...
    • Device 0's response appears LAST (at byte (n-1)*5)
  • To read from device k in chain of n devices:
    • Send 40·(n-k) bits total (40·(n-k-1) padding + 40 command, or just 40 command if k=n-1)
    • Response from device k appears at offset (n-k-1)*5 bytes in received data
    • Example: For n=3, k=1: Send 40*(3-1)=80 bits, response at offset (3-1-1)*5=5 bytes

CRITICAL: Chain Length MUST Always Be Known

Sending vs Receiving Calculations:

  • Sending (Command Transmission): To address device k, send (k+1)*40 bits = (k+1)*5 bytes
    • This shifts the command through k devices to reach device k
    • This calculation only requires knowing k (device position)
  • Receiving (Response Extraction): To receive response from device k in chain of n devices:
    • Total transfer size: 40·(n-k) bits = (n-k)*5 bytes (datasheet formula)
    • Response appears at offset (n-k-1)*5 bytes (reverse order: last device first)
    • This calculation REQUIRES knowing n (total chain length)
  • Transfer Size: For simultaneous send/receive, use max((k+1)*5, (n-k)*5) bytes
    • Sending requirement: (k+1)*5 bytes needed to shift command to device k
    • Receiving requirement: (n-k)*5 bytes needed to shift response back (datasheet formula)
    • Use max() to ensure both requirements are met:
      • For k < n/2: (n-k)*5 >= (k+1)*5, so (n-k)*5 dominates
      • For k >= n/2: (k+1)*5 > (n-k)*5, so (k+1)*5 dominates
    • Extra bytes beyond (k+1)*5 are padding (zeros) for full-duplex response extraction

Chain Length Requirements:

  • Chain length MUST be known for correct response extraction
  • If daisy_chain_position > 0 and chain length is unknown, it is automatically detected
  • If detection fails, operation returns false (chain length is required)
  • For single chip (daisy_chain_position == 0), chain length defaults to 1

Auto-Detection on First Access:

  • If daisy_chain_position > 0 and chain length is unknown, it is automatically detected on the first ReadRegister() or WriteRegister() call
  • Detection uses AutoDetectChainLength() which sends a unique command that loops back
  • The detected length is stored and used for all subsequent operations
  • If detection fails, operation returns false

Verification of User-Specified Length:

  • If user calls SetDaisyChainLength(n), the specified length is verified against auto-detected length on first access
  • If mismatch is detected, an error is logged: "DAISY CHAIN LENGTH MISMATCH!"
  • The detected length is used (not the user-specified value) to ensure correctness

Why This Matters:

  • Incorrect chain length leads to wrong response extraction offset
  • This causes reading wrong register values and incorrect SPI_STATUS flags
  • Auto-detection ensures correctness without requiring user to manually specify length
  • Verification catches configuration errors early

For multi-chip simultaneous communication:

  • Commands must be sent in REVERSE order: [cmd_n-1] [cmd_n-2] ... [cmd_0] (last device first)
  • Total: n * 40 bits = n * 5 bytes (back-to-back, no padding needed)
  • As data shifts continuously through the chain:
    • After (k+1)*40 clocks, device k has received cmd_k in its shift register
    • After n*40 clocks total, device 0 has cmd_0, device 1 has cmd_1, ..., device n-1 has cmd_n-1
  • When CS goes HIGH (rising edge), each device latches the 40 bits currently in its shift register
  • The reverse order ensures that after n*40 clocks, each device has the correct command to latch Example for 3-chip daisy chain (n=3, devices 0, 1, 2):
  • Single chip addressing:
    • Address chip 0 (k=0): Send 40-bit command + 0 padding = 40 bits (5 bytes)
    • Address chip 1 (k=1): Send 40-bit command + 40 padding = 80 bits (10 bytes)
    • Address chip 2 (k=2): Send 40-bit command + 80 padding = 120 bits (15 bytes)
  • Multi-chip simultaneous (all 3 chips):
    • Send: [cmd_2] [cmd_1] [cmd_0] = 120 bits (15 bytes, back-to-back, reverse order)
    • As data shifts continuously through the chain (CS held low):
      • After 40 clocks: Device 0 has cmd_2 in shift register, Device 1 has nothing, Device 2 has nothing
      • After 80 clocks: Device 0 has cmd_1 (shifted in), Device 1 has cmd_2 (from Device 0's SDO), Device 2 has nothing
      • After 120 clocks: Device 0 has cmd_0 (shifted in), Device 1 has cmd_1 (from Device 0's SDO), Device 2 has cmd_2 (from Device 1's SDO)
    • When CS goes HIGH (rising edge): Each device latches the 40 bits currently in its shift register
      • Device 0 latches cmd_0 ✓
      • Device 1 latches cmd_1 ✓
      • Device 2 latches cmd_2 ✓
  • Read response from chip k: Send 40·(n-k) dummy bits total (40·(n-k-1) padding + 40 command, or just 40 command if k=n-1) Response appears at offset (n-k-1)*5 bytes (reverse order: last device first) CRITICAL: Responses come back in REVERSE order - device n-1 response first, then n-2, ..., device 0 last

Architecture:

  • Each SpiCommInterface instance supports ONE SPI bus (shared by multiple TMC5160 drivers)
  • For daisy-chaining: Each TMC5160 instance tracks its own position and passes it to ReadRegister()/WriteRegister()
  • For multi-CS setups: Create separate SpiCommInterface instances (one per chip)
  • ReadRegister() and WriteRegister() automatically handle daisy-chaining based on position parameter
  • SetDaisyChainLength() must be called to enable optimal response extraction using datasheet formula
  • For higher-level multi-driver management, use TMC51x0DaisyChain class that manages multiple TMC5160 instances on a single SPI bus and automatically configures chain length

Example usage:

class MySPI : public tmc5160::SpiCommInterface<MySPI> {
public:
CommMode mode() const noexcept { return CommMode::SPI; }
bool spiTransfer(...) { ... }
bool gpioSet(...) { ... }
bool gpioRead(...) { ... }
void debugLog(...) { ... }
void delayMs(...) { ... }
void delayUs(...) { ... }
};
CommMode
Supported physical communication modes for TMC51x0.
Definition tmc51x0_comm_interface.hpp:221
Template Parameters
DerivedThe derived class type (CRTP pattern)

Constructor & Destructor Documentation

◆ SpiCommInterface() [1/3]

template<typename Derived >
tmc51x0::SpiCommInterface< Derived >::SpiCommInterface ( )
inlinenoexcept

Construct SPI communication interface.

Note: Pin active level configuration is handled by the derived class. The base class only deals with abstract signals (ACTIVE/INACTIVE).

◆ ~SpiCommInterface()

template<typename Derived >
tmc51x0::SpiCommInterface< Derived >::~SpiCommInterface ( )
protecteddefault

Protected destructor.

◆ SpiCommInterface() [2/3]

template<typename Derived >
tmc51x0::SpiCommInterface< Derived >::SpiCommInterface ( SpiCommInterface< Derived > && )
protecteddefault

◆ SpiCommInterface() [3/3]

template<typename Derived >
tmc51x0::SpiCommInterface< Derived >::SpiCommInterface ( const SpiCommInterface< Derived > & )
delete

Member Function Documentation

◆ AutoDetectChainLength()

template<typename Derived >
uint8_t tmc51x0::SpiCommInterface< Derived >::AutoDetectChainLength ( uint8_t max_devices = 8)
inlinenoexcept

Auto-detect the daisy chain length by sending a unique command that loops back.

This method sends a command with a unique, recognizable pattern to position (max_devices+1), which is beyond the last device. The command will shift through all devices and loop back to the MCU via the last device's SDO. By searching for our exact command pattern in the received data, we can determine the actual chain length.

Algorithm:

  1. Create a unique command with a distinctive pattern (e.g., read register 0x73 with unique data)
  2. Send command to position (max_devices+1) - beyond the last device
  3. Send enough padding: (max_devices+2)*40 bits total to ensure loopback is captured
  4. The command loops back after (n+1)*40 bits where n is the actual chain length
  5. Search received data for our exact command pattern
  6. When found at offset (n+1)*5, chain length = n
Parameters
max_devicesMaximum number of devices to probe (default: 8, max: 255)
Returns
Detected chain length (0 = single chip or detection failed, >0 = number of devices)
Note
This method requires that devices are powered (but don't need to be initialized)
The command uses a read operation which is safe and doesn't modify device state
The detected length is automatically set via SetDaisyChainLength()
Warning
This method performs a full SPI transaction and may take time
Here is the call graph for this function:
Here is the caller graph for this function:

◆ EnsureChainLengthKnown()

template<typename Derived >
Result< void > tmc51x0::SpiCommInterface< Derived >::EnsureChainLengthKnown ( uint8_t daisy_chain_position,
const char * context )
inlineprivatenoexcept

Ensure chain length is known and verified for daisy-chain operations.

Parameters
daisy_chain_positionPosition in daisy chain (0 = first chip/single chip)
contextContext string for logging (e.g., "ReadRegister", "WriteRegister")
Returns
Result<void> indicating success or error

This function handles:

  • Auto-detection if daisy_chain_position > 0 and chain length is unknown
  • Setting chain length to 1 for single chip mode (daisy_chain_position == 0)
  • Verification of user-specified chain length against auto-detected value
  • Verification of set chain length against auto-detected value
Note
This function is defined in the class body, so it's implicitly inline. This allows compiler optimization while maintaining code clarity and avoiding duplication between ReadRegister and WriteRegister.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDaisyChainLength()

template<typename Derived >
uint8_t tmc51x0::SpiCommInterface< Derived >::GetDaisyChainLength ( ) const
inlinenoexcept

Get the total number of devices in the daisy chain.

Returns
Total chain length (0 = unknown/single chip, >0 = total number of devices)

◆ GetMode()

template<typename Derived >
CommMode tmc51x0::SpiCommInterface< Derived >::GetMode ( ) const
inlinenoexcept

Get communication mode (always SPI for this interface)

Returns
CommMode::SPI

◆ operator=() [1/2]

template<typename Derived >
SpiCommInterface & tmc51x0::SpiCommInterface< Derived >::operator= ( const SpiCommInterface< Derived > & )
delete

◆ operator=() [2/2]

template<typename Derived >
SpiCommInterface & tmc51x0::SpiCommInterface< Derived >::operator= ( SpiCommInterface< Derived > && )
protecteddefault

◆ ReadRegister()

template<typename Derived >
Result< uint32_t > tmc51x0::SpiCommInterface< Derived >::ReadRegister ( uint8_t address,
uint8_t daisy_chain_position = 0 )
inlinenoexcept

Read a 32-bit register via SPI.

Parameters
addressRegister address (0x00-0x73)
valueReference to store the read value
daisy_chain_positionPosition in daisy chain (0 = first chip/single chip, default: 0) Specifies which chip in the chain to address
Returns
Result<uint32_t> containing the value or error

This method handles both single-chip and daisy-chain modes:

  • Single chip (daisy_chain_position = 0): Standard 40-bit SPI transaction (5 bytes)
  • Daisy-chain (daisy_chain_position > 0): Sends command with padding to shift it to the target device position in the chain

Daisy-Chain Transfer Logic:

CRITICAL: Chain length MUST be known for correct operation

  • Chain length is automatically detected on first access if not manually set
  • If detection fails, operation will fail (chain length is required)

Sending (Command Transmission):

  • Command is placed at bytes 0-4 (the 40-bit SPI frame)
  • Padding (zeros) is added from byte 5 onwards
  • To address device k: Send (k+1)*40 bits = (k+1)*5 bytes minimum
    • This shifts the command through k devices to reach device k

Receiving (Response Extraction):

  • To receive response from device k in chain of n devices:
    • Total transfer size: 40·(n-k) bits = (n-k)*5 bytes (datasheet formula)
    • Response appears at offset (n-k-1)*5 bytes (reverse order: last device first)
    • This requires knowing total chain length n

Transfer Size Calculation:

  • For simultaneous send/receive, use max((k+1)*5, (n-k)*5) bytes
    • Sending requirement: (k+1)*5 bytes to shift command to device k
    • Receiving requirement: (n-k)*5 bytes to shift response back (datasheet formula)
    • Use max() to ensure both requirements are met:
      • For k < n/2: (n-k)*5 >= (k+1)*5, so (n-k)*5 dominates
      • For k >= n/2: (k+1)*5 > (n-k)*5, so (k+1)*5 dominates
    • Extra bytes beyond (k+1)*5 are padding (zeros) for full-duplex behavior

Auto-Detection and Verification:

  • If daisy_chain_position > 0 and chain length is unknown (total_chain_length_ == 0), chain length is automatically detected on first access
  • If user has specified a chain length via SetDaisyChainLength(), it is verified against auto-detected length on first access
  • If mismatch is detected, an error is logged and the detected length is used
  • If detection fails, operation returns false (chain length is required)

Architecture Note: This SpiCommInterface instance can be shared by multiple TMC5160 drivers on the same SPI bus. Each TMC5160 instance has its own daisy_chain_position_ and passes it as a parameter when calling ReadRegister() or WriteRegister().

CSN is handled automatically by the SPI hardware or derived class implementation. For daisy-chaining, all chips share the same CSN (tied together).

Here is the call graph for this function:

◆ SetDaisyChainLength()

template<typename Derived >
void tmc51x0::SpiCommInterface< Derived >::SetDaisyChainLength ( uint8_t total_length)
inlinenoexcept

Set the total number of devices in the daisy chain.

Parameters
total_lengthTotal number of devices in the chain (1 = single chip, 2 = two chips, etc.) Set to 0 to disable daisy-chain mode (single chip, default)
Note
This is CRITICAL for proper response extraction using the datasheet formula 40·(n-k)
This should be set once during initialization, before any register access
For optimal efficiency with TMC51x0DaisyChain, set this to match the chain length
If set to a non-zero value, it will be verified against auto-detected length on first access. If mismatch is detected, ReadRegister/WriteRegister will return false.
If set to 0 and daisy_chain_position > 0, chain length will be auto-detected on first access.

◆ SpiTransfer()

template<typename Derived >
Result< void > tmc51x0::SpiCommInterface< Derived >::SpiTransfer ( const uint8_t * tx,
uint8_t * rx,
size_t length )
inlinenoexcept

Low-level SPI transfer for register read/write.

Parameters
txBuffer containing bytes to transmit
rxBuffer to receive bytes from device
lengthNumber of bytes to transfer
Returns
Result<void> indicating success or error
Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteRegister()

template<typename Derived >
Result< void > tmc51x0::SpiCommInterface< Derived >::WriteRegister ( uint8_t address,
uint32_t value,
uint8_t daisy_chain_position = 0 )
inlinenoexcept

Write a 32-bit register via SPI.

Parameters
addressRegister address (0x00-0x73)
value32-bit value to write
daisy_chain_positionPosition in daisy chain (0 = first chip/single chip, default: 0) Specifies which chip in the chain to address
Returns
Result<void> indicating success or error

This method handles both single-chip and daisy-chain modes:

  • Single chip (daisy_chain_position = 0): Standard 40-bit SPI transaction (5 bytes)
  • Daisy-chain (daisy_chain_position > 0): Sends command with padding to shift it to the target device position in the chain

Daisy-Chain Transfer Logic: Same as ReadRegister() - see ReadRegister() documentation for detailed explanation.

Key Points:

  • Chain length MUST be known (auto-detected if not set)
  • Sending: (k+1)*5 bytes to address device k
  • Receiving: (n-k)*5 bytes total, response at offset (n-k-1)*5 bytes
  • Transfer size: max((k+1)*5, (n-k)*5) bytes
  • Extra bytes beyond (k+1)*5 are padding (zeros) for full-duplex behavior

Auto-Detection and Verification: Same as ReadRegister() - chain length is auto-detected on first access if needed, and user-specified length is verified against detected length. If detection fails, operation returns false.

Architecture Note: This SpiCommInterface instance can be shared by multiple TMC5160 drivers on the same SPI bus. Each TMC5160 instance has its own daisy_chain_position_ and passes it as a parameter when calling ReadRegister() or WriteRegister().

CSN is handled automatically by the SPI hardware or derived class implementation. For daisy-chaining, all chips share the same CSN (tied together).

Here is the call graph for this function:

Member Data Documentation

◆ chain_length_verified_

template<typename Derived >
bool tmc51x0::SpiCommInterface< Derived >::chain_length_verified_ {false}
protected

Flag to track if chain length has been verified via auto-detection

◆ drv_err_log_count_

template<typename Derived >
uint32_t tmc51x0::SpiCommInterface< Derived >::drv_err_log_count_ {0}
private

◆ kSpiScratchBytes

template<typename Derived >
constexpr size_t tmc51x0::SpiCommInterface< Derived >::kSpiScratchBytes
staticconstexpr
Initial value:
=
static_cast<size_t>(TMC51X0_SPI_MAX_CHAIN_DEVICES + 2U) * 5U
#define TMC51X0_SPI_MAX_CHAIN_DEVICES
Definition tmc51x0_comm_interface.hpp:1672

◆ rx_scratch_

template<typename Derived >
std::array<uint8_t, kSpiScratchBytes> tmc51x0::SpiCommInterface< Derived >::rx_scratch_ {}
private

◆ total_chain_length_

template<typename Derived >
uint8_t tmc51x0::SpiCommInterface< Derived >::total_chain_length_
protected
Initial value:
{
0}

Total number of devices in the daisy chain.

0 = unknown/single chip (uses simplified approach) >0 = total number of devices (uses datasheet formula 40·(n-k))

This is CRITICAL for proper response extraction. When set correctly, ReadRegister and WriteRegister use the optimal datasheet formula. Total number of devices in daisy chain (0 = unknown/single chip)

◆ tx_scratch_

template<typename Derived >
std::array<uint8_t, kSpiScratchBytes> tmc51x0::SpiCommInterface< Derived >::tx_scratch_ {}
private

◆ user_specified_chain_length_

template<typename Derived >
uint8_t tmc51x0::SpiCommInterface< Derived >::user_specified_chain_length_ {0}
protected

User-specified chain length (0 = not specified, >0 = user value)


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