drv_usart.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. while (!(uart->UartHandle.Instance->ISR & UART_FLAG_TXE));
  123. uart->UartHandle.Instance->TDR = c;
  124. return 1;
  125. }
  126. static int stm32_getc(struct rt_serial_device *serial)
  127. {
  128. int ch;
  129. struct stm32_uart *uart;
  130. RT_ASSERT(serial != RT_NULL);
  131. uart = (struct stm32_uart *)serial->parent.user_data;
  132. ch = -1;
  133. if (uart->UartHandle.Instance->ISR & UART_FLAG_RXNE)
  134. {
  135. ch = uart->UartHandle.Instance->RDR & 0xff;
  136. }
  137. return ch;
  138. }
  139. static const struct rt_uart_ops stm32_uart_ops =
  140. {
  141. stm32_configure,
  142. stm32_control,
  143. stm32_putc,
  144. stm32_getc,
  145. };
  146. #if defined(RT_USING_UART1)
  147. /* UART1 device driver structure */
  148. static struct stm32_uart uart1;
  149. struct rt_serial_device serial1;
  150. void USART1_IRQHandler(void)
  151. {
  152. struct stm32_uart *uart;
  153. uart = &uart1;
  154. /* enter interrupt */
  155. rt_interrupt_enter();
  156. /* UART in mode Receiver ---------------------------------------------------*/
  157. if ((__HAL_UART_GET_IT(&uart->UartHandle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  158. {
  159. rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
  160. /* Clear RXNE interrupt flag */
  161. __HAL_UART_SEND_REQ(&uart->UartHandle, UART_RXDATA_FLUSH_REQUEST);
  162. }
  163. /* leave interrupt */
  164. rt_interrupt_leave();
  165. }
  166. #endif /* RT_USING_UART1 */
  167. /**
  168. * @brief UART MSP Initialization
  169. * This function configures the hardware resources used in this example:
  170. * - Peripheral's clock enable
  171. * - Peripheral's GPIO Configuration
  172. * - NVIC configuration for UART interrupt request enable
  173. * @param huart: UART handle pointer
  174. * @retval None
  175. */
  176. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  177. {
  178. GPIO_InitTypeDef GPIO_InitStruct;
  179. if (huart->Instance == USART1)
  180. {
  181. /* Enable GPIO TX/RX clock */
  182. USART1_TX_GPIO_CLK_ENABLE();
  183. USART1_RX_GPIO_CLK_ENABLE();
  184. /* Enable USARTx clock */
  185. USART1_CLK_ENABLE();
  186. /* UART TX GPIO pin configuration */
  187. GPIO_InitStruct.Pin = USART1_TX_PIN;
  188. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  189. GPIO_InitStruct.Pull = GPIO_PULLUP;
  190. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  191. GPIO_InitStruct.Alternate = USART1_TX_AF;
  192. HAL_GPIO_Init(USART1_TX_GPIO_PORT, &GPIO_InitStruct);
  193. /* UART RX GPIO pin configuration */
  194. GPIO_InitStruct.Pin = USART1_RX_PIN;
  195. GPIO_InitStruct.Alternate = USART1_RX_AF;
  196. HAL_GPIO_Init(USART1_RX_GPIO_PORT, &GPIO_InitStruct);
  197. /* NVIC for USART */
  198. HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
  199. HAL_NVIC_EnableIRQ(USART1_IRQn);
  200. }
  201. }
  202. /**
  203. * @brief UART MSP De-Initialization
  204. * This function frees the hardware resources used in this example:
  205. * - Disable the Peripheral's clock
  206. * - Revert GPIO and NVIC configuration to their default state
  207. * @param huart: UART handle pointer
  208. * @retval None
  209. */
  210. void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
  211. {
  212. if (huart->Instance == USART1)
  213. {
  214. /* Reset peripherals */
  215. USART1_FORCE_RESET();
  216. USART1_RELEASE_RESET();
  217. /* Disable peripherals and GPIO Clocks */
  218. /* Configure UART Tx as alternate function */
  219. HAL_GPIO_DeInit(USART1_TX_GPIO_PORT, USART1_TX_PIN);
  220. /* Configure UART Rx as alternate function */
  221. HAL_GPIO_DeInit(USART1_RX_GPIO_PORT, USART1_RX_PIN);
  222. /* Disable the NVIC for UART */
  223. HAL_NVIC_DisableIRQ(USART1_IRQn);
  224. }
  225. }
  226. int stm32_hw_usart_init(void)
  227. {
  228. struct stm32_uart *uart;
  229. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  230. #ifdef RT_USING_UART1
  231. uart = &uart1;
  232. uart->UartHandle.Instance = USART1;
  233. serial1.ops = &stm32_uart_ops;
  234. serial1.config = config;
  235. /* register UART1 device */
  236. rt_hw_serial_register(&serial1, "uart1",
  237. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  238. uart);
  239. #endif /* RT_USING_UART1 */
  240. return 0;
  241. }
  242. INIT_BOARD_EXPORT(stm32_hw_usart_init);