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.
 
 
 

516 lines
17 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32l0xx_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. @verbatim
  13. ==============================================================================
  14. ##### UART peripheral extended features #####
  15. ==============================================================================
  16. (#) Declare a UART_HandleTypeDef handle structure.
  17. (#) For the UART RS485 Driver Enable mode, initialize the UART registers
  18. by calling the HAL_RS485Ex_Init() API.
  19. @endverbatim
  20. ******************************************************************************
  21. * @attention
  22. *
  23. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  24. * All rights reserved.</center></h2>
  25. *
  26. * This software component is licensed by ST under BSD 3-Clause license,
  27. * the "License"; You may not use this file except in compliance with the
  28. * License. You may obtain a copy of the License at:
  29. * opensource.org/licenses/BSD-3-Clause
  30. *
  31. ******************************************************************************
  32. */
  33. /* Includes ------------------------------------------------------------------*/
  34. #include "stm32l0xx_hal.h"
  35. /** @addtogroup STM32L0xx_HAL_Driver
  36. * @{
  37. */
  38. /** @defgroup UARTEx UARTEx
  39. * @brief UART Extended HAL module driver
  40. * @{
  41. */
  42. #ifdef HAL_UART_MODULE_ENABLED
  43. /* Private typedef -----------------------------------------------------------*/
  44. /* Private define ------------------------------------------------------------*/
  45. /* Private macros ------------------------------------------------------------*/
  46. /* Private variables ---------------------------------------------------------*/
  47. /* Private function prototypes -----------------------------------------------*/
  48. /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
  49. * @{
  50. */
  51. #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
  52. extern void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
  53. #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
  54. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
  55. /**
  56. * @}
  57. */
  58. /* Exported functions --------------------------------------------------------*/
  59. /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions
  60. * @{
  61. */
  62. /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
  63. * @brief Extended Initialization and Configuration Functions
  64. *
  65. @verbatim
  66. ===============================================================================
  67. ##### Initialization and Configuration functions #####
  68. ===============================================================================
  69. [..]
  70. This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
  71. in asynchronous mode.
  72. (+) For the asynchronous mode the parameters below can be configured:
  73. (++) Baud Rate
  74. (++) Word Length
  75. (++) Stop Bit
  76. (++) Parity: If the parity is enabled, then the MSB bit of the data written
  77. in the data register is transmitted but is changed by the parity bit.
  78. (++) Hardware flow control
  79. (++) Receiver/transmitter modes
  80. (++) Over Sampling Method
  81. (++) One-Bit Sampling Method
  82. (+) For the asynchronous mode, the following advanced features can be configured as well:
  83. (++) TX and/or RX pin level inversion
  84. (++) data logical level inversion
  85. (++) RX and TX pins swap
  86. (++) RX overrun detection disabling
  87. (++) DMA disabling on RX error
  88. (++) MSB first on communication line
  89. (++) auto Baud rate detection
  90. [..]
  91. The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
  92. procedures (details for the procedures are available in reference manual).
  93. @endverbatim
  94. Depending on the frame length defined by the M1 and M0 bits (7-bit,
  95. 8-bit or 9-bit), the possible UART formats are listed in the
  96. following table.
  97. Table 1. UART frame format.
  98. +-----------------------------------------------------------------------+
  99. | M1 bit | M0 bit | PCE bit | UART frame |
  100. |---------|---------|-----------|---------------------------------------|
  101. | 0 | 0 | 0 | | SB | 8 bit data | STB | |
  102. |---------|---------|-----------|---------------------------------------|
  103. | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
  104. |---------|---------|-----------|---------------------------------------|
  105. | 0 | 1 | 0 | | SB | 9 bit data | STB | |
  106. |---------|---------|-----------|---------------------------------------|
  107. | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
  108. |---------|---------|-----------|---------------------------------------|
  109. | 1 | 0 | 0 | | SB | 7 bit data | STB | |
  110. |---------|---------|-----------|---------------------------------------|
  111. | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
  112. +-----------------------------------------------------------------------+
  113. * @{
  114. */
  115. /**
  116. * @brief Initialize the RS485 Driver enable feature according to the specified
  117. * parameters in the UART_InitTypeDef and creates the associated handle.
  118. * @param huart UART handle.
  119. * @param Polarity Select the driver enable polarity.
  120. * This parameter can be one of the following values:
  121. * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
  122. * @arg @ref UART_DE_POLARITY_LOW DE signal is active low
  123. * @param AssertionTime Driver Enable assertion time:
  124. * 5-bit value defining the time between the activation of the DE (Driver Enable)
  125. * signal and the beginning of the start bit. It is expressed in sample time
  126. * units (1/8 or 1/16 bit time, depending on the oversampling rate)
  127. * @param DeassertionTime Driver Enable deassertion time:
  128. * 5-bit value defining the time between the end of the last stop bit, in a
  129. * transmitted message, and the de-activation of the DE (Driver Enable) signal.
  130. * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
  131. * oversampling rate).
  132. * @retval HAL status
  133. */
  134. HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime)
  135. {
  136. uint32_t temp;
  137. /* Check the UART handle allocation */
  138. if (huart == NULL)
  139. {
  140. return HAL_ERROR;
  141. }
  142. /* Check the Driver Enable UART instance */
  143. assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
  144. /* Check the Driver Enable polarity */
  145. assert_param(IS_UART_DE_POLARITY(Polarity));
  146. /* Check the Driver Enable assertion time */
  147. assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
  148. /* Check the Driver Enable deassertion time */
  149. assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
  150. if (huart->gState == HAL_UART_STATE_RESET)
  151. {
  152. /* Allocate lock resource and initialize it */
  153. huart->Lock = HAL_UNLOCKED;
  154. #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
  155. UART_InitCallbacksToDefault(huart);
  156. if (huart->MspInitCallback == NULL)
  157. {
  158. huart->MspInitCallback = HAL_UART_MspInit;
  159. }
  160. /* Init the low level hardware */
  161. huart->MspInitCallback(huart);
  162. #else
  163. /* Init the low level hardware : GPIO, CLOCK, CORTEX */
  164. HAL_UART_MspInit(huart);
  165. #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
  166. }
  167. huart->gState = HAL_UART_STATE_BUSY;
  168. /* Disable the Peripheral */
  169. __HAL_UART_DISABLE(huart);
  170. /* Set the UART Communication parameters */
  171. if (UART_SetConfig(huart) == HAL_ERROR)
  172. {
  173. return HAL_ERROR;
  174. }
  175. if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
  176. {
  177. UART_AdvFeatureConfig(huart);
  178. }
  179. /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
  180. SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
  181. /* Set the Driver Enable polarity */
  182. MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
  183. /* Set the Driver Enable assertion and deassertion times */
  184. temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
  185. temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
  186. MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
  187. /* Enable the Peripheral */
  188. __HAL_UART_ENABLE(huart);
  189. /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
  190. return (UART_CheckIdleState(huart));
  191. }
  192. /**
  193. * @}
  194. */
  195. /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions
  196. * @brief Extended functions
  197. *
  198. @verbatim
  199. ===============================================================================
  200. ##### IO operation functions #####
  201. ===============================================================================
  202. This subsection provides a set of Wakeup and FIFO mode related callback functions.
  203. (#) Wakeup from Stop mode Callback:
  204. (+) HAL_UARTEx_WakeupCallback()
  205. @endverbatim
  206. * @{
  207. */
  208. /**
  209. * @brief UART wakeup from Stop mode callback.
  210. * @param huart UART handle.
  211. * @retval None
  212. */
  213. __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
  214. {
  215. /* Prevent unused argument(s) compilation warning */
  216. UNUSED(huart);
  217. /* NOTE : This function should not be modified, when the callback is needed,
  218. the HAL_UARTEx_WakeupCallback can be implemented in the user file.
  219. */
  220. }
  221. /**
  222. * @}
  223. */
  224. /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
  225. * @brief Extended Peripheral Control functions
  226. *
  227. @verbatim
  228. ===============================================================================
  229. ##### Peripheral Control functions #####
  230. ===============================================================================
  231. [..] This section provides the following functions:
  232. (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode
  233. (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality
  234. (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
  235. detection length to more than 4 bits for multiprocessor address mark wake up.
  236. (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
  237. trigger: address match, Start Bit detection or RXNE bit status.
  238. (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
  239. (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
  240. @endverbatim
  241. * @{
  242. */
  243. /**
  244. * @brief Keep UART Clock enabled when in Stop Mode.
  245. * @note When the USART clock source is configured to be LSE or HSI, it is possible to keep enabled
  246. * this clock during STOP mode by setting the UCESM bit in USART_CR3 control register.
  247. * @note When LPUART is used to wakeup from stop with LSE is selected as LPUART clock source,
  248. * and desired baud rate is 9600 baud, the bit UCESM bit in LPUART_CR3 control register must be set.
  249. * @param huart UART handle.
  250. * @retval HAL status
  251. */
  252. HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart)
  253. {
  254. /* Process Locked */
  255. __HAL_LOCK(huart);
  256. /* Set UCESM bit */
  257. SET_BIT(huart->Instance->CR3, USART_CR3_UCESM);
  258. /* Process Unlocked */
  259. __HAL_UNLOCK(huart);
  260. return HAL_OK;
  261. }
  262. /**
  263. * @brief Disable UART Clock when in Stop Mode.
  264. * @param huart UART handle.
  265. * @retval HAL status
  266. */
  267. HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart)
  268. {
  269. /* Process Locked */
  270. __HAL_LOCK(huart);
  271. /* Clear UCESM bit */
  272. CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM);
  273. /* Process Unlocked */
  274. __HAL_UNLOCK(huart);
  275. return HAL_OK;
  276. }
  277. /**
  278. * @brief By default in multiprocessor mode, when the wake up method is set
  279. * to address mark, the UART handles only 4-bit long addresses detection;
  280. * this API allows to enable longer addresses detection (6-, 7- or 8-bit
  281. * long).
  282. * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
  283. * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
  284. * @param huart UART handle.
  285. * @param AddressLength This parameter can be one of the following values:
  286. * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
  287. * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
  288. * @retval HAL status
  289. */
  290. HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
  291. {
  292. /* Check the UART handle allocation */
  293. if (huart == NULL)
  294. {
  295. return HAL_ERROR;
  296. }
  297. /* Check the address length parameter */
  298. assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
  299. huart->gState = HAL_UART_STATE_BUSY;
  300. /* Disable the Peripheral */
  301. __HAL_UART_DISABLE(huart);
  302. /* Set the address length */
  303. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
  304. /* Enable the Peripheral */
  305. __HAL_UART_ENABLE(huart);
  306. /* TEACK and/or REACK to check before moving huart->gState to Ready */
  307. return (UART_CheckIdleState(huart));
  308. }
  309. /**
  310. * @brief Set Wakeup from Stop mode interrupt flag selection.
  311. * @note It is the application responsibility to enable the interrupt used as
  312. * usart_wkup interrupt source before entering low-power mode.
  313. * @param huart UART handle.
  314. * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
  315. * This parameter can be one of the following values:
  316. * @arg @ref UART_WAKEUP_ON_ADDRESS
  317. * @arg @ref UART_WAKEUP_ON_STARTBIT
  318. * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
  319. * @retval HAL status
  320. */
  321. HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  322. {
  323. HAL_StatusTypeDef status = HAL_OK;
  324. uint32_t tickstart;
  325. /* check the wake-up from stop mode UART instance */
  326. assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
  327. /* check the wake-up selection parameter */
  328. assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
  329. /* Process Locked */
  330. __HAL_LOCK(huart);
  331. huart->gState = HAL_UART_STATE_BUSY;
  332. /* Disable the Peripheral */
  333. __HAL_UART_DISABLE(huart);
  334. /* Set the wake-up selection scheme */
  335. MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
  336. if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
  337. {
  338. UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
  339. }
  340. /* Enable the Peripheral */
  341. __HAL_UART_ENABLE(huart);
  342. /* Init tickstart for timeout managment*/
  343. tickstart = HAL_GetTick();
  344. /* Wait until REACK flag is set */
  345. if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
  346. {
  347. status = HAL_TIMEOUT;
  348. }
  349. else
  350. {
  351. /* Initialize the UART State */
  352. huart->gState = HAL_UART_STATE_READY;
  353. }
  354. /* Process Unlocked */
  355. __HAL_UNLOCK(huart);
  356. return status;
  357. }
  358. /**
  359. * @brief Enable UART Stop Mode.
  360. * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
  361. * @param huart UART handle.
  362. * @retval HAL status
  363. */
  364. HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
  365. {
  366. /* Process Locked */
  367. __HAL_LOCK(huart);
  368. /* Set UESM bit */
  369. SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
  370. /* Process Unlocked */
  371. __HAL_UNLOCK(huart);
  372. return HAL_OK;
  373. }
  374. /**
  375. * @brief Disable UART Stop Mode.
  376. * @param huart UART handle.
  377. * @retval HAL status
  378. */
  379. HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
  380. {
  381. /* Process Locked */
  382. __HAL_LOCK(huart);
  383. /* Clear UESM bit */
  384. CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
  385. /* Process Unlocked */
  386. __HAL_UNLOCK(huart);
  387. return HAL_OK;
  388. }
  389. /**
  390. * @}
  391. */
  392. /**
  393. * @}
  394. */
  395. /** @addtogroup UARTEx_Private_Functions
  396. * @{
  397. */
  398. /**
  399. * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
  400. * @param huart UART handle.
  401. * @param WakeUpSelection UART wake up from stop mode parameters.
  402. * @retval None
  403. */
  404. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  405. {
  406. assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
  407. /* Set the USART address length */
  408. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
  409. /* Set the USART address node */
  410. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
  411. }
  412. /**
  413. * @}
  414. */
  415. #endif /* HAL_UART_MODULE_ENABLED */
  416. /**
  417. * @}
  418. */
  419. /**
  420. * @}
  421. */
  422. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/