+++ /dev/null
-/**\r
- ******************************************************************************\r
- * @file stm32l1xx_spi.c\r
- * @author MCD Application Team\r
- * @version V1.0.0\r
- * @date 31-December-2010\r
- * @brief This file provides firmware functions to manage the following \r
- * functionalities of the Serial peripheral interface (SPI): \r
- * - Initialization and Configuration\r
- * - Data transfers functions\r
- * - Hardware CRC Calculation\r
- * - DMA transfers management\r
- * - Interrupts and flags management \r
- * \r
- * @verbatim\r
- * \r
- * The I2S feature is not implemented in STM32L1xx Ultra Low Power\r
- * Medium-density devices and will be supported in future products.\r
- * \r
- * ===================================================================\r
- * How to use this driver\r
- * ===================================================================\r
- * 1. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE)\r
- * function for SPI1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE)\r
- * function for SPI2.\r
- *\r
- * 2. Enable SCK, MOSI, MISO and NSS GPIO clocks using RCC_AHBPeriphClockCmd()\r
- * function. \r
- *\r
- * 3. Peripherals alternate function: \r
- * - Connect the pin to the desired peripherals' Alternate \r
- * Function (AF) using GPIO_PinAFConfig() function\r
- * - Configure the desired pin in alternate function by:\r
- * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF\r
- * - Select the type, pull-up/pull-down and output speed via \r
- * GPIO_PuPd, GPIO_OType and GPIO_Speed members\r
- * - Call GPIO_Init() function\r
- * \r
- * 4. Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave \r
- * Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()\r
- * function.\r
- *\r
- * 5. Enable the NVIC and the corresponding interrupt using the function \r
- * SPI_ITConfig() if you need to use interrupt mode. \r
- *\r
- * 6. When using the DMA mode \r
- * - Configure the DMA using DMA_Init() function\r
- * - Active the needed channel Request using SPI_I2S_DMACmd() function\r
- * \r
- * 7. Enable the SPI using the SPI_Cmd() function.\r
- * \r
- * 8. Enable the DMA using the DMA_Cmd() function when using DMA mode. \r
- *\r
- * 9. Optionally you can enable/configure the following parameters without\r
- * re-initialization (i.e there is no need to call again SPI_Init() function):\r
- * - When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx)\r
- * is programmed as Data direction parameter using the SPI_Init() function\r
- * it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx\r
- * using the SPI_BiDirectionalLineConfig() function.\r
- * - When SPI_NSS_Soft is selected as Slave Select Management parameter \r
- * using the SPI_Init() function it can be possible to manage the \r
- * NSS internal signal using the SPI_NSSInternalSoftwareConfig() function.\r
- * - Reconfigure the data size using the SPI_DataSizeConfig() function \r
- * - Enable or disable the SS output using the SPI_SSOutputCmd() function \r
- * \r
- * 10. To use the CRC Hardware calculation feature refer to the Peripheral \r
- * CRC hardware Calculation subsection.\r
- *\r
- * @endverbatim \r
- * \r
- ******************************************************************************\r
- * @attention\r
- *\r
- * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
- * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
- * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
- *\r
- * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>\r
- ****************************************************************************** \r
- */ \r
-\r
-/* Includes ------------------------------------------------------------------*/\r
-#include "stm32l1xx_spi.h"\r
-#include "stm32l1xx_rcc.h"\r
-\r
-/** @addtogroup STM32L1xx_StdPeriph_Driver\r
- * @{\r
- */\r
-\r
-/** @defgroup SPI \r
- * @brief SPI driver modules\r
- * @{\r
- */ \r
-\r
-/* Private typedef -----------------------------------------------------------*/\r
-/* Private define ------------------------------------------------------------*/\r
-/* SPI registers Masks */\r
-#define CR1_CLEAR_MASK ((uint16_t)0x3040)\r
-\r
-/* Private macro -------------------------------------------------------------*/\r
-/* Private variables ---------------------------------------------------------*/\r
-/* Private function prototypes -----------------------------------------------*/\r
-/* Private functions ---------------------------------------------------------*/\r
-\r
-/** @defgroup SPI_Private_Functions\r
- * @{\r
- */\r
-\r
-/** @defgroup SPI_Group1 Initialization and Configuration functions\r
- * @brief Initialization and Configuration functions \r
- *\r
-@verbatim \r
- ===============================================================================\r
- Initialization and Configuration functions\r
- =============================================================================== \r
-\r
- This section provides a set of functions allowing to initialize the SPI Direction,\r
- SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud\r
- Rate Prescaler, SPI First Bit and SPI CRC Polynomial.\r
- \r
- The SPI_Init() function follows the SPI configuration procedures for Master mode\r
- and Slave mode (details for these procedures are available in reference manual\r
- (RM0038)).\r
- \r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Deinitializes the SPIx peripheral registers to their default\r
- * reset values.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @retval None\r
- */\r
-void SPI_I2S_DeInit(SPI_TypeDef* SPIx)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
-\r
- if (SPIx == SPI1)\r
- {\r
- /* Enable SPI1 reset state */\r
- RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);\r
- /* Release SPI1 from reset state */\r
- RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);\r
- }\r
- else\r
- {\r
- if (SPIx == SPI2)\r
- {\r
- /* Enable SPI2 reset state */\r
- RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);\r
- /* Release SPI2 from reset state */\r
- RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);\r
- }\r
- }\r
-}\r
-\r
-/**\r
- * @brief Initializes the SPIx peripheral according to the specified \r
- * parameters in the SPI_InitStruct.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that\r
- * contains the configuration information for the specified SPI peripheral.\r
- * @retval None\r
- */\r
-void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)\r
-{\r
- uint16_t tmpreg = 0;\r
- \r
- /* check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- \r
- /* Check the SPI parameters */\r
- assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));\r
- assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));\r
- assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));\r
- assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));\r
- assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));\r
- assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));\r
- assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));\r
- assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));\r
- assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));\r
-\r
-/*---------------------------- SPIx CR1 Configuration ------------------------*/\r
- /* Get the SPIx CR1 value */\r
- tmpreg = SPIx->CR1;\r
- /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */\r
- tmpreg &= CR1_CLEAR_MASK;\r
- /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler\r
- master/salve mode, CPOL and CPHA */\r
- /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */\r
- /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */\r
- /* Set LSBFirst bit according to SPI_FirstBit value */\r
- /* Set BR bits according to SPI_BaudRatePrescaler value */\r
- /* Set CPOL bit according to SPI_CPOL value */\r
- /* Set CPHA bit according to SPI_CPHA value */\r
- tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |\r
- SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | \r
- SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | \r
- SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);\r
- /* Write to SPIx CR1 */\r
- SPIx->CR1 = tmpreg;\r
- \r
-/*---------------------------- SPIx CRCPOLY Configuration --------------------*/\r
- /* Write to SPIx CRCPOLY */\r
- SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;\r
-}\r
-\r
-/**\r
- * @brief Fills each SPI_InitStruct member with its default value.\r
- * @param SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized.\r
- * @retval None\r
- */\r
-void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)\r
-{\r
-/*--------------- Reset SPI init structure parameters values -----------------*/\r
- /* Initialize the SPI_Direction member */\r
- SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;\r
- /* initialize the SPI_Mode member */\r
- SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;\r
- /* initialize the SPI_DataSize member */\r
- SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;\r
- /* Initialize the SPI_CPOL member */\r
- SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;\r
- /* Initialize the SPI_CPHA member */\r
- SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;\r
- /* Initialize the SPI_NSS member */\r
- SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;\r
- /* Initialize the SPI_BaudRatePrescaler member */\r
- SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;\r
- /* Initialize the SPI_FirstBit member */\r
- SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;\r
- /* Initialize the SPI_CRCPolynomial member */\r
- SPI_InitStruct->SPI_CRCPolynomial = 7;\r
-}\r
-\r
-/**\r
- * @brief Enables or disables the specified SPI peripheral.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param NewState: new state of the SPIx peripheral. \r
- * This parameter can be: ENABLE or DISABLE.\r
- * @retval None\r
- */\r
-void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_FUNCTIONAL_STATE(NewState));\r
- if (NewState != DISABLE)\r
- {\r
- /* Enable the selected SPI peripheral */\r
- SPIx->CR1 |= SPI_CR1_SPE;\r
- }\r
- else\r
- {\r
- /* Disable the selected SPI peripheral */\r
- SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);\r
- }\r
-}\r
-\r
-/**\r
- * @brief Configures the data size for the selected SPI.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param SPI_DataSize: specifies the SPI data size.\r
- * This parameter can be one of the following values:\r
- * @arg SPI_DataSize_16b: Set data frame format to 16bit\r
- * @arg SPI_DataSize_8b: Set data frame format to 8bit\r
- * @retval None\r
- */\r
-void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_DATASIZE(SPI_DataSize));\r
- /* Clear DFF bit */\r
- SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b;\r
- /* Set new DFF bit value */\r
- SPIx->CR1 |= SPI_DataSize;\r
-}\r
-\r
-/**\r
- * @brief Selects the data transfer direction in bidirectional mode for the specified SPI.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param SPI_Direction: specifies the data transfer direction in bidirectional mode. \r
- * This parameter can be one of the following values:\r
- * @arg SPI_Direction_Tx: Selects Tx transmission direction\r
- * @arg SPI_Direction_Rx: Selects Rx receive direction\r
- * @retval None\r
- */\r
-void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_DIRECTION(SPI_Direction));\r
- if (SPI_Direction == SPI_Direction_Tx)\r
- {\r
- /* Set the Tx only mode */\r
- SPIx->CR1 |= SPI_Direction_Tx;\r
- }\r
- else\r
- {\r
- /* Set the Rx only mode */\r
- SPIx->CR1 &= SPI_Direction_Rx;\r
- }\r
-}\r
-\r
-/**\r
- * @brief Configures internally by software the NSS pin for the selected SPI.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state.\r
- * This parameter can be one of the following values:\r
- * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally\r
- * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally\r
- * @retval None\r
- */\r
-void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));\r
- if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)\r
- {\r
- /* Set NSS pin internally by software */\r
- SPIx->CR1 |= SPI_NSSInternalSoft_Set;\r
- }\r
- else\r
- {\r
- /* Reset NSS pin internally by software */\r
- SPIx->CR1 &= SPI_NSSInternalSoft_Reset;\r
- }\r
-}\r
-\r
-/**\r
- * @brief Enables or disables the SS output for the selected SPI.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param NewState: new state of the SPIx SS output. \r
- * This parameter can be: ENABLE or DISABLE.\r
- * @retval None\r
- */\r
-void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_FUNCTIONAL_STATE(NewState));\r
- if (NewState != DISABLE)\r
- {\r
- /* Enable the selected SPI SS output */\r
- SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE;\r
- }\r
- else\r
- {\r
- /* Disable the selected SPI SS output */\r
- SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);\r
- }\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SPI_Group2 Data transfers functions\r
- * @brief Data transfers functions\r
- *\r
-@verbatim \r
- ===============================================================================\r
- Data transfers functions\r
- =============================================================================== \r
-\r
- This section provides a set of functions allowing to manage the SPI data transfers\r
- \r
- In reception, data are received and then stored into an internal Rx buffer while \r
- In transmission, data are first stored into an internal Tx buffer before being \r
- transmitted.\r
-\r
- The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData()\r
- function and returns the Rx buffered value. Whereas a write access to the SPI_DR \r
- can be done using SPI_I2S_SendData() function and stores the written data into \r
- Tx buffer.\r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Returns the most recent received data by the SPIx peripheral. \r
- * @param SPIx: where x can be 1 or 2 in SPI mode.\r
- * @retval The value of the received data.\r
- */\r
-uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- \r
- /* Return the data in the DR register */\r
- return SPIx->DR;\r
-}\r
-\r
-/**\r
- * @brief Transmits a Data through the SPIx peripheral.\r
- * @param SPIx: where x can be 1 or 2 in SPI mode. \r
- * @param Data: Data to be transmitted.\r
- * @retval None\r
- */\r
-void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- \r
- /* Write in the DR register the data to be sent */\r
- SPIx->DR = Data;\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SPI_Group3 Hardware CRC Calculation functions\r
- * @brief Hardware CRC Calculation functions\r
- *\r
-@verbatim \r
- ===============================================================================\r
- Hardware CRC Calculation functions\r
- =============================================================================== \r
-\r
- This section provides a set of functions allowing to manage the SPI CRC hardware \r
- calculation\r
-\r
- SPI communication using CRC is possible through the following procedure:\r
- 1. Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler, \r
- Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()\r
- function.\r
- 2. Enable the CRC calculation using the SPI_CalculateCRC() function.\r
- 3. Enable the SPI using the SPI_Cmd() function\r
- 4. Before writing the last data to the TX buffer, set the CRCNext bit using the \r
- SPI_TransmitCRC() function to indicate that after transmission of the last \r
- data, the CRC should be transmitted.\r
- 5. After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT\r
- bit is reset. The CRC is also received and compared against the SPI_RXCRCR \r
- value. \r
- If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt\r
- can be generated when the SPI_I2S_IT_ERR interrupt is enabled.\r
-\r
-Note: \r
------\r
- - It is advised to don't read the calculate CRC values during the communication.\r
-\r
- - When the SPI is in slave mode, be careful to enable CRC calculation only \r
- when the clock is stable, that is, when the clock is in the steady state. \r
- If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive \r
- to the SCK slave input clock as soon as CRCEN is set, and this, whatever \r
- the value of the SPE bit.\r
-\r
- - With high bitrate frequencies, be careful when transmitting the CRC.\r
- As the number of used CPU cycles has to be as low as possible in the CRC \r
- transfer phase, it is forbidden to call software functions in the CRC \r
- transmission sequence to avoid errors in the last data and CRC reception. \r
- In fact, CRCNEXT bit has to be written before the end of the transmission/reception \r
- of the last data.\r
-\r
- - For high bit rate frequencies, it is advised to use the DMA mode to avoid the\r
- degradation of the SPI speed performance due to CPU accesses impacting the \r
- SPI bandwidth.\r
-\r
- - When the STM32L15xxx are configured as slaves and the NSS hardware mode is \r
- used, the NSS pin needs to be kept low between the data phase and the CRC \r
- phase.\r
-\r
- - When the SPI is configured in slave mode with the CRC feature enabled, CRC\r
- calculation takes place even if a high level is applied on the NSS pin. \r
- This may happen for example in case of a multislave environment where the \r
- communication master addresses slaves alternately.\r
-\r
- - Between a slave deselection (high level on NSS) and a new slave selection \r
- (low level on NSS), the CRC value should be cleared on both master and slave\r
- sides in order to resynchronize the master and slave for their respective \r
- CRC calculation.\r
-\r
- To clear the CRC, follow the procedure below:\r
- 1. Disable SPI using the SPI_Cmd() function\r
- 2. Disable the CRC calculation using the SPI_CalculateCRC() function.\r
- 3. Enable the CRC calculation using the SPI_CalculateCRC() function.\r
- 4. Enable SPI using the SPI_Cmd() function.\r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Enables or disables the CRC value calculation of the transferred bytes.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param NewState: new state of the SPIx CRC value calculation.\r
- * This parameter can be: ENABLE or DISABLE.\r
- * @retval None\r
- */\r
-void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_FUNCTIONAL_STATE(NewState));\r
- if (NewState != DISABLE)\r
- {\r
- /* Enable the selected SPI CRC calculation */\r
- SPIx->CR1 |= SPI_CR1_CRCEN;\r
- }\r
- else\r
- {\r
- /* Disable the selected SPI CRC calculation */\r
- SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);\r
- }\r
-}\r
-\r
-/**\r
- * @brief Transmit the SPIx CRC value.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @retval None\r
- */\r
-void SPI_TransmitCRC(SPI_TypeDef* SPIx)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- \r
- /* Enable the selected SPI CRC transmission */\r
- SPIx->CR1 |= SPI_CR1_CRCNEXT;\r
-}\r
-\r
-/**\r
- * @brief Returns the transmit or the receive CRC register value for the specified SPI.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @param SPI_CRC: specifies the CRC register to be read.\r
- * This parameter can be one of the following values:\r
- * @arg SPI_CRC_Tx: Selects Tx CRC register\r
- * @arg SPI_CRC_Rx: Selects Rx CRC register\r
- * @retval The selected CRC register value..\r
- */\r
-uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)\r
-{\r
- uint16_t crcreg = 0;\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_CRC(SPI_CRC));\r
- if (SPI_CRC != SPI_CRC_Rx)\r
- {\r
- /* Get the Tx CRC register */\r
- crcreg = SPIx->TXCRCR;\r
- }\r
- else\r
- {\r
- /* Get the Rx CRC register */\r
- crcreg = SPIx->RXCRCR;\r
- }\r
- /* Return the selected CRC register */\r
- return crcreg;\r
-}\r
-\r
-/**\r
- * @brief Returns the CRC Polynomial register value for the specified SPI.\r
- * @param SPIx: where x can be 1 or 2 to select the SPI peripheral.\r
- * @retval The CRC Polynomial register value.\r
- */\r
-uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- \r
- /* Return the CRC polynomial register */\r
- return SPIx->CRCPR;\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SPI_Group4 DMA transfers management functions\r
- * @brief DMA transfers management functions\r
- *\r
-@verbatim \r
- ===============================================================================\r
- DMA transfers management functions\r
- =============================================================================== \r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Enables or disables the SPIx DMA interface.\r
- * @param SPIx: where x can be 1 or 2 in SPI mode \r
- * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. \r
- * This parameter can be any combination of the following values:\r
- * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request\r
- * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request\r
- * @param NewState: new state of the selected SPI DMA transfer request.\r
- * This parameter can be: ENABLE or DISABLE.\r
- * @retval None\r
- */\r
-void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_FUNCTIONAL_STATE(NewState));\r
- assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));\r
-\r
- if (NewState != DISABLE)\r
- {\r
- /* Enable the selected SPI DMA requests */\r
- SPIx->CR2 |= SPI_I2S_DMAReq;\r
- }\r
- else\r
- {\r
- /* Disable the selected SPI DMA requests */\r
- SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;\r
- }\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/** @defgroup SPI_Group5 Interrupts and flags management functions\r
- * @brief Interrupts and flags management functions\r
- *\r
-@verbatim \r
- ===============================================================================\r
- Interrupts and flags management functions\r
- =============================================================================== \r
-\r
- This section provides a set of functions allowing to configure the SPI Interrupts \r
- sources and check or clear the flags or pending bits status.\r
- The user should identify which mode will be used in his application to manage \r
- the communication: Polling mode, Interrupt mode or DMA mode. \r
- \r
- Polling Mode\r
- =============\r
- In Polling Mode, the SPI communication can be managed by 6 flags:\r
- 1. SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register\r
- 2. SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register\r
- 3. SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.\r
- 4. SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur \r
- 5. SPI_FLAG_MODF : to indicate if a Mode Fault error occur\r
- 6. SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur\r
-\r
-Note: Do not use the BSY flag to handle each data transmission or reception.\r
------ It is better to use the TXE and RXNE flags instead.\r
-\r
- In this Mode it is advised to use the following functions:\r
- - FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);\r
- - void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);\r
-\r
- Interrupt Mode\r
- ===============\r
- In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources\r
- and 5 pending bits: \r
- Pending Bits:\r
- ------------- \r
- 1. SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register\r
- 2. SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register\r
- 3. SPI_IT_CRCERR : to indicate if a CRC Calculation error occur \r
- 4. SPI_IT_MODF : to indicate if a Mode Fault error occur\r
- 5. SPI_I2S_IT_OVR : to indicate if an Overrun error occur\r
-\r
- Interrupt Source:\r
- -----------------\r
- 1. SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty \r
- interrupt. \r
- 2. SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not \r
- empty interrupt.\r
- 3. SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.\r
-\r
- In this Mode it is advised to use the following functions:\r
- - void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);\r
- - ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);\r
- - void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);\r
-\r
- DMA Mode\r
- ========\r
- In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests:\r
- 1. SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request\r
- 2. SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request\r
-\r
- In this Mode it is advised to use the following function:\r
- - void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);\r
-\r
-@endverbatim\r
- * @{\r
- */\r
-\r
-/**\r
- * @brief Enables or disables the specified SPI interrupts.\r
- * @param SPIx: where x can be 1 or 2 in SPI mode \r
- * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled. \r
- * This parameter can be one of the following values:\r
- * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask\r
- * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask\r
- * @arg SPI_I2S_IT_ERR: Error interrupt mask\r
- * @param NewState: new state of the specified SPI interrupt.\r
- * This parameter can be: ENABLE or DISABLE.\r
- * @retval None\r
- */\r
-void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)\r
-{\r
- uint16_t itpos = 0, itmask = 0 ;\r
- \r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_FUNCTIONAL_STATE(NewState));\r
- assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));\r
-\r
- /* Get the SPI IT index */\r
- itpos = SPI_I2S_IT >> 4;\r
-\r
- /* Set the IT mask */\r
- itmask = (uint16_t)1 << (uint16_t)itpos;\r
-\r
- if (NewState != DISABLE)\r
- {\r
- /* Enable the selected SPI interrupt */\r
- SPIx->CR2 |= itmask;\r
- }\r
- else\r
- {\r
- /* Disable the selected SPI interrupt */\r
- SPIx->CR2 &= (uint16_t)~itmask;\r
- }\r
-}\r
-\r
-/**\r
- * @brief Checks whether the specified SPI flag is set or not.\r
- * @param SPIx: where x can be 1 or 2 in SPI mode \r
- * @param SPI_I2S_FLAG: specifies the SPI flag to check. \r
- * This parameter can be one of the following values:\r
- * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.\r
- * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.\r
- * @arg SPI_I2S_FLAG_BSY: Busy flag.\r
- * @arg SPI_I2S_FLAG_OVR: Overrun flag.\r
- * @arg SPI_I2S_FLAG_MODF: Mode Fault flag.\r
- * @arg SPI_I2S_FLAG_CRCERR: CRC Error flag.\r
- * @retval The new state of SPI_I2S_FLAG (SET or RESET).\r
- */\r
-FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)\r
-{\r
- FlagStatus bitstatus = RESET;\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));\r
- \r
- /* Check the status of the specified SPI flag */\r
- if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)\r
- {\r
- /* SPI_I2S_FLAG is set */\r
- bitstatus = SET;\r
- }\r
- else\r
- {\r
- /* SPI_I2S_FLAG is reset */\r
- bitstatus = RESET;\r
- }\r
- /* Return the SPI_I2S_FLAG status */\r
- return bitstatus;\r
-}\r
-\r
-/**\r
- * @brief Clears the SPIx CRC Error (CRCERR) flag.\r
- * @param SPIx: where x can be 1 or 2 in SPI mode \r
- * @param SPI_I2S_FLAG: specifies the SPI flag to clear. \r
- * This function clears only CRCERR flag.\r
- * @note\r
- * - OVR (OverRun error) flag is cleared by software sequence: a read \r
- * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read \r
- * operation to SPI_SR register (SPI_I2S_GetFlagStatus()).\r
- * - MODF (Mode Fault) flag is cleared by software sequence: a read/write \r
- * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a \r
- * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).\r
- * @retval None\r
- */\r
-void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)\r
-{\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG));\r
- \r
- /* Clear the selected SPI CRC Error (CRCERR) flag */\r
- SPIx->SR = (uint16_t)~SPI_I2S_FLAG;\r
-}\r
-\r
-/**\r
- * @brief Checks whether the specified SPI interrupt has occurred or not.\r
- * @param SPIx: where x can be\r
- * - 1 or 2 in SPI mode \r
- * @param SPI_I2S_IT: specifies the SPI interrupt source to check. \r
- * This parameter can be one of the following values:\r
- * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.\r
- * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.\r
- * @arg SPI_I2S_IT_OVR: Overrun interrupt.\r
- * @arg SPI_I2S_IT_MODF: Mode Fault interrupt.\r
- * @arg SPI_I2S_IT_CRCERR: CRC Error interrupt.\r
- * @retval The new state of SPI_I2S_IT (SET or RESET).\r
- */\r
-ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)\r
-{\r
- ITStatus bitstatus = RESET;\r
- uint16_t itpos = 0, itmask = 0, enablestatus = 0;\r
-\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));\r
-\r
- /* Get the SPI_I2S_IT index */\r
- itpos = 0x01 << (SPI_I2S_IT & 0x0F);\r
-\r
- /* Get the SPI_I2S_IT IT mask */\r
- itmask = SPI_I2S_IT >> 4;\r
-\r
- /* Set the IT mask */\r
- itmask = 0x01 << itmask;\r
-\r
- /* Get the SPI_I2S_IT enable bit status */\r
- enablestatus = (SPIx->CR2 & itmask) ;\r
-\r
- /* Check the status of the specified SPI interrupt */\r
- if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)\r
- {\r
- /* SPI_I2S_IT is set */\r
- bitstatus = SET;\r
- }\r
- else\r
- {\r
- /* SPI_I2S_IT is reset */\r
- bitstatus = RESET;\r
- }\r
- /* Return the SPI_I2S_IT status */\r
- return bitstatus;\r
-}\r
-\r
-/**\r
- * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit.\r
- * @param SPIx: where x can be\r
- * - 1 or 2 in SPI mode \r
- * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear.\r
- * This function clears only CRCERR interrupt pending bit. \r
- * @note\r
- * - OVR (OverRun Error) interrupt pending bit is cleared by software \r
- * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) \r
- * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()).\r
- * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence:\r
- * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) \r
- * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable \r
- * the SPI).\r
- * @retval None\r
- */\r
-void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)\r
-{\r
- uint16_t itpos = 0;\r
- /* Check the parameters */\r
- assert_param(IS_SPI_ALL_PERIPH(SPIx));\r
- assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT));\r
-\r
- /* Get the SPI_I2S IT index */\r
- itpos = 0x01 << (SPI_I2S_IT & 0x0F);\r
-\r
- /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */\r
- SPIx->SR = (uint16_t)~itpos;\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
-\r
-/**\r
- * @}\r
- */ \r
-\r
-/**\r
- * @}\r
- */ \r
-\r
-/**\r
- * @}\r
- */ \r
-\r
-/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/\r