1 /*****************************************************************************
2 * Copyright (c) 2022, Nations Technologies Inc.
3 *
4 * All rights reserved.
5 * ****************************************************************************
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the disclaimer below.
12 *
13 * Nations' name may not be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * ****************************************************************************/
27
28 /**
29 * @file n32g43x_spi.c
30 * @author Nations
31 * @version v1.2.0
32 *
33 * @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
34 */
35 #include "n32g43x_spi.h"
36 #include "n32g43x_rcc.h"
37
38 /** @addtogroup N32G43x_StdPeriph_Driver
39 * @{
40 */
41
42 /** @addtogroup SPI
43 * @brief SPI driver modules
44 * @{
45 */
46
47 /** @addtogroup SPI_Private_TypesDefinitions
48 * @{
49 */
50
51 /**
52 * @}
53 */
54
55 /** @addtogroup SPI_Private_Defines
56 * @{
57 */
58
59 /* SPI SPIEN mask */
60 #define CTRL1_SPIEN_ENABLE ((uint16_t)0x0040)
61 #define CTRL1_SPIEN_DISABLE ((uint16_t)0xFFBF)
62
63 /* I2S I2SEN mask */
64 #define I2SCFG_I2SEN_ENABLE ((uint16_t)0x0400)
65 #define I2SCFG_I2SEN_DISABLE ((uint16_t)0xFBFF)
66
67 /* SPI CRCNEXT mask */
68 #define CTRL1_CRCNEXT_ENABLE ((uint16_t)0x1000)
69
70 /* SPI CRCEN mask */
71 #define CTRL1_CRCEN_ENABLE ((uint16_t)0x2000)
72 #define CTRL1_CRCEN_DISABLE ((uint16_t)0xDFFF)
73
74 /* SPI SSOE mask */
75 #define CTRL2_SSOEN_ENABLE ((uint16_t)0x0004)
76 #define CTRL2_SSOEN_DISABLE ((uint16_t)0xFFFB)
77
78 /* SPI registers Masks */
79 #define CTRL1_CLR_MASK ((uint16_t)0x3040)
80 #define I2SCFG_CLR_MASK ((uint16_t)0xF040)
81
82 /* SPI or I2S mode selection masks */
83 #define SPI_MODE_ENABLE ((uint16_t)0xF7FF)
84 #define I2S_MODE_ENABLE ((uint16_t)0x0800)
85
86 /* I2S clock source selection masks */
87 #define I2S1_CLKSRC ((uint32_t)(0x00020000))
88 #define I2S2_CLKSRC ((uint32_t)(0x00040000))
89 #define I2S_MUL_MASK ((uint32_t)(0x0000F000))
90 #define I2S_DIV_MASK ((uint32_t)(0x000000F0))
91
92 /**
93 * @}
94 */
95
96 /** @addtogroup SPI_Private_Macros
97 * @{
98 */
99
100 /**
101 * @}
102 */
103
104 /** @addtogroup SPI_Private_Variables
105 * @{
106 */
107
108 /**
109 * @}
110 */
111
112 /** @addtogroup SPI_Private_FunctionPrototypes
113 * @{
114 */
115
116 /**
117 * @}
118 */
119
120 /** @addtogroup SPI_Private_Functions
121 * @{
122 */
123
124 /**
125 * @brief Deinitializes the SPIx peripheral registers to their default
126 * reset values (Affects also the I2Ss).
127 * @param SPIx where x can be 1, 2 to select the SPI peripheral.
128 */
SPI_I2S_DeInit(SPI_Module * SPIx)129 void SPI_I2S_DeInit(SPI_Module* SPIx)
130 {
131 /* Check the parameters */
132 assert_param(IS_SPI_PERIPH(SPIx));
133
134 if (SPIx == SPI1)
135 {
136 /* Enable SPI1 reset state */
137 RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_SPI1, ENABLE);
138 /* Release SPI1 from reset state */
139 RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_SPI1, DISABLE);
140 }
141 else if (SPIx == SPI2)
142 {
143 /* Enable SPI2 reset state */
144 RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_SPI2, ENABLE);
145 /* Release SPI2 from reset state */
146 RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_SPI2, DISABLE);
147 }
148
149 }
150
151 /**
152 * @brief Initializes the SPIx peripheral according to the specified
153 * parameters in the SPI_InitStruct.
154 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
155 * @param SPI_InitStruct pointer to a SPI_InitType structure that
156 * contains the configuration information for the specified SPI peripheral.
157 */
SPI_Init(SPI_Module * SPIx,SPI_InitType * SPI_InitStruct)158 void SPI_Init(SPI_Module* SPIx, SPI_InitType* SPI_InitStruct)
159 {
160 uint16_t tmpregister = 0;
161
162 /* check the parameters */
163 assert_param(IS_SPI_PERIPH(SPIx));
164
165 /* Check the SPI parameters */
166 assert_param(IS_SPI_DIR_MODE(SPI_InitStruct->DataDirection));
167 assert_param(IS_SPI_MODE(SPI_InitStruct->SpiMode));
168 assert_param(IS_SPI_DATASIZE(SPI_InitStruct->DataLen));
169 assert_param(IS_SPI_CLKPOL(SPI_InitStruct->CLKPOL));
170 assert_param(IS_SPI_CLKPHA(SPI_InitStruct->CLKPHA));
171 assert_param(IS_SPI_NSS(SPI_InitStruct->NSS));
172 assert_param(IS_SPI_BR_PRESCALER(SPI_InitStruct->BaudRatePres));
173 assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->FirstBit));
174 assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly));
175
176 /*---------------------------- SPIx CTRL1 Configuration ------------------------*/
177 /* Get the SPIx CTRL1 value */
178 tmpregister = SPIx->CTRL1;
179 /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
180 tmpregister &= CTRL1_CLR_MASK;
181 /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
182 master/salve mode, CPOL and CPHA */
183 /* Set BIDImode, BIDIOE and RxONLY bits according to DataDirection value */
184 /* Set SSM, SSI and MSTR bits according to SpiMode and NSS values */
185 /* Set LSBFirst bit according to FirstBit value */
186 /* Set BR bits according to BaudRatePres value */
187 /* Set CPOL bit according to CLKPOL value */
188 /* Set CPHA bit according to CLKPHA value */
189 tmpregister |= (uint16_t)((uint32_t)SPI_InitStruct->DataDirection | SPI_InitStruct->SpiMode
190 | SPI_InitStruct->DataLen | SPI_InitStruct->CLKPOL | SPI_InitStruct->CLKPHA
191 | SPI_InitStruct->NSS | SPI_InitStruct->BaudRatePres | SPI_InitStruct->FirstBit);
192 /* Write to SPIx CTRL1 */
193 SPIx->CTRL1 = tmpregister;
194
195 /* Activate the SPI mode (Reset I2SMOD bit in I2SCFG register) */
196 SPIx->I2SCFG &= SPI_MODE_ENABLE;
197
198 /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
199 /* Write to SPIx CRCPOLY */
200 SPIx->CRCPOLY = SPI_InitStruct->CRCPoly;
201 }
202
203 /**
204 * @brief Initializes the SPIx peripheral according to the specified
205 * parameters in the I2S_InitStruct.
206 * @param SPIx where x can be 1 or 2 to select the SPI peripheral
207 * (configured in I2S mode).
208 * @param I2S_InitStruct pointer to an I2S_InitType structure that
209 * contains the configuration information for the specified SPI peripheral
210 * configured in I2S mode.
211 * @note
212 * The function calculates the optimal prescaler needed to obtain the most
213 * accurate audio frequency (depending on the I2S clock source, the PLL values
214 * and the product configuration). But in case the prescaler value is greater
215 * than 511, the default value (0x02) will be configured instead. *
216 */
I2S_Init(SPI_Module * SPIx,I2S_InitType * I2S_InitStruct)217 void I2S_Init(SPI_Module* SPIx, I2S_InitType* I2S_InitStruct)
218 {
219 uint16_t tmpregister = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
220 uint32_t tmp = 0;
221 RCC_ClocksType RCC_Clocks;
222 uint32_t sourceclock = 0;
223
224 /* Check the I2S parameters */
225 assert_param(IS_SPI_PERIPH(SPIx));
226 assert_param(IS_I2S_MODE(I2S_InitStruct->I2sMode));
227 assert_param(IS_I2S_STANDARD(I2S_InitStruct->Standard));
228 assert_param(IS_I2S_DATA_FMT(I2S_InitStruct->DataFormat));
229 assert_param(IS_I2S_MCLK_ENABLE(I2S_InitStruct->MCLKEnable));
230 assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFrequency));
231 assert_param(IS_I2S_CLKPOL(I2S_InitStruct->CLKPOL));
232
233 /*----------------------- SPIx I2SCFG & I2SPREDIV Configuration -----------------*/
234 /* Clear I2SMOD, I2SE, MODCFG, PCMSYNC, STDSEL, CKPOL, TDATLEN and CHLEN bits */
235 SPIx->I2SCFG &= I2SCFG_CLR_MASK;
236 SPIx->I2SPREDIV = 0x0002;
237
238 /* Get the I2SCFG register value */
239 tmpregister = SPIx->I2SCFG;
240
241 /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
242 if (I2S_InitStruct->AudioFrequency == I2S_AUDIO_FREQ_DEFAULT)
243 {
244 i2sodd = (uint16_t)0;
245 i2sdiv = (uint16_t)2;
246 }
247 /* If the requested audio frequency is not the default, compute the prescaler */
248 else
249 {
250 /* Check the frame length (For the Prescaler computing) */
251 if (I2S_InitStruct->DataFormat == I2S_DATA_FMT_16BITS)
252 {
253 /* Packet length is 16 bits */
254 packetlength = 1;
255 }
256 else
257 {
258 /* Packet length is 32 bits */
259 packetlength = 2;
260 }
261
262 /* Get the I2S clock source mask depending on the peripheral number */
263 if (((uint32_t)SPIx) == SPI2_BASE)
264 {
265 /* The mask is relative to I2S1 */
266 tmp = I2S1_CLKSRC;
267 }
268 else
269 {
270 /* The mask is relative to I2S2 */
271 tmp = I2S2_CLKSRC;
272 }
273
274 /* I2S Clock source is System clock: Get System Clock frequency */
275 RCC_GetClocksFreqValue(&RCC_Clocks);
276
277 /* Get the source clock value: based on System Clock value */
278 sourceclock = RCC_Clocks.SysclkFreq;
279
280 /* Compute the Real divider depending on the MCLK output state with a floating point */
281 if (I2S_InitStruct->MCLKEnable == I2S_MCLK_ENABLE)
282 {
283 /* MCLK output is enabled */
284 tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->AudioFrequency)) + 5);
285 }
286 else
287 {
288 /* MCLK output is disabled */
289 tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) * 10) / I2S_InitStruct->AudioFrequency)) + 5);
290 }
291
292 /* Remove the floating point */
293 tmp = tmp / 10;
294
295 /* Check the parity of the divider */
296 i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
297
298 /* Compute the i2sdiv prescaler */
299 i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
300
301 /* Get the Mask for the Odd bit (SPI_I2SPREDIV[8]) register */
302 i2sodd = (uint16_t)(i2sodd << 8);
303 }
304
305 /* Test if the divider is 1 or 0 or greater than 0xFF */
306 if ((i2sdiv < 2) || (i2sdiv > 0xFF))
307 {
308 /* Set the default values */
309 i2sdiv = 2;
310 i2sodd = 0;
311 }
312
313 /* Write to SPIx I2SPREDIV register the computed value */
314 SPIx->I2SPREDIV = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->MCLKEnable));
315
316 /* Configure the I2S with the SPI_InitStruct values */
317 tmpregister |= (uint16_t)(
318 I2S_MODE_ENABLE
319 | (uint16_t)(I2S_InitStruct->I2sMode
320 | (uint16_t)(I2S_InitStruct->Standard
321 | (uint16_t)(I2S_InitStruct->DataFormat | (uint16_t)I2S_InitStruct->CLKPOL))));
322
323 /* Write to SPIx I2SCFG */
324 SPIx->I2SCFG = tmpregister;
325 }
326
327 /**
328 * @brief Fills each SPI_InitStruct member with its default value.
329 * @param SPI_InitStruct pointer to a SPI_InitType structure which will be initialized.
330 */
SPI_InitStruct(SPI_InitType * SPI_InitStruct)331 void SPI_InitStruct(SPI_InitType* SPI_InitStruct)
332 {
333 /*--------------- Reset SPI init structure parameters values -----------------*/
334 /* Initialize the DataDirection member */
335 SPI_InitStruct->DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
336 /* initialize the SpiMode member */
337 SPI_InitStruct->SpiMode = SPI_MODE_SLAVE;
338 /* initialize the DataLen member */
339 SPI_InitStruct->DataLen = SPI_DATA_SIZE_8BITS;
340 /* Initialize the CLKPOL member */
341 SPI_InitStruct->CLKPOL = SPI_CLKPOL_LOW;
342 /* Initialize the CLKPHA member */
343 SPI_InitStruct->CLKPHA = SPI_CLKPHA_FIRST_EDGE;
344 /* Initialize the NSS member */
345 SPI_InitStruct->NSS = SPI_NSS_HARD;
346 /* Initialize the BaudRatePres member */
347 SPI_InitStruct->BaudRatePres = SPI_BR_PRESCALER_2;
348 /* Initialize the FirstBit member */
349 SPI_InitStruct->FirstBit = SPI_FB_MSB;
350 /* Initialize the CRCPoly member */
351 SPI_InitStruct->CRCPoly = 7;
352 }
353
354 /**
355 * @brief Fills each I2S_InitStruct member with its default value.
356 * @param I2S_InitStruct pointer to a I2S_InitType structure which will be initialized.
357 */
I2S_InitStruct(I2S_InitType * I2S_InitStruct)358 void I2S_InitStruct(I2S_InitType* I2S_InitStruct)
359 {
360 /*--------------- Reset I2S init structure parameters values -----------------*/
361 /* Initialize the I2sMode member */
362 I2S_InitStruct->I2sMode = I2S_MODE_SlAVE_TX;
363
364 /* Initialize the Standard member */
365 I2S_InitStruct->Standard = I2S_STD_PHILLIPS;
366
367 /* Initialize the DataFormat member */
368 I2S_InitStruct->DataFormat = I2S_DATA_FMT_16BITS;
369
370 /* Initialize the MCLKEnable member */
371 I2S_InitStruct->MCLKEnable = I2S_MCLK_DISABLE;
372
373 /* Initialize the AudioFrequency member */
374 I2S_InitStruct->AudioFrequency = I2S_AUDIO_FREQ_DEFAULT;
375
376 /* Initialize the CLKPOL member */
377 I2S_InitStruct->CLKPOL = I2S_CLKPOL_LOW;
378 }
379
380 /**
381 * @brief Enables or disables the specified SPI peripheral.
382 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
383 * @param Cmd new state of the SPIx peripheral.
384 * This parameter can be: ENABLE or DISABLE.
385 */
SPI_Enable(SPI_Module * SPIx,FunctionalState Cmd)386 void SPI_Enable(SPI_Module* SPIx, FunctionalState Cmd)
387 {
388 /* Check the parameters */
389 assert_param(IS_SPI_PERIPH(SPIx));
390 assert_param(IS_FUNCTIONAL_STATE(Cmd));
391 if (Cmd != DISABLE)
392 {
393 /* Enable the selected SPI peripheral */
394 SPIx->CTRL1 |= CTRL1_SPIEN_ENABLE;
395 }
396 else
397 {
398 /* Disable the selected SPI peripheral */
399 SPIx->CTRL1 &= CTRL1_SPIEN_DISABLE;
400 }
401 }
402
403 /**
404 * @brief Enables or disables the specified SPI peripheral (in I2S mode).
405 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
406 * @param Cmd new state of the SPIx peripheral.
407 * This parameter can be: ENABLE or DISABLE.
408 */
I2S_Enable(SPI_Module * SPIx,FunctionalState Cmd)409 void I2S_Enable(SPI_Module* SPIx, FunctionalState Cmd)
410 {
411 /* Check the parameters */
412 assert_param(IS_SPI_PERIPH(SPIx));
413 assert_param(IS_FUNCTIONAL_STATE(Cmd));
414 if (Cmd != DISABLE)
415 {
416 /* Enable the selected SPI peripheral (in I2S mode) */
417 SPIx->I2SCFG |= I2SCFG_I2SEN_ENABLE;
418 }
419 else
420 {
421 /* Disable the selected SPI peripheral (in I2S mode) */
422 SPIx->I2SCFG &= I2SCFG_I2SEN_DISABLE;
423 }
424 }
425
426 /**
427 * @brief Enables or disables the specified SPI/I2S interrupts.
428 * @param SPIx where x can be
429 * - 1 or 2 in SPI mode
430 * - 1 or 2 in I2S mode
431 * @param SPI_I2S_IT specifies the SPI/I2S interrupt source to be enabled or disabled.
432 * This parameter can be one of the following values:
433 * @arg SPI_I2S_INT_TE Tx buffer empty interrupt mask
434 * @arg SPI_I2S_INT_RNE Rx buffer not empty interrupt mask
435 * @arg SPI_I2S_INT_ERR Error interrupt mask
436 * @param Cmd new state of the specified SPI/I2S interrupt.
437 * This parameter can be: ENABLE or DISABLE.
438 */
SPI_I2S_EnableInt(SPI_Module * SPIx,uint8_t SPI_I2S_IT,FunctionalState Cmd)439 void SPI_I2S_EnableInt(SPI_Module* SPIx, uint8_t SPI_I2S_IT, FunctionalState Cmd)
440 {
441 uint16_t itpos = 0, itmask = 0;
442 /* Check the parameters */
443 assert_param(IS_SPI_PERIPH(SPIx));
444 assert_param(IS_FUNCTIONAL_STATE(Cmd));
445 assert_param(IS_SPI_I2S_CONFIG_INT(SPI_I2S_IT));
446
447 /* Get the SPI/I2S IT index */
448 itpos = SPI_I2S_IT >> 4;
449
450 /* Set the IT mask */
451 itmask = (uint16_t)1 << (uint16_t)itpos;
452
453 if (Cmd != DISABLE)
454 {
455 /* Enable the selected SPI/I2S interrupt */
456 SPIx->CTRL2 |= itmask;
457 }
458 else
459 {
460 /* Disable the selected SPI/I2S interrupt */
461 SPIx->CTRL2 &= (uint16_t)~itmask;
462 }
463 }
464
465 /**
466 * @brief Enables or disables the SPIx/I2Sx DMA interface.
467 * @param SPIx where x can be
468 * - 1 or 2 in SPI mode
469 * - 1 or 2 in I2S mode
470 * @param SPI_I2S_DMAReq specifies the SPI/I2S DMA transfer request to be enabled or disabled.
471 * This parameter can be any combination of the following values:
472 * @arg SPI_I2S_DMA_TX Tx buffer DMA transfer request
473 * @arg SPI_I2S_DMA_RX Rx buffer DMA transfer request
474 * @param Cmd new state of the selected SPI/I2S DMA transfer request.
475 * This parameter can be: ENABLE or DISABLE.
476 */
SPI_I2S_EnableDma(SPI_Module * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState Cmd)477 void SPI_I2S_EnableDma(SPI_Module* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState Cmd)
478 {
479 /* Check the parameters */
480 assert_param(IS_SPI_PERIPH(SPIx));
481 assert_param(IS_FUNCTIONAL_STATE(Cmd));
482 assert_param(IS_SPI_I2S_DMA(SPI_I2S_DMAReq));
483 if (Cmd != DISABLE)
484 {
485 /* Enable the selected SPI/I2S DMA requests */
486 SPIx->CTRL2 |= SPI_I2S_DMAReq;
487 }
488 else
489 {
490 /* Disable the selected SPI/I2S DMA requests */
491 SPIx->CTRL2 &= (uint16_t)~SPI_I2S_DMAReq;
492 }
493 }
494
495 /**
496 * @brief Transmits a Data through the SPIx/I2Sx peripheral.
497 * @param SPIx where x can be
498 * - 1 or 2 in SPI mode
499 * - 1 or 2 in I2S mode
500 * @param Data Data to be transmitted.
501 */
SPI_I2S_TransmitData(SPI_Module * SPIx,uint16_t Data)502 void SPI_I2S_TransmitData(SPI_Module* SPIx, uint16_t Data)
503 {
504 /* Check the parameters */
505 assert_param(IS_SPI_PERIPH(SPIx));
506
507 /* Write in the DAT register the data to be sent */
508 SPIx->DAT = Data;
509 }
510
511 /**
512 * @brief Returns the most recent received data by the SPIx/I2Sx peripheral.
513 * @param SPIx where x can be
514 * - 1 or 2 in SPI mode
515 * - 1 or 2 in I2S mode
516 * @return The value of the received data.
517 */
SPI_I2S_ReceiveData(SPI_Module * SPIx)518 uint16_t SPI_I2S_ReceiveData(SPI_Module* SPIx)
519 {
520 /* Check the parameters */
521 assert_param(IS_SPI_PERIPH(SPIx));
522
523 /* Return the data in the DAT register */
524 return SPIx->DAT;
525 }
526
527 /**
528 * @brief Configures internally by software the NSS pin for the selected SPI.
529 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
530 * @param SPI_NSSInternalSoft specifies the SPI NSS internal state.
531 * This parameter can be one of the following values:
532 * @arg SPI_NSS_HIGH Set NSS pin internally
533 * @arg SPI_NSS_LOW Reset NSS pin internally
534 */
SPI_SetNssLevel(SPI_Module * SPIx,uint16_t SPI_NSSInternalSoft)535 void SPI_SetNssLevel(SPI_Module* SPIx, uint16_t SPI_NSSInternalSoft)
536 {
537 /* Check the parameters */
538 assert_param(IS_SPI_PERIPH(SPIx));
539 assert_param(IS_SPI_NSS_LEVEL(SPI_NSSInternalSoft));
540 if (SPI_NSSInternalSoft != SPI_NSS_LOW)
541 {
542 /* Set NSS pin internally by software */
543 SPIx->CTRL1 |= SPI_NSS_HIGH;
544 }
545 else
546 {
547 /* Reset NSS pin internally by software */
548 SPIx->CTRL1 &= SPI_NSS_LOW;
549 }
550 }
551
552 /**
553 * @brief Enables or disables the SS output for the selected SPI.
554 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
555 * @param Cmd new state of the SPIx SS output.
556 * This parameter can be: ENABLE or DISABLE.
557 */
SPI_SSOutputEnable(SPI_Module * SPIx,FunctionalState Cmd)558 void SPI_SSOutputEnable(SPI_Module* SPIx, FunctionalState Cmd)
559 {
560 /* Check the parameters */
561 assert_param(IS_SPI_PERIPH(SPIx));
562 assert_param(IS_FUNCTIONAL_STATE(Cmd));
563 if (Cmd != DISABLE)
564 {
565 /* Enable the selected SPI SS output */
566 SPIx->CTRL2 |= CTRL2_SSOEN_ENABLE;
567 }
568 else
569 {
570 /* Disable the selected SPI SS output */
571 SPIx->CTRL2 &= CTRL2_SSOEN_DISABLE;
572 }
573 }
574
575 /**
576 * @brief Configures the data size for the selected SPI.
577 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
578 * @param DataLen specifies the SPI data size.
579 * This parameter can be one of the following values:
580 * @arg SPI_DATA_SIZE_16BITS Set data frame format to 16bit
581 * @arg SPI_DATA_SIZE_8BITS Set data frame format to 8bit
582 */
SPI_ConfigDataLen(SPI_Module * SPIx,uint16_t DataLen)583 void SPI_ConfigDataLen(SPI_Module* SPIx, uint16_t DataLen)
584 {
585 /* Check the parameters */
586 assert_param(IS_SPI_PERIPH(SPIx));
587 assert_param(IS_SPI_DATASIZE(DataLen));
588 /* Clear DFF bit */
589 SPIx->CTRL1 &= (uint16_t)~SPI_DATA_SIZE_16BITS;
590 /* Set new DFF bit value */
591 SPIx->CTRL1 |= DataLen;
592 }
593
594 /**
595 * @brief Transmit the SPIx CRC value.
596 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
597 */
SPI_TransmitCrcNext(SPI_Module * SPIx)598 void SPI_TransmitCrcNext(SPI_Module* SPIx)
599 {
600 /* Check the parameters */
601 assert_param(IS_SPI_PERIPH(SPIx));
602
603 /* Enable the selected SPI CRC transmission */
604 SPIx->CTRL1 |= CTRL1_CRCNEXT_ENABLE;
605 }
606
607 /**
608 * @brief Enables or disables the CRC value calculation of the transferred bytes.
609 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
610 * @param Cmd new state of the SPIx CRC value calculation.
611 * This parameter can be: ENABLE or DISABLE.
612 */
SPI_EnableCalculateCrc(SPI_Module * SPIx,FunctionalState Cmd)613 void SPI_EnableCalculateCrc(SPI_Module* SPIx, FunctionalState Cmd)
614 {
615 /* Check the parameters */
616 assert_param(IS_SPI_PERIPH(SPIx));
617 assert_param(IS_FUNCTIONAL_STATE(Cmd));
618 if (Cmd != DISABLE)
619 {
620 /* Enable the selected SPI CRC calculation */
621 SPIx->CTRL1 |= CTRL1_CRCEN_ENABLE;
622 }
623 else
624 {
625 /* Disable the selected SPI CRC calculation */
626 SPIx->CTRL1 &= CTRL1_CRCEN_DISABLE;
627 }
628 }
629
630 /**
631 * @brief Returns the transmit or the receive CRC register value for the specified SPI.
632 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
633 * @param SPI_CRC specifies the CRC register to be read.
634 * This parameter can be one of the following values:
635 * @arg SPI_CRC_TX Selects Tx CRC register
636 * @arg SPI_CRC_RX Selects Rx CRC register
637 * @return The selected CRC register value..
638 */
SPI_GetCRCDat(SPI_Module * SPIx,uint8_t SPI_CRC)639 uint16_t SPI_GetCRCDat(SPI_Module* SPIx, uint8_t SPI_CRC)
640 {
641 uint16_t crcreg = 0;
642 /* Check the parameters */
643 assert_param(IS_SPI_PERIPH(SPIx));
644 assert_param(IS_SPI_CRC(SPI_CRC));
645 if (SPI_CRC != SPI_CRC_RX)
646 {
647 /* Get the Tx CRC register */
648 crcreg = SPIx->CRCTDAT;
649 }
650 else
651 {
652 /* Get the Rx CRC register */
653 crcreg = SPIx->CRCRDAT;
654 }
655 /* Return the selected CRC register */
656 return crcreg;
657 }
658
659 /**
660 * @brief Returns the CRC Polynomial register value for the specified SPI.
661 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
662 * @return The CRC Polynomial register value.
663 */
SPI_GetCRCPoly(SPI_Module * SPIx)664 uint16_t SPI_GetCRCPoly(SPI_Module* SPIx)
665 {
666 /* Check the parameters */
667 assert_param(IS_SPI_PERIPH(SPIx));
668
669 /* Return the CRC polynomial register */
670 return SPIx->CRCPOLY;
671 }
672
673 /**
674 * @brief Selects the data transfer direction in bi-directional mode for the specified SPI.
675 * @param SPIx where x can be 1 or 2 to select the SPI peripheral.
676 * @param DataDirection specifies the data transfer direction in bi-directional mode.
677 * This parameter can be one of the following values:
678 * @arg SPI_BIDIRECTION_TX Selects Tx transmission direction
679 * @arg SPI_BIDIRECTION_RX Selects Rx receive direction
680 */
SPI_ConfigBidirectionalMode(SPI_Module * SPIx,uint16_t DataDirection)681 void SPI_ConfigBidirectionalMode(SPI_Module* SPIx, uint16_t DataDirection)
682 {
683 /* Check the parameters */
684 assert_param(IS_SPI_PERIPH(SPIx));
685 assert_param(IS_SPI_BIDIRECTION(DataDirection));
686 if (DataDirection == SPI_BIDIRECTION_TX)
687 {
688 /* Set the Tx only mode */
689 SPIx->CTRL1 |= SPI_BIDIRECTION_TX;
690 }
691 else
692 {
693 /* Set the Rx only mode */
694 SPIx->CTRL1 &= SPI_BIDIRECTION_RX;
695 }
696 }
697
698 /**
699 * @brief Checks whether the specified SPI/I2S flag is set or not.
700 * @param SPIx where x can be
701 * - 1 or 2 in SPI mode
702 * - 1 or 2 in I2S mode
703 * @param SPI_I2S_FLAG specifies the SPI/I2S flag to check.
704 * This parameter can be one of the following values:
705 * @arg SPI_I2S_TE_FLAG Transmit buffer empty flag.
706 * @arg SPI_I2S_RNE_FLAG Receive buffer not empty flag.
707 * @arg SPI_I2S_BUSY_FLAG Busy flag.
708 * @arg SPI_I2S_OVER_FLAG Overrun flag.
709 * @arg SPI_MODERR_FLAG Mode Fault flag.
710 * @arg SPI_CRCERR_FLAG CRC Error flag.
711 * @arg I2S_UNDER_FLAG Underrun Error flag.
712 * @arg I2S_CHSIDE_FLAG Channel Side flag.
713 * @return The new state of SPI_I2S_FLAG (SET or RESET).
714 */
SPI_I2S_GetStatus(SPI_Module * SPIx,uint16_t SPI_I2S_FLAG)715 FlagStatus SPI_I2S_GetStatus(SPI_Module* SPIx, uint16_t SPI_I2S_FLAG)
716 {
717 FlagStatus bitstatus = RESET;
718 /* Check the parameters */
719 assert_param(IS_SPI_PERIPH(SPIx));
720 assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
721 /* Check the status of the specified SPI/I2S flag */
722 if ((SPIx->STS & SPI_I2S_FLAG) != (uint16_t)RESET)
723 {
724 /* SPI_I2S_FLAG is set */
725 bitstatus = SET;
726 }
727 else
728 {
729 /* SPI_I2S_FLAG is reset */
730 bitstatus = RESET;
731 }
732 /* Return the SPI_I2S_FLAG status */
733 return bitstatus;
734 }
735
736 /**
737 * @brief Clears the SPIx CRC Error (CRCERR) flag.
738 * @param SPIx where x can be
739 * - 1 or 2 in SPI mode
740 * @param SPI_I2S_FLAG specifies the SPI flag to clear.
741 * This function clears only CRCERR flag.
742 * @note
743 * - OVR (OverRun error) flag is cleared by software sequence: a read
744 * operation to SPI_DAT register (SPI_I2S_ReceiveData()) followed by a read
745 * operation to SPI_STS register (SPI_I2S_GetStatus()).
746 * - UDR (UnderRun error) flag is cleared by a read operation to
747 * SPI_STS register (SPI_I2S_GetStatus()).
748 * - MODF (Mode Fault) flag is cleared by software sequence: a read/write
749 * operation to SPI_STS register (SPI_I2S_GetStatus()) followed by a
750 * write operation to SPI_CTRL1 register (SPI_Enable() to enable the SPI).
751 */
SPI_I2S_ClrCRCErrFlag(SPI_Module * SPIx,uint16_t SPI_I2S_FLAG)752 void SPI_I2S_ClrCRCErrFlag(SPI_Module* SPIx, uint16_t SPI_I2S_FLAG)
753 {
754 /* Check the parameters */
755 assert_param(IS_SPI_PERIPH(SPIx));
756 assert_param(IS_SPI_I2S_CLR_FLAG(SPI_I2S_FLAG));
757
758 /* Clear the selected SPI CRC Error (CRCERR) flag */
759 SPIx->STS = (uint16_t)~SPI_I2S_FLAG;
760 }
761
762 /**
763 * @brief Checks whether the specified SPI/I2S interrupt has occurred or not.
764 * @param SPIx where x can be
765 * - 1 or 2 in SPI mode
766 * - 1 or 2 in I2S mode
767 * @param SPI_I2S_IT specifies the SPI/I2S interrupt source to check.
768 * This parameter can be one of the following values:
769 * @arg SPI_I2S_INT_TE Transmit buffer empty interrupt.
770 * @arg SPI_I2S_INT_RNE Receive buffer not empty interrupt.
771 * @arg SPI_I2S_INT_OVER Overrun interrupt.
772 * @arg SPI_INT_MODERR Mode Fault interrupt.
773 * @arg SPI_INT_CRCERR CRC Error interrupt.
774 * @arg I2S_INT_UNDER Underrun Error interrupt.
775 * @return The new state of SPI_I2S_IT (SET or RESET).
776 */
SPI_I2S_GetIntStatus(SPI_Module * SPIx,uint8_t SPI_I2S_IT)777 INTStatus SPI_I2S_GetIntStatus(SPI_Module* SPIx, uint8_t SPI_I2S_IT)
778 {
779 INTStatus bitstatus = RESET;
780 uint16_t itpos = 0, itmask = 0, enablestatus = 0;
781
782 /* Check the parameters */
783 assert_param(IS_SPI_PERIPH(SPIx));
784 assert_param(IS_SPI_I2S_GET_INT(SPI_I2S_IT));
785
786 /* Get the SPI/I2S IT index */
787 itpos = 0x01 << (SPI_I2S_IT & 0x0F);
788
789 /* Get the SPI/I2S IT mask */
790 itmask = SPI_I2S_IT >> 4;
791
792 /* Set the IT mask */
793 itmask = 0x01 << itmask;
794
795 /* Get the SPI_I2S_IT enable bit status */
796 enablestatus = (SPIx->CTRL2 & itmask);
797
798 /* Check the status of the specified SPI/I2S interrupt */
799 if (((SPIx->STS & itpos) != (uint16_t)RESET) && enablestatus)
800 {
801 /* SPI_I2S_IT is set */
802 bitstatus = SET;
803 }
804 else
805 {
806 /* SPI_I2S_IT is reset */
807 bitstatus = RESET;
808 }
809 /* Return the SPI_I2S_IT status */
810 return bitstatus;
811 }
812
813 /**
814 * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
815 * @param SPIx where x can be
816 * - 1 or 2 in SPI mode
817 * @param SPI_I2S_IT specifies the SPI interrupt pending bit to clear.
818 * This function clears only CRCERR interrupt pending bit.
819 * @note
820 * - OVR (OverRun Error) interrupt pending bit is cleared by software
821 * sequence: a read operation to SPI_DAT register (SPI_I2S_ReceiveData())
822 * followed by a read operation to SPI_STS register (SPI_I2S_GetIntStatus()).
823 * - UDR (UnderRun Error) interrupt pending bit is cleared by a read
824 * operation to SPI_STS register (SPI_I2S_GetIntStatus()).
825 * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence:
826 * a read/write operation to SPI_STS register (SPI_I2S_GetIntStatus())
827 * followed by a write operation to SPI_CTRL1 register (SPI_Enable() to enable
828 * the SPI).
829 */
SPI_I2S_ClrITPendingBit(SPI_Module * SPIx,uint8_t SPI_I2S_IT)830 void SPI_I2S_ClrITPendingBit(SPI_Module* SPIx, uint8_t SPI_I2S_IT)
831 {
832 uint16_t itpos = 0;
833 /* Check the parameters */
834 assert_param(IS_SPI_PERIPH(SPIx));
835 assert_param(IS_SPI_I2S_CLR_INT(SPI_I2S_IT));
836
837 /* Get the SPI IT index */
838 itpos = 0x01 << (SPI_I2S_IT & 0x0F);
839
840 /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */
841 SPIx->STS = (uint16_t)~itpos;
842 }
843 /**
844 * @}
845 */
846
847 /**
848 * @}
849 */
850
851 /**
852 * @}
853 */
854