HF Interface Wrapper 0.1.0-dev
Embedded C++ hardware abstraction layer
Loading...
Searching...
No Matches
EspPio.h
Go to the documentation of this file.
1
29#pragma once
30
31#include "BasePio.h"
32#include "EspTypes.h"
33#include "PlatformMutex.h"
34#include <array>
35// Include ESP-IDF RMT driver headers for direct type usage
36// ESP-IDF C headers must be wrapped in extern "C" for C++ compatibility
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41#include "driver/rmt_encoder.h"
42#include "driver/rmt_rx.h"
43#include "driver/rmt_tx.h"
44
45#ifdef __cplusplus
46}
47#endif
48
49//==============================================================================
50// TYPE ALIASES FOR PLATFORM COMPATIBILITY (from McuTypes.h)
51//==============================================================================
52
53// Forward declarations for PIO types
66
111class EspPio : public BasePio {
112public:
116 EspPio() noexcept;
117
121 ~EspPio() noexcept override;
122
123 // Disable copy constructor and assignment operator
124 EspPio(const EspPio&) = delete;
125 EspPio& operator=(const EspPio&) = delete;
126
127 // Allow move operations
128 EspPio(EspPio&&) noexcept = default;
129 EspPio& operator=(EspPio&&) noexcept = default;
130
131 //==============================================//
132 // BasePio Interface Implementation
133 //==============================================//
134 hf_pio_err_t Initialize() noexcept override;
135 hf_pio_err_t Deinitialize() noexcept override;
136
138 const hf_pio_channel_config_t& config) noexcept override;
139
140 hf_pio_err_t Transmit(hf_u8_t channel_id, const hf_pio_symbol_t* symbols, size_t symbol_count,
141 bool wait_completion = false) noexcept override;
142
143 hf_pio_err_t StartReceive(hf_u8_t channel_id, hf_pio_symbol_t* buffer, size_t buffer_size,
144 uint32_t timeout_us = 0) noexcept override;
145 hf_pio_err_t StopReceive(hf_u8_t channel_id, size_t& symbols_received) noexcept override;
146
147 bool IsChannelBusy(hf_u8_t channel_id) const noexcept override;
149 hf_pio_channel_status_t& status) const noexcept override;
150 hf_pio_err_t GetCapabilities(hf_pio_capabilities_t& capabilities) const noexcept override;
151
153 void* user_data = nullptr) noexcept override;
155 void* user_data = nullptr) noexcept override;
157 void* user_data = nullptr) noexcept override;
158 void ClearChannelCallbacks(hf_u8_t channel_id) noexcept override;
159 void ClearCallbacks() noexcept override;
160
168 hf_pio_statistics_t& statistics) const noexcept override;
169
177 hf_pio_diagnostics_t& diagnostics) const noexcept override;
178
179 //==============================================//
180 // Lazy Initialization Support
181 // Advanced Low-Level RMT Control Methods
182 //==============================================//
183
193 hf_pio_err_t TransmitRawRmtSymbols(hf_u8_t channel_id, const rmt_symbol_word_t* rmt_symbols,
194 size_t symbol_count, bool wait_completion = false) noexcept;
195
206 hf_pio_err_t ReceiveRawRmtSymbols(hf_u8_t channel_id, rmt_symbol_word_t* rmt_buffer,
207 size_t buffer_size, size_t& symbols_received,
208 uint32_t timeout_us = 10000) noexcept;
217 hf_pio_err_t ConfigureAdvancedRmt(hf_u8_t channel_id, size_t memory_blocks = 64,
218 bool enable_dma = false, uint32_t queue_depth = 4) noexcept;
219
220 //==============================================//
221 // ESP32-Specific Methods (continued)
222 //==============================================//
223
231 hf_pio_err_t ConfigureCarrier(hf_u8_t channel_id, uint32_t carrier_freq_hz,
232 float duty_cycle) noexcept;
233
240 hf_pio_err_t EnableLoopback(hf_u8_t channel_id, bool enable) noexcept;
241
246 size_t GetMaxSymbolCount() const noexcept;
247
252 bool ValidatePioSystem() noexcept;
253
261 hf_pio_err_t ConfigureEncoder(hf_u8_t channel_id, const hf_pio_symbol_t& bit0_config,
262 const hf_pio_symbol_t& bit1_config) noexcept;
263
270 hf_pio_err_t SetIdleLevel(hf_u8_t channel_id, bool idle_level) noexcept;
271
279 hf_pio_channel_statistics_t& stats) const noexcept;
280
287
297 hf_u32_t& achieved_resolution_ns) const noexcept;
298
308 hf_pio_err_t SetClockSource(hf_u8_t channel_id, rmt_clock_source_t clk_src) noexcept;
309
313 hf_pio_err_t GetClockSource(hf_u8_t channel_id, rmt_clock_source_t& clk_src) const noexcept;
314
318 hf_pio_err_t GetSourceClockHz(hf_u8_t channel_id, hf_u32_t& clock_hz) const noexcept;
319
320private:
321 //==============================================//
322 // Internal Structures
323 //==============================================//
324
327 bool busy;
330
331 // Use original ESP-IDF RMT types directly
332 rmt_channel_handle_t tx_channel;
333 rmt_channel_handle_t rx_channel;
334 rmt_encoder_handle_t encoder;
335 rmt_encoder_handle_t bytes_encoder; // For byte-level protocols
336
337 // Buffers
341 rmt_symbol_word_t* rmt_rx_buffer; // Allocated RMT buffer for reception
342
343 // Timing
345 hf_u32_t actual_resolution_ns; // Actual achieved resolution due to divider constraints
346 rmt_clock_source_t selected_clk_src; // Selected clock source for this channel
347 hf_u32_t source_clock_hz; // Source clock frequency in Hz for calculations
348
349 // Idle level configuration
351
352 // Callbacks
359
360 ChannelState() noexcept
361 : configured(false), busy(false), config(), status(), tx_channel(nullptr),
362 rx_channel(nullptr), encoder(nullptr), bytes_encoder(nullptr), rx_buffer(nullptr),
363 rx_buffer_size(0), rx_symbols_received(0), rmt_rx_buffer(nullptr), last_operation_time(0),
364 actual_resolution_ns(0), selected_clk_src(RMT_CLK_SRC_DEFAULT), source_clock_hz(80000000),
365 idle_level(false), transmit_callback(nullptr), transmit_user_data(nullptr),
366 receive_callback(nullptr), receive_user_data(nullptr), error_callback(nullptr),
367 error_user_data(nullptr) {}
368 };
369
370 //==============================================//
371 // Member Variables
372 //==============================================//
373
374 static constexpr hf_u8_t MAX_CHANNELS = HF_RMT_MAX_CHANNELS; // Use centralized constant
375 static constexpr size_t MAX_SYMBOLS_PER_TRANSMISSION = 256;
376 static constexpr uint32_t DEFAULT_RESOLUTION_NS = 1000; // 1 microsecond
377// ESP32-C6 specific clock frequency configuration
378#if defined(CONFIG_IDF_TARGET_ESP32C6)
379 static constexpr uint32_t RMT_CLK_SRC_FREQ = 80000000; // ESP32-C6 APB clock (80 MHz)
380#else
381 static constexpr uint32_t RMT_CLK_SRC_FREQ = 80000000; // 80 MHz APB clock
382#endif
383
384 std::array<ChannelState, MAX_CHANNELS> channels_;
386
387 // Global statistics and diagnostics
390
391 //==============================================//
392 // Internal Helper Methods
393 //==============================================//
394
398 bool IsValidChannelId(hf_u8_t channel_id) const noexcept;
402 hf_pio_err_t ConvertToRmtSymbols(const hf_pio_symbol_t* symbols, size_t symbol_count,
403 rmt_symbol_word_t* rmt_symbols,
404 size_t& rmt_symbol_count) noexcept;
405
414 hf_pio_err_t ConvertFromRmtSymbols(const rmt_symbol_word_t* rmt_symbols, size_t rmt_symbol_count,
415 hf_pio_symbol_t* symbols, size_t max_symbols,
416 size_t& symbols_converted) noexcept;
417
418#ifdef HF_MCU_FAMILY_ESP32
419 // Update callback signatures to match ESP-IDF v5.5 API
420 static bool OnTransmitComplete(rmt_channel_handle_t channel,
421 const rmt_tx_done_event_data_t* edata, void* user_ctx);
422 static bool OnReceiveComplete(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t* edata,
423 void* user_ctx);
424#endif
425
430
435
439 hf_pio_err_t ValidateSymbols(const hf_pio_symbol_t* symbols, size_t symbol_count) const noexcept;
440
450 hf_u32_t CalculateResolutionHz(hf_u32_t resolution_ns, hf_u32_t& actual_resolution_ns,
451 hf_u32_t source_clock_hz) const noexcept;
452
462 uint32_t CalculateClockDivider(uint32_t resolution_ns, uint32_t& actual_resolution_ns,
463 uint32_t source_clock_hz) const noexcept;
464
471 uint32_t GetEffectiveClockFrequency(uint32_t clock_divider,
472 uint32_t source_clock_hz) const noexcept;
473
481 hf_pio_err_t GetResolutionConstraints(hf_u32_t& min_resolution_ns, hf_u32_t& max_resolution_ns,
482 hf_u32_t& clock_freq_hz) const noexcept;
483
488 hf_u32_t& max_resolution_ns,
489 hf_u32_t& clock_freq_hz) const noexcept;
490
494 static inline hf_u32_t GetClockSourceFrequency(rmt_clock_source_t clk_src) noexcept;
495 static inline hf_u32_t ResolveClockSourceHz(rmt_clock_source_t clk_src) noexcept;
496
504 const hf_pio_channel_config_t& config) const noexcept;
505
511 void InvokeChannelErrorCallback(hf_u8_t channel_id, hf_pio_err_t error) noexcept;
512
513 static constexpr const char* TAG = "EspPio";
514};
Abstract base class for Programmable IO Channel implementations in the HardFOC system.
@ Transmit
Transmit mode (output)
void(*)( hf_u8_t channel_id, const hf_pio_symbol_t *symbols, size_t symbol_count, void *user_data) hf_pio_receive_callback_t
Callback for PIO reception complete events.
Definition BasePio.h:256
hf_pio_err_t
Definition BasePio.h:83
void(*)(hf_u8_t channel_id, hf_pio_err_t error, void *user_data) hf_pio_error_callback_t
Callback for PIO error events.
Definition BasePio.h:264
void(*)(hf_u8_t channel_id, size_t symbols_sent, void *user_data) hf_pio_transmit_callback_t
Callback for PIO transmission complete events.
Definition BasePio.h:246
Consolidated MCU-specific type definitions for hardware abstraction (hf_* types).
static constexpr uint8_t HF_RMT_MAX_CHANNELS
Definition EspTypes_PIO.h:70
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
uint64_t hf_u64_t
Platform-agnostic 64-bit unsigned integer type.
Definition HardwareTypes.h:58
Cross-platform RTOS mutex and synchronization primitives.
Abstract base class for Programmable IO Channel implementations.
Definition BasePio.h:292
ESP32C6 RMT-based Programmable IO Channel implementation with advanced ESP-IDF v5....
Definition EspPio.h:111
hf_pio_err_t GetClockSource(hf_u8_t channel_id, rmt_clock_source_t &clk_src) const noexcept
Get the currently selected RMT clock source for a channel.
EspPio() noexcept
Constructor.
static constexpr size_t MAX_SYMBOLS_PER_TRANSMISSION
Definition EspPio.h:375
void ClearChannelCallbacks(hf_u8_t channel_id) noexcept override
Clear all callbacks for a specific channel.
static hf_u32_t GetClockSourceFrequency(rmt_clock_source_t clk_src) noexcept
Map an RMT clock source to its nominal frequency in Hz.
hf_pio_err_t StartReceive(hf_u8_t channel_id, hf_pio_symbol_t *buffer, size_t buffer_size, uint32_t timeout_us=0) noexcept override
Start receiving symbols.
std::array< ChannelState, MAX_CHANNELS > channels_
Definition EspPio.h:384
PlatformMutex state_mutex_
Definition EspPio.h:385
hf_pio_err_t InitializeChannel(hf_u8_t channel_id) noexcept
Initialize a specific channel.
hf_pio_err_t ResetChannelStatistics(hf_u8_t channel_id) noexcept
Reset channel statistics counters.
hf_pio_err_t EnableLoopback(hf_u8_t channel_id, bool enable) noexcept
Enable/disable loopback mode for testing.
uint32_t GetEffectiveClockFrequency(uint32_t clock_divider, uint32_t source_clock_hz) const noexcept
Get effective RMT clock frequency for a given divider.
hf_pio_err_t ConvertToRmtSymbols(const hf_pio_symbol_t *symbols, size_t symbol_count, rmt_symbol_word_t *rmt_symbols, size_t &rmt_symbol_count) noexcept
Convert hf_pio_symbol_t array to RMT symbol format.
hf_u32_t CalculateResolutionHz(hf_u32_t resolution_ns, hf_u32_t &actual_resolution_ns, hf_u32_t source_clock_hz) const noexcept
Calculate the best possible resolution_hz from requested resolution_ns.
hf_pio_err_t GetDiagnostics(hf_u8_t channel_id, hf_pio_diagnostics_t &diagnostics) const noexcept override
Get PIO diagnostic information.
hf_pio_err_t Initialize() noexcept override
Initialize the PIO peripheral.
static constexpr uint32_t RMT_CLK_SRC_FREQ
Definition EspPio.h:381
static hf_u32_t ResolveClockSourceHz(rmt_clock_source_t clk_src) noexcept
void SetErrorCallback(hf_u8_t channel_id, hf_pio_error_callback_t callback, void *user_data=nullptr) noexcept override
Set callback for error events.
hf_pio_err_t SetClockSource(hf_u8_t channel_id, rmt_clock_source_t clk_src) noexcept
Allow caller to choose the RMT clock source per channel.
bool IsValidChannelId(hf_u8_t channel_id) const noexcept
Validate channel ID.
static constexpr const char * TAG
Logging tag.
Definition EspPio.h:513
void ClearCallbacks() noexcept override
Clear all callbacks.
void InvokeChannelErrorCallback(hf_u8_t channel_id, hf_pio_err_t error) noexcept
Invoke channel-specific error callback.
hf_pio_err_t ValidateSymbols(const hf_pio_symbol_t *symbols, size_t symbol_count) const noexcept
Validate symbol array.
bool ValidatePioSystem() noexcept
Comprehensive PIO system validation and performance test.
hf_pio_err_t ReceiveRawRmtSymbols(hf_u8_t channel_id, rmt_symbol_word_t *rmt_buffer, size_t buffer_size, size_t &symbols_received, uint32_t timeout_us=10000) noexcept
Receive raw RMT symbols directly (bypassing hf_pio_symbol_t conversion)
void SetReceiveCallback(hf_u8_t channel_id, hf_pio_receive_callback_t callback, void *user_data=nullptr) noexcept override
Set callback for reception complete events.
hf_pio_statistics_t global_statistics_
Definition EspPio.h:388
hf_pio_err_t ConfigureAdvancedRmt(hf_u8_t channel_id, size_t memory_blocks=64, bool enable_dma=false, uint32_t queue_depth=4) noexcept
Configure advanced RMT channel settings.
bool IsChannelBusy(hf_u8_t channel_id) const noexcept override
Check if a channel is currently busy.
static constexpr uint32_t DEFAULT_RESOLUTION_NS
Definition EspPio.h:376
hf_pio_err_t ConvertFromRmtSymbols(const rmt_symbol_word_t *rmt_symbols, size_t rmt_symbol_count, hf_pio_symbol_t *symbols, size_t max_symbols, size_t &symbols_converted) noexcept
Convert RMT symbols back to hf_pio_symbol_t format.
size_t GetMaxSymbolCount() const noexcept
Get the maximum number of symbols that can be transmitted in one operation.
hf_pio_err_t GetStatistics(hf_u8_t channel_id, hf_pio_statistics_t &statistics) const noexcept override
Get PIO operation statistics.
hf_pio_err_t ConfigureChannel(hf_u8_t channel_id, const hf_pio_channel_config_t &config) noexcept override
Configure a PIO channel.
hf_pio_err_t ConfigureCarrier(hf_u8_t channel_id, uint32_t carrier_freq_hz, float duty_cycle) noexcept
Configure carrier modulation for IR protocols.
void SetTransmitCallback(hf_u8_t channel_id, hf_pio_transmit_callback_t callback, void *user_data=nullptr) noexcept override
Set callback for transmission complete events.
static constexpr hf_u8_t MAX_CHANNELS
Definition EspPio.h:374
hf_pio_err_t GetChannelStatus(hf_u8_t channel_id, hf_pio_channel_status_t &status) const noexcept override
Get channel status information.
hf_pio_err_t GetResolutionConstraints(hf_u8_t channel_id, hf_u32_t &min_resolution_ns, hf_u32_t &max_resolution_ns, hf_u32_t &clock_freq_hz) const noexcept
Get resolution constraints for a specific channel's selected clock source.
hf_pio_err_t GetResolutionConstraints(hf_u32_t &min_resolution_ns, hf_u32_t &max_resolution_ns, hf_u32_t &clock_freq_hz) const noexcept
Get information about resolution constraints for current ESP32 variant.
hf_pio_err_t GetActualResolution(hf_u8_t channel_id, hf_u32_t &achieved_resolution_ns) const noexcept
Get the actual achieved resolution for a channel in nanoseconds.
hf_pio_err_t GetChannelStatistics(hf_u8_t channel_id, hf_pio_channel_statistics_t &stats) const noexcept
Get current RMT channel statistics.
hf_pio_err_t ConfigureEncoder(hf_u8_t channel_id, const hf_pio_symbol_t &bit0_config, const hf_pio_symbol_t &bit1_config) noexcept
Configure RMT encoder for specific protocol.
uint32_t CalculateClockDivider(uint32_t resolution_ns, uint32_t &actual_resolution_ns, uint32_t source_clock_hz) const noexcept
Calculate RMT clock divider for desired resolution.
hf_pio_err_t GetSourceClockHz(hf_u8_t channel_id, hf_u32_t &clock_hz) const noexcept
Get the current source clock frequency for a channel (Hz)
hf_pio_err_t TransmitRawRmtSymbols(hf_u8_t channel_id, const rmt_symbol_word_t *rmt_symbols, size_t symbol_count, bool wait_completion=false) noexcept
Transmit raw RMT symbols directly (bypassing hf_pio_symbol_t conversion)
hf_pio_err_t ValidateChannelConfiguration(hf_u8_t channel_id, const hf_pio_channel_config_t &config) const noexcept
Validate channel configuration for current ESP32 variant.
hf_pio_err_t Deinitialize() noexcept override
Deinitialize the PIO peripheral.
hf_pio_err_t DeinitializeChannel(hf_u8_t channel_id) noexcept
Deinitialize a specific channel.
hf_pio_err_t GetCapabilities(hf_pio_capabilities_t &capabilities) const noexcept override
Get PIO capabilities.
hf_pio_err_t SetIdleLevel(hf_u8_t channel_id, bool idle_level) noexcept
Set RMT channel idle output level.
hf_pio_err_t StopReceive(hf_u8_t channel_id, size_t &symbols_received) noexcept override
Stop receiving and get the number of symbols received.
hf_pio_diagnostics_t global_diagnostics_
Definition EspPio.h:389
Definition PlatformMutex.h:78
Definition EspPio.h:325
ChannelState() noexcept
Definition EspPio.h:360
uint64_t last_operation_time
Definition EspPio.h:344
rmt_encoder_handle_t encoder
Definition EspPio.h:334
size_t rx_symbols_received
Definition EspPio.h:340
void * receive_user_data
Definition EspPio.h:356
hf_u32_t actual_resolution_ns
Definition EspPio.h:345
rmt_encoder_handle_t bytes_encoder
Definition EspPio.h:335
hf_pio_symbol_t * rx_buffer
Definition EspPio.h:338
void * error_user_data
Definition EspPio.h:358
bool configured
Definition EspPio.h:326
void * transmit_user_data
Definition EspPio.h:354
rmt_channel_handle_t rx_channel
Definition EspPio.h:333
rmt_symbol_word_t * rmt_rx_buffer
Definition EspPio.h:341
rmt_clock_source_t selected_clk_src
Definition EspPio.h:346
hf_pio_channel_status_t status
Definition EspPio.h:329
hf_u32_t source_clock_hz
Definition EspPio.h:347
hf_pio_error_callback_t error_callback
Definition EspPio.h:357
size_t rx_buffer_size
Definition EspPio.h:339
hf_pio_channel_config_t config
Definition EspPio.h:328
rmt_channel_handle_t tx_channel
Definition EspPio.h:332
bool busy
Definition EspPio.h:327
bool idle_level
Definition EspPio.h:350
hf_pio_transmit_callback_t transmit_callback
Definition EspPio.h:353
hf_pio_receive_callback_t receive_callback
Definition EspPio.h:355
PIO capability information.
Definition BasePio.h:181
PIO channel configuration structure.
Definition BasePio.h:138
Definition EspPio.h:54
hf_u64_t failed_receptions
Definition EspPio.h:58
hf_u64_t last_operation_time
Definition EspPio.h:59
bool is_busy
Definition EspPio.h:61
bool dma_enabled
Definition EspPio.h:64
hf_u32_t current_resolution_ns
Definition EspPio.h:62
size_t memory_blocks_allocated
Definition EspPio.h:63
hf_u64_t failed_transmissions
Definition EspPio.h:57
hf_u64_t total_transmissions
Definition EspPio.h:55
hf_u64_t total_receptions
Definition EspPio.h:56
bool is_configured
Definition EspPio.h:60
PIO channel status information.
Definition BasePio.h:167
PIO diagnostic information.
Definition BasePio.h:220
PIO operation statistics.
Definition BasePio.h:195
PIO symbol structure for precise timing.
Definition BasePio.h:156