1 ////////////////////////////////////////////////////////////////////////////////
2 /// @file     hal_spi.c
3 /// @author   AE TEAM
4 /// @brief    THIS FILE PROVIDES ALL THE SPI FIRMWARE FUNCTIONS.
5 ////////////////////////////////////////////////////////////////////////////////
6 /// @attention
7 ///
8 /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
9 /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
10 /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
11 /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
12 /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
13 /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
14 ///
15 /// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 // Define to prevent recursive inclusion
19 #define _HAL_SPI_C_
20 #include <math.h>
21 // Files includes
22 #include "hal_spi.h"
23 #include "hal_rcc.h"
24 
25 ////////////////////////////////////////////////////////////////////////////////
26 /// @addtogroup MM32_Hardware_Abstract_Layer
27 /// @{
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 /// @addtogroup SPI_HAL
31 /// @{
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 ///@addtogroup SPI_Exported_Functions
35 ///@{
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// @brief  Deinitializes the spi peripheral registers to their
39 ///         default reset values.
40 /// @param  spi: Select the SPI peripheral.
41 ///         This parameter can be one of the following values:
42 ///         SPI1, SPI2.
43 /// @retval None.
44 ////////////////////////////////////////////////////////////////////////////////
SPI_DeInit(SPI_TypeDef * spi)45 void SPI_DeInit(SPI_TypeDef* spi)
46 {
47     switch (*(vu32*)&spi) {
48         case (u32)SPI2:  // SPI2_BASE:
49             RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI2, ENABLE);
50             RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI2, DISABLE);
51             break;
52         case (u32)SPI3:  // SPI3_BASE:
53             RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI3, ENABLE);
54             RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI3, DISABLE);
55             break;
56         case (u32)SPI1:  // SPI1_BASE:
57             RCC_APB2PeriphResetCmd(RCC_APB2ENR_SPI1, ENABLE);
58             RCC_APB2PeriphResetCmd(RCC_APB2ENR_SPI1, DISABLE);
59             break;
60         default:
61             break;
62     }
63 }
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// @brief  Initializes the spi peripheral according to the specified
67 ///         parameters in the init_struct .
68 /// @param  spi: Select the SPI peripheral.
69 ///         This parameter can be one of the following values:
70 ///         SPI1, SPI2.
71 /// @param  init_struct: pointer to a SPI_InitTypeDef structure
72 ///         that contains the configuration information for the
73 ///         specified SPI peripheral.
74 /// @retval None.
75 ////////////////////////////////////////////////////////////////////////////////
SPI_Init(SPI_TypeDef * spi,SPI_InitTypeDef * init_struct)76 void SPI_Init(SPI_TypeDef* spi, SPI_InitTypeDef* init_struct)
77 {
78     if (init_struct->SPI_DataSize == SPI_DataSize_32b) {
79         SET_BIT(spi->GCR, SPI_GCR_DWSEL);
80     }
81     else {
82         CLEAR_BIT(spi->GCR, SPI_GCR_DWSEL);
83     }
84     MODIFY_REG(spi->GCR, SPI_GCR_NSS, init_struct->SPI_NSS);
85     MODIFY_REG(spi->GCR, SPI_GCR_MODE, init_struct->SPI_Mode);
86     MODIFY_REG(spi->CCR, SPI_CCR_LSBFE, init_struct->SPI_FirstBit);
87     MODIFY_REG(spi->CCR, SPI_CCR_CPOL, init_struct->SPI_CPOL);
88     MODIFY_REG(spi->CCR, SPI_CCR_CPHA, init_struct->SPI_CPHA);
89 
90     SET_BIT(spi->CCR, SPI_CCR_SPILEN);
91 
92     MODIFY_REG(spi->BRR, BRR_Mask, init_struct->SPI_BaudRatePrescaler);
93 
94     if (init_struct->SPI_DataWidth >= 32) {
95         MODIFY_REG(spi->ECR, ECR_Mask, 0);
96     }
97     else {
98         MODIFY_REG(spi->ECR, ECR_Mask, init_struct->SPI_DataWidth);
99     }
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 /// @brief  Fills each init_struct member with its default value.
104 /// @param  init_struct: pointer to a SPI_InitTypeDef structure
105 ///         which will be initialized.
106 /// @retval None.
107 ////////////////////////////////////////////////////////////////////////////////
SPI_StructInit(SPI_InitTypeDef * init_struct)108 void SPI_StructInit(SPI_InitTypeDef* init_struct)
109 {
110     init_struct->SPI_Mode              = SPI_Mode_Slave;
111     init_struct->SPI_DataSize          = SPI_DataSize_8b;
112     init_struct->SPI_DataWidth         = 8;
113     init_struct->SPI_CPOL              = SPI_CPOL_Low;
114     init_struct->SPI_CPHA              = SPI_CPHA_1Edge;
115     init_struct->SPI_NSS               = SPI_NSS_Soft;
116     init_struct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
117     init_struct->SPI_FirstBit          = SPI_FirstBit_MSB;
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// @brief  Enables or disables the specified SPI peripheral.
122 /// @param  spi: Select the SPI peripheral.
123 ///         This parameter can be one of the following values:
124 ///         SPI1, SPI2.
125 /// @param  state: new state of the spi peripheral.
126 ///         This parameter can be: ENABLE or DISABLE.
127 /// @retval None.
128 ////////////////////////////////////////////////////////////////////////////////
SPI_Cmd(SPI_TypeDef * spi,FunctionalState state)129 void SPI_Cmd(SPI_TypeDef* spi, FunctionalState state)
130 {
131     (state) ? SET_BIT(spi->GCR, SPI_GCR_SPIEN) : CLEAR_BIT(spi->GCR, SPI_GCR_SPIEN);
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// @brief  Enables or disables the specified SPI interrupts.
136 /// @param  spi: Select the SPI peripheral.
137 ///         This parameter can be one of the following values:SPI1, SPI2.
138 /// @param  interrupt: specifies the SPI interrupt sources to be
139 ///         enabled or disabled.
140 ///         This parameter can be one of the following values:
141 /// @arg    SPI_IT_TXEPT: Transmitter empty interrupt
142 /// @arg    SPI_IT_RXFULL: RX FIFO full interrupt
143 /// @arg    SPI_IT_RXMATCH: Receive data match the RXDNR number interrupt
144 /// @arg    SPI_IT_RXOERR: Receive overrun error interrupt
145 /// @arg    SPI_IT_UNDERRUN: underrun interrupt
146 /// @arg    SPI_IT_RX: Receive data available interrupt
147 /// @arg    SPI_IT_TX: Transmit FIFO available interrupt
148 /// @param  state: new state of the specified spi interrupts.
149 ///         This parameter can be: ENABLE or DISABLE.
150 /// @retval None.
151 ////////////////////////////////////////////////////////////////////////////////
SPI_ITConfig(SPI_TypeDef * spi,u8 interrupt,FunctionalState state)152 void SPI_ITConfig(SPI_TypeDef* spi, u8 interrupt, FunctionalState state)
153 {
154     if (state) {
155         SET_BIT(spi->GCR, (u32)SPI_GCR_IEN);
156         SET_BIT(spi->IER, (u32)interrupt);
157     }
158     else {
159         CLEAR_BIT(spi->IER, interrupt);
160         CLEAR_BIT(spi->GCR, SPI_GCR_IEN);
161     }
162 }
163 ////////////////////////////////////////////////////////////////////////////////
164 /// @brief  Enables or disables the SPI DMA interface.
165 /// @param  spi: Select the SPI peripheral.
166 ///         This parameter can be one of the following values:
167 ///         SPI1, SPI2.
168 /// @param  state: new state of the DMA Request sources.
169 ///         This parameter can be: ENABLE or DISABLE.
170 /// @retval None.
171 ////////////////////////////////////////////////////////////////////////////////
SPI_DMACmd(SPI_TypeDef * spi,FunctionalState state)172 void SPI_DMACmd(SPI_TypeDef* spi, FunctionalState state)
173 {
174     (state) ? SET_BIT(spi->GCR, SPI_GCR_DMAEN) : CLEAR_BIT(spi->GCR, SPI_GCR_DMAEN);
175 }
176 ////////////////////////////////////////////////////////////////////////////////
177 /// @brief  configure tn Fifo trigger level bit.
178 /// @param  spi: Select the SPI peripheral.
179 ///         This parameter can be one of the following values:
180 ///         SPI1, SPI2.
181 /// @param  fifo_trigger_value: specifies the Fifo trigger level
182 ///         This parameter can be any combination of the following values:
183 ///         SPI_TXTLF : SPI TX FIFO Trigger value set
184 ///         SPI_RXTLF : SPI RX FIFO Trigger value set
185 /// @param  state: new state of the selected SPI transfer request.
186 ///         This parameter can be: ENABLE or DISABLE.
187 /// @retval None.
188 ////////////////////////////////////////////////////////////////////////////////
SPI_FifoTrigger(SPI_TypeDef * spi,SPI_TLF_TypeDef fifo_trigger_value,FunctionalState state)189 void SPI_FifoTrigger(SPI_TypeDef* spi, SPI_TLF_TypeDef fifo_trigger_value, FunctionalState state)
190 {
191     (state) ? SET_BIT(spi->GCR, (u32)fifo_trigger_value) : CLEAR_BIT(spi->GCR, (u32)fifo_trigger_value);
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// @brief  Transmits a Data through the spi peripheral.
196 /// @param  spi: Select the SPI peripheral.
197 ///         This parameter can be one of the following values:
198 ///         SPI1, SPI2.
199 /// @param  data : Data to be transmitted.
200 /// @retval None.
201 ////////////////////////////////////////////////////////////////////////////////
SPI_SendData(SPI_TypeDef * spi,u32 data)202 void SPI_SendData(SPI_TypeDef* spi, u32 data)
203 {
204     u16 templen;
205     __asm volatile("cpsid i");
206 
207     WRITE_REG(spi->TDR, data);
208 
209     templen = READ_REG(spi->ECR);
210     if(templen  == 0)
211         templen = 32;
212     if (templen > 8)
213         WRITE_REG(spi->TDR, data >> 8);
214     if (templen > 16)
215         WRITE_REG(spi->TDR, data >> 16);
216     if (templen > 24)
217         WRITE_REG(spi->TDR, data >> 24);
218     __asm volatile("cpsie i");
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 /// @brief  Returns the most recent received data by the spi peripheral.
223 /// @param  spi: Select the SPI peripheral.
224 ///         This parameter can be one of the following values:
225 ///         SPI1, SPI2.
226 /// @retval The value of the received data.
227 ////////////////////////////////////////////////////////////////////////////////
SPI_ReceiveData(SPI_TypeDef * spi)228 u32 SPI_ReceiveData(SPI_TypeDef* spi)
229 {
230     u32 temp;
231     u8 templen;
232     __asm volatile("cpsid i");
233 
234     temp = READ_REG(spi->RDR);
235 
236     templen = READ_REG(spi->ECR);
237     if(templen  == 0)
238         templen = 32;
239     if (templen > 8)
240         temp |= (u32)(READ_REG(spi->RDR) << 8);
241     if (templen > 16)
242         temp |= (u32)(READ_REG(spi->RDR) << 16);
243     if (templen > 24)
244         temp |= (u32)(READ_REG(spi->RDR) << 24);
245 
246     __asm volatile("cpsie i");
247 
248     return temp;
249 }
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 /// @brief  Slave chip csn single by selected
253 /// @param  spi: Select the SPI peripheral.
254 ///         This parameter can be one of the following values:
255 ///         SPI1, SPI2.
256 /// @param  state: new state of the selected SPI CS pin
257 ///         request.
258 ///         This parameter can be: ENABLE or DISABLE.
259 /// @retval None.
260 ////////////////////////////////////////////////////////////////////////////////
SPI_CSInternalSelected(SPI_TypeDef * spi,FunctionalState state)261 void SPI_CSInternalSelected(SPI_TypeDef* spi, FunctionalState state)
262 {
263     (state) ? CLEAR_BIT(spi->NSSR, SPI_NSSR_NSS) : SET_BIT(spi->NSSR, SPI_NSSR_NSS);  // illogical
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 /// @brief  Configures the NSS pin control mode for the selected SPI.
268 /// @param  spi: Select the SPI peripheral.
269 ///         This parameter can be one of the following values:
270 ///         SPI1, SPI2.
271 /// @param  nss: specifies the SPI NSS internal state.
272 ///         This parameter can be one of the following values:
273 /// @arg    SPI_NSS_Soft: NSS pin control by software
274 /// @arg    SPI_NSS_Hard: NSS pin control by hardware
275 /// @retval None.
276 ////////////////////////////////////////////////////////////////////////////////
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * spi,SPI_NSS_TypeDef nss)277 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* spi, SPI_NSS_TypeDef nss)
278 {
279     (nss != SPI_NSS_Soft) ? SET_BIT(spi->GCR, SPI_NSS_Hard) : CLEAR_BIT(spi->GCR, SPI_NSS_Hard);
280 }
281 
282 ////////////////////////////////////////////////////////////////////////////////
283 /// @brief  Configures the data size for the selected SPI.
284 /// @param  spi: Select the SPI peripheral.
285 ///         This parameter can be one of the following values:
286 ///         SPI1, SPI2.
287 /// @param  data_size: specifies the SPI data size.
288 ///         This parameter can be one of the following values:
289 ///         0 to 31, 0 = 32b, 1 = 1b, 2 = 2b
290 /// @arg    DataSize : 0 to 31
291 /// @retval None.
292 /// @retval None.
SPI_DataSizeConfig(SPI_TypeDef * spi,u8 data_size)293 bool SPI_DataSizeConfig(SPI_TypeDef* spi, u8 data_size)
294 {
295     if (data_size > 32)
296         return false;
297     data_size &= 0x1F;
298     WRITE_REG(spi->ECR, data_size);
299     return true;
300 }
301 
302 //////////////////////////////////////////////////////////////////////////////////
SPI_DataSizeTypeConfig(SPI_TypeDef * spi,SPI_DataSize_TypeDef SPI_DataSize)303 void SPI_DataSizeTypeConfig(SPI_TypeDef* spi, SPI_DataSize_TypeDef SPI_DataSize)
304 {
305     CLEAR_BIT(spi->GCR, (u32)SPI_DataSize_32b);
306     SET_BIT(spi->GCR, (u32)SPI_DataSize);
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// @brief  Selects the data transfer direction in bi-directional mode
311 ///         for the specified SPI.
312 /// @param spi: Select the SPI peripheral.
313 ///         This parameter can be one of the following values:
314 ///         SPI1, SPI2.
315 /// @param direction: specifies the data transfer direction in
316 ///         bi-directional mode.
317 ///         This parameter can be one of the following values:
318 /// @arg    SPI_Direction_Tx: Selects Tx transmission direction
319 /// @arg    SPI_Direction_Rx: Selects Rx receive direction
320 /// @arg    SPI_Disable_Tx: Selects Rx receive direction
321 /// @arg    SPI_Disable_Rx: Selects Rx receive direction
322 /// @retval None.
323 ////////////////////////////////////////////////////////////////////////////////
SPI_BiDirectionalLineConfig(SPI_TypeDef * spi,SPI_Direction_TypeDef direction)324 void SPI_BiDirectionalLineConfig(SPI_TypeDef* spi, SPI_Direction_TypeDef direction)
325 {
326     switch (direction) {
327         case SPI_Direction_Rx:
328             SET_BIT(spi->GCR, SPI_GCR_RXEN);
329             break;
330         case SPI_Direction_Tx:
331             SET_BIT(spi->GCR, SPI_GCR_TXEN);
332             break;
333         case SPI_Disable_Rx:
334             CLEAR_BIT(spi->GCR, SPI_GCR_RXEN);
335             break;
336         case SPI_Disable_Tx:
337             CLEAR_BIT(spi->GCR, SPI_GCR_TXEN);
338             break;
339         default:
340             break;
341     }
342 }
343 
344 ////////////////////////////////////////////////////////////////////////////////
345 /// @brief  Checks whether the specified SPI flag is set or not.
346 /// @param  spi: Select the SPI peripheral.
347 ///         This parameter can be one of the following values:
348 ///         SPI1, SPI2.
349 /// @param  flag: specifies the SPI flag to check.
350 ///         This parameter can be one of the following values:
351 /// @arg    SPI_FLAG_RXAVL: Rx buffer has bytes flag
352 /// @arg    SPI_FLAG_TXEPT: Tx buffer and tx shifter empty flag
353 /// @arg    SPI_FLAG_TXFULL: Tx buffer full flag
354 /// @arg    SPI_FLAG_RXAVL_4BYTE: Receive available 4 byte data message flag.
355 /// @retval The new state of SPI_FLAG (SET or RESET).
356 ////////////////////////////////////////////////////////////////////////////////
SPI_GetFlagStatus(SPI_TypeDef * spi,SPI_FLAG_TypeDef flag)357 FlagStatus SPI_GetFlagStatus(SPI_TypeDef* spi, SPI_FLAG_TypeDef flag)
358 {
359 //    u8 number;
360     return (spi->SR & flag) ? SET : RESET;
361 //  if (spi->ECR == 8 || spi->ECR == 0)
362 //      return (spi->SR & SPI_FLAG) ? SET : RESET;
363 //  else {
364 //      if ((spi->ECR > 0) && (spi->ECR <= 8))
365 //          number = 1;
366 //      else if ((spi->ECR) <= 16)
367 //          number = 2;
368 //      else if ((spi->ECR) <= 24)
369 //          number = 3;
370 //      else if (((spi->ECR) <= 31) || (spi->ECR == 0))
371 //          number = 4;
372 //      return (((spi->SR & 0xf00) >> 8) >= number) ? SET : RESET;
373 //  }
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// @brief  Checks whether the specified SPI interrupt has occurred or not.
378 /// @param  spi: Select the SPI peripheral.
379 ///         This parameter can be one of the following values:
380 ///         SPI1, SPI2.
381 /// @param  interrupt: specifies the SPI interrupt source to check.
382 ///         This parameter can be one of the following values:
383 /// @arg    SPI_IT_TX: Tx buffer empty interrupt
384 /// @arg    SPI_IT_RX: Rx buffer  interrupt
385 /// @arg    SPI_IT_UNDERRUN: under Error interrupt in slave mode
386 /// @arg    SPI_IT_RXOVER: RX OVER Error interrupt
387 /// @arg    SPI_IT_RXMATCH: spectials rx data numbers  interrupt
388 /// @arg    SPI_IT_RXFULL: Rx buffer full interrupt
389 /// @arg    SPI_IT_TXEPT: Tx buffer  and tx shifter empty interrupt
390 /// @retval The new state of SPI_IT (SET or RESET).
391 ////////////////////////////////////////////////////////////////////////////////
SPI_GetITStatus(SPI_TypeDef * spi,SPI_IT_TypeDef interrupt)392 ITStatus SPI_GetITStatus(SPI_TypeDef* spi, SPI_IT_TypeDef interrupt)
393 {
394     return (spi->ISR & interrupt) ? SET : RESET;
395 }
396 
397 ////////////////////////////////////////////////////////////////////////////////
398 /// @brief  Clears the spi  interrupt pending bit.
399 /// @param  spi: Select the SPI peripheral.
400 ///         This parameter can be one of the following values:
401 ///         SPI1, SPI2.
402 /// @param  interrupt: specifies the SPI interrupt pending bit to clear.
403 /// @arg    SPI_IT_TX: Tx buffer empty interrupt
404 /// @arg    SPI_IT_RX: Rx buffer  interrupt
405 /// @arg    SPI_IT_UNDERRUN: under Error interrupt in slave mode
406 /// @arg    SPI_IT_RXOVER: RX OVER Error interrupt
407 /// @arg    SPI_IT_RXMATCH: spectials rx data numbers  interrupt
408 /// @arg    SPI_IT_RXFULL: Rx buffer full interrupt
409 /// @arg    SPI_IT_TXEPT: Tx buffer  and tx shifter empty interrupt
410 ///         This function clears only ERR intetrrupt pending bit.
411 /// @retval None.
412 ////////////////////////////////////////////////////////////////////////////////
SPI_ClearITPendingBit(SPI_TypeDef * spi,SPI_IT_TypeDef interrupt)413 void SPI_ClearITPendingBit(SPI_TypeDef* spi, SPI_IT_TypeDef interrupt)
414 {
415     SET_BIT(spi->ICR, interrupt);
416 }
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// @brief  SPI Hole a count Received bytes in next receive process.
420 /// @param  spi: Select the SPI peripheral.
421 ///         This parameter can be one of the following values:
422 ///         SPI1, SPI2.
423 /// @param  number: specifies the SPI receive Number.
424 ///         This parament can be 1-65535.
425 ///         This function can use only in SPI master single receive mode.
426 /// @retval None.
427 ////////////////////////////////////////////////////////////////////////////////
SPI_RxBytes(SPI_TypeDef * spi,u16 number)428 void SPI_RxBytes(SPI_TypeDef* spi, u16 number)
429 {
430     WRITE_REG(spi->RDNR, number);
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////
434 /// @brief  slave mode tx data transmit phase adjust set.
435 /// @param  spi: Select the SPI peripheral.
436 ///         This parameter can be one of the following values:
437 ///         SPI1, SPI2.
438 /// @param  adjust_value: slave mode tx data transmit phase adjust enum.
439 ///         This parament can be :
440 ///         SPI_SlaveAdjust_FAST:  fast speed use
441 ///         SPI_SlaveAdjust_LOW:   low speed use
442 ///         This function can use only in SPI master single receive mode.
443 /// @retval None.
444 ////////////////////////////////////////////////////////////////////////////////
SPI_SlaveAdjust(SPI_TypeDef * spi,SPI_SlaveAdjust_TypeDef adjust_value)445 void SPI_SlaveAdjust(SPI_TypeDef* spi, SPI_SlaveAdjust_TypeDef adjust_value)
446 {
447     (adjust_value) ? SET_BIT(spi->CCR, SPI_CCR_RXEDGE) : CLEAR_BIT(spi->CCR, SPI_CCR_RXEDGE);
448 }
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 /// @brief  Enables or disables all SPI interrupts.
452 /// @param  spi: Select the SPI peripheral.
453 ///         This parameter can be one of the following values:
454 ///         SPI1, SPI2.
455 /// @param  state: new state of all spi interrupts.
456 ///         This parameter can be: ENABLE or DISABLE.
457 /// @retval None.
458 ////////////////////////////////////////////////////////////////////////////////
exSPI_ITCmd(SPI_TypeDef * spi,FunctionalState state)459 void exSPI_ITCmd(SPI_TypeDef* spi, FunctionalState state)
460 {
461     (state) ? SET_BIT(spi->IER, (u32)SPI_GCR_IEN) : CLEAR_BIT(spi->IER, (u32)SPI_GCR_IEN);
462 }
463 
464 ////////////////////////////////////////////////////////////////////////////////
465 /// @brief  Enables or disables the specified SPI interrupts.
466 /// @param  spi: Select the SPI peripheral.
467 ///         This parameter can be one of the following values:
468 ///         SPI1, SPI2.
469 /// @param  interrupt: specifies the SPI interrupt sources to be enabled or disabled.
470 ///         This parameter can be one of the following values:
471 /// @arg    SPI_IT_TXEPT: Transmitter empty interrupt
472 /// @arg    SPI_IT_RXFULL: RX FIFO full interrupt
473 /// @arg    SPI_IT_RXMATCH: Receive data match the RXDNR number interrupt
474 /// @arg    SPI_IT_RXOERR: Receive overrun error interrupt
475 /// @arg    SPI_IT_UNDERRUN: underrun interrupt
476 /// @arg    SPI_IT_RX: Receive data available interrupt
477 /// @arg    SPI_IT_TX: Transmit FIFO available interrupt
478 /// @param  state: new state of the specified spi interrupts.
479 ///         This parameter can be: ENABLE or DISABLE.
480 /// @retval None.
481 ////////////////////////////////////////////////////////////////////////////////
exSPI_ITConfig(SPI_TypeDef * spi,SPI_IT_TypeDef interrupt,FunctionalState state)482 void exSPI_ITConfig(SPI_TypeDef* spi, SPI_IT_TypeDef interrupt, FunctionalState state)
483 {
484     (state) ? SET_BIT(spi->IER, (u32)interrupt) : CLEAR_BIT(spi->IER, (u32)interrupt);
485 }
486 ////////////////////////////////////////////////////////////////////////////////
487 /// @brief  Enables or disables the SPI DMA request.
488 /// @param  spi: Select the SPI peripheral.
489 ///         This parameter can be one of the following values:
490 ///         SPI1, SPI2.
491 /// @param  state: new state of the DMA Request.
492 ///         This parameter can be: ENABLE or DISABLE.
493 /// @retval None.
494 ////////////////////////////////////////////////////////////////////////////////
exSPI_DMACmd(SPI_TypeDef * spi,FunctionalState state)495 void exSPI_DMACmd(SPI_TypeDef* spi, FunctionalState state)
496 {
497     (state) ? SET_BIT(spi->GCR, SPI_GCR_DMAEN) : CLEAR_BIT(spi->GCR, SPI_GCR_DMAEN);
498 }
499 ////////////////////////////////////////////////////////////////////////////////
500 /// @brief  Set or reset Slave chip csn signal output
501 /// @param  spi: Select the SPI peripheral.
502 ///         This parameter can be one of the following values:
503 ///         SPI1, SPI2.
504 /// @param  state: new state of Slave chip csn signal output.
505 ///         This parameter can be: ENABLE or DISABLE.
506 /// @retval None.
507 ////////////////////////////////////////////////////////////////////////////////
exSPI_CSInternalSelected(SPI_TypeDef * spi,FunctionalState state)508 void exSPI_CSInternalSelected(SPI_TypeDef* spi, FunctionalState state)
509 {
510     (state) ? CLEAR_BIT(spi->NSSR, SPI_NSSR_NSS) : SET_BIT(spi->NSSR, SPI_NSSR_NSS);  // illogical
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// @brief  tx data and rx data phase adjust.
515 /// @param  spi: Select the SPI peripheral.
516 ///         This parameter can be one of the following values:
517 ///         SPI1, SPI2.
518 /// @param  adjust_value: choose adjust mode.
519 ///         This parament can be :
520 ///         SPI_DataEdgeAdjust_LOW,
521 ///         SPI_DataEdgeAdjust_FAST
522 /// @retval None.
523 ////////////////////////////////////////////////////////////////////////////////
exSPI_DataEdgeAdjust(SPI_TypeDef * spi,SPI_DataEdgeAdjust_TypeDef adjust_value)524 void exSPI_DataEdgeAdjust(SPI_TypeDef* spi, SPI_DataEdgeAdjust_TypeDef adjust_value)
525 {
526     // master mode
527     if (spi->GCR & SPI_GCR_MODE) {
528         adjust_value ? SET_BIT(spi->CCR, SPI_CCR_RXEDGE) : CLEAR_BIT(spi->CCR, SPI_CCR_RXEDGE);
529     }
530     // slave mode
531     else {
532         adjust_value ? SET_BIT(spi->CCR, SPI_CCR_TXEDGE) : CLEAR_BIT(spi->CCR, SPI_CCR_TXEDGE);
533     }
534 }
535 ////////////////////////////////////////////////////////////////////////////////
536 /// @brief  Set or reset i2s
537 /// @param  spi: Select the SPI peripheral.
538 ///         This parameter can be one of the following values:
539 ///         SPI1, SPI2, SPI3.
540 /// @param  state: new state of Slave chip csn signal output.
541 ///         This parameter can be: ENABLE or DISABLE.
542 /// @retval None.
543 ////////////////////////////////////////////////////////////////////////////////
I2S_Cmd(SPI_TypeDef * spi,FunctionalState state)544 void I2S_Cmd(SPI_TypeDef* spi, FunctionalState state)
545 {
546     (state) ? SET_BIT(spi->CFGR, I2S_CFGR_SPI_I2S) : CLEAR_BIT(spi->CFGR, I2S_CFGR_SPI_I2S);
547 }
548 ////////////////////////////////////////////////////////////////////////////////
549 /// @brief  i2s Config
550 /// @param  spi: Select the SPI peripheral.
551 ///         This parameter can be one of the following values:
552 ///         SPI1, SPI2, SPI3.
553 /// @param  state: new state of Slave chip csn signal output.
554 ///         This parameter can be: ENABLE or DISABLE.
555 /// @retval None.
556 ////////////////////////////////////////////////////////////////////////////////
I2S_Init(SPI_TypeDef * spi,I2S_InitTypeDef * I2S_InitStruct)557 void I2S_Init(SPI_TypeDef* spi, I2S_InitTypeDef* I2S_InitStruct)
558 {
559     u32 i2sdiv = 2;
560     u32 tmpreg = 0;
561     u32 packetlength = 1;
562     u32 result = 0, yushu = 0;
563     u32 sourceclock = 0;
564     RCC_ClocksTypeDef RCC_Clocks;
565 
566     if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) {
567         i2sdiv = 2;
568     }
569     else {
570         if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) {
571             packetlength = 1;
572         }
573         else {
574             packetlength = 2;
575         }
576         RCC_GetClocksFreq(&RCC_Clocks);
577 
578         if((SPI2 == spi) || (SPI3 == spi))  {
579             sourceclock = RCC_Clocks.PCLK1_Frequency;
580         }
581         else {
582             sourceclock = RCC_Clocks.PCLK2_Frequency;
583         }
584         if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) {
585             result = (sourceclock) / (256 * (I2S_InitStruct->I2S_AudioFreq));
586             yushu = (sourceclock) % (256 * (I2S_InitStruct->I2S_AudioFreq));
587             if(yushu > (128 * (I2S_InitStruct->I2S_AudioFreq))) {
588                 result = result + 1;
589             }
590             i2sdiv = result;
591             if ((i2sdiv < 2) || (i2sdiv > 0x1FF)) {
592                 i2sdiv = 2;
593             }
594         }
595         else {
596             result = (sourceclock) / (16 * 2 * packetlength * (I2S_InitStruct->I2S_AudioFreq));
597             yushu = (sourceclock) % (16 * 2 * packetlength * (I2S_InitStruct->I2S_AudioFreq));
598             if(yushu > ((16 * packetlength * (I2S_InitStruct->I2S_AudioFreq)))) {
599                 result = result + 1;
600             }
601             if ((i2sdiv < 1) || (i2sdiv > 0x1FF)) {
602                 i2sdiv = 1;
603             }
604         }
605     }
606     if(I2S_CPOL_High  == I2S_InitStruct->I2S_CPOL) {
607         spi->CCTL |= SPI_CCR_CPOL;
608     }
609     else {
610         spi->CCTL &= ~SPI_CCR_CPOL;
611     }
612 
613     spi->CFGR = 0x2 << I2S_CFGR_I2SDIV_Pos;
614 
615     if((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_MasterRx)) {
616         spi->GCTL |= SPI_GCR_MODE;
617     }
618     else {
619         spi->GCTL &= ~SPI_GCR_MODE;
620     }
621     if((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveTx)) {
622         spi->GCTL |= SPI_GCR_TXEN;
623         spi->GCTL &= ~SPI_GCR_RXEN;
624     }
625     else {
626         spi->GCTL &= ~SPI_GCR_TXEN;
627         spi->GCTL |= SPI_GCR_RXEN;
628     }
629 //    tmpreg = spi->GCTL;
630 //    tmpreg &= ~(1 << 2);
631 //    tmpreg |= (u16)(I2S_InitStruct->I2S_Mode);
632 //    spi->GCTL = tmpreg;
633 //
634     tmpreg = 0;
635     tmpreg |= (i2sdiv << I2S_CFGR_I2SDIV_Pos) | \
636               (I2S_InitStruct->I2S_MCLKOutput) | \
637               (I2S_CFGR_SPI_I2S) | \
638               (I2S_InitStruct->I2S_Standard) | \
639               (I2S_InitStruct->I2S_DataFormat);
640     spi->CFGR &= ~I2S_CFGR_I2SDIV;
641     spi->CFGR |= tmpreg;
642 
643 }
644 /// @}
645 
646 /// @}
647 
648 /// @}
649