1 /******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
2 * File Name : stm32f10x_spi.c
3 * Author : MCD Application Team
4 * Date First Issued : 09/29/2006
5 * Description : This file provides all the SPI firmware functions.
6 ********************************************************************************
11 ********************************************************************************
12 * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
13 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
14 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
15 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
16 * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
17 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18 *******************************************************************************/
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32f10x_spi.h"
22 #include "stm32f10x_rcc.h"
24 /* Private typedef -----------------------------------------------------------*/
25 /* Private define ------------------------------------------------------------*/
27 #define CR1_SPE_Set ((u16)0x0040)
28 #define CR1_SPE_Reset ((u16)0xFFBF)
30 /* SPI CRCNext mask */
31 #define CR1_CRCNext_Set ((u16)0x1000)
34 #define CR1_CRCEN_Set ((u16)0x2000)
35 #define CR1_CRCEN_Reset ((u16)0xDFFF)
38 #define CR2_SSOE_Set ((u16)0x0004)
39 #define CR2_SSOE_Reset ((u16)0xFFFB)
41 /* SPI registers Masks */
42 #define CR1_CLEAR_Mask ((u16)0x3040)
44 /* Private macro -------------------------------------------------------------*/
45 /* Private variables ---------------------------------------------------------*/
46 /* Private function prototypes -----------------------------------------------*/
47 /* Private functions ---------------------------------------------------------*/
49 /*******************************************************************************
50 * Function Name : SPI_DeInit
51 * Description : Deinitializes the SPIx peripheral registers to their default
53 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
56 *******************************************************************************/
57 void SPI_DeInit(SPI_TypeDef* SPIx)
62 /* Enable SPI1 reset state */
63 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
64 /* Release SPI1 from reset state */
65 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
69 /* Enable SPI2 reset state */
70 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
71 /* Release SPI2 from reset state */
72 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
80 /*******************************************************************************
81 * Function Name : SPI_Init
82 * Description : Initializes the SPIx according to the specified parameters
83 * in the SPI_InitStruct.
84 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
85 * - SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
86 * contains the configuration information for the specified
90 ******************************************************************************/
91 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
95 /* Check the parameters */
96 assert(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
97 assert(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
98 assert(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
99 assert(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
100 assert(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
101 assert(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
102 assert(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
103 assert(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
104 assert(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
106 /*---------------------------- SPIx CR1 Configuration ------------------------*/
107 /* Get the SPIx CR1 value */
109 /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
110 tmpreg &= CR1_CLEAR_Mask;
111 /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
112 master/salve mode, CPOL and CPHA */
113 /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
114 /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
115 /* Set LSBFirst bit according to SPI_FirstBit value */
116 /* Set BR bits according to SPI_BaudRatePrescaler value */
117 /* Set CPOL bit according to SPI_CPOL value */
118 /* Set CPHA bit according to SPI_CPHA value */
119 tmpreg |= (u16)((u32)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
120 SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |
121 SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |
122 SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
123 /* Write to SPIx CR1 */
126 /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
127 /* Write to SPIx CRCPOLY */
128 SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
131 /*******************************************************************************
132 * Function Name : SPI_StructInit
133 * Description : Fills each SPI_InitStruct member with its default value.
134 * Input : - SPI_InitStruct : pointer to a SPI_InitTypeDef structure
135 * which will be initialized.
138 *******************************************************************************/
139 void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
141 /*--------------- Reset SPI init structure parameters values -----------------*/
142 /* Initialize the SPI_Direction member */
143 SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
145 /* initialize the SPI_Mode member */
146 SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
148 /* initialize the SPI_DataSize member */
149 SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
151 /* Initialize the SPI_CPOL member */
152 SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
154 /* Initialize the SPI_CPHA member */
155 SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
157 /* Initialize the SPI_NSS member */
158 SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
160 /* Initialize the SPI_BaudRatePrescaler member */
161 SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
163 /* Initialize the SPI_FirstBit member */
164 SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
166 /* Initialize the SPI_CRCPolynomial member */
167 SPI_InitStruct->SPI_CRCPolynomial = 7;
170 /*******************************************************************************
171 * Function Name : SPI_Cmd
172 * Description : Enables or disables the specified SPI peripheral.
173 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
174 * - NewState: new state of the SPIx peripheral.
175 * This parameter can be: ENABLE or DISABLE.
178 *******************************************************************************/
179 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
181 /* Check the parameters */
182 assert(IS_FUNCTIONAL_STATE(NewState));
184 if (NewState != DISABLE)
186 /* Enable the selected SPI peripheral */
187 SPIx->CR1 |= CR1_SPE_Set;
191 /* Disable the selected SPI peripheral */
192 SPIx->CR1 &= CR1_SPE_Reset;
196 /*******************************************************************************
197 * Function Name : SPI_ITConfig
198 * Description : Enables or disables the specified SPI interrupts.
199 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
200 * - SPI_IT: specifies the SPI interrupts sources to be enabled
202 * This parameter can be one of the following values:
203 * - SPI_IT_TXE: Tx buffer empty interrupt mask
204 * - SPI_IT_RXNE: Rx buffer not empty interrupt mask
205 * - SPI_IT_ERR: Error interrupt mask
206 * - NewState: new state of the specified SPI interrupts.
207 * This parameter can be: ENABLE or DISABLE.
210 *******************************************************************************/
211 void SPI_ITConfig(SPI_TypeDef* SPIx, u8 SPI_IT, FunctionalState NewState)
213 u16 itpos = 0, itmask = 0 ;
215 /* Check the parameters */
216 assert(IS_FUNCTIONAL_STATE(NewState));
217 assert(IS_SPI_CONFIG_IT(SPI_IT));
219 /* Get the SPI IT index */
221 /* Set the IT mask */
222 itmask = (u16)((u16)1 << itpos);
224 if (NewState != DISABLE)
226 /* Enable the selected SPI interrupt */
231 /* Disable the selected SPI interrupt */
232 SPIx->CR2 &= (u16)~itmask;
236 /*******************************************************************************
237 * Function Name : SPI_DMACmd
238 * Description : Enables or disables the SPIx
\92s DMA interface.
239 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
240 * - SPI_DMAReq: specifies the SPI DMA transfer request to be
241 * enabled or disabled.
242 * This parameter can be any combination of the following values:
243 * - SPI_DMAReq_Tx: Tx buffer DMA transfer request
244 * - SPI_DMAReq_Rx: Rx buffer DMA transfer request
245 * - NewState: new state of the selected SPI DMA transfer request.
246 * This parameter can be: ENABLE or DISABLE.
249 *******************************************************************************/
250 void SPI_DMACmd(SPI_TypeDef* SPIx, u16 SPI_DMAReq, FunctionalState NewState)
252 /* Check the parameters */
253 assert(IS_FUNCTIONAL_STATE(NewState));
254 assert(IS_SPI_DMA_REQ(SPI_DMAReq));
256 if (NewState != DISABLE)
258 /* Enable the selected SPI DMA requests */
259 SPIx->CR2 |= SPI_DMAReq;
263 /* Disable the selected SPI DMA requests */
264 SPIx->CR2 &= (u16)~SPI_DMAReq;
268 /*******************************************************************************
269 * Function Name : SPI_SendData
270 * Description : Transmits a Data through the SPIx peripheral.
271 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
272 * - Data : Data to be transmitted..
275 *******************************************************************************/
276 void SPI_SendData(SPI_TypeDef* SPIx, u16 Data)
278 /* Write in the DR register the data to be sent */
282 /*******************************************************************************
283 * Function Name : SPI_ReceiveData
284 * Description : Returns the most recent received data by the SPIx peripheral.
285 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
287 * Return : The value of the received data.
288 *******************************************************************************/
289 u16 SPI_ReceiveData(SPI_TypeDef* SPIx)
291 /* Return the data in the DR register */
295 /*******************************************************************************
296 * Function Name : SPI_NSSInternalSoftwareConfig
297 * Description : Configures internally by software the NSS pin for the selected
299 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
300 * - SPI_NSSInternalSoft: specifies the SPI NSS internal state.
301 * This parameter can be one of the following values:
302 * - SPI_NSSInternalSoft_Set: Set NSS pin internally
303 * - SPI_NSSInternalSoft_Reset: Reset NSS pin internally
306 *******************************************************************************/
307 void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, u16 SPI_NSSInternalSoft)
309 /* Check the parameters */
310 assert(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
312 if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
314 /* Set NSS pin internally by software */
315 SPIx->CR1 |= SPI_NSSInternalSoft_Set;
319 /* Reset NSS pin internally by software */
320 SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
324 /*******************************************************************************
325 * Function Name : SPI_SSOutputCmd
326 * Description : Enables or disables the SS output for the selected SPI.
327 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
328 * - NewState: new state of the SPIx SS output.
329 * This parameter can be: ENABLE or DISABLE.
332 *******************************************************************************/
333 void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
335 /* Check the parameters */
336 assert(IS_FUNCTIONAL_STATE(NewState));
338 if (NewState != DISABLE)
340 /* Enable the selected SPI SS output */
341 SPIx->CR2 |= CR2_SSOE_Set;
345 /* Disable the selected SPI SS output */
346 SPIx->CR2 &= CR2_SSOE_Reset;
350 /*******************************************************************************
351 * Function Name : SPI_DataSizeConfig
352 * Description : Configures the data size for the selected SPI.
353 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
354 * - SPI_DataSize: specifies the SPI data size.
355 * This parameter can be one of the following values:
356 * - SPI_DataSize_16b: Set data frame format to 16bit
357 * - SPI_DataSize_8b: Set data frame format to 8bit
360 *******************************************************************************/
361 void SPI_DataSizeConfig(SPI_TypeDef* SPIx, u16 SPI_DataSize)
363 /* Check the parameters */
364 assert(IS_SPI_DATASIZE(SPI_DataSize));
366 if (SPI_DataSize != SPI_DataSize_8b)
368 /* Set data frame format to 16bit */
369 SPIx->CR1 |= SPI_DataSize_16b;
373 /* Set data frame format to 8bit */
374 SPIx->CR1 &= SPI_DataSize_8b;
378 /*******************************************************************************
379 * Function Name : SPI_TransmitCRC
380 * Description : Transmit the SPIx CRC value.
381 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
384 *******************************************************************************/
385 void SPI_TransmitCRC(SPI_TypeDef* SPIx)
387 /* Enable the selected SPI CRC transmission */
388 SPIx->CR1 |= CR1_CRCNext_Set;
391 /*******************************************************************************
392 * Function Name : SPI_CalculateCRC
393 * Description : Enables or disables the CRC value calculation of the
395 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
396 * - NewState: new state of the SPIx CRC value calculation.
397 * This parameter can be: ENABLE or DISABLE.
400 *******************************************************************************/
401 void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
403 /* Check the parameters */
404 assert(IS_FUNCTIONAL_STATE(NewState));
406 if (NewState != DISABLE)
408 /* Enable the selected SPI CRC calculation */
409 SPIx->CR1 |= CR1_CRCEN_Set;
413 /* Disable the selected SPI CRC calculation */
414 SPIx->CR1 &= CR1_CRCEN_Reset;
418 /*******************************************************************************
419 * Function Name : SPI_GetCRC
420 * Description : Returns the transmit or the receive CRC register value for
422 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
423 * - SPI_CRC: specifies the CRC register to be read.
424 * This parameter can be one of the following values:
425 * - SPI_CRC_Tx: Selects Tx CRC register
426 * - SPI_CRC_Rx: Selects Rx CRC register
428 * Return : The selected CRC register value..
429 *******************************************************************************/
430 u16 SPI_GetCRC(SPI_TypeDef* SPIx, u8 SPI_CRC)
434 /* Check the parameters */
435 assert(IS_SPI_CRC(SPI_CRC));
437 if (SPI_CRC != SPI_CRC_Rx)
439 /* Get the Tx CRC register */
440 crcreg = SPIx->TXCRCR;
444 /* Get the Rx CRC register */
445 crcreg = SPIx->RXCRCR;
448 /* Return the selected CRC register */
452 /*******************************************************************************
453 * Function Name : SPI_GetCRCPolynomial
454 * Description : Returns the CRC Polynomial register value for the specified SPI.
455 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
457 * Return : The CRC Polynomial register value.
458 *******************************************************************************/
459 u16 SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
461 /* Return the CRC polynomial register */
465 /*******************************************************************************
466 * Function Name : SPI_BiDirectionalLineConfig
467 * Description : Selects the data transfer direction in bi-directional mode
468 * for the specified SPI.
469 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
470 * - SPI_Direction: specifies the data transfer direction in
471 * bi-directional mode.
472 * This parameter can be one of the following values:
473 * - SPI_Direction_Tx: Selects Tx transmission direction
474 * - SPI_Direction_Rx: Selects Rx receive direction
477 *******************************************************************************/
478 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, u16 SPI_Direction)
480 /* Check the parameters */
481 assert(IS_SPI_DIRECTION(SPI_Direction));
483 if (SPI_Direction == SPI_Direction_Tx)
485 /* Set the Tx only mode */
486 SPIx->CR1 |= SPI_Direction_Tx;
490 /* Set the Rx only mode */
491 SPIx->CR1 &= SPI_Direction_Rx;
495 /*******************************************************************************
496 * Function Name : SPI_GetFlagStatus
497 * Description : Checks whether the specified SPI flag is set or not.
498 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
499 * - SPI_FLAG: specifies the flag to check.
500 * This parameter can be one of the following values:
501 * - SPI_FLAG_BSY: Busy flag.
502 * - SPI_FLAG_OVR: Overrun flag.
503 * - SPI_FLAG_MODF: Mode Fault flag.
504 * - SPI_FLAG_CRCERR: CRC Error flag.
505 * - SPI_FLAG_TXE: Transmit buffer empty flag.
506 * - SPI_FLAG_RXNE: Receive buffer not empty flag.
508 * Return : The new state of SPI_FLAG (SET or RESET).
509 *******************************************************************************/
510 FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, u16 SPI_FLAG)
512 FlagStatus bitstatus = RESET;
514 /* Check the parameters */
515 assert(IS_SPI_GET_FLAG(SPI_FLAG));
517 /* Check the status of the specified SPI flag */
518 if ((SPIx->SR & SPI_FLAG) != (u16)RESET)
520 /* SPI_FLAG is set */
525 /* SPI_FLAG is reset */
528 /* Return the SPI_FLAG status */
532 /*******************************************************************************
533 * Function Name : SPI_ClearFlag
534 * Description : Clears the SPIx's pending flags.
535 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
536 * - SPI_FLAG: specifies the flag to clear.
537 * This parameter can be any combination of the following values:
538 * - SPI_FLAG_OVR: Overrun flag.
539 * - SPI_FLAG_MODF: Mode Fault flag.
540 * - SPI_FLAG_CRCERR: CRC Error flag.
543 *******************************************************************************/
544 void SPI_ClearFlag(SPI_TypeDef* SPIx, u16 SPI_FLAG)
546 /* Check the parameters */
547 assert(IS_SPI_CLEAR_FLAG(SPI_FLAG));
549 /* SPI_FLAG_MODF flag clear */
550 if(SPI_FLAG == SPI_FLAG_MODF)
552 /* Read SR register */
554 /* Write on CR1 register */
555 SPIx->CR1 |= CR1_SPE_Set;
557 /* SPI_FLAG_OVR flag clear */
558 else if(SPI_FLAG == SPI_FLAG_OVR)
560 /* Read SR register */
563 else /* SPI_FLAG_CRCERR flag clear */
565 /* Clear the selected SPI flag */
566 SPIx->SR &= (u16)~SPI_FLAG;
570 /*******************************************************************************
571 * Function Name : SPI_GetITStatus
572 * Description : Checks whether the specified SPI interrupt has occurred or not.
573 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
574 * - SPI_IT: specifies the SPI interrupt source to check.
575 * This parameter can be one of the following values:
576 * - SPI_IT_OVR: Overrun interrupt.
577 * - SPI_IT_MODF: Mode Fault interrupt.
578 * - SPI_IT_CRCERR: CRC Error interrupt.
579 * - SPI_IT_TXE: Transmit buffer empty interrupt.
580 * - SPI_IT_RXNE: Receive buffer not empty interrupt.
582 * Return : The new state of SPI_IT (SET or RESET).
583 *******************************************************************************/
584 ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, u8 SPI_IT)
586 ITStatus bitstatus = RESET;
587 u16 itpos = 0, itmask = 0, enablestatus = 0;
589 /* Check the parameters */
590 assert(IS_SPI_GET_IT(SPI_IT));
592 /* Get the SPI IT index */
593 itpos = (u16)((u16)0x01 << (SPI_IT & (u8)0x0F));
595 /* Get the SPI IT index */
596 itmask = SPI_IT >> 4;
597 /* Set the IT mask */
598 itmask = (u16)((u16)0x01 << itmask);
599 /* Get the SPI_IT enable bit status */
600 enablestatus = (SPIx->CR2 & itmask) ;
602 /* Check the status of the specified SPI interrupt */
603 if (((SPIx->SR & itpos) != (u16)RESET) && enablestatus)
610 /* SPI_IT is reset */
613 /* Return the SPI_IT status */
617 /*******************************************************************************
618 * Function Name : SPI_ClearITPendingBit
619 * Description : Clears the SPI
\92s interrupt pending bits.
620 * Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
621 * - SPI_IT: specifies the SPI interrupt pending bit to clear.
622 * This parameter can be one of the following values:
623 * - SPI_IT_OVR: Overrun interrupt.
624 * - SPI_IT_MODF: Mode Fault interrupt.
625 * - SPI_IT_CRCERR: CRC Error interrupt.
628 *******************************************************************************/
629 void SPI_ClearITPendingBit(SPI_TypeDef* SPIx, u8 SPI_IT)
633 /* Check the parameters */
634 assert(IS_SPI_CLEAR_IT(SPI_IT));
636 /* SPI_IT_MODF pending bit clear */
637 if(SPI_IT == SPI_IT_MODF)
639 /* Read SR register */
641 /* Write on CR1 register */
642 SPIx->CR1 |= CR1_SPE_Set;
644 else if(SPI_IT == SPI_IT_OVR) /* SPI_IT_OVR pending bit clear */
646 /* Read SR register */
649 else /* SPI_IT_CRCERR pending bit clear */
651 /* Get the SPI IT index */
652 itpos = (u16)((u16)0x01 << (SPI_IT & (u8)0x0F));
653 /* Clear the selected SPI interrupt pending bits */
654 SPIx->SR &= (u16)~itpos;
658 /******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/