stm32l4xx_hal_uart_ex.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_hal_uart_ex.c
  4. * @author MCD Application Team
  5. * @brief Extended UART HAL module driver.
  6. * This file provides firmware functions to manage the following extended
  7. * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
  8. * + Initialization and de-initialization functions
  9. * + Peripheral Control functions
  10. *
  11. *
  12. ******************************************************************************
  13. * @attention
  14. *
  15. * Copyright (c) 2017 STMicroelectronics.
  16. * All rights reserved.
  17. *
  18. * This software is licensed under terms that can be found in the LICENSE file
  19. * in the root directory of this software component.
  20. * If no LICENSE file comes with this software, it is provided AS-IS.
  21. *
  22. ******************************************************************************
  23. @verbatim
  24. ==============================================================================
  25. ##### UART peripheral extended features #####
  26. ==============================================================================
  27. [..]
  28. (#) Declare a UART_HandleTypeDef handle structure.
  29. (#) For the UART RS485 Driver Enable mode, initialize the UART registers
  30. by calling the HAL_RS485Ex_Init() API.
  31. (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
  32. -@- When UART operates in FIFO mode, FIFO mode must be enabled prior
  33. starting RX/TX transfers. Also RX/TX FIFO thresholds must be
  34. configured prior starting RX/TX transfers.
  35. @endverbatim
  36. ******************************************************************************
  37. */
  38. /* Includes ------------------------------------------------------------------*/
  39. #include "stm32l4xx_hal.h"
  40. /** @addtogroup STM32L4xx_HAL_Driver
  41. * @{
  42. */
  43. /** @defgroup UARTEx UARTEx
  44. * @brief UART Extended HAL module driver
  45. * @{
  46. */
  47. #ifdef HAL_UART_MODULE_ENABLED
  48. /* Private typedef -----------------------------------------------------------*/
  49. /* Private define ------------------------------------------------------------*/
  50. #if defined(USART_CR1_FIFOEN)
  51. /** @defgroup UARTEX_Private_Constants UARTEx Private Constants
  52. * @{
  53. */
  54. /* UART RX FIFO depth */
  55. #define RX_FIFO_DEPTH 8U
  56. /* UART TX FIFO depth */
  57. #define TX_FIFO_DEPTH 8U
  58. /**
  59. * @}
  60. */
  61. #endif /* USART_CR1_FIFOEN */
  62. /* Private macros ------------------------------------------------------------*/
  63. /* Private variables ---------------------------------------------------------*/
  64. /* Private function prototypes -----------------------------------------------*/
  65. /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
  66. * @{
  67. */
  68. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
  69. #if defined(USART_CR1_FIFOEN)
  70. static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart);
  71. #endif /* USART_CR1_FIFOEN */
  72. /**
  73. * @}
  74. */
  75. /* Exported functions --------------------------------------------------------*/
  76. /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions
  77. * @{
  78. */
  79. /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
  80. * @brief Extended Initialization and Configuration Functions
  81. *
  82. @verbatim
  83. ===============================================================================
  84. ##### Initialization and Configuration functions #####
  85. ===============================================================================
  86. [..]
  87. This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
  88. in asynchronous mode.
  89. (+) For the asynchronous mode the parameters below can be configured:
  90. (++) Baud Rate
  91. (++) Word Length
  92. (++) Stop Bit
  93. (++) Parity: If the parity is enabled, then the MSB bit of the data written
  94. in the data register is transmitted but is changed by the parity bit.
  95. (++) Hardware flow control
  96. (++) Receiver/transmitter modes
  97. (++) Over Sampling Method
  98. (++) One-Bit Sampling Method
  99. (+) For the asynchronous mode, the following advanced features can be configured as well:
  100. (++) TX and/or RX pin level inversion
  101. (++) data logical level inversion
  102. (++) RX and TX pins swap
  103. (++) RX overrun detection disabling
  104. (++) DMA disabling on RX error
  105. (++) MSB first on communication line
  106. (++) auto Baud rate detection
  107. [..]
  108. The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
  109. procedures (details for the procedures are available in reference manual).
  110. @endverbatim
  111. Depending on the frame length defined by the M1 and M0 bits (7-bit,
  112. 8-bit or 9-bit), the possible UART formats are listed in the
  113. following table.
  114. Table 1. UART frame format.
  115. +-----------------------------------------------------------------------+
  116. | M1 bit | M0 bit | PCE bit | UART frame |
  117. |---------|---------|-----------|---------------------------------------|
  118. | 0 | 0 | 0 | | SB | 8 bit data | STB | |
  119. |---------|---------|-----------|---------------------------------------|
  120. | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
  121. |---------|---------|-----------|---------------------------------------|
  122. | 0 | 1 | 0 | | SB | 9 bit data | STB | |
  123. |---------|---------|-----------|---------------------------------------|
  124. | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
  125. |---------|---------|-----------|---------------------------------------|
  126. | 1 | 0 | 0 | | SB | 7 bit data | STB | |
  127. |---------|---------|-----------|---------------------------------------|
  128. | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
  129. +-----------------------------------------------------------------------+
  130. * @{
  131. */
  132. /**
  133. * @brief Initialize the RS485 Driver enable feature according to the specified
  134. * parameters in the UART_InitTypeDef and creates the associated handle.
  135. * @param huart UART handle.
  136. * @param Polarity Select the driver enable polarity.
  137. * This parameter can be one of the following values:
  138. * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
  139. * @arg @ref UART_DE_POLARITY_LOW DE signal is active low
  140. * @param AssertionTime Driver Enable assertion time:
  141. * 5-bit value defining the time between the activation of the DE (Driver Enable)
  142. * signal and the beginning of the start bit. It is expressed in sample time
  143. * units (1/8 or 1/16 bit time, depending on the oversampling rate)
  144. * @param DeassertionTime Driver Enable deassertion time:
  145. * 5-bit value defining the time between the end of the last stop bit, in a
  146. * transmitted message, and the de-activation of the DE (Driver Enable) signal.
  147. * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
  148. * oversampling rate).
  149. * @retval HAL status
  150. */
  151. HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime,
  152. uint32_t DeassertionTime)
  153. {
  154. uint32_t temp;
  155. /* Check the UART handle allocation */
  156. if (huart == NULL)
  157. {
  158. return HAL_ERROR;
  159. }
  160. /* Check the Driver Enable UART instance */
  161. assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
  162. /* Check the Driver Enable polarity */
  163. assert_param(IS_UART_DE_POLARITY(Polarity));
  164. /* Check the Driver Enable assertion time */
  165. assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
  166. /* Check the Driver Enable deassertion time */
  167. assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
  168. if (huart->gState == HAL_UART_STATE_RESET)
  169. {
  170. /* Allocate lock resource and initialize it */
  171. huart->Lock = HAL_UNLOCKED;
  172. #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
  173. UART_InitCallbacksToDefault(huart);
  174. if (huart->MspInitCallback == NULL)
  175. {
  176. huart->MspInitCallback = HAL_UART_MspInit;
  177. }
  178. /* Init the low level hardware */
  179. huart->MspInitCallback(huart);
  180. #else
  181. /* Init the low level hardware : GPIO, CLOCK, CORTEX */
  182. HAL_UART_MspInit(huart);
  183. #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
  184. }
  185. huart->gState = HAL_UART_STATE_BUSY;
  186. /* Disable the Peripheral */
  187. __HAL_UART_DISABLE(huart);
  188. /* Perform advanced settings configuration */
  189. /* For some items, configuration requires to be done prior TE and RE bits are set */
  190. if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
  191. {
  192. UART_AdvFeatureConfig(huart);
  193. }
  194. /* Set the UART Communication parameters */
  195. if (UART_SetConfig(huart) == HAL_ERROR)
  196. {
  197. return HAL_ERROR;
  198. }
  199. /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
  200. SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
  201. /* Set the Driver Enable polarity */
  202. MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
  203. /* Set the Driver Enable assertion and deassertion times */
  204. temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
  205. temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
  206. MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
  207. /* Enable the Peripheral */
  208. __HAL_UART_ENABLE(huart);
  209. /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
  210. return (UART_CheckIdleState(huart));
  211. }
  212. /**
  213. * @}
  214. */
  215. /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions
  216. * @brief Extended functions
  217. *
  218. @verbatim
  219. ===============================================================================
  220. ##### IO operation functions #####
  221. ===============================================================================
  222. [..]
  223. This subsection provides a set of Wakeup and FIFO mode related callback functions.
  224. (#) Wakeup from Stop mode Callback:
  225. (++) HAL_UARTEx_WakeupCallback()
  226. (#) TX/RX Fifos Callbacks:
  227. (++) HAL_UARTEx_RxFifoFullCallback()
  228. (++) HAL_UARTEx_TxFifoEmptyCallback()
  229. @endverbatim
  230. * @{
  231. */
  232. /**
  233. * @brief UART wakeup from Stop mode callback.
  234. * @param huart UART handle.
  235. * @retval None
  236. */
  237. __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
  238. {
  239. /* Prevent unused argument(s) compilation warning */
  240. UNUSED(huart);
  241. /* NOTE : This function should not be modified, when the callback is needed,
  242. the HAL_UARTEx_WakeupCallback can be implemented in the user file.
  243. */
  244. }
  245. #if defined(USART_CR1_FIFOEN)
  246. /**
  247. * @brief UART RX Fifo full callback.
  248. * @param huart UART handle.
  249. * @retval None
  250. */
  251. __weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart)
  252. {
  253. /* Prevent unused argument(s) compilation warning */
  254. UNUSED(huart);
  255. /* NOTE : This function should not be modified, when the callback is needed,
  256. the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file.
  257. */
  258. }
  259. /**
  260. * @brief UART TX Fifo empty callback.
  261. * @param huart UART handle.
  262. * @retval None
  263. */
  264. __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart)
  265. {
  266. /* Prevent unused argument(s) compilation warning */
  267. UNUSED(huart);
  268. /* NOTE : This function should not be modified, when the callback is needed,
  269. the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file.
  270. */
  271. }
  272. #endif /* USART_CR1_FIFOEN */
  273. /**
  274. * @}
  275. */
  276. /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
  277. * @brief Extended Peripheral Control functions
  278. *
  279. @verbatim
  280. ===============================================================================
  281. ##### Peripheral Control functions #####
  282. ===============================================================================
  283. [..] This section provides the following functions:
  284. (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode
  285. (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality
  286. (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
  287. detection length to more than 4 bits for multiprocessor address mark wake up.
  288. (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
  289. trigger: address match, Start Bit detection or RXNE bit status.
  290. (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
  291. (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
  292. (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode
  293. (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode
  294. (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
  295. (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
  296. [..] This subsection also provides a set of additional functions providing enhanced reception
  297. services to user. (For example, these functions allow application to handle use cases
  298. where number of data to be received is unknown).
  299. (#) Compared to standard reception services which only consider number of received
  300. data elements as reception completion criteria, these functions also consider additional events
  301. as triggers for updating reception status to caller :
  302. (++) Detection of inactivity period (RX line has not been active for a given period).
  303. (+++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
  304. for 1 frame time, after last received byte.
  305. (+++) RX inactivity detected by RTO, i.e. line has been in idle state
  306. for a programmable time, after last received byte.
  307. (++) Detection that a specific character has been received.
  308. (#) There are two modes of transfer:
  309. (++) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
  310. or till IDLE event occurs. Reception is handled only during function execution.
  311. When function exits, no data reception could occur. HAL status and number of actually received data elements,
  312. are returned by function after finishing transfer.
  313. (++) Non-Blocking mode: The reception is performed using Interrupts or DMA.
  314. These API's return the HAL status.
  315. The end of the data processing will be indicated through the
  316. dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
  317. The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
  318. The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
  319. (#) Blocking mode API:
  320. (++) HAL_UARTEx_ReceiveToIdle()
  321. (#) Non-Blocking mode API with Interrupt:
  322. (++) HAL_UARTEx_ReceiveToIdle_IT()
  323. (#) Non-Blocking mode API with DMA:
  324. (++) HAL_UARTEx_ReceiveToIdle_DMA()
  325. @endverbatim
  326. * @{
  327. */
  328. #if defined(USART_CR3_UCESM)
  329. /**
  330. * @brief Keep UART Clock enabled when in Stop Mode.
  331. * @note When the USART clock source is configured to be LSE or HSI, it is possible to keep enabled
  332. * this clock during STOP mode by setting the UCESM bit in USART_CR3 control register.
  333. * @note When LPUART is used to wakeup from stop with LSE is selected as LPUART clock source,
  334. * and desired baud rate is 9600 baud, the bit UCESM bit in LPUART_CR3 control register must be set.
  335. * @param huart UART handle.
  336. * @retval HAL status
  337. */
  338. HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart)
  339. {
  340. /* Process Locked */
  341. __HAL_LOCK(huart);
  342. /* Set UCESM bit */
  343. ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_UCESM);
  344. /* Process Unlocked */
  345. __HAL_UNLOCK(huart);
  346. return HAL_OK;
  347. }
  348. /**
  349. * @brief Disable UART Clock when in Stop Mode.
  350. * @param huart UART handle.
  351. * @retval HAL status
  352. */
  353. HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart)
  354. {
  355. /* Process Locked */
  356. __HAL_LOCK(huart);
  357. /* Clear UCESM bit */
  358. ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM);
  359. /* Process Unlocked */
  360. __HAL_UNLOCK(huart);
  361. return HAL_OK;
  362. }
  363. #endif /* USART_CR3_UCESM */
  364. /**
  365. * @brief By default in multiprocessor mode, when the wake up method is set
  366. * to address mark, the UART handles only 4-bit long addresses detection;
  367. * this API allows to enable longer addresses detection (6-, 7- or 8-bit
  368. * long).
  369. * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
  370. * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
  371. * @param huart UART handle.
  372. * @param AddressLength This parameter can be one of the following values:
  373. * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
  374. * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
  375. * @retval HAL status
  376. */
  377. HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
  378. {
  379. /* Check the UART handle allocation */
  380. if (huart == NULL)
  381. {
  382. return HAL_ERROR;
  383. }
  384. /* Check the address length parameter */
  385. assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
  386. huart->gState = HAL_UART_STATE_BUSY;
  387. /* Disable the Peripheral */
  388. __HAL_UART_DISABLE(huart);
  389. /* Set the address length */
  390. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
  391. /* Enable the Peripheral */
  392. __HAL_UART_ENABLE(huart);
  393. /* TEACK and/or REACK to check before moving huart->gState to Ready */
  394. return (UART_CheckIdleState(huart));
  395. }
  396. /**
  397. * @brief Set Wakeup from Stop mode interrupt flag selection.
  398. * @note It is the application responsibility to enable the interrupt used as
  399. * usart_wkup interrupt source before entering low-power mode.
  400. * @param huart UART handle.
  401. * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
  402. * This parameter can be one of the following values:
  403. * @arg @ref UART_WAKEUP_ON_ADDRESS
  404. * @arg @ref UART_WAKEUP_ON_STARTBIT
  405. * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
  406. * @retval HAL status
  407. */
  408. HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  409. {
  410. HAL_StatusTypeDef status = HAL_OK;
  411. uint32_t tickstart;
  412. /* check the wake-up from stop mode UART instance */
  413. assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
  414. /* check the wake-up selection parameter */
  415. assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
  416. /* Process Locked */
  417. __HAL_LOCK(huart);
  418. huart->gState = HAL_UART_STATE_BUSY;
  419. /* Disable the Peripheral */
  420. __HAL_UART_DISABLE(huart);
  421. /* Set the wake-up selection scheme */
  422. MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
  423. if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
  424. {
  425. UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
  426. }
  427. /* Enable the Peripheral */
  428. __HAL_UART_ENABLE(huart);
  429. /* Init tickstart for timeout management */
  430. tickstart = HAL_GetTick();
  431. /* Wait until REACK flag is set */
  432. if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
  433. {
  434. status = HAL_TIMEOUT;
  435. }
  436. else
  437. {
  438. /* Initialize the UART State */
  439. huart->gState = HAL_UART_STATE_READY;
  440. }
  441. /* Process Unlocked */
  442. __HAL_UNLOCK(huart);
  443. return status;
  444. }
  445. /**
  446. * @brief Enable UART Stop Mode.
  447. * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
  448. * @param huart UART handle.
  449. * @retval HAL status
  450. */
  451. HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
  452. {
  453. /* Process Locked */
  454. __HAL_LOCK(huart);
  455. /* Set UESM bit */
  456. ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
  457. /* Process Unlocked */
  458. __HAL_UNLOCK(huart);
  459. return HAL_OK;
  460. }
  461. /**
  462. * @brief Disable UART Stop Mode.
  463. * @param huart UART handle.
  464. * @retval HAL status
  465. */
  466. HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
  467. {
  468. /* Process Locked */
  469. __HAL_LOCK(huart);
  470. /* Clear UESM bit */
  471. ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
  472. /* Process Unlocked */
  473. __HAL_UNLOCK(huart);
  474. return HAL_OK;
  475. }
  476. #if defined(USART_CR1_FIFOEN)
  477. /**
  478. * @brief Enable the FIFO mode.
  479. * @param huart UART handle.
  480. * @retval HAL status
  481. */
  482. HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart)
  483. {
  484. uint32_t tmpcr1;
  485. /* Check parameters */
  486. assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
  487. /* Process Locked */
  488. __HAL_LOCK(huart);
  489. huart->gState = HAL_UART_STATE_BUSY;
  490. /* Save actual UART configuration */
  491. tmpcr1 = READ_REG(huart->Instance->CR1);
  492. /* Disable UART */
  493. __HAL_UART_DISABLE(huart);
  494. /* Enable FIFO mode */
  495. SET_BIT(tmpcr1, USART_CR1_FIFOEN);
  496. huart->FifoMode = UART_FIFOMODE_ENABLE;
  497. /* Restore UART configuration */
  498. WRITE_REG(huart->Instance->CR1, tmpcr1);
  499. /* Determine the number of data to process during RX/TX ISR execution */
  500. UARTEx_SetNbDataToProcess(huart);
  501. huart->gState = HAL_UART_STATE_READY;
  502. /* Process Unlocked */
  503. __HAL_UNLOCK(huart);
  504. return HAL_OK;
  505. }
  506. /**
  507. * @brief Disable the FIFO mode.
  508. * @param huart UART handle.
  509. * @retval HAL status
  510. */
  511. HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart)
  512. {
  513. uint32_t tmpcr1;
  514. /* Check parameters */
  515. assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
  516. /* Process Locked */
  517. __HAL_LOCK(huart);
  518. huart->gState = HAL_UART_STATE_BUSY;
  519. /* Save actual UART configuration */
  520. tmpcr1 = READ_REG(huart->Instance->CR1);
  521. /* Disable UART */
  522. __HAL_UART_DISABLE(huart);
  523. /* Disable FIFO mode */
  524. CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
  525. huart->FifoMode = UART_FIFOMODE_DISABLE;
  526. /* Restore UART configuration */
  527. WRITE_REG(huart->Instance->CR1, tmpcr1);
  528. huart->gState = HAL_UART_STATE_READY;
  529. /* Process Unlocked */
  530. __HAL_UNLOCK(huart);
  531. return HAL_OK;
  532. }
  533. /**
  534. * @brief Set the TXFIFO threshold.
  535. * @param huart UART handle.
  536. * @param Threshold TX FIFO threshold value
  537. * This parameter can be one of the following values:
  538. * @arg @ref UART_TXFIFO_THRESHOLD_1_8
  539. * @arg @ref UART_TXFIFO_THRESHOLD_1_4
  540. * @arg @ref UART_TXFIFO_THRESHOLD_1_2
  541. * @arg @ref UART_TXFIFO_THRESHOLD_3_4
  542. * @arg @ref UART_TXFIFO_THRESHOLD_7_8
  543. * @arg @ref UART_TXFIFO_THRESHOLD_8_8
  544. * @retval HAL status
  545. */
  546. HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
  547. {
  548. uint32_t tmpcr1;
  549. /* Check parameters */
  550. assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
  551. assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold));
  552. /* Process Locked */
  553. __HAL_LOCK(huart);
  554. huart->gState = HAL_UART_STATE_BUSY;
  555. /* Save actual UART configuration */
  556. tmpcr1 = READ_REG(huart->Instance->CR1);
  557. /* Disable UART */
  558. __HAL_UART_DISABLE(huart);
  559. /* Update TX threshold configuration */
  560. MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
  561. /* Determine the number of data to process during RX/TX ISR execution */
  562. UARTEx_SetNbDataToProcess(huart);
  563. /* Restore UART configuration */
  564. WRITE_REG(huart->Instance->CR1, tmpcr1);
  565. huart->gState = HAL_UART_STATE_READY;
  566. /* Process Unlocked */
  567. __HAL_UNLOCK(huart);
  568. return HAL_OK;
  569. }
  570. /**
  571. * @brief Set the RXFIFO threshold.
  572. * @param huart UART handle.
  573. * @param Threshold RX FIFO threshold value
  574. * This parameter can be one of the following values:
  575. * @arg @ref UART_RXFIFO_THRESHOLD_1_8
  576. * @arg @ref UART_RXFIFO_THRESHOLD_1_4
  577. * @arg @ref UART_RXFIFO_THRESHOLD_1_2
  578. * @arg @ref UART_RXFIFO_THRESHOLD_3_4
  579. * @arg @ref UART_RXFIFO_THRESHOLD_7_8
  580. * @arg @ref UART_RXFIFO_THRESHOLD_8_8
  581. * @retval HAL status
  582. */
  583. HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
  584. {
  585. uint32_t tmpcr1;
  586. /* Check the parameters */
  587. assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
  588. assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold));
  589. /* Process Locked */
  590. __HAL_LOCK(huart);
  591. huart->gState = HAL_UART_STATE_BUSY;
  592. /* Save actual UART configuration */
  593. tmpcr1 = READ_REG(huart->Instance->CR1);
  594. /* Disable UART */
  595. __HAL_UART_DISABLE(huart);
  596. /* Update RX threshold configuration */
  597. MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
  598. /* Determine the number of data to process during RX/TX ISR execution */
  599. UARTEx_SetNbDataToProcess(huart);
  600. /* Restore UART configuration */
  601. WRITE_REG(huart->Instance->CR1, tmpcr1);
  602. huart->gState = HAL_UART_STATE_READY;
  603. /* Process Unlocked */
  604. __HAL_UNLOCK(huart);
  605. return HAL_OK;
  606. }
  607. #endif /* USART_CR1_FIFOEN */
  608. /**
  609. * @brief Receive an amount of data in blocking mode till either the expected number of data
  610. * is received or an IDLE event occurs.
  611. * @note HAL_OK is returned if reception is completed (expected number of data has been received)
  612. * or if reception is stopped after IDLE event (less than the expected number of data has been received)
  613. * In this case, RxLen output parameter indicates number of data available in reception buffer.
  614. * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  615. * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
  616. * of uint16_t available through pData.
  617. * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
  618. * is not empty. Read operations from the RDR register are performed when
  619. * RXFNE flag is set. From hardware perspective, RXFNE flag and
  620. * RXNE are mapped on the same bit-field.
  621. * @param huart UART handle.
  622. * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
  623. * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
  624. * @param RxLen Number of data elements finally received
  625. * (could be lower than Size, in case reception ends on IDLE event)
  626. * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
  627. * @retval HAL status
  628. */
  629. HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
  630. uint32_t Timeout)
  631. {
  632. uint8_t *pdata8bits;
  633. uint16_t *pdata16bits;
  634. uint16_t uhMask;
  635. uint32_t tickstart;
  636. /* Check that a Rx process is not already ongoing */
  637. if (huart->RxState == HAL_UART_STATE_READY)
  638. {
  639. if ((pData == NULL) || (Size == 0U))
  640. {
  641. return HAL_ERROR;
  642. }
  643. huart->ErrorCode = HAL_UART_ERROR_NONE;
  644. huart->RxState = HAL_UART_STATE_BUSY_RX;
  645. huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
  646. huart->RxEventType = HAL_UART_RXEVENT_TC;
  647. /* Init tickstart for timeout management */
  648. tickstart = HAL_GetTick();
  649. huart->RxXferSize = Size;
  650. huart->RxXferCount = Size;
  651. /* Computation of UART mask to apply to RDR register */
  652. UART_MASK_COMPUTATION(huart);
  653. uhMask = huart->Mask;
  654. /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
  655. if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
  656. {
  657. pdata8bits = NULL;
  658. pdata16bits = (uint16_t *) pData;
  659. }
  660. else
  661. {
  662. pdata8bits = pData;
  663. pdata16bits = NULL;
  664. }
  665. /* Initialize output number of received elements */
  666. *RxLen = 0U;
  667. /* as long as data have to be received */
  668. while (huart->RxXferCount > 0U)
  669. {
  670. /* Check if IDLE flag is set */
  671. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
  672. {
  673. /* Clear IDLE flag in ISR */
  674. __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
  675. /* If Set, but no data ever received, clear flag without exiting loop */
  676. /* If Set, and data has already been received, this means Idle Event is valid : End reception */
  677. if (*RxLen > 0U)
  678. {
  679. huart->RxEventType = HAL_UART_RXEVENT_IDLE;
  680. huart->RxState = HAL_UART_STATE_READY;
  681. return HAL_OK;
  682. }
  683. }
  684. /* Check if RXNE flag is set */
  685. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
  686. {
  687. if (pdata8bits == NULL)
  688. {
  689. *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
  690. pdata16bits++;
  691. }
  692. else
  693. {
  694. *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
  695. pdata8bits++;
  696. }
  697. /* Increment number of received elements */
  698. *RxLen += 1U;
  699. huart->RxXferCount--;
  700. }
  701. /* Check for the Timeout */
  702. if (Timeout != HAL_MAX_DELAY)
  703. {
  704. if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
  705. {
  706. huart->RxState = HAL_UART_STATE_READY;
  707. return HAL_TIMEOUT;
  708. }
  709. }
  710. }
  711. /* Set number of received elements in output parameter : RxLen */
  712. *RxLen = huart->RxXferSize - huart->RxXferCount;
  713. /* At end of Rx process, restore huart->RxState to Ready */
  714. huart->RxState = HAL_UART_STATE_READY;
  715. return HAL_OK;
  716. }
  717. else
  718. {
  719. return HAL_BUSY;
  720. }
  721. }
  722. /**
  723. * @brief Receive an amount of data in interrupt mode till either the expected number of data
  724. * is received or an IDLE event occurs.
  725. * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
  726. * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
  727. * number of received data elements.
  728. * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  729. * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
  730. * of uint16_t available through pData.
  731. * @param huart UART handle.
  732. * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
  733. * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
  734. * @retval HAL status
  735. */
  736. HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  737. {
  738. HAL_StatusTypeDef status = HAL_OK;
  739. /* Check that a Rx process is not already ongoing */
  740. if (huart->RxState == HAL_UART_STATE_READY)
  741. {
  742. if ((pData == NULL) || (Size == 0U))
  743. {
  744. return HAL_ERROR;
  745. }
  746. /* Set Reception type to reception till IDLE Event*/
  747. huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
  748. huart->RxEventType = HAL_UART_RXEVENT_TC;
  749. (void)UART_Start_Receive_IT(huart, pData, Size);
  750. if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
  751. {
  752. __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
  753. ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
  754. }
  755. else
  756. {
  757. /* In case of errors already pending when reception is started,
  758. Interrupts may have already been raised and lead to reception abortion.
  759. (Overrun error for instance).
  760. In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
  761. status = HAL_ERROR;
  762. }
  763. return status;
  764. }
  765. else
  766. {
  767. return HAL_BUSY;
  768. }
  769. }
  770. /**
  771. * @brief Receive an amount of data in DMA mode till either the expected number
  772. * of data is received or an IDLE event occurs.
  773. * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
  774. * to DMA services, transferring automatically received data elements in user reception buffer and
  775. * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
  776. * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
  777. * @note When the UART parity is enabled (PCE = 1), the received data contain
  778. * the parity bit (MSB position).
  779. * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  780. * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
  781. * of uint16_t available through pData.
  782. * @param huart UART handle.
  783. * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
  784. * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
  785. * @retval HAL status
  786. */
  787. HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  788. {
  789. HAL_StatusTypeDef status;
  790. /* Check that a Rx process is not already ongoing */
  791. if (huart->RxState == HAL_UART_STATE_READY)
  792. {
  793. if ((pData == NULL) || (Size == 0U))
  794. {
  795. return HAL_ERROR;
  796. }
  797. /* Set Reception type to reception till IDLE Event*/
  798. huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
  799. huart->RxEventType = HAL_UART_RXEVENT_TC;
  800. status = UART_Start_Receive_DMA(huart, pData, Size);
  801. /* Check Rx process has been successfully started */
  802. if (status == HAL_OK)
  803. {
  804. if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
  805. {
  806. __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
  807. ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
  808. }
  809. else
  810. {
  811. /* In case of errors already pending when reception is started,
  812. Interrupts may have already been raised and lead to reception abortion.
  813. (Overrun error for instance).
  814. In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
  815. status = HAL_ERROR;
  816. }
  817. }
  818. return status;
  819. }
  820. else
  821. {
  822. return HAL_BUSY;
  823. }
  824. }
  825. /**
  826. * @brief Provide Rx Event type that has lead to RxEvent callback execution.
  827. * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
  828. * of reception process is provided to application through calls of Rx Event callback (either default one
  829. * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
  830. * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
  831. * to Rx Event callback execution.
  832. * @note This function is expected to be called within the user implementation of Rx Event Callback,
  833. * in order to provide the accurate value.
  834. * @note In Interrupt Mode:
  835. * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received).
  836. * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed.
  837. * @note In DMA Mode:
  838. * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received).
  839. * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received.
  840. * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed.
  841. * @note In DMA mode, RxEvent callback could be called several times;
  842. * When DMA is configured in Normal Mode, HT event does not stop Reception process;
  843. * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
  844. * @param huart UART handle.
  845. * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values)
  846. */
  847. HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart)
  848. {
  849. /* Return Rx Event type value, as stored in UART handle */
  850. return (huart->RxEventType);
  851. }
  852. /**
  853. * @}
  854. */
  855. /**
  856. * @}
  857. */
  858. /** @addtogroup UARTEx_Private_Functions
  859. * @{
  860. */
  861. /**
  862. * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
  863. * @param huart UART handle.
  864. * @param WakeUpSelection UART wake up from stop mode parameters.
  865. * @retval None
  866. */
  867. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  868. {
  869. assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
  870. /* Set the USART address length */
  871. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
  872. /* Set the USART address node */
  873. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
  874. }
  875. #if defined(USART_CR1_FIFOEN)
  876. /**
  877. * @brief Calculate the number of data to process in RX/TX ISR.
  878. * @note The RX FIFO depth and the TX FIFO depth is extracted from
  879. * the UART configuration registers.
  880. * @param huart UART handle.
  881. * @retval None
  882. */
  883. static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart)
  884. {
  885. uint8_t rx_fifo_depth;
  886. uint8_t tx_fifo_depth;
  887. uint8_t rx_fifo_threshold;
  888. uint8_t tx_fifo_threshold;
  889. static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
  890. static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
  891. if (huart->FifoMode == UART_FIFOMODE_DISABLE)
  892. {
  893. huart->NbTxDataToProcess = 1U;
  894. huart->NbRxDataToProcess = 1U;
  895. }
  896. else
  897. {
  898. rx_fifo_depth = RX_FIFO_DEPTH;
  899. tx_fifo_depth = TX_FIFO_DEPTH;
  900. rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
  901. tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
  902. huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
  903. (uint16_t)denominator[tx_fifo_threshold];
  904. huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
  905. (uint16_t)denominator[rx_fifo_threshold];
  906. }
  907. }
  908. #endif /* USART_CR1_FIFOEN */
  909. /**
  910. * @}
  911. */
  912. #endif /* HAL_UART_MODULE_ENABLED */
  913. /**
  914. * @}
  915. */
  916. /**
  917. * @}
  918. */