You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

539 lines
15 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32wbxx_hal_usart_ex.c
  4. * @author MCD Application Team
  5. * @brief Extended USART HAL module driver.
  6. * This file provides firmware functions to manage the following extended
  7. * functionalities of the Universal Synchronous Receiver Transmitter Peripheral (USART).
  8. * + Peripheral Control functions
  9. *
  10. *
  11. @verbatim
  12. ==============================================================================
  13. ##### USART peripheral extended features #####
  14. ==============================================================================
  15. (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
  16. -@- When USART operates in FIFO mode, FIFO mode must be enabled prior
  17. starting RX/TX transfers. Also RX/TX FIFO thresholds must be
  18. configured prior starting RX/TX transfers.
  19. (#) Slave mode enabling/disabling and NSS pin configuration.
  20. -@- When USART operates in Slave mode, Slave mode must be enabled prior
  21. starting RX/TX transfers.
  22. @endverbatim
  23. ******************************************************************************
  24. * @attention
  25. *
  26. * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  27. * All rights reserved.</center></h2>
  28. *
  29. * This software component is licensed by ST under BSD 3-Clause license,
  30. * the "License"; You may not use this file except in compliance with the
  31. * License. You may obtain a copy of the License at:
  32. * opensource.org/licenses/BSD-3-Clause
  33. *
  34. ******************************************************************************
  35. */
  36. /* Includes ------------------------------------------------------------------*/
  37. #include "stm32wbxx_hal.h"
  38. /** @addtogroup STM32WBxx_HAL_Driver
  39. * @{
  40. */
  41. /** @defgroup USARTEx USARTEx
  42. * @brief USART Extended HAL module driver
  43. * @{
  44. */
  45. #ifdef HAL_USART_MODULE_ENABLED
  46. /* Private typedef -----------------------------------------------------------*/
  47. /** @defgroup USARTEx_Private_Constants USARTEx Private Constants
  48. * @{
  49. */
  50. /* USART RX FIFO depth */
  51. #define RX_FIFO_DEPTH 8U
  52. /* USART TX FIFO depth */
  53. #define TX_FIFO_DEPTH 8U
  54. /**
  55. * @}
  56. */
  57. /* Private define ------------------------------------------------------------*/
  58. /* Private macros ------------------------------------------------------------*/
  59. /* Private variables ---------------------------------------------------------*/
  60. /* Private function prototypes -----------------------------------------------*/
  61. /** @defgroup USARTEx_Private_Functions USARTEx Private Functions
  62. * @{
  63. */
  64. static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart);
  65. /**
  66. * @}
  67. */
  68. /* Exported functions --------------------------------------------------------*/
  69. /** @defgroup USARTEx_Exported_Functions USARTEx Exported Functions
  70. * @{
  71. */
  72. /** @defgroup USARTEx_Exported_Functions_Group1 IO operation functions
  73. * @brief Extended USART Transmit/Receive functions
  74. *
  75. @verbatim
  76. ===============================================================================
  77. ##### IO operation functions #####
  78. ===============================================================================
  79. This subsection provides a set of FIFO mode related callback functions.
  80. (#) TX/RX Fifos Callbacks:
  81. (+) HAL_USARTEx_RxFifoFullCallback()
  82. (+) HAL_USARTEx_TxFifoEmptyCallback()
  83. @endverbatim
  84. * @{
  85. */
  86. /**
  87. * @brief USART RX Fifo full callback.
  88. * @param husart USART handle.
  89. * @retval None
  90. */
  91. __weak void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart)
  92. {
  93. /* Prevent unused argument(s) compilation warning */
  94. UNUSED(husart);
  95. /* NOTE : This function should not be modified, when the callback is needed,
  96. the HAL_USARTEx_RxFifoFullCallback can be implemented in the user file.
  97. */
  98. }
  99. /**
  100. * @brief USART TX Fifo empty callback.
  101. * @param husart USART handle.
  102. * @retval None
  103. */
  104. __weak void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart)
  105. {
  106. /* Prevent unused argument(s) compilation warning */
  107. UNUSED(husart);
  108. /* NOTE : This function should not be modified, when the callback is needed,
  109. the HAL_USARTEx_TxFifoEmptyCallback can be implemented in the user file.
  110. */
  111. }
  112. /**
  113. * @}
  114. */
  115. /** @defgroup USARTEx_Exported_Functions_Group2 Peripheral Control functions
  116. * @brief Extended Peripheral Control functions
  117. *
  118. @verbatim
  119. ===============================================================================
  120. ##### Peripheral Control functions #####
  121. ===============================================================================
  122. [..] This section provides the following functions:
  123. (+) HAL_USARTEx_EnableSPISlaveMode() API enables the SPI slave mode
  124. (+) HAL_USARTEx_DisableSPISlaveMode() API disables the SPI slave mode
  125. (+) HAL_USARTEx_ConfigNSS API configures the Slave Select input pin (NSS)
  126. (+) HAL_USARTEx_EnableFifoMode() API enables the FIFO mode
  127. (+) HAL_USARTEx_DisableFifoMode() API disables the FIFO mode
  128. (+) HAL_USARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
  129. (+) HAL_USARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
  130. @endverbatim
  131. * @{
  132. */
  133. /**
  134. * @brief Enable the SPI slave mode.
  135. * @note When the USART operates in SPI slave mode, it handles data flow using
  136. * the serial interface clock derived from the external SCLK signal
  137. * provided by the external master SPI device.
  138. * @note In SPI slave mode, the USART must be enabled before starting the master
  139. * communications (or between frames while the clock is stable). Otherwise,
  140. * if the USART slave is enabled while the master is in the middle of a
  141. * frame, it will become desynchronized with the master.
  142. * @note The data register of the slave needs to be ready before the first edge
  143. * of the communication clock or before the end of the ongoing communication,
  144. * otherwise the SPI slave will transmit zeros.
  145. * @param husart USART handle.
  146. * @retval HAL status
  147. */
  148. HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart)
  149. {
  150. uint32_t tmpcr1;
  151. /* Check parameters */
  152. assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
  153. /* Process Locked */
  154. __HAL_LOCK(husart);
  155. husart->State = HAL_USART_STATE_BUSY;
  156. /* Save actual USART configuration */
  157. tmpcr1 = READ_REG(husart->Instance->CR1);
  158. /* Disable USART */
  159. __HAL_USART_DISABLE(husart);
  160. /* In SPI slave mode mode, the following bits must be kept cleared:
  161. - LINEN and CLKEN bit in the USART_CR2 register
  162. - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
  163. CLEAR_BIT(husart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
  164. CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
  165. /* Enable SPI slave mode */
  166. SET_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
  167. /* Restore USART configuration */
  168. WRITE_REG(husart->Instance->CR1, tmpcr1);
  169. husart->SlaveMode = USART_SLAVEMODE_ENABLE;
  170. husart->State = HAL_USART_STATE_READY;
  171. /* Enable USART */
  172. __HAL_USART_ENABLE(husart);
  173. /* Process Unlocked */
  174. __HAL_UNLOCK(husart);
  175. return HAL_OK;
  176. }
  177. /**
  178. * @brief Disable the SPI slave mode.
  179. * @param husart USART handle.
  180. * @retval HAL status
  181. */
  182. HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart)
  183. {
  184. uint32_t tmpcr1;
  185. /* Check parameters */
  186. assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
  187. /* Process Locked */
  188. __HAL_LOCK(husart);
  189. husart->State = HAL_USART_STATE_BUSY;
  190. /* Save actual USART configuration */
  191. tmpcr1 = READ_REG(husart->Instance->CR1);
  192. /* Disable USART */
  193. __HAL_USART_DISABLE(husart);
  194. /* Disable SPI slave mode */
  195. CLEAR_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
  196. /* Restore USART configuration */
  197. WRITE_REG(husart->Instance->CR1, tmpcr1);
  198. husart->SlaveMode = USART_SLAVEMODE_DISABLE;
  199. husart->State = HAL_USART_STATE_READY;
  200. /* Process Unlocked */
  201. __HAL_UNLOCK(husart);
  202. return HAL_OK;
  203. }
  204. /**
  205. * @brief Configure the Slave Select input pin (NSS).
  206. * @note Software NSS management: SPI slave will always be selected and NSS
  207. * input pin will be ignored.
  208. * @note Hardware NSS management: the SPI slave selection depends on NSS
  209. * input pin. The slave is selected when NSS is low and deselected when
  210. * NSS is high.
  211. * @param husart USART handle.
  212. * @param NSSConfig NSS configuration.
  213. * This parameter can be one of the following values:
  214. * @arg @ref USART_NSS_HARD
  215. * @arg @ref USART_NSS_SOFT
  216. * @retval HAL status
  217. */
  218. HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig)
  219. {
  220. uint32_t tmpcr1;
  221. /* Check parameters */
  222. assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
  223. assert_param(IS_USART_NSS(NSSConfig));
  224. /* Process Locked */
  225. __HAL_LOCK(husart);
  226. husart->State = HAL_USART_STATE_BUSY;
  227. /* Save actual USART configuration */
  228. tmpcr1 = READ_REG(husart->Instance->CR1);
  229. /* Disable USART */
  230. __HAL_USART_DISABLE(husart);
  231. /* Program DIS_NSS bit in the USART_CR2 register */
  232. MODIFY_REG(husart->Instance->CR2, USART_CR2_DIS_NSS, NSSConfig);
  233. /* Restore USART configuration */
  234. WRITE_REG(husart->Instance->CR1, tmpcr1);
  235. husart->State = HAL_USART_STATE_READY;
  236. /* Process Unlocked */
  237. __HAL_UNLOCK(husart);
  238. return HAL_OK;
  239. }
  240. /**
  241. * @brief Enable the FIFO mode.
  242. * @param husart USART handle.
  243. * @retval HAL status
  244. */
  245. HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart)
  246. {
  247. uint32_t tmpcr1;
  248. /* Check parameters */
  249. assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
  250. /* Process Locked */
  251. __HAL_LOCK(husart);
  252. husart->State = HAL_USART_STATE_BUSY;
  253. /* Save actual USART configuration */
  254. tmpcr1 = READ_REG(husart->Instance->CR1);
  255. /* Disable USART */
  256. __HAL_USART_DISABLE(husart);
  257. /* Enable FIFO mode */
  258. SET_BIT(tmpcr1, USART_CR1_FIFOEN);
  259. husart->FifoMode = USART_FIFOMODE_ENABLE;
  260. /* Restore USART configuration */
  261. WRITE_REG(husart->Instance->CR1, tmpcr1);
  262. /* Determine the number of data to process during RX/TX ISR execution */
  263. USARTEx_SetNbDataToProcess(husart);
  264. husart->State = HAL_USART_STATE_READY;
  265. /* Process Unlocked */
  266. __HAL_UNLOCK(husart);
  267. return HAL_OK;
  268. }
  269. /**
  270. * @brief Disable the FIFO mode.
  271. * @param husart USART handle.
  272. * @retval HAL status
  273. */
  274. HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart)
  275. {
  276. uint32_t tmpcr1;
  277. /* Check parameters */
  278. assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
  279. /* Process Locked */
  280. __HAL_LOCK(husart);
  281. husart->State = HAL_USART_STATE_BUSY;
  282. /* Save actual USART configuration */
  283. tmpcr1 = READ_REG(husart->Instance->CR1);
  284. /* Disable USART */
  285. __HAL_USART_DISABLE(husart);
  286. /* Enable FIFO mode */
  287. CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
  288. husart->FifoMode = USART_FIFOMODE_DISABLE;
  289. /* Restore USART configuration */
  290. WRITE_REG(husart->Instance->CR1, tmpcr1);
  291. husart->State = HAL_USART_STATE_READY;
  292. /* Process Unlocked */
  293. __HAL_UNLOCK(husart);
  294. return HAL_OK;
  295. }
  296. /**
  297. * @brief Set the TXFIFO threshold.
  298. * @param husart USART handle.
  299. * @param Threshold TX FIFO threshold value
  300. * This parameter can be one of the following values:
  301. * @arg @ref USART_TXFIFO_THRESHOLD_1_8
  302. * @arg @ref USART_TXFIFO_THRESHOLD_1_4
  303. * @arg @ref USART_TXFIFO_THRESHOLD_1_2
  304. * @arg @ref USART_TXFIFO_THRESHOLD_3_4
  305. * @arg @ref USART_TXFIFO_THRESHOLD_7_8
  306. * @arg @ref USART_TXFIFO_THRESHOLD_8_8
  307. * @retval HAL status
  308. */
  309. HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
  310. {
  311. uint32_t tmpcr1;
  312. /* Check parameters */
  313. assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
  314. assert_param(IS_USART_TXFIFO_THRESHOLD(Threshold));
  315. /* Process Locked */
  316. __HAL_LOCK(husart);
  317. husart->State = HAL_USART_STATE_BUSY;
  318. /* Save actual USART configuration */
  319. tmpcr1 = READ_REG(husart->Instance->CR1);
  320. /* Disable USART */
  321. __HAL_USART_DISABLE(husart);
  322. /* Update TX threshold configuration */
  323. MODIFY_REG(husart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
  324. /* Determine the number of data to process during RX/TX ISR execution */
  325. USARTEx_SetNbDataToProcess(husart);
  326. /* Restore USART configuration */
  327. WRITE_REG(husart->Instance->CR1, tmpcr1);
  328. husart->State = HAL_USART_STATE_READY;
  329. /* Process Unlocked */
  330. __HAL_UNLOCK(husart);
  331. return HAL_OK;
  332. }
  333. /**
  334. * @brief Set the RXFIFO threshold.
  335. * @param husart USART handle.
  336. * @param Threshold RX FIFO threshold value
  337. * This parameter can be one of the following values:
  338. * @arg @ref USART_RXFIFO_THRESHOLD_1_8
  339. * @arg @ref USART_RXFIFO_THRESHOLD_1_4
  340. * @arg @ref USART_RXFIFO_THRESHOLD_1_2
  341. * @arg @ref USART_RXFIFO_THRESHOLD_3_4
  342. * @arg @ref USART_RXFIFO_THRESHOLD_7_8
  343. * @arg @ref USART_RXFIFO_THRESHOLD_8_8
  344. * @retval HAL status
  345. */
  346. HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
  347. {
  348. uint32_t tmpcr1;
  349. /* Check the parameters */
  350. assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
  351. assert_param(IS_USART_RXFIFO_THRESHOLD(Threshold));
  352. /* Process Locked */
  353. __HAL_LOCK(husart);
  354. husart->State = HAL_USART_STATE_BUSY;
  355. /* Save actual USART configuration */
  356. tmpcr1 = READ_REG(husart->Instance->CR1);
  357. /* Disable USART */
  358. __HAL_USART_DISABLE(husart);
  359. /* Update RX threshold configuration */
  360. MODIFY_REG(husart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
  361. /* Determine the number of data to process during RX/TX ISR execution */
  362. USARTEx_SetNbDataToProcess(husart);
  363. /* Restore USART configuration */
  364. WRITE_REG(husart->Instance->CR1, tmpcr1);
  365. husart->State = HAL_USART_STATE_READY;
  366. /* Process Unlocked */
  367. __HAL_UNLOCK(husart);
  368. return HAL_OK;
  369. }
  370. /**
  371. * @}
  372. */
  373. /**
  374. * @}
  375. */
  376. /** @addtogroup USARTEx_Private_Functions
  377. * @{
  378. */
  379. /**
  380. * @brief Calculate the number of data to process in RX/TX ISR.
  381. * @note The RX FIFO depth and the TX FIFO depth is extracted from
  382. * the USART configuration registers.
  383. * @param husart USART handle.
  384. * @retval None
  385. */
  386. static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart)
  387. {
  388. uint8_t rx_fifo_depth;
  389. uint8_t tx_fifo_depth;
  390. uint8_t rx_fifo_threshold;
  391. uint8_t tx_fifo_threshold;
  392. /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */
  393. uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
  394. uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
  395. if (husart->FifoMode == USART_FIFOMODE_DISABLE)
  396. {
  397. husart->NbTxDataToProcess = 1U;
  398. husart->NbRxDataToProcess = 1U;
  399. }
  400. else
  401. {
  402. rx_fifo_depth = RX_FIFO_DEPTH;
  403. tx_fifo_depth = TX_FIFO_DEPTH;
  404. rx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos) & 0xFFU);
  405. tx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos) & 0xFFU);
  406. husart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / (uint16_t)denominator[tx_fifo_threshold];
  407. husart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / (uint16_t)denominator[rx_fifo_threshold];
  408. }
  409. }
  410. /**
  411. * @}
  412. */
  413. #endif /* HAL_USART_MODULE_ENABLED */
  414. /**
  415. * @}
  416. */
  417. /**
  418. * @}
  419. */
  420. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/