1 /**
2   ******************************************************************************
3   * @file    lib_spi.c
4   * @author  Application Team
5   * @version V4.4.0
6   * @date    2018-09-27
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  Reset SPI controller.
19   * @param  SPIx:SPI1~SPI2
20   * @retval None
21   */
SPI_DeviceInit(SPI_TypeDef * SPIx)22 void SPI_DeviceInit(SPI_TypeDef *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_SPIRST;
33   SPIx->CTRL &= ~SPI_CTRL_SPIRST;
34   /* Clear flag */
35   dummy_data = SPIx->RXDAT;
36   dummy_data += 1;
37   SPIx->TXSTS = SPI_TXSTS_TXIF;
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  SPI initialization.
67   * @param  SPIx:SPI1~SPI2
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_TypeDef * SPIx,SPI_InitType * InitStruct)94 void SPI_Init(SPI_TypeDef *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~SPI2
126             NewState:
127                 ENABLE
128                 DISABLE
129   * @retval None
130   */
SPI_Cmd(SPI_TypeDef * SPIx,uint32_t NewState)131 void SPI_Cmd(SPI_TypeDef *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_SPIEN;
139   else
140     SPIx->CTRL &= ~SPI_CTRL_SPIEN;
141 }
142 
143 /**
144   * @brief  SPI interrupt config.
145   * @param  SPIx:SPI1~SPI2
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_TypeDef * SPIx,uint32_t INTMask,uint32_t NewState)154 void SPI_INTConfig(SPI_TypeDef *SPIx, uint32_t INTMask, uint32_t NewState)
155 {
156   uint32_t tmp, tmp_INTMask;
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   tmp_INTMask = INTMask;
164   if (tmp_INTMask & 0x80000000)
165   {
166     INTMask &= 0xFFFF;
167     tmp = SPIx->TXSTS;
168     tmp &= ~SPI_TXSTS_TXIF;
169     if (NewState == ENABLE)
170     {
171       tmp |= INTMask;
172       SPIx->TXSTS = tmp;
173     }
174     else
175     {
176       tmp &= ~INTMask;
177       SPIx->TXSTS = tmp;
178     }
179   }
180   if (tmp_INTMask & 0x40000000)
181   {
182     INTMask &= 0xFFFF;
183     tmp = SPIx->RXSTS;
184     tmp &= ~SPI_RXSTS_RXIF;
185     if (NewState == ENABLE)
186     {
187       tmp |= INTMask;
188       SPIx->RXSTS = tmp;
189     }
190     else
191     {
192       tmp &= ~INTMask;
193       SPIx->RXSTS = tmp;
194     }
195   }
196 }
197 
198 /**
199   * @brief  Get status flag.
200   * @param  SPIx:SPI1~SPI2
201             Status:
202                 SPI_STS_TXIF
203                 SPI_STS_TXEMPTY
204                 SPI_STS_TXFUR
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_TypeDef * SPIx,uint32_t Status)215 uint8_t SPI_GetStatus(SPI_TypeDef *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  Clear status flag.
246   * @param  SPIx:SPI1~SPI2
247             Status: can use the ��|�� operator
248                 SPI_STS_TXIF
249                 SPI_STS_RXIF
250   * @retval None
251   */
SPI_ClearStatus(SPI_TypeDef * SPIx,uint32_t Status)252 void SPI_ClearStatus(SPI_TypeDef *SPIx, uint32_t Status)
253 {
254   uint32_t tmp_status;
255 
256   /* Check parameters */
257   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
258   assert_parameters(IS_SPI_STSC(Status));
259 
260   tmp_status = Status;
261   if (tmp_status & 0x80000000)
262   {
263     Status &= 0xFFFF;
264     SPIx->TXSTS |= Status;
265   }
266   if (tmp_status & 0x40000000)
267   {
268     Status &= 0xFFFF;
269     SPIx->RXSTS |= Status;
270   }
271 }
272 
273 /**
274   * @brief  Load send data register.
275   * @param  SPIx:SPI1~SPI2
276             ch: data write to send data register
277   * @retval None
278   */
SPI_SendData(SPI_TypeDef * SPIx,uint8_t ch)279 void SPI_SendData(SPI_TypeDef *SPIx, uint8_t ch)
280 {
281   /* Check parameters */
282   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
283 
284   SPIx->TXDAT = ch;
285 }
286 
287 /**
288   * @brief  Read receive data register.
289   * @param  SPIx:SPI1~SPI2
290   * @retval receive data value
291   */
SPI_ReceiveData(SPI_TypeDef * SPIx)292 uint8_t SPI_ReceiveData(SPI_TypeDef *SPIx)
293 {
294   /* Check parameters */
295   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
296 
297   return (SPIx->RXDAT);
298 }
299 
300 /**
301   * @brief  Transmit fifo level configure.
302   * @param  SPIx:SPI1~SPI2
303             FIFOLevel:
304                 SPI_TXFLEV_0
305                 SPI_TXFLEV_1
306                 SPI_TXFLEV_2
307                 SPI_TXFLEV_3
308                 SPI_TXFLEV_4
309                 SPI_TXFLEV_5
310                 SPI_TXFLEV_6
311                 SPI_TXFLEV_7
312   * @retval None
313   */
SPI_TransmitFIFOLevelConfig(SPI_TypeDef * SPIx,uint32_t FIFOLevel)314 void SPI_TransmitFIFOLevelConfig(SPI_TypeDef *SPIx, uint32_t FIFOLevel)
315 {
316   uint32_t tmp;
317 
318   /* Check parameters */
319   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
320   assert_parameters(IS_SPI_TXFLEV(FIFOLevel));
321 
322   tmp = SPIx->TXSTS;
323   tmp &= ~(SPI_TXSTS_TXFLEV | SPI_TXSTS_TXIF);
324   tmp |= FIFOLevel;
325   SPIx->TXSTS = tmp;
326 }
327 
328 /**
329   * @brief  Receive fifo level configure.
330   * @param  SPIx:SPI1~SPI2
331             FIFOLevel:
332                 SPI_RXFLEV_0
333                 SPI_RXFLEV_1
334                 SPI_RXFLEV_2
335                 SPI_RXFLEV_3
336                 SPI_RXFLEV_4
337                 SPI_RXFLEV_5
338                 SPI_RXFLEV_6
339                 SPI_RXFLEV_7
340   * @retval None
341   */
SPI_ReceiveFIFOLevelConfig(SPI_TypeDef * SPIx,uint32_t FIFOLevel)342 void SPI_ReceiveFIFOLevelConfig(SPI_TypeDef *SPIx, uint32_t FIFOLevel)
343 {
344   uint32_t tmp;
345 
346   /* Check parameters */
347   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
348   assert_parameters(IS_SPI_RXFLEV(FIFOLevel));
349 
350   tmp = SPIx->RXSTS;
351   tmp &= ~(SPI_RXSTS_RXFLEV | SPI_RXSTS_RXIF);
352   tmp |= FIFOLevel;
353   SPIx->RXSTS = tmp;
354 }
355 
356 /**
357   * @brief  Get transmit fifo level.
358   * @param  SPIx:SPI1~SPI2
359   * @retval Transmit fifo level.
360   */
SPI_GetTransmitFIFOLevel(SPI_TypeDef * SPIx)361 uint8_t SPI_GetTransmitFIFOLevel(SPI_TypeDef *SPIx)
362 {
363   /* Check parameters */
364   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
365 
366   return (SPIx->TXSTS & SPI_TXSTS_TXFFLAG);
367 }
368 
369 /**
370   * @brief  Get receive fifo level.
371   * @param  SPIx:SPI1~SPI2
372   * @retval Receive fifo level.
373   */
SPI_GetReceiveFIFOLevel(SPI_TypeDef * SPIx)374 uint8_t SPI_GetReceiveFIFOLevel(SPI_TypeDef *SPIx)
375 {
376   /* Check parameters */
377   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
378 
379   return (SPIx->RXSTS & SPI_RXSTS_RXFFLAG);
380 }
381 
382 /**
383   * @brief  FIFO smart mode.
384   * @param  SPIx:SPI1~SPI2
385             NewState:
386                 ENABLE
387                 DISABLE
388   * @retval None
389   */
SPI_SmartModeCmd(SPI_TypeDef * SPIx,uint32_t NewState)390 void SPI_SmartModeCmd(SPI_TypeDef *SPIx, uint32_t NewState)
391 {
392   /* Check parameters */
393   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
394   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
395 
396   if (NewState == ENABLE)
397   {
398     SPIx->MISC_ |= SPI_MISC_SMART;
399   }
400   else
401   {
402     SPIx->MISC_ &= ~SPI_MISC_SMART;
403   }
404 }
405 
406 /**
407   * @brief  FIFO over write mode.
408   * @param  SPIx:SPI1~SPI2
409             NewState:
410                 ENABLE
411                 DISABLE
412   * @retval None
413   */
SPI_OverWriteModeCmd(SPI_TypeDef * SPIx,uint32_t NewState)414 void SPI_OverWriteModeCmd(SPI_TypeDef *SPIx, uint32_t NewState)
415 {
416   /* Check parameters */
417   assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
418   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
419 
420   if (NewState == ENABLE)
421   {
422     SPIx->MISC_ |= SPI_MISC_OVER;
423   }
424   else
425   {
426     SPIx->MISC_ &= ~SPI_MISC_OVER;
427   }
428 }
429 
430 /*********************************** END OF FILE ******************************/
431