HardFOC Core
API reference
Loading...
Searching...
No Matches
Tmc9660Handler.h
Go to the documentation of this file.
1
85#ifndef COMPONENT_HANDLER_TMC9660_HANDLER_H_
86#define COMPONENT_HANDLER_TMC9660_HANDLER_H_
87
88#include <cstdint>
89#include <memory>
90#include <array>
91#include <atomic>
92#include <type_traits>
93#include <variant>
94#include "core/hf-core-drivers/external/hf-tmc9660-driver/inc/tmc9660.hpp"
95#include "core/hf-core-drivers/external/hf-tmc9660-driver/inc/tmc9660_comm_interface.hpp"
96#include "base/BaseGpio.h"
97#include "base/BaseAdc.h"
98#include "base/BaseTemperature.h"
99#include "base/BaseSpi.h"
100#include "base/BaseUart.h"
101#include "RtosMutex.h"
102#include <utility> // for std::as_const
103
109
123 BaseGpio& rst;
124 BaseGpio& drv_en;
125 BaseGpio& faultn;
126 BaseGpio& wake;
127
129 BaseGpio& get(tmc9660::TMC9660CtrlPin pin) noexcept {
130 switch (pin) {
131 case tmc9660::TMC9660CtrlPin::RST: return rst;
132 case tmc9660::TMC9660CtrlPin::DRV_EN: return drv_en;
133 case tmc9660::TMC9660CtrlPin::FAULTN: return faultn;
134 case tmc9660::TMC9660CtrlPin::WAKE: return wake;
135 default: return rst;
136 }
137 }
138
140 const BaseGpio& get(tmc9660::TMC9660CtrlPin pin) const noexcept {
141 switch (pin) {
142 case tmc9660::TMC9660CtrlPin::RST: return rst;
143 case tmc9660::TMC9660CtrlPin::DRV_EN: return drv_en;
144 case tmc9660::TMC9660CtrlPin::FAULTN: return faultn;
145 case tmc9660::TMC9660CtrlPin::WAKE: return wake;
146 default: return rst;
147 }
148 }
149};
150
182class HalSpiTmc9660Comm : public tmc9660::SpiCommInterface<HalSpiTmc9660Comm> {
183public:
203 HalSpiTmc9660Comm(BaseSpi& spi, BaseGpio& rst, BaseGpio& drv_en,
204 BaseGpio& faultn, BaseGpio& wake,
205 bool rst_active_high = true, bool drv_en_active_high = true,
206 bool faultn_active_low = false, bool wake_active_low = false) noexcept;
207
211
218 bool spiTransferTMCL(std::array<uint8_t, 8>& tx, std::array<uint8_t, 8>& rx) noexcept;
219
226 bool hostSpiTransferTMCLPair(std::array<uint8_t, 8>& tx1, std::array<uint8_t, 8>& rx1,
227 std::array<uint8_t, 8>& tx2, std::array<uint8_t, 8>& rx2,
228 uint32_t gap_us) noexcept;
229
236 bool spiTransferBootloader(std::array<uint8_t, 5>& tx, std::array<uint8_t, 5>& rx) noexcept;
237
248 bool gpioSet(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal signal) noexcept;
249
260 bool gpioRead(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal& signal) noexcept;
261
269 void debugLog(int level, const char* tag, const char* format, va_list args) noexcept;
270
275 void delayMs(uint32_t ms) noexcept;
276
285 void delayUs(uint32_t us) noexcept;
286
288
295 uint32_t transportDiag() const noexcept { return last_spi_err_; }
296
302 uint32_t rawTmclProbe(std::array<uint8_t, 8>& tx, std::array<uint8_t, 8>& rx,
303 uint32_t timeout_ms) noexcept;
304
305private:
306 BaseSpi& spi_;
308 uint32_t last_spi_err_{0};
309};
310
330class HalUartTmc9660Comm : public tmc9660::UartCommInterface<HalUartTmc9660Comm> {
331public:
345 HalUartTmc9660Comm(BaseUart& uart, BaseGpio& rst, BaseGpio& drv_en,
346 BaseGpio& faultn, BaseGpio& wake,
347 bool rst_active_high = true, bool drv_en_active_high = true,
348 bool faultn_active_low = false, bool wake_active_low = false) noexcept;
349
352
358 bool uartSendTMCL(const std::array<uint8_t, 9>& data) noexcept;
359
365 bool uartReceiveTMCL(std::array<uint8_t, 9>& data) noexcept;
366
373 bool uartTransferBootloader(const std::array<uint8_t, 8>& tx,
374 std::array<uint8_t, 8>& rx) noexcept;
375
377 bool gpioSet(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal signal) noexcept;
378
380 bool gpioRead(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal& signal) noexcept;
381
383 void debugLog(int level, const char* tag, const char* format, va_list args) noexcept;
384
386 void delayMs(uint32_t ms) noexcept;
387
389 void delayUs(uint32_t us) noexcept;
390
392
401 void setReplyTimeoutMs(uint32_t ms) noexcept { reply_timeout_ms_ = ms == 0U ? 80U : ms; }
402 uint32_t replyTimeoutMs() const noexcept { return reply_timeout_ms_; }
403
404private:
405 BaseUart& uart_;
407 uint32_t reply_timeout_ms_{80U};
408};
409
411
417
492public:
493 //==========================================================================
496 //==========================================================================
497
499 using SpiDriver = tmc9660::TMC9660<HalSpiTmc9660Comm>;
500
502 using UartDriver = tmc9660::TMC9660<HalUartTmc9660Comm>;
503
505 using DriverVariant = std::variant<std::monostate, SpiDriver*, UartDriver*>;
506
508 using ConstDriverVariant = std::variant<std::monostate, const SpiDriver*, const UartDriver*>;
509
511
512 //==========================================================================
515 //==========================================================================
516
531 static const tmc9660::BootloaderConfig kDefaultBootConfig;
532
534
535 //==========================================================================
538 //==========================================================================
539
560 Tmc9660Handler(BaseSpi& spi, BaseGpio& rst, BaseGpio& drv_en,
561 BaseGpio& faultn, BaseGpio& wake,
562 uint8_t address = 0,
563 const tmc9660::BootloaderConfig* bootCfg = &kDefaultBootConfig);
564
578 Tmc9660Handler(BaseUart& uart, BaseGpio& rst, BaseGpio& drv_en,
579 BaseGpio& faultn, BaseGpio& wake,
580 uint8_t address = 0,
581 const tmc9660::BootloaderConfig* bootCfg = &kDefaultBootConfig);
582
586 ~Tmc9660Handler() noexcept;
587
591 Tmc9660Handler& operator=(const Tmc9660Handler&) = delete;
592
596 Tmc9660Handler& operator=(Tmc9660Handler&&) = delete;
597
599
600 //==========================================================================
603 //==========================================================================
604
632 bool Initialize(bool performReset = true, bool retrieveBootloaderInfo = true,
633 bool failOnVerifyError = false);
634
639 bool EnsureInitialized() noexcept;
640
647 bool IsDriverReady() const noexcept;
648
655 void SetTmclReplyTimeoutMs(uint32_t ms) noexcept {
656 if (uart_comm_) uart_comm_->setReplyTimeoutMs(ms);
657 }
658
660
661 //==========================================================================
665 //==========================================================================
666
683 class Gpio : public BaseGpio {
684 public:
690 Gpio(Tmc9660Handler& parent, uint8_t gpioNumber);
691
693 ~Gpio() noexcept override = default;
694
697
699 bool Initialize() noexcept override;
700
702 bool Deinitialize() noexcept override;
703
705 bool IsPinAvailable() const noexcept override;
706
708 hf_u8_t GetMaxPins() const noexcept override;
709
711 const char* GetDescription() const noexcept override;
712
714
715 protected:
718
720 hf_gpio_err_t SetDirectionImpl(hf_gpio_direction_t direction) noexcept override;
721
723 hf_gpio_err_t SetOutputModeImpl(hf_gpio_output_mode_t mode) noexcept override;
724
726 hf_gpio_err_t SetPullModeImpl(hf_gpio_pull_mode_t mode) noexcept override;
727
729 hf_gpio_err_t SetPinLevelImpl(hf_gpio_level_t level) noexcept override;
730
732 hf_gpio_err_t GetPinLevelImpl(hf_gpio_level_t& level) noexcept override;
733
735 hf_gpio_pull_mode_t GetPullModeImpl() const noexcept override;
736
738 hf_gpio_err_t GetDirectionImpl(hf_gpio_direction_t& direction) const noexcept override;
739
741 hf_gpio_err_t GetOutputModeImpl(hf_gpio_output_mode_t& mode) const noexcept override;
742
744
745 private:
747 uint8_t gpioNumber_;
748 char description_[32];
749 hf_gpio_direction_t direction_ = hf_gpio_direction_t::HF_GPIO_DIRECTION_OUTPUT;
750 };
751
778 class Adc : public BaseAdc {
779 public:
784 Adc(Tmc9660Handler& parent);
785
787 ~Adc() noexcept override = default;
788
791
793 bool Initialize() noexcept override;
794
796 bool Deinitialize() noexcept override;
797
809 hf_u8_t GetMaxChannels() const noexcept override;
810
816 bool IsChannelAvailable(hf_channel_id_t channel_id) const noexcept override;
817
826 hf_adc_err_t ReadChannelV(hf_channel_id_t channel_id, float& channel_reading_v,
827 hf_u8_t numOfSamplesToAvg = 1,
828 hf_time_t timeBetweenSamples = 0) noexcept override;
829
838 hf_adc_err_t ReadChannelCount(hf_channel_id_t channel_id, hf_u32_t& channel_reading_count,
839 hf_u8_t numOfSamplesToAvg = 1,
840 hf_time_t timeBetweenSamples = 0) noexcept override;
841
851 hf_adc_err_t ReadChannel(hf_channel_id_t channel_id, hf_u32_t& channel_reading_count,
852 float& channel_reading_v, hf_u8_t numOfSamplesToAvg = 1,
853 hf_time_t timeBetweenSamples = 0) noexcept override;
854
863 hf_adc_err_t ReadMultipleChannels(const hf_channel_id_t* channel_ids, hf_u8_t num_channels,
864 hf_u32_t* readings, float* voltages) noexcept override;
865
867 hf_adc_err_t GetStatistics(hf_adc_statistics_t& statistics) noexcept override;
868
870 hf_adc_err_t GetDiagnostics(hf_adc_diagnostics_t& diagnostics) noexcept override;
871
873 hf_adc_err_t ResetStatistics() noexcept override;
874
876 hf_adc_err_t ResetDiagnostics() noexcept override;
877
879
883
891 hf_adc_err_t ReadAinChannel(uint8_t ain_channel, hf_u32_t& raw_value, float& voltage) noexcept;
892
900 hf_adc_err_t ReadCurrentSenseChannel(uint8_t current_channel, hf_u32_t& raw_value, float& voltage) noexcept;
901
909 hf_adc_err_t ReadVoltageChannel(uint8_t voltage_channel, hf_u32_t& raw_value, float& voltage) noexcept;
910
918 hf_adc_err_t ReadTemperatureChannel(uint8_t temp_channel, hf_u32_t& raw_value, float& voltage) noexcept;
919
927 hf_adc_err_t ReadMotorDataChannel(uint8_t motor_channel, hf_u32_t& raw_value, float& voltage) noexcept;
928
930
931 private:
933 mutable RtosMutex mutex_;
934 mutable hf_adc_statistics_t statistics_;
935 mutable hf_adc_diagnostics_t diagnostics_;
936 std::atomic<hf_adc_err_t> last_error_;
937
939 hf_adc_err_t ValidateChannelId(hf_channel_id_t channel_id) const noexcept;
940
953 hf_adc_err_t ReadChannelLocked(hf_channel_id_t channel_id,
954 hf_u32_t& raw, float& voltage) noexcept;
955
957 hf_adc_err_t UpdateStatistics(hf_adc_err_t result, uint64_t start_time_us) noexcept;
958
960 uint64_t GetCurrentTimeUs() const noexcept;
961
963 void UpdateDiagnostics(hf_adc_err_t error) noexcept;
964
966 const char* GetChannelTypeString(hf_channel_id_t channel_id) const noexcept;
967 };
968
987 class Temperature : public BaseTemperature {
988 public:
994
996 ~Temperature() noexcept override = default;
997
1000
1002 bool Initialize() noexcept override;
1003
1005 bool Deinitialize() noexcept override;
1006
1012 hf_temp_err_t ReadTemperatureCelsiusImpl(float* temperature_celsius) noexcept override;
1013
1019 hf_temp_err_t GetSensorInfo(hf_temp_sensor_info_t* info) const noexcept override;
1020
1025 hf_u32_t GetCapabilities() const noexcept override;
1026
1028
1029 private:
1031 mutable RtosMutex mutex_;
1032 mutable hf_temp_statistics_t statistics_;
1033 mutable hf_temp_diagnostics_t diagnostics_;
1034 std::atomic<hf_temp_err_t> last_error_;
1035
1037 hf_temp_err_t UpdateStatistics(hf_temp_err_t result, uint64_t start_time_us) noexcept;
1038
1040 uint64_t GetCurrentTimeUs() const noexcept;
1041
1043 void UpdateDiagnostics(hf_temp_err_t error) noexcept;
1044 };
1045
1047
1048 //==========================================================================
1052 //==========================================================================
1053
1064 Gpio* gpio(uint8_t gpioNumber) noexcept;
1065
1072 Adc* adc() noexcept;
1073
1080 Temperature* temperature() noexcept;
1081
1083
1084 //==========================================================================
1087 //==========================================================================
1088
1093 tmc9660::CommMode GetCommMode() const noexcept;
1094
1099 const tmc9660::BootloaderConfig* bootConfig() const noexcept { return bootCfg_; }
1100
1102
1103 //==========================================================================
1106 //==========================================================================
1107
1117 void DumpDiagnostics() noexcept;
1118
1123 const char* GetDescription() const noexcept;
1124
1126
1127 //==========================================================================
1131 //==========================================================================
1132
1160 SpiDriver* driverViaSpi() noexcept;
1161
1163 const SpiDriver* driverViaSpi() const noexcept;
1164
1178 UartDriver* driverViaUart() noexcept;
1179
1181 const UartDriver* driverViaUart() const noexcept;
1182
1187 [[nodiscard]] DriverVariant GetDriver() noexcept {
1188 if (auto* spi = driverViaSpi()) {
1189 return spi;
1190 }
1191 if (auto* uart = driverViaUart()) {
1192 return uart;
1193 }
1194 return std::monostate{};
1195 }
1196
1198 [[nodiscard]] ConstDriverVariant GetDriver() const noexcept {
1199 if (auto* spi = driverViaSpi()) {
1200 return spi;
1201 }
1202 if (auto* uart = driverViaUart()) {
1203 return uart;
1204 }
1205 return std::monostate{};
1206 }
1207
1209
1210 //==========================================================================
1214 //==========================================================================
1215
1230 template <typename Func>
1231 auto visitDriver(Func&& func) noexcept {
1232 using ReturnType = decltype(func(*spi_driver_));
1233 MutexLockGuard lock(handler_mutex_);
1234 if (!EnsureInitializedLocked()) {
1235 if constexpr (std::is_void_v<ReturnType>) {
1236 return;
1237 } else {
1238 return ReturnType{};
1239 }
1240 }
1241 if (use_spi_) {
1242 if (spi_driver_) return func(*spi_driver_);
1243 } else {
1244 if (uart_driver_) return func(*uart_driver_);
1245 }
1246 if constexpr (std::is_void_v<ReturnType>) {
1247 return;
1248 } else {
1249 return ReturnType{};
1250 }
1251 }
1252
1254 template <typename Func>
1255 auto visitDriver(Func&& func) const noexcept {
1256 using ReturnType = decltype(func(std::as_const(*spi_driver_)));
1257 MutexLockGuard lock(handler_mutex_);
1258 auto* self = const_cast<Tmc9660Handler*>(this);
1259 if (!self->EnsureInitializedLocked()) {
1260 if constexpr (std::is_void_v<ReturnType>) {
1261 return;
1262 } else {
1263 return ReturnType{};
1264 }
1265 }
1266 if (use_spi_) {
1267 if (spi_driver_) return func(std::as_const(*spi_driver_));
1268 } else {
1269 if (uart_driver_) return func(std::as_const(*uart_driver_));
1270 }
1271 if constexpr (std::is_void_v<ReturnType>) {
1272 return;
1273 } else {
1274 return ReturnType{};
1275 }
1276 }
1277
1279
1280private:
1281 //==========================================================================
1282 // Private Helpers
1283 //==========================================================================
1284
1286 friend class Tmc9660AdcWrapper;
1287
1294 Adc& AdcInstance() noexcept { return *adcWrapper_; }
1295
1297 bool EnsureInitializedLocked() noexcept;
1298
1300 template <typename Func>
1301 auto visitDriverInternal(Func&& func) noexcept {
1302 using ReturnType = decltype(func(*spi_driver_));
1303 if (use_spi_) {
1304 if (spi_driver_) return func(*spi_driver_);
1305 } else {
1306 if (uart_driver_) return func(*uart_driver_);
1307 }
1308 if constexpr (std::is_void_v<ReturnType>) {
1309 return;
1310 } else {
1311 return ReturnType{};
1312 }
1313 }
1314
1315 //==========================================================================
1316 // Private Members
1317 //==========================================================================
1318
1320
1324 std::unique_ptr<HalSpiTmc9660Comm> spi_comm_;
1325 std::unique_ptr<HalUartTmc9660Comm> uart_comm_;
1327
1331 std::unique_ptr<SpiDriver> spi_driver_;
1332 std::unique_ptr<UartDriver> uart_driver_;
1334
1338 std::array<std::unique_ptr<Gpio>, 2> gpioWrappers_;
1339 std::unique_ptr<Adc> adcWrapper_;
1340 std::unique_ptr<Temperature> temperatureWrapper_;
1342
1345 const tmc9660::BootloaderConfig* bootCfg_;
1347 bool boot_ok_{false};
1349
1352 mutable RtosMutex handler_mutex_;
1354
1355 char description_[64]{};
1356};
1357
1359
1360#endif // COMPONENT_HANDLER_TMC9660_HANDLER_H_
Concrete SPI communication adapter for TMC9660 using BaseSpi and BaseGpio.
Definition Tmc9660Handler.h:182
bool hostSpiTransferTMCLPair(std::array< uint8_t, 8 > &tx1, std::array< uint8_t, 8 > &rx1, std::array< uint8_t, 8 > &tx2, std::array< uint8_t, 8 > &rx2, uint32_t gap_us) noexcept
Two TMCL soft-CS frames under one bus lock (cmd + NO_OP / reply).
Definition Tmc9660Handler.cpp:185
void delayMs(uint32_t ms) noexcept
Delay execution for the specified number of milliseconds.
Definition Tmc9660Handler.cpp:243
uint32_t transportDiag() const noexcept
Last BaseSpi error observed by any TMCL/bootloader transfer.
Definition Tmc9660Handler.h:295
Tmc9660CtrlPins ctrl_pins_
Host-side control pin references.
Definition Tmc9660Handler.h:307
bool spiTransferBootloader(std::array< uint8_t, 5 > &tx, std::array< uint8_t, 5 > &rx) noexcept
Perform a 5-byte full-duplex SPI transfer for bootloader mode.
Definition Tmc9660Handler.cpp:218
BaseSpi & spi_
SPI bus interface (not owned).
Definition Tmc9660Handler.h:306
bool spiTransferTMCL(std::array< uint8_t, 8 > &tx, std::array< uint8_t, 8 > &rx) noexcept
Perform an 8-byte full-duplex SPI transfer for TMCL parameter mode.
Definition Tmc9660Handler.cpp:171
bool gpioRead(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal &signal) noexcept
Read a TMC9660 control pin's current logical signal state.
Definition Tmc9660Handler.cpp:234
uint32_t last_spi_err_
Last hf_spi_err_t from Transfer/TransferChain.
Definition Tmc9660Handler.h:308
void debugLog(int level, const char *tag, const char *format, va_list args) noexcept
Route TMC9660 driver debug output to the HardFOC Logger.
Definition Tmc9660Handler.cpp:239
bool gpioSet(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal signal) noexcept
Set a TMC9660 control pin to a given logical signal state.
Definition Tmc9660Handler.cpp:229
uint32_t rawTmclProbe(std::array< uint8_t, 8 > &tx, std::array< uint8_t, 8 > &rx, uint32_t timeout_ms) noexcept
Single-shot raw 8-byte transfer with caller-chosen bus-lock timeout.
Definition Tmc9660Handler.cpp:207
void delayUs(uint32_t us) noexcept
Delay execution for the specified number of microseconds.
Definition Tmc9660Handler.cpp:244
Concrete UART communication adapter for TMC9660 using BaseUart and BaseGpio.
Definition Tmc9660Handler.h:330
void delayUs(uint32_t us) noexcept
Delay execution for the specified number of microseconds.
Definition Tmc9660Handler.cpp:318
bool uartTransferBootloader(const std::array< uint8_t, 8 > &tx, std::array< uint8_t, 8 > &rx) noexcept
Perform an 8-byte UART bootloader transfer (send + receive).
Definition Tmc9660Handler.cpp:287
bool uartReceiveTMCL(std::array< uint8_t, 9 > &data) noexcept
Receive a 9-byte TMCL reply datagram over UART.
Definition Tmc9660Handler.cpp:275
void debugLog(int level, const char *tag, const char *format, va_list args) noexcept
Route TMC9660 driver debug output to the HardFOC Logger.
Definition Tmc9660Handler.cpp:313
bool uartSendTMCL(const std::array< uint8_t, 9 > &data) noexcept
Send a 9-byte TMCL datagram over UART.
Definition Tmc9660Handler.cpp:261
uint32_t reply_timeout_ms_
see setReplyTimeoutMs
Definition Tmc9660Handler.h:407
uint32_t replyTimeoutMs() const noexcept
Definition Tmc9660Handler.h:402
Tmc9660CtrlPins ctrl_pins_
Host-side control pin references.
Definition Tmc9660Handler.h:406
bool gpioSet(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal signal) noexcept
Set a TMC9660 control pin to a given logical signal state.
Definition Tmc9660Handler.cpp:303
void setReplyTimeoutMs(uint32_t ms) noexcept
How long a TMCL reply may take before the exchange fails.
Definition Tmc9660Handler.h:401
void delayMs(uint32_t ms) noexcept
Delay execution for the specified number of milliseconds.
Definition Tmc9660Handler.cpp:317
BaseUart & uart_
UART bus interface (not owned).
Definition Tmc9660Handler.h:405
bool gpioRead(tmc9660::TMC9660CtrlPin pin, tmc9660::GpioSignal &signal) noexcept
Read a TMC9660 control pin's current logical signal state.
Definition Tmc9660Handler.cpp:308
Delegation wrapper that adapts Tmc9660Handler::Adc for external ownership.
Definition Tmc9660AdcWrapper.h:63
BaseAdc adapter for all TMC9660 ADC channels.
Definition Tmc9660Handler.h:778
~Adc() noexcept override=default
Default destructor.
BaseGpio adapter for a single TMC9660 internal GPIO channel.
Definition Tmc9660Handler.h:683
hf_gpio_pull_mode_t GetPullModeImpl() const noexcept override
Returns FLOATING (TMC9660 pull is set via bootloader config).
Definition Tmc9660Handler.cpp:575
const char * GetDescription() const noexcept override
Returns a description string like "TMC9660 GPIO17".
Definition Tmc9660Handler.cpp:585
bool IsPinAvailable() const noexcept override
Check if this GPIO number is a valid TMC9660 pin (17 or 18).
Definition Tmc9660Handler.cpp:579
hf_gpio_err_t SetPinLevelImpl(hf_gpio_level_t level) noexcept override
Write HIGH or LOW to the TMC9660 GPIO pin via the driver.
Definition Tmc9660Handler.cpp:528
uint8_t gpioNumber_
TMC9660 internal GPIO pin number.
Definition Tmc9660Handler.h:747
hf_gpio_err_t SetOutputModeImpl(hf_gpio_output_mode_t mode) noexcept override
Set output mode. Only PUSH_PULL is supported.
Definition Tmc9660Handler.cpp:563
hf_gpio_err_t GetPinLevelImpl(hf_gpio_level_t &level) noexcept override
Read the current level of the TMC9660 GPIO pin via the driver.
Definition Tmc9660Handler.cpp:539
bool Initialize() noexcept override
Initialize the GPIO pin (configures as output by default on the TMC9660).
Definition Tmc9660Handler.cpp:519
hf_gpio_err_t SetPullModeImpl(hf_gpio_pull_mode_t mode) noexcept override
Set pull mode. Only FLOATING is supported.
Definition Tmc9660Handler.cpp:569
hf_gpio_direction_t direction_
Current direction.
Definition Tmc9660Handler.h:749
hf_gpio_err_t GetDirectionImpl(hf_gpio_direction_t &direction) const noexcept override
Returns the current configured direction (INPUT or OUTPUT).
Definition Tmc9660Handler.cpp:587
hf_gpio_err_t GetOutputModeImpl(hf_gpio_output_mode_t &mode) const noexcept override
Returns PUSH_PULL.
Definition Tmc9660Handler.cpp:592
bool Deinitialize() noexcept override
Deinitialize (no-op; TMC9660 GPIO persists until device reset).
Definition Tmc9660Handler.cpp:526
hf_gpio_err_t SetDirectionImpl(hf_gpio_direction_t direction) noexcept override
Set pin direction (INPUT or OUTPUT supported).
Definition Tmc9660Handler.cpp:550
Tmc9660Handler & parent_
Owning handler instance.
Definition Tmc9660Handler.h:746
~Gpio() noexcept override=default
Default destructor.
char description_[32]
Human-readable description (e.g., "TMC9660 GPIO17").
Definition Tmc9660Handler.h:748
hf_u8_t GetMaxPins() const noexcept override
Returns 2 (GPIO17 and GPIO18 are exposed).
Definition Tmc9660Handler.cpp:583
BaseTemperature adapter for the TMC9660 internal chip temperature sensor.
Definition Tmc9660Handler.h:987
~Temperature() noexcept override=default
Default destructor.
Unified, non-templated handler for a single TMC9660 motor controller device.
Definition Tmc9660Handler.h:491
bool use_spi_
true = SPI communication active, false = UART.
Definition Tmc9660Handler.h:1319
std::variant< std::monostate, SpiDriver *, UartDriver * > DriverVariant
Non-owning variant holding either driver type or empty (monostate).
Definition Tmc9660Handler.h:505
Temperature * temperature() noexcept
Get the Temperature wrapper.
Definition Tmc9660Handler.cpp:473
auto visitDriverInternal(Func &&func) noexcept
Internal no-lock visitDriver for use from already-locked contexts.
Definition Tmc9660Handler.h:1301
std::unique_ptr< UartDriver > uart_driver_
TMC9660 driver for UART mode (or nullptr).
Definition Tmc9660Handler.h:1332
Adc * adc() noexcept
Get the ADC wrapper.
Definition Tmc9660Handler.cpp:469
std::variant< std::monostate, const SpiDriver *, const UartDriver * > ConstDriverVariant
Const version of DriverVariant.
Definition Tmc9660Handler.h:508
bool IsDriverReady() const noexcept
Check if the TMC9660 driver has been initialized and is ready.
Definition Tmc9660Handler.cpp:451
uint8_t device_address_
7-bit TMCL device address.
Definition Tmc9660Handler.h:1346
const tmc9660::BootloaderConfig * bootCfg_
Bootloader config (not owned; must outlive handler).
Definition Tmc9660Handler.h:1345
Gpio * gpio(uint8_t gpioNumber) noexcept
Get the GPIO wrapper for a TMC9660 internal GPIO pin.
Definition Tmc9660Handler.cpp:459
std::unique_ptr< SpiDriver > spi_driver_
TMC9660 driver for SPI mode (or nullptr).
Definition Tmc9660Handler.h:1331
void SetTmclReplyTimeoutMs(uint32_t ms) noexcept
TMCL reply window for UART transfers (HalUartTmc9660Comm::setReplyTimeoutMs).
Definition Tmc9660Handler.h:655
std::unique_ptr< HalUartTmc9660Comm > uart_comm_
UART communication adapter (or nullptr).
Definition Tmc9660Handler.h:1325
static const tmc9660::BootloaderConfig kDefaultBootConfig
Default bootloader configuration based on TMC9660-3PH-EVAL board settings.
Definition Tmc9660Handler.h:28
auto visitDriver(Func &&func) noexcept
Execute a function on the underlying typed TMC9660 driver.
Definition Tmc9660Handler.h:1231
Adc & AdcInstance() noexcept
The always-present Adc instance, without the bring-up attempt adc() makes.
Definition Tmc9660Handler.h:1294
bool EnsureInitialized() noexcept
Ensure driver is initialized (lazy init entrypoint).
Definition Tmc9660Handler.cpp:439
tmc9660::TMC9660< HalSpiTmc9660Comm > SpiDriver
TMC9660 driver instantiated with SPI communication.
Definition Tmc9660Handler.h:499
tmc9660::TMC9660< HalUartTmc9660Comm > UartDriver
TMC9660 driver instantiated with UART communication.
Definition Tmc9660Handler.h:502
std::unique_ptr< Temperature > temperatureWrapper_
Chip temperature wrapper.
Definition Tmc9660Handler.h:1340
bool EnsureInitializedLocked() noexcept
Ensure initialized while handler_mutex_ is already held.
Definition Tmc9660Handler.cpp:444
bool boot_ok_
true only after bootloaderInit Success.
Definition Tmc9660Handler.h:1347
SpiDriver * driverViaSpi() noexcept
Get the TMC9660 driver instance connected via SPI (nullptr if using UART).
Definition Tmc9660Handler.cpp:485
std::array< std::unique_ptr< Gpio >, 2 > gpioWrappers_
GPIO17 [0] and GPIO18 [1].
Definition Tmc9660Handler.h:1338
auto visitDriver(Func &&func) const noexcept
Const overload of visitDriver().
Definition Tmc9660Handler.h:1255
RtosMutex handler_mutex_
Recursive mutex for thread-safe access.
Definition Tmc9660Handler.h:1352
std::unique_ptr< Adc > adcWrapper_
Multi-channel ADC wrapper.
Definition Tmc9660Handler.h:1339
std::unique_ptr< HalSpiTmc9660Comm > spi_comm_
SPI communication adapter (or nullptr).
Definition Tmc9660Handler.h:1324
DriverVariant GetDriver() noexcept
Get the active driver pointer without requiring visitor usage.
Definition Tmc9660Handler.h:1187
UartDriver * driverViaUart() noexcept
Get the TMC9660 driver instance connected via UART (nullptr if using SPI).
Definition Tmc9660Handler.cpp:497
tmc9660::CommMode GetCommMode() const noexcept
Get the communication mode in use (SPI or UART).
Definition Tmc9660Handler.cpp:481
~Tmc9660Handler() noexcept
Destructor. Releases the driver, communication adapter, and all wrappers.
bool Initialize(bool performReset=true, bool retrieveBootloaderInfo=true, bool failOnVerifyError=false)
Initialize the TMC9660 device.
Definition Tmc9660Handler.cpp:377
void DumpDiagnostics() noexcept
Dump comprehensive diagnostics to the system log.
Definition Tmc9660Handler.cpp:1013
ConstDriverVariant GetDriver() const noexcept
Const overload of GetDriver().
Definition Tmc9660Handler.h:1198
const tmc9660::BootloaderConfig * bootConfig() const noexcept
Get the bootloader configuration in use.
Definition Tmc9660Handler.h:1099
Shared helper holding the four TMC9660 host-side control pin references.
Definition Tmc9660Handler.h:122
BaseGpio & wake
WAKE control pin GPIO (not owned).
Definition Tmc9660Handler.h:126
const BaseGpio & get(tmc9660::TMC9660CtrlPin pin) const noexcept
Resolve a TMC9660CtrlPin enum (const).
Definition Tmc9660Handler.h:140
BaseGpio & faultn
FAULTN status pin GPIO (not owned).
Definition Tmc9660Handler.h:125
BaseGpio & get(tmc9660::TMC9660CtrlPin pin) noexcept
Resolve a TMC9660CtrlPin enum to the corresponding BaseGpio reference.
Definition Tmc9660Handler.h:129
BaseGpio & rst
RST control pin GPIO (not owned).
Definition Tmc9660Handler.h:123
BaseGpio & drv_en
DRV_EN control pin GPIO (not owned).
Definition Tmc9660Handler.h:124