STM8L15x Standard Peripherals Drivers
|
stm8l15x_spi.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm8l15x_spi.c 00004 * @author MCD Application Team 00005 * @version V1.5.0 00006 * @date 13-May-2011 00007 * @brief This file provides firmware functions to manage the following 00008 * functionalities of the Serial peripheral interface (SPI): 00009 * - Initialization and Configuration 00010 * - Data transfers functions 00011 * - Hardware CRC Calculation 00012 * - DMA transfers management 00013 * - Interrupts and flags management 00014 * 00015 * @verbatim 00016 * 00017 * =================================================================== 00018 * How to use this driver 00019 * =================================================================== 00020 * 1. Enable peripheral clock using CLK_PeripheralClockConfig(CLK_Peripheral_SPIx, 00021 * ENABLE) function (Refer to the product datasheet for the available SPI 00022 * peripherals) 00023 * 00024 * 2. Enable the external Pull-up on the used SPI Pins using the 00025 * GPIO_ExternalPullUpConfig() function or an eternal pull-up equivalent resistor 00026 * (RPU = 45 KOhm typical value). 00027 * 00028 * 00029 * 3. Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave 00030 * Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() 00031 * function. 00032 * 00033 * 4. Enable the corresponding interrupt using the function SPI_ITConfig() if you 00034 * need to use interrupt mode. 00035 * 00036 * 5. When using the DMA mode 00037 * - Configure the DMA using DMA_Init() function 00038 * - Active the needed channel Request using SPI_DMACmd() function 00039 * 00040 * 6. Enable the SPI using the SPI_Cmd() function. 00041 * 00042 * 7. Enable the DMA using the DMA_Cmd() function when using DMA mode. 00043 * 00044 * 8. Optionally you can enable/configure the following parameters without 00045 * re-initialization (i.e there is no need to call again SPI_Init() function): 00046 * - When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx) 00047 * is programmed as Data direction parameter using the SPI_Init() function 00048 * it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx 00049 * using the SPI_BiDirectionalLineConfig() function. 00050 * - When SPI_NSS_Soft is selected as Slave Select Management parameter 00051 * using the SPI_Init() function it can be possible to manage the 00052 * NSS internal signal using the SPI_NSSInternalSoftwareConfig() function. 00053 * 00054 * 9. To use the CRC Hardware calculation feature refer to the Peripheral 00055 * CRC hardware Calculation subsection. 00056 * 00057 * @endverbatim 00058 * 00059 ****************************************************************************** 00060 * @attention 00061 * 00062 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00063 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00064 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00065 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00066 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00067 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00068 * 00069 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> 00070 ****************************************************************************** 00071 */ 00072 00073 /* Includes ------------------------------------------------------------------*/ 00074 #include "stm8l15x_spi.h" 00075 00076 /** @addtogroup STM8L15x_StdPeriph_Driver 00077 * @{ 00078 */ 00079 00080 /** @defgroup SPI 00081 * @brief SPI driver modules 00082 * @{ 00083 */ 00084 00085 /* Private typedef -----------------------------------------------------------*/ 00086 /* Private define ------------------------------------------------------------*/ 00087 /* Private macro -------------------------------------------------------------*/ 00088 /* Private variables ---------------------------------------------------------*/ 00089 /* Private function prototypes -----------------------------------------------*/ 00090 /* Private functions ---------------------------------------------------------*/ 00091 00092 /** @defgroup SPI_Private_Functions 00093 * @{ 00094 */ 00095 00096 /** @defgroup SPI_Group1 Initialization and Configuration functions 00097 * @brief Initialization and Configuration functions 00098 * 00099 @verbatim 00100 =============================================================================== 00101 Initialization and Configuration functions 00102 =============================================================================== 00103 00104 This section provides a set of functions allowing to initialize the SPI Direction, 00105 SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud 00106 Rate Prescaler, SPI First Bit and SPI CRC Polynomial. 00107 00108 The SPI_Init() function follows the SPI configuration procedures for Master mode 00109 and Slave mode (details for these procedures are available in reference manual 00110 (RM0031)). 00111 00112 @endverbatim 00113 * @{ 00114 */ 00115 00116 /** 00117 * @brief Deinitializes the SPI peripheral registers to their default reset values. 00118 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00119 * @param None 00120 * @retval None 00121 */ 00122 void SPI_DeInit(SPI_TypeDef* SPIx) 00123 { 00124 SPIx->CR1 = SPI_CR1_RESET_VALUE; 00125 SPIx->CR2 = SPI_CR2_RESET_VALUE; 00126 SPIx->CR3 = SPI_CR3_RESET_VALUE; 00127 SPIx->SR = SPI_SR_RESET_VALUE; 00128 SPIx->CRCPR = SPI_CRCPR_RESET_VALUE; 00129 } 00130 00131 /** 00132 * @brief Initializes the SPI according to the specified parameters. 00133 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00134 * @param SPI_FirstBit: This parameter can be any of the 00135 * This parameter can be one of the following values: 00136 * @arg SPI_FirstBit_MSB: MSB bit will be transmitted first 00137 * @arg SPI_FirstBit_LSB: LSB bit will be transmitted first 00138 * @param SPI_BaudRatePrescaler: This parameter can be any of the 00139 * This parameter can be one of the following values: 00140 * @arg SPI_BaudRatePrescaler_2: SPI frequency = frequency(CPU)/2 00141 * @arg SPI_BaudRatePrescaler_4: SPI frequency = frequency(CPU)/4 00142 * @arg SPI_BaudRatePrescaler_8: SPI frequency = frequency(CPU)/8 00143 * @arg SPI_BaudRatePrescaler_16: SPI frequency = frequency(CPU)/16 00144 * @arg SPI_BaudRatePrescaler_32: SPI frequency = frequency(CPU)/32 00145 * @arg SPI_BaudRatePrescaler_64: SPI frequency = frequency(CPU)/64 00146 * @arg SPI_BaudRatePrescaler_128: SPI frequency = frequency(CPU)/128 00147 * @arg SPI_BaudRatePrescaler_256: SPI frequency = frequency(CPU)/256 00148 * @param SPI_Mode: Mode 00149 * This parameter can be one of the following values: 00150 * @arg SPI_Mode_Master: SPI Master configuration 00151 * @arg SPI_Mode_Slave: SPI Slave configuration 00152 * @param SPI_CPOL: Clock Polarity 00153 * This parameter can be one of the following values: 00154 * @arg SPI_CPOL_Low: Clock to 0 when idle 00155 * @arg SPI_CPOL_High: Clock to 1 when idle 00156 * @param SPI_CPHA: Clock Phase 00157 * This parameter can be one of the following values: 00158 * @arg SPI_CPHA_1Edge: The first clock transition is the first data capture edge 00159 * @arg SPI_CPHA_2Edge: The second clock transition is the first data capture edge 00160 * @param SPI_Data_Direction: Data direction 00161 * This parameter can be one of the following values: 00162 * @arg SPI_Direction_Rx: Select Rx receive direction in bi-directional mode 00163 * @arg SPI_Direction_Tx: Select Tx transmission direction in bi-directional mode 00164 * @param SPI_Slave_Management: Slave management 00165 * This parameter can be one of the following values: 00166 * @arg SPI_NSS_Soft: Software slave management disabled 00167 * @arg SPI_NSS_Hard: Software slave management enabled 00168 * @param CRCPolynomial: Configures the CRC polynomial. 00169 * @retval None 00170 */ 00171 void SPI_Init(SPI_TypeDef* SPIx, SPI_FirstBit_TypeDef SPI_FirstBit, 00172 SPI_BaudRatePrescaler_TypeDef SPI_BaudRatePrescaler, 00173 SPI_Mode_TypeDef SPI_Mode, SPI_CPOL_TypeDef SPI_CPOL, 00174 SPI_CPHA_TypeDef SPI_CPHA, SPI_DirectionMode_TypeDef SPI_Data_Direction, 00175 SPI_NSS_TypeDef SPI_Slave_Management, uint8_t CRCPolynomial) 00176 { 00177 /* Check structure elements */ 00178 assert_param(IS_SPI_FIRSTBIT(SPI_FirstBit)); 00179 assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); 00180 assert_param(IS_SPI_MODE(SPI_Mode)); 00181 assert_param(IS_SPI_POLARITY(SPI_CPOL)); 00182 assert_param(IS_SPI_PHASE(SPI_CPHA)); 00183 assert_param(IS_SPI_DATA_DIRECTION(SPI_Data_Direction)); 00184 assert_param(IS_SPI_SLAVEMANAGEMENT(SPI_Slave_Management)); 00185 assert_param(IS_SPI_CRC_POLYNOMIAL(CRCPolynomial)); 00186 00187 /* Frame Format, BaudRate, Clock Polarity and Phase configuration */ 00188 SPIx->CR1 = (uint8_t)((uint8_t)((uint8_t)SPI_FirstBit | 00189 (uint8_t)SPI_BaudRatePrescaler) | 00190 (uint8_t)((uint8_t)SPI_CPOL | 00191 SPI_CPHA)); 00192 00193 /* Data direction configuration: BDM, BDOE and RXONLY bits */ 00194 SPIx->CR2 = (uint8_t)((uint8_t)(SPI_Data_Direction) | (uint8_t)(SPI_Slave_Management)); 00195 00196 if (SPI_Mode == SPI_Mode_Master) 00197 { 00198 SPIx->CR2 |= (uint8_t)SPI_CR2_SSI; 00199 } 00200 else 00201 { 00202 SPIx->CR2 &= (uint8_t)~(SPI_CR2_SSI); 00203 } 00204 00205 /* Master/Slave mode configuration */ 00206 SPIx->CR1 |= (uint8_t)(SPI_Mode); 00207 00208 /* CRC configuration */ 00209 SPIx->CRCPR = (uint8_t)CRCPolynomial; 00210 } 00211 00212 /** 00213 * @brief Enables or disables the SPI peripheral. 00214 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00215 * @param NewState New state of the SPI peripheral. 00216 * This parameter can be: ENABLE or DISABLE 00217 * @retval None 00218 */ 00219 void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) 00220 { 00221 /* Check function parameters */ 00222 assert_param(IS_FUNCTIONAL_STATE(NewState)); 00223 00224 if (NewState != DISABLE) 00225 { 00226 SPIx->CR1 |= SPI_CR1_SPE; /* Enable the SPI peripheral*/ 00227 } 00228 else 00229 { 00230 SPIx->CR1 &= (uint8_t)(~SPI_CR1_SPE); /* Disable the SPI peripheral*/ 00231 } 00232 } 00233 00234 /** 00235 * @brief Configures internally by software the NSS pin. 00236 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00237 * @param NewState Indicates the new state of the SPI Software slave management. 00238 * This parameter can be: ENABLE or DISABLE. 00239 * @retval None 00240 */ 00241 void SPI_NSSInternalSoftwareCmd(SPI_TypeDef* SPIx, FunctionalState NewState) 00242 { 00243 /* Check function parameters */ 00244 assert_param(IS_FUNCTIONAL_STATE(NewState)); 00245 00246 if (NewState != DISABLE) 00247 { 00248 SPIx->CR2 |= SPI_CR2_SSI; /* Set NSS pin internally by software*/ 00249 } 00250 else 00251 { 00252 SPIx->CR2 &= (uint8_t)(~SPI_CR2_SSI); /* Reset NSS pin internally by software*/ 00253 } 00254 } 00255 00256 /** 00257 * @brief Selects the data transfer direction in Bi-directional mode. 00258 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00259 * @param SPI_Direction Specifies the data transfer direction in Bi-directional mode. 00260 * This parameter can be one of the following values: 00261 * @arg SPI_Direction_Rx: Select Rx receive direction in bi-directional mode 00262 * @arg SPI_Direction_Tx: Select Tx transmission direction in bi-directional mode 00263 * @retval None 00264 */ 00265 void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, SPI_Direction_TypeDef SPI_Direction) 00266 { 00267 /* Check function parameters */ 00268 assert_param(IS_SPI_DIRECTION(SPI_Direction)); 00269 00270 if (SPI_Direction != SPI_Direction_Rx) 00271 { 00272 SPIx->CR2 |= SPI_CR2_BDOE; /* Set the Tx only mode*/ 00273 } 00274 else 00275 { 00276 SPIx->CR2 &= (uint8_t)(~SPI_CR2_BDOE); /* Set the Rx only mode*/ 00277 } 00278 } 00279 00280 /** 00281 * @} 00282 */ 00283 00284 /** @defgroup SPI_Group2 Data transfers functions 00285 * @brief Data transfers functions 00286 * 00287 @verbatim 00288 =============================================================================== 00289 Data transfers functions 00290 =============================================================================== 00291 00292 This section provides a set of functions allowing to manage the SPI data transfers 00293 00294 In reception, data are received and then stored into an internal Rx buffer while 00295 In transmission, data are first stored into an internal Tx buffer before being 00296 transmitted. 00297 00298 The read access of the SPI_DR register can be done using the SPI_ReceiveData() 00299 function and returns the Rx buffered value. Whereas a write access to the SPI_DR 00300 can be done using SPI_SendData() function and stores the written data into 00301 Tx buffer. 00302 00303 @endverbatim 00304 * @{ 00305 */ 00306 00307 /** 00308 * @brief Transmits a Data through the SPI peripheral. 00309 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00310 * @param Data: Byte to be transmitted. 00311 * @retval None 00312 */ 00313 void SPI_SendData(SPI_TypeDef* SPIx, uint8_t Data) 00314 { 00315 SPIx->DR = Data; /* Write in the DR register the data to be sent*/ 00316 } 00317 00318 /** 00319 * @brief Returns the most recent received data by the SPI peripheral. 00320 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00321 * @retval The value of the received data. 00322 */ 00323 uint8_t SPI_ReceiveData(SPI_TypeDef* SPIx) 00324 { 00325 return ((uint8_t)SPIx->DR); /* Return the data in the DR register*/ 00326 } 00327 00328 /** 00329 * @} 00330 */ 00331 00332 /** @defgroup SPI_Group3 Hardware CRC Calculation functions 00333 * @brief Hardware CRC Calculation functions 00334 * 00335 @verbatim 00336 =============================================================================== 00337 Hardware CRC Calculation functions 00338 =============================================================================== 00339 00340 This section provides a set of functions allowing to manage the SPI CRC hardware 00341 calculation 00342 00343 SPI communication using CRC is possible through the following procedure: 00344 1. Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler, 00345 Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() 00346 function. 00347 2. Enable the CRC calculation using the SPI_CalculateCRC() function. 00348 3. Enable the SPI using the SPI_Cmd() function 00349 4. Before writing the last data to the TX buffer, set the CRCNext bit using the 00350 SPI_TransmitCRC() function to indicate that after transmission of the last 00351 data, the CRC should be transmitted. 00352 5. After transmitting the last data, the SPI transmits the CRC. The SPI_CR2_CRCNEXT 00353 bit is reset. The CRC is also received and compared against the SPI_RXCRCR 00354 value. 00355 If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt 00356 can be generated when the SPI_IT_ERR interrupt is enabled. 00357 00358 Note: 00359 ----- 00360 - It is advised to don't read the calculate CRC values during the communication. 00361 00362 - When the SPI is in slave mode, be careful to enable CRC calculation only 00363 when the clock is stable, that is, when the clock is in the steady state. 00364 If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive 00365 to the SCK slave input clock as soon as CRCEN is set, and this, whatever 00366 the value of the SPE bit. 00367 00368 - With high bitrate frequencies, be careful when transmitting the CRC. 00369 As the number of used CPU cycles has to be as low as possible in the CRC 00370 transfer phase, it is forbidden to call software functions in the CRC 00371 transmission sequence to avoid errors in the last data and CRC reception. 00372 In fact, CRCNEXT bit has to be written before the end of the transmission/reception 00373 of the last data. 00374 00375 - For high bit rate frequencies, it is advised to use the DMA mode to avoid the 00376 degradation of the SPI speed performance due to CPU accesses impacting the 00377 SPI bandwidth. 00378 00379 - When the STM8L15x are configured as slaves and the NSS hardware mode is 00380 used, the NSS pin needs to be kept low between the data phase and the CRC 00381 phase. 00382 00383 - When the SPI is configured in slave mode with the CRC feature enabled, CRC 00384 calculation takes place even if a high level is applied on the NSS pin. 00385 This may happen for example in case of a multislave environment where the 00386 communication master addresses slaves alternately. 00387 00388 - Between a slave de-selection (high level on NSS) and a new slave selection 00389 (low level on NSS), the CRC value should be cleared on both master and slave 00390 sides in order to resynchronize the master and slave for their respective 00391 CRC calculation. 00392 00393 To clear the CRC, follow the procedure below: 00394 1. Disable SPI using the SPI_Cmd() function 00395 2. Disable the CRC calculation using the SPI_CalculateCRC() function. 00396 3. Enable the CRC calculation using the SPI_CalculateCRC() function. 00397 4. Enable SPI using the SPI_Cmd() function. 00398 00399 @endverbatim 00400 * @{ 00401 */ 00402 00403 /** 00404 * @brief Enables the transmit of the CRC value. 00405 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00406 * @retval None 00407 */ 00408 void SPI_TransmitCRC(SPI_TypeDef* SPIx) 00409 { 00410 SPIx->CR2 |= SPI_CR2_CRCNEXT; /* Enable the CRC transmission*/ 00411 } 00412 00413 /** 00414 * @brief Enables or disables the CRC value calculation of the transferred bytes. 00415 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00416 * @param NewState Indicates the new state of the SPI CRC value calculation. 00417 * This parameter can be: ENABLE or DISABLE. 00418 * @retval None 00419 */ 00420 void SPI_CalculateCRCCmd(SPI_TypeDef* SPIx, FunctionalState NewState) 00421 { 00422 /* Check function parameters */ 00423 assert_param(IS_FUNCTIONAL_STATE(NewState)); 00424 00425 /* SPI must be disable for correct operation od Hardware CRC calculation */ 00426 SPI_Cmd(SPI1, DISABLE); 00427 00428 if (NewState != DISABLE) 00429 { 00430 SPIx->CR2 |= SPI_CR2_CRCEN; /* Enable the CRC calculation*/ 00431 } 00432 else 00433 { 00434 SPIx->CR2 &= (uint8_t)(~SPI_CR2_CRCEN); /* Disable the CRC calculation*/ 00435 } 00436 } 00437 00438 /** 00439 * @brief Returns the transmit or the receive CRC register value. 00440 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00441 * @param SPI_CRC: Specifies the CRC register to be read. 00442 * This parameter can be one of the following values: 00443 * @arg SPI_CRC_RX: Select Tx CRC register 00444 * @arg SPI_CRC_TX: Select Rx CRC register 00445 * @retval The selected CRC register value. 00446 */ 00447 uint8_t SPI_GetCRC(SPI_TypeDef* SPIx, SPI_CRC_TypeDef SPI_CRC) 00448 { 00449 uint8_t crcreg = 0; 00450 00451 /* Check function parameters */ 00452 assert_param(IS_SPI_CRC(SPI_CRC)); 00453 00454 if (SPI_CRC != SPI_CRC_RX) 00455 { 00456 crcreg = SPIx->TXCRCR; /* Get the Tx CRC register*/ 00457 } 00458 else 00459 { 00460 crcreg = SPIx->RXCRCR; /* Get the Rx CRC register*/ 00461 } 00462 00463 /* Return the selected CRC register status*/ 00464 return crcreg; 00465 } 00466 00467 /** 00468 * @brief Reset the Rx CRCR and Tx CRCR registers. 00469 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00470 * @retval None 00471 */ 00472 void SPI_ResetCRC(SPI_TypeDef* SPIx) 00473 { 00474 /* Rx CRCR & Tx CRCR registers are reset when CRCEN (hardware calculation) 00475 bit in SPI_CR2 is written to 1 (enable) */ 00476 SPI_CalculateCRCCmd(SPIx, ENABLE); 00477 00478 /* Previous function disable the SPI */ 00479 SPI_Cmd(SPIx, ENABLE); 00480 } 00481 00482 /** 00483 * @brief Returns the CRC Polynomial register value. 00484 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00485 * @retval uint8_t The CRC Polynomial register value. 00486 */ 00487 uint8_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) 00488 { 00489 return SPIx->CRCPR; /* Return the CRC polynomial register */ 00490 } 00491 00492 /** 00493 * @} 00494 */ 00495 00496 /** @defgroup SPI_Group4 DMA transfers management functions 00497 * @brief DMA transfers management functions 00498 * 00499 @verbatim 00500 =============================================================================== 00501 DMA transfers management functions 00502 =============================================================================== 00503 00504 @endverbatim 00505 * @{ 00506 */ 00507 00508 /** 00509 * @brief Enables or disables the SPI DMA interface. 00510 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00511 * @param SPI_DMAReq Specifies the SPI DMA transfer request to be enabled or disabled. 00512 * This parameter can be one of the following values: 00513 * @arg SPI_DMAReq_RX: SPI DMA Rx transfer requests 00514 * @arg SPI_DMAReq_TX: SPI DMA Tx transfer requests 00515 * @param NewState Indicates the new state of the SPI DMA request. 00516 * This parameter can be: ENABLE or DISABLE. 00517 * @retval None 00518 */ 00519 void SPI_DMACmd(SPI_TypeDef* SPIx, SPI_DMAReq_TypeDef SPI_DMAReq, FunctionalState NewState) 00520 { 00521 /* Check the parameters */ 00522 assert_param(IS_FUNCTIONAL_STATE(NewState)); 00523 assert_param(IS_SPI_DMAREQ(SPI_DMAReq)); 00524 00525 if (NewState != DISABLE) 00526 { 00527 /* Enable the selected SPI DMA requests */ 00528 SPIx->CR3 |= (uint8_t) SPI_DMAReq; 00529 } 00530 else 00531 { 00532 /* Disable the selected SPI DMA requests */ 00533 SPIx->CR3 &= (uint8_t)~SPI_DMAReq; 00534 } 00535 } 00536 00537 /** 00538 * @} 00539 */ 00540 00541 /** @defgroup SPI_Group5 Interrupts and flags management functions 00542 * @brief Interrupts and flags management functions 00543 * 00544 @verbatim 00545 =============================================================================== 00546 Interrupts and flags management functions 00547 =============================================================================== 00548 00549 This section provides a set of functions allowing to configure the SPI Interrupts 00550 sources and check or clear the flags or pending bits status. 00551 The user should identify which mode will be used in his application to manage 00552 the communication: Polling mode, Interrupt mode or DMA mode. 00553 00554 Polling Mode 00555 ============= 00556 In Polling Mode, the SPI communication can be managed by 6 flags: 00557 1. SPI_FLAG_TXE: to indicate the status of the transmit buffer register 00558 2. SPI_FLAG_RXNE: to indicate the status of the receive buffer register 00559 3. SPI_FLAG_WKUP: to indicate the state of the Wakeup event. 00560 4. SPI_FLAG_CRCERR: to indicate if a CRC Calculation error occurs 00561 5. SPI_FLAG_MODF: to indicate if a Mode Fault error occurs 00562 6. SPI_FLAG_OVR: to indicate if an Overrun error occurs 00563 00564 In this Mode it is advised to use the following functions: 00565 - FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, SPI_FLAG_TypeDef SPI_FLAG); 00566 - void SPI_ClearFlag(SPI_TypeDef* SPIx, SPI_FLAG_TypeDef SPI_FLAG); 00567 00568 Interrupt Mode 00569 =============== 00570 In Interrupt Mode, the SPI communication can be managed by 4 interrupt sources 00571 and 6 pending bits: 00572 Pending Bits: 00573 ------------- 00574 1. SPI_IT_TXE: to indicate the status of the transmit buffer register 00575 2. SPI_IT_RXNE: to indicate the status of the receive buffer register 00576 3. SPI_IT_CRCERR: to indicate if a CRC Calculation error occurs 00577 4. SPI_IT_MODF: to indicate if a Mode Fault error occurs 00578 5. SPI_IT_OVR: to indicate if an Overrun error occurs 00579 6. SPI_IT_WKUP: to indicate if an Wake_up event occurs 00580 Interrupt Source: 00581 ----------------- 00582 1. SPI_IT_TXE: specifies the interrupt source for the Tx buffer empty 00583 interrupt. 00584 2. SPI_IT_RXNE: specifies the interrupt source for the Rx buffer not 00585 empty interrupt. 00586 3. SPI_IT_ERR: specifies the interrupt source for the errors interrupt. 00587 4. SPI_IT_WKUP: specifies the interrupt source for the Wake-up interrupt. 00588 00589 In this Mode it is advised to use the following functions: 00590 - void SPI_ITConfig(SPI_TypeDef* SPIx, SPI_IT_TypeDef SPI_IT, FunctionalState NewState); 00591 - ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, SPI_IT_TypeDef SPI_IT); 00592 - void SPI_ClearITPendingBit(SPI_TypeDef* SPIx, SPI_IT_TypeDef SPI_IT); 00593 00594 DMA Mode 00595 ======== 00596 In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests: 00597 1. SPI_DMAReq_Tx: specifies the Tx buffer DMA transfer request 00598 2. SPI_DMAReq_Rx: specifies the Rx buffer DMA transfer request 00599 00600 In this Mode it is advised to use the following function: 00601 - void SPI_DMACmd(SPI_TypeDef* SPIx, SPI_DMAReq_TypeDef SPI_DMAReq, FunctionalState NewState); 00602 00603 @endverbatim 00604 * @{ 00605 */ 00606 00607 /** 00608 * @brief Enables or disables the specified interrupts. 00609 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00610 * @param SPI_IT Specifies the SPI interrupts sources to be enabled or disabled. 00611 * This parameter can be one of the following values: 00612 * @arg SPI_IT_TXE: Transmit buffer empty 00613 * @arg SPI_IT_RXNE: Receive buffer not empty 00614 * @arg SPI_IT_ERR: Error 00615 * @arg SPI_IT_WKUP: Wake-up 00616 * @param NewState: The new state of the specified SPI interrupts. 00617 * This parameter can be: ENABLE or DISABLE. 00618 * @retval None 00619 */ 00620 void SPI_ITConfig(SPI_TypeDef* SPIx, SPI_IT_TypeDef SPI_IT, FunctionalState NewState) 00621 { 00622 uint8_t itpos = 0; 00623 /* Check function parameters */ 00624 assert_param(IS_SPI_CONFIG_IT(SPI_IT)); 00625 assert_param(IS_FUNCTIONAL_STATE(NewState)); 00626 00627 /* Get the SPI IT index */ 00628 itpos = (uint8_t)((uint8_t)1 << (uint8_t)((uint8_t)SPI_IT & (uint8_t)0x0F)); 00629 00630 if (NewState != DISABLE) 00631 { 00632 SPIx->CR3 |= itpos; /* Enable interrupt*/ 00633 } 00634 else 00635 { 00636 SPIx->CR3 &= (uint8_t)(~itpos); /* Disable interrupt*/ 00637 } 00638 } 00639 00640 /** 00641 * @brief Checks whether the specified SPI flag is set or not. 00642 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00643 * @param SPI_FLAG: Specifies the flag to check. 00644 * This parameter can be one of the following values: 00645 * @arg SPI_FLAG_BSY: Busy 00646 * @arg SPI_FLAG_OVR: Overrun 00647 * @arg SPI_FLAG_MODF: Mode fault 00648 * @arg SPI_FLAG_CRCERR: CRC error 00649 * @arg SPI_FLAG_WKUP: Wake-up 00650 * @arg SPI_FLAG_TXE: Transmit buffer empty 00651 * @arg SPI_FLAG_RXNE: Receive buffer empty 00652 * @retval Indicates the state of SPI_FLAG. 00653 * This parameter can be SET or RESET. 00654 */ 00655 FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, SPI_FLAG_TypeDef SPI_FLAG) 00656 { 00657 FlagStatus status = RESET; 00658 /* Check parameters */ 00659 assert_param(IS_SPI_FLAG(SPI_FLAG)); 00660 00661 /* Check the status of the specified SPI flag */ 00662 if ((SPIx->SR & (uint8_t)SPI_FLAG) != (uint8_t)RESET) 00663 { 00664 status = SET; /* SPI_FLAG is set */ 00665 } 00666 else 00667 { 00668 status = RESET; /* SPI_FLAG is reset*/ 00669 } 00670 00671 /* Return the SPI_FLAG status */ 00672 return status; 00673 } 00674 00675 /** 00676 * @brief Clears the SPI flags. 00677 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00678 * @param SPI_FLAG: Specifies the flag to clear. 00679 * This parameter can be one of the following values: 00680 * @arg SPI_FLAG_CRCERR 00681 * @arg SPI_FLAG_WKUP 00682 * @note OVR (OverRun Error) interrupt pending bit is cleared by software 00683 * sequence: a read operation to SPI_DR register (SPI_ReceiveData()) followed by 00684 * a read operation to SPI_SR register (SPI_GetFlagStatus()). 00685 * @note MODF (Mode Fault) interrupt pending bit is cleared by software sequence: 00686 * a read/write operation to SPI_SR register (SPI_GetFlagStatus()) followed by 00687 * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). 00688 * @retval None 00689 */ 00690 void SPI_ClearFlag(SPI_TypeDef* SPIx, SPI_FLAG_TypeDef SPI_FLAG) 00691 { 00692 assert_param(IS_SPI_CLEAR_FLAG(SPI_FLAG)); 00693 /* Clear the flag bit */ 00694 SPIx->SR = (uint8_t)(~SPI_FLAG); 00695 } 00696 00697 /** 00698 * @brief Checks whether the specified interrupt has occurred or not. 00699 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00700 * @param SPI_IT: Specifies the SPI interrupt pending bit to check. 00701 * This parameter can be one of the following values: 00702 * @arg SPI_IT_CRCERR 00703 * @arg SPI_IT_WKUP 00704 * @arg SPI_IT_OVR 00705 * @arg SPI_IT_MODF 00706 * @arg SPI_IT_RXNE 00707 * @arg SPI_IT_TXE 00708 * @retval Indicates the state of the SPI_IT. 00709 00710 */ 00711 ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, SPI_IT_TypeDef SPI_IT) 00712 { 00713 ITStatus pendingbitstatus = RESET; 00714 uint8_t itpos = 0; 00715 uint8_t itmask1 = 0; 00716 uint8_t itmask2 = 0; 00717 __IO uint8_t enablestatus = 0; 00718 assert_param(IS_SPI_GET_IT(SPI_IT)); 00719 /* Get the SPI IT index */ 00720 itpos = (uint8_t)((uint8_t)1 << ((uint8_t)SPI_IT & (uint8_t)0x0F)); 00721 00722 /* Get the SPI IT mask */ 00723 itmask1 = (uint8_t)((uint8_t)SPI_IT >> (uint8_t)4); 00724 /* Set the IT mask */ 00725 itmask2 = (uint8_t)((uint8_t)1 << itmask1); 00726 /* Get the SPI_IT enable bit status */ 00727 enablestatus = (uint8_t)((uint8_t)SPIx->SR & itmask2); 00728 /* Check the status of the specified SPI interrupt */ 00729 if (((SPIx->CR3 & itpos) != RESET) && enablestatus) 00730 { 00731 /* SPI_IT is set */ 00732 pendingbitstatus = SET; 00733 } 00734 else 00735 { 00736 /* SPI_IT is reset */ 00737 pendingbitstatus = RESET; 00738 } 00739 /* Return the SPI_IT status */ 00740 return pendingbitstatus; 00741 } 00742 00743 /** 00744 * @brief Clears the interrupt pending bits. 00745 * @param SPIx: where x can be 1 to select the specified SPI peripheral. 00746 * @param SPI_IT: Specifies the interrupt pending bit to clear. 00747 * This parameter can be one of the following values: 00748 * @arg SPI_IT_CRCERR 00749 * @arg SPI_IT_WKUP 00750 * @note OVR (OverRun Error) interrupt pending bit is cleared by software sequence: 00751 * a read operation to SPI_DR register (SPI_ReceiveData()) followed by 00752 * a read operation to SPI_SR register (SPI_GetITStatus()). 00753 * @note MODF (Mode Fault) interrupt pending bit is cleared by software sequence: 00754 * a read/write operation to SPI_SR register (SPI_GetITStatus()) followed by 00755 * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). 00756 * @retval None 00757 */ 00758 void SPI_ClearITPendingBit(SPI_TypeDef* SPIx, SPI_IT_TypeDef SPI_IT) 00759 { 00760 uint8_t itpos = 0; 00761 assert_param(IS_SPI_CLEAR_IT(SPI_IT)); 00762 00763 /* Clear SPI_IT_CRCERR or SPI_IT_WKUP interrupt pending bits */ 00764 00765 /* Get the SPI pending bit index */ 00766 itpos = (uint8_t)((uint8_t)1 << (uint8_t)((uint8_t)(SPI_IT & (uint8_t)0xF0) >> 4)); 00767 /* Clear the pending bit */ 00768 SPIx->SR = (uint8_t)(~itpos); 00769 00770 } 00771 00772 /** 00773 * @} 00774 */ 00775 00776 /** 00777 * @} 00778 */ 00779 00780 /** 00781 * @} 00782 */ 00783 00784 /** 00785 * @} 00786 */ 00787 00788 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/