5#ifdef HAL_SPI_MODULE_ENABLED
11#include "libxr_def.hpp"
12#include "libxr_rw.hpp"
45stm32_spi_id_t STM32_SPI_GetID(SPI_TypeDef *addr);
53 uint32_t dma_enable_min_size = 3)
55 dma_buff_rx_(dma_buff_rx),
56 dma_buff_tx_(dma_buff_tx),
57 spi_handle_(spi_handle),
58 id_(STM32_SPI_GetID(spi_handle_->Instance)),
59 dma_enable_min_size_(dma_enable_min_size)
61 ASSERT(id_ != STM32_SPI_ID_ERROR);
70 ASSERT(need_write <= dma_buff_rx_.
size_ && need_write <= dma_buff_tx_.
size_);
72 if (spi_handle_->State != HAL_SPI_STATE_READY)
74 return ErrorCode::BUSY;
79 if (need_write > dma_enable_min_size_)
81 memcpy(dma_buff_tx_.
addr_, write_data.
addr_, need_write);
82 memset(dma_buff_rx_.
addr_, 0, need_write);
84 read_buff_ = read_data;
87 if (write_data.
size_ > 0)
89 SCB_CleanDCache_by_Addr(
static_cast<uint32_t *
>(dma_buff_tx_.
addr_),
94 HAL_SPI_TransmitReceive_DMA(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
95 static_cast<uint8_t *
>(dma_buff_rx_.
addr_), need_write);
98 if (op.
type == OperationRW::OperationType::BLOCK)
100 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
102 return ErrorCode::OK;
107 memset(dma_buff_rx_.
addr_, 0, write_data.
size_);
109 HAL_SPI_TransmitReceive(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
110 static_cast<uint8_t *
>(dma_buff_rx_.
addr_), need_write,
119 if (op.
type == OperationRW::OperationType::BLOCK)
121 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
133 spi_handle_->Init.CLKPolarity = SPI_POLARITY_LOW;
136 spi_handle_->Init.CLKPolarity = SPI_POLARITY_HIGH;
143 spi_handle_->Init.CLKPhase = SPI_PHASE_1EDGE;
146 spi_handle_->Init.CLKPhase = SPI_PHASE_2EDGE;
150 return HAL_SPI_Init(spi_handle_) == HAL_OK ? ErrorCode::OK : ErrorCode::BUSY;
155 uint32_t need_read = read_data.
size_;
157 if (spi_handle_->State != HAL_SPI_STATE_READY)
159 return ErrorCode::BUSY;
164 uint8_t *dma_buffer_rx =
reinterpret_cast<uint8_t *
>(dma_buff_rx_.
addr_);
165 uint8_t *dma_buffer_tx =
reinterpret_cast<uint8_t *
>(dma_buff_tx_.
addr_);
167 if (need_read + 1 > dma_enable_min_size_)
169 memset(dma_buff_rx_.
addr_, 0, need_read + 1);
170 memset(dma_buff_tx_.
addr_, 0, need_read + 1);
171 dma_buffer_tx[0] = reg | 0x80;
173 read_buff_ = read_data;
177 HAL_SPI_TransmitReceive_DMA(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
178 static_cast<uint8_t *
>(dma_buff_rx_.
addr_),
182 if (op.
type == OperationRW::OperationType::BLOCK)
184 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
186 return ErrorCode::OK;
190 memset(dma_buff_rx_.
addr_, 0, need_read + 1);
191 memset(dma_buff_tx_.
addr_, 0, need_read + 1);
192 dma_buffer_tx[0] = reg | 0x80;
194 HAL_SPI_TransmitReceive(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
195 static_cast<uint8_t *
>(dma_buff_rx_.
addr_),
196 need_read + 1, 20) == HAL_OK
200 memcpy(read_data.
addr_, dma_buffer_rx + 1, read_data.
size_);
204 if (op.
type == OperationRW::OperationType::BLOCK)
206 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
215 uint32_t need_write = write_data.
size_;
217 if (spi_handle_->State != HAL_SPI_STATE_READY)
219 return ErrorCode::BUSY;
224 uint8_t *dma_buffer_tx =
reinterpret_cast<uint8_t *
>(dma_buff_tx_.
addr_);
226 if (need_write + 1 > dma_enable_min_size_)
228 memcpy(dma_buffer_tx + 1, write_data.
addr_, need_write);
229 *dma_buffer_tx = reg & 0x7f;
232 read_buff_ = {
nullptr, 0};
234 HAL_SPI_TransmitReceive_DMA(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
235 static_cast<uint8_t *
>(dma_buff_rx_.
addr_),
239 if (op.
type == OperationRW::OperationType::BLOCK)
241 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
243 return ErrorCode::OK;
247 memcpy(dma_buffer_tx + 1, write_data.
addr_, need_write);
248 *dma_buffer_tx = reg & 0x7f;
250 HAL_SPI_TransmitReceive(spi_handle_,
static_cast<uint8_t *
>(dma_buff_tx_.
addr_),
251 static_cast<uint8_t *
>(dma_buff_rx_.
addr_),
252 need_write + 1, 20) == HAL_OK
258 if (op.
type == OperationRW::OperationType::BLOCK)
260 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
267 RawData dma_buff_rx_, dma_buff_tx_;
269 SPI_HandleTypeDef *spi_handle_;
271 stm32_spi_id_t id_ = STM32_SPI_ID_ERROR;
273 uint32_t dma_enable_min_size_ = 3;
279 bool mem_read_ =
false;
281 static STM32SPI *map[STM32_SPI_NUMBER];
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
void UpdateStatus(bool in_isr, Status &&...status)
Updates operation status based on type.
union LibXR::Operation::@4 data
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
串行外设接口(SPI)抽象类。Abstract class for Serial Peripheral Interface (SPI).
@ EDGE_2
在第二个时钟边沿采样数据。Data sampled on the second clock edge.
@ EDGE_1
在第一个时钟边沿采样数据。Data sampled on the first clock edge.
WriteOperation OperationRW
定义读写操作类型的别名。Defines an alias for the read/write operation type.
SPI()
默认构造函数。Default constructor.
@ LOW
时钟空闲时为低电平。Clock idle low.
@ HIGH
时钟空闲时为高电平。Clock idle high.
ErrorCode MemRead(uint16_t reg, RawData read_data, OperationRW &op) override
从 SPI 设备的寄存器读取数据。 Reads data from a specific register of the SPI device.
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 MemWrite(uint16_t reg, ConstRawData write_data, OperationRW &op) override
向 SPI 设备的寄存器写入数据。 Writes data to a specific register of the SPI device.
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待(减少)信号量 Waits (decrements) the semaphore
constexpr auto max(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最大值
存储 SPI 配置参数的结构体。Structure for storing SPI configuration parameters.
ClockPhase clock_phase
SPI 时钟相位。SPI clock phase.
ClockPolarity clock_polarity
SPI 时钟极性。SPI clock polarity.