Internal Interface Wrap
API reference
Loading...
Searching...
No Matches
StmSpi.h
Go to the documentation of this file.
1
34#pragma once
35
36#include "BaseSpi.h"
37#include "StmTypes.h"
38#include "PlatformMutex.h"
39#include "SoftChipSelectGuard.h"
40#include <vector>
41#include <memory>
42
43class StmSpiBus;
44
52class StmSpiBusLock final {
53public:
54 StmSpiBusLock(StmSpiBus& bus, hf_u32_t timeout_ms) noexcept;
55 ~StmSpiBusLock() noexcept;
56
57 StmSpiBusLock(const StmSpiBusLock&) = delete;
59 StmSpiBusLock(StmSpiBusLock&& other) noexcept;
60 StmSpiBusLock& operator=(StmSpiBusLock&& other) noexcept;
61
62 [[nodiscard]] bool OwnsLock() const noexcept { return locked_; }
63
64private:
65 StmSpiBus* bus_{nullptr};
66 bool locked_{false};
67};
68
87class StmSpiDevice : public BaseSpi {
88public:
89 StmSpiDevice(StmSpiBus* parent, const hf_spi_device_config_t& config) noexcept;
90 ~StmSpiDevice() noexcept override;
91
92 bool Initialize() noexcept override;
93 bool Deinitialize() noexcept override;
94
102 hf_spi_err_t Transfer(const hf_u8_t* tx_data, hf_u8_t* rx_data,
103 hf_u16_t length, hf_u32_t timeout_ms = 0) noexcept override;
104
112 hf_spi_err_t TransferChain(const hf_u8_t* const* tx_frames, hf_u8_t* const* rx_frames,
113 hf_u16_t frame_length, hf_u16_t frame_count,
114 hf_u32_t inter_frame_gap_us,
115 hf_u32_t timeout_ms = 0) noexcept override;
116
117 const void* GetDeviceConfig() const noexcept override;
118
120 void IdleChipSelect() noexcept override;
121
123 void HoldChipSelectMs(hf_u32_t ms) noexcept override;
124
126 bool SetTransferMode(hf_u8_t mode_0_to_3) noexcept override;
127
129 bool SetIoSwap(bool enable) noexcept override;
130
132 const hf_spi_device_config_t& GetConfig() const noexcept { return config_; }
133
134private:
135 friend class StmSpiBus;
136
138 void AssertCS() noexcept;
139
141 void DeassertCS() noexcept;
142
153 hf_spi_err_t TransferLocked(const hf_u8_t* tx_data, hf_u8_t* rx_data,
154 hf_u16_t length, hf_u32_t effective_timeout,
155 bool park_mode3_after = true,
156 bool bus_already_armed = false) noexcept;
157
159 hf_u32_t GetEffectiveTimeout(hf_u32_t requested_ms) const noexcept;
160
162 static hf_spi_err_t ConvertHalStatus(hf_u32_t hal_status) noexcept;
163
166 bool io_swap_{false};
167};
168
188public:
189 explicit StmSpiBus(const hf_spi_bus_config_t& config) noexcept;
190
192 explicit StmSpiBus(SPI_HandleTypeDef* hal_handle, hf_u32_t timeout_ms = 1000) noexcept;
193
194 ~StmSpiBus() noexcept;
195
196 bool Initialize() noexcept;
197 bool IsInitialized() const noexcept;
198 bool Deinitialize() noexcept;
199
204 int CreateDevice(const hf_spi_device_config_t& device_config) noexcept;
205 BaseSpi* GetDevice(int device_index) noexcept;
206 const BaseSpi* GetDevice(int device_index) const noexcept;
207 std::size_t GetDeviceCount() const noexcept;
208 bool RemoveDevice(int device_index) noexcept;
209 const hf_spi_bus_config_t& GetConfig() const noexcept;
210
212 SPI_HandleTypeDef* GetHalHandle() const noexcept;
213
232 bool ApplyDeviceMode(hf_stm32_spi_mode_t mode, bool io_swap = false,
233 hf_u8_t midi_cycles = 15,
234 hf_u32_t clock_speed_hz = 0,
235 bool* reconfigured = nullptr) noexcept;
236
243 [[nodiscard]] hf_u32_t GetKernelClockHz() const noexcept;
244
249 [[nodiscard]] hf_u32_t GetEffectiveClockHz() const noexcept;
250
258 [[nodiscard]] static hf_u8_t ResolveBaudMbr(hf_u32_t kernel_hz,
259 hf_u32_t requested_hz) noexcept;
260
265 void IdleAllChipSelects() noexcept;
266
289 hf_u8_t ProbeMisoLine(void* miso_port, hf_u8_t miso_pin_pos,
290 const BaseSpi* device) noexcept;
291
296 static constexpr hf_u16_t kScratchBytes = 32;
297 uint8_t* ScratchTx() noexcept { return scratch_tx_; }
298 uint8_t* ScratchRx() noexcept { return scratch_rx_; }
299
305 bool LockBus(hf_u32_t timeout_ms) noexcept;
306 void UnlockBus() noexcept;
307
308private:
309 friend class StmSpiDevice;
310 friend class StmSpiBusLock;
311
313 bool initialized_{false};
314 bool mode_applied_{false};
316 bool last_io_swap_{false};
322 std::vector<std::unique_ptr<StmSpiDevice>> devices_;
323 alignas(4) uint8_t scratch_tx_[kScratchBytes]{};
324 alignas(4) uint8_t scratch_rx_[kScratchBytes]{};
325};
Abstract base class for SPI device implementations in the HardFOC system.
hf_spi_err_t
Definition BaseSpi.h:84
uint32_t hf_u32_t
Platform-agnostic 32-bit unsigned integer type.
Definition HardwareTypes.h:52
uint8_t hf_u8_t
Platform-agnostic 8-bit unsigned integer type.
Definition HardwareTypes.h:40
uint16_t hf_u16_t
Platform-agnostic 16-bit unsigned integer type.
Definition HardwareTypes.h:46
Cross-platform mutex and synchronization primitives with pluggable backend.
RAII soft chip-select (assert on construct, deassert on destroy).
STM32 platform-specific type definitions for hardware abstraction.
hf_stm32_spi_mode_t
SPI mode (CPOL/CPHA)
Definition StmTypes.h:335
@ MODE_0
CPOL=0, CPHA=0.
Abstract base class for SPI device implementations.
Definition BaseSpi.h:184
One MCU SPI peripheral + its soft-CS device collection.
Definition StmSpi.h:187
bool LockBus(hf_u32_t timeout_ms) noexcept
Exclusive bus lock for mode + FIFO + CS + HAL transfer.
Definition StmSpi.cpp:595
PlatformMutex bus_mutex_
Definition StmSpi.h:321
~StmSpiBus() noexcept
Definition StmSpi.cpp:530
bool IsInitialized() const noexcept
Definition StmSpi.cpp:552
const hf_spi_bus_config_t & GetConfig() const noexcept
Definition StmSpi.cpp:591
bool ApplyDeviceMode(hf_stm32_spi_mode_t mode, bool io_swap=false, hf_u8_t midi_cycles=15, hf_u32_t clock_speed_hz=0, bool *reconfigured=nullptr) noexcept
Apply mode (CPOL/CPHA), midi_cycles (CFG2.MIDI) and clock_speed_hz (CFG1.MBR) if they differ from the...
Definition StmSpi.cpp:746
void UnlockBus() noexcept
Definition StmSpi.cpp:599
uint8_t * ScratchRx() noexcept
Definition StmSpi.h:298
static hf_u8_t ResolveBaudMbr(hf_u32_t kernel_hz, hf_u32_t requested_hz) noexcept
Smallest CFG1.MBR whose SCK does not exceed requested_hz.
Definition StmSpi.cpp:693
uint8_t * ScratchTx() noexcept
Definition StmSpi.h:297
std::vector< std::unique_ptr< StmSpiDevice > > devices_
Definition StmSpi.h:322
bool last_io_swap_
Definition StmSpi.h:316
bool initialized_
Definition StmSpi.h:313
uint8_t scratch_rx_[kScratchBytes]
Definition StmSpi.h:324
int CreateDevice(const hf_spi_device_config_t &device_config) noexcept
Register a soft-CS device on this bus.
Definition StmSpi.cpp:563
std::size_t GetDeviceCount() const noexcept
Definition StmSpi.cpp:581
bool Initialize() noexcept
Definition StmSpi.cpp:534
hf_u8_t last_midi_cycles_
Definition StmSpi.h:317
uint8_t scratch_tx_[kScratchBytes]
Definition StmSpi.h:323
hf_u8_t last_baud_mbr_
Definition StmSpi.h:320
static constexpr hf_u16_t kScratchBytes
Definition StmSpi.h:296
hf_u8_t ProbeMisoLine(void *miso_port, hf_u8_t miso_pin_pos, const BaseSpi *device) noexcept
Bring-up probe of the shared MISO/SDO net — no scope required.
Definition StmSpi.cpp:626
hf_u32_t GetEffectiveClockHz() const noexcept
Effective SCK in Hz for the prescaler currently programmed.
Definition StmSpi.cpp:730
BaseSpi * GetDevice(int device_index) noexcept
Definition StmSpi.cpp:569
void IdleAllChipSelects() noexcept
Drive every registered soft-CS to idle (active-low → HIGH).
Definition StmSpi.cpp:603
bool mode_applied_
Definition StmSpi.h:314
bool Deinitialize() noexcept
Definition StmSpi.cpp:554
bool RemoveDevice(int device_index) noexcept
Definition StmSpi.cpp:583
hf_spi_bus_config_t config_
Definition StmSpi.h:312
SPI_HandleTypeDef * GetHalHandle() const noexcept
Underlying CubeMX SPI handle (platform wiring only).
Definition StmSpi.cpp:593
hf_stm32_spi_mode_t last_mode_
Definition StmSpi.h:315
hf_u32_t GetKernelClockHz() const noexcept
Kernel clock feeding this SPI peripheral, in Hz (0 if unknown).
Definition StmSpi.cpp:708
RAII exclusive ownership of one StmSpiBus (RTOS mutex).
Definition StmSpi.h:52
bool OwnsLock() const noexcept
Definition StmSpi.h:62
StmSpiBus * bus_
Definition StmSpi.h:65
StmSpiBusLock(const StmSpiBusLock &)=delete
~StmSpiBusLock() noexcept
Definition StmSpi.cpp:162
StmSpiBusLock & operator=(const StmSpiBusLock &)=delete
bool locked_
Definition StmSpi.h:66
Soft-CS SPI slave on a shared StmSpiBus.
Definition StmSpi.h:87
hf_spi_err_t TransferChain(const hf_u8_t *const *tx_frames, hf_u8_t *const *rx_frames, hf_u16_t frame_length, hf_u16_t frame_count, hf_u32_t inter_frame_gap_us, hf_u32_t timeout_ms=0) noexcept override
N soft-CS frames under one bus lock (CS still toggles per frame).
Definition StmSpi.cpp:437
hf_u32_t GetEffectiveTimeout(hf_u32_t requested_ms) const noexcept
Resolve requested_ms against the parent bus default.
Definition StmSpi.cpp:504
void DeassertCS() noexcept
Drive CS to the idle level (active-low → GPIO high).
Definition StmSpi.cpp:494
bool io_swap_
CFG2 IOSWP for next transfer.
Definition StmSpi.h:166
const hf_spi_device_config_t & GetConfig() const noexcept
Device configuration (CS port/pin, mode, clock hint).
Definition StmSpi.h:132
void HoldChipSelectMs(hf_u32_t ms) noexcept override
Bus-locked soft-CS hold for pad proof (peers idle-high).
Definition StmSpi.cpp:260
const void * GetDeviceConfig() const noexcept override
Get the device configuration for this SPI device.
Definition StmSpi.cpp:479
bool Deinitialize() noexcept override
Deinitialize the SPI bus.
Definition StmSpi.cpp:245
void AssertCS() noexcept
Drive CS to the active level (active-low → GPIO low).
Definition StmSpi.cpp:483
bool Initialize() noexcept override
Initialize the SPI bus.
Definition StmSpi.cpp:215
StmSpiBus * parent_bus_
Parent bus reference.
Definition StmSpi.h:164
hf_spi_err_t Transfer(const hf_u8_t *tx_data, hf_u8_t *rx_data, hf_u16_t length, hf_u32_t timeout_ms=0) noexcept override
One soft-CS frame: bus lock + mode + FIFO flush + CS RAII + HAL.
Definition StmSpi.cpp:422
bool SetIoSwap(bool enable) noexcept override
Set MOSI↔MISO IOSwap for the next transfer (CFG2 IOSWP).
Definition StmSpi.cpp:290
void IdleChipSelect() noexcept override
Force soft-CS idle-high (shared-bus peer park before Mode1 identity).
Definition StmSpi.cpp:253
bool SetTransferMode(hf_u8_t mode_0_to_3) noexcept override
Set CPOL/CPHA for the next transfer (0=Mode0 … 3=Mode3).
Definition StmSpi.cpp:282
static hf_spi_err_t ConvertHalStatus(hf_u32_t hal_status) noexcept
Map STM32 HAL status codes to hf_spi_err_t.
Definition StmSpi.cpp:510
hf_spi_err_t TransferLocked(const hf_u8_t *tx_data, hf_u8_t *rx_data, hf_u16_t length, hf_u32_t effective_timeout, bool park_mode3_after=true, bool bus_already_armed=false) noexcept
One CS-framed HAL transfer; caller must hold StmSpiBusLock.
Definition StmSpi.cpp:295
~StmSpiDevice() noexcept override
Definition StmSpi.cpp:211
hf_spi_device_config_t config_
Device configuration.
Definition StmSpi.h:165
Platform-agnostic SPI bus configuration for STM32.
Definition EspTypes_SPI.h:150
SPI device configuration for STM32.
Definition EspTypes_SPI.h:210