drv_usart.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-08-25 LongfeiMa the first version for stm32h7xx
  9. */
  10. #include "stm32h7xx.h"
  11. #include "drv_usart.h"
  12. #include "board.h"
  13. #include <rtdevice.h>
  14. /* Definition for USART1 clock resources */
  15. #define USART1_CLK_ENABLE() __USART1_CLK_ENABLE()
  16. #define USART1_RX_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE()
  17. #define USART1_TX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
  18. #define USART1_FORCE_RESET() __USART1_FORCE_RESET()
  19. #define USART1_RELEASE_RESET() __USART1_RELEASE_RESET()
  20. /* Definition for USARTx Pins */
  21. #define USART1_TX_PIN GPIO_PIN_9
  22. #define USART1_TX_GPIO_PORT GPIOA
  23. #define USART1_TX_AF GPIO_AF7_USART1
  24. #define USART1_RX_PIN GPIO_PIN_7
  25. #define USART1_RX_GPIO_PORT GPIOB
  26. #define USART1_RX_AF GPIO_AF7_USART1
  27. /* STM32 uart driver */
  28. struct stm32_uart
  29. {
  30. UART_HandleTypeDef UartHandle;
  31. IRQn_Type irq;
  32. };
  33. static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  34. {
  35. struct stm32_uart *uart;
  36. RT_ASSERT(serial != RT_NULL);
  37. RT_ASSERT(cfg != RT_NULL);
  38. uart = (struct stm32_uart *)serial->parent.user_data;
  39. uart->UartHandle.Init.BaudRate = cfg->baud_rate;
  40. uart->UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  41. uart->UartHandle.Init.Mode = UART_MODE_TX_RX;
  42. uart->UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  43. switch (cfg->data_bits)
  44. {
  45. case DATA_BITS_7:
  46. uart->UartHandle.Init.WordLength = UART_WORDLENGTH_7B;
  47. break;
  48. case DATA_BITS_8:
  49. uart->UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  50. break;
  51. case DATA_BITS_9:
  52. uart->UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
  53. break;
  54. default:
  55. uart->UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  56. break;
  57. }
  58. switch (cfg->stop_bits)
  59. {
  60. case STOP_BITS_1:
  61. uart->UartHandle.Init.StopBits = UART_STOPBITS_1;
  62. break;
  63. case STOP_BITS_2:
  64. uart->UartHandle.Init.StopBits = UART_STOPBITS_2;
  65. break;
  66. default:
  67. uart->UartHandle.Init.StopBits = UART_STOPBITS_1;
  68. break;
  69. }
  70. switch (cfg->parity)
  71. {
  72. case PARITY_NONE:
  73. uart->UartHandle.Init.Parity = UART_PARITY_NONE;
  74. break;
  75. case PARITY_ODD:
  76. uart->UartHandle.Init.Parity = UART_PARITY_ODD;
  77. break;
  78. case PARITY_EVEN:
  79. uart->UartHandle.Init.Parity = UART_PARITY_EVEN;
  80. break;
  81. default:
  82. uart->UartHandle.Init.Parity = UART_PARITY_NONE;
  83. break;
  84. }
  85. if (HAL_UART_DeInit(&uart->UartHandle) != HAL_OK)
  86. {
  87. return RT_ERROR;
  88. }
  89. if (HAL_UART_Init(&uart->UartHandle) != HAL_OK)
  90. {
  91. return RT_ERROR;
  92. }
  93. return RT_EOK;
  94. }
  95. static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *arg)
  96. {
  97. struct stm32_uart *uart;
  98. RT_ASSERT(serial != RT_NULL);
  99. uart = (struct stm32_uart *)serial->parent.user_data;
  100. switch (cmd)
  101. {
  102. case RT_DEVICE_CTRL_CLR_INT:
  103. /* disable rx irq */
  104. UART_DISABLE_IRQ(uart->irq);
  105. /* disable interrupt */
  106. __HAL_UART_DISABLE_IT(&uart->UartHandle, UART_IT_RXNE);
  107. break;
  108. case RT_DEVICE_CTRL_SET_INT:
  109. /* enable rx irq */
  110. UART_ENABLE_IRQ(uart->irq);
  111. /* enable interrupt */
  112. __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_RXNE);
  113. break;
  114. }
  115. return RT_EOK;
  116. }
  117. static int stm32_putc(struct rt_serial_device *serial, char c)
  118. {
  119. struct stm32_uart *uart;
  120. RT_ASSERT(serial != RT_NULL);
  121. uart = (struct stm32_uart *)serial->parent.user_data;
  122. __HAL_UART_CLEAR_FLAG(&(uart->UartHandle), UART_FLAG_TC);
  123. uart->UartHandle.Instance->TDR = c;
  124. while (__HAL_UART_GET_FLAG(&(uart->UartHandle), UART_FLAG_TC) == RESET);
  125. return 1;
  126. }
  127. static int stm32_getc(struct rt_serial_device *serial)
  128. {
  129. int ch;
  130. struct stm32_uart *uart;
  131. RT_ASSERT(serial != RT_NULL);
  132. uart = (struct stm32_uart *)serial->parent.user_data;
  133. ch = -1;
  134. if (uart->UartHandle.Instance->ISR & UART_FLAG_RXNE)
  135. {
  136. ch = uart->UartHandle.Instance->RDR & 0xff;
  137. }
  138. return ch;
  139. }
  140. static const struct rt_uart_ops stm32_uart_ops =
  141. {
  142. stm32_configure,
  143. stm32_control,
  144. stm32_putc,
  145. stm32_getc,
  146. };
  147. #if defined(RT_USING_UART1)
  148. /* UART1 device driver structure */
  149. static struct stm32_uart uart1;
  150. struct rt_serial_device serial1;
  151. void USART1_IRQHandler(void)
  152. {
  153. struct stm32_uart *uart;
  154. uart = &uart1;
  155. /* enter interrupt */
  156. rt_interrupt_enter();
  157. /* UART in mode Receiver ---------------------------------------------------*/
  158. if ((__HAL_UART_GET_IT(&uart->UartHandle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  159. {
  160. rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
  161. /* Clear RXNE interrupt flag */
  162. __HAL_UART_SEND_REQ(&uart->UartHandle, UART_RXDATA_FLUSH_REQUEST);
  163. }
  164. /* leave interrupt */
  165. rt_interrupt_leave();
  166. }
  167. #endif /* RT_USING_UART1 */
  168. /**
  169. * @brief UART MSP Initialization
  170. * This function configures the hardware resources used in this example:
  171. * - Peripheral's clock enable
  172. * - Peripheral's GPIO Configuration
  173. * - NVIC configuration for UART interrupt request enable
  174. * @param huart: UART handle pointer
  175. * @retval None
  176. */
  177. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  178. {
  179. GPIO_InitTypeDef GPIO_InitStruct;
  180. if (huart->Instance == USART1)
  181. {
  182. /* Enable GPIO TX/RX clock */
  183. USART1_TX_GPIO_CLK_ENABLE();
  184. USART1_RX_GPIO_CLK_ENABLE();
  185. /* Enable USARTx clock */
  186. USART1_CLK_ENABLE();
  187. /* UART TX GPIO pin configuration */
  188. GPIO_InitStruct.Pin = USART1_TX_PIN;
  189. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  190. GPIO_InitStruct.Pull = GPIO_PULLUP;
  191. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  192. GPIO_InitStruct.Alternate = USART1_TX_AF;
  193. HAL_GPIO_Init(USART1_TX_GPIO_PORT, &GPIO_InitStruct);
  194. /* UART RX GPIO pin configuration */
  195. GPIO_InitStruct.Pin = USART1_RX_PIN;
  196. GPIO_InitStruct.Alternate = USART1_RX_AF;
  197. HAL_GPIO_Init(USART1_RX_GPIO_PORT, &GPIO_InitStruct);
  198. /* NVIC for USART */
  199. HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
  200. HAL_NVIC_EnableIRQ(USART1_IRQn);
  201. }
  202. }
  203. /**
  204. * @brief UART MSP De-Initialization
  205. * This function frees the hardware resources used in this example:
  206. * - Disable the Peripheral's clock
  207. * - Revert GPIO and NVIC configuration to their default state
  208. * @param huart: UART handle pointer
  209. * @retval None
  210. */
  211. void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
  212. {
  213. if (huart->Instance == USART1)
  214. {
  215. /* Reset peripherals */
  216. USART1_FORCE_RESET();
  217. USART1_RELEASE_RESET();
  218. /* Disable peripherals and GPIO Clocks */
  219. /* Configure UART Tx as alternate function */
  220. HAL_GPIO_DeInit(USART1_TX_GPIO_PORT, USART1_TX_PIN);
  221. /* Configure UART Rx as alternate function */
  222. HAL_GPIO_DeInit(USART1_RX_GPIO_PORT, USART1_RX_PIN);
  223. /* Disable the NVIC for UART */
  224. HAL_NVIC_DisableIRQ(USART1_IRQn);
  225. }
  226. }
  227. int stm32_hw_usart_init(void)
  228. {
  229. struct stm32_uart *uart;
  230. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  231. #ifdef RT_USING_UART1
  232. uart = &uart1;
  233. uart->UartHandle.Instance = USART1;
  234. serial1.ops = &stm32_uart_ops;
  235. serial1.config = config;
  236. /* register UART1 device */
  237. rt_hw_serial_register(&serial1, "uart1",
  238. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  239. uart);
  240. #endif /* RT_USING_UART1 */
  241. return 0;
  242. }
  243. INIT_BOARD_EXPORT(stm32_hw_usart_init);