66 :
SPI(dma_rx, dma_tx),
67 instance_(CH32_SPI_GetInstanceID(id)),
68 dma_rx_channel_(CH32_SPI_RX_DMA_CHANNEL_MAP[id]),
69 dma_tx_channel_(CH32_SPI_TX_DMA_CHANNEL_MAP[id]),
70 id_(id),
71 dma_enable_min_size_(dma_enable_min_size),
72 mode_(master_mode ? SPI_Mode_Master : SPI_Mode_Slave),
73 datasize_(SPI_DataSize_8b),
74 firstbit_(firstbit_msb ? SPI_FirstBit_MSB : SPI_FirstBit_LSB),
75 prescaler_(prescaler),
76 sck_port_(sck_port),
77 sck_pin_(sck_pin),
78 miso_port_(miso_port),
79 miso_pin_(miso_pin),
80 mosi_port_(mosi_port),
81 mosi_pin_(mosi_pin)
82{
83 ASSERT(instance_ != nullptr);
84
85 map[id] = this;
86
87
88 if (CH32_SPI_APB_MAP[id] == 1)
89 {
90 RCC_APB1PeriphClockCmd(CH32_SPI_RCC_PERIPH_MAP[id], ENABLE);
91 }
92 else if (CH32_SPI_APB_MAP[id] == 2)
93 {
94 RCC_APB2PeriphClockCmd(CH32_SPI_RCC_PERIPH_MAP[id], ENABLE);
95 }
96 else
97 {
98 ASSERT(false);
99 }
100 RCC_AHBPeriphClockCmd(CH32_SPI_RCC_PERIPH_MAP_DMA[id], ENABLE);
101
102
103 {
104 GPIO_InitTypeDef gpio = {};
105 gpio.GPIO_Speed = GPIO_Speed_50MHz;
106
107
108 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(sck_port_), ENABLE);
109 if (mode_ == SPI_Mode_Master)
110 {
111 gpio.GPIO_Pin = sck_pin_;
112 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
113 }
114 else
115 {
116 gpio.GPIO_Pin = sck_pin_;
117 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
118 }
119 GPIO_Init(sck_port_, &gpio);
120
121
122 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(miso_port_), ENABLE);
123 if (mode_ == SPI_Mode_Master)
124 {
125 gpio.GPIO_Pin = miso_pin_;
126 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
127 }
128 else
129 {
130 gpio.GPIO_Pin = miso_pin_;
131 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
132 }
133 GPIO_Init(miso_port_, &gpio);
134
135
136 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(mosi_port_), ENABLE);
137 if (mode_ == SPI_Mode_Master)
138 {
139 gpio.GPIO_Pin = mosi_pin_;
140 gpio.GPIO_Mode = GPIO_Mode_AF_PP;
141 }
142 else
143 {
144 gpio.GPIO_Pin = mosi_pin_;
145 gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
146 }
147 GPIO_Init(mosi_port_, &gpio);
148
149 if (pin_remap != 0)
150 {
151 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
152 GPIO_PinRemapConfig(pin_remap, ENABLE);
153 }
154 }
155
156
157 {
158 SPI_InitTypeDef init = {};
159 init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
160 init.SPI_Mode = mode_;
161 init.SPI_DataSize = datasize_;
162 init.SPI_CPOL =
164 init.SPI_CPHA =
166 init.SPI_NSS = nss_;
167 init.SPI_BaudRatePrescaler = prescaler_;
168 init.SPI_FirstBit = firstbit_;
169 init.SPI_CRCPolynomial = 7;
170
171 SPI_Init(instance_, &init);
172 SPI_Cmd(instance_, ENABLE);
173 }
174
175
176 {
177
178 {
179 ch32_dma_callback_t cb = [](void* arg)
180 {
reinterpret_cast<CH32SPI*
>(arg)->RxDmaIRQHandler(); };
181 CH32_DMA_RegisterCallback(CH32_DMA_GetID(dma_rx_channel_), cb, this);
182
183 DMA_InitTypeDef di = {};
184 DMA_DeInit(dma_rx_channel_);
185 di.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
186 di.DMA_MemoryBaseAddr = (uint32_t)dma_rx.
addr_;
187 di.DMA_DIR = DMA_DIR_PeripheralSRC;
188 di.DMA_BufferSize = 0;
189 di.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
190 di.DMA_MemoryInc = DMA_MemoryInc_Enable;
191 di.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
192 di.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
193 di.DMA_Mode = DMA_Mode_Normal;
194 di.DMA_Priority = DMA_Priority_High;
195 di.DMA_M2M = DMA_M2M_Disable;
196 DMA_Init(dma_rx_channel_, &di);
197 DMA_ITConfig(dma_rx_channel_, DMA_IT_TC, ENABLE);
198 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[CH32_DMA_GetID(dma_rx_channel_)]);
199 }
200
201 {
202 ch32_dma_callback_t cb = [](void* arg)
203 {
reinterpret_cast<CH32SPI*
>(arg)->TxDmaIRQHandler(); };
204 CH32_DMA_RegisterCallback(CH32_DMA_GetID(dma_tx_channel_), cb, this);
205
206 DMA_InitTypeDef di = {};
207 DMA_DeInit(dma_tx_channel_);
208 di.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
209 di.DMA_MemoryBaseAddr = 0;
210 di.DMA_DIR = DMA_DIR_PeripheralDST;
211 di.DMA_BufferSize = 0;
212 di.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
213 di.DMA_MemoryInc = DMA_MemoryInc_Enable;
214 di.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
215 di.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
216 di.DMA_Mode = DMA_Mode_Normal;
217 di.DMA_Priority = DMA_Priority_VeryHigh;
218 di.DMA_M2M = DMA_M2M_Disable;
219 DMA_Init(dma_tx_channel_, &di);
220 DMA_ITConfig(dma_tx_channel_, DMA_IT_TC, ENABLE);
221 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[CH32_DMA_GetID(dma_tx_channel_)]);
222 }
223 }
224
225
228}
void * addr_
数据存储地址。 The storage address of the data.
@ EDGE_1
在第一个时钟边沿采样数据。Data sampled on the first clock edge.
SPI(RawData rx_buffer, RawData tx_buffer)
构造函数。Constructor.
@ LOW
时钟空闲时为低电平。Clock idle low.
Configuration & GetConfig()
获取 SPI 配置参数。Gets the SPI configuration parameters.
ClockPhase clock_phase
SPI 时钟相位。SPI clock phase.
Prescaler prescaler
SPI 分频系数。SPI prescaler.
ClockPolarity clock_polarity
SPI 时钟极性。SPI clock polarity.