libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::ESP32SPI Class Reference
Inheritance diagram for LibXR::ESP32SPI:
[legend]
Collaboration diagram for LibXR::ESP32SPI:
[legend]

Public Member Functions

 ESP32SPI (spi_host_device_t host, int sclk_pin, int miso_pin, int mosi_pin, RawData dma_rx, RawData dma_tx, SPI::Configuration config={ SPI::ClockPolarity::LOW, SPI::ClockPhase::EDGE_1, SPI::Prescaler::DIV_8, false, }, uint32_t dma_enable_min_size=3U, bool enable_dma=true)
 
ErrorCode ReadAndWrite (RawData read_data, ConstRawData write_data, OperationRW &op, bool in_isr=false) override
 进行 SPI 读写操作 / Performs SPI read and write operations.
 
ErrorCode SetConfig (SPI::Configuration config) override
 设置 SPI 配置参数 / Sets SPI configuration parameters.
 
ErrorCode MemRead (uint16_t reg, RawData read_data, OperationRW &op, bool in_isr=false) override
 从 SPI 设备的寄存器读取数据。 Reads data from a specific register of the SPI device.
 
ErrorCode MemWrite (uint16_t reg, ConstRawData write_data, OperationRW &op, bool in_isr=false) override
 向 SPI 设备的寄存器写入数据。 Writes data to a specific register of the SPI device.
 
ErrorCode Transfer (size_t size, OperationRW &op, bool in_isr=false) override
 进行一次SPI传输(使用当前缓冲区数据,零拷贝,支持双缓冲)。 Performs a SPI transfer (zero-copy, supports double buffering).
 
uint32_t GetMaxBusSpeed () const override
 获取 SPI 设备的最大时钟速度 / Gets the maximum clock speed of the SPI device.
 
Prescaler GetMaxPrescaler () const override
 获取 SPI 设备的最大分频系数 / Gets the maximum prescaler of the SPI device.
 
RawData GetRxBuffer ()
 
RawData GetTxBuffer ()
 
- Public Member Functions inherited from LibXR::SPI
 SPI (RawData rx_buffer, RawData tx_buffer)
 构造函数 / Constructor.
 
virtual ErrorCode Read (RawData read_data, OperationRW &op, bool in_isr=false)
 进行 SPI 读取操作 / Performs SPI read operation.
 
virtual ErrorCode Write (ConstRawData write_data, OperationRW &op, bool in_isr=false)
 进行 SPI 写入操作 / Performs SPI write operation.
 
uint32_t GetBusSpeed () const
 获取 SPI 设备的当前总线速度 / Gets the current bus speed of the SPI device.
 
Prescaler CalcPrescaler (uint32_t target_max_bus_speed, uint32_t target_min_bus_speed, bool increase)
 计算 SPI 分频系数 / Calculates the SPI prescaler.
 
RawData GetRxBuffer ()
 获取接收数据的缓冲区 / Gets the buffer for storing received data.
 
RawData GetTxBuffer ()
 获取发送数据的缓冲区 / Gets the buffer for storing data to be sent.
 
void SwitchBuffer ()
 切换缓冲区 / Switches the buffer.
 
void SetActiveLength (size_t len)
 设置缓冲区的有效数据长度 / Sets the length of valid data in the buffer.
 
size_t GetActiveLength () const
 获取缓冲区的有效数据长度 / Gets the length of valid data in the buffer.
 
Configuration & GetConfig ()
 获取 SPI 配置参数 / Gets the SPI configuration parameters.
 
bool IsDoubleBuffer () const
 检查是否使用双缓冲区 / Checks if double buffering is enabled.
 

Additional Inherited Members

- Public Types inherited from LibXR::SPI
enum class  ClockPolarity : uint8_t { LOW = 0 , HIGH = 1 }
 定义 SPI 时钟极性 / Defines the SPI clock polarity. More...
 
enum class  ClockPhase : uint8_t { EDGE_1 = 0 , EDGE_2 = 1 }
 定义 SPI 时钟相位 / Defines the SPI clock phase. More...
 
enum class  Prescaler : uint8_t {
  DIV_1 = 0 , DIV_2 = 1 , DIV_4 = 2 , DIV_8 = 3 ,
  DIV_16 = 4 , DIV_32 = 5 , DIV_64 = 6 , DIV_128 = 7 ,
  DIV_256 = 8 , DIV_512 = 9 , DIV_1024 = 10 , DIV_2048 = 11 ,
  DIV_4096 = 12 , DIV_8192 = 13 , DIV_16384 = 14 , DIV_32768 = 15 ,
  DIV_65536 = 16 , UNKNOWN = 0xFF
}
 
using OperationRW = WriteOperation
 定义读写操作类型的别名 / Defines an alias for the read/write operation type.
 
- Static Public Member Functions inherited from LibXR::SPI
static constexpr uint32_t PrescalerToDiv (Prescaler prescaler)
 将分频系数转换为除数 / Converts a prescaler to a divisor.
 

Detailed Description

Definition at line 18 of file esp_spi.hpp.

Constructor & Destructor Documentation

◆ ESP32SPI()

LibXR::ESP32SPI::ESP32SPI ( spi_host_device_t host,
int sclk_pin,
int miso_pin,
int mosi_pin,
RawData dma_rx,
RawData dma_tx,
SPI::Configuration config = { SPI::ClockPolarity::LOW, SPI::ClockPhase::EDGE_1, SPI::Prescaler::DIV_8, false, },
uint32_t dma_enable_min_size = 3U,
bool enable_dma = true )

Definition at line 108 of file esp_spi.cpp.

111 : SPI(dma_rx, dma_tx),
112 host_(host),
113 sclk_pin_(sclk_pin),
114 miso_pin_(miso_pin),
115 mosi_pin_(mosi_pin),
116 dma_enable_min_size_(dma_enable_min_size),
117 dma_requested_(enable_dma),
118 dma_rx_raw_(dma_rx),
119 dma_tx_raw_(dma_tx),
120 dbuf_rx_block_size_(dma_rx.size_ / 2U),
121 dbuf_tx_block_size_(dma_tx.size_ / 2U)
122{
123 ASSERT(host_ != SPI1_HOST);
124 ASSERT(host_ < SPI_HOST_MAX);
125 ASSERT(static_cast<int>(host_) < SOC_SPI_PERIPH_NUM);
126 ASSERT(dma_rx_raw_.addr_ != nullptr);
127 ASSERT(dma_tx_raw_.addr_ != nullptr);
128 ASSERT(dma_rx_raw_.size_ > 0U);
129 ASSERT(dma_tx_raw_.size_ > 0U);
130
131 if (InitializeHardware() != ErrorCode::OK)
132 {
133 REQUIRE(false);
134 return;
135 }
136
137 if (ConfigurePins() != ErrorCode::OK)
138 {
139 REQUIRE(false);
140 return;
141 }
142
143 if (InstallInterrupt() != ErrorCode::OK)
144 {
145 REQUIRE(false);
146 return;
147 }
148
149 if (dma_requested_)
150 {
151 const ErrorCode dma_ans = InitDmaBackend();
152 REQUIRE(dma_ans == ErrorCode::OK);
153 if (dma_ans != ErrorCode::OK)
154 {
155 return;
156 }
157 }
158
159 if (SetConfig(config) != ErrorCode::OK)
160 {
161 REQUIRE(false);
162 return;
163 }
164}
ErrorCode SetConfig(SPI::Configuration config) override
设置 SPI 配置参数 / Sets SPI configuration parameters.
Definition esp_spi.cpp:451
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
SPI(RawData rx_buffer, RawData tx_buffer)
构造函数 / Constructor.
Definition spi.hpp:111
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful

Member Function Documentation

◆ GetMaxBusSpeed()

uint32_t LibXR::ESP32SPI::GetMaxBusSpeed ( ) const
overridevirtual

获取 SPI 设备的最大时钟速度 / Gets the maximum clock speed of the SPI device.

Returns
SPI 设备的最大时钟速度(单位:Hz)。 The maximum clock speed of the SPI device (in Hz).

Implements LibXR::SPI.

Definition at line 931 of file esp_spi.cpp.

931{ return source_clock_hz_; }

◆ GetMaxPrescaler()

SPI::Prescaler LibXR::ESP32SPI::GetMaxPrescaler ( ) const
overridevirtual

获取 SPI 设备的最大分频系数 / Gets the maximum prescaler of the SPI device.

Returns
SPI 设备的最大分频系数 / The maximum prescaler of the SPI device.

Implements LibXR::SPI.

Definition at line 933 of file esp_spi.cpp.

933{ return Prescaler::DIV_65536; }
@ DIV_65536
分频系数为 65536 / Division factor is 65536.

◆ GetRxBuffer()

RawData LibXR::ESP32SPI::GetRxBuffer ( )

Definition at line 507 of file esp_spi.cpp.

508{
509 if (UseLocalDoubleBuffer())
510 {
511 auto* base = static_cast<uint8_t*>(dma_rx_raw_.addr_);
512 return {base + static_cast<size_t>(dbuf_active_block_) * dbuf_rx_block_size_,
513 dbuf_rx_block_size_};
514 }
515 return dma_rx_raw_;
516}

◆ GetTxBuffer()

RawData LibXR::ESP32SPI::GetTxBuffer ( )

Definition at line 518 of file esp_spi.cpp.

519{
520 if (UseLocalDoubleBuffer())
521 {
522 auto* base = static_cast<uint8_t*>(dma_tx_raw_.addr_);
523 return {base + static_cast<size_t>(dbuf_active_block_) * dbuf_tx_block_size_,
524 dbuf_tx_block_size_};
525 }
526 return dma_tx_raw_;
527}

◆ MemRead()

ErrorCode LibXR::ESP32SPI::MemRead ( uint16_t reg,
RawData read_data,
OperationRW & op,
bool in_isr = false )
overridevirtual

从 SPI 设备的寄存器读取数据。 Reads data from a specific register of the SPI device.

Parameters
reg寄存器地址 / Register address.
read_data读取的数据缓冲区 / Buffer to store read data.
op操作类型(同步/异步) / Operation mode (sync/async).
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
操作结果的错误码 / Error code indicating success or failure.

Implements LibXR::SPI.

Definition at line 808 of file esp_spi.cpp.

809{
810 if (read_data.size_ == 0U)
811 {
812 return CompleteZeroSize(op, in_isr);
813 }
814
815 const ErrorCode lock_ec = EnsureReadyAndAcquire();
816 if (lock_ec != ErrorCode::OK)
817 {
818 return lock_ec;
819 }
820
821 RawData rx = GetRxBuffer();
822 RawData tx = GetTxBuffer();
823 const size_t total = read_data.size_ + 1U;
824
825 ASSERT(rx.size_ >= total);
826 ASSERT(tx.size_ >= total);
827
828 auto* tx_ptr = static_cast<uint8_t*>(tx.addr_);
829 tx_ptr[0] = static_cast<uint8_t>(reg | 0x80U);
830 Memory::FastSet(tx_ptr + 1, 0x00, read_data.size_);
831
832 if (CanUseDma(total))
833 {
834 bool started = false;
835 const ErrorCode ec = StartAsyncTransfer(tx_ptr, static_cast<uint8_t*>(rx.addr_),
836 total, true, read_data, true, op, started);
837 return ReturnAsyncStartResult(ec, started);
838 }
839
840 const ErrorCode ec =
841 ExecuteTransfer(tx_ptr, static_cast<uint8_t*>(rx.addr_), total, true);
842 if (ec == ErrorCode::OK)
843 {
844 auto* rx_ptr = static_cast<uint8_t*>(rx.addr_);
845 Memory::FastCopy(read_data.addr_, rx_ptr + 1, read_data.size_);
846 SwitchBufferLocal();
847 }
848
849 Release();
850 return FinalizeSyncResult(op, in_isr, ec);
851}
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy

◆ MemWrite()

ErrorCode LibXR::ESP32SPI::MemWrite ( uint16_t reg,
ConstRawData write_data,
OperationRW & op,
bool in_isr = false )
overridevirtual

向 SPI 设备的寄存器写入数据。 Writes data to a specific register of the SPI device.

Parameters
reg寄存器地址 / Register address.
write_data写入的数据缓冲区 / Buffer containing data to write.
op操作类型(同步/异步) / Operation mode (sync/async).
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
操作结果的错误码 / Error code indicating success or failure.

Implements LibXR::SPI.

Definition at line 853 of file esp_spi.cpp.

855{
856 if (write_data.size_ == 0U)
857 {
858 return CompleteZeroSize(op, in_isr);
859 }
860
861 const ErrorCode lock_ec = EnsureReadyAndAcquire();
862 if (lock_ec != ErrorCode::OK)
863 {
864 return lock_ec;
865 }
866
867 RawData tx = GetTxBuffer();
868 const size_t total = write_data.size_ + 1U;
869 ASSERT(tx.size_ >= total);
870
871 auto* tx_ptr = static_cast<uint8_t*>(tx.addr_);
872 tx_ptr[0] = static_cast<uint8_t>(reg & 0x7FU);
873 Memory::FastCopy(tx_ptr + 1, write_data.addr_, write_data.size_);
874
875 if (CanUseDma(total))
876 {
877 bool started = false;
878 const ErrorCode ec = StartAsyncTransfer(tx_ptr, nullptr, total, false, {nullptr, 0},
879 false, op, started);
880 return ReturnAsyncStartResult(ec, started);
881 }
882
883 const ErrorCode ec = ExecuteTransfer(tx_ptr, nullptr, total, false);
884 if (ec == ErrorCode::OK)
885 {
886 SwitchBufferLocal();
887 }
888
889 Release();
890 return FinalizeSyncResult(op, in_isr, ec);
891}

◆ ReadAndWrite()

ErrorCode LibXR::ESP32SPI::ReadAndWrite ( RawData read_data,
ConstRawData write_data,
OperationRW & op,
bool in_isr = false )
overridevirtual

进行 SPI 读写操作 / Performs SPI read and write operations.

Parameters
read_data存储读取数据的缓冲区 / Buffer to store the read data.
write_data需要写入的数据缓冲区 / Buffer containing the data to be written.
op读写操作类型 / Type of read/write operation.
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
操作结果的错误码 / Error code indicating the result of the operation.

Implements LibXR::SPI.

Definition at line 755 of file esp_spi.cpp.

757{
758 const size_t need = std::max(read_data.size_, write_data.size_);
759 if (need == 0U)
760 {
761 return CompleteZeroSize(op, in_isr);
762 }
763
764 const ErrorCode lock_ec = EnsureReadyAndAcquire();
765 if (lock_ec != ErrorCode::OK)
766 {
767 return lock_ec;
768 }
769
770 RawData rx = GetRxBuffer();
771 RawData tx = GetTxBuffer();
772 ASSERT(rx.size_ >= need);
773 ASSERT(tx.size_ >= need);
774
775 auto* tx_ptr = static_cast<uint8_t*>(tx.addr_);
776 if (write_data.size_ > 0U)
777 {
778 Memory::FastCopy(tx_ptr, write_data.addr_, write_data.size_);
779 }
780 if (need > write_data.size_)
781 {
782 Memory::FastSet(tx_ptr + write_data.size_, 0x00, need - write_data.size_);
783 }
784
785 if (CanUseDma(need))
786 {
787 bool started = false;
788 const ErrorCode ec = StartAsyncTransfer(tx_ptr, static_cast<uint8_t*>(rx.addr_), need,
789 true, read_data, false, op, started);
790 return ReturnAsyncStartResult(ec, started);
791 }
792
793 const ErrorCode ec =
794 ExecuteTransfer(tx_ptr, static_cast<uint8_t*>(rx.addr_), need, true);
795 if (ec == ErrorCode::OK)
796 {
797 if (read_data.size_ > 0U)
798 {
799 Memory::FastCopy(read_data.addr_, rx.addr_, read_data.size_);
800 }
801 SwitchBufferLocal();
802 }
803
804 Release();
805 return FinalizeSyncResult(op, in_isr, ec);
806}

◆ SetConfig()

ErrorCode LibXR::ESP32SPI::SetConfig ( SPI::Configuration config)
overridevirtual

设置 SPI 配置参数 / Sets SPI configuration parameters.

Parameters
config需要应用的 SPI 配置 / The SPI configuration to apply.
Returns
操作结果的错误码 / Error code indicating the result of the operation.

Implements LibXR::SPI.

Definition at line 451 of file esp_spi.cpp.

452{
453 if (!initialized_ || (hw_ == nullptr))
454 {
456 }
457 if (busy_.IsSet())
458 {
459 return ErrorCode::BUSY;
460 }
461
462 if (config.prescaler == Prescaler::UNKNOWN)
463 {
464 return ErrorCode::ARG_ERR;
465 }
466 if (config.double_buffer &&
467 ((dbuf_rx_block_size_ == 0U) || (dbuf_tx_block_size_ == 0U)))
468 {
469 return ErrorCode::ARG_ERR;
470 }
471
472 const uint32_t div = PrescalerToDiv(config.prescaler);
473 if ((div == 0) || (source_clock_hz_ == 0))
474 {
475 return ErrorCode::ARG_ERR;
476 }
477
478 const uint32_t target_hz = source_clock_hz_ / div;
479 if (target_hz == 0)
480 {
481 return ErrorCode::ARG_ERR;
482 }
483
484 const uint8_t mode = ResolveSpiMode(config.clock_polarity, config.clock_phase);
485 spi_ll_master_set_mode(hw_, mode);
486
487 const int applied_hz = spi_ll_master_set_clock(hw_, static_cast<int>(source_clock_hz_),
488 static_cast<int>(target_hz), 128);
489 if (applied_hz <= 0)
490 {
491 return ErrorCode::INIT_ERR;
492 }
493
494 spi_ll_apply_config(hw_);
495 GetConfig() = config;
496 dbuf_enabled_ = config.double_buffer;
497 dbuf_active_block_ = 0U;
498
499 return ErrorCode::OK;
500}
bool IsSet() const noexcept
判断是否已置位 / Check whether the flag is set
Definition flag.hpp:55
@ UNKNOWN
未知分频系数 / Unknown prescaler.
static constexpr uint32_t PrescalerToDiv(Prescaler prescaler)
将分频系数转换为除数 / Converts a prescaler to a divisor.
Definition spi.hpp:70
Configuration & GetConfig()
获取 SPI 配置参数 / Gets the SPI configuration parameters.
Definition spi.hpp:397
@ INIT_ERR
初始化错误 / Initialization error
@ STATE_ERR
状态错误 / State error
@ BUSY
忙碌 / Busy
@ ARG_ERR
参数错误 / Argument error

◆ Transfer()

ErrorCode LibXR::ESP32SPI::Transfer ( size_t size,
OperationRW & op,
bool in_isr = false )
overridevirtual

进行一次SPI传输(使用当前缓冲区数据,零拷贝,支持双缓冲)。 Performs a SPI transfer (zero-copy, supports double buffering).

Parameters
size需要传输的数据大小 / The size of the data to be transferred.
op读写操作类型 / Type of read/write operation.
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
操作结果的错误码 / Error code indicating the result of the operation.

Implements LibXR::SPI.

Definition at line 893 of file esp_spi.cpp.

894{
895 if (size == 0U)
896 {
897 return CompleteZeroSize(op, in_isr);
898 }
899
900 const ErrorCode lock_ec = EnsureReadyAndAcquire();
901 if (lock_ec != ErrorCode::OK)
902 {
903 return lock_ec;
904 }
905
906 RawData rx = GetRxBuffer();
907 RawData tx = GetTxBuffer();
908 ASSERT(rx.size_ >= size);
909 ASSERT(tx.size_ >= size);
910
911 if (CanUseDma(size))
912 {
913 bool started = false;
914 const ErrorCode ec = StartAsyncTransfer(static_cast<const uint8_t*>(tx.addr_),
915 static_cast<uint8_t*>(rx.addr_), size, true,
916 {nullptr, 0}, false, op, started);
917 return ReturnAsyncStartResult(ec, started);
918 }
919
920 const ErrorCode ec = ExecuteTransfer(static_cast<const uint8_t*>(tx.addr_),
921 static_cast<uint8_t*>(rx.addr_), size, true);
922 if (ec == ErrorCode::OK)
923 {
924 SwitchBufferLocal();
925 }
926
927 Release();
928 return FinalizeSyncResult(op, in_isr, ec);
929}

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