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.
 
 
 

507 lines
17 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_uart_ex.c
  4. * @author MCD Application Team
  5. * @version V1.2.0
  6. * @date 29-December-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 "stm32h7xx_hal.h"
  53. /** @addtogroup STM32H7xx_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 UART_DE_POLARITY_HIGH: DE signal is active high
  137. * @arg 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 = 0x0U;
  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 UART_ADDRESS_DETECT_4B: 4-bit long address
  230. * @arg 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, RXNE bit status
  256. * or RX/TX FIFO related event.
  257. * This parameter can be one of the following values:
  258. * @arg @ref UART_WAKEUP_ON_ADDRESS
  259. * @arg @ref UART_WAKEUP_ON_STARTBIT
  260. * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
  261. * @arg @ref UART_WAKEUP_ON_RXFIFO_THRESHOLD
  262. * @arg @ref UART_WAKEUP_ON_RXFIFO_FULL
  263. * @arg @ref UART_WAKEUP_ON_TXFIFO_THRESHOLD
  264. * @arg @ref UART_WAKEUP_ON_TXFIFO_EMPTY
  265. * @retval HAL status
  266. */
  267. HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  268. {
  269. HAL_StatusTypeDef status = HAL_OK;
  270. uint32_t tickstart = 0U;
  271. /* check the wake-up from stop mode UART instance */
  272. assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
  273. /* check the wake-up selection parameter */
  274. assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
  275. /* Process Locked */
  276. __HAL_LOCK(huart);
  277. huart->gState = HAL_UART_STATE_BUSY;
  278. switch (WakeUpSelection.WakeUpEvent)
  279. {
  280. case UART_WAKEUP_ON_ADDRESS:
  281. case UART_WAKEUP_ON_STARTBIT:
  282. case UART_WAKEUP_ON_READDATA_NONEMPTY:
  283. /* Disable the Peripheral */
  284. __HAL_UART_DISABLE(huart);
  285. /* Set the wake-up selection scheme */
  286. MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
  287. if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
  288. {
  289. UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
  290. }
  291. /* Enable the Peripheral */
  292. __HAL_UART_ENABLE(huart);
  293. /* Init tickstart for timeout managment*/
  294. tickstart = HAL_GetTick();
  295. /* Wait until REACK flag is set */
  296. if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
  297. {
  298. status = HAL_TIMEOUT;
  299. }
  300. else
  301. {
  302. /* Initialize the UART State */
  303. huart->gState = HAL_UART_STATE_READY;
  304. }
  305. break;
  306. case UART_WAKEUP_ON_RXFIFO_THRESHOLD:
  307. /* Enable RXFT interrupt */
  308. SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
  309. huart->gState = HAL_UART_STATE_READY;
  310. break;
  311. case UART_WAKEUP_ON_RXFIFO_FULL:
  312. /* Enable RXFF interrupt */
  313. SET_BIT(huart->Instance->CR1, USART_CR1_RXFFIE);
  314. huart->gState = HAL_UART_STATE_READY;
  315. break;
  316. case UART_WAKEUP_ON_TXFIFO_THRESHOLD:
  317. /* Enable TXFT interrupt */
  318. SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
  319. huart->gState = HAL_UART_STATE_READY;
  320. break;
  321. case UART_WAKEUP_ON_TXFIFO_EMPTY:
  322. /* Enable TXFE interrupt */
  323. SET_BIT(huart->Instance->CR1, USART_CR1_TXFEIE);
  324. huart->gState = HAL_UART_STATE_READY;
  325. break;
  326. default:
  327. break;
  328. }
  329. /* Process Unlocked */
  330. __HAL_UNLOCK(huart);
  331. return status;
  332. }
  333. /**
  334. * @brief Enable UART Stop Mode.
  335. * @note The UART is able to wake up the MCU from Stop mode as long as UART clock is HSI or LSE.
  336. * @param huart: UART handle.
  337. * @retval HAL status
  338. */
  339. HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
  340. {
  341. /* Process Locked */
  342. __HAL_LOCK(huart);
  343. huart->gState = HAL_UART_STATE_BUSY;
  344. /* Set UESM bit */
  345. SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
  346. huart->gState = HAL_UART_STATE_READY;
  347. /* Process Unlocked */
  348. __HAL_UNLOCK(huart);
  349. return HAL_OK;
  350. }
  351. /**
  352. * @brief Disable UART Stop Mode.
  353. * @param huart: UART handle.
  354. * @retval HAL status
  355. */
  356. HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
  357. {
  358. /* Process Locked */
  359. __HAL_LOCK(huart);
  360. huart->gState = HAL_UART_STATE_BUSY;
  361. /* Clear UESM bit */
  362. CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
  363. huart->gState = HAL_UART_STATE_READY;
  364. /* Process Unlocked */
  365. __HAL_UNLOCK(huart);
  366. return HAL_OK;
  367. }
  368. /**
  369. * @brief UART wakeup from Stop mode callback.
  370. * @param huart: UART handle.
  371. * @retval None
  372. */
  373. __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
  374. {
  375. /* Prevent unused argument(s) compilation warning */
  376. UNUSED(huart);
  377. /* NOTE : This function should not be modified, when the callback is needed,
  378. the HAL_UARTEx_WakeupCallback can be implemented in the user file.
  379. */
  380. }
  381. /**
  382. * @}
  383. */
  384. /**
  385. * @}
  386. */
  387. /** @addtogroup UARTEx_Private_Functions
  388. * @{
  389. */
  390. /**
  391. * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
  392. * @param huart: UART handle.
  393. * @param WakeUpSelection: UART wake up from stop mode parameters.
  394. * @retval None
  395. */
  396. static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
  397. {
  398. assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
  399. /* Set the USART address length */
  400. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
  401. /* Set the USART address node */
  402. MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
  403. }
  404. /**
  405. * @}
  406. */
  407. #endif /* HAL_UART_MODULE_ENABLED */
  408. /**
  409. * @}
  410. */
  411. /**
  412. * @}
  413. */
  414. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/