1 /*********************************************************************************************************//**
2  * @file    ht32f5xxxx_spi.c
3  * @version $Rev:: 7674         $
4  * @date    $Date:: 2024-03-28 #$
5  * @brief   This file provides all the SPI firmware functions.
6  *************************************************************************************************************
7  * @attention
8  *
9  * Firmware Disclaimer Information
10  *
11  * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
12  *    code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
13  *    proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
14  *    other intellectual property laws.
15  *
16  * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
17  *    code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
18  *    other than HOLTEK and the customer.
19  *
20  * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
21  *    only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
22  *    the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
23  *    the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
24  *
25  * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
26  ************************************************************************************************************/
27 
28 /* Includes ------------------------------------------------------------------------------------------------*/
29 #include "ht32f5xxxx_spi.h"
30 
31 /** @addtogroup HT32F5xxxx_Peripheral_Driver HT32F5xxxx Peripheral Driver
32   * @{
33   */
34 
35 /** @defgroup SPI SPI
36   * @brief SPI driver modules
37   * @{
38   */
39 
40 
41 #if (LIBCFG_MIDI)
42 #include "ht32f5xxxx_spi_midi.c"
43 #endif
44 
45 /* Private constants ---------------------------------------------------------------------------------------*/
46 /** @defgroup SPI_Private_Define SPI private definitions
47   * @{
48   */
49 /* SPI SPIEN Mask                                                                                           */
50 #define CR0_SPIEN_SET       (u32)0x00000001
51 #define CR0_SPIEN_RESET     (u32)0xFFFFFFFE
52 
53 /* SPI SELOEN Mask                                                                                          */
54 #define CR0_SELOEN_SET      (u32)0x00000008
55 #define CR0_SELOEN_RESET    (u32)0xFFFFFFF7
56 
57 /* SPI SPI DUALEN Mask                                                                                      */
58 #define CR0_DUALEN_SET      (u32)0x00000040
59 #define CR0_DUALEN_RESET    (u32)0xFFFFFFBF
60 
61 #if (LIBCFG_QSPI)
62 /* QSPI QUADEN Mask                                                                                         */
63 #define CR0_QUADEN_SET      (u32)0x00020000
64 #define CR0_QUADEN_RESET    (u32)0xFFFDFFFF
65 /* QSPI QDIODIR Mask                                                                                        */
66 #define CR0_QDIODIR_OUT     (u32)0x00010000
67 #define CR0_QDIODIR_IN      (u32)0xFFFEFFFF
68 #endif
69 
70 /* SPI SPI GUADTEN Mask                                                                                     */
71 #define CR0_GUADTEN_SET     (u32)0x00000080
72 #define CR0_GUADTEN_RESET   (u32)0xFFFFFF7F
73 
74 /* SPI FIFOEN Mask                                                                                          */
75 #define FCR_FIFOEN_SET      (u32)0x00000400
76 #define FCR_FIFOEN_RESET    (u32)0xFFFFFBFF
77 
78 /* SPI DFL Mask                                                                                             */
79 #if (LIBCFG_SPI_DATA_LENGTH_V01)
80 #define CR1_DFL_MASK        (u32)0x00000007
81 #else
82 #define CR1_DFL_MASK        (u32)0x0000000F
83 #endif
84 
85 /* SPI FIFO Mask                                                                                            */
86 #if (LIBCFG_SPI_FIFO_DEPTH_V01)
87 #define FCR_FIFO_MASK        (u32)0x00000007
88 #else
89 #define FCR_FIFO_MASK        (u32)0x0000000F
90 #endif
91 
92 /**
93   * @}
94   */
95 
96 
97 /* Global functions ----------------------------------------------------------------------------------------*/
98 /** @defgroup SPI_Exported_Functions SPI exported functions
99   * @{
100   */
101 /*********************************************************************************************************//**
102  * @brief Deinitialize the SPI peripheral registers to their default reset values.
103  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
104  * @retval None
105  ************************************************************************************************************/
SPI_DeInit(HT_SPI_TypeDef * SPIx)106 void SPI_DeInit(HT_SPI_TypeDef* SPIx)
107 {
108   RSTCU_PeripReset_TypeDef RSTCUReset = {{0}};
109 
110   /* Check the parameters                                                                                   */
111   Assert_Param(IS_SPI(SPIx));
112 
113   if (SPIx == HT_SPI0)
114   {
115     RSTCUReset.Bit.SPI0 = 1;
116   }
117   #if (LIBCFG_SPI1)
118   else if (SPIx == HT_SPI1)
119   {
120     RSTCUReset.Bit.SPI1 = 1;
121   }
122   #endif
123   #if (LIBCFG_QSPI)
124   else if (SPIx == HT_QSPI)
125   {
126     RSTCUReset.Bit.QSPI = 1;
127   }
128   #endif
129   RSTCU_PeripReset(RSTCUReset, ENABLE);
130 }
131 
132 /*********************************************************************************************************//**
133  * @brief Initialize the SPIx peripheral according to the specified parameters in the SPI_InitStruct.
134  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
135  * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure.
136  * @retval None
137  ************************************************************************************************************/
SPI_Init(HT_SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)138 void SPI_Init(HT_SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
139 {
140   u32 tmp;
141 
142   /* Check the parameters                                                                                   */
143   Assert_Param(IS_SPI(SPIx));
144   Assert_Param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
145   Assert_Param(IS_SPI_FIFO_SET(SPI_InitStruct->SPI_FIFO));
146   Assert_Param(IS_SPI_DATALENGTH(SPI_InitStruct->SPI_DataLength));
147   Assert_Param(IS_SPI_SEL_MODE(SPI_InitStruct->SPI_SELMode));
148   Assert_Param(IS_SPI_SEL_POLARITY(SPI_InitStruct->SPI_SELPolarity));
149   Assert_Param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
150   Assert_Param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
151   Assert_Param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
152   Assert_Param(IS_SPI_FIFO_LEVEL(SPI_InitStruct->SPI_RxFIFOTriggerLevel));
153   Assert_Param(IS_SPI_FIFO_LEVEL(SPI_InitStruct->SPI_TxFIFOTriggerLevel));
154   Assert_Param(IS_SPI_CLOCK_PRESCALER(SPI_InitStruct->SPI_ClockPrescaler));
155 
156   /*---------------------------- SPIx Control Register 2 Configuration -------------------------------------*/
157   tmp =  SPI_InitStruct->SPI_CPOL;
158   if (tmp == SPI_CPOL_LOW)
159   {
160     tmp |= (0x100 << SPI_InitStruct->SPI_CPHA);
161   }
162   else
163   {
164     tmp |= (0x200 >> SPI_InitStruct->SPI_CPHA);
165   }
166 
167   SPIx->CR1 = SPI_InitStruct->SPI_Mode |  SPI_InitStruct->SPI_DataLength |
168               SPI_InitStruct->SPI_SELMode | SPI_InitStruct->SPI_SELPolarity |
169               SPI_InitStruct->SPI_FirstBit | tmp;
170 
171   /*---------------------------- SPIx FIFO Control Register Configuration ----------------------------------*/
172   SPIx->FCR = SPI_InitStruct->SPI_FIFO | SPI_InitStruct->SPI_TxFIFOTriggerLevel |
173              (SPI_InitStruct->SPI_RxFIFOTriggerLevel << 4);
174 
175   /*---------------------------- SPIx Clock Prescaler Register Configuration -------------------------------*/
176   #if (LIBCFG_SPI_CLK_PRE_V01)
177   SPIx->CPR = (SPI_InitStruct->SPI_ClockPrescaler - 1);
178   #else
179   SPIx->CPR = (SPI_InitStruct->SPI_ClockPrescaler / 2) - 1;
180   #endif
181 }
182 
183 /*********************************************************************************************************//**
184  * @brief Fill each SPI_InitStruct member with its default value.
185  * @param SPI_InitStruct: pointer to an SPI_InitTypeDef structure.
186  * @retval None
187  ************************************************************************************************************/
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)188 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
189 {
190   /* Initialize the SPI_Mode member                                                                         */
191   SPI_InitStruct->SPI_Mode = SPI_SLAVE;
192 
193   /* Initialize the SPI_FIFO member                                                                         */
194   SPI_InitStruct->SPI_FIFO = SPI_FIFO_DISABLE;
195 
196   /* Initialize the SPI_DataLength member                                                                   */
197   #if (LIBCFG_SPI_DATA_LENGTH_V01)
198   SPI_InitStruct->SPI_DataLength = SPI_DATALENGTH_8;
199   #else
200   SPI_InitStruct->SPI_DataLength = SPI_DATALENGTH_16;
201   #endif
202 
203   /* Initialize the SPI_SELMode member                                                                      */
204   SPI_InitStruct->SPI_SELMode = SPI_SEL_SOFTWARE;
205 
206   /* Initialize the SPI_SELPolarity member                                                                  */
207   SPI_InitStruct->SPI_SELPolarity = SPI_SELPOLARITY_LOW;
208 
209   /* Initialize the SPI_CPOL member                                                                         */
210   SPI_InitStruct->SPI_CPOL = SPI_CPOL_LOW;
211 
212   /* Initialize the SPI_CPHA member                                                                         */
213   SPI_InitStruct->SPI_CPHA = SPI_CPHA_FIRST;
214 
215   /* Initialize the SPI_FirstBit member                                                                     */
216   SPI_InitStruct->SPI_FirstBit = SPI_FIRSTBIT_MSB;
217 
218   /* Initialize the SPI_RxFIFOTriggerLevel member                                                           */
219   SPI_InitStruct->SPI_RxFIFOTriggerLevel = 0;
220 
221   /* Initialize the SPI_TxFIFOTriggerLevel member                                                           */
222   SPI_InitStruct->SPI_TxFIFOTriggerLevel = 0;
223 
224   /* Initialize the SPI_ClockPrescaler member                                                               */
225   SPI_InitStruct->SPI_ClockPrescaler = 2;
226 }
227 
228 /*********************************************************************************************************//**
229  * @brief Enable or Disable the specified SPI peripheral.
230  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
231  * @param NewState: This parameter can be ENABLE or DISABLE.
232  * @retval None
233  ************************************************************************************************************/
SPI_Cmd(HT_SPI_TypeDef * SPIx,ControlStatus NewState)234 void SPI_Cmd(HT_SPI_TypeDef* SPIx, ControlStatus NewState)
235 {
236   /* Check the parameters                                                                                   */
237   Assert_Param(IS_SPI(SPIx));
238   Assert_Param(IS_CONTROL_STATUS(NewState));
239 
240   if (NewState != DISABLE)
241   {
242     /* Enable the selected SPI peripheral                                                                   */
243     SPIx->CR0 |= CR0_SPIEN_SET;
244   }
245   else
246   {
247     /* Disable the selected SPI peripheral                                                                  */
248     SPIx->CR0 &= CR0_SPIEN_RESET;
249   }
250 }
251 
252 #if (!LIBCFG_SPI_NO_MULTI_MASTER)
253 /*********************************************************************************************************//**
254  * @brief Enable or Disable the SEL output for the specified SPI peripheral.
255  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
256  * @param NewState: This parameter can be ENABLE or DISABLE.
257  * @retval None
258  ************************************************************************************************************/
SPI_SELOutputCmd(HT_SPI_TypeDef * SPIx,ControlStatus NewState)259 void SPI_SELOutputCmd(HT_SPI_TypeDef* SPIx, ControlStatus NewState)
260 {
261   /* Check the parameters                                                                                   */
262   Assert_Param(IS_SPI(SPIx));
263   Assert_Param(IS_CONTROL_STATUS(NewState));
264 
265   if (NewState != DISABLE)
266   {
267     SPIx->CR0 |= CR0_SELOEN_SET;
268   }
269   else
270   {
271     SPIx->CR0 &= CR0_SELOEN_RESET;
272   }
273 }
274 #endif
275 
276 /*********************************************************************************************************//**
277  * @brief Enable or Disable SPI FIFO.
278  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
279  * @param NewState: This parameter can be ENABLE or DISABLE.
280  * @retval None
281  ************************************************************************************************************/
SPI_FIFOCmd(HT_SPI_TypeDef * SPIx,ControlStatus NewState)282 void SPI_FIFOCmd(HT_SPI_TypeDef* SPIx, ControlStatus NewState)
283 {
284   /* Check the parameters                                                                                   */
285   Assert_Param(IS_SPI(SPIx));
286   Assert_Param(IS_CONTROL_STATUS(NewState));
287 
288   if (NewState != DISABLE)
289   {
290     SPIx->FCR |= FCR_FIFOEN_SET;
291   }
292   else
293   {
294     SPIx->FCR &= FCR_FIFOEN_RESET;
295   }
296 }
297 
298 /*********************************************************************************************************//**
299  * @brief Configure the data length for the selected SPI.
300  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
301  * @param SPI_DataLength: specify data length of the SPI.
302  * @retval None
303  ************************************************************************************************************/
SPI_SetDataLength(HT_SPI_TypeDef * SPIx,u16 SPI_DataLength)304 void SPI_SetDataLength(HT_SPI_TypeDef* SPIx, u16 SPI_DataLength)
305 {
306   /* Check the parameters                                                                                   */
307   Assert_Param(IS_SPI(SPIx));
308   Assert_Param(IS_SPI_DATALENGTH(SPI_DataLength));
309 
310   /* Clear DFL[x:0] in CR1.
311      if Datalength is 16-bit mode, then x = 3
312      if Datalength is 8-bit mode, then x = 2                                                                */
313   SPIx->CR1 &= (u32)~CR1_DFL_MASK;
314 
315   /* Set new DFL[x:0] in CR1.
316      if Datalength is 16-bit mode, then x = 3
317      if Datalength is 8-bit mode, then x = 2                                                                */
318   SPIx->CR1 |= SPI_DataLength;
319 }
320 
321 /*********************************************************************************************************//**
322  * @brief SEL pin is configured to be driven by hardware or software.
323  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
324  * @param SPI_SEL: specify the SPI SEL pin mode.
325  *   This parameter can be one of the following values:
326  *     @arg SPI_SEL_HARDWARE : SEL is driven by hardware
327  *     @arg SPI_SEL_SOFTWARE : SEL is driven by software
328  * @retval None
329  ************************************************************************************************************/
SPI_SELModeConfig(HT_SPI_TypeDef * SPIx,u32 SPI_SEL)330 void SPI_SELModeConfig(HT_SPI_TypeDef* SPIx, u32 SPI_SEL)
331 {
332   /* Check the parameters                                                                                   */
333   Assert_Param(IS_SPI(SPIx));
334   Assert_Param(IS_SPI_SEL_MODE(SPI_SEL));
335 
336   if (SPI_SEL != SPI_SEL_SOFTWARE)
337   {
338     SPIx->CR1 |= SPI_SEL_HARDWARE;
339   }
340   else
341   {
342     SPIx->CR1 &= ~SPI_SEL_HARDWARE;
343   }
344 }
345 
346 /*********************************************************************************************************//**
347  * @brief Configure the SEL state by software.
348  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
349  * @param SPI_SoftwareSEL: specify if the SPI SEL to be active or inactive.
350  *   This parameter can be one of the following values:
351  *     @arg SPI_SEL_ACTIVE   : activate SEL signal
352  *     @arg SPI_SEL_INACTIVE : deactivate SEL signal
353  * @retval None
354  ************************************************************************************************************/
SPI_SoftwareSELCmd(HT_SPI_TypeDef * SPIx,u32 SPI_SoftwareSEL)355 void SPI_SoftwareSELCmd(HT_SPI_TypeDef* SPIx, u32 SPI_SoftwareSEL)
356 {
357   /* Check the parameters                                                                                   */
358   Assert_Param(IS_SPI(SPIx));
359   Assert_Param(IS_SPI_SOFTWARE_SEL(SPI_SoftwareSEL));
360 
361   if (SPI_SoftwareSEL != SPI_SEL_INACTIVE)
362   {
363     SPIx->CR0 |= SPI_SEL_ACTIVE;
364   }
365   else
366   {
367     /* Inactive SEL pin needs to ensure the transmission has ended. If the program flow cannot guarantee    */
368     /* SPI transmission completion, you can enable the procedure below.                                     */
369     #if 0
370     while (SPIx->SR & SPI_FLAG_BUSY);      /* Wait until SPI NOT BUSY                                       */
371     #endif
372     SPIx->CR0 &= SPI_SEL_INACTIVE;
373   }
374 }
375 
376 /*********************************************************************************************************//**
377  * @brief Send a data through the SPIx peripheral.
378  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
379  * @param SPI_Data: the data to be transmitted.
380  * @retval None
381  ************************************************************************************************************/
SPI_SendData(HT_SPI_TypeDef * SPIx,SPI_DataTypeDef SPI_Data)382 void SPI_SendData(HT_SPI_TypeDef* SPIx, SPI_DataTypeDef SPI_Data)
383 {
384   /* Check the parameters                                                                                   */
385   Assert_Param(IS_SPI(SPIx));
386   Assert_Param(IS_SPI_DATA(SPI_Data));
387 
388   SPIx->DR = SPI_Data;
389 }
390 
391 /*********************************************************************************************************//**
392  * @brief Return the received data through the SPIx peripheral
393  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
394  * @retval The value of the received data.
395  ************************************************************************************************************/
SPI_ReceiveData(HT_SPI_TypeDef * SPIx)396 SPI_DataTypeDef SPI_ReceiveData(HT_SPI_TypeDef* SPIx)
397 {
398   /* Check the parameters                                                                                   */
399   Assert_Param(IS_SPI(SPIx));
400 
401   return (SPI_DataTypeDef)SPIx->DR;
402 }
403 
404 /*********************************************************************************************************//**
405  * @brief Set the value of SPI FIFO Time Out.
406  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
407  * @param SPI_Timeout: specify the value of Time Out.
408  * @retval None
409  ************************************************************************************************************/
SPI_SetTimeOutValue(HT_SPI_TypeDef * SPIx,SPI_TimeoutTypeDef SPI_Timeout)410 void SPI_SetTimeOutValue(HT_SPI_TypeDef* SPIx, SPI_TimeoutTypeDef SPI_Timeout)
411 {
412   /* Check the parameters                                                                                   */
413   Assert_Param(IS_SPI(SPIx));
414 
415   SPIx->FTOCR = SPI_Timeout;
416 }
417 
418 /*********************************************************************************************************//**
419  * @brief Enable or Disable the specified SPI interrupt.
420  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
421  * @param SPI_Int: specify if the SPI interrupt source to be enabled or disabled.
422  *   This parameter can be any combination of the following values:
423  *     @arg SPI_INT_TXBE  : SPI Tx buffer empty interrupt
424  *     @arg SPI_INT_TXE   : SPI Tx empty interrupt
425  *     @arg SPI_INT_RXBNE : SPI Rx buffer not empty interrupt
426  *     @arg SPI_INT_WC    : SPI write collision interrupt
427  *     @arg SPI_INT_RO    : SPI read overrun interrupt
428  *     @arg SPI_INT_MF    : SPI mode fault interrupt
429  *     @arg SPI_INT_SA    : SPI slave abort interrupt
430  *     @arg SPI_INT_TO    : SPI time out interrupt
431  *     @arg SPI_INT_ALL   : All SPI interrupt
432  * @param NewState: This parameter can be ENABLE or DISABLE.
433  * @retval None
434  ************************************************************************************************************/
SPI_IntConfig(HT_SPI_TypeDef * SPIx,u32 SPI_Int,ControlStatus NewState)435 void SPI_IntConfig(HT_SPI_TypeDef* SPIx, u32 SPI_Int, ControlStatus NewState)
436 {
437   /* Check the parameters                                                                                   */
438   Assert_Param(IS_SPI(SPIx));
439   Assert_Param(IS_SPI_INT(SPI_Int));
440   Assert_Param(IS_CONTROL_STATUS(NewState));
441 
442   if (NewState != DISABLE)
443   {
444     SPIx->IER |= SPI_Int;
445   }
446   else
447   {
448     SPIx->IER &= (u32)~SPI_Int;
449   }
450 }
451 
452 /*********************************************************************************************************//**
453  * @brief Check whether the specified SPI flag has been set or not.
454  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
455  * @param SPI_Flag: specify the flag that is to be check.
456  *   This parameter can be one of the following values:
457  *     @arg SPI_FLAG_TXBE  : SPI Tx buffer empty flag
458  *     @arg SPI_FLAG_TXE   : SPI Tx empty flag
459  *     @arg SPI_FLAG_RXBNE : SPI Rx buffer not empty flag
460  *     @arg SPI_FLAG_WC    : SPI write collision flag
461  *     @arg SPI_FLAG_RO    : SPI read overrun flag
462  *     @arg SPI_FLAG_MF    : SPI mode fault flag
463  *     @arg SPI_FLAG_SA    : SPI slave abort flag
464  *     @arg SPI_FLAG_TOUT  : SPI time out flag
465  *     @arg SPI_FLAG_BUSY  : SPI busy flag
466  * @retval SET or RESET
467  ************************************************************************************************************/
SPI_GetFlagStatus(HT_SPI_TypeDef * SPIx,u32 SPI_Flag)468 FlagStatus SPI_GetFlagStatus(HT_SPI_TypeDef* SPIx, u32 SPI_Flag)
469 {
470   FlagStatus bitstatus = RESET;
471   u32 statusreg = 0;
472 
473   /* Check the parameters                                                                                   */
474   Assert_Param(IS_SPI(SPIx));
475   Assert_Param(IS_SPI_FLAG(SPI_Flag));
476 
477   statusreg = SPIx->SR;
478 
479   if ((statusreg & SPI_Flag) != (u32)RESET)
480   {
481     bitstatus = SET;
482   }
483   else
484   {
485     bitstatus = RESET;
486   }
487 
488   return bitstatus;
489 }
490 
491 /*********************************************************************************************************//**
492  * @brief Return the status of specified SPI FIFO.
493  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
494  * @param SPI_FIFODirection: specify the FIFO that is to be checked.
495  *   This parameter can be one of the following values:
496  *     @arg SPI_FIFO_TX :
497  *     @arg SPI_FIFO_RX :
498  * @retval The number of data in Tx FIFO or Rx FIFO.
499  ************************************************************************************************************/
SPI_GetFIFOStatus(HT_SPI_TypeDef * SPIx,u32 SPI_FIFODirection)500 u8 SPI_GetFIFOStatus(HT_SPI_TypeDef* SPIx, u32 SPI_FIFODirection)
501 {
502   u32 tmpreg;
503 
504   /* Check the parameters                                                                                   */
505   Assert_Param(IS_SPI(SPIx));
506   Assert_Param(IS_SPI_FIFO_DIRECTION(SPI_FIFODirection));
507 
508   if (SPI_FIFODirection == SPI_FIFO_TX)
509   {
510     tmpreg = SPIx->FSR & FCR_FIFO_MASK;
511   }
512   else
513   {
514     tmpreg = (SPIx->FSR & (FCR_FIFO_MASK << 4)) >> 4;
515   }
516 
517   return (u8)tmpreg;
518 }
519 
520 /*********************************************************************************************************//**
521  * @brief Clear the specified SPI flag.
522  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
523  * @param SPI_Flag: specify the flag that is to be cleared.
524  *   This parameter can be one of the following values:
525  *     @arg SPI_FLAG_WC   : SPI write collision flag
526  *     @arg SPI_FLAG_RO   : SPI read overrun flag
527  *     @arg SPI_FLAG_MF   : SPI mode fault flag
528  *     @arg SPI_FLAG_SA   : SPI slave abort flag
529  *     @arg SPI_FLAG_TOUT : SPI time out flag
530  * @retval None
531  ************************************************************************************************************/
SPI_ClearFlag(HT_SPI_TypeDef * SPIx,u32 SPI_Flag)532 void SPI_ClearFlag(HT_SPI_TypeDef* SPIx, u32 SPI_Flag)
533 {
534   /* Check the parameters                                                                                   */
535   Assert_Param(IS_SPI(SPIx));
536   Assert_Param(IS_SPI_FLAG_CLEAR(SPI_Flag));
537 
538   SPIx->SR = SPI_Flag;
539 }
540 
541 /*********************************************************************************************************//**
542  * @brief Set the trigger level of SPI FIFO.
543  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
544  * @param SPI_FIFODirection: specify the FIFO that is to be set.
545  *   This parameter can be one of the following values:
546  *     @arg SPI_FIFO_TX :
547  *     @arg SPI_FIFO_RX :
548  * @param SPI_FIFOLevel: Specify the FIFO trigger level.
549  * @retval None
550  ************************************************************************************************************/
SPI_FIFOTriggerLevelConfig(HT_SPI_TypeDef * SPIx,u32 SPI_FIFODirection,u8 SPI_FIFOLevel)551 void SPI_FIFOTriggerLevelConfig(HT_SPI_TypeDef* SPIx, u32 SPI_FIFODirection, u8 SPI_FIFOLevel)
552 {
553   /* Check the parameters                                                                                   */
554   Assert_Param(IS_SPI(SPIx));
555   Assert_Param(IS_SPI_FIFO_DIRECTION(SPI_FIFODirection));
556   Assert_Param(IS_SPI_FIFO_LEVEL(SPI_FIFOLevel));
557 
558   if (SPI_FIFODirection == SPI_FIFO_TX)
559   {
560     SPIx->FCR = ((SPIx->FCR & (0x00000400 | (FCR_FIFO_MASK << 4))) | SPI_FIFOLevel);
561   }
562   else
563   {
564     SPIx->FCR = ((SPIx->FCR & (0x00000400 | FCR_FIFO_MASK)) | (SPI_FIFOLevel << 4));
565   }
566 }
567 
568 #if (LIBCFG_PDMA)
569 /*********************************************************************************************************//**
570  * @brief Enable or Disable the SPIx PDMA interface.
571  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
572  * @param SPI_PDMAREQ: specify the SPI PDMA transfer request to be enabled or disabled.
573  *   This parameter can be any combination of the following values:
574  *     @arg SPI_PDMAREQ_TX : Tx PDMA transfer request
575  *     @arg SPI_PDMAREQ_RX : Rx PDMA transfer request
576  * @param NewState: This parameter can be ENABLE or DISABLE.
577  * @retval None
578  ************************************************************************************************************/
SPI_PDMACmd(HT_SPI_TypeDef * SPIx,u32 SPI_PDMAREQ,ControlStatus NewState)579 void SPI_PDMACmd(HT_SPI_TypeDef* SPIx, u32 SPI_PDMAREQ, ControlStatus NewState)
580 {
581   /* Check the parameters                                                                                   */
582   Assert_Param(IS_SPI(SPIx));
583   Assert_Param(IS_SPI_PDMA_REQ(SPI_PDMAREQ));
584   Assert_Param(IS_CONTROL_STATUS(NewState));
585 
586   if (NewState != DISABLE)
587   {
588     SPIx->CR0 |= SPI_PDMAREQ;
589   }
590   else
591   {
592     SPIx->CR0 &= ~SPI_PDMAREQ;
593   }
594 }
595 #endif
596 
597 #if (!LIBCFG_SPI_NO_DUAL)
598 /*********************************************************************************************************//**
599  * @brief Enable or Disable the SPIx dual port read interface.
600  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
601  * @param NewState: This parameter can be ENABLE or DISABLE.
602  * @retval None
603  ************************************************************************************************************/
SPI_DUALCmd(HT_SPI_TypeDef * SPIx,ControlStatus NewState)604 void SPI_DUALCmd(HT_SPI_TypeDef* SPIx, ControlStatus NewState)
605 {
606   /* Check the parameters                                                                                   */
607   Assert_Param(IS_SPI(SPIx));
608   Assert_Param(IS_CONTROL_STATUS(NewState));
609 
610   while (SPIx->SR & SPI_FLAG_BUSY);      /* Wait until SPI NOT BUSY                                         */
611 
612   (NewState == ENABLE)?(SPIx->CR0 |= CR0_DUALEN_SET):(SPIx->CR0 &= CR0_DUALEN_RESET);
613 }
614 #endif
615 
616 #if (LIBCFG_QSPI)
617 /*********************************************************************************************************//**
618  * @brief Enable or Disable the QSPI quad port interface.
619  * @param SPIx: where SPIx is the selected QSPI from the QSPI peripherals.
620  * @param NewState: This parameter can be ENABLE or DISABLE.
621  * @retval None
622  ************************************************************************************************************/
QSPI_QuadCmd(HT_SPI_TypeDef * SPIx,ControlStatus NewState)623 void QSPI_QuadCmd(HT_SPI_TypeDef* SPIx, ControlStatus NewState)
624 {
625   /* Check the parameters                                                                                   */
626   Assert_Param(IS_QSPI(SPIx));
627   Assert_Param(IS_CONTROL_STATUS(NewState));
628 
629   while (SPIx->SR & SPI_FLAG_BUSY);      /* Wait until SPI NOT BUSY                                         */
630 
631   if (NewState == DISABLE)
632   {
633     QSPI_DirectionConfig(SPIx, SIO_DIR_IN);
634     SPIx->CR0 &= CR0_QUADEN_RESET;
635   }
636   else
637   {
638     SPIx->CR0 |= CR0_QUADEN_SET;
639   }
640 }
641 
642 /*********************************************************************************************************//**
643  * @brief Configure the direction of SIO pins in dual or quad mode.
644  * @param SPIx: where SPIx is the selected QSPI from the QSPI peripherals.
645  * @param SIO_DIR_INorOUT:
646  *   This parameter can be one of below:
647  *     @arg SIO_DIR_IN  : The SIO pins are input mode
648  *     @arg SIO_DIR_OUT : The SIO pins are output mode
649  * @retval None
650  ************************************************************************************************************/
QSPI_DirectionConfig(HT_SPI_TypeDef * SPIx,SIO_DIR_Enum SIO_DIR_INorOUT)651 void QSPI_DirectionConfig(HT_SPI_TypeDef* SPIx, SIO_DIR_Enum SIO_DIR_INorOUT)
652 {
653   /* Check the parameters                                                                                   */
654   Assert_Param(IS_QSPI(SPIx));
655   Assert_Param(IS_SIO_DIR(SIO_DIR_INorOUT));
656 
657   while (SPIx->SR & SPI_FLAG_BUSY);      /* Wait until SPI NOT BUSY                                         */
658 
659   if (SIO_DIR_INorOUT != SIO_DIR_IN)
660     SPIx->CR0 |= CR0_QDIODIR_OUT;
661   else
662     SPIx->CR0 &= CR0_QDIODIR_IN;
663 }
664 #endif
665 
666 /*********************************************************************************************************//**
667  * @brief Enable or Disable the SPIx guard time selection function.
668  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
669  * @param NewState: This parameter can be ENABLE or DISABLE.
670  * @retval None
671  ************************************************************************************************************/
SPI_GUARDTCmd(HT_SPI_TypeDef * SPIx,ControlStatus NewState)672 void SPI_GUARDTCmd(HT_SPI_TypeDef* SPIx, ControlStatus NewState)
673 {
674   /* Check the parameters                                                                                   */
675   Assert_Param(IS_SPI(SPIx));
676   Assert_Param(IS_CONTROL_STATUS(NewState));
677 
678   (NewState == ENABLE) ? (SPIx->CR0 |= CR0_GUADTEN_SET) : (SPIx->CR0 &= CR0_GUADTEN_RESET);
679 }
680 
681 /*********************************************************************************************************//**
682  * @brief Set the SPIx guard time length.
683  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
684  * @param Guard_Time: number of SCK to be the guard time length.
685  *   This parameter can be: SPI_GUADTIME_1_SCK to SPI_GUADTIME_16_SCK.
686  * @retval None
687  ************************************************************************************************************/
SPI_GUARDTConfig(HT_SPI_TypeDef * SPIx,u32 Guard_Time)688 void SPI_GUARDTConfig(HT_SPI_TypeDef* SPIx, u32 Guard_Time)
689 {
690   /* Check the parameters                                                                                   */
691   Assert_Param(IS_SPI(SPIx));
692   Assert_Param(IS_SPI_GUADTIME(Guard_Time));
693 
694   SPIx->CR0 = (SPIx->CR0 & 0xF0FF) | (Guard_Time << 8);
695 }
696 
697 /*********************************************************************************************************//**
698  * @brief Set the SPIx chip select hold time.
699  * @param SPIx: where SPIx is the selected SPI from the SPI peripherals.
700  * @param CS_Hold_Time: number of SCK to be the hold time length.
701  *   This parameter can be: 0 ~ 15
702  * @retval None
703  ************************************************************************************************************/
SPI_SELHTConfig(HT_SPI_TypeDef * SPIx,u32 CS_Hold_Time)704 void SPI_SELHTConfig(HT_SPI_TypeDef* SPIx, u32 CS_Hold_Time)
705 {
706   /* Check the parameters                                                                                   */
707   Assert_Param(IS_SPI(SPIx));
708   Assert_Param(IS_SPI_SELHOLDTIME(CS_Hold_Time));
709 
710   SPIx->CR0 = (SPIx->CR0 & 0x0FFF) | (CS_Hold_Time << 12);
711 }
712 /**
713   * @}
714   */
715 
716 
717 /**
718   * @}
719   */
720 
721 /**
722   * @}
723   */
724