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

Public Member Functions

 CH32SPI (ch32_spi_id_t id, RawData dma_rx, RawData dma_tx, GPIO_TypeDef *sck_port, uint16_t sck_pin, GPIO_TypeDef *miso_port, uint16_t miso_pin, GPIO_TypeDef *mosi_port, uint16_t mosi_pin, uint32_t pin_remap=0, bool master_mode=true, bool firstbit_msb=true, uint16_t prescaler=SPI_BaudRatePrescaler_64, uint32_t dma_enable_min_size=3, SPI::Configuration config={SPI::ClockPolarity::LOW, SPI::ClockPhase::EDGE_1})
 
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.
 
void RxDmaIRQHandler ()
 
void TxDmaIRQHandler ()
 
ErrorCode PollingTransfer (uint8_t *rx, const uint8_t *tx, uint32_t len)
 
- Public Member Functions inherited from LibXR::SPI
 SPI ()
 默认构造函数。Default 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.
 

Data Fields

RawData dma_buff_rx_
 
RawData dma_buff_tx_
 
SPI_TypeDef * instance_
 
DMA_Channel_TypeDef * dma_rx_channel_
 
DMA_Channel_TypeDef * dma_tx_channel_
 
ch32_spi_id_t id_
 
uint32_t dma_enable_min_size_
 
OperationRW rw_op_
 
RawData read_buff_
 
bool mem_read_ = false
 
bool busy_ = false
 
uint16_t mode_
 
uint16_t datasize_
 
uint16_t firstbit_
 
uint16_t prescaler_
 
uint16_t nss_ = SPI_NSS_Soft
 
GPIO_TypeDef * sck_port_
 
uint16_t sck_pin_
 
GPIO_TypeDef * miso_port_
 
uint16_t miso_pin_
 
GPIO_TypeDef * mosi_port_
 
uint16_t mosi_pin_
 

Static Public Attributes

static CH32SPImap [CH32_SPI_NUMBER] = {nullptr}
 

Private Member Functions

bool DmaBusy () const
 
void StartDmaDuplex (uint32_t count)
 
void StopDma ()
 
void PrepareTxBuffer (ConstRawData write_data, uint32_t need_len, uint32_t prefix=0, uint8_t dummy=0xFF)
 

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...
 
using OperationRW = WriteOperation
 定义读写操作类型的别名。Defines an alias for the read/write operation type.
 

Detailed Description

Definition at line 16 of file ch32_spi.hpp.

Constructor & Destructor Documentation

◆ CH32SPI()

CH32SPI::CH32SPI ( ch32_spi_id_t id,
RawData dma_rx,
RawData dma_tx,
GPIO_TypeDef * sck_port,
uint16_t sck_pin,
GPIO_TypeDef * miso_port,
uint16_t miso_pin,
GPIO_TypeDef * mosi_port,
uint16_t mosi_pin,
uint32_t pin_remap = 0,
bool master_mode = true,
bool firstbit_msb = true,
uint16_t prescaler = SPI_BaudRatePrescaler_64,
uint32_t dma_enable_min_size = 3,
SPI::Configuration config = {SPI::ClockPolarity::LOWSPI::ClockPhase::EDGE_1} )

Definition at line 12 of file ch32_spi.cpp.

17 : SPI(),
18 dma_buff_rx_(dma_rx),
19 dma_buff_tx_(dma_tx),
20 instance_(CH32_SPI_GetInstanceID(id)),
21 dma_rx_channel_(CH32_SPI_RX_DMA_CHANNEL_MAP[id]),
22 dma_tx_channel_(CH32_SPI_TX_DMA_CHANNEL_MAP[id]),
23 id_(id),
24 dma_enable_min_size_(dma_enable_min_size),
25 mode_(master_mode ? SPI_Mode_Master : SPI_Mode_Slave),
26 datasize_(SPI_DataSize_8b),
27 firstbit_(firstbit_msb ? SPI_FirstBit_MSB : SPI_FirstBit_LSB),
28 prescaler_(prescaler),
29 sck_port_(sck_port),
30 sck_pin_(sck_pin),
31 miso_port_(miso_port),
32 miso_pin_(miso_pin),
33 mosi_port_(mosi_port),
34 mosi_pin_(mosi_pin)
35{
36 ASSERT(instance_ != nullptr);
37 ASSERT(dma_buff_tx_.size_ >= 1);
38 // 读至少给 1 字节,便于 MemRead 的“命令 + N 字节” DMA 长度
39 ASSERT(dma_buff_rx_.size_ >= 1);
40
41 map[id] = this;
42
43 // === 时钟 ===
44 if (CH32_SPI_APB_MAP[id] == 1)
45 {
46 RCC_APB1PeriphClockCmd(CH32_SPI_RCC_PERIPH_MAP[id], ENABLE);
47 }
48 else if (CH32_SPI_APB_MAP[id] == 2)
49 {
50 RCC_APB2PeriphClockCmd(CH32_SPI_RCC_PERIPH_MAP[id], ENABLE);
51 }
52 else
53 {
54 ASSERT(false);
55 }
56 RCC_AHBPeriphClockCmd(CH32_SPI_RCC_PERIPH_MAP_DMA[id], ENABLE);
57
58 // === GPIO ===
59 {
60 GPIO_InitTypeDef gpio = {};
61 gpio.GPIO_Speed = GPIO_Speed_50MHz;
62
63 // SCK
64 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(sck_port_), ENABLE);
65 if (mode_ == SPI_Mode_Master)
66 {
67 gpio.GPIO_Pin = sck_pin_;
68 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
69 }
70 else
71 {
72 gpio.GPIO_Pin = sck_pin_;
73 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
74 }
75 GPIO_Init(sck_port_, &gpio);
76
77 // MISO
78 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(miso_port_), ENABLE);
79 if (mode_ == SPI_Mode_Master)
80 {
81 gpio.GPIO_Pin = miso_pin_;
82 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
83 }
84 else
85 {
86 gpio.GPIO_Pin = miso_pin_;
87 gpio.GPIO_Mode = GPIO_Mode_AF_PP; // 从机输出
88 }
89 GPIO_Init(miso_port_, &gpio);
90
91 // MOSI
92 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(mosi_port_), ENABLE);
93 if (mode_ == SPI_Mode_Master)
94 {
95 gpio.GPIO_Pin = mosi_pin_;
96 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
97 }
98 else
99 {
100 gpio.GPIO_Pin = mosi_pin_;
101 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
102 }
103 GPIO_Init(mosi_port_, &gpio);
104
105 if (pin_remap != 0)
106 {
107 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
108 GPIO_PinRemapConfig(pin_remap, ENABLE);
109 }
110 }
111
112 // === SPI 基本配置 ===
113 {
114 SPI_InitTypeDef init = {};
115 init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
116 init.SPI_Mode = mode_;
117 init.SPI_DataSize = datasize_;
118 init.SPI_CPOL =
119 (config.clock_polarity == SPI::ClockPolarity::LOW) ? SPI_CPOL_Low : SPI_CPOL_High;
120 init.SPI_CPHA =
121 (config.clock_phase == SPI::ClockPhase::EDGE_1) ? SPI_CPHA_1Edge : SPI_CPHA_2Edge;
122 init.SPI_NSS = nss_;
123 init.SPI_BaudRatePrescaler = prescaler_;
124 init.SPI_FirstBit = firstbit_;
125 init.SPI_CRCPolynomial = 7;
126
127 SPI_Init(instance_, &init);
128 SPI_Cmd(instance_, ENABLE);
129 }
130
131 // === DMA 通道基础配置 & 回调注册(启动传输时再设定 MADDR/CNTR) ===
132 {
133 // RX
134 {
135 ch32_dma_callback_t cb = [](void *arg)
136 { reinterpret_cast<CH32SPI *>(arg)->RxDmaIRQHandler(); };
137 CH32_DMA_RegisterCallback(CH32_DMA_GetID(dma_rx_channel_), cb, this);
138
139 DMA_InitTypeDef di = {};
140 DMA_DeInit(dma_rx_channel_);
141 di.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
142 di.DMA_MemoryBaseAddr = (uint32_t)dma_buff_rx_.addr_;
143 di.DMA_DIR = DMA_DIR_PeripheralSRC;
144 di.DMA_BufferSize = 0; // run-time 填
145 di.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
146 di.DMA_MemoryInc = DMA_MemoryInc_Enable;
147 di.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
148 di.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
149 di.DMA_Mode = DMA_Mode_Normal;
150 di.DMA_Priority = DMA_Priority_High;
151 di.DMA_M2M = DMA_M2M_Disable;
152 DMA_Init(dma_rx_channel_, &di);
153 DMA_ITConfig(dma_rx_channel_, DMA_IT_TC, ENABLE);
154 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[CH32_DMA_GetID(dma_rx_channel_)]);
155 }
156 // TX
157 {
158 ch32_dma_callback_t cb = [](void *arg)
159 { reinterpret_cast<CH32SPI *>(arg)->TxDmaIRQHandler(); };
160 CH32_DMA_RegisterCallback(CH32_DMA_GetID(dma_tx_channel_), cb, this);
161
162 DMA_InitTypeDef di = {};
163 DMA_DeInit(dma_tx_channel_);
164 di.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
165 di.DMA_MemoryBaseAddr = 0; // run-time 填
166 di.DMA_DIR = DMA_DIR_PeripheralDST;
167 di.DMA_BufferSize = 0; // run-time 填
168 di.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
169 di.DMA_MemoryInc = DMA_MemoryInc_Enable;
170 di.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
171 di.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
172 di.DMA_Mode = DMA_Mode_Normal;
173 di.DMA_Priority = DMA_Priority_VeryHigh;
174 di.DMA_M2M = DMA_M2M_Disable;
175 DMA_Init(dma_tx_channel_, &di);
176 DMA_ITConfig(dma_tx_channel_, DMA_IT_TC, ENABLE);
177 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[CH32_DMA_GetID(dma_tx_channel_)]);
178 }
179 }
180}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
@ EDGE_1
在第一个时钟边沿采样数据。Data sampled on the first clock edge.
SPI()
默认构造函数。Default constructor.
Definition spi.hpp:66
@ LOW
时钟空闲时为低电平。Clock idle low.
ClockPhase clock_phase
SPI 时钟相位。SPI clock phase.
Definition spi.hpp:48
ClockPolarity clock_polarity
SPI 时钟极性。SPI clock polarity.
Definition spi.hpp:47

Member Function Documentation

◆ DmaBusy()

bool LibXR::CH32SPI::DmaBusy ( ) const
inlineprivate

Definition at line 40 of file ch32_spi.hpp.

41 {
42 return (dma_rx_channel_->CNTR != 0) || (dma_tx_channel_->CNTR != 0) || busy_;
43 }

◆ MemRead()

ErrorCode CH32SPI::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 298 of file ch32_spi.cpp.

299{
300 const uint32_t n = read_data.size_;
301 if (n == 0)
302 {
303 if (op.type != OperationRW::OperationType::BLOCK)
304 op.UpdateStatus(false, ErrorCode::OK);
305 return ErrorCode::OK;
306 }
307
308 if (DmaBusy()) return ErrorCode::BUSY;
309
310 const uint32_t total = n + 1; // 含首字节命令
311 if (total > dma_enable_min_size_)
312 {
313 ASSERT(dma_buff_tx_.size_ >= total);
314 ASSERT(dma_buff_rx_.size_ >= total);
315
316 uint8_t *tx = static_cast<uint8_t *>(dma_buff_tx_.addr_);
317 tx[0] = static_cast<uint8_t>(reg | 0x80);
318 memset(tx + 1, 0xFF, n);
319
320 mem_read_ = true;
321 read_buff_ = read_data;
322 rw_op_ = op;
323 busy_ = true;
324
325 StartDmaDuplex(total);
326
327 op.MarkAsRunning();
328 if (op.type == OperationRW::OperationType::BLOCK)
329 {
330 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
331 }
332 return ErrorCode::OK;
333 }
334 else
335 {
336 // 轮询
337 uint8_t *rx = static_cast<uint8_t *>(dma_buff_rx_.addr_);
338 uint8_t *tx = static_cast<uint8_t *>(dma_buff_tx_.addr_);
339 tx[0] = static_cast<uint8_t>(reg | 0x80);
340 memset(tx + 1, 0xFF, n);
341
342 ErrorCode ec = PollingTransfer(rx, tx, n + 1);
343 memcpy(read_data.addr_, rx + 1, n);
344
345 if (op.type == OperationRW::OperationType::BLOCK)
346 {
347 return ec;
348 }
349
350 op.UpdateStatus(false, ec);
351
352 return ec;
353 }
354}

◆ MemWrite()

ErrorCode CH32SPI::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 356 of file ch32_spi.cpp.

357{
358 const uint32_t n = write_data.size_;
359 if (n == 0)
360 {
361 if (op.type != OperationRW::OperationType::BLOCK)
362 op.UpdateStatus(false, ErrorCode::OK);
363 return ErrorCode::OK;
364 }
365
366 if (DmaBusy()) return ErrorCode::BUSY;
367
368 const uint32_t total = n + 1;
369 if (total > dma_enable_min_size_)
370 {
371 ASSERT(dma_buff_tx_.size_ >= total);
372 ASSERT(dma_buff_rx_.size_ >= total); // RX 用于丢弃
373
374 uint8_t *tx = static_cast<uint8_t *>(dma_buff_tx_.addr_);
375 tx[0] = static_cast<uint8_t>(reg & 0x7F);
376 memcpy(tx + 1, write_data.addr_, n);
377
378 mem_read_ = false;
379 read_buff_ = {nullptr, 0};
380 rw_op_ = op;
381 busy_ = true;
382
383 StartDmaDuplex(total);
384
385 op.MarkAsRunning();
386 if (op.type == OperationRW::OperationType::BLOCK)
387 {
388 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
389 }
390 return ErrorCode::OK;
391 }
392 else
393 {
394 // 轮询
395 uint8_t *rx = static_cast<uint8_t *>(dma_buff_rx_.addr_);
396 uint8_t *tx = static_cast<uint8_t *>(dma_buff_tx_.addr_);
397 tx[0] = static_cast<uint8_t>(reg & 0x7F);
398 memcpy(tx + 1, write_data.addr_, n);
399
400 ErrorCode ec = PollingTransfer(rx, tx, n + 1);
401
402 if (op.type == OperationRW::OperationType::BLOCK)
403 {
404 return ec;
405 }
406
407 op.UpdateStatus(false, ec);
408
409 return ec;
410 }
411}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).

◆ PollingTransfer()

ErrorCode CH32SPI::PollingTransfer ( uint8_t * rx,
const uint8_t * tx,
uint32_t len )

Definition at line 205 of file ch32_spi.cpp.

206{
207 for (uint32_t i = 0; i < len; ++i)
208 {
209 // 等待 TXE
210 while (SPI_I2S_GetFlagStatus(instance_, SPI_I2S_FLAG_TXE) == RESET)
211 {
212 }
213 SPI_I2S_SendData(instance_, tx ? tx[i] : 0xFF);
214
215 // 等待 RXNE
216 while (SPI_I2S_GetFlagStatus(instance_, SPI_I2S_FLAG_RXNE) == RESET)
217 {
218 }
219 uint16_t d = SPI_I2S_ReceiveData(instance_);
220 if (rx) rx[i] = static_cast<uint8_t>(d & 0xFF);
221 }
222 return ErrorCode::OK;
223}

◆ PrepareTxBuffer()

void CH32SPI::PrepareTxBuffer ( ConstRawData write_data,
uint32_t need_len,
uint32_t prefix = 0,
uint8_t dummy = 0xFF )
private

Definition at line 413 of file ch32_spi.cpp.

415{
416 uint8_t *tx = static_cast<uint8_t *>(dma_buff_tx_.addr_);
417 if (write_data.size_ > 0)
418 {
419 const uint32_t copy =
420 (write_data.size_ > need_len - prefix) ? (need_len - prefix) : write_data.size_;
421 memcpy(tx + prefix, write_data.addr_, copy);
422 if (prefix + copy < need_len)
423 {
424 memset(tx + prefix + copy, dummy, need_len - prefix - copy);
425 }
426 }
427 else
428 {
429 memset(tx + prefix, dummy, need_len - prefix);
430 }
431}

◆ ReadAndWrite()

ErrorCode CH32SPI::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 225 of file ch32_spi.cpp.

227{
228 const uint32_t rsz = read_data.size_;
229 const uint32_t wsz = write_data.size_;
230 const uint32_t need = (rsz > wsz) ? rsz : wsz;
231
232 if (need == 0)
233 {
234 if (op.type != OperationRW::OperationType::BLOCK)
235 op.UpdateStatus(false, ErrorCode::OK);
236 return ErrorCode::OK;
237 }
238
239 if (DmaBusy()) return ErrorCode::BUSY;
240
241 if (need > dma_enable_min_size_)
242 {
243 ASSERT(dma_buff_tx_.size_ >= need);
244 ASSERT(dma_buff_rx_.size_ >= need);
245
246 mem_read_ = false;
247 read_buff_ = read_data;
248 rw_op_ = op;
249 busy_ = true;
250
251 PrepareTxBuffer(write_data, need);
252
253 // 配置 DMA 长度与地址并启动
254 StartDmaDuplex(need);
255
256 op.MarkAsRunning();
257 if (op.type == OperationRW::OperationType::BLOCK)
258 {
259 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
260 }
261 return ErrorCode::OK;
262 }
263 else
264 {
265 // 轮询路径
266 uint8_t *rx = static_cast<uint8_t *>(dma_buff_rx_.addr_);
267 uint8_t *tx = static_cast<uint8_t *>(dma_buff_tx_.addr_);
268
269 // 准备 tx
270 if (wsz)
271 {
272 memcpy(tx, write_data.addr_, wsz);
273 if (need > wsz) memset(tx + wsz, 0xFF, need - wsz);
274 }
275 else
276 {
277 memset(tx, 0xFF, need);
278 }
279
280 ErrorCode ec = PollingTransfer(rsz ? rx : nullptr, tx, need);
281
282 if (rsz)
283 {
284 memcpy(read_data.addr_, rx, rsz);
285 }
286
287 if (op.type == OperationRW::OperationType::BLOCK)
288 {
289 return ec;
290 }
291
292 op.UpdateStatus(false, ec);
293
294 return ec;
295 }
296}

◆ RxDmaIRQHandler()

void CH32SPI::RxDmaIRQHandler ( )

Definition at line 455 of file ch32_spi.cpp.

456{
457 // 只在 TC 时处理
458 if (DMA_GetITStatus(CH32_SPI_RX_DMA_IT_MAP[id_]) == RESET) return;
459
460 DMA_ClearITPendingBit(CH32_SPI_RX_DMA_IT_MAP[id_]);
461
462 SPI_I2S_DMACmd(instance_, SPI_I2S_DMAReq_Rx, DISABLE);
463 DMA_Cmd(dma_rx_channel_, DISABLE);
464
465 // 拷贝读数据(若有)
466 if (read_buff_.size_ > 0)
467 {
468 uint8_t *rx = static_cast<uint8_t *>(dma_buff_rx_.addr_);
469 if (mem_read_)
470 {
471 // 丢首字节命令
472 memcpy(read_buff_.addr_, rx + 1, read_buff_.size_);
473 }
474 else
475 {
476 memcpy(read_buff_.addr_, rx, read_buff_.size_);
477 }
478 }
479
480 busy_ = false;
481 rw_op_.UpdateStatus(true, ErrorCode::OK);
482}
void UpdateStatus(bool in_isr, Status &&...status)
Updates operation status based on type.
Definition libxr_rw.hpp:171

◆ SetConfig()

ErrorCode CH32SPI::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 183 of file ch32_spi.cpp.

184{
185 SPI_Cmd(instance_, DISABLE);
186 SPI_I2S_DeInit(instance_);
187
188 SPI_InitTypeDef init = {};
189 init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
190 init.SPI_Mode = mode_;
191 init.SPI_DataSize = datasize_;
192 init.SPI_CPOL =
193 (config.clock_polarity == SPI::ClockPolarity::LOW) ? SPI_CPOL_Low : SPI_CPOL_High;
194 init.SPI_CPHA =
195 (config.clock_phase == SPI::ClockPhase::EDGE_1) ? SPI_CPHA_1Edge : SPI_CPHA_2Edge;
196 init.SPI_NSS = nss_;
197 init.SPI_BaudRatePrescaler = prescaler_;
198 init.SPI_FirstBit = firstbit_;
199 init.SPI_CRCPolynomial = 7;
200 SPI_Init(instance_, &init);
201 SPI_Cmd(instance_, ENABLE);
202 return ErrorCode::OK;
203}

◆ StartDmaDuplex()

void CH32SPI::StartDmaDuplex ( uint32_t count)
private

Definition at line 433 of file ch32_spi.cpp.

434{
435 // 配置长度与地址
436 dma_rx_channel_->MADDR = reinterpret_cast<uint32_t>(dma_buff_rx_.addr_);
437 dma_rx_channel_->CNTR = count;
438
439 dma_tx_channel_->MADDR = reinterpret_cast<uint32_t>(dma_buff_tx_.addr_);
440 dma_tx_channel_->CNTR = count;
441
442 SPI_I2S_DMACmd(instance_, SPI_I2S_DMAReq_Rx, ENABLE);
443 SPI_I2S_DMACmd(instance_, SPI_I2S_DMAReq_Tx, ENABLE);
444
445 DMA_Cmd(dma_rx_channel_, ENABLE);
446 DMA_Cmd(dma_tx_channel_, ENABLE);
447}

◆ StopDma()

void CH32SPI::StopDma ( )
private

Definition at line 449 of file ch32_spi.cpp.

450{
451 DMA_Cmd(dma_tx_channel_, DISABLE);
452 DMA_Cmd(dma_rx_channel_, DISABLE);
453}

◆ TxDmaIRQHandler()

void CH32SPI::TxDmaIRQHandler ( )

Definition at line 484 of file ch32_spi.cpp.

485{
486 if (DMA_GetITStatus(CH32_SPI_TX_DMA_IT_MAP[id_]) == RESET) return;
487 DMA_ClearITPendingBit(CH32_SPI_TX_DMA_IT_MAP[id_]);
488
489 SPI_I2S_DMACmd(instance_, SPI_I2S_DMAReq_Tx, DISABLE);
490 DMA_Cmd(dma_tx_channel_, DISABLE);
491}

Field Documentation

◆ busy_

bool LibXR::CH32SPI::busy_ = false

Definition at line 64 of file ch32_spi.hpp.

◆ datasize_

uint16_t LibXR::CH32SPI::datasize_

Definition at line 68 of file ch32_spi.hpp.

◆ dma_buff_rx_

RawData LibXR::CH32SPI::dma_buff_rx_

Definition at line 52 of file ch32_spi.hpp.

◆ dma_buff_tx_

RawData LibXR::CH32SPI::dma_buff_tx_

Definition at line 53 of file ch32_spi.hpp.

◆ dma_enable_min_size_

uint32_t LibXR::CH32SPI::dma_enable_min_size_

Definition at line 58 of file ch32_spi.hpp.

◆ dma_rx_channel_

DMA_Channel_TypeDef* LibXR::CH32SPI::dma_rx_channel_

Definition at line 55 of file ch32_spi.hpp.

◆ dma_tx_channel_

DMA_Channel_TypeDef* LibXR::CH32SPI::dma_tx_channel_

Definition at line 56 of file ch32_spi.hpp.

◆ firstbit_

uint16_t LibXR::CH32SPI::firstbit_

Definition at line 69 of file ch32_spi.hpp.

◆ id_

ch32_spi_id_t LibXR::CH32SPI::id_

Definition at line 57 of file ch32_spi.hpp.

◆ instance_

SPI_TypeDef* LibXR::CH32SPI::instance_

Definition at line 54 of file ch32_spi.hpp.

◆ map

CH32SPI * CH32SPI::map = {nullptr}
static

Definition at line 37 of file ch32_spi.hpp.

◆ mem_read_

bool LibXR::CH32SPI::mem_read_ = false

Definition at line 63 of file ch32_spi.hpp.

◆ miso_pin_

uint16_t LibXR::CH32SPI::miso_pin_

Definition at line 77 of file ch32_spi.hpp.

◆ miso_port_

GPIO_TypeDef* LibXR::CH32SPI::miso_port_

Definition at line 76 of file ch32_spi.hpp.

◆ mode_

uint16_t LibXR::CH32SPI::mode_

Definition at line 67 of file ch32_spi.hpp.

◆ mosi_pin_

uint16_t LibXR::CH32SPI::mosi_pin_

Definition at line 79 of file ch32_spi.hpp.

◆ mosi_port_

GPIO_TypeDef* LibXR::CH32SPI::mosi_port_

Definition at line 78 of file ch32_spi.hpp.

◆ nss_

uint16_t LibXR::CH32SPI::nss_ = SPI_NSS_Soft

Definition at line 71 of file ch32_spi.hpp.

◆ prescaler_

uint16_t LibXR::CH32SPI::prescaler_

Definition at line 70 of file ch32_spi.hpp.

◆ read_buff_

RawData LibXR::CH32SPI::read_buff_

Definition at line 62 of file ch32_spi.hpp.

◆ rw_op_

OperationRW LibXR::CH32SPI::rw_op_

Definition at line 61 of file ch32_spi.hpp.

◆ sck_pin_

uint16_t LibXR::CH32SPI::sck_pin_

Definition at line 75 of file ch32_spi.hpp.

◆ sck_port_

GPIO_TypeDef* LibXR::CH32SPI::sck_port_

Definition at line 74 of file ch32_spi.hpp.


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