Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:09

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_usart_ex.c
0004   * @author  MCD Application Team
0005   * @brief   Extended USART HAL module driver.
0006   *          This file provides firmware functions to manage the following extended
0007   *          functionalities of the Universal Synchronous Receiver Transmitter Peripheral (USART).
0008   *           + Peripheral Control functions
0009   *
0010   *
0011   ******************************************************************************
0012   * @attention
0013   *
0014   * Copyright (c) 2017 STMicroelectronics.
0015   * All rights reserved.
0016   *
0017   * This software is licensed under terms that can be found in the LICENSE file
0018   * in the root directory of this software component.
0019   * If no LICENSE file comes with this software, it is provided AS-IS.
0020   *
0021   ******************************************************************************
0022   @verbatim
0023   ==============================================================================
0024                ##### USART peripheral extended features  #####
0025   ==============================================================================
0026 
0027     (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
0028 
0029         -@- When USART operates in FIFO mode, FIFO mode must be enabled prior
0030             starting RX/TX transfers. Also RX/TX FIFO thresholds must be
0031             configured prior starting RX/TX transfers.
0032 
0033     (#) Slave mode enabling/disabling and NSS pin configuration.
0034 
0035         -@- When USART operates in Slave mode, Slave mode must be enabled prior
0036             starting RX/TX transfers.
0037 
0038   @endverbatim
0039   ******************************************************************************
0040   */
0041 
0042 /* Includes ------------------------------------------------------------------*/
0043 #include "stm32h7xx_hal.h"
0044 
0045 /** @addtogroup STM32H7xx_HAL_Driver
0046   * @{
0047   */
0048 
0049 /** @defgroup USARTEx USARTEx
0050   * @ingroup RTEMSBSPsARMSTM32H7
0051   * @brief USART Extended HAL module driver
0052   * @{
0053   */
0054 
0055 #ifdef HAL_USART_MODULE_ENABLED
0056 
0057 /* Private typedef -----------------------------------------------------------*/
0058 /** @defgroup USARTEx_Private_Constants USARTEx Private Constants
0059   * @ingroup RTEMSBSPsARMSTM32H7
0060   * @{
0061   */
0062 /* USART RX FIFO depth */
0063 #define RX_FIFO_DEPTH 16U
0064 
0065 /* USART TX FIFO depth */
0066 #define TX_FIFO_DEPTH 16U
0067 /**
0068   * @}
0069   */
0070 
0071 /* Private define ------------------------------------------------------------*/
0072 /* Private macros ------------------------------------------------------------*/
0073 /* Private variables ---------------------------------------------------------*/
0074 /* Private function prototypes -----------------------------------------------*/
0075 /** @defgroup USARTEx_Private_Functions USARTEx Private Functions
0076   * @ingroup RTEMSBSPsARMSTM32H7
0077   * @{
0078   */
0079 static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart);
0080 /**
0081   * @}
0082   */
0083 
0084 /* Exported functions --------------------------------------------------------*/
0085 
0086 /** @defgroup USARTEx_Exported_Functions  USARTEx Exported Functions
0087   * @ingroup RTEMSBSPsARMSTM32H7
0088   * @{
0089   */
0090 
0091 /** @defgroup USARTEx_Exported_Functions_Group1 IO operation functions
0092   * @ingroup RTEMSBSPsARMSTM32H7
0093   * @brief Extended USART Transmit/Receive functions
0094   *
0095 @verbatim
0096  ===============================================================================
0097                       ##### IO operation functions #####
0098  ===============================================================================
0099     This subsection provides a set of FIFO mode related callback functions.
0100 
0101     (#) TX/RX Fifos Callbacks:
0102         (+) HAL_USARTEx_RxFifoFullCallback()
0103         (+) HAL_USARTEx_TxFifoEmptyCallback()
0104 
0105 @endverbatim
0106   * @{
0107   */
0108 
0109 /**
0110   * @brief  USART RX Fifo full callback.
0111   * @param  husart USART handle.
0112   * @retval None
0113   */
0114 __weak void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart)
0115 {
0116   /* Prevent unused argument(s) compilation warning */
0117   UNUSED(husart);
0118 
0119   /* NOTE : This function should not be modified, when the callback is needed,
0120             the HAL_USARTEx_RxFifoFullCallback can be implemented in the user file.
0121    */
0122 }
0123 
0124 /**
0125   * @brief  USART TX Fifo empty callback.
0126   * @param  husart USART handle.
0127   * @retval None
0128   */
0129 __weak void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart)
0130 {
0131   /* Prevent unused argument(s) compilation warning */
0132   UNUSED(husart);
0133 
0134   /* NOTE : This function should not be modified, when the callback is needed,
0135             the HAL_USARTEx_TxFifoEmptyCallback can be implemented in the user file.
0136    */
0137 }
0138 
0139 /**
0140   * @}
0141   */
0142 
0143 /** @defgroup USARTEx_Exported_Functions_Group2 Peripheral Control functions
0144   * @ingroup RTEMSBSPsARMSTM32H7
0145   * @brief    Extended Peripheral Control functions
0146   *
0147 @verbatim
0148  ===============================================================================
0149                       ##### Peripheral Control functions #####
0150  ===============================================================================
0151     [..] This section provides the following functions:
0152      (+) HAL_USARTEx_EnableSPISlaveMode() API enables the SPI slave mode
0153      (+) HAL_USARTEx_DisableSPISlaveMode() API disables the SPI slave mode
0154      (+) HAL_USARTEx_ConfigNSS API configures the Slave Select input pin (NSS)
0155      (+) HAL_USARTEx_EnableFifoMode() API enables the FIFO mode
0156      (+) HAL_USARTEx_DisableFifoMode() API disables the FIFO mode
0157      (+) HAL_USARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
0158      (+) HAL_USARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
0159 
0160 
0161 @endverbatim
0162   * @{
0163   */
0164 
0165 /**
0166   * @brief  Enable the SPI slave mode.
0167   * @note When the USART operates in SPI slave mode, it handles data flow using
0168   *       the serial interface clock derived from the external SCLK signal
0169   *       provided by the external master SPI device.
0170   * @note In SPI slave mode, the USART must be enabled before starting the master
0171   *       communications (or between frames while the clock is stable). Otherwise,
0172   *       if the USART slave is enabled while the master is in the middle of a
0173   *       frame, it will become desynchronized with the master.
0174   * @note The data register of the slave needs to be ready before the first edge
0175   *       of the communication clock or before the end of the ongoing communication,
0176   *       otherwise the SPI slave will transmit zeros.
0177   * @param husart      USART handle.
0178   * @retval HAL status
0179   */
0180 HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart)
0181 {
0182   uint32_t tmpcr1;
0183 
0184   /* Check parameters */
0185   assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
0186 
0187   /* Process Locked */
0188   __HAL_LOCK(husart);
0189 
0190   husart->State = HAL_USART_STATE_BUSY;
0191 
0192   /* Save actual USART configuration */
0193   tmpcr1 = READ_REG(husart->Instance->CR1);
0194 
0195   /* Disable USART */
0196   __HAL_USART_DISABLE(husart);
0197 
0198   /* In SPI slave mode mode, the following bits must be kept cleared:
0199   - LINEN and CLKEN bit in the USART_CR2 register
0200   - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
0201   CLEAR_BIT(husart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
0202   CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
0203 
0204   /* Enable SPI slave mode */
0205   SET_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
0206 
0207   /* Restore USART configuration */
0208   WRITE_REG(husart->Instance->CR1, tmpcr1);
0209 
0210   husart->SlaveMode = USART_SLAVEMODE_ENABLE;
0211 
0212   husart->State = HAL_USART_STATE_READY;
0213 
0214   /* Enable USART */
0215   __HAL_USART_ENABLE(husart);
0216 
0217   /* Process Unlocked */
0218   __HAL_UNLOCK(husart);
0219 
0220   return HAL_OK;
0221 }
0222 
0223 /**
0224   * @brief  Disable the SPI slave mode.
0225   * @param husart      USART handle.
0226   * @retval HAL status
0227   */
0228 HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart)
0229 {
0230   uint32_t tmpcr1;
0231 
0232   /* Check parameters */
0233   assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
0234 
0235   /* Process Locked */
0236   __HAL_LOCK(husart);
0237 
0238   husart->State = HAL_USART_STATE_BUSY;
0239 
0240   /* Save actual USART configuration */
0241   tmpcr1 = READ_REG(husart->Instance->CR1);
0242 
0243   /* Disable USART */
0244   __HAL_USART_DISABLE(husart);
0245 
0246   /* Disable SPI slave mode */
0247   CLEAR_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
0248 
0249   /* Restore USART configuration */
0250   WRITE_REG(husart->Instance->CR1, tmpcr1);
0251 
0252   husart->SlaveMode = USART_SLAVEMODE_DISABLE;
0253 
0254   husart->State = HAL_USART_STATE_READY;
0255 
0256   /* Process Unlocked */
0257   __HAL_UNLOCK(husart);
0258 
0259   return HAL_OK;
0260 }
0261 
0262 /**
0263   * @brief  Configure the Slave Select input pin (NSS).
0264   * @note Software NSS management: SPI slave will always be selected and NSS
0265   *       input pin will be ignored.
0266   * @note Hardware NSS management: the SPI slave selection depends on NSS
0267   *       input pin. The slave is selected when NSS is low and deselected when
0268   *       NSS is high.
0269   * @param husart      USART handle.
0270   * @param NSSConfig   NSS configuration.
0271   *          This parameter can be one of the following values:
0272   *            @arg @ref USART_NSS_HARD
0273   *            @arg @ref USART_NSS_SOFT
0274   * @retval HAL status
0275   */
0276 HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig)
0277 {
0278   uint32_t tmpcr1;
0279 
0280   /* Check parameters */
0281   assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
0282   assert_param(IS_USART_NSS(NSSConfig));
0283 
0284   /* Process Locked */
0285   __HAL_LOCK(husart);
0286 
0287   husart->State = HAL_USART_STATE_BUSY;
0288 
0289   /* Save actual USART configuration */
0290   tmpcr1 = READ_REG(husart->Instance->CR1);
0291 
0292   /* Disable USART */
0293   __HAL_USART_DISABLE(husart);
0294 
0295   /* Program DIS_NSS bit in the USART_CR2 register */
0296   MODIFY_REG(husart->Instance->CR2, USART_CR2_DIS_NSS, NSSConfig);
0297 
0298   /* Restore USART configuration */
0299   WRITE_REG(husart->Instance->CR1, tmpcr1);
0300 
0301   husart->State = HAL_USART_STATE_READY;
0302 
0303   /* Process Unlocked */
0304   __HAL_UNLOCK(husart);
0305 
0306   return HAL_OK;
0307 }
0308 
0309 /**
0310   * @brief  Enable the FIFO mode.
0311   * @param husart      USART handle.
0312   * @retval HAL status
0313   */
0314 HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart)
0315 {
0316   uint32_t tmpcr1;
0317 
0318   /* Check parameters */
0319   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
0320 
0321   /* Process Locked */
0322   __HAL_LOCK(husart);
0323 
0324   husart->State = HAL_USART_STATE_BUSY;
0325 
0326   /* Save actual USART configuration */
0327   tmpcr1 = READ_REG(husart->Instance->CR1);
0328 
0329   /* Disable USART */
0330   __HAL_USART_DISABLE(husart);
0331 
0332   /* Enable FIFO mode */
0333   SET_BIT(tmpcr1, USART_CR1_FIFOEN);
0334   husart->FifoMode = USART_FIFOMODE_ENABLE;
0335 
0336   /* Restore USART configuration */
0337   WRITE_REG(husart->Instance->CR1, tmpcr1);
0338 
0339   /* Determine the number of data to process during RX/TX ISR execution */
0340   USARTEx_SetNbDataToProcess(husart);
0341 
0342   husart->State = HAL_USART_STATE_READY;
0343 
0344   /* Process Unlocked */
0345   __HAL_UNLOCK(husart);
0346 
0347   return HAL_OK;
0348 }
0349 
0350 /**
0351   * @brief  Disable the FIFO mode.
0352   * @param husart      USART handle.
0353   * @retval HAL status
0354   */
0355 HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart)
0356 {
0357   uint32_t tmpcr1;
0358 
0359   /* Check parameters */
0360   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
0361 
0362   /* Process Locked */
0363   __HAL_LOCK(husart);
0364 
0365   husart->State = HAL_USART_STATE_BUSY;
0366 
0367   /* Save actual USART configuration */
0368   tmpcr1 = READ_REG(husart->Instance->CR1);
0369 
0370   /* Disable USART */
0371   __HAL_USART_DISABLE(husart);
0372 
0373   /* Enable FIFO mode */
0374   CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
0375   husart->FifoMode = USART_FIFOMODE_DISABLE;
0376 
0377   /* Restore USART configuration */
0378   WRITE_REG(husart->Instance->CR1, tmpcr1);
0379 
0380   husart->State = HAL_USART_STATE_READY;
0381 
0382   /* Process Unlocked */
0383   __HAL_UNLOCK(husart);
0384 
0385   return HAL_OK;
0386 }
0387 
0388 /**
0389   * @brief  Set the TXFIFO threshold.
0390   * @param husart      USART handle.
0391   * @param Threshold  TX FIFO threshold value
0392   *          This parameter can be one of the following values:
0393   *            @arg @ref USART_TXFIFO_THRESHOLD_1_8
0394   *            @arg @ref USART_TXFIFO_THRESHOLD_1_4
0395   *            @arg @ref USART_TXFIFO_THRESHOLD_1_2
0396   *            @arg @ref USART_TXFIFO_THRESHOLD_3_4
0397   *            @arg @ref USART_TXFIFO_THRESHOLD_7_8
0398   *            @arg @ref USART_TXFIFO_THRESHOLD_8_8
0399   * @retval HAL status
0400   */
0401 HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
0402 {
0403   uint32_t tmpcr1;
0404 
0405   /* Check parameters */
0406   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
0407   assert_param(IS_USART_TXFIFO_THRESHOLD(Threshold));
0408 
0409   /* Process Locked */
0410   __HAL_LOCK(husart);
0411 
0412   husart->State = HAL_USART_STATE_BUSY;
0413 
0414   /* Save actual USART configuration */
0415   tmpcr1 = READ_REG(husart->Instance->CR1);
0416 
0417   /* Disable USART */
0418   __HAL_USART_DISABLE(husart);
0419 
0420   /* Update TX threshold configuration */
0421   MODIFY_REG(husart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
0422 
0423   /* Determine the number of data to process during RX/TX ISR execution */
0424   USARTEx_SetNbDataToProcess(husart);
0425 
0426   /* Restore USART configuration */
0427   WRITE_REG(husart->Instance->CR1, tmpcr1);
0428 
0429   husart->State = HAL_USART_STATE_READY;
0430 
0431   /* Process Unlocked */
0432   __HAL_UNLOCK(husart);
0433 
0434   return HAL_OK;
0435 }
0436 
0437 /**
0438   * @brief  Set the RXFIFO threshold.
0439   * @param husart      USART handle.
0440   * @param Threshold  RX FIFO threshold value
0441   *          This parameter can be one of the following values:
0442   *            @arg @ref USART_RXFIFO_THRESHOLD_1_8
0443   *            @arg @ref USART_RXFIFO_THRESHOLD_1_4
0444   *            @arg @ref USART_RXFIFO_THRESHOLD_1_2
0445   *            @arg @ref USART_RXFIFO_THRESHOLD_3_4
0446   *            @arg @ref USART_RXFIFO_THRESHOLD_7_8
0447   *            @arg @ref USART_RXFIFO_THRESHOLD_8_8
0448   * @retval HAL status
0449   */
0450 HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
0451 {
0452   uint32_t tmpcr1;
0453 
0454   /* Check the parameters */
0455   assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
0456   assert_param(IS_USART_RXFIFO_THRESHOLD(Threshold));
0457 
0458   /* Process Locked */
0459   __HAL_LOCK(husart);
0460 
0461   husart->State = HAL_USART_STATE_BUSY;
0462 
0463   /* Save actual USART configuration */
0464   tmpcr1 = READ_REG(husart->Instance->CR1);
0465 
0466   /* Disable USART */
0467   __HAL_USART_DISABLE(husart);
0468 
0469   /* Update RX threshold configuration */
0470   MODIFY_REG(husart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
0471 
0472   /* Determine the number of data to process during RX/TX ISR execution */
0473   USARTEx_SetNbDataToProcess(husart);
0474 
0475   /* Restore USART configuration */
0476   WRITE_REG(husart->Instance->CR1, tmpcr1);
0477 
0478   husart->State = HAL_USART_STATE_READY;
0479 
0480   /* Process Unlocked */
0481   __HAL_UNLOCK(husart);
0482 
0483   return HAL_OK;
0484 }
0485 
0486 /**
0487   * @}
0488   */
0489 
0490 /**
0491   * @}
0492   */
0493 
0494 /** @addtogroup USARTEx_Private_Functions
0495   * @{
0496   */
0497 
0498 /**
0499   * @brief Calculate the number of data to process in RX/TX ISR.
0500   * @note The RX FIFO depth and the TX FIFO depth is extracted from
0501   *       the USART configuration registers.
0502   * @param husart USART handle.
0503   * @retval None
0504   */
0505 static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart)
0506 {
0507   uint8_t rx_fifo_depth;
0508   uint8_t tx_fifo_depth;
0509   uint8_t rx_fifo_threshold;
0510   uint8_t tx_fifo_threshold;
0511   /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */
0512   static const uint8_t numerator[]   = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
0513   static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
0514 
0515   if (husart->FifoMode == USART_FIFOMODE_DISABLE)
0516   {
0517     husart->NbTxDataToProcess = 1U;
0518     husart->NbRxDataToProcess = 1U;
0519   }
0520   else
0521   {
0522     rx_fifo_depth = RX_FIFO_DEPTH;
0523     tx_fifo_depth = TX_FIFO_DEPTH;
0524     rx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
0525                                             USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos) & 0xFFU);
0526     tx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
0527                                             USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos) & 0xFFU);
0528     husart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
0529                                 (uint16_t)denominator[tx_fifo_threshold];
0530     husart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
0531                                 (uint16_t)denominator[rx_fifo_threshold];
0532   }
0533 }
0534 /**
0535   * @}
0536   */
0537 
0538 #endif /* HAL_USART_MODULE_ENABLED */
0539 
0540 /**
0541   * @}
0542   */
0543 
0544 /**
0545   * @}
0546   */
0547