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