1
0

drv_usart.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * File : drv_usart.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2018-05-17 ZYH first implementation
  23. */
  24. #include "drv_usart.h"
  25. #include "board.h"
  26. #include <rtdevice.h>
  27. #include <rthw.h>
  28. #include <rtthread.h>
  29. /* STM32 uart driver */
  30. struct drv_uart
  31. {
  32. UART_HandleTypeDef UartHandle;
  33. IRQn_Type irq;
  34. };
  35. static rt_err_t drv_configure(struct rt_serial_device *serial,
  36. struct serial_configure *cfg)
  37. {
  38. struct drv_uart *uart;
  39. RT_ASSERT(serial != RT_NULL);
  40. RT_ASSERT(cfg != RT_NULL);
  41. uart = (struct drv_uart *)serial->parent.user_data;
  42. uart->UartHandle.Init.BaudRate = cfg->baud_rate;
  43. uart->UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  44. uart->UartHandle.Init.Mode = UART_MODE_TX_RX;
  45. uart->UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
  46. switch (cfg->data_bits)
  47. {
  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_Init(&uart->UartHandle) != HAL_OK)
  86. {
  87. return RT_ERROR;
  88. }
  89. return RT_EOK;
  90. }
  91. static rt_err_t drv_control(struct rt_serial_device *serial,
  92. int cmd, void *arg)
  93. {
  94. struct drv_uart *uart;
  95. RT_ASSERT(serial != RT_NULL);
  96. uart = (struct drv_uart *)serial->parent.user_data;
  97. switch (cmd)
  98. {
  99. case RT_DEVICE_CTRL_CLR_INT:
  100. /* disable rx irq */
  101. HAL_NVIC_DisableIRQ(uart->irq);
  102. /* disable interrupt */
  103. __HAL_UART_DISABLE_IT(&uart->UartHandle, UART_IT_RXNE);
  104. break;
  105. case RT_DEVICE_CTRL_SET_INT:
  106. /* enable rx irq */
  107. HAL_NVIC_EnableIRQ(uart->irq);
  108. HAL_NVIC_SetPriority(uart->irq, 5, 0);
  109. /* enable interrupt */
  110. __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_RXNE);
  111. break;
  112. }
  113. return RT_EOK;
  114. }
  115. static int drv_putc(struct rt_serial_device *serial, char c)
  116. {
  117. struct drv_uart *uart;
  118. RT_ASSERT(serial != RT_NULL);
  119. uart = (struct drv_uart *)serial->parent.user_data;
  120. while ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_TXE) == RESET));
  121. uart->UartHandle.Instance->TDR = c;
  122. return 1;
  123. }
  124. static int drv_getc(struct rt_serial_device *serial)
  125. {
  126. int ch;
  127. struct drv_uart *uart;
  128. RT_ASSERT(serial != RT_NULL);
  129. uart = (struct drv_uart *)serial->parent.user_data;
  130. ch = -1;
  131. if (__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET)
  132. ch = uart->UartHandle.Instance->RDR & 0xff;
  133. return ch;
  134. }
  135. static const struct rt_uart_ops drv_uart_ops =
  136. {
  137. drv_configure,
  138. drv_control,
  139. drv_putc,
  140. drv_getc,
  141. };
  142. #if defined(BSP_USING_UART1)
  143. /* UART1 device driver structure */
  144. static struct drv_uart uart1;
  145. struct rt_serial_device serial1;
  146. void USART1_IRQHandler(void)
  147. {
  148. struct drv_uart *uart;
  149. uart = &uart1;
  150. /* enter interrupt */
  151. rt_interrupt_enter();
  152. /* UART in mode Receiver -------------------------------------------------*/
  153. if ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET) &&
  154. (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  155. {
  156. rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
  157. /* Clear RXNE interrupt flag */
  158. __HAL_UART_CLEAR_IT(&uart->UartHandle, UART_FLAG_RXNE);
  159. }
  160. /* leave interrupt */
  161. rt_interrupt_leave();
  162. }
  163. #endif /* BSP_USING_UART1 */
  164. #if defined(BSP_USING_UART4)
  165. /* UART4 device driver structure */
  166. static struct drv_uart uart4;
  167. struct rt_serial_device serial4;
  168. void UART4_IRQHandler(void)
  169. {
  170. struct drv_uart *uart;
  171. uart = &uart4;
  172. /* enter interrupt */
  173. rt_interrupt_enter();
  174. /* UART in mode Receiver -------------------------------------------------*/
  175. if ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET) &&
  176. (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  177. {
  178. rt_hw_serial_isr(&serial4, RT_SERIAL_EVENT_RX_IND);
  179. /* Clear RXNE interrupt flag */
  180. __HAL_UART_CLEAR_IT(&uart->UartHandle, UART_FLAG_RXNE);
  181. }
  182. /* leave interrupt */
  183. rt_interrupt_leave();
  184. }
  185. #endif /* BSP_USING_UART4 */
  186. #if defined(BSP_USING_UART5)
  187. /* UART5 device driver structure */
  188. static struct drv_uart uart5;
  189. struct rt_serial_device serial5;
  190. void UART5_IRQHandler(void)
  191. {
  192. struct drv_uart *uart;
  193. uart = &uart5;
  194. /* enter interrupt */
  195. rt_interrupt_enter();
  196. /* UART in mode Receiver -------------------------------------------------*/
  197. if ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET) &&
  198. (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  199. {
  200. rt_hw_serial_isr(&serial5, RT_SERIAL_EVENT_RX_IND);
  201. /* Clear RXNE interrupt flag */
  202. __HAL_UART_CLEAR_IT(&uart->UartHandle, UART_FLAG_RXNE);
  203. }
  204. /* leave interrupt */
  205. rt_interrupt_leave();
  206. }
  207. #endif /* BSP_USING_UART5 */
  208. #if defined(BSP_USING_UART6)
  209. /* UART6 device driver structure */
  210. static struct drv_uart uart6;
  211. struct rt_serial_device serial6;
  212. void USART6_IRQHandler(void)
  213. {
  214. struct drv_uart *uart;
  215. uart = &uart6;
  216. /* enter interrupt */
  217. rt_interrupt_enter();
  218. /* UART in mode Receiver -------------------------------------------------*/
  219. if ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET) &&
  220. (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  221. {
  222. rt_hw_serial_isr(&serial6, RT_SERIAL_EVENT_RX_IND);
  223. /* Clear RXNE interrupt flag */
  224. __HAL_UART_CLEAR_IT(&uart->UartHandle, UART_FLAG_RXNE);
  225. }
  226. /* leave interrupt */
  227. rt_interrupt_leave();
  228. }
  229. #endif /* BSP_USING_UART6 */
  230. #if defined(BSP_USING_UART7)
  231. /* UART7 device driver structure */
  232. static struct drv_uart uart7;
  233. struct rt_serial_device serial7;
  234. void UART7_IRQHandler(void)
  235. {
  236. struct drv_uart *uart;
  237. uart = &uart7;
  238. /* enter interrupt */
  239. rt_interrupt_enter();
  240. /* UART in mode Receiver -------------------------------------------------*/
  241. if ((__HAL_UART_GET_FLAG(&uart->UartHandle, UART_FLAG_RXNE) != RESET) &&
  242. (__HAL_UART_GET_IT_SOURCE(&uart->UartHandle, UART_IT_RXNE) != RESET))
  243. {
  244. rt_hw_serial_isr(&serial7, RT_SERIAL_EVENT_RX_IND);
  245. /* Clear RXNE interrupt flag */
  246. __HAL_UART_CLEAR_IT(&uart->UartHandle, UART_FLAG_RXNE);
  247. }
  248. /* leave interrupt */
  249. rt_interrupt_leave();
  250. }
  251. #endif /* BSP_USING_UART7 */
  252. /**
  253. * @brief UART MSP Initialization
  254. * This function configures the hardware resources used in this example:
  255. * - Peripheral's clock enable
  256. * - Peripheral's GPIO Configuration
  257. * - NVIC configuration for UART interrupt request enable
  258. * @param huart: UART handle pointer
  259. * @retval None
  260. */
  261. void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle)
  262. {
  263. GPIO_InitTypeDef GPIO_InitStruct;
  264. if (uartHandle->Instance == UART4)
  265. {
  266. /* UART4 clock enable */
  267. __HAL_RCC_UART4_CLK_ENABLE();
  268. __HAL_RCC_GPIOC_CLK_ENABLE();
  269. __HAL_RCC_GPIOA_CLK_ENABLE();
  270. /**UART4 GPIO Configuration
  271. PC11 ------> UART4_RX
  272. PA0/WKUP ------> UART4_TX
  273. */
  274. GPIO_InitStruct.Pin = GPIO_PIN_11;
  275. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  276. GPIO_InitStruct.Pull = GPIO_NOPULL;
  277. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  278. GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
  279. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  280. GPIO_InitStruct.Pin = GPIO_PIN_0;
  281. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  282. GPIO_InitStruct.Pull = GPIO_NOPULL;
  283. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  284. GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
  285. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  286. /* UART4 interrupt Init */
  287. HAL_NVIC_SetPriority(UART4_IRQn, 5, 0);
  288. HAL_NVIC_EnableIRQ(UART4_IRQn);
  289. }
  290. else if (uartHandle->Instance == UART5)
  291. {
  292. /* UART5 clock enable */
  293. __HAL_RCC_UART5_CLK_ENABLE();
  294. __HAL_RCC_GPIOB_CLK_ENABLE();
  295. __HAL_RCC_GPIOC_CLK_ENABLE();
  296. /**UART5 GPIO Configuration
  297. PB8 ------> UART5_RX
  298. PC12 ------> UART5_TX
  299. */
  300. GPIO_InitStruct.Pin = GPIO_PIN_8;
  301. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  302. GPIO_InitStruct.Pull = GPIO_NOPULL;
  303. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  304. GPIO_InitStruct.Alternate = GPIO_AF7_UART5;
  305. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  306. GPIO_InitStruct.Pin = GPIO_PIN_12;
  307. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  308. GPIO_InitStruct.Pull = GPIO_NOPULL;
  309. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  310. GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
  311. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  312. /* UART5 interrupt Init */
  313. HAL_NVIC_SetPriority(UART5_IRQn, 5, 0);
  314. HAL_NVIC_EnableIRQ(UART5_IRQn);
  315. }
  316. else if (uartHandle->Instance == UART7)
  317. {
  318. /* UART7 clock enable */
  319. __HAL_RCC_UART7_CLK_ENABLE();
  320. __HAL_RCC_GPIOA_CLK_ENABLE();
  321. /**UART7 GPIO Configuration
  322. PA15 ------> UART7_TX
  323. PA8 ------> UART7_RX
  324. */
  325. GPIO_InitStruct.Pin = GPIO_PIN_15 | GPIO_PIN_8;
  326. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  327. GPIO_InitStruct.Pull = GPIO_NOPULL;
  328. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  329. GPIO_InitStruct.Alternate = GPIO_AF12_UART7;
  330. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  331. /* UART7 interrupt Init */
  332. HAL_NVIC_SetPriority(UART7_IRQn, 5, 0);
  333. HAL_NVIC_EnableIRQ(UART7_IRQn);
  334. }
  335. else if (uartHandle->Instance == USART1)
  336. {
  337. /* USART1 clock enable */
  338. __HAL_RCC_USART1_CLK_ENABLE();
  339. __HAL_RCC_GPIOA_CLK_ENABLE();
  340. /**USART1 GPIO Configuration
  341. PA10 ------> USART1_RX
  342. PA9 ------> USART1_TX
  343. */
  344. GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
  345. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  346. GPIO_InitStruct.Pull = GPIO_NOPULL;
  347. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  348. GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  349. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  350. /* USART1 interrupt Init */
  351. HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
  352. HAL_NVIC_EnableIRQ(USART1_IRQn);
  353. }
  354. else if (uartHandle->Instance == USART6)
  355. {
  356. /* USART6 clock enable */
  357. __HAL_RCC_USART6_CLK_ENABLE();
  358. __HAL_RCC_GPIOC_CLK_ENABLE();
  359. /**USART6 GPIO Configuration
  360. PC7 ------> USART6_RX
  361. PC6 ------> USART6_TX
  362. */
  363. GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_6;
  364. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  365. GPIO_InitStruct.Pull = GPIO_NOPULL;
  366. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  367. GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
  368. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  369. }
  370. }
  371. void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle)
  372. {
  373. if (uartHandle->Instance == UART4)
  374. {
  375. /* Peripheral clock disable */
  376. __HAL_RCC_UART4_CLK_DISABLE();
  377. /**UART4 GPIO Configuration
  378. PC11 ------> UART4_RX
  379. PA0/WKUP ------> UART4_TX
  380. */
  381. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_11);
  382. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
  383. }
  384. else if (uartHandle->Instance == UART5)
  385. {
  386. /* Peripheral clock disable */
  387. __HAL_RCC_UART5_CLK_DISABLE();
  388. /**UART5 GPIO Configuration
  389. PB8 ------> UART5_RX
  390. PC12 ------> UART5_TX
  391. */
  392. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);
  393. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
  394. }
  395. else if (uartHandle->Instance == UART7)
  396. {
  397. /* Peripheral clock disable */
  398. __HAL_RCC_UART7_CLK_DISABLE();
  399. /**UART7 GPIO Configuration
  400. PA15 ------> UART7_TX
  401. PA8 ------> UART7_RX
  402. */
  403. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15 | GPIO_PIN_8);
  404. }
  405. else if (uartHandle->Instance == USART1)
  406. {
  407. /* Peripheral clock disable */
  408. __HAL_RCC_USART1_CLK_DISABLE();
  409. /**USART1 GPIO Configuration
  410. PB7 ------> USART1_RX
  411. PA9 ------> USART1_TX
  412. */
  413. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
  414. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);
  415. }
  416. else if (uartHandle->Instance == USART6)
  417. {
  418. /* Peripheral clock disable */
  419. __HAL_RCC_USART6_CLK_DISABLE();
  420. /**USART6 GPIO Configuration
  421. PC7 ------> USART6_RX
  422. PC6 ------> USART6_TX
  423. */
  424. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7 | GPIO_PIN_6);
  425. }
  426. }
  427. int hw_usart_init(void)
  428. {
  429. struct drv_uart *uart;
  430. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  431. #ifdef BSP_USING_UART1
  432. uart = &uart1;
  433. uart->UartHandle.Instance = USART1;
  434. uart->irq = USART1_IRQn;
  435. serial1.ops = &drv_uart_ops;
  436. serial1.config = config;
  437. /* register UART1 device */
  438. rt_hw_serial_register(&serial1, "uart1",
  439. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  440. uart);
  441. #endif /* BSP_USING_UART1 */
  442. #ifdef BSP_USING_UART4
  443. uart = &uart4;
  444. uart->UartHandle.Instance = UART4;
  445. uart->irq = UART4_IRQn;
  446. serial4.ops = &drv_uart_ops;
  447. serial4.config = config;
  448. /* register UART4 device */
  449. rt_hw_serial_register(&serial4, "uart4",
  450. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  451. uart);
  452. #endif /* BSP_USING_UART4 */
  453. #ifdef BSP_USING_UART5
  454. uart = &uart5;
  455. uart->UartHandle.Instance = UART5;
  456. uart->irq = UART5_IRQn;
  457. serial5.ops = &drv_uart_ops;
  458. serial5.config = config;
  459. /* register UART5 device */
  460. rt_hw_serial_register(&serial5, "uart5",
  461. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  462. uart);
  463. #endif /* BSP_USING_UART5 */
  464. #ifdef BSP_USING_UART6
  465. uart = &uart6;
  466. uart->UartHandle.Instance = USART6;
  467. uart->irq = USART6_IRQn;
  468. serial6.ops = &drv_uart_ops;
  469. serial6.config = config;
  470. /* register UART6 device */
  471. rt_hw_serial_register(&serial6, "uart6",
  472. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  473. uart);
  474. #endif /* BSP_USING_UART6 */
  475. #ifdef BSP_USING_UART7
  476. uart = &uart7;
  477. uart->UartHandle.Instance = UART7;
  478. uart->irq = UART7_IRQn;
  479. serial7.ops = &drv_uart_ops;
  480. serial7.config = config;
  481. /* register UART7 device */
  482. rt_hw_serial_register(&serial7, "uart7",
  483. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  484. uart);
  485. #endif /* BSP_USING_UART7 */
  486. return 0;
  487. }
  488. INIT_BOARD_EXPORT(hw_usart_init);