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