1 /**
2   ******************************************************************************
3   * @file    lib_spi.c
4   * @author  Application Team
5   * @version V1.1.0
6   * @date    2019-10-28
7   * @brief   SPI library.
8   ******************************************************************************
9   * @attention
10   *
11   ******************************************************************************
12   */
13 #include "lib_spi.h"
14 
15 #define SPI_MISC_RSTValue    (0UL)
16 
17 /**
18   * @brief  Initializes SPI peripheral registers to their default reset values(Reset SPI FIFO when this function is called).
19   * @param  SPIx:SPI1~SPI3
20   * @retval None
21   */
SPI_DeviceInit(SPI_Type * SPIx)22 void SPI_DeviceInit(SPI_Type *SPIx)
23 {
24   __IO uint32_t dummy_data = 0UL;
25 
26   /* Check parameters */
27   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
28 
29   /* Disable SPI */
30   SPIx->CTRL = 0;
31   /* SPI soft reset */
32   SPIx->CTRL |= SPI_CTRL_RST;
33   SPIx->CTRL &= ~SPI_CTRL_RST;
34   /* Clear flag */
35   dummy_data = SPIx->RXDAT;
36   dummy_data += 1;
37   SPIx->TXSTS = SPI_TXSTS_TXIF|SPI_TXSTS_DMATXDONE;
38   SPIx->RXSTS = SPI_RXSTS_RXIF;
39   /* write default values */
40   SPIx->MISC = SPI_MISC_RSTValue;
41 }
42 
43 /**
44   * @brief  Fills each SPI_InitType member with its default value.
45   * @param  InitStruct: pointer to an SPI_InitType structure which will be initialized.
46   * @retval None
47   */
SPI_StructInit(SPI_InitType * InitStruct)48 void SPI_StructInit(SPI_InitType *InitStruct)
49 {
50   /*--------------- Reset SPI init structure parameters values ---------------*/
51   /* Initialize the ClockDivision member */
52   InitStruct->ClockDivision = SPI_CLKDIV_2;
53   /* Initialize the CSNSoft member */
54   InitStruct->CSNSoft = SPI_CSNSOFT_DISABLE;
55   /* Initialize the Mode member */
56   InitStruct->Mode = SPI_MODE_MASTER;
57   /* Initialize the SPH member */
58   InitStruct->SPH = SPI_SPH_0;
59   /* Initialize the SPO member */
60   InitStruct->SPO = SPI_SPO_0;
61   /* Initialize the SWAP member */
62   InitStruct->SWAP = SPI_SWAP_DISABLE;
63 }
64 
65 /**
66   * @brief  Initializes SPI.
67   * @param  SPIx:SPI1~SPI3
68             InitStruct: SPI configuration.
69                 Mode:
70                     SPI_MODE_MASTER
71                     SPI_MODE_SLAVE
72                 SPH:
73                     SPI_SPH_0
74                     SPI_SPH_1
75                 SPO:
76                     SPI_SPO_0
77                     SPI_SPO_1
78                 ClockDivision:
79                     SPI_CLKDIV_2
80                     SPI_CLKDIV_4
81                     SPI_CLKDIV_8
82                     SPI_CLKDIV_16
83                     SPI_CLKDIV_32
84                     SPI_CLKDIV_64
85                     SPI_CLKDIV_128
86                 CSNSoft:
87                     SPI_CSNSOFT_ENABLE
88                     SPI_CSNSOFT_DISABLE
89                 SWAP:
90                     SPI_SWAP_ENABLE
91                     SPI_SWAP_DISABLE
92   * @retval None
93   */
SPI_Init(SPI_Type * SPIx,SPI_InitType * InitStruct)94 void SPI_Init(SPI_Type *SPIx, SPI_InitType *InitStruct)
95 {
96   uint32_t tmp;
97 
98   /* Check parameters */
99   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
100   assert_parameters(IS_SPI_MODE(InitStruct->Mode));
101   assert_parameters(IS_SPI_SPH(InitStruct->SPH));
102   assert_parameters(IS_SPI_SPO(InitStruct->SPO));
103   assert_parameters(IS_SPI_CLKDIV(InitStruct->ClockDivision));
104   assert_parameters(IS_SPI_CSN(InitStruct->CSNSoft));
105   assert_parameters(IS_SPI_SWAP(InitStruct->SWAP));
106 
107   tmp = SPIx->CTRL;
108   tmp &= ~(SPI_CTRL_MOD\
109           |SPI_CTRL_SCKPHA\
110           |SPI_CTRL_SCKPOL\
111           |SPI_CTRL_CSGPIO\
112           |SPI_CTRL_SWAP\
113           |SPI_CTRL_SCKSEL);
114   tmp |= (InitStruct->Mode\
115          |InitStruct->SPH\
116          |InitStruct->SPO\
117          |InitStruct->CSNSoft\
118          |InitStruct->SWAP\
119          |InitStruct->ClockDivision);
120   SPIx->CTRL = tmp;
121 }
122 
123 /**
124   * @brief  Enables or disables SPI.
125   * @param  SPIx:SPI1~SPI3
126             NewState:
127                 ENABLE
128                 DISABLE
129   * @retval None
130   */
SPI_Cmd(SPI_Type * SPIx,uint32_t NewState)131 void SPI_Cmd(SPI_Type *SPIx, uint32_t NewState)
132 {
133   /* Check parameters */
134   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
135   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
136 
137   if (NewState == ENABLE)
138     SPIx->CTRL |= SPI_CTRL_EN;
139   else
140     SPIx->CTRL &= ~SPI_CTRL_EN;
141 }
142 
143 /**
144   * @brief  Enables or disables SPI interrupt.
145   * @param  SPIx:SPI1~SPI3
146             INTMask: can use the '|' operator
147                 SPI_INT_TX
148                 SPI_INT_RX
149             NewState:
150                 ENABLE
151                 DISABLE
152   * @retval None
153   */
SPI_INTConfig(SPI_Type * SPIx,uint32_t INTMask,uint32_t NewState)154 void SPI_INTConfig(SPI_Type *SPIx, uint32_t INTMask, uint32_t NewState)
155 {
156   uint32_t tmp;
157 
158   /* Check parameters */
159   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
160   assert_parameters(IS_SPI_INT(INTMask));
161   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
162 
163   if (INTMask & 0x80000000)
164   {
165     INTMask &= 0xFFFF;
166     tmp = SPIx->TXSTS;
167     tmp &= ~SPI_TXSTS_TXIF;
168     if (NewState == ENABLE)
169     {
170       tmp |= INTMask;
171       SPIx->TXSTS = tmp;
172     }
173     else
174     {
175       tmp &= ~INTMask;
176       SPIx->TXSTS = tmp;
177     }
178   }
179   if (INTMask & 0x40000000)
180   {
181     INTMask &= 0xFFFF;
182     tmp = SPIx->RXSTS;
183     tmp &= ~SPI_RXSTS_RXIF;
184     if (NewState == ENABLE)
185     {
186       tmp |= INTMask;
187       SPIx->RXSTS = tmp;
188     }
189     else
190     {
191       tmp &= ~INTMask;
192       SPIx->RXSTS = tmp;
193     }
194   }
195 }
196 
197 /**
198   * @brief  Gets SPI status flag.
199   * @param  SPIx:SPI1~SPI3
200             Status:
201                 SPI_STS_TXIF
202                 SPI_STS_TXEMPTY
203                 SPI_STS_TXFUR
204                 SPI_STS_DMATXDONE
205                 SPI_STS_RXIF
206                 SPI_STS_RXFULL
207                 SPI_STS_RXFOV
208                 SPI_STS_BSY
209                 SPI_STS_RFF
210                 SPI_STS_RNE
211                 SPI_STS_TNF
212                 SPI_STS_TFE
213   * @retval Flag status.
214   */
SPI_GetStatus(SPI_Type * SPIx,uint32_t Status)215 uint8_t SPI_GetStatus(SPI_Type *SPIx, uint32_t Status)
216 {
217   /* Check parameters */
218   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
219   assert_parameters(IS_SPI_STSR(Status));
220 
221   if ((Status&0xE0000000) == 0x80000000)
222   {
223     if (Status&SPIx->TXSTS)
224       return 1;
225     else
226       return 0;
227   }
228   else if ((Status&0xE0000000) == 0x40000000)
229   {
230     if (Status&SPIx->RXSTS)
231       return 1;
232     else
233       return 0;
234   }
235   else
236   {
237     if (Status&SPIx->MISC)
238       return 1;
239     else
240       return 0;
241   }
242 }
243 
244 /**
245   * @brief  Clears SPI status flag.
246   * @param  SPIx:SPI1~SPI3
247             Status: can use the '|' operator
248                 SPI_STS_TXIF
249                 SPI_STS_RXIF
250                 SPI_STS_DMATXDONE
251   * @retval None
252   */
SPI_ClearStatus(SPI_Type * SPIx,uint32_t Status)253 void SPI_ClearStatus(SPI_Type *SPIx, uint32_t Status)
254 {
255   uint32_t tmp = 0UL;
256 
257   /* Check parameters */
258   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
259   assert_parameters(IS_SPI_STSC(Status));
260 
261   if (Status & 0x80000000)
262   {
263     Status &= 0xFFFF;
264     tmp = SPIx->TXSTS;
265     tmp &= ~(SPI_TXSTS_DMATXDONE | SPI_TXSTS_TXIF);
266     tmp |= Status;
267     SPIx->TXSTS = tmp;
268   }
269   if (Status & 0x40000000)
270   {
271     Status &= 0xFFFF;
272     SPIx->RXSTS |= Status;
273   }
274 }
275 
276 /**
277   * @brief  Loads send data register.
278   * @param  SPIx:SPI1~SPI3
279             ch: data write to send data register
280   * @retval None
281   */
SPI_SendData(SPI_Type * SPIx,uint8_t ch)282 void SPI_SendData(SPI_Type *SPIx, uint8_t ch)
283 {
284   /* Check parameters */
285   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
286 
287   SPIx->TXDAT = ch;
288 }
289 
290 /**
291   * @brief  Reads receive data register.
292   * @param  SPIx:SPI1~SPI3
293   * @retval receive data value
294   */
SPI_ReceiveData(SPI_Type * SPIx)295 uint8_t SPI_ReceiveData(SPI_Type *SPIx)
296 {
297   /* Check parameters */
298   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
299 
300   return (SPIx->RXDAT);
301 }
302 
303 /**
304   * @brief  Configures transmit fifo level.
305   * @param  SPIx:SPI1~SPI3
306             FIFOLevel:
307                 SPI_TXFLEV_0
308                 SPI_TXFLEV_1
309                 SPI_TXFLEV_2
310                 SPI_TXFLEV_3
311                 SPI_TXFLEV_4
312                 SPI_TXFLEV_5
313                 SPI_TXFLEV_6
314                 SPI_TXFLEV_7
315   * @retval None
316   */
SPI_TransmitFIFOLevelConfig(SPI_Type * SPIx,uint32_t FIFOLevel)317 void SPI_TransmitFIFOLevelConfig(SPI_Type *SPIx, uint32_t FIFOLevel)
318 {
319   uint32_t tmp;
320 
321   /* Check parameters */
322   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
323   assert_parameters(IS_SPI_TXFLEV(FIFOLevel));
324 
325   tmp = SPIx->TXSTS;
326   tmp &= ~(SPI_TXSTS_TXFLEV | SPI_TXSTS_TXIF|SPI_TXSTS_DMATXDONE);
327   tmp |= FIFOLevel;
328   SPIx->TXSTS = tmp;
329 }
330 
331 /**
332   * @brief  Configures receive fifo level.
333   * @param  SPIx:SPI1~SPI3
334             FIFOLevel:
335                 SPI_RXFLEV_0
336                 SPI_RXFLEV_1
337                 SPI_RXFLEV_2
338                 SPI_RXFLEV_3
339                 SPI_RXFLEV_4
340                 SPI_RXFLEV_5
341                 SPI_RXFLEV_6
342                 SPI_RXFLEV_7
343   * @retval None
344   */
SPI_ReceiveFIFOLevelConfig(SPI_Type * SPIx,uint32_t FIFOLevel)345 void SPI_ReceiveFIFOLevelConfig(SPI_Type *SPIx, uint32_t FIFOLevel)
346 {
347   uint32_t tmp;
348 
349   /* Check parameters */
350   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
351   assert_parameters(IS_SPI_RXFLEV(FIFOLevel));
352 
353   tmp = SPIx->RXSTS;
354   tmp &= ~(SPI_RXSTS_RXFLEV | SPI_RXSTS_RXIF);
355   tmp |= FIFOLevel;
356   SPIx->RXSTS = tmp;
357 }
358 
359 /**
360   * @brief  Gets transmit fifo level.
361   * @param  SPIx:SPI1~SPI3
362   * @retval Transmit fifo level.
363   */
SPI_GetTransmitFIFOLevel(SPI_Type * SPIx)364 uint8_t SPI_GetTransmitFIFOLevel(SPI_Type *SPIx)
365 {
366   /* Check parameters */
367   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
368 
369   return (SPIx->TXSTS & SPI_TXSTS_TXFFLAG);
370 }
371 
372 /**
373   * @brief  Gets receive fifo level.
374   * @param  SPIx:SPI1~SPI3
375   * @retval Receive fifo level.
376   */
SPI_GetReceiveFIFOLevel(SPI_Type * SPIx)377 uint8_t SPI_GetReceiveFIFOLevel(SPI_Type *SPIx)
378 {
379   /* Check parameters */
380   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
381 
382   return (SPIx->RXSTS & SPI_RXSTS_RXFFLAG);
383 }
384 
385 /**
386   * @brief  Enables or disables FIFO smart mode.
387   * @param  SPIx:SPI1~SPI3
388             NewState:
389                 ENABLE
390                 DISABLE
391   * @retval None
392   */
SPI_SmartModeCmd(SPI_Type * SPIx,uint32_t NewState)393 void SPI_SmartModeCmd(SPI_Type *SPIx, uint32_t NewState)
394 {
395   /* Check parameters */
396   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
397   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
398 
399   if (NewState == ENABLE)
400   {
401     SPIx->MISC |= SPI_MISC_SMART;
402   }
403   else
404   {
405     SPIx->MISC &= ~SPI_MISC_SMART;
406   }
407 }
408 
409 /**
410   * @brief  Enables or disables FIFO over write mode.
411   * @param  SPIx:SPI1~SPI3
412             NewState:
413                 ENABLE
414                 DISABLE
415   * @retval None
416   */
SPI_OverWriteModeCmd(SPI_Type * SPIx,uint32_t NewState)417 void SPI_OverWriteModeCmd(SPI_Type *SPIx, uint32_t NewState)
418 {
419   /* Check parameters */
420   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
421   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
422 
423   if (NewState == ENABLE)
424   {
425     SPIx->MISC |= SPI_MISC_OVER;
426   }
427   else
428   {
429     SPIx->MISC &= ~SPI_MISC_OVER;
430   }
431 }
432 
433 /*********************************** END OF FILE ******************************/
434