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.
 
 
 

467 lines
16 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_hal_uart_ex.c
  4. * @author MCD Application Team
  5. * @version V1.7.2
  6. * @date 16-June-2017
  7. * @brief Extended UART HAL module driver.
  8. * This file provides firmware functions to manage the following extended
  9. * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
  10. * + Initialization and de-initialization functions
  11. * + Peripheral Control functions
  12. *
  13. *
  14. @verbatim
  15. ==============================================================================
  16. ##### UART peripheral extended features #####
  17. ==============================================================================
  18. (#) Declare a UART_HandleTypeDef handle structure.
  19. (#) For the UART RS485 Driver Enable mode, initialize the UART registers
  20. by calling the HAL_RS485Ex_Init() API.
  21. @endverbatim
  22. ******************************************************************************
  23. * @attention
  24. *
  25. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  26. *
  27. * Redistribution and use in source and binary forms, with or without modification,
  28. * are permitted provided that the following conditions are met:
  29. * 1. Redistributions of source code must retain the above copyright notice,
  30. * this list of conditions and the following disclaimer.
  31. * 2. Redistributions in binary form must reproduce the above copyright notice,
  32. * this list of conditions and the following disclaimer in the documentation
  33. * and/or other materials provided with the distribution.
  34. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  35. * may be used to endorse or promote products derived from this software
  36. * without specific prior written permission.
  37. *
  38. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  39. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  40. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  42. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  43. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  44. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  45. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  46. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  47. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48. *
  49. ******************************************************************************
  50. */
  51. /* Includes ------------------------------------------------------------------*/
  52. #include "stm32l4xx_hal.h"
  53. /** @addtogroup STM32L4xx_HAL_Driver
  54. * @{
  55. */
  56. /** @defgroup UARTEx UARTEx
  57. * @brief UART Extended HAL module driver
  58. * @{
  59. */
  60. #ifdef HAL_UART_MODULE_ENABLED
  61. /* Private typedef -----------------------------------------------------------*/
  62. /* Private define ------------------------------------------------------------*/
  63. /* Private macros ------------------------------------------------------------*/
  64. /* Private variables ---------------------------------------------------------*/
  65. /* Private function prototypes -----------------------------------------------*/
  66. /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
  67. * @{
  68. */
  69. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
  70. /**
  71. * @}
  72. */
  73. /* Exported functions --------------------------------------------------------*/
  74. /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions
  75. * @{
  76. */
  77. /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
  78. * @brief Extended Initialization and Configuration Functions
  79. *
  80. @verbatim
  81. ===============================================================================
  82. ##### Initialization and Configuration functions #####
  83. ===============================================================================
  84. [..]
  85. This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
  86. in asynchronous mode.
  87. (+) For the asynchronous mode the parameters below can be configured:
  88. (++) Baud Rate
  89. (++) Word Length
  90. (++) Stop Bit
  91. (++) Parity: If the parity is enabled, then the MSB bit of the data written
  92. in the data register is transmitted but is changed by the parity bit.
  93. (++) Hardware flow control
  94. (++) Receiver/transmitter modes
  95. (++) Over Sampling Method
  96. (++) One-Bit Sampling Method
  97. (+) For the asynchronous mode, the following advanced features can be configured as well:
  98. (++) TX and/or RX pin level inversion
  99. (++) data logical level inversion
  100. (++) RX and TX pins swap
  101. (++) RX overrun detection disabling
  102. (++) DMA disabling on RX error
  103. (++) MSB first on communication line
  104. (++) auto Baud rate detection
  105. [..]
  106. The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
  107. procedures (details for the procedures are available in reference manual).
  108. @endverbatim
  109. Depending on the frame length defined by the M1 and M0 bits (7-bit,
  110. 8-bit or 9-bit), the possible UART formats are listed in the
  111. following table.
  112. Table 1. UART frame format.
  113. +-----------------------------------------------------------------------+
  114. | M1 bit | M0 bit | PCE bit | UART frame |
  115. |---------|---------|-----------|---------------------------------------|
  116. | 0 | 0 | 0 | | SB | 8 bit data | STB | |
  117. |---------|---------|-----------|---------------------------------------|
  118. | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
  119. |---------|---------|-----------|---------------------------------------|
  120. | 0 | 1 | 0 | | SB | 9 bit data | STB | |
  121. |---------|---------|-----------|---------------------------------------|
  122. | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
  123. |---------|---------|-----------|---------------------------------------|
  124. | 1 | 0 | 0 | | SB | 7 bit data | STB | |
  125. |---------|---------|-----------|---------------------------------------|
  126. | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
  127. +-----------------------------------------------------------------------+
  128. * @{
  129. */
  130. /**
  131. * @brief Initialize the RS485 Driver enable feature according to the specified
  132. * parameters in the UART_InitTypeDef and creates the associated handle.
  133. * @param huart: UART handle.
  134. * @param Polarity: select the driver enable polarity.
  135. * This parameter can be one of the following values:
  136. * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
  137. * @arg @ref UART_DE_POLARITY_LOW DE signal is active low
  138. * @param AssertionTime: Driver Enable assertion time:
  139. * 5-bit value defining the time between the activation of the DE (Driver Enable)
  140. * signal and the beginning of the start bit. It is expressed in sample time
  141. * units (1/8 or 1/16 bit time, depending on the oversampling rate)
  142. * @param DeassertionTime: Driver Enable deassertion time:
  143. * 5-bit value defining the time between the end of the last stop bit, in a
  144. * transmitted message, and the de-activation of the DE (Driver Enable) signal.
  145. * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
  146. * oversampling rate).
  147. * @retval HAL status
  148. */
  149. HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime)
  150. {
  151. uint32_t temp = 0x0;
  152. /* Check the UART handle allocation */
  153. if(huart == NULL)
  154. {
  155. return HAL_ERROR;
  156. }
  157. /* Check the Driver Enable UART instance */
  158. assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
  159. /* Check the Driver Enable polarity */
  160. assert_param(IS_UART_DE_POLARITY(Polarity));
  161. /* Check the Driver Enable assertion time */
  162. assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
  163. /* Check the Driver Enable deassertion time */
  164. assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
  165. if(huart->gState == HAL_UART_STATE_RESET)
  166. {
  167. /* Allocate lock resource and initialize it */
  168. huart->Lock = HAL_UNLOCKED;
  169. /* Init the low level hardware : GPIO, CLOCK, CORTEX */
  170. HAL_UART_MspInit(huart);
  171. }
  172. huart->gState = HAL_UART_STATE_BUSY;
  173. /* Disable the Peripheral */
  174. __HAL_UART_DISABLE(huart);
  175. /* Set the UART Communication parameters */
  176. if (UART_SetConfig(huart) == HAL_ERROR)
  177. {
  178. return HAL_ERROR;
  179. }
  180. if(huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
  181. {
  182. UART_AdvFeatureConfig(huart);
  183. }
  184. /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
  185. SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
  186. /* Set the Driver Enable polarity */
  187. MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
  188. /* Set the Driver Enable assertion and deassertion times */
  189. temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
  190. temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
  191. MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT|USART_CR1_DEAT), temp);
  192. /* Enable the Peripheral */
  193. __HAL_UART_ENABLE(huart);
  194. /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
  195. return (UART_CheckIdleState(huart));
  196. }
  197. /**
  198. * @}
  199. */
  200. /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
  201. * @brief Extended Peripheral Control functions
  202. *
  203. @verbatim
  204. ===============================================================================
  205. ##### Peripheral Control functions #####
  206. ===============================================================================
  207. [..] This section provides the following functions:
  208. (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode
  209. (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality
  210. (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
  211. detection length to more than 4 bits for multiprocessor address mark wake up.
  212. (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
  213. trigger: address match, Start Bit detection or RXNE bit status.
  214. (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
  215. (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
  216. (+) HAL_UARTEx_WakeupCallback() called upon UART wakeup interrupt
  217. @endverbatim
  218. * @{
  219. */
  220. /**
  221. * @brief By default in multiprocessor mode, when the wake up method is set
  222. * to address mark, the UART handles only 4-bit long addresses detection;
  223. * this API allows to enable longer addresses detection (6-, 7- or 8-bit
  224. * long).
  225. * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
  226. * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
  227. * @param huart: UART handle.
  228. * @param AddressLength: this parameter can be one of the following values:
  229. * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
  230. * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
  231. * @retval HAL status
  232. */
  233. HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
  234. {
  235. /* Check the UART handle allocation */
  236. if(huart == NULL)
  237. {
  238. return HAL_ERROR;
  239. }
  240. /* Check the address length parameter */
  241. assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
  242. huart->gState = HAL_UART_STATE_BUSY;
  243. /* Disable the Peripheral */
  244. __HAL_UART_DISABLE(huart);
  245. /* Set the address length */
  246. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
  247. /* Enable the Peripheral */
  248. __HAL_UART_ENABLE(huart);
  249. /* TEACK and/or REACK to check before moving huart->gState to Ready */
  250. return (UART_CheckIdleState(huart));
  251. }
  252. /**
  253. * @brief Set Wakeup from Stop mode interrupt flag selection.
  254. * @param huart: UART handle.
  255. * @param WakeUpSelection: address match, Start Bit detection or RXNE bit status.
  256. * This parameter can be one of the following values:
  257. * @arg @ref UART_WAKEUP_ON_ADDRESS
  258. * @arg @ref UART_WAKEUP_ON_STARTBIT
  259. * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
  260. * @retval HAL status
  261. */
  262. HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  263. {
  264. HAL_StatusTypeDef status = HAL_OK;
  265. uint32_t tickstart = 0;
  266. /* check the wake-up from stop mode UART instance */
  267. assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
  268. /* check the wake-up selection parameter */
  269. assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
  270. /* Process Locked */
  271. __HAL_LOCK(huart);
  272. huart->gState = HAL_UART_STATE_BUSY;
  273. /* Disable the Peripheral */
  274. __HAL_UART_DISABLE(huart);
  275. /* Set the wake-up selection scheme */
  276. MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
  277. if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
  278. {
  279. UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
  280. }
  281. /* Enable the Peripheral */
  282. __HAL_UART_ENABLE(huart);
  283. /* Init tickstart for timeout managment*/
  284. tickstart = HAL_GetTick();
  285. /* Wait until REACK flag is set */
  286. if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
  287. {
  288. status = HAL_TIMEOUT;
  289. }
  290. else
  291. {
  292. /* Initialize the UART State */
  293. huart->gState = HAL_UART_STATE_READY;
  294. }
  295. /* Process Unlocked */
  296. __HAL_UNLOCK(huart);
  297. return status;
  298. }
  299. /**
  300. * @brief Enable UART Stop Mode.
  301. * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
  302. * @param huart: UART handle.
  303. * @retval HAL status
  304. */
  305. HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
  306. {
  307. /* Process Locked */
  308. __HAL_LOCK(huart);
  309. huart->gState = HAL_UART_STATE_BUSY;
  310. /* Set UESM bit */
  311. SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
  312. huart->gState = HAL_UART_STATE_READY;
  313. /* Process Unlocked */
  314. __HAL_UNLOCK(huart);
  315. return HAL_OK;
  316. }
  317. /**
  318. * @brief Disable UART Stop Mode.
  319. * @param huart: UART handle.
  320. * @retval HAL status
  321. */
  322. HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
  323. {
  324. /* Process Locked */
  325. __HAL_LOCK(huart);
  326. huart->gState = HAL_UART_STATE_BUSY;
  327. /* Clear UESM bit */
  328. CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
  329. huart->gState = HAL_UART_STATE_READY;
  330. /* Process Unlocked */
  331. __HAL_UNLOCK(huart);
  332. return HAL_OK;
  333. }
  334. /**
  335. * @brief UART wakeup from Stop mode callback.
  336. * @param huart: UART handle.
  337. * @retval None
  338. */
  339. __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
  340. {
  341. /* Prevent unused argument(s) compilation warning */
  342. UNUSED(huart);
  343. /* NOTE : This function should not be modified, when the callback is needed,
  344. the HAL_UARTEx_WakeupCallback can be implemented in the user file.
  345. */
  346. }
  347. /**
  348. * @}
  349. */
  350. /**
  351. * @}
  352. */
  353. /** @addtogroup UARTEx_Private_Functions
  354. * @{
  355. */
  356. /**
  357. * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
  358. * @param huart: UART handle.
  359. * @param WakeUpSelection: UART wake up from stop mode parameters.
  360. * @retval None
  361. */
  362. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  363. {
  364. assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
  365. /* Set the USART address length */
  366. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
  367. /* Set the USART address node */
  368. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
  369. }
  370. /**
  371. * @}
  372. */
  373. #endif /* HAL_UART_MODULE_ENABLED */
  374. /**
  375. * @}
  376. */
  377. /**
  378. * @}
  379. */
  380. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/