STM32L443xx HAL User Manual
stm32l4xx_hal_usart_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_usart_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extended USART HAL module driver.
00006   *          This file provides firmware functions to manage the following extended
00007   *          functionalities of the Universal Synchronous Receiver Transmitter Peripheral (USART).
00008   *           + Peripheral Control functions
00009   *
00010   *
00011   ******************************************************************************
00012   * @attention
00013   *
00014   * Copyright (c) 2017 STMicroelectronics.
00015   * All rights reserved.
00016   *
00017   * This software is licensed under terms that can be found in the LICENSE file
00018   * in the root directory of this software component.
00019   * If no LICENSE file comes with this software, it is provided AS-IS.
00020   *
00021   ******************************************************************************
00022   @verbatim
00023   ==============================================================================
00024                ##### USART peripheral extended features  #####
00025   ==============================================================================
00026 
00027     (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
00028 
00029         -@- When USART operates in FIFO mode, FIFO mode must be enabled prior
00030             starting RX/TX transfers. Also RX/TX FIFO thresholds must be
00031             configured prior starting RX/TX transfers.
00032 
00033     (#) Slave mode enabling/disabling and NSS pin configuration.
00034 
00035         -@- When USART operates in Slave mode, Slave mode must be enabled prior
00036             starting RX/TX transfers.
00037 
00038   @endverbatim
00039   ******************************************************************************
00040   */
00041 
00042 /* Includes ------------------------------------------------------------------*/
00043 #include "stm32l4xx_hal.h"
00044 
00045 /** @addtogroup STM32L4xx_HAL_Driver
00046   * @{
00047   */
00048 
00049 /** @defgroup USARTEx USARTEx
00050   * @brief USART Extended HAL module driver
00051   * @{
00052   */
00053 
00054 #ifdef HAL_USART_MODULE_ENABLED
00055 
00056 /* Private typedef -----------------------------------------------------------*/
00057 #if defined(USART_CR1_FIFOEN)
00058 /** @defgroup USARTEx_Private_Constants USARTEx Private Constants
00059   * @{
00060   */
00061 /* USART RX FIFO depth */
00062 #define RX_FIFO_DEPTH 8U
00063 
00064 /* USART TX FIFO depth */
00065 #define TX_FIFO_DEPTH 8U
00066 /**
00067   * @}
00068   */
00069 
00070 #endif /* USART_CR1_FIFOEN */
00071 /* Private define ------------------------------------------------------------*/
00072 /* Private macros ------------------------------------------------------------*/
00073 /* Private variables ---------------------------------------------------------*/
00074 /* Private function prototypes -----------------------------------------------*/
00075 #if defined(USART_CR1_FIFOEN)
00076 /** @defgroup USARTEx_Private_Functions USARTEx Private Functions
00077   * @{
00078   */
00079 static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart);
00080 /**
00081   * @}
00082   */
00083 #endif /* USART_CR1_FIFOEN */
00084 
00085 /* Exported functions --------------------------------------------------------*/
00086 
00087 /** @defgroup USARTEx_Exported_Functions  USARTEx Exported Functions
00088   * @{
00089   */
00090 
00091 /** @defgroup USARTEx_Exported_Functions_Group1 IO operation functions
00092   * @brief Extended USART Transmit/Receive functions
00093   *
00094 @verbatim
00095  ===============================================================================
00096                       ##### IO operation functions #####
00097  ===============================================================================
00098     This subsection provides a set of FIFO mode related callback functions.
00099 
00100     (#) TX/RX Fifos Callbacks:
00101         (+) HAL_USARTEx_RxFifoFullCallback()
00102         (+) HAL_USARTEx_TxFifoEmptyCallback()
00103 
00104 @endverbatim
00105   * @{
00106   */
00107 
00108 #if defined(USART_CR1_FIFOEN)
00109 /**
00110   * @brief  USART RX Fifo full callback.
00111   * @param  husart USART handle.
00112   * @retval None
00113   */
00114 __weak void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart)
00115 {
00116   /* Prevent unused argument(s) compilation warning */
00117   UNUSED(husart);
00118 
00119   /* NOTE : This function should not be modified, when the callback is needed,
00120             the HAL_USARTEx_RxFifoFullCallback can be implemented in the user file.
00121    */
00122 }
00123 
00124 /**
00125   * @brief  USART TX Fifo empty callback.
00126   * @param  husart USART handle.
00127   * @retval None
00128   */
00129 __weak void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart)
00130 {
00131   /* Prevent unused argument(s) compilation warning */
00132   UNUSED(husart);
00133 
00134   /* NOTE : This function should not be modified, when the callback is needed,
00135             the HAL_USARTEx_TxFifoEmptyCallback can be implemented in the user file.
00136    */
00137 }
00138 #endif /* USART_CR1_FIFOEN */
00139 
00140 /**
00141   * @}
00142   */
00143 
00144 /** @defgroup USARTEx_Exported_Functions_Group2 Peripheral Control functions
00145   * @brief    Extended Peripheral Control functions
00146   *
00147 @verbatim
00148  ===============================================================================
00149                       ##### Peripheral Control functions #####
00150  ===============================================================================
00151     [..] This section provides the following functions:
00152      (+) HAL_USARTEx_EnableSPISlaveMode() API enables the SPI slave mode
00153      (+) HAL_USARTEx_DisableSPISlaveMode() API disables the SPI slave mode
00154      (+) HAL_USARTEx_ConfigNSS API configures the Slave Select input pin (NSS)
00155      (+) HAL_USARTEx_EnableFifoMode() API enables the FIFO mode
00156      (+) HAL_USARTEx_DisableFifoMode() API disables the FIFO mode
00157      (+) HAL_USARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
00158      (+) HAL_USARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
00159 
00160 
00161 @endverbatim
00162   * @{
00163   */
00164 
00165 #if defined(USART_CR2_SLVEN)
00166 /**
00167   * @brief  Enable the SPI slave mode.
00168   * @note When the USART operates in SPI slave mode, it handles data flow using
00169   *       the serial interface clock derived from the external SCLK signal
00170   *       provided by the external master SPI device.
00171   * @note In SPI slave mode, the USART must be enabled before starting the master
00172   *       communications (or between frames while the clock is stable). Otherwise,
00173   *       if the USART slave is enabled while the master is in the middle of a
00174   *       frame, it will become desynchronized with the master.
00175   * @note The data register of the slave needs to be ready before the first edge
00176   *       of the communication clock or before the end of the ongoing communication,
00177   *       otherwise the SPI slave will transmit zeros.
00178   * @param husart      USART handle.
00179   * @retval HAL status
00180   */
00181 HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart)
00182 {
00183   uint32_t tmpcr1;
00184 
00185   /* Check parameters */
00186   assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
00187 
00188   /* Process Locked */
00189   __HAL_LOCK(husart);
00190 
00191   husart->State = HAL_USART_STATE_BUSY;
00192 
00193   /* Save actual USART configuration */
00194   tmpcr1 = READ_REG(husart->Instance->CR1);
00195 
00196   /* Disable USART */
00197   __HAL_USART_DISABLE(husart);
00198 
00199   /* In SPI slave mode mode, the following bits must be kept cleared:
00200   - LINEN and CLKEN bit in the USART_CR2 register
00201   - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
00202   CLEAR_BIT(husart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
00203   CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
00204 
00205   /* Enable SPI slave mode */
00206   SET_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
00207 
00208   /* Restore USART configuration */
00209   WRITE_REG(husart->Instance->CR1, tmpcr1);
00210 
00211   husart->SlaveMode = USART_SLAVEMODE_ENABLE;
00212 
00213   husart->State = HAL_USART_STATE_READY;
00214 
00215   /* Enable USART */
00216   __HAL_USART_ENABLE(husart);
00217 
00218   /* Process Unlocked */
00219   __HAL_UNLOCK(husart);
00220 
00221   return HAL_OK;
00222 }
00223 
00224 /**
00225   * @brief  Disable the SPI slave mode.
00226   * @param husart      USART handle.
00227   * @retval HAL status
00228   */
00229 HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart)
00230 {
00231   uint32_t tmpcr1;
00232 
00233   /* Check parameters */
00234   assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
00235 
00236   /* Process Locked */
00237   __HAL_LOCK(husart);
00238 
00239   husart->State = HAL_USART_STATE_BUSY;
00240 
00241   /* Save actual USART configuration */
00242   tmpcr1 = READ_REG(husart->Instance->CR1);
00243 
00244   /* Disable USART */
00245   __HAL_USART_DISABLE(husart);
00246 
00247   /* Disable SPI slave mode */
00248   CLEAR_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
00249 
00250   /* Restore USART configuration */
00251   WRITE_REG(husart->Instance->CR1, tmpcr1);
00252 
00253   husart->SlaveMode = USART_SLAVEMODE_DISABLE;
00254 
00255   husart->State = HAL_USART_STATE_READY;
00256 
00257   /* Process Unlocked */
00258   __HAL_UNLOCK(husart);
00259 
00260   return HAL_OK;
00261 }
00262 
00263 /**
00264   * @brief  Configure the Slave Select input pin (NSS).
00265   * @note Software NSS management: SPI slave will always be selected and NSS
00266   *       input pin will be ignored.
00267   * @note Hardware NSS management: the SPI slave selection depends on NSS
00268   *       input pin. The slave is selected when NSS is low and deselected when
00269   *       NSS is high.
00270   * @param husart      USART handle.
00271   * @param NSSConfig   NSS configuration.
00272   *          This parameter can be one of the following values:
00273   *            @arg @ref USART_NSS_HARD
00274   *            @arg @ref USART_NSS_SOFT
00275   * @retval HAL status
00276   */
00277 HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig)
00278 {
00279   uint32_t tmpcr1;
00280 
00281   /* Check parameters */
00282   assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
00283   assert_param(IS_USART_NSS(NSSConfig));
00284 
00285   /* Process Locked */
00286   __HAL_LOCK(husart);
00287 
00288   husart->State = HAL_USART_STATE_BUSY;
00289 
00290   /* Save actual USART configuration */
00291   tmpcr1 = READ_REG(husart->Instance->CR1);
00292 
00293   /* Disable USART */
00294   __HAL_USART_DISABLE(husart);
00295 
00296   /* Program DIS_NSS bit in the USART_CR2 register */
00297   MODIFY_REG(husart->Instance->CR2, USART_CR2_DIS_NSS, NSSConfig);
00298 
00299   /* Restore USART configuration */
00300   WRITE_REG(husart->Instance->CR1, tmpcr1);
00301 
00302   husart->State = HAL_USART_STATE_READY;
00303 
00304   /* Process Unlocked */
00305   __HAL_UNLOCK(husart);
00306 
00307   return HAL_OK;
00308 }
00309 #endif /* USART_CR2_SLVEN */
00310 
00311 #if defined(USART_CR1_FIFOEN)
00312 /**
00313   * @brief  Enable the FIFO mode.
00314   * @param husart      USART handle.
00315   * @retval HAL status
00316   */
00317 HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart)
00318 {
00319   uint32_t tmpcr1;
00320 
00321   /* Check parameters */
00322   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
00323 
00324   /* Process Locked */
00325   __HAL_LOCK(husart);
00326 
00327   husart->State = HAL_USART_STATE_BUSY;
00328 
00329   /* Save actual USART configuration */
00330   tmpcr1 = READ_REG(husart->Instance->CR1);
00331 
00332   /* Disable USART */
00333   __HAL_USART_DISABLE(husart);
00334 
00335   /* Enable FIFO mode */
00336   SET_BIT(tmpcr1, USART_CR1_FIFOEN);
00337   husart->FifoMode = USART_FIFOMODE_ENABLE;
00338 
00339   /* Restore USART configuration */
00340   WRITE_REG(husart->Instance->CR1, tmpcr1);
00341 
00342   /* Determine the number of data to process during RX/TX ISR execution */
00343   USARTEx_SetNbDataToProcess(husart);
00344 
00345   husart->State = HAL_USART_STATE_READY;
00346 
00347   /* Process Unlocked */
00348   __HAL_UNLOCK(husart);
00349 
00350   return HAL_OK;
00351 }
00352 
00353 /**
00354   * @brief  Disable the FIFO mode.
00355   * @param husart      USART handle.
00356   * @retval HAL status
00357   */
00358 HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart)
00359 {
00360   uint32_t tmpcr1;
00361 
00362   /* Check parameters */
00363   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
00364 
00365   /* Process Locked */
00366   __HAL_LOCK(husart);
00367 
00368   husart->State = HAL_USART_STATE_BUSY;
00369 
00370   /* Save actual USART configuration */
00371   tmpcr1 = READ_REG(husart->Instance->CR1);
00372 
00373   /* Disable USART */
00374   __HAL_USART_DISABLE(husart);
00375 
00376   /* Enable FIFO mode */
00377   CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
00378   husart->FifoMode = USART_FIFOMODE_DISABLE;
00379 
00380   /* Restore USART configuration */
00381   WRITE_REG(husart->Instance->CR1, tmpcr1);
00382 
00383   husart->State = HAL_USART_STATE_READY;
00384 
00385   /* Process Unlocked */
00386   __HAL_UNLOCK(husart);
00387 
00388   return HAL_OK;
00389 }
00390 
00391 /**
00392   * @brief  Set the TXFIFO threshold.
00393   * @param husart      USART handle.
00394   * @param Threshold  TX FIFO threshold value
00395   *          This parameter can be one of the following values:
00396   *            @arg @ref USART_TXFIFO_THRESHOLD_1_8
00397   *            @arg @ref USART_TXFIFO_THRESHOLD_1_4
00398   *            @arg @ref USART_TXFIFO_THRESHOLD_1_2
00399   *            @arg @ref USART_TXFIFO_THRESHOLD_3_4
00400   *            @arg @ref USART_TXFIFO_THRESHOLD_7_8
00401   *            @arg @ref USART_TXFIFO_THRESHOLD_8_8
00402   * @retval HAL status
00403   */
00404 HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
00405 {
00406   uint32_t tmpcr1;
00407 
00408   /* Check parameters */
00409   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
00410   assert_param(IS_USART_TXFIFO_THRESHOLD(Threshold));
00411 
00412   /* Process Locked */
00413   __HAL_LOCK(husart);
00414 
00415   husart->State = HAL_USART_STATE_BUSY;
00416 
00417   /* Save actual USART configuration */
00418   tmpcr1 = READ_REG(husart->Instance->CR1);
00419 
00420   /* Disable USART */
00421   __HAL_USART_DISABLE(husart);
00422 
00423   /* Update TX threshold configuration */
00424   MODIFY_REG(husart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
00425 
00426   /* Determine the number of data to process during RX/TX ISR execution */
00427   USARTEx_SetNbDataToProcess(husart);
00428 
00429   /* Restore USART configuration */
00430   WRITE_REG(husart->Instance->CR1, tmpcr1);
00431 
00432   husart->State = HAL_USART_STATE_READY;
00433 
00434   /* Process Unlocked */
00435   __HAL_UNLOCK(husart);
00436 
00437   return HAL_OK;
00438 }
00439 
00440 /**
00441   * @brief  Set the RXFIFO threshold.
00442   * @param husart      USART handle.
00443   * @param Threshold  RX FIFO threshold value
00444   *          This parameter can be one of the following values:
00445   *            @arg @ref USART_RXFIFO_THRESHOLD_1_8
00446   *            @arg @ref USART_RXFIFO_THRESHOLD_1_4
00447   *            @arg @ref USART_RXFIFO_THRESHOLD_1_2
00448   *            @arg @ref USART_RXFIFO_THRESHOLD_3_4
00449   *            @arg @ref USART_RXFIFO_THRESHOLD_7_8
00450   *            @arg @ref USART_RXFIFO_THRESHOLD_8_8
00451   * @retval HAL status
00452   */
00453 HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
00454 {
00455   uint32_t tmpcr1;
00456 
00457   /* Check the parameters */
00458   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
00459   assert_param(IS_USART_RXFIFO_THRESHOLD(Threshold));
00460 
00461   /* Process Locked */
00462   __HAL_LOCK(husart);
00463 
00464   husart->State = HAL_USART_STATE_BUSY;
00465 
00466   /* Save actual USART configuration */
00467   tmpcr1 = READ_REG(husart->Instance->CR1);
00468 
00469   /* Disable USART */
00470   __HAL_USART_DISABLE(husart);
00471 
00472   /* Update RX threshold configuration */
00473   MODIFY_REG(husart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
00474 
00475   /* Determine the number of data to process during RX/TX ISR execution */
00476   USARTEx_SetNbDataToProcess(husart);
00477 
00478   /* Restore USART configuration */
00479   WRITE_REG(husart->Instance->CR1, tmpcr1);
00480 
00481   husart->State = HAL_USART_STATE_READY;
00482 
00483   /* Process Unlocked */
00484   __HAL_UNLOCK(husart);
00485 
00486   return HAL_OK;
00487 }
00488 
00489 #endif /* USART_CR1_FIFOEN */
00490 /**
00491   * @}
00492   */
00493 
00494 /**
00495   * @}
00496   */
00497 
00498 /** @addtogroup USARTEx_Private_Functions
00499   * @{
00500   */
00501 
00502 #if defined(USART_CR1_FIFOEN)
00503 /**
00504   * @brief Calculate the number of data to process in RX/TX ISR.
00505   * @note The RX FIFO depth and the TX FIFO depth is extracted from
00506   *       the USART configuration registers.
00507   * @param husart USART handle.
00508   * @retval None
00509   */
00510 static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart)
00511 {
00512   uint8_t rx_fifo_depth;
00513   uint8_t tx_fifo_depth;
00514   uint8_t rx_fifo_threshold;
00515   uint8_t tx_fifo_threshold;
00516   /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */
00517   static const uint8_t numerator[]   = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
00518   static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
00519 
00520   if (husart->FifoMode == USART_FIFOMODE_DISABLE)
00521   {
00522     husart->NbTxDataToProcess = 1U;
00523     husart->NbRxDataToProcess = 1U;
00524   }
00525   else
00526   {
00527     rx_fifo_depth = RX_FIFO_DEPTH;
00528     tx_fifo_depth = TX_FIFO_DEPTH;
00529     rx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
00530                                             USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos) & 0xFFU);
00531     tx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
00532                                             USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos) & 0xFFU);
00533     husart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
00534                                 (uint16_t)denominator[tx_fifo_threshold];
00535     husart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
00536                                 (uint16_t)denominator[rx_fifo_threshold];
00537   }
00538 }
00539 #endif /* USART_CR1_FIFOEN */
00540 /**
00541   * @}
00542   */
00543 
00544 #endif /* HAL_USART_MODULE_ENABLED */
00545 
00546 /**
00547   * @}
00548   */
00549 
00550 /**
00551   * @}
00552   */
00553