HardFOC Core
API reference
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | List of all members
Tle92466edHandler Class Reference

Unified handler for TLE92466ED six-channel solenoid driver. More...

#include <Tle92466edHandler.h>

Classes

struct  is_driver_result
 Type trait to detect tle92466ed::DriverResult<T> types. More...
 
struct  is_driver_result< tle92466ed::DriverResult< T > >
 

Public Types

using DriverType = tle92466ed::Driver< HalSpiTle92466edComm >
 Driver type alias (tle92466ed::Driver bound to HalSpiTle92466edComm).
 

Public Member Functions

 Tle92466edHandler (BaseSpi &spi, BaseGpio &resn, BaseGpio &en, BaseGpio *faultn=nullptr) noexcept
 Construct TLE92466ED handler.
 
 ~Tle92466edHandler () noexcept
 Best-effort Deinitialize when the handler was initialized.
 
 Tle92466edHandler (const Tle92466edHandler &)=delete
 
Tle92466edHandler & operator= (const Tle92466edHandler &)=delete
 
 Tle92466edHandler (Tle92466edHandler &&)=delete
 
Tle92466edHandler & operator= (Tle92466edHandler &&)=delete
 
tle92466ed::DriverResult< void > Initialize (bool perform_hardware_reset=true) noexcept
 Initialize driver (hardware reset + SPI init + config mode).
 
bool EnsureInitialized () noexcept
 Lazy-init entrypoint: initialize on first use if needed.
 
tle92466ed::DriverResult< void > Initialize (const tle92466ed::GlobalConfig &config) noexcept
 Initialize, then apply config before mission mode.
 
tle92466ed::DriverResult< void > Deinitialize () noexcept
 Disable all channels and tear down driver_.
 
bool IsInitialized () const noexcept
 true after a successful Initialize or lazy EnsureInitialized.
 
tle92466ed::DriverResult< void > ConfigureChannel (uint8_t channel, const tle92466ed::ChannelConfig &config) noexcept
 Configure a channel (PWM, dither, current limit, …).
 
tle92466ed::DriverResult< void > EnableChannel (uint8_t channel) noexcept
 Enable a channel in CH_CTRL (requires EnableOutputStage for load current).
 
tle92466ed::DriverResult< void > DisableChannel (uint8_t channel) noexcept
 Disable a channel in CH_CTRL.
 
tle92466ed::DriverResult< void > EnableAllChannels () noexcept
 Set CH_CTRL enable for every channel.
 
tle92466ed::DriverResult< void > DisableAllChannels () noexcept
 Clear CH_CTRL enable for every channel.
 
tle92466ed::DriverResult< void > SetChannelCurrent (uint8_t channel, uint16_t current_ma) noexcept
 Set channel current setpoint.
 
tle92466ed::DriverResult< void > SetChannelCurrentUa (uint8_t channel, uint32_t current_ua) noexcept
 Set channel ICC setpoint in microamperes (15-bit TARGET resolution, ~61 µA LSB).
 
tle92466ed::DriverResult< uint16_t > GetChannelCurrentSetpoint (uint8_t channel, bool parallel_mode=false) noexcept
 Read back programmed current setpoint for SW-HAL-01 verification.
 
tle92466ed::DriverResult< void > ConfigurePwmRaw (uint8_t channel, uint8_t mantissa, uint8_t exponent, bool low_freq_range=false) noexcept
 Configure raw TP_MANT / TP_EXP PWM period fields.
 
tle92466ed::DriverResult< void > EnterMissionMode () noexcept
 Enter mission mode after configuration (required before driving loads).
 
tle92466ed::DriverResult< void > EnterConfigMode () noexcept
 Enter config mode so register writes are accepted.
 
bool IsMissionMode () noexcept
 true when the device is in mission (non-config) mode.
 
tle92466ed::DriverResult< void > EnableOutputStage () noexcept
 Drive the chip's hardware EN pin HIGH so the output stage can deliver current to the load.
 
tle92466ed::DriverResult< void > DisableOutputStage () noexcept
 Drive the chip's EN pin LOW to gate off the output stage. SPI access remains functional; only the low-side driver outputs are disabled. Useful as an emergency stop.
 
tle92466ed::DriverResult< void > EnableFeedbackUpdates () noexcept
 Clear the FB_FRZ register so the chip updates FB_DC / FB_I_AVG / FB_VBAT on every channel.
 
tle92466ed::DriverResult< void > GetStatus (tle92466ed::DeviceStatus &status) noexcept
 Read global device status (mode, rail voltages, OT flags, …).
 
tle92466ed::DriverResult< void > GetChannelDiagnostics (uint8_t channel, tle92466ed::ChannelDiagnostics &diag) noexcept
 Read per-channel diagnostics (faults, FB_I_AVG, duty cycle, …).
 
tle92466ed::DriverResult< void > GetFaultReport (tle92466ed::FaultReport &report) noexcept
 Aggregate fault snapshot across device and all channels.
 
tle92466ed::DriverResult< void > ClearFaults () noexcept
 Clear latched fault registers after the fault condition is removed.
 
bool HasFault () noexcept
 Check if any fault is present.
 
tle92466ed::DriverResult< void > KickWatchdog (uint16_t reload_value=1000) noexcept
 Reload the SPI watchdog (must be kicked periodically in mission mode).
 
uint32_t GetChipId () noexcept
 Read combined chip ID words for identity checks.
 
uint32_t GetIcVersion () noexcept
 Read IC version register (ICVID).
 
uint32_t LastSpiRxWord () const noexcept
 Last SPI RX word from HalSpiTle92466edComm (init / WrongDeviceID diag).
 
uint32_t LastSpiRxWordFirst () const noexcept
 RX word from the first frame of the last pipelined SPI chain.
 
bool RawSpiChain (std::span< const uint32_t > tx, std::span< uint32_t > rx, uint32_t gap_us=0U) noexcept
 Clock tx out as one bus-ownership chain and capture every reply.
 
template<typename Fn >
auto WithLock (Fn &&fn) noexcept
 Run fn (no arguments) while mutex_ is held.
 
template<typename Fn >
auto WithDriver (Fn &&fn) noexcept
 Run fn against the raw driver with mutex_ held.
 
DriverType * GetDriver () noexcept
 Get the underlying driver for advanced operations.
 
const DriverType * GetDriver () const noexcept
 
void DumpDiagnostics () noexcept
 Log device status, per-channel diagnostics, and chip ID to Logger.
 

Static Public Attributes

static constexpr uint8_t kNumChannels = 6
 Number of solenoid channels (0–5); only CH5 is populated on this board.
 

Private Member Functions

tle92466ed::DriverResult< void > InitializeLocked (bool perform_hardware_reset) noexcept
 Initialize while mutex_ is already held.
 
bool EnsureInitializedLocked () noexcept
 
template<typename Fn >
auto withDriver (Fn &&fn) noexcept
 Execute a lambda with a locked, initialized driver.
 

Private Attributes

bool initialized_ {false}
 
RtosMutex mutex_
 
std::unique_ptr< HalSpiTle92466edComm > comm_
 
std::unique_ptr< DriverType > driver_
 

Detailed Description

Unified handler for TLE92466ED six-channel solenoid driver.

Provides thread-safe access to all TLE92466ED driver features:

Member Typedef Documentation

◆ DriverType

Driver type alias (tle92466ed::Driver bound to HalSpiTle92466edComm).

Constructor & Destructor Documentation

◆ Tle92466edHandler() [1/3]

Tle92466edHandler::Tle92466edHandler ( BaseSpi &  spi,
BaseGpio &  resn,
BaseGpio &  en,
BaseGpio *  faultn = nullptr 
)
noexcept

Construct TLE92466ED handler.

Parameters
spiReference to pre-configured BaseSpi.
resnBaseGpio for RESN pin (active LOW reset).
enBaseGpio for EN pin (active HIGH enable).
faultnOptional BaseGpio for FAULTN (active LOW fault indicator).

◆ ~Tle92466edHandler()

Tle92466edHandler::~Tle92466edHandler ( )
noexcept

Best-effort Deinitialize when the handler was initialized.

◆ Tle92466edHandler() [2/3]

Tle92466edHandler::Tle92466edHandler ( const Tle92466edHandler &  )
delete

◆ Tle92466edHandler() [3/3]

Tle92466edHandler::Tle92466edHandler ( Tle92466edHandler &&  )
delete

Member Function Documentation

◆ ClearFaults()

tle92466ed::DriverResult< void > Tle92466edHandler::ClearFaults ( )
noexcept

Clear latched fault registers after the fault condition is removed.

◆ ConfigureChannel()

tle92466ed::DriverResult< void > Tle92466edHandler::ConfigureChannel ( uint8_t  channel,
const tle92466ed::ChannelConfig &  config 
)
noexcept

Configure a channel (PWM, dither, current limit, …).

Parameters
channelChannel index 0–5 (kNumChannels).
configPer-channel register image.
Return values
InvalidChannelwhen channel >= kNumChannels.

◆ ConfigurePwmRaw()

tle92466ed::DriverResult< void > Tle92466edHandler::ConfigurePwmRaw ( uint8_t  channel,
uint8_t  mantissa,
uint8_t  exponent,
bool  low_freq_range = false 
)
noexcept

Configure raw TP_MANT / TP_EXP PWM period fields.

Parameters
channelChannel index 0–5.
mantissaPWM period mantissa (datasheet TP_MANT).
exponentPWM period exponent (datasheet TP_EXP).
low_freq_rangeSelect low-frequency PWM range when true.

◆ Deinitialize()

tle92466ed::DriverResult< void > Tle92466edHandler::Deinitialize ( )
noexcept

Disable all channels and tear down driver_.

Returns
Empty (always succeeds at handler layer).
Note
Acquires mutex_; does not pulse RESN or change EN parking.

◆ DisableAllChannels()

tle92466ed::DriverResult< void > Tle92466edHandler::DisableAllChannels ( )
noexcept

Clear CH_CTRL enable for every channel.

◆ DisableChannel()

tle92466ed::DriverResult< void > Tle92466edHandler::DisableChannel ( uint8_t  channel)
noexcept

Disable a channel in CH_CTRL.

Parameters
channelChannel index 0–5.

◆ DisableOutputStage()

tle92466ed::DriverResult< void > Tle92466edHandler::DisableOutputStage ( )
noexcept

Drive the chip's EN pin LOW to gate off the output stage. SPI access remains functional; only the low-side driver outputs are disabled. Useful as an emergency stop.

◆ DumpDiagnostics()

void Tle92466edHandler::DumpDiagnostics ( )
noexcept

Log device status, per-channel diagnostics, and chip ID to Logger.

Note
Acquires mutex_ for the duration of the dump.

◆ EnableAllChannels()

tle92466ed::DriverResult< void > Tle92466edHandler::EnableAllChannels ( )
noexcept

Set CH_CTRL enable for every channel.

◆ EnableChannel()

tle92466ed::DriverResult< void > Tle92466edHandler::EnableChannel ( uint8_t  channel)
noexcept

Enable a channel in CH_CTRL (requires EnableOutputStage for load current).

Parameters
channelChannel index 0–5.

◆ EnableFeedbackUpdates()

tle92466ed::DriverResult< void > Tle92466edHandler::EnableFeedbackUpdates ( )
noexcept

Clear the FB_FRZ register so the chip updates FB_DC / FB_I_AVG / FB_VBAT on every channel.

Per the TLE92466ED datasheet §4.10 and the FB_FRZ register description (offset 0x0007): "Setting the <CH> bit in FB_FRZ to 0 enables the update of the feedback values; setting it to 1 freezes the values." The chip's POR default leaves all six channel bits set (frozen), which is why FB_DC / FB_I_AVG read back as 0 even when the chip is actively driving a coil. Writing 0x0000 unfreezes every channel. Averaged current feedback also requires non-zero DITHER_CLK_DIV. Safe to call multiple times; idempotent.

◆ EnableOutputStage()

tle92466ed::DriverResult< void > Tle92466edHandler::EnableOutputStage ( )
noexcept

Drive the chip's hardware EN pin HIGH so the output stage can deliver current to the load.

The TLE92466ED's EN input gates the entire output stage. While EN is LOW (the state the driver puts it in during reset), no current is delivered regardless of the per-channel EnableChannel bits or SetChannelCurrent setpoints. This method just calls Driver::Enable() which writes GpioSignal::ACTIVE to the configured EN GPIO.

Returns
Empty result on success or the underlying driver error.

◆ EnsureInitialized()

bool Tle92466edHandler::EnsureInitialized ( )
noexcept

Lazy-init entrypoint: initialize on first use if needed.

Returns
true when driver_ is ready after this call.
Note
Acquires mutex_. Lazy path always performs a hardware reset.

◆ EnsureInitializedLocked()

bool Tle92466edHandler::EnsureInitializedLocked ( )
privatenoexcept

◆ EnterConfigMode()

tle92466ed::DriverResult< void > Tle92466edHandler::EnterConfigMode ( )
noexcept

Enter config mode so register writes are accepted.

◆ EnterMissionMode()

tle92466ed::DriverResult< void > Tle92466edHandler::EnterMissionMode ( )
noexcept

Enter mission mode after configuration (required before driving loads).

Note
Does not assert EN; call EnableOutputStage separately.

◆ GetChannelCurrentSetpoint()

tle92466ed::DriverResult< uint16_t > Tle92466edHandler::GetChannelCurrentSetpoint ( uint8_t  channel,
bool  parallel_mode = false 
)
noexcept

Read back programmed current setpoint for SW-HAL-01 verification.

Parameters
channelChannel index 0–5.
parallel_modeWhen true, read parallel-setpoint register path.
Returns
Setpoint in milliamps.

◆ GetChannelDiagnostics()

tle92466ed::DriverResult< void > Tle92466edHandler::GetChannelDiagnostics ( uint8_t  channel,
tle92466ed::ChannelDiagnostics &  diag 
)
noexcept

Read per-channel diagnostics (faults, FB_I_AVG, duty cycle, …).

Parameters
channelChannel index 0–5.
[out]diagPopulated on success.
Note
FB_I_AVG stays 0 when FB_FRZ freezes the channel or DITHER_CLK_DIV is 0.

◆ GetChipId()

uint32_t Tle92466edHandler::GetChipId ( )
noexcept

Read combined chip ID words for identity checks.

Returns
32-bit ID or 0 when uninitialized / SPI failure.

◆ GetDriver() [1/2]

const Tle92466edHandler::DriverType * Tle92466edHandler::GetDriver ( ) const
noexcept

◆ GetDriver() [2/2]

Tle92466edHandler::DriverType * Tle92466edHandler::GetDriver ( )
noexcept

Get the underlying driver for advanced operations.

Returns
Pointer to driver, or nullptr if not initialized.
Warning
The returned pointer is not protected: the mutex is released when this call returns. Using it from more than one thread corrupts the chip's pipelined reply sequence. Production code must use WithDriver instead; this accessor remains for single-threaded bring-up and bench example programs.

◆ GetFaultReport()

tle92466ed::DriverResult< void > Tle92466edHandler::GetFaultReport ( tle92466ed::FaultReport &  report)
noexcept

Aggregate fault snapshot across device and all channels.

Parameters
[out]reportPopulated on success.

◆ GetIcVersion()

uint32_t Tle92466edHandler::GetIcVersion ( )
noexcept

Read IC version register (ICVID).

Returns
Version field or 0 when uninitialized / SPI failure.

◆ GetStatus()

tle92466ed::DriverResult< void > Tle92466edHandler::GetStatus ( tle92466ed::DeviceStatus &  status)
noexcept

Read global device status (mode, rail voltages, OT flags, …).

Parameters
[out]statusPopulated on success.

◆ HasFault()

bool Tle92466edHandler::HasFault ( )
noexcept

Check if any fault is present.

Returns
false when the driver is unavailable or the query fails.

◆ Initialize() [1/2]

tle92466ed::DriverResult< void > Tle92466edHandler::Initialize ( bool  perform_hardware_reset = true)
noexcept

Initialize driver (hardware reset + SPI init + config mode).

Parameters
perform_hardware_resetPulse RESN on first bring-up; false keeps RESN released for SPI-only retries (see Driver::Init).
Returns
Empty on success; tle92466ed::DriverError on failure.
Note
Acquires mutex_; blocks concurrent handler callers.

◆ Initialize() [2/2]

tle92466ed::DriverResult< void > Tle92466edHandler::Initialize ( const tle92466ed::GlobalConfig &  config)
noexcept

Initialize, then apply config before mission mode.

tle92466ed::GlobalConfig{} is now the configuration Driver::Init() itself writes: CRC check and SPI watchdog off, VBAT UV / OV at 7 V / 40 V. Set crc_enabled / spi_watchdog_enabled explicitly to turn them on; a default-constructed config no longer arms the watchdog.

Parameters
configGlobal device configuration (watchdog, dither clock, …).
Returns
Empty on success; rolls back driver_ on configure failure.
Note
Acquires mutex_; always performs hardware reset via Driver::Init().

◆ InitializeLocked()

tle92466ed::DriverResult< void > Tle92466edHandler::InitializeLocked ( bool  perform_hardware_reset)
privatenoexcept

Initialize while mutex_ is already held.

◆ IsInitialized()

bool Tle92466edHandler::IsInitialized ( ) const
inlinenoexcept

true after a successful Initialize or lazy EnsureInitialized.

◆ IsMissionMode()

bool Tle92466edHandler::IsMissionMode ( )
noexcept

true when the device is in mission (non-config) mode.

◆ KickWatchdog()

tle92466ed::DriverResult< void > Tle92466edHandler::KickWatchdog ( uint16_t  reload_value = 1000)
noexcept

Reload the SPI watchdog (must be kicked periodically in mission mode).

Parameters
reload_valueWatchdog reload counter written to the device (default 1000).

◆ LastSpiRxWord()

uint32_t Tle92466edHandler::LastSpiRxWord ( ) const
inlinenoexcept

Last SPI RX word from HalSpiTle92466edComm (init / WrongDeviceID diag).

Note
Does not acquire mutex_; safe for read-only post-mortem logging.

◆ LastSpiRxWordFirst()

uint32_t Tle92466edHandler::LastSpiRxWordFirst ( ) const
inlinenoexcept

RX word from the first frame of the last pipelined SPI chain.

See also
HalSpiTle92466edComm::LastRxWordFirst

◆ operator=() [1/2]

Tle92466edHandler & Tle92466edHandler::operator= ( const Tle92466edHandler &  )
delete

◆ operator=() [2/2]

Tle92466edHandler & Tle92466edHandler::operator= ( Tle92466edHandler &&  )
delete

◆ RawSpiChain()

bool Tle92466edHandler::RawSpiChain ( std::span< const uint32_t >  tx,
std::span< uint32_t >  rx,
uint32_t  gap_us = 0U 
)
inlinenoexcept

Clock tx out as one bus-ownership chain and capture every reply.

Parameters
txFrames to send (CRC must already be set by the caller).
rxReceives one MISO word per frame; same size as tx.
Returns
true when the chain completed on the wire.

The driver's own read path decodes only the slot it expects the reply in, so a register that reads back zero cannot be told apart from a reply that arrived one slot early or late. This hands back the untouched words for exactly that comparison.

Note
Holds mutex_ across the whole chain, so it cannot interleave with control-loop writes inside the device's reply pipeline.
Warning
Bench diagnostic (tle reg raw). Arbitrary frames can change device state — not for production paths.

◆ SetChannelCurrent()

tle92466ed::DriverResult< void > Tle92466edHandler::SetChannelCurrent ( uint8_t  channel,
uint16_t  current_ma 
)
noexcept

Set channel current setpoint.

Parameters
channelChannel index 0–5.
current_maTarget coil current in milliamps (e.g. 115 mA at full flow on CH5).

◆ SetChannelCurrentUa()

tle92466ed::DriverResult< void > Tle92466edHandler::SetChannelCurrentUa ( uint8_t  channel,
uint32_t  current_ua 
)
noexcept

Set channel ICC setpoint in microamperes (15-bit TARGET resolution, ~61 µA LSB).

Parameters
channelChannel index.
current_uaTarget current in µA.

◆ WithDriver()

template<typename Fn >
auto Tle92466edHandler::WithDriver ( Fn &&  fn)
inlinenoexcept

Run fn against the raw driver with mutex_ held.

This is the only safe way to reach advanced driver APIs (ConfigureDither, GetAverageCurrent, ReadPinStatus, rail reads, …) from production code. The TLE92466ED answers a read on the next CS window, so two threads interleaving driver calls consume each other's pipeline slots — which surfaced as sticky-zero register readback and impossible FB_I_AVG ratios. Holding the handler mutex for the whole sequence keeps a multi-register operation coherent across host control (~500 Hz) and diagnostic threads; HalSpiTle92466edComm::TransferMulti additionally keeps the SPI2 bus lock across the frames of a single pipelined access.

Template Parameters
FnCallable taking DriverType&.
Returns
fn's result, or a NotInitialized error / value-initialized result when the driver is unavailable. When fn returns void, this returns bool (true when fn actually ran).

◆ withDriver()

template<typename Fn >
auto Tle92466edHandler::withDriver ( Fn &&  fn)
inlineprivatenoexcept

Execute a lambda with a locked, initialized driver.

Acquires the mutex, ensures initialization, and invokes fn(*driver_). Returns a default-constructed R on failure, or for DriverResult types, returns an error indicating the driver is not initialized.

◆ WithLock()

template<typename Fn >
auto Tle92466edHandler::WithLock ( Fn &&  fn)
inlinenoexcept

Run fn (no arguments) while mutex_ is held.

WithDriver keeps a single driver call coherent, but a snapshot built from several handler calls (probe: PIN_STAT + FB_STAT + FB_FRZ + CH_CTRL + …) can still interleave with other host SPI users between those calls, so the fields describe different instants. mutex_ is recursive, so fn may freely call WithDriver and any other handler method; the outer hold makes the whole composition atomic with respect to every other TLE user.

Warning
Everything in fn runs with the TLE pipeline blocked for other threads — keep sleeps inside to a few milliseconds.

Member Data Documentation

◆ comm_

std::unique_ptr<HalSpiTle92466edComm> Tle92466edHandler::comm_
private

◆ driver_

std::unique_ptr<DriverType> Tle92466edHandler::driver_
private

◆ initialized_

bool Tle92466edHandler::initialized_ {false}
private

◆ kNumChannels

constexpr uint8_t Tle92466edHandler::kNumChannels = 6
staticconstexpr

Number of solenoid channels (0–5); only CH5 is populated on this board.

◆ mutex_

RtosMutex Tle92466edHandler::mutex_
mutableprivate

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