STM8S/A Standard Peripherals Drivers
|
stm8s_spi.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm8s_spi.c 00004 * @author MCD Application Team 00005 * @version V2.3.0 00006 * @date 16-June-2017 00007 * @brief This file contains all the functions for the SPI peripheral. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> 00012 * 00013 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00014 * You may not use this file except in compliance with the License. 00015 * You may obtain a copy of the License at: 00016 * 00017 * http://www.st.com/software_license_agreement_liberty_v2 00018 * 00019 * Unless required by applicable law or agreed to in writing, software 00020 * distributed under the License is distributed on an "AS IS" BASIS, 00021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00022 * See the License for the specific language governing permissions and 00023 * limitations under the License. 00024 * 00025 ****************************************************************************** 00026 */ 00027 00028 /* Includes ------------------------------------------------------------------*/ 00029 #include "stm8s_spi.h" 00030 00031 /** @addtogroup STM8S_StdPeriph_Driver 00032 * @{ 00033 */ 00034 00035 /* Private define ------------------------------------------------------------*/ 00036 /* Private macro -------------------------------------------------------------*/ 00037 /* Private variables ---------------------------------------------------------*/ 00038 /* Private function prototypes -----------------------------------------------*/ 00039 /* Private functions ---------------------------------------------------------*/ 00040 00041 /** @addtogroup SPI_Public_Functions 00042 * @{ 00043 */ 00044 00045 /** 00046 * @brief Deinitializes the SPI peripheral registers to their default reset values. 00047 * @param None 00048 * @retval None 00049 */ 00050 void SPI_DeInit(void) 00051 { 00052 SPI->CR1 = SPI_CR1_RESET_VALUE; 00053 SPI->CR2 = SPI_CR2_RESET_VALUE; 00054 SPI->ICR = SPI_ICR_RESET_VALUE; 00055 SPI->SR = SPI_SR_RESET_VALUE; 00056 SPI->CRCPR = SPI_CRCPR_RESET_VALUE; 00057 } 00058 00059 /** 00060 * @brief Initializes the SPI according to the specified parameters. 00061 * @param FirstBit : This parameter can be any of the 00062 * @ref SPI_FirstBit_TypeDef enumeration. 00063 * @param BaudRatePrescaler : This parameter can be any of the 00064 * @ref SPI_BaudRatePrescaler_TypeDef enumeration. 00065 * @param Mode : This parameter can be any of the 00066 * @ref SPI_Mode_TypeDef enumeration. 00067 * @param ClockPolarity : This parameter can be any of the 00068 * @ref SPI_ClockPolarity_TypeDef enumeration. 00069 * @param ClockPhase : This parameter can be any of the 00070 * @ref SPI_ClockPhase_TypeDef enumeration. 00071 * @param Data_Direction : This parameter can be any of the 00072 * @ref SPI_DataDirection_TypeDef enumeration. 00073 * @param Slave_Management : This parameter can be any of the 00074 * @ref SPI_NSS_TypeDef enumeration. 00075 * @param CRCPolynomial : Configures the CRC polynomial. 00076 * @retval None 00077 */ 00078 void SPI_Init(SPI_FirstBit_TypeDef FirstBit, SPI_BaudRatePrescaler_TypeDef BaudRatePrescaler, SPI_Mode_TypeDef Mode, SPI_ClockPolarity_TypeDef ClockPolarity, SPI_ClockPhase_TypeDef ClockPhase, SPI_DataDirection_TypeDef Data_Direction, SPI_NSS_TypeDef Slave_Management, uint8_t CRCPolynomial) 00079 { 00080 /* Check structure elements */ 00081 assert_param(IS_SPI_FIRSTBIT_OK(FirstBit)); 00082 assert_param(IS_SPI_BAUDRATE_PRESCALER_OK(BaudRatePrescaler)); 00083 assert_param(IS_SPI_MODE_OK(Mode)); 00084 assert_param(IS_SPI_POLARITY_OK(ClockPolarity)); 00085 assert_param(IS_SPI_PHASE_OK(ClockPhase)); 00086 assert_param(IS_SPI_DATA_DIRECTION_OK(Data_Direction)); 00087 assert_param(IS_SPI_SLAVEMANAGEMENT_OK(Slave_Management)); 00088 assert_param(IS_SPI_CRC_POLYNOMIAL_OK(CRCPolynomial)); 00089 00090 /* Frame Format, BaudRate, Clock Polarity and Phase configuration */ 00091 SPI->CR1 = (uint8_t)((uint8_t)((uint8_t)FirstBit | BaudRatePrescaler) | 00092 (uint8_t)((uint8_t)ClockPolarity | ClockPhase)); 00093 00094 /* Data direction configuration: BDM, BDOE and RXONLY bits */ 00095 SPI->CR2 = (uint8_t)((uint8_t)(Data_Direction) | (uint8_t)(Slave_Management)); 00096 00097 if (Mode == SPI_MODE_MASTER) 00098 { 00099 SPI->CR2 |= (uint8_t)SPI_CR2_SSI; 00100 } 00101 else 00102 { 00103 SPI->CR2 &= (uint8_t)~(SPI_CR2_SSI); 00104 } 00105 00106 /* Master/Slave mode configuration */ 00107 SPI->CR1 |= (uint8_t)(Mode); 00108 00109 /* CRC configuration */ 00110 SPI->CRCPR = (uint8_t)CRCPolynomial; 00111 } 00112 00113 /** 00114 * @brief Enables or disables the SPI peripheral. 00115 * @param NewState New state of the SPI peripheral. 00116 * This parameter can be: ENABLE or DISABLE 00117 * @retval None 00118 */ 00119 void SPI_Cmd(FunctionalState NewState) 00120 { 00121 /* Check function parameters */ 00122 assert_param(IS_FUNCTIONALSTATE_OK(NewState)); 00123 00124 if (NewState != DISABLE) 00125 { 00126 SPI->CR1 |= SPI_CR1_SPE; /* Enable the SPI peripheral*/ 00127 } 00128 else 00129 { 00130 SPI->CR1 &= (uint8_t)(~SPI_CR1_SPE); /* Disable the SPI peripheral*/ 00131 } 00132 } 00133 00134 /** 00135 * @brief Enables or disables the specified interrupts. 00136 * @param SPI_IT Specifies the SPI interrupts sources to be enabled or disabled. 00137 * @param NewState: The new state of the specified SPI interrupts. 00138 * This parameter can be: ENABLE or DISABLE. 00139 * @retval None 00140 */ 00141 void SPI_ITConfig(SPI_IT_TypeDef SPI_IT, FunctionalState NewState) 00142 { 00143 uint8_t itpos = 0; 00144 /* Check function parameters */ 00145 assert_param(IS_SPI_CONFIG_IT_OK(SPI_IT)); 00146 assert_param(IS_FUNCTIONALSTATE_OK(NewState)); 00147 00148 /* Get the SPI IT index */ 00149 itpos = (uint8_t)((uint8_t)1 << (uint8_t)((uint8_t)SPI_IT & (uint8_t)0x0F)); 00150 00151 if (NewState != DISABLE) 00152 { 00153 SPI->ICR |= itpos; /* Enable interrupt*/ 00154 } 00155 else 00156 { 00157 SPI->ICR &= (uint8_t)(~itpos); /* Disable interrupt*/ 00158 } 00159 } 00160 00161 /** 00162 * @brief Transmits a Data through the SPI peripheral. 00163 * @param Data : Byte to be transmitted. 00164 * @retval None 00165 */ 00166 void SPI_SendData(uint8_t Data) 00167 { 00168 SPI->DR = Data; /* Write in the DR register the data to be sent*/ 00169 } 00170 00171 /** 00172 * @brief Returns the most recent received data by the SPI peripheral. 00173 * @param None 00174 * @retval The value of the received data. 00175 */ 00176 uint8_t SPI_ReceiveData(void) 00177 { 00178 return ((uint8_t)SPI->DR); /* Return the data in the DR register*/ 00179 } 00180 00181 /** 00182 * @brief Configures internally by software the NSS pin. 00183 * @param NewState Indicates the new state of the SPI Software slave management. 00184 * This parameter can be: ENABLE or DISABLE. 00185 * @retval None 00186 */ 00187 void SPI_NSSInternalSoftwareCmd(FunctionalState NewState) 00188 { 00189 /* Check function parameters */ 00190 assert_param(IS_FUNCTIONALSTATE_OK(NewState)); 00191 00192 if (NewState != DISABLE) 00193 { 00194 SPI->CR2 |= SPI_CR2_SSI; /* Set NSS pin internally by software*/ 00195 } 00196 else 00197 { 00198 SPI->CR2 &= (uint8_t)(~SPI_CR2_SSI); /* Reset NSS pin internally by software*/ 00199 } 00200 } 00201 00202 /** 00203 * @brief Enables the transmit of the CRC value. 00204 * @param None 00205 * @retval None 00206 */ 00207 void SPI_TransmitCRC(void) 00208 { 00209 SPI->CR2 |= SPI_CR2_CRCNEXT; /* Enable the CRC transmission*/ 00210 } 00211 00212 /** 00213 * @brief Enables or disables the CRC value calculation of the transferred bytes. 00214 * @param NewState Indicates the new state of the SPI CRC value calculation. 00215 * This parameter can be: ENABLE or DISABLE. 00216 * @retval None 00217 */ 00218 void SPI_CalculateCRCCmd(FunctionalState NewState) 00219 { 00220 /* Check function parameters */ 00221 assert_param(IS_FUNCTIONALSTATE_OK(NewState)); 00222 00223 if (NewState != DISABLE) 00224 { 00225 SPI->CR2 |= SPI_CR2_CRCEN; /* Enable the CRC calculation*/ 00226 } 00227 else 00228 { 00229 SPI->CR2 &= (uint8_t)(~SPI_CR2_CRCEN); /* Disable the CRC calculation*/ 00230 } 00231 } 00232 00233 /** 00234 * @brief Returns the transmit or the receive CRC register value. 00235 * @param SPI_CRC Specifies the CRC register to be read. 00236 * @retval The selected CRC register value. 00237 */ 00238 uint8_t SPI_GetCRC(SPI_CRC_TypeDef SPI_CRC) 00239 { 00240 uint8_t crcreg = 0; 00241 00242 /* Check function parameters */ 00243 assert_param(IS_SPI_CRC_OK(SPI_CRC)); 00244 00245 if (SPI_CRC != SPI_CRC_RX) 00246 { 00247 crcreg = SPI->TXCRCR; /* Get the Tx CRC register*/ 00248 } 00249 else 00250 { 00251 crcreg = SPI->RXCRCR; /* Get the Rx CRC register*/ 00252 } 00253 00254 /* Return the selected CRC register status*/ 00255 return crcreg; 00256 } 00257 00258 /** 00259 * @brief Reset the Rx CRCR and Tx CRCR registers. 00260 * @param None 00261 * @retval None 00262 */ 00263 void SPI_ResetCRC(void) 00264 { 00265 /* Rx CRCR & Tx CRCR registers are reset when CRCEN (hardware calculation) 00266 bit in SPI_CR2 is written to 1 (enable) */ 00267 SPI_CalculateCRCCmd(ENABLE); 00268 00269 /* Previous function disable the SPI */ 00270 SPI_Cmd(ENABLE); 00271 } 00272 00273 /** 00274 * @brief Returns the CRC Polynomial register value. 00275 * @param None 00276 * @retval The CRC Polynomial register value. 00277 */ 00278 uint8_t SPI_GetCRCPolynomial(void) 00279 { 00280 return SPI->CRCPR; /* Return the CRC polynomial register */ 00281 } 00282 00283 /** 00284 * @brief Selects the data transfer direction in bi-directional mode. 00285 * @param SPI_Direction Specifies the data transfer direction in bi-directional mode. 00286 * @retval None 00287 */ 00288 void SPI_BiDirectionalLineConfig(SPI_Direction_TypeDef SPI_Direction) 00289 { 00290 /* Check function parameters */ 00291 assert_param(IS_SPI_DIRECTION_OK(SPI_Direction)); 00292 00293 if (SPI_Direction != SPI_DIRECTION_RX) 00294 { 00295 SPI->CR2 |= SPI_CR2_BDOE; /* Set the Tx only mode*/ 00296 } 00297 else 00298 { 00299 SPI->CR2 &= (uint8_t)(~SPI_CR2_BDOE); /* Set the Rx only mode*/ 00300 } 00301 } 00302 00303 /** 00304 * @brief Checks whether the specified SPI flag is set or not. 00305 * @param SPI_FLAG : Specifies the flag to check. 00306 * This parameter can be any of the @ref SPI_Flag_TypeDef enumeration. 00307 * @retval FlagStatus : Indicates the state of SPI_FLAG. 00308 * This parameter can be any of the @ref FlagStatus enumeration. 00309 */ 00310 00311 FlagStatus SPI_GetFlagStatus(SPI_Flag_TypeDef SPI_FLAG) 00312 { 00313 FlagStatus status = RESET; 00314 /* Check parameters */ 00315 assert_param(IS_SPI_FLAGS_OK(SPI_FLAG)); 00316 00317 /* Check the status of the specified SPI flag */ 00318 if ((SPI->SR & (uint8_t)SPI_FLAG) != (uint8_t)RESET) 00319 { 00320 status = SET; /* SPI_FLAG is set */ 00321 } 00322 else 00323 { 00324 status = RESET; /* SPI_FLAG is reset*/ 00325 } 00326 00327 /* Return the SPI_FLAG status */ 00328 return status; 00329 } 00330 00331 /** 00332 * @brief Clears the SPI flags. 00333 * @param SPI_FLAG : Specifies the flag to clear. 00334 * This parameter can be one of the following values: 00335 * - SPI_FLAG_CRCERR 00336 * - SPI_FLAG_WKUP 00337 * @note - OVR (OverRun Error) interrupt pending bit is cleared by software 00338 * sequence: 00339 * a read operation to SPI_DR register (SPI_ReceiveData()) followed by 00340 * a read operation to SPI_SR register (SPI_GetFlagStatus()). 00341 * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence: 00342 * a read/write operation to SPI_SR register (SPI_GetFlagStatus()) followed by 00343 * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). 00344 * @retval None 00345 */ 00346 void SPI_ClearFlag(SPI_Flag_TypeDef SPI_FLAG) 00347 { 00348 assert_param(IS_SPI_CLEAR_FLAGS_OK(SPI_FLAG)); 00349 /* Clear the flag bit */ 00350 SPI->SR = (uint8_t)(~SPI_FLAG); 00351 } 00352 00353 /** 00354 * @brief Checks whether the specified interrupt has occurred or not. 00355 * @param SPI_IT: Specifies the SPI interrupt pending bit to check. 00356 * This parameter can be one of the following values: 00357 * - SPI_IT_CRCERR 00358 * - SPI_IT_WKUP 00359 * - SPI_IT_OVR 00360 * - SPI_IT_MODF 00361 * - SPI_IT_RXNE 00362 * - SPI_IT_TXE 00363 * @retval ITStatus : Indicates the state of the SPI_IT. 00364 * This parameter can be any of the @ref ITStatus enumeration. 00365 */ 00366 ITStatus SPI_GetITStatus(SPI_IT_TypeDef SPI_IT) 00367 { 00368 ITStatus pendingbitstatus = RESET; 00369 uint8_t itpos = 0; 00370 uint8_t itmask1 = 0; 00371 uint8_t itmask2 = 0; 00372 uint8_t enablestatus = 0; 00373 assert_param(IS_SPI_GET_IT_OK(SPI_IT)); 00374 /* Get the SPI IT index */ 00375 itpos = (uint8_t)((uint8_t)1 << ((uint8_t)SPI_IT & (uint8_t)0x0F)); 00376 00377 /* Get the SPI IT mask */ 00378 itmask1 = (uint8_t)((uint8_t)SPI_IT >> (uint8_t)4); 00379 /* Set the IT mask */ 00380 itmask2 = (uint8_t)((uint8_t)1 << itmask1); 00381 /* Get the SPI_ITPENDINGBIT enable bit status */ 00382 enablestatus = (uint8_t)((uint8_t)SPI->SR & itmask2); 00383 /* Check the status of the specified SPI interrupt */ 00384 if (((SPI->ICR & itpos) != RESET) && enablestatus) 00385 { 00386 /* SPI_ITPENDINGBIT is set */ 00387 pendingbitstatus = SET; 00388 } 00389 else 00390 { 00391 /* SPI_ITPENDINGBIT is reset */ 00392 pendingbitstatus = RESET; 00393 } 00394 /* Return the SPI_ITPENDINGBIT status */ 00395 return pendingbitstatus; 00396 } 00397 00398 /** 00399 * @brief Clears the interrupt pending bits. 00400 * @param SPI_IT: Specifies the interrupt pending bit to clear. 00401 * This parameter can be one of the following values: 00402 * - SPI_IT_CRCERR 00403 * - SPI_IT_WKUP 00404 * @note - OVR (OverRun Error) interrupt pending bit is cleared by software sequence: 00405 * a read operation to SPI_DR register (SPI_ReceiveData()) followed by 00406 * a read operation to SPI_SR register (SPI_GetITStatus()). 00407 * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence: 00408 * a read/write operation to SPI_SR register (SPI_GetITStatus()) followed by 00409 * a write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). 00410 * @retval None 00411 */ 00412 void SPI_ClearITPendingBit(SPI_IT_TypeDef SPI_IT) 00413 { 00414 uint8_t itpos = 0; 00415 assert_param(IS_SPI_CLEAR_IT_OK(SPI_IT)); 00416 00417 /* Clear SPI_IT_CRCERR or SPI_IT_WKUP interrupt pending bits */ 00418 00419 /* Get the SPI pending bit index */ 00420 itpos = (uint8_t)((uint8_t)1 << (uint8_t)((uint8_t)(SPI_IT & (uint8_t)0xF0) >> 4)); 00421 /* Clear the pending bit */ 00422 SPI->SR = (uint8_t)(~itpos); 00423 00424 } 00425 00426 /** 00427 * @} 00428 */ 00429 00430 /** 00431 * @} 00432 */ 00433 00434 00435 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/