1#ifndef COMPONENT_HANDLER_MOTOR_CONTROLLER_H_
2#define COMPONENT_HANDLER_MOTOR_CONTROLLER_H_
4#include "handlers/tmc9660/Tmc9660Handler.h"
163 default:
return "Unknown error";
419 template <typename Func>
429 return h->visitDriver(std::forward<Func>(func));
432 using ReturnType =
decltype(h->visitDriver(std::forward<Func>(func)));
433 if constexpr (std::is_void_v<ReturnType>) {
479 ::tmc9660::units::MotorContext
const& ctx,
483 bool getMotorVelocity(
double& out_value, ::tmc9660::units::VelocityUnit unit,
484 ::tmc9660::units::MotorContext
const& ctx,
489 ::tmc9660::units::MotorContext
const& ctx,
493 bool getMotorPosition(
double& out_value, ::tmc9660::units::PositionUnit unit,
494 ::tmc9660::units::MotorContext
const& ctx,
513 bool setLoadVelocity(
double value, ::tmc9660::units::VelocityUnit unit,
514 ::tmc9660::units::MotorContext
const& ctx,
518 bool getLoadVelocity(
double& out_value, ::tmc9660::units::VelocityUnit unit,
519 ::tmc9660::units::MotorContext
const& ctx,
523 bool setLoadPosition(
double value, ::tmc9660::units::PositionUnit unit,
524 ::tmc9660::units::MotorContext
const& ctx,
528 bool getLoadPosition(
double& out_value, ::tmc9660::units::PositionUnit unit,
529 ::tmc9660::units::MotorContext
const& ctx,
549 const tmc9660::BootloaderConfig* bootCfg =
nullptr) noexcept;
564 const tmc9660::BootloaderConfig* bootCfg =
nullptr) noexcept;
580 const tmc9660::BootloaderConfig* bootCfg =
nullptr) noexcept;
593 BaseUart& uartInterface,
596 const tmc9660::BootloaderConfig* bootCfg =
nullptr) noexcept;
702 template <typename Fn>
720 void recordBatchLocked(uint8_t device_index,
size_t accesses,
size_t failed, uint32_t duration_us)
noexcept;
722 template <
typename Fn>
731 tmcHandlers_[device_index]->visitDriver([&](
auto& driver) {
732 if constexpr (std::is_same_v<std::decay_t<
decltype(driver)>, Tmc9660Handler::SpiDriver>) {
745 std::array<MotorMechanics, MAX_TMC9660_DEVICES>
mechanics_{};
Communication channels manager for the HardFOC Vortex V1 platform.
SpiDeviceId
SPI device identifiers for the Vortex V1 board.
Definition CommChannelsManager.h:113
constexpr const char * MotorErrorToString(MotorError error) noexcept
Convert MotorError to a human-readable string.
Definition MotorController.h:149
MotorController & GetMotorController() noexcept
Convenience accessor — equivalent to MotorController::GetInstance().
Definition MotorController.h:763
MotorError
Motor controller manager error codes for consistent error reporting.
Definition MotorController.h:117
@ NOT_INITIALIZED
Manager not yet initialised.
@ MUTEX_LOCK_FAILED
RTOS mutex acquire timed out.
@ INVALID_DEVICE_INDEX
Device index out of valid range.
@ DEPENDENCY_NOT_READY
Required dependency not initialised.
@ HANDLER_CREATION_FAILED
Heap allocation or handler init failed.
@ COMMUNICATION_FAILED
A bus-level transfer failed.
@ DEVICE_ALREADY_EXISTS
A device already occupies this slot.
@ CANNOT_DELETE_ONBOARD
Onboard device (index 0) cannot be deleted.
@ DEVICE_NOT_FOUND
No active device at the given index.
@ SUCCESS
Operation completed successfully.
@ INITIALIZATION_FAILED
Device initialisation failed.
@ INVALID_PARAMETER
Null pointer or out-of-range argument.
Tmc9660HostSpiGateMode
Vortex-style host SPI steering to the onboard TMC9660 (PCAL95555 outputs).
Definition MotorController.h:139
@ EnabledForHostSpiMotor
Host SPI to TMC9660 (PCAL_TMC_SPI_COMM_EN asserted).
@ Disabled
SPI mux released (UART motor path / idle).
TMC9660 telemetry snapshots, fault decoding and parameter-image apply for MotorController.
Singleton managing multiple TMC9660 motor controllers on Vortex V1.
Definition MotorController.h:207
MotorError ResetTmclSpiStats(uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Reset the SPI TMCL transport counters.
Definition MotorController.cpp:497
void recordBatchLocked(uint8_t device_index, size_t accesses, size_t failed, uint32_t duration_us) noexcept
Account one batch in accessStats_. Caller holds deviceMutex_.
Definition MotorController.cpp:516
bool withSpiDriverLocked(uint8_t device_index, Fn &&fn) noexcept
Definition MotorController.h:723
MotorError DeleteExternalDevice(uint8_t csDeviceIndex) noexcept
Delete an external TMC9660 device.
Definition MotorController.cpp:261
MotorError GetSystemDiagnostics(MotorSystemDiagnostics &diagnostics) const noexcept
Fill a diagnostics snapshot with current system state.
Definition MotorController.cpp:670
MotorError ApplyParameterImage(std::span< const MotorParameterWrite > image, const MotorApplyOptions &options, MotorApplyResult &result, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Apply a parameter image (MOTOR_TYPE first), optionally only where the chip differs and with read-back...
Definition MotorController.cpp:627
static constexpr uint8_t EXTERNAL_DEVICE_2_INDEX
External device 2 index (EXT_GPIO_CS_2)
Definition MotorController.h:212
MotorError ClearLatchedFaults(uint32_t general_errors, uint32_t gate_driver_errors, uint32_t adc_status, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Clear latched (write-1-to-clear) bits of the general error, gate-driver and ADC words.
Definition MotorController.cpp:606
MotorError GetLastError() const noexcept
Get the most recent error code.
Definition MotorController.h:254
MotorError CreateExternalDevice(uint8_t csDeviceIndex, SpiDeviceId spiDeviceId, uint8_t address, const Tmc9660ControlPins &pins, const tmc9660::BootloaderConfig *bootCfg=nullptr) noexcept
Create an external TMC9660 device on specified CS line (SPI).
Definition MotorController.cpp:160
void DumpStatistics() const noexcept
Dump comprehensive system statistics to log as INFO level. Logs all device statistics,...
Definition MotorController.cpp:699
static MotorController & GetInstance() noexcept
Get the singleton instance.
Definition MotorController.cpp:11
static constexpr uint8_t ONBOARD_TMC9660_INDEX
Onboard TMC9660 device index (SPI2_CS_TMC9660)
Definition MotorController.h:210
size_t InitializeAllDevices(std::array< bool, MAX_TMC9660_DEVICES > &results) noexcept
Initialize all active devices.
Definition MotorController.cpp:347
bool setMotorPosition(double value, ::tmc9660::units::PositionUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Command target position in motor frame.
Definition MotorController.cpp:846
std::array< tmc9660::TmclSpiTiming, MAX_TMC9660_DEVICES > tmclSpiTiming_
Per-device SPI TMCL timing.
Definition MotorController.h:746
void ResetAccessStats(uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Zero the access accounting of one device.
Definition MotorController.cpp:658
std::array< std::optional< Tmc9660Handler >, MAX_TMC9660_DEVICES > tmcHandlers_
Handlers in place (no heap): a slot is emplaced by Create*Device() and reset on delete/deinit.
Definition MotorController.h:741
bool setLoadVelocity(double value, ::tmc9660::units::VelocityUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Command target velocity in the load (output-shaft) frame.
Definition MotorController.cpp:874
std::optional< tmc9660::CommMode > TryGetOnboardCommMode() const noexcept
Physical comm mode for the onboard handler (slot 0), if present.
Definition MotorController.cpp:403
std::array< std::atomic< uint32_t >, MAX_TMC9660_DEVICES > deviceErrorCounts_
Per-device error counters.
Definition MotorController.h:744
std::array< bool, MAX_TMC9660_DEVICES > deviceInitialized_
Definition MotorController.h:742
std::array< bool, MAX_TMC9660_DEVICES > deviceActive_
Track which devices are active.
Definition MotorController.h:743
std::array< MotorAccessStats, MAX_TMC9660_DEVICES > accessStats_
Per-device TMCL access accounting.
Definition MotorController.h:747
bool getMotorPosition(double &out_value, ::tmc9660::units::PositionUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Read actual position in motor frame.
Definition MotorController.cpp:855
MotorError WriteParameters(std::span< MotorParameterAccess > items, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Write several axis parameters in pipelined batches (SAP); per-element status in items.
Definition MotorController.cpp:559
bool IsDeviceValid(uint8_t deviceIndex) const noexcept
Check if a device index is valid and has an active device.
Definition MotorController.cpp:303
bool setMotorVelocity(double value, ::tmc9660::units::VelocityUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Command target velocity in the motor (rotor) frame.
Definition MotorController.cpp:828
void UpdateLastError(MotorError error, int deviceIndex=-1) noexcept
Store a new error code and update per-device counter.
Definition MotorController.cpp:378
MotorError ReadTelemetry(MotorTelemetrySet set, MotorTelemetrySnapshot &snapshot, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Refresh a caller-owned telemetry snapshot from one batch.
Definition MotorController.cpp:573
void GetActiveDeviceIndices(std::array< uint8_t, MAX_TMC9660_DEVICES > &out, size_t &count) const noexcept
Get indices of all active devices.
Definition MotorController.cpp:318
MotorError CreateOnboardDevice(BaseSpi &spiInterface, uint8_t address, const Tmc9660ControlPins &pins, const tmc9660::BootloaderConfig *bootCfg=nullptr) noexcept
Create the onboard TMC9660 device using an SPI interface.
Definition MotorController.cpp:82
std::array< MotorMechanics, MAX_TMC9660_DEVICES > mechanics_
Per-device mechanical mapping (default 1:1)
Definition MotorController.h:745
MotorError SetTmclSpiTiming(const tmc9660::TmclSpiTiming &timing, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Set the SPI TMCL handshake timing for one TMC9660.
Definition MotorController.cpp:457
bool IsExternalDeviceIndex(uint8_t csDeviceIndex) const noexcept
Validate if CS device index is for external device.
Definition MotorController.cpp:286
void configureOnboardHostBusBeforeHandlerInitLocked(uint8_t device_index) noexcept
Definition MotorController.cpp:389
void applyTmclSpiTimingLocked(uint8_t device_index) noexcept
Definition MotorController.cpp:451
bool Initialize()
Initialize all registered motor controller devices.
Definition MotorController.cpp:24
uint8_t GetDeviceCount() const noexcept
Get the number of active TMC9660 devices.
Definition MotorController.cpp:291
void GetInitializationStatus(std::array< bool, MAX_TMC9660_DEVICES > &status) const noexcept
Get initialization status of all device slots.
Definition MotorController.cpp:366
bool Deinitialize() noexcept
Shut down all motor controller devices and release resources.
Definition MotorController.cpp:54
Tmc9660Handler * handler(uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Get access to Tmc9660Handler by device index.
Definition MotorController.cpp:333
MotorError GetTmclSpiTiming(tmc9660::TmclSpiTiming &timing, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) const noexcept
SPI TMCL timing stored for a slot (the driver defaults unless changed).
Definition MotorController.cpp:473
auto visitDriver(Func &&func, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Visit the underlying typed TMC9660 driver by device index.
Definition MotorController.h:420
MotorError applyOnboardTmc9660HostSpiGateModeLocked(Tmc9660HostSpiGateMode mode) noexcept
Definition MotorController.cpp:411
bool getLoadPosition(double &out_value, ::tmc9660::units::PositionUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Read actual position expressed in the load frame.
Definition MotorController.cpp:916
MotorError withReadyDriverLocked(uint8_t device_index, Fn &&fn) noexcept
Run fn on the SPI driver of a ready device, through the handler (handler lock held).
Definition MotorController.h:703
bool getLoadVelocity(double &out_value, ::tmc9660::units::VelocityUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Read actual velocity expressed in the load frame.
Definition MotorController.cpp:887
MotorError ReadParameters(std::span< MotorParameterAccess > items, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Read several axis parameters in pipelined batches (GAP).
Definition MotorController.cpp:545
bool EnsureInitialized() noexcept
Initialise all registered motor controllers if not already done.
Definition MotorController.h:228
MotorError ReadDriveDiagnostics(MotorDriveDiagnostics &out, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Read the four status words (289/299/300/301) in one batch and decode them.
Definition MotorController.cpp:586
static constexpr uint8_t MAX_TMC9660_DEVICES
Maximum supported TMC9660 devices (board + external)
Definition MotorController.h:209
bool IsExternalSlotAvailable(uint8_t csDeviceIndex) const noexcept
Check if an external device slot is available for creation.
Definition MotorController.cpp:308
bool onboardDeviceCreated_
Track if onboard device has been created.
Definition MotorController.h:749
RtosMutex deviceMutex_
RTOS mutex for thread-safe device access.
Definition MotorController.h:752
bool IsInitialized() const noexcept
Check whether the motor controller subsystem has been initialised.
Definition MotorController.h:242
MotorError GetAccessStats(MotorAccessStats &stats, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) const noexcept
TMCL access accounting of one device (batches, accesses, failures, batch latency).
Definition MotorController.cpp:649
static constexpr uint8_t EXTERNAL_DEVICE_1_INDEX
External device 1 index (EXT_GPIO_CS_1)
Definition MotorController.h:211
std::atomic< MotorError > last_error_
Most recent error code.
Definition MotorController.h:751
bool setMotorMechanics(const MotorMechanics &mech, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Set the mechanical mapping (gearbox + direction) for a device.
Definition MotorController.cpp:809
MotorMechanics getMotorMechanics(uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) const noexcept
Read back the currently configured mechanical mapping.
Definition MotorController.cpp:818
bool setLoadPosition(double value, ::tmc9660::units::PositionUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Command target position in the load frame (gearbox-aware).
Definition MotorController.cpp:903
std::atomic< bool > initialized_
Track if system has been initialized.
Definition MotorController.h:750
MotorError GetTmclSpiStats(tmc9660::TmclSpiStats &stats, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
SPI TMCL transport counters (frames, NOT_READY re-sends, stale replies, failures).
Definition MotorController.cpp:482
bool getMotorVelocity(double &out_value, ::tmc9660::units::VelocityUnit unit, ::tmc9660::units::MotorContext const &ctx, uint8_t deviceIndex=ONBOARD_TMC9660_INDEX) noexcept
Read actual velocity in motor frame.
Definition MotorController.cpp:837
MotorError ApplyOnboardTmc9660HostSpiGateMode(Tmc9660HostSpiGateMode mode) noexcept
Drive the onboard TMC9660 host SPI mux (PCAL_TMC_SPI_COMM_EN) on Vortex.
Definition MotorController.cpp:665
TelemetrySet
Which signals one ReadTelemetry() call fetches.
Definition Tmc9660DriveObservability.h:152
TelemetryField
The telemetry signals a snapshot carries (design §1.3, tiers C/F/S).
Definition Tmc9660DriveObservability.h:117
TMCL access accounting per device (every batch MotorController sends on the device's behalf).
Definition MotorController.h:99
uint32_t accesses
TMCL accesses in those batches.
Definition MotorController.h:101
uint32_t failed_accesses
Accesses not answered REPLY_OK.
Definition MotorController.h:102
uint32_t last_batch_us
Duration of the latest batch.
Definition MotorController.h:103
uint32_t max_batch_us
Longest batch since the last reset.
Definition MotorController.h:104
uint32_t batches
Batches sent (one per telemetry / diagnostics / parameter call)
Definition MotorController.h:100
Mechanical mapping between the motor (rotor) frame and the load (output-shaft) frame.
Definition MotorController.h:69
bool invert_output
Definition MotorController.h:82
double gear_ratio_motor_to_output
Definition MotorController.h:75
Per-device snapshot (indexed 0..MAX_TMC9660_DEVICES-1)
Definition MotorController.h:185
bool initialized
Definition MotorController.h:187
uint32_t error_count
Cumulative errors for this slot.
Definition MotorController.h:188
bool active
Definition MotorController.h:186
System-level diagnostics snapshot for motor controller health monitoring.
Definition MotorController.h:177
bool system_healthy
true when all active devices are initialized
Definition MotorController.h:178
static constexpr uint8_t kMaxDevices
Definition MotorController.h:190
bool system_initialized
MotorController::IsInitialized()
Definition MotorController.h:179
DeviceSnapshot devices[kMaxDevices]
Definition MotorController.h:191
uint8_t active_device_count
Number of active device slots.
Definition MotorController.h:180
uint8_t initialized_device_count
Number of successfully initialized devices.
Definition MotorController.h:181
MotorError last_error
Most recent error code.
Definition MotorController.h:182
Bundle of host-side GPIO references for TMC9660 control pins.
Definition MotorController.h:40
BaseGpio & rst
RST pin (output) - hardware reset.
Definition MotorController.h:41
BaseGpio & faultn
FAULTN pin (input) - fault status.
Definition MotorController.h:43
BaseGpio & drv_en
DRV_EN pin (output) - driver enable.
Definition MotorController.h:42
BaseGpio & wake
WAKE pin (output) - wake from hibernation.
Definition MotorController.h:44
How ApplyParameterImage() works.
Definition Tmc9660DriveObservability.h:437
What ApplyParameterImage() did.
Definition Tmc9660DriveObservability.h:443
The four TMC9660 status words, decoded (design §1.5). Raw words are kept for anything not named.
Definition Tmc9660DriveObservability.h:284
Caller-owned snapshot, refreshed in place by MotorController::ReadTelemetry().
Definition Tmc9660DriveObservability.h:166
One axis-parameter access in a batch (MCU- and transport-neutral copy of the driver's type).
Definition Tmc9660DriveObservability.h:52
One entry of a parameter image (design §4.1, the TMC image).
Definition Tmc9660DriveObservability.h:431