libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::STM32SPI Class Reference
Inheritance diagram for LibXR::STM32SPI:
[legend]
Collaboration diagram for LibXR::STM32SPI:
[legend]

Public Member Functions

 STM32SPI (SPI_HandleTypeDef *spi_handle, RawData dma_buff_rx, RawData dma_buff_tx, uint32_t dma_enable_min_size=3)
 
ErrorCode ReadAndWrite (RawData read_data, ConstRawData write_data, OperationRW &op) 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) override
 SPI 设备的寄存器读取数据。 Reads data from a specific register of the SPI device.
 
ErrorCode MemWrite (uint16_t reg, ConstRawData write_data, OperationRW &op) override
 SPI 设备的寄存器写入数据。 Writes data to a specific register of the SPI device.
 
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.
 
ErrorCode Transfer (size_t size, OperationRW &op) override
 进行一次SPI传输(使用当前缓冲区数据,零拷贝,支持双缓冲)。 Performs a SPI transfer (zero-copy, supports double buffering).
 
- Public Member Functions inherited from LibXR::SPI
 SPI (RawData rx_buffer, RawData tx_buffer)
 构造函数。Constructor.
 
virtual ErrorCode Read (RawData read_data, OperationRW &op)
 进行 SPI 读取操作。Performs SPI read operation.
 
virtual ErrorCode Write (ConstRawData write_data, OperationRW &op)
 进行 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.
 
ConfigurationGetConfig ()
 获取 SPI 配置参数。Gets the SPI configuration parameters.
 
bool IsDoubleBuffer () const
 检查是否使用双缓冲区。Checks if double buffering is enabled.
 

Data Fields

SPI_HandleTypeDef * spi_handle_
 
stm32_spi_id_t id_ = STM32_SPI_ID_ERROR
 
uint32_t dma_enable_min_size_ = 3
 
OperationRW rw_op_
 
RawData read_buff_
 
bool mem_read_ = false
 

Static Public Attributes

static STM32SPImap [STM32_SPI_NUMBER] = {nullptr}
 

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 51 of file stm32_spi.hpp.

Constructor & Destructor Documentation

◆ STM32SPI()

STM32SPI::STM32SPI ( SPI_HandleTypeDef * spi_handle,
RawData dma_buff_rx,
RawData dma_buff_tx,
uint32_t dma_enable_min_size = 3 )

Definition at line 71 of file stm32_spi.cpp.

73 : SPI(rx, tx),
74 spi_handle_(spi_handle),
75 id_(STM32_SPI_GetID(spi_handle_->Instance)),
76 dma_enable_min_size_(dma_enable_min_size)
77{
78 ASSERT(id_ != STM32_SPI_ID_ERROR);
79
80 map[id_] = this;
81}
SPI(RawData rx_buffer, RawData tx_buffer)
构造函数。Constructor.
Definition spi.hpp:110

Member Function Documentation

◆ GetMaxBusSpeed()

uint32_t STM32SPI::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 484 of file stm32_spi.cpp.

485{
486 SPI_TypeDef *inst = spi_handle_ ? spi_handle_->Instance : nullptr;
487 if (!inst)
488 {
489 return 0u;
490 }
491
492#if defined(HAL_RCC_MODULE_ENABLED)
493// === 1) 优先读取“独立的 SPI 内核时钟” (kernel clock) ===
494// H7: 分组宏 SPI123 / SPI45 / SPI6
495#if defined(RCC_PERIPHCLK_SPI123) || defined(RCC_PERIPHCLK_SPI45) || \
496 defined(RCC_PERIPHCLK_SPI6)
497 // SPI1/2/3 → RCC_PERIPHCLK_SPI123
498 if (
499#ifdef SPI1
500 inst == SPI1 ||
501#endif
502#ifdef SPI2
503 inst == SPI2 ||
504#endif
505#ifdef SPI3
506 inst == SPI3 ||
507#endif
508 false)
509 {
510#ifdef RCC_PERIPHCLK_SPI123
511 return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
512#endif
513 }
514 // SPI4/5 → RCC_PERIPHCLK_SPI45
515 if (
516#ifdef SPI4
517 inst == SPI4 ||
518#endif
519#ifdef SPI5
520 inst == SPI5 ||
521#endif
522 false)
523 {
524#ifdef RCC_PERIPHCLK_SPI45
525 return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI45);
526#endif
527 }
528// SPI6 → RCC_PERIPHCLK_SPI6
529#ifdef SPI6
530 if (inst == SPI6)
531 {
532#ifdef RCC_PERIPHCLK_SPI6
533 return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6);
534#endif
535 }
536#endif
537#endif // H7 分组
538
539// 其它系列:通常是逐个 SPIx 宏
540#if defined(RCC_PERIPHCLK_SPI1)
541#ifdef SPI1
542 if (inst == SPI1) return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1);
543#endif
544#endif
545#if defined(RCC_PERIPHCLK_SPI2)
546#ifdef SPI2
547 if (inst == SPI2) return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI2);
548#endif
549#endif
550#if defined(RCC_PERIPHCLK_SPI3)
551#ifdef SPI3
552 if (inst == SPI3) return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI3);
553#endif
554#endif
555#if defined(RCC_PERIPHCLK_SPI4)
556#ifdef SPI4
557 if (inst == SPI4) return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI4);
558#endif
559#endif
560#if defined(RCC_PERIPHCLK_SPI5)
561#ifdef SPI5
562 if (inst == SPI5) return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI5);
563#endif
564#endif
565#if defined(RCC_PERIPHCLK_SPI6)
566#ifdef SPI6
567 if (inst == SPI6) return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6);
568#endif
569#endif
570#endif // HAL_RCC_MODULE_ENABLED
571
572 // === 2) 回退:使用所在 APB 的 PCLK 作为 SPI 内核时钟 ===
573#if defined(STM32H7) && defined(SPI6)
574 if (inst == SPI6)
575 {
576#if defined(HAL_RCC_GetPCLK4Freq)
577 return HAL_RCC_GetPCLK4Freq();
578#else
579 return HAL_RCC_GetHCLKFreq();
580#endif
581 }
582#endif
583
584 // 大多数系列:SPI1/4/5/6/7/8 → APB2;SPI2/3 → APB1
585 if (
586#ifdef SPI1
587 inst == SPI1 ||
588#endif
589#ifdef SPI4
590 inst == SPI4 ||
591#endif
592#ifdef SPI5
593 inst == SPI5 ||
594#endif
595#ifdef SPI6
596 inst == SPI6 ||
597#endif
598#ifdef SPI7
599 inst == SPI7 ||
600#endif
601#ifdef SPI8
602 inst == SPI8 ||
603#endif
604 false)
605 {
606#if defined(HAL_RCC_GetPCLK2Freq)
607 return HAL_RCC_GetPCLK2Freq();
608#elif defined(HAL_RCC_GetPCLK1Freq)
609 return HAL_RCC_GetPCLK1Freq(); // 低端/单APB系列兜底
610#else
611 return HAL_RCC_GetHCLKFreq();
612#endif
613 }
614 else
615 {
616#if defined(HAL_RCC_GetPCLK1Freq)
617 return HAL_RCC_GetPCLK1Freq();
618#elif defined(HAL_RCC_GetPCLK2Freq)
619 return HAL_RCC_GetPCLK2Freq();
620#else
621 return HAL_RCC_GetHCLKFreq();
622#endif
623 }
624}

◆ GetMaxPrescaler()

STM32SPI::Prescaler STM32SPI::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 626 of file stm32_spi.cpp.

627{
628#if defined(SPI_BAUDRATEPRESCALER_1024)
629 return Prescaler::DIV_1024;
630#elif defined(SPI_BAUDRATEPRESCALER_512)
631 return Prescaler::DIV_512;
632#elif defined(SPI_BAUDRATEPRESCALER_256)
633 return Prescaler::DIV_256;
634#elif defined(SPI_BAUDRATEPRESCALER_128)
635 return Prescaler::DIV_128;
636#elif defined(SPI_BAUDRATEPRESCALER_64)
637 return Prescaler::DIV_64;
638#elif defined(SPI_BAUDRATEPRESCALER_32)
639 return Prescaler::DIV_32;
640#elif defined(SPI_BAUDRATEPRESCALER_16)
641 return Prescaler::DIV_16;
642#elif defined(SPI_BAUDRATEPRESCALER_8)
643 return Prescaler::DIV_8;
644#elif defined(SPI_BAUDRATEPRESCALER_4)
645 return Prescaler::DIV_4;
646#elif defined(SPI_BAUDRATEPRESCALER_2)
647 return Prescaler::DIV_2;
648#elif defined(SPI_BAUDRATEPRESCALER_1)
649 return Prescaler::DIV_1;
650#else
651 return Prescaler::UNKNOWN;
652#endif
653}
@ DIV_16
分频系数为 16。Division factor is 16.
@ DIV_2
分频系数为 2。Division factor is 2.
@ DIV_64
分频系数为 64。Division factor is 64.
@ DIV_1
分频系数为 1。Division factor is 1.
@ UNKNOWN
未知分频系数。Unknown prescaler.
@ DIV_256
分频系数为 256。Division factor is 256.
@ DIV_128
分频系数为 128。Division factor is 128.
@ DIV_4
分频系数为 4。Division factor is 4.
@ DIV_32
分频系数为 32。Division factor is 32.
@ DIV_512
分频系数为 512。Division factor is 512.
@ DIV_8
分频系数为 8。Division factor is 8.
@ DIV_1024
分频系数为 1024。Division factor is 1024.

◆ MemRead()

ErrorCode STM32SPI::MemRead ( uint16_t reg,
RawData read_data,
OperationRW & op )
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).
Returns
操作结果的错误码。Error code indicating success or failure.

Implements LibXR::SPI.

Definition at line 345 of file stm32_spi.cpp.

346{
347 uint32_t need_read = read_data.size_;
348
349 if (spi_handle_->State != HAL_SPI_STATE_READY)
350 {
351 return ErrorCode::BUSY;
352 }
353
354 RawData rx = GetRxBuffer();
355 RawData tx = GetTxBuffer();
356
357 ASSERT(rx.size_ >= need_read + 1);
358 ASSERT(tx.size_ >= need_read + 1);
359
360 if (need_read + 1 > dma_enable_min_size_)
361 {
362 mem_read_ = true;
363 rw_op_ = op;
364
365 uint8_t *txb = reinterpret_cast<uint8_t *>(tx.addr_);
366 memset(txb, 0, need_read + 1);
367 txb[0] = static_cast<uint8_t>(reg | 0x80);
368#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
369 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
370 static_cast<int32_t>(need_read + 1));
371#endif
372 read_buff_ = read_data;
373
374 HAL_StatusTypeDef st =
375 HAL_SPI_TransmitReceive_DMA(spi_handle_, static_cast<uint8_t *>(tx.addr_),
376 static_cast<uint8_t *>(rx.addr_), need_read + 1);
377
378 if (st != HAL_OK)
379 {
380 return ErrorCode::BUSY;
381 }
382
383 op.MarkAsRunning();
384 if (op.type == OperationRW::OperationType::BLOCK)
385 {
386 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
387 }
388 return ErrorCode::OK;
389 }
390
391 mem_read_ = false;
392 uint8_t *txb = reinterpret_cast<uint8_t *>(tx.addr_);
393 memset(txb, 0, need_read + 1);
394 txb[0] = static_cast<uint8_t>(reg | 0x80);
395#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
396 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
397 static_cast<int32_t>(need_read + 1));
398#endif
399
400 ErrorCode ans = (HAL_SPI_TransmitReceive(spi_handle_, static_cast<uint8_t *>(tx.addr_),
401 static_cast<uint8_t *>(rx.addr_),
402 need_read + 1, 20) == HAL_OK)
403 ? ErrorCode::OK
404 : ErrorCode::BUSY;
405
406 if (ans == ErrorCode::OK)
407 {
408 uint8_t *rxb = reinterpret_cast<uint8_t *>(rx.addr_);
409 memcpy(read_data.addr_, rxb + 1, need_read);
410 }
411 SwitchBuffer();
412
413 if (op.type != OperationRW::OperationType::BLOCK)
414 {
415 op.UpdateStatus(false, ans);
416 }
417 return ans;
418}
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
RawData GetRxBuffer()
获取接收数据的缓冲区。Gets the buffer for storing received data.
Definition spi.hpp:303
void SwitchBuffer()
切换缓冲区。Switches the buffer.
Definition spi.hpp:334
RawData GetTxBuffer()
获取发送数据的缓冲区。Gets the buffer for storing data to be sent.
Definition spi.hpp:319

◆ MemWrite()

ErrorCode STM32SPI::MemWrite ( uint16_t reg,
ConstRawData write_data,
OperationRW & op )
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).
Returns
操作结果的错误码。Error code indicating success or failure.

Implements LibXR::SPI.

Definition at line 420 of file stm32_spi.cpp.

421{
422 uint32_t need_write = write_data.size_;
423
424 if (spi_handle_->State != HAL_SPI_STATE_READY)
425 {
426 return ErrorCode::BUSY;
427 }
428
429 RawData tx = GetTxBuffer();
430 ASSERT(tx.size_ >= need_write + 1);
431
432 if (need_write + 1 > dma_enable_min_size_)
433 {
434 mem_read_ = false;
435 rw_op_ = op;
436
437 uint8_t *txb = reinterpret_cast<uint8_t *>(tx.addr_);
438 txb[0] = static_cast<uint8_t>(reg & 0x7F);
439 memcpy(txb + 1, write_data.addr_, need_write);
440#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
441 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
442 static_cast<int32_t>(need_write + 1));
443#endif
444 read_buff_ = {nullptr, 0};
445
446 HAL_StatusTypeDef st = HAL_SPI_Transmit_DMA(
447 spi_handle_, static_cast<uint8_t *>(tx.addr_), need_write + 1);
448
449 if (st != HAL_OK)
450 {
451 return ErrorCode::BUSY;
452 }
453
454 op.MarkAsRunning();
455 if (op.type == OperationRW::OperationType::BLOCK)
456 {
457 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
458 }
459 return ErrorCode::OK;
460 }
461
462 uint8_t *txb = reinterpret_cast<uint8_t *>(tx.addr_);
463 txb[0] = static_cast<uint8_t>(reg & 0x7F);
464 memcpy(txb + 1, write_data.addr_, need_write);
465#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
466 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
467 static_cast<int32_t>(need_write + 1));
468#endif
469
470 ErrorCode ans = (HAL_SPI_Transmit(spi_handle_, static_cast<uint8_t *>(tx.addr_),
471 need_write + 1, 20) == HAL_OK)
472 ? ErrorCode::OK
473 : ErrorCode::BUSY;
474
475 SwitchBuffer();
476
477 if (op.type != OperationRW::OperationType::BLOCK)
478 {
479 op.UpdateStatus(false, ans);
480 }
481 return ans;
482}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).

◆ ReadAndWrite()

ErrorCode STM32SPI::ReadAndWrite ( RawData read_data,
ConstRawData write_data,
OperationRW & op )
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.
Returns
操作结果的错误码。Error code indicating the result of the operation.

Implements LibXR::SPI.

Definition at line 83 of file stm32_spi.cpp.

85{
86 uint32_t need_write = max(write_data.size_, read_data.size_);
87
88 RawData rx = GetRxBuffer();
89 RawData tx = GetTxBuffer();
90
91 if (rx.size_ > 0)
92 {
93 ASSERT(need_write <= rx.size_);
94 }
95 if (tx.size_ > 0)
96 {
97 ASSERT(need_write <= tx.size_);
98 }
99
100 if (spi_handle_->State != HAL_SPI_STATE_READY)
101 {
102 return ErrorCode::BUSY;
103 }
104
105 mem_read_ = false;
106
107 if (need_write > dma_enable_min_size_)
108 {
109 rw_op_ = op;
110
111 HAL_StatusTypeDef st = HAL_OK;
112
113 if (write_data.size_ > 0 && read_data.size_ > 0)
114 {
115 memcpy(tx.addr_, write_data.addr_, write_data.size_);
116 if (write_data.size_ < need_write)
117 {
118 memset(reinterpret_cast<uint8_t *>(tx.addr_) + write_data.size_, 0,
119 need_write - write_data.size_);
120 }
121#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
122 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
123 static_cast<int32_t>(need_write));
124#endif
125 read_buff_ = read_data;
126
127 st = HAL_SPI_TransmitReceive_DMA(spi_handle_, static_cast<uint8_t *>(tx.addr_),
128 static_cast<uint8_t *>(rx.addr_), need_write);
129 }
130 else if (write_data.size_ > 0)
131 {
132 memcpy(tx.addr_, write_data.addr_, write_data.size_);
133 if (write_data.size_ < need_write)
134 {
135 memset(reinterpret_cast<uint8_t *>(tx.addr_) + write_data.size_, 0,
136 need_write - write_data.size_);
137 }
138#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
139 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
140 static_cast<int32_t>(need_write));
141#endif
142 read_buff_ = {nullptr, 0};
143
144 st =
145 HAL_SPI_Transmit_DMA(spi_handle_, static_cast<uint8_t *>(tx.addr_), need_write);
146 }
147 else if (read_data.size_ > 0)
148 {
149 read_buff_ = read_data;
150
151 st = HAL_SPI_Receive_DMA(spi_handle_, static_cast<uint8_t *>(rx.addr_),
152 read_data.size_);
153 }
154 else
155 {
156 if (op.type != OperationRW::OperationType::BLOCK)
157 {
158 op.UpdateStatus(false, ErrorCode::OK);
159 }
160 return ErrorCode::OK;
161 }
162
163 if (st != HAL_OK)
164 {
165 return ErrorCode::BUSY;
166 }
167
168 op.MarkAsRunning();
169 if (op.type == OperationRW::OperationType::BLOCK)
170 {
171 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
172 }
173 return ErrorCode::OK;
174 }
175
176 ErrorCode ans = ErrorCode::OK;
177
178 if (write_data.size_ > 0 && read_data.size_ > 0)
179 {
180 memcpy(tx.addr_, write_data.addr_, write_data.size_);
181 if (write_data.size_ < need_write)
182 {
183 memset(reinterpret_cast<uint8_t *>(tx.addr_) + write_data.size_, 0,
184 need_write - write_data.size_);
185 }
186#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
187 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
188 static_cast<int32_t>(need_write));
189#endif
190 ans = (HAL_SPI_TransmitReceive(spi_handle_, static_cast<uint8_t *>(tx.addr_),
191 static_cast<uint8_t *>(rx.addr_), need_write,
192 20) == HAL_OK)
193 ? ErrorCode::OK
194 : ErrorCode::BUSY;
195
196 if (ans == ErrorCode::OK)
197 {
198 memcpy(read_data.addr_, rx.addr_, read_data.size_);
199 }
200 SwitchBuffer();
201 }
202 else if (read_data.size_ > 0)
203 {
204 ans = (HAL_SPI_Receive(spi_handle_, static_cast<uint8_t *>(rx.addr_), read_data.size_,
205 20) == HAL_OK)
206 ? ErrorCode::OK
207 : ErrorCode::BUSY;
208
209 if (ans == ErrorCode::OK)
210 {
211 memcpy(read_data.addr_, rx.addr_, read_data.size_);
212 }
213 SwitchBuffer();
214 }
215 else if (write_data.size_ > 0)
216 {
217 memcpy(tx.addr_, write_data.addr_, write_data.size_);
218#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
219 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
220 static_cast<int32_t>(need_write));
221#endif
222 ans = (HAL_SPI_Transmit(spi_handle_, static_cast<uint8_t *>(tx.addr_),
223 write_data.size_, 20) == HAL_OK)
224 ? ErrorCode::OK
225 : ErrorCode::BUSY;
226
227 SwitchBuffer();
228 }
229 else
230 {
231 if (op.type != OperationRW::OperationType::BLOCK)
232 {
233 op.UpdateStatus(false, ErrorCode::OK);
234 }
235 return ErrorCode::OK;
236 }
237
238 if (op.type != OperationRW::OperationType::BLOCK)
239 {
240 op.UpdateStatus(false, ans);
241 }
242 return ans;
243}
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
Definition libxr_rw.hpp:202
constexpr auto max(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最大值

◆ SetConfig()

ErrorCode STM32SPI::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 245 of file stm32_spi.cpp.

246{
247 switch (config.clock_polarity)
248 {
250 spi_handle_->Init.CLKPolarity = SPI_POLARITY_LOW;
251 break;
253 spi_handle_->Init.CLKPolarity = SPI_POLARITY_HIGH;
254 break;
255 }
256
257 switch (config.clock_phase)
258 {
260 spi_handle_->Init.CLKPhase = SPI_PHASE_1EDGE;
261 break;
263 spi_handle_->Init.CLKPhase = SPI_PHASE_2EDGE;
264 break;
265 }
266
267 bool ok = true;
268 uint32_t hal_presc = 0;
269
270 switch (config.prescaler)
271 {
272#ifdef SPI_BAUDRATEPRESCALER_1
273 case Prescaler::DIV_1:
274 hal_presc = SPI_BAUDRATEPRESCALER_1;
275 break;
276#endif
277#ifdef SPI_BAUDRATEPRESCALER_2
278 case Prescaler::DIV_2:
279 hal_presc = SPI_BAUDRATEPRESCALER_2;
280 break;
281#endif
282#ifdef SPI_BAUDRATEPRESCALER_4
283 case Prescaler::DIV_4:
284 hal_presc = SPI_BAUDRATEPRESCALER_4;
285 break;
286#endif
287#ifdef SPI_BAUDRATEPRESCALER_8
288 case Prescaler::DIV_8:
289 hal_presc = SPI_BAUDRATEPRESCALER_8;
290 break;
291#endif
292#ifdef SPI_BAUDRATEPRESCALER_16
294 hal_presc = SPI_BAUDRATEPRESCALER_16;
295 break;
296#endif
297#ifdef SPI_BAUDRATEPRESCALER_32
299 hal_presc = SPI_BAUDRATEPRESCALER_32;
300 break;
301#endif
302#ifdef SPI_BAUDRATEPRESCALER_64
304 hal_presc = SPI_BAUDRATEPRESCALER_64;
305 break;
306#endif
307#ifdef SPI_BAUDRATEPRESCALER_128
309 hal_presc = SPI_BAUDRATEPRESCALER_128;
310 break;
311#endif
312#ifdef SPI_BAUDRATEPRESCALER_256
314 hal_presc = SPI_BAUDRATEPRESCALER_256;
315 break;
316#endif
317#ifdef SPI_BAUDRATEPRESCALER_512
319 hal_presc = SPI_BAUDRATEPRESCALER_512;
320 break;
321#endif
322#ifdef SPI_BAUDRATEPRESCALER_1024
324 hal_presc = SPI_BAUDRATEPRESCALER_1024;
325 break;
326#endif
327 default:
328 ok = false;
329 break;
330 }
331
332 ASSERT(ok);
333 if (!ok)
334 {
335 return ErrorCode::NOT_SUPPORT;
336 }
337
338 spi_handle_->Init.BaudRatePrescaler = hal_presc;
339
340 GetConfig() = config;
341
342 return (HAL_SPI_Init(spi_handle_) == HAL_OK) ? ErrorCode::OK : ErrorCode::BUSY;
343}
@ EDGE_2
在第二个时钟边沿采样数据。Data sampled on the second clock edge.
@ EDGE_1
在第一个时钟边沿采样数据。Data sampled on the first clock edge.
@ LOW
时钟空闲时为低电平。Clock idle low.
@ HIGH
时钟空闲时为高电平。Clock idle high.
Configuration & GetConfig()
获取 SPI 配置参数。Gets the SPI configuration parameters.
Definition spi.hpp:388
ClockPhase clock_phase
SPI 时钟相位。SPI clock phase.
Definition spi.hpp:88
Prescaler prescaler
SPI 分频系数。SPI prescaler.
Definition spi.hpp:89
ClockPolarity clock_polarity
SPI 时钟极性。SPI clock polarity.
Definition spi.hpp:86

◆ Transfer()

ErrorCode STM32SPI::Transfer ( size_t size,
OperationRW & op )
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.
Returns
操作结果的错误码。Error code indicating the result of the operation.

Implements LibXR::SPI.

Definition at line 655 of file stm32_spi.cpp.

656{
657 if (spi_handle_->State != HAL_SPI_STATE_READY)
658 {
659 return ErrorCode::BUSY;
660 }
661
662 if (size == 0)
663 {
664 if (op.type != OperationRW::OperationType::BLOCK)
665 {
666 op.UpdateStatus(false, ErrorCode::OK);
667 }
668 return ErrorCode::OK;
669 }
670
671 RawData rx = GetRxBuffer();
672 RawData tx = GetTxBuffer();
673
674 const uint16_t xfer = static_cast<uint16_t>(size);
675
676 if (size > dma_enable_min_size_)
677 {
678 rw_op_ = op;
679
680#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
681 SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(tx.addr_),
682 static_cast<int32_t>(xfer));
683 SCB_InvalidateDCache_by_Addr(static_cast<uint32_t *>(rx.addr_),
684 static_cast<int32_t>(xfer));
685#endif
686
687 HAL_StatusTypeDef st =
688 HAL_SPI_TransmitReceive_DMA(spi_handle_, static_cast<uint8_t *>(tx.addr_),
689 static_cast<uint8_t *>(rx.addr_), xfer);
690
691 if (st != HAL_OK)
692 {
693 return ErrorCode::BUSY;
694 }
695
696 op.MarkAsRunning();
697 if (op.type == OperationRW::OperationType::BLOCK)
698 {
699 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
700 }
701 return ErrorCode::OK;
702 }
703
704 ErrorCode ans =
705 (HAL_SPI_TransmitReceive(spi_handle_, static_cast<uint8_t *>(tx.addr_),
706 static_cast<uint8_t *>(rx.addr_), xfer, 20) == HAL_OK)
707 ? ErrorCode::OK
708 : ErrorCode::BUSY;
709
710#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
711 SCB_InvalidateDCache_by_Addr(static_cast<uint32_t *>(rx.addr_),
712 static_cast<int32_t>(xfer));
713#endif
714
715 SwitchBuffer();
716
717 if (op.type != OperationRW::OperationType::BLOCK)
718 {
719 op.UpdateStatus(false, ans);
720 }
721 return ans;
722}

Field Documentation

◆ dma_enable_min_size_

uint32_t LibXR::STM32SPI::dma_enable_min_size_ = 3

Definition at line 76 of file stm32_spi.hpp.

◆ id_

stm32_spi_id_t LibXR::STM32SPI::id_ = STM32_SPI_ID_ERROR

Definition at line 74 of file stm32_spi.hpp.

◆ map

STM32SPI * STM32SPI::map = {nullptr}
static

Definition at line 84 of file stm32_spi.hpp.

◆ mem_read_

bool LibXR::STM32SPI::mem_read_ = false

Definition at line 82 of file stm32_spi.hpp.

◆ read_buff_

RawData LibXR::STM32SPI::read_buff_

Definition at line 80 of file stm32_spi.hpp.

◆ rw_op_

OperationRW LibXR::STM32SPI::rw_op_

Definition at line 78 of file stm32_spi.hpp.

◆ spi_handle_

SPI_HandleTypeDef* LibXR::STM32SPI::spi_handle_

Definition at line 72 of file stm32_spi.hpp.


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