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.
 
 
 

463 lines
16 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_hal_uart_ex.c
  4. * @author MCD Application Team
  5. * @version V1.3.0
  6. * @date 29-January-2016
  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) 2016 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->State == 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->State = 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->State 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->State = 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->State 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. /* check the wake-up from stop mode UART instance */
  266. assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
  267. /* check the wake-up selection parameter */
  268. assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
  269. /* Process Locked */
  270. __HAL_LOCK(huart);
  271. huart->State = HAL_UART_STATE_BUSY;
  272. /* Disable the Peripheral */
  273. __HAL_UART_DISABLE(huart);
  274. /* Set the wake-up selection scheme */
  275. MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
  276. if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
  277. {
  278. UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
  279. }
  280. /* Enable the Peripheral */
  281. __HAL_UART_ENABLE(huart);
  282. /* Wait until REACK flag is set */
  283. if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
  284. {
  285. status = HAL_TIMEOUT;
  286. }
  287. else
  288. {
  289. /* Initialize the UART State */
  290. huart->State = HAL_UART_STATE_READY;
  291. }
  292. /* Process Unlocked */
  293. __HAL_UNLOCK(huart);
  294. return status;
  295. }
  296. /**
  297. * @brief Enable UART Stop Mode.
  298. * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
  299. * @param huart: UART handle.
  300. * @retval HAL status
  301. */
  302. HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
  303. {
  304. /* Process Locked */
  305. __HAL_LOCK(huart);
  306. huart->State = HAL_UART_STATE_BUSY;
  307. /* Set UESM bit */
  308. SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
  309. huart->State = HAL_UART_STATE_READY;
  310. /* Process Unlocked */
  311. __HAL_UNLOCK(huart);
  312. return HAL_OK;
  313. }
  314. /**
  315. * @brief Disable UART Stop Mode.
  316. * @param huart: UART handle.
  317. * @retval HAL status
  318. */
  319. HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
  320. {
  321. /* Process Locked */
  322. __HAL_LOCK(huart);
  323. huart->State = HAL_UART_STATE_BUSY;
  324. /* Clear UESM bit */
  325. CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
  326. huart->State = HAL_UART_STATE_READY;
  327. /* Process Unlocked */
  328. __HAL_UNLOCK(huart);
  329. return HAL_OK;
  330. }
  331. /**
  332. * @brief UART wakeup from Stop mode callback.
  333. * @param huart: UART handle.
  334. * @retval None
  335. */
  336. __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
  337. {
  338. /* Prevent unused argument(s) compilation warning */
  339. UNUSED(huart);
  340. /* NOTE : This function should not be modified, when the callback is needed,
  341. the HAL_UARTEx_WakeupCallback can be implemented in the user file.
  342. */
  343. }
  344. /**
  345. * @}
  346. */
  347. /**
  348. * @}
  349. */
  350. /** @addtogroup UARTEx_Private_Functions
  351. * @{
  352. */
  353. /**
  354. * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
  355. * @param huart: UART handle.
  356. * @param WakeUpSelection: UART wake up from stop mode parameters.
  357. * @retval None
  358. */
  359. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  360. {
  361. assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
  362. /* Set the USART address length */
  363. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
  364. /* Set the USART address node */
  365. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
  366. }
  367. /**
  368. * @}
  369. */
  370. #endif /* HAL_UART_MODULE_ENABLED */
  371. /**
  372. * @}
  373. */
  374. /**
  375. * @}
  376. */
  377. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/