1 /**
2 ******************************************************************************
3 * @file stm32f37x_spi.c
4 * @author MCD Application Team
5 * @version V1.0.0
6 * @date 20-September-2012
7 * @brief This file provides firmware functions to manage the following
8 * functionalities of the Serial peripheral interface (SPI):
9 * + Initialization and Configuration
10 * + Data transfers functions
11 * + Hardware CRC Calculation
12 * + DMA transfers management
13 * + Interrupts and flags management
14 *
15 * @verbatim
16
17 ===============================================================================
18 ##### How to use this driver #####
19 ===============================================================================
20 [..]
21 (#) Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE)
22 function for SPI1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE)
23 function for SPI2 or using RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE)
24 for SPI3.
25
26 (#) Enable SCK, MOSI, MISO and NSS GPIO clocks using
27 RCC_AHBPeriphClockCmd() function.
28
29 (#) Peripherals alternate function:
30 (++) Connect the pin to the desired peripherals' Alternate
31 Function (AF) using GPIO_PinAFConfig() function.
32 (++) Configure the desired pin in alternate function by:
33 GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF.
34 (++) Select the type, pull-up/pull-down and output speed via
35 GPIO_PuPd, GPIO_OType and GPIO_Speed members.
36 (++) Call GPIO_Init() function.
37
38 (#) Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave
39 Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
40 function.In I2S mode, program the Mode, Standard, Data Format, MCLK
41 Output, Audio frequency and Polarity using I2S_Init() function.
42
43 (#) Configure the FIFO threshold using SPI_RxFIFOThresholdConfig() to select
44 at which threshold the RXNE event is generated.
45
46 (#) Enable the NVIC and the corresponding interrupt using the function
47 SPI_ITConfig() if you need to use interrupt mode.
48
49 (#) When using the DMA mode
50 (++) Configure the DMA using DMA_Init() function.
51 (++) Active the needed channel Request using SPI_I2S_DMACmd() function.
52
53 (#) Enable the SPI using the SPI_Cmd() function or enable the I2S using
54 I2S_Cmd().
55
56 (#) Enable the DMA using the DMA_Cmd() function when using DMA mode.
57
58 (#) Optionally, you can enable/configure the following parameters without
59 re-initialization (i.e there is no need to call again SPI_Init() function):
60 (++) When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx)
61 is programmed as Data direction parameter using the SPI_Init()
62 function it can be possible to switch between SPI_Direction_Tx
63 or SPI_Direction_Rx using the SPI_BiDirectionalLineConfig() function.
64 (++) When SPI_NSS_Soft is selected as Slave Select Management parameter
65 using the SPI_Init() function it can be possible to manage the
66 NSS internal signal using the SPI_NSSInternalSoftwareConfig() function.
67 (++) Reconfigure the data size using the SPI_DataSizeConfig() function.
68 (++) Enable or disable the SS output using the SPI_SSOutputCmd() function.
69
70 (#) To use the CRC Hardware calculation feature refer to the Peripheral
71 CRC hardware Calculation subsection.
72
73 @endverbatim
74 ******************************************************************************
75 * @attention
76 *
77 * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
78 *
79 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
80 * You may not use this file except in compliance with the License.
81 * You may obtain a copy of the License at:
82 *
83 * http://www.st.com/software_license_agreement_liberty_v2
84 *
85 * Unless required by applicable law or agreed to in writing, software
86 * distributed under the License is distributed on an "AS IS" BASIS,
87 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88 * See the License for the specific language governing permissions and
89 * limitations under the License.
90 *
91 ******************************************************************************
92 */
93
94 /* Includes ------------------------------------------------------------------*/
95 #include "stm32f37x_spi.h"
96 #include "stm32f37x_rcc.h"
97
98 /** @addtogroup STM32F37x_StdPeriph_Driver
99 * @{
100 */
101
102 /** @defgroup SPI
103 * @brief SPI driver modules
104 * @{
105 */
106
107 /* Private typedef -----------------------------------------------------------*/
108 /* Private define ------------------------------------------------------------*/
109 /* SPI registers Masks */
110 #define CR1_CLEAR_MASK ((uint16_t)0x3040)
111 #define CR1_CLEAR_MASK2 ((uint16_t)0xFFFB)
112 #define CR2_LDMA_MASK ((uint16_t)0x9FFF)
113
114 #define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040)
115
116 /* Private macro -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 /* Private functions ---------------------------------------------------------*/
120
121 /** @defgroup SPI_Private_Functions
122 * @{
123 */
124
125 /** @defgroup SPI_Group1 Initialization and Configuration functions
126 * @brief Initialization and Configuration functions
127 *
128 @verbatim
129 ===============================================================================
130 ##### Initialization and Configuration functions #####
131 ===============================================================================
132 [..] This section provides a set of functions allowing to initialize the SPI Direction,
133 SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud
134 Rate Prescaler, SPI First Bit and SPI CRC Polynomial.
135
136 [..] The SPI_Init() function follows the SPI configuration procedures for Master mode
137 and Slave mode (details for these procedures are available in reference manual).
138
139 [..] When the Software NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Soft) is selected,
140 use the following function to manage the NSS bit:
141 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
142
143 [..] In Master mode, when the Hardware NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Hard)
144 is selected, use the follwoing function to enable the NSS output feature.
145 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
146
147 [..] The NSS pulse mode can be managed by the SPI TI mode when enabling it using the following function:
148 void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
149 And it can be managed by software in the SPI Motorola mode using this function:
150 void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
151
152 [..] This section provides also functions to initialize the I2S Mode, Standard,
153 Data Format, MCLK Output, Audio frequency and Polarity.
154
155 [..] The I2S_Init() function follows the I2S configuration procedures for Master mode
156 and Slave mode.
157
158 @endverbatim
159 * @{
160 */
161
162 /**
163 * @brief Deinitializes the SPIx peripheral registers to their default
164 * reset values.
165 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
166 * @retval None
167 */
SPI_I2S_DeInit(SPI_TypeDef * SPIx)168 void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
169 {
170 /* Check the parameters */
171 assert_param(IS_SPI_ALL_PERIPH(SPIx));
172
173 if (SPIx == SPI1)
174 {
175 /* Enable SPI1 reset state */
176 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
177 /* Release SPI1 from reset state */
178 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
179 }
180 else if (SPIx == SPI2)
181 {
182 /* Enable SPI2 reset state */
183 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
184 /* Release SPI2 from reset state */
185 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
186 }
187 else
188 {
189 if (SPIx == SPI3)
190 {
191 /* Enable SPI3 reset state */
192 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
193 /* Release SPI3 from reset state */
194 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
195 }
196 }
197 }
198
199 /**
200 * @brief Fills each SPI_InitStruct member with its default value.
201 * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
202 * @retval None
203 */
SPI_StructInit(SPI_InitTypeDef * SPI_InitStruct)204 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
205 {
206 /*--------------- Reset SPI init structure parameters values -----------------*/
207 /* Initialize the SPI_Direction member */
208 SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
209 /* Initialize the SPI_Mode member */
210 SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
211 /* Initialize the SPI_DataSize member */
212 SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
213 /* Initialize the SPI_CPOL member */
214 SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
215 /* Initialize the SPI_CPHA member */
216 SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
217 /* Initialize the SPI_NSS member */
218 SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
219 /* Initialize the SPI_BaudRatePrescaler member */
220 SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
221 /* Initialize the SPI_FirstBit member */
222 SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
223 /* Initialize the SPI_CRCPolynomial member */
224 SPI_InitStruct->SPI_CRCPolynomial = 7;
225 }
226
227 /**
228 * @brief Initializes the SPIx peripheral according to the specified
229 * parameters in the SPI_InitStruct.
230 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
231 * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
232 * contains the configuration information for the specified SPI peripheral.
233 * @retval None
234 */
SPI_Init(SPI_TypeDef * SPIx,SPI_InitTypeDef * SPI_InitStruct)235 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
236 {
237 uint16_t tmpreg = 0;
238
239 /* check the parameters */
240 assert_param(IS_SPI_ALL_PERIPH(SPIx));
241
242 /* Check the SPI parameters */
243 assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
244 assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
245 assert_param(IS_SPI_DATA_SIZE(SPI_InitStruct->SPI_DataSize));
246 assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
247 assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
248 assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
249 assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
250 assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
251 assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
252
253 /*---------------------------- SPIx CR1 Configuration ------------------------*/
254 /* Get the SPIx CR1 value */
255 tmpreg = SPIx->CR1;
256 /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, CPOL and CPHA bits */
257 tmpreg &= CR1_CLEAR_MASK;
258 /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
259 master/slave mode, CPOL and CPHA */
260 /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
261 /* Set SSM, SSI bit according to SPI_NSS values */
262 /* Set LSBFirst bit according to SPI_FirstBit value */
263 /* Set BR bits according to SPI_BaudRatePrescaler value */
264 /* Set CPOL bit according to SPI_CPOL value */
265 /* Set CPHA bit according to SPI_CPHA value */
266 tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_FirstBit |
267 SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA |
268 SPI_InitStruct->SPI_NSS | SPI_InitStruct->SPI_BaudRatePrescaler);
269 /* Write to SPIx CR1 */
270 SPIx->CR1 = tmpreg;
271 /*-------------------------Data Size Configuration -----------------------*/
272 /* Get the SPIx CR2 value */
273 tmpreg = SPIx->CR2;
274 /* Clear DS[3:0] bits */
275 tmpreg &=(uint16_t)~SPI_CR2_DS;
276 /* Configure SPIx: Data Size */
277 tmpreg |= (uint16_t)(SPI_InitStruct->SPI_DataSize);
278 /* Write to SPIx CR2 */
279 SPIx->CR2 = tmpreg;
280
281 /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
282 /* Write to SPIx CRCPOLY */
283 SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
284
285 /*---------------------------- SPIx CR1 Configuration ------------------------*/
286 /* Get the SPIx CR1 value */
287 tmpreg = SPIx->CR1;
288 /* Clear MSTR bit */
289 tmpreg &= CR1_CLEAR_MASK2;
290 /* Configure SPIx: master/slave mode */
291 /* Set MSTR bit according to SPI_Mode */
292 tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Mode);
293 /* Write to SPIx CR1 */
294 SPIx->CR1 = tmpreg;
295
296 /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
297 SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
298 }
299
300 /**
301 * @brief Fills each I2S_InitStruct member with its default value.
302 * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized.
303 * @retval None
304 */
I2S_StructInit(I2S_InitTypeDef * I2S_InitStruct)305 void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
306 {
307 /*--------------- Reset I2S init structure parameters values -----------------*/
308 /* Initialize the I2S_Mode member */
309 I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
310
311 /* Initialize the I2S_Standard member */
312 I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
313
314 /* Initialize the I2S_DataFormat member */
315 I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
316
317 /* Initialize the I2S_MCLKOutput member */
318 I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
319
320 /* Initialize the I2S_AudioFreq member */
321 I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
322
323 /* Initialize the I2S_CPOL member */
324 I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
325 }
326
327 /**
328 * @brief Initializes the SPIx peripheral according to the specified
329 * parameters in the I2S_InitStruct.
330 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
331 * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
332 * contains the configuration information for the specified SPI peripheral
333 * configured in I2S mode.
334 * @note This function calculates the optimal prescaler needed to obtain the most
335 * accurate audio frequency (depending on the I2S clock source, the PLL values
336 * and the product configuration). But in case the prescaler value is greater
337 * than 511, the default value (0x02) will be configured instead.
338 * @retval None
339 */
I2S_Init(SPI_TypeDef * SPIx,I2S_InitTypeDef * I2S_InitStruct)340 void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
341 {
342 uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
343 uint32_t tmp = 0;
344 RCC_ClocksTypeDef RCC_Clocks;
345 uint32_t sourceclock = 0;
346
347 /* Check the I2S parameters */
348 assert_param(IS_SPI_ALL_PERIPH(SPIx));
349 assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
350 assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
351 assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
352 assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
353 assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
354 assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));
355
356 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
357 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
358 SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask;
359 SPIx->I2SPR = 0x0002;
360
361 /* Get the I2SCFGR register value */
362 tmpreg = SPIx->I2SCFGR;
363
364 /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
365 if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
366 {
367 i2sodd = (uint16_t)0;
368 i2sdiv = (uint16_t)2;
369 }
370 /* If the requested audio frequency is not the default, compute the prescaler */
371 else
372 {
373 /* Check the frame length (For the Prescaler computing) */
374 if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
375 {
376 /* Packet length is 16 bits */
377 packetlength = 1;
378 }
379 else
380 {
381 /* Packet length is 32 bits */
382 packetlength = 2;
383 }
384
385 /* I2S Clock source is System clock: Get System Clock frequency */
386 RCC_GetClocksFreq(&RCC_Clocks);
387
388 /* Get the source clock value: based on System Clock value */
389 sourceclock = RCC_Clocks.SYSCLK_Frequency;
390
391 /* Compute the Real divider depending on the MCLK output state with a floating point */
392 if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
393 {
394 /* MCLK output is enabled */
395 tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
396 }
397 else
398 {
399 /* MCLK output is disabled */
400 tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
401 }
402
403 /* Remove the floating point */
404 tmp = tmp / 10;
405
406 /* Check the parity of the divider */
407 i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
408
409 /* Compute the i2sdiv prescaler */
410 i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
411
412 /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
413 i2sodd = (uint16_t) (i2sodd << 8);
414 }
415
416 /* Test if the divider is 1 or 0 or greater than 0xFF */
417 if ((i2sdiv < 2) || (i2sdiv > 0xFF))
418 {
419 /* Set the default values */
420 i2sdiv = 2;
421 i2sodd = 0;
422 }
423
424 /* Write to SPIx I2SPR register the computed value */
425 SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
426
427 /* Configure the I2S with the SPI_InitStruct values */
428 tmpreg |= (uint16_t)(SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
429 (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
430 (uint16_t)I2S_InitStruct->I2S_CPOL))));
431
432 /* Write to SPIx I2SCFGR */
433 SPIx->I2SCFGR = tmpreg;
434 }
435
436 /**
437 * @brief Enables or disables the specified SPI peripheral.
438 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
439 * @param NewState: new state of the SPIx peripheral.
440 * This parameter can be: ENABLE or DISABLE.
441 * @retval None
442 */
SPI_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)443 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
444 {
445 /* Check the parameters */
446 assert_param(IS_SPI_ALL_PERIPH(SPIx));
447 assert_param(IS_FUNCTIONAL_STATE(NewState));
448
449 if (NewState != DISABLE)
450 {
451 /* Enable the selected SPI peripheral */
452 SPIx->CR1 |= SPI_CR1_SPE;
453 }
454 else
455 {
456 /* Disable the selected SPI peripheral */
457 SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
458 }
459 }
460
461 /**
462 * @brief Enables or disables the TI Mode.
463 *
464 * @note This function can be called only after the SPI_Init() function has
465 * been called.
466 * @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
467 * are not taken into consideration and are configured by hardware
468 * respectively to the TI mode requirements.
469 *
470 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
471 * @param NewState: new state of the selected SPI TI communication mode.
472 * This parameter can be: ENABLE or DISABLE.
473 * @retval None
474 */
SPI_TIModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)475 void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
476 {
477 /* Check the parameters */
478 assert_param(IS_SPI_ALL_PERIPH(SPIx));
479 assert_param(IS_FUNCTIONAL_STATE(NewState));
480
481 if (NewState != DISABLE)
482 {
483 /* Enable the TI mode for the selected SPI peripheral */
484 SPIx->CR2 |= SPI_CR2_FRF;
485 }
486 else
487 {
488 /* Disable the TI mode for the selected SPI peripheral */
489 SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRF);
490 }
491 }
492
493 /**
494 * @brief Enables or disables the specified SPI peripheral (in I2S mode).
495 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
496 * @param NewState: new state of the SPIx peripheral.
497 * This parameter can be: ENABLE or DISABLE.
498 * @retval None
499 */
I2S_Cmd(SPI_TypeDef * SPIx,FunctionalState NewState)500 void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
501 {
502 /* Check the parameters */
503 assert_param(IS_SPI_ALL_PERIPH(SPIx));
504 assert_param(IS_FUNCTIONAL_STATE(NewState));
505 if (NewState != DISABLE)
506 {
507 /* Enable the selected SPI peripheral in I2S mode */
508 SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
509 }
510 else
511 {
512 /* Disable the selected SPI peripheral in I2S mode */
513 SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
514 }
515 }
516
517 /**
518 * @brief Configures the data size for the selected SPI.
519 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
520 * @param SPI_DataSize: specifies the SPI data size.
521 * For the SPIx peripheral this parameter can be one of the following values:
522 * @arg SPI_DataSize_4b: Set data size to 4 bits
523 * @arg SPI_DataSize_5b: Set data size to 5 bits
524 * @arg SPI_DataSize_6b: Set data size to 6 bits
525 * @arg SPI_DataSize_7b: Set data size to 7 bits
526 * @arg SPI_DataSize_8b: Set data size to 8 bits
527 * @arg SPI_DataSize_9b: Set data size to 9 bits
528 * @arg SPI_DataSize_10b: Set data size to 10 bits
529 * @arg SPI_DataSize_11b: Set data size to 11 bits
530 * @arg SPI_DataSize_12b: Set data size to 12 bits
531 * @arg SPI_DataSize_13b: Set data size to 13 bits
532 * @arg SPI_DataSize_14b: Set data size to 14 bits
533 * @arg SPI_DataSize_15b: Set data size to 15 bits
534 * @arg SPI_DataSize_16b: Set data size to 16 bits
535 * @retval None
536 */
SPI_DataSizeConfig(SPI_TypeDef * SPIx,uint16_t SPI_DataSize)537 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
538 {
539 uint16_t tmpreg = 0;
540
541 /* Check the parameters */
542 assert_param(IS_SPI_ALL_PERIPH(SPIx));
543 assert_param(IS_SPI_DATA_SIZE(SPI_DataSize));
544 /* Read the CR2 register */
545 tmpreg = SPIx->CR2;
546 /* Clear DS[3:0] bits */
547 tmpreg &= (uint16_t)~SPI_CR2_DS;
548 /* Set new DS[3:0] bits value */
549 tmpreg |= SPI_DataSize;
550 SPIx->CR2 = tmpreg;
551 }
552
553 /**
554 * @brief Configures the FIFO reception threshold for the selected SPI.
555 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
556 * @param SPI_RxFIFOThreshold: specifies the FIFO reception threshold.
557 * This parameter can be one of the following values:
558 * @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO
559 * level is greater or equal to 1/2.
560 * @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO
561 * level is greater or equal to 1/4.
562 * @retval None
563 */
SPI_RxFIFOThresholdConfig(SPI_TypeDef * SPIx,uint16_t SPI_RxFIFOThreshold)564 void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)
565 {
566 /* Check the parameters */
567 assert_param(IS_SPI_ALL_PERIPH(SPIx));
568 assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));
569
570 /* Clear FRXTH bit */
571 SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
572
573 /* Set new FRXTH bit value */
574 SPIx->CR2 |= SPI_RxFIFOThreshold;
575 }
576
577 /**
578 * @brief Selects the data transfer direction in bidirectional mode for the specified SPI.
579 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
580 * @param SPI_Direction: specifies the data transfer direction in bidirectional mode.
581 * This parameter can be one of the following values:
582 * @arg SPI_Direction_Tx: Selects Tx transmission direction
583 * @arg SPI_Direction_Rx: Selects Rx receive direction
584 * @retval None
585 */
SPI_BiDirectionalLineConfig(SPI_TypeDef * SPIx,uint16_t SPI_Direction)586 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
587 {
588 /* Check the parameters */
589 assert_param(IS_SPI_ALL_PERIPH(SPIx));
590 assert_param(IS_SPI_DIRECTION(SPI_Direction));
591 if (SPI_Direction == SPI_Direction_Tx)
592 {
593 /* Set the Tx only mode */
594 SPIx->CR1 |= SPI_Direction_Tx;
595 }
596 else
597 {
598 /* Set the Rx only mode */
599 SPIx->CR1 &= SPI_Direction_Rx;
600 }
601 }
602
603 /**
604 * @brief Configures internally by software the NSS pin for the selected SPI.
605 * @note This function can be called only after the SPI_Init() function has
606 * been called.
607 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
608 * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state.
609 * This parameter can be one of the following values:
610 * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
611 * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
612 * @retval None
613 */
SPI_NSSInternalSoftwareConfig(SPI_TypeDef * SPIx,uint16_t SPI_NSSInternalSoft)614 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
615 {
616 /* Check the parameters */
617 assert_param(IS_SPI_ALL_PERIPH(SPIx));
618 assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
619
620 if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
621 {
622 /* Set NSS pin internally by software */
623 SPIx->CR1 |= SPI_NSSInternalSoft_Set;
624 }
625 else
626 {
627 /* Reset NSS pin internally by software */
628 SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
629 }
630 }
631
632 /**
633 * @brief Enables or disables the SS output for the selected SPI.
634 * @note This function can be called only after the SPI_Init() function has
635 * been called and the NSS hardware management mode is selected.
636 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
637 * @param NewState: new state of the SPIx SS output.
638 * This parameter can be: ENABLE or DISABLE.
639 * @retval None
640 */
SPI_SSOutputCmd(SPI_TypeDef * SPIx,FunctionalState NewState)641 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
642 {
643 /* Check the parameters */
644 assert_param(IS_SPI_ALL_PERIPH(SPIx));
645 assert_param(IS_FUNCTIONAL_STATE(NewState));
646 if (NewState != DISABLE)
647 {
648 /* Enable the selected SPI SS output */
649 SPIx->CR2 |= SPI_CR2_SSOE;
650 }
651 else
652 {
653 /* Disable the selected SPI SS output */
654 SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
655 }
656 }
657
658 /**
659 * @brief Enables or disables the NSS pulse management mode.
660 * @note This function can be called only after the SPI_Init() function has
661 * been called.
662 * @note When TI mode is selected, the control bits NSSP is not taken into
663 * consideration and are configured by hardware respectively to the
664 * TI mode requirements.
665 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
666 * @param NewState: new state of the NSS pulse management mode.
667 * This parameter can be: ENABLE or DISABLE.
668 * @retval None
669 */
SPI_NSSPulseModeCmd(SPI_TypeDef * SPIx,FunctionalState NewState)670 void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
671 {
672 /* Check the parameters */
673 assert_param(IS_SPI_ALL_PERIPH(SPIx));
674 assert_param(IS_FUNCTIONAL_STATE(NewState));
675
676 if (NewState != DISABLE)
677 {
678 /* Enable the NSS pulse management mode */
679 SPIx->CR2 |= SPI_CR2_NSSP;
680 }
681 else
682 {
683 /* Disable the NSS pulse management mode */
684 SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_NSSP);
685 }
686 }
687
688 /**
689 * @}
690 */
691
692 /** @defgroup SPI_Group2 Data transfers functions
693 * @brief Data transfers functions
694 *
695 @verbatim
696 ===============================================================================
697 ##### Data transfers functions #####
698 ===============================================================================
699 [..] This section provides a set of functions allowing to manage the SPI or I2S
700 data transfers.
701
702 [..] In reception, data are received and then stored into an internal Rx buffer while
703 In transmission, data are first stored into an internal Tx buffer before being
704 transmitted.
705
706 [..] The read access of the SPI_DR register can be done using
707 SPI_ReceiveData8() (when data size is equal or inferior than 8bits) and.
708 SPI_I2S_ReceiveData16() (when data size is superior than 8bits)function
709 and returns the Rx buffered value. Whereas a write access to the SPI_DR
710 can be done using SPI_SendData8() (when data size is equal or inferior than 8bits)
711 and SPI_I2S_SendData16() (when data size is superior than 8bits) function
712 and stores the written data into Tx buffer.
713
714 @endverbatim
715 * @{
716 */
717
718 /**
719 * @brief Transmits a Data through the SPIx/I2Sx peripheral.
720 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
721 * @param Data: Data to be transmitted.
722 * @retval None
723 */
SPI_SendData8(SPI_TypeDef * SPIx,uint8_t Data)724 void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
725 {
726 uint32_t spixbase = 0x00;
727
728 /* Check the parameters */
729 assert_param(IS_SPI_ALL_PERIPH(SPIx));
730
731 spixbase = (uint32_t)SPIx;
732 spixbase += 0x0C;
733
734 *(__IO uint8_t *) spixbase = Data;
735 }
736
737 /**
738 * @brief Transmits a Data through the SPIx/I2Sx peripheral.
739 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
740 * @param Data: Data to be transmitted.
741 * @retval None
742 */
SPI_I2S_SendData16(SPI_TypeDef * SPIx,uint16_t Data)743 void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data)
744 {
745 /* Check the parameters */
746 assert_param(IS_SPI_ALL_PERIPH(SPIx));
747
748 SPIx->DR = (uint16_t)Data;
749 }
750
751 /**
752 * @brief Returns the most recent received data by the SPIx/I2Sx peripheral.
753 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
754 * @retval The value of the received data.
755 */
SPI_ReceiveData8(SPI_TypeDef * SPIx)756 uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx)
757 {
758 uint32_t spixbase = 0x00;
759
760 spixbase = (uint32_t)SPIx;
761 spixbase += 0x0C;
762
763 return *(__IO uint8_t *) spixbase;
764 }
765
766 /**
767 * @brief Returns the most recent received data by the SPIx peripheral.
768 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
769 * @retval The value of the received data.
770 */
SPI_I2S_ReceiveData16(SPI_TypeDef * SPIx)771 uint16_t SPI_I2S_ReceiveData16(SPI_TypeDef* SPIx)
772 {
773 return SPIx->DR;
774 }
775 /**
776 * @}
777 */
778
779 /** @defgroup SPI_Group3 Hardware CRC Calculation functions
780 * @brief Hardware CRC Calculation functions
781 *
782 @verbatim
783 ===============================================================================
784 ##### Hardware CRC Calculation functions #####
785 ===============================================================================
786 [..] This section provides a set of functions allowing to manage the SPI CRC hardware
787 calculation.SPI communication using CRC is possible through the following procedure:
788
789 (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler,
790 Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
791 function.
792 (#) Enable the CRC calculation using the SPI_CalculateCRC() function.
793 (#) Enable the SPI using the SPI_Cmd() function
794 (#) Before writing the last data to the TX buffer, set the CRCNext bit using the
795 SPI_TransmitCRC() function to indicate that after transmission of the last
796 data, the CRC should be transmitted.
797 (#) After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT
798 bit is reset. The CRC is also received and compared against the SPI_RXCRCR
799 value.
800 If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt
801 can be generated when the SPI_I2S_IT_ERR interrupt is enabled.
802
803 -@-
804 (+@) It is advised to don't read the calculate CRC values during the communication.
805 (+@) When the SPI is in slave mode, be careful to enable CRC calculation only
806 when the clock is stable, that is, when the clock is in the steady state.
807 If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive
808 to the SCK slave input clock as soon as CRCEN is set, and this, whatever
809 the value of the SPE bit.
810 (+@) With high bitrate frequencies, be careful when transmitting the CRC.
811 As the number of used CPU cycles has to be as low as possible in the CRC
812 transfer phase, it is forbidden to call software functions in the CRC
813 transmission sequence to avoid errors in the last data and CRC reception.
814 In fact, CRCNEXT bit has to be written before the end of the transmission/reception
815 of the last data.
816 (+@) For high bit rate frequencies, it is advised to use the DMA mode to avoid the
817 degradation of the SPI speed performance due to CPU accesses impacting the
818 SPI bandwidth.
819 (+@) When the STM32F37x are configured as slaves and the NSS hardware mode is
820 used, the NSS pin needs to be kept low between the data phase and the CRC
821 phase.
822 (+@) When the SPI is configured in slave mode with the CRC feature enabled, CRC
823 calculation takes place even if a high level is applied on the NSS pin.
824 This may happen for example in case of a multislave environment where the
825 communication master addresses slaves alternately.
826 (+@) Between a slave deselection (high level on NSS) and a new slave selection
827 (low level on NSS), the CRC value should be cleared on both master and slave
828 sides in order to resynchronize the master and slave for their respective
829 CRC calculation.
830
831 -@- To clear the CRC, follow the procedure below:
832 (#@) Disable SPI using the SPI_Cmd() function
833 (#@) Disable the CRC calculation using the SPI_CalculateCRC() function.
834 (#@) Enable the CRC calculation using the SPI_CalculateCRC() function.
835 (#@) Enable SPI using the SPI_Cmd() function.
836
837 @endverbatim
838 * @{
839 */
840
841 /**
842 * @brief Configures the CRC calculation length for the selected SPI.
843 * @note This function can be called only after the SPI_Init() function has
844 * been called.
845 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
846 * @param SPI_CRCLength: specifies the SPI CRC calculation length.
847 * This parameter can be one of the following values:
848 * @arg SPI_CRCLength_8b: Set CRC Calculation to 8 bits
849 * @arg SPI_CRCLength_16b: Set CRC Calculation to 16 bits
850 * @retval None
851 */
SPI_CRCLengthConfig(SPI_TypeDef * SPIx,uint16_t SPI_CRCLength)852 void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength)
853 {
854 /* Check the parameters */
855 assert_param(IS_SPI_ALL_PERIPH(SPIx));
856 assert_param(IS_SPI_CRC_LENGTH(SPI_CRCLength));
857
858 /* Clear CRCL bit */
859 SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCL);
860
861 /* Set new CRCL bit value */
862 SPIx->CR1 |= SPI_CRCLength;
863 }
864
865 /**
866 * @brief Enables or disables the CRC value calculation of the transferred bytes.
867 * @note This function can be called only after the SPI_Init() function has
868 * been called.
869 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral..
870 * @param NewState: new state of the SPIx CRC value calculation.
871 * This parameter can be: ENABLE or DISABLE.
872 * @retval None
873 */
SPI_CalculateCRC(SPI_TypeDef * SPIx,FunctionalState NewState)874 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
875 {
876 /* Check the parameters */
877 assert_param(IS_SPI_ALL_PERIPH(SPIx));
878 assert_param(IS_FUNCTIONAL_STATE(NewState));
879
880 if (NewState != DISABLE)
881 {
882 /* Enable the selected SPI CRC calculation */
883 SPIx->CR1 |= SPI_CR1_CRCEN;
884 }
885 else
886 {
887 /* Disable the selected SPI CRC calculation */
888 SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
889 }
890 }
891
892 /**
893 * @brief Transmit the SPIx CRC value.
894 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
895 * @retval None
896 */
SPI_TransmitCRC(SPI_TypeDef * SPIx)897 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
898 {
899 /* Check the parameters */
900 assert_param(IS_SPI_ALL_PERIPH(SPIx));
901
902 /* Enable the selected SPI CRC transmission */
903 SPIx->CR1 |= SPI_CR1_CRCNEXT;
904 }
905
906 /**
907 * @brief Returns the transmit or the receive CRC register value for the specified SPI.
908 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
909 * @param SPI_CRC: specifies the CRC register to be read.
910 * This parameter can be one of the following values:
911 * @arg SPI_CRC_Tx: Selects Tx CRC register
912 * @arg SPI_CRC_Rx: Selects Rx CRC register
913 * @retval The selected CRC register value..
914 */
SPI_GetCRC(SPI_TypeDef * SPIx,uint8_t SPI_CRC)915 uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
916 {
917 uint16_t crcreg = 0;
918 /* Check the parameters */
919 assert_param(IS_SPI_ALL_PERIPH(SPIx));
920 assert_param(IS_SPI_CRC(SPI_CRC));
921
922 if (SPI_CRC != SPI_CRC_Rx)
923 {
924 /* Get the Tx CRC register */
925 crcreg = SPIx->TXCRCR;
926 }
927 else
928 {
929 /* Get the Rx CRC register */
930 crcreg = SPIx->RXCRCR;
931 }
932 /* Return the selected CRC register */
933 return crcreg;
934 }
935
936 /**
937 * @brief Returns the CRC Polynomial register value for the specified SPI.
938 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
939 * @retval The CRC Polynomial register value.
940 */
SPI_GetCRCPolynomial(SPI_TypeDef * SPIx)941 uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
942 {
943 /* Check the parameters */
944 assert_param(IS_SPI_ALL_PERIPH(SPIx));
945
946 /* Return the CRC polynomial register */
947 return SPIx->CRCPR;
948 }
949
950 /**
951 * @}
952 */
953
954 /** @defgroup SPI_Group4 DMA transfers management functions
955 * @brief DMA transfers management functions
956 *
957 @verbatim
958 ===============================================================================
959 ##### DMA transfers management functions #####
960 ===============================================================================
961 [..] This section provides two functions that can be used only in DMA mode.
962
963 @endverbatim
964 * @{
965 */
966
967 /**
968 * @brief Enables or disables the SPIx/I2Sx DMA interface.
969 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
970 * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled.
971 * This parameter can be any combination of the following values:
972 * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
973 * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
974 * @param NewState: new state of the selected SPI DMA transfer request.
975 * This parameter can be: ENABLE or DISABLE.
976 * @retval None
977 */
SPI_I2S_DMACmd(SPI_TypeDef * SPIx,uint16_t SPI_I2S_DMAReq,FunctionalState NewState)978 void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
979 {
980 /* Check the parameters */
981 assert_param(IS_SPI_ALL_PERIPH(SPIx));
982 assert_param(IS_FUNCTIONAL_STATE(NewState));
983 assert_param(IS_SPI_I2S_DMA_REQ(SPI_I2S_DMAReq));
984
985 if (NewState != DISABLE)
986 {
987 /* Enable the selected SPI DMA requests */
988 SPIx->CR2 |= SPI_I2S_DMAReq;
989 }
990 else
991 {
992 /* Disable the selected SPI DMA requests */
993 SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
994 }
995 }
996
997 /**
998 * @brief Configures the number of data to transfer type(Even/Odd) for the DMA
999 * last transfers and for the selected SPI.
1000 * @note This function have a meaning only if DMA mode is selected and if
1001 * the packing mode is used (data length <= 8 and DMA transfer size halfword)
1002 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1003 * @param SPI_LastDMATransfer: specifies the SPI last DMA transfers state.
1004 * This parameter can be one of the following values:
1005 * @arg SPI_LastDMATransfer_TxEvenRxEven: Number of data for transmission Even
1006 * and number of data for reception Even.
1007 * @arg SPI_LastDMATransfer_TxOddRxEven: Number of data for transmission Odd
1008 * and number of data for reception Even.
1009 * @arg SPI_LastDMATransfer_TxEvenRxOdd: Number of data for transmission Even
1010 * and number of data for reception Odd.
1011 * @arg SPI_LastDMATransfer_TxOddRxOdd: Number of data for transmission Odd
1012 * and number of data for reception Odd.
1013 * @retval None
1014 */
SPI_LastDMATransferCmd(SPI_TypeDef * SPIx,uint16_t SPI_LastDMATransfer)1015 void SPI_LastDMATransferCmd(SPI_TypeDef* SPIx, uint16_t SPI_LastDMATransfer)
1016 {
1017 /* Check the parameters */
1018 assert_param(IS_SPI_ALL_PERIPH(SPIx));
1019 assert_param(IS_SPI_LAST_DMA_TRANSFER(SPI_LastDMATransfer));
1020
1021 /* Clear LDMA_TX and LDMA_RX bits */
1022 SPIx->CR2 &= CR2_LDMA_MASK;
1023
1024 /* Set new LDMA_TX and LDMA_RX bits value */
1025 SPIx->CR2 |= SPI_LastDMATransfer;
1026 }
1027
1028 /**
1029 * @}
1030 */
1031
1032 /** @defgroup SPI_Group5 Interrupts and flags management functions
1033 * @brief Interrupts and flags management functions
1034 *
1035 @verbatim
1036 ===============================================================================
1037 ##### Interrupts and flags management functions #####
1038 ===============================================================================
1039 [..] This section provides a set of functions allowing to configure the SPI/I2S Interrupts
1040 sources and check or clear the flags or pending bits status.
1041 The user should identify which mode will be used in his application to manage
1042 the communication: Polling mode, Interrupt mode or DMA mode.
1043
1044 *** Polling Mode ***
1045 ====================
1046 [..] In Polling Mode, the SPI/I2S communication can be managed by 9 flags:
1047 (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
1048 (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
1049 (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
1050 (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur
1051 (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur
1052 (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
1053 (#) SPI_I2S_FLAG_FRE: to indicate a Frame Format error occurs.
1054 (#) I2S_FLAG_UDR: to indicate an Underrun error occurs.
1055 (#) I2S_FLAG_CHSIDE: to indicate Channel Side.
1056
1057 [..]
1058 (@)Do not use the BSY flag to handle each data transmission or reception. It is better
1059 to use the TXE and RXNE flags instead.
1060
1061 [..] In this Mode it is advised to use the following functions:
1062 (+) FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1063 (+) void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1064
1065 *** Interrupt Mode ***
1066 ======================
1067 [..] In Interrupt Mode, the SPI/I2S communication can be managed by 3 interrupt sources
1068 and 5 pending bits:
1069 [..] Pending Bits:
1070 (#) SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register
1071 (#) SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register
1072 (#) SPI_I2S_IT_OVR : to indicate if an Overrun error occur
1073 (#) I2S_IT_UDR : to indicate an Underrun Error occurs.
1074 (#) SPI_I2S_FLAG_FRE : to indicate a Frame Format error occurs.
1075
1076 [..] Interrupt Source:
1077 (#) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty
1078 interrupt.
1079 (#) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not
1080 empty interrupt.
1081 (#) SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.
1082
1083 [..] In this Mode it is advised to use the following functions:
1084 (+) void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
1085 (+) ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
1086
1087 *** FIFO Status ***
1088 ===================
1089 [..] It is possible to monitor the FIFO status when a transfer is ongoing using the
1090 following function:
1091 (+) uint32_t SPI_GetFIFOStatus(uint8_t SPI_FIFO_Direction);
1092
1093 *** DMA Mode ***
1094 ================
1095 [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel
1096 requests:
1097 (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request.
1098 (#) SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request.
1099
1100 [..] In this Mode it is advised to use the following function:
1101 (+) void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState).
1102
1103 @endverbatim
1104 * @{
1105 */
1106
1107 /**
1108 * @brief Enables or disables the specified SPI/I2S interrupts.
1109 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1110 * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled.
1111 * This parameter can be one of the following values:
1112 * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
1113 * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
1114 * @arg SPI_I2S_IT_ERR: Error interrupt mask
1115 * @param NewState: new state of the specified SPI interrupt.
1116 * This parameter can be: ENABLE or DISABLE.
1117 * @retval None
1118 */
SPI_I2S_ITConfig(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT,FunctionalState NewState)1119 void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
1120 {
1121 uint16_t itpos = 0, itmask = 0 ;
1122
1123 /* Check the parameters */
1124 assert_param(IS_SPI_ALL_PERIPH(SPIx));
1125 assert_param(IS_FUNCTIONAL_STATE(NewState));
1126 assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
1127
1128 /* Get the SPI IT index */
1129 itpos = SPI_I2S_IT >> 4;
1130
1131 /* Set the IT mask */
1132 itmask = (uint16_t)1 << (uint16_t)itpos;
1133
1134 if (NewState != DISABLE)
1135 {
1136 /* Enable the selected SPI interrupt */
1137 SPIx->CR2 |= itmask;
1138 }
1139 else
1140 {
1141 /* Disable the selected SPI interrupt */
1142 SPIx->CR2 &= (uint16_t)~itmask;
1143 }
1144 }
1145
1146 /**
1147 * @brief Returns the current SPIx Transmission FIFO filled level.
1148 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1149 * @retval The Transmission FIFO filling state.
1150 * - SPI_TransmissionFIFOStatus_Empty: when FIFO is empty
1151 * - SPI_TransmissionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
1152 * - SPI_TransmissionFIFOStatus_HalfFull: if more than 1 half-full.
1153 * - SPI_TransmissionFIFOStatus_Full: when FIFO is full.
1154 */
SPI_GetTransmissionFIFOStatus(SPI_TypeDef * SPIx)1155 uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx)
1156 {
1157 /* Get the SPIx Transmission FIFO level bits */
1158 return (uint16_t)((SPIx->SR & SPI_SR_FTLVL));
1159 }
1160
1161 /**
1162 * @brief Returns the current SPIx Reception FIFO filled level.
1163 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1164 * @retval The Reception FIFO filling state.
1165 * - SPI_ReceptionFIFOStatus_Empty: when FIFO is empty
1166 * - SPI_ReceptionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
1167 * - SPI_ReceptionFIFOStatus_HalfFull: if more than 1 half-full.
1168 * - SPI_ReceptionFIFOStatus_Full: when FIFO is full.
1169 */
SPI_GetReceptionFIFOStatus(SPI_TypeDef * SPIx)1170 uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx)
1171 {
1172 /* Get the SPIx Reception FIFO level bits */
1173 return (uint16_t)((SPIx->SR & SPI_SR_FRLVL));
1174 }
1175
1176 /**
1177 * @brief Checks whether the specified SPI flag is set or not.
1178 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1179 * @param SPI_I2S_FLAG: specifies the SPI flag to check.
1180 * This parameter can be one of the following values:
1181 * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
1182 * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
1183 * @arg SPI_I2S_FLAG_BSY: Busy flag.
1184 * @arg SPI_I2S_FLAG_OVR: Overrun flag.
1185 * @arg SPI_FLAG_MODF: Mode Fault flag.
1186 * @arg SPI_FLAG_CRCERR: CRC Error flag.
1187 * @arg SPI_I2S_FLAG_FRE: TI frame format error flag.
1188 * @arg I2S_FLAG_UDR: Underrun Error flag.
1189 * @arg I2S_FLAG_CHSIDE: Channel Side flag.
1190 * @retval The new state of SPI_I2S_FLAG (SET or RESET).
1191 */
SPI_I2S_GetFlagStatus(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)1192 FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1193 {
1194 FlagStatus bitstatus = RESET;
1195 /* Check the parameters */
1196 assert_param(IS_SPI_ALL_PERIPH(SPIx));
1197 assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
1198
1199 /* Check the status of the specified SPI flag */
1200 if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
1201 {
1202 /* SPI_I2S_FLAG is set */
1203 bitstatus = SET;
1204 }
1205 else
1206 {
1207 /* SPI_I2S_FLAG is reset */
1208 bitstatus = RESET;
1209 }
1210 /* Return the SPI_I2S_FLAG status */
1211 return bitstatus;
1212 }
1213
1214 /**
1215 * @brief Clears the SPIx CRC Error (CRCERR) flag.
1216 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1217 * @param SPI_I2S_FLAG: specifies the SPI flag to clear.
1218 * This function clears only CRCERR flag.
1219 * @note OVR (OverRun error) flag is cleared by software sequence: a read
1220 * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by
1221 * a read operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
1222 * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write
1223 * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by
1224 * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
1225 * @retval None
1226 */
SPI_I2S_ClearFlag(SPI_TypeDef * SPIx,uint16_t SPI_I2S_FLAG)1227 void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
1228 {
1229 /* Check the parameters */
1230 assert_param(IS_SPI_ALL_PERIPH(SPIx));
1231 assert_param(IS_SPI_CLEAR_FLAG(SPI_I2S_FLAG));
1232
1233 /* Clear the selected SPI CRC Error (CRCERR) flag */
1234 SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
1235 }
1236
1237 /**
1238 * @brief Checks whether the specified SPI/I2S interrupt has occurred or not.
1239 * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
1240 * @param SPI_I2S_IT: specifies the SPI interrupt source to check.
1241 * This parameter can be one of the following values:
1242 * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
1243 * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
1244 * @arg SPI_IT_MODF: Mode Fault interrupt.
1245 * @arg SPI_I2S_IT_OVR: Overrun interrupt.
1246 * @arg I2S_IT_UDR: Underrun interrupt.
1247 * @arg SPI_I2S_IT_FRE: Format Error interrupt.
1248 * @retval The new state of SPI_I2S_IT (SET or RESET).
1249 */
SPI_I2S_GetITStatus(SPI_TypeDef * SPIx,uint8_t SPI_I2S_IT)1250 ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
1251 {
1252 ITStatus bitstatus = RESET;
1253 uint16_t itpos = 0, itmask = 0, enablestatus = 0;
1254
1255 /* Check the parameters */
1256 assert_param(IS_SPI_ALL_PERIPH(SPIx));
1257 assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
1258
1259 /* Get the SPI_I2S_IT index */
1260 itpos = 0x01 << (SPI_I2S_IT & 0x0F);
1261
1262 /* Get the SPI_I2S_IT IT mask */
1263 itmask = SPI_I2S_IT >> 4;
1264
1265 /* Set the IT mask */
1266 itmask = 0x01 << itmask;
1267
1268 /* Get the SPI_I2S_IT enable bit status */
1269 enablestatus = (SPIx->CR2 & itmask) ;
1270
1271 /* Check the status of the specified SPI interrupt */
1272 if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
1273 {
1274 /* SPI_I2S_IT is set */
1275 bitstatus = SET;
1276 }
1277 else
1278 {
1279 /* SPI_I2S_IT is reset */
1280 bitstatus = RESET;
1281 }
1282 /* Return the SPI_I2S_IT status */
1283 return bitstatus;
1284 }
1285
1286 /**
1287 * @}
1288 */
1289
1290 /**
1291 * @}
1292 */
1293
1294 /**
1295 * @}
1296 */
1297
1298 /**
1299 * @}
1300 */
1301
1302 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1303