serial_device.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /* mbed Microcontroller Library
  2. *******************************************************************************
  3. * Copyright (c) 2017, STMicroelectronics
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  24. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *******************************************************************************
  29. */
  30. #if DEVICE_SERIAL
  31. #include "serial_api_hal.h"
  32. #if defined (TARGET_STM32L432xC)
  33. #define UART_NUM (3)
  34. #elif defined (TARGET_STM32L433xC)
  35. #define UART_NUM (4)
  36. #else
  37. #define UART_NUM (6) // max value (TARGET_STM32L475xG / TARGET_STM32L476xG / TARGET_STM32L486xG / TARGET_STM32L496xG)
  38. #endif
  39. uint32_t serial_irq_ids[UART_NUM] = {0};
  40. UART_HandleTypeDef uart_handlers[UART_NUM];
  41. static uart_irq_handler irq_handler;
  42. // Defined in serial_api.c
  43. extern int8_t get_uart_index(UARTName uart_name);
  44. /******************************************************************************
  45. * INTERRUPTS HANDLING
  46. ******************************************************************************/
  47. static void uart_irq(UARTName uart_name)
  48. {
  49. int8_t id = get_uart_index(uart_name);
  50. if (id >= 0) {
  51. UART_HandleTypeDef *huart = &uart_handlers[id];
  52. if (serial_irq_ids[id] != 0) {
  53. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE) != RESET) {
  54. if (__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) {
  55. irq_handler(serial_irq_ids[id], TxIrq);
  56. }
  57. }
  58. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
  59. if (__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) {
  60. irq_handler(serial_irq_ids[id], RxIrq);
  61. /* Flag has been cleared when reading the content */
  62. }
  63. }
  64. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
  65. if (__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) {
  66. volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear ORE flag
  67. }
  68. }
  69. }
  70. }
  71. }
  72. #if defined(USART1_BASE)
  73. static void uart1_irq(void)
  74. {
  75. uart_irq(UART_1);
  76. }
  77. #endif
  78. #if defined(USART2_BASE)
  79. static void uart2_irq(void)
  80. {
  81. uart_irq(UART_2);
  82. }
  83. #endif
  84. #if defined(USART3_BASE)
  85. static void uart3_irq(void)
  86. {
  87. uart_irq(UART_3);
  88. }
  89. #endif
  90. #if defined(UART4_BASE)
  91. static void uart4_irq(void)
  92. {
  93. uart_irq(UART_4);
  94. }
  95. #endif
  96. #if defined(UART5_BASE)
  97. static void uart5_irq(void)
  98. {
  99. uart_irq(UART_5);
  100. }
  101. #endif
  102. #if defined(LPUART1_BASE)
  103. static void lpuart1_irq(void)
  104. {
  105. uart_irq(LPUART_1);
  106. }
  107. #endif
  108. void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
  109. {
  110. struct serial_s *obj_s = SERIAL_S(obj);
  111. irq_handler = handler;
  112. serial_irq_ids[obj_s->index] = id;
  113. }
  114. void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
  115. {
  116. struct serial_s *obj_s = SERIAL_S(obj);
  117. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  118. IRQn_Type irq_n = (IRQn_Type)0;
  119. uint32_t vector = 0;
  120. switch (obj_s->uart) {
  121. #if defined(USART1_BASE)
  122. case UART_1:
  123. irq_n = USART1_IRQn;
  124. vector = (uint32_t)&uart1_irq;
  125. break;
  126. #endif
  127. #if defined(USART2_BASE)
  128. case UART_2:
  129. irq_n = USART2_IRQn;
  130. vector = (uint32_t)&uart2_irq;
  131. break;
  132. #endif
  133. #if defined(USART3_BASE)
  134. case UART_3:
  135. irq_n = USART3_IRQn;
  136. vector = (uint32_t)&uart3_irq;
  137. break;
  138. #endif
  139. #if defined(UART4_BASE)
  140. case UART_4:
  141. irq_n = UART4_IRQn;
  142. vector = (uint32_t)&uart4_irq;
  143. break;
  144. #endif
  145. #if defined(UART5_BASE)
  146. case UART_5:
  147. irq_n = UART5_IRQn;
  148. vector = (uint32_t)&uart5_irq;
  149. break;
  150. #endif
  151. #if defined(LPUART1_BASE)
  152. case LPUART_1:
  153. irq_n = LPUART1_IRQn;
  154. vector = (uint32_t)&lpuart1_irq;
  155. break;
  156. #endif
  157. }
  158. if (enable) {
  159. if (irq == RxIrq) {
  160. __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
  161. } else { // TxIrq
  162. __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
  163. }
  164. NVIC_SetVector(irq_n, vector);
  165. NVIC_EnableIRQ(irq_n);
  166. } else { // disable
  167. int all_disabled = 0;
  168. if (irq == RxIrq) {
  169. __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
  170. // Check if TxIrq is disabled too
  171. if ((huart->Instance->CR1 & USART_CR1_TXEIE) == 0) {
  172. all_disabled = 1;
  173. }
  174. } else { // TxIrq
  175. __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
  176. // Check if RxIrq is disabled too
  177. if ((huart->Instance->CR1 & USART_CR1_RXNEIE) == 0) {
  178. all_disabled = 1;
  179. }
  180. }
  181. if (all_disabled) {
  182. NVIC_DisableIRQ(irq_n);
  183. }
  184. }
  185. }
  186. /******************************************************************************
  187. * READ/WRITE
  188. ******************************************************************************/
  189. int serial_getc(serial_t *obj)
  190. {
  191. struct serial_s *obj_s = SERIAL_S(obj);
  192. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  193. while (!serial_readable(obj));
  194. if (obj_s->databits == UART_WORDLENGTH_8B) {
  195. return (int)(huart->Instance->RDR & (uint8_t)0xFF);
  196. } else {
  197. return (int)(huart->Instance->RDR & (uint16_t)0x1FF);
  198. }
  199. }
  200. void serial_putc(serial_t *obj, int c)
  201. {
  202. struct serial_s *obj_s = SERIAL_S(obj);
  203. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  204. while (!serial_writable(obj));
  205. if (obj_s->databits == UART_WORDLENGTH_8B) {
  206. huart->Instance->TDR = (uint8_t)(c & (uint8_t)0xFF);
  207. } else {
  208. huart->Instance->TDR = (uint16_t)(c & (uint16_t)0x1FF);
  209. }
  210. }
  211. void serial_clear(serial_t *obj)
  212. {
  213. struct serial_s *obj_s = SERIAL_S(obj);
  214. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  215. huart->TxXferCount = 0;
  216. huart->RxXferCount = 0;
  217. }
  218. void serial_break_set(serial_t *obj)
  219. {
  220. struct serial_s *obj_s = SERIAL_S(obj);
  221. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  222. HAL_LIN_SendBreak(huart);
  223. }
  224. #if DEVICE_SERIAL_ASYNCH
  225. /******************************************************************************
  226. * LOCAL HELPER FUNCTIONS
  227. ******************************************************************************/
  228. /**
  229. * Configure the TX buffer for an asynchronous write serial transaction
  230. *
  231. * @param obj The serial object.
  232. * @param tx The buffer for sending.
  233. * @param tx_length The number of words to transmit.
  234. */
  235. static void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
  236. {
  237. (void)width;
  238. // Exit if a transmit is already on-going
  239. if (serial_tx_active(obj)) {
  240. return;
  241. }
  242. obj->tx_buff.buffer = tx;
  243. obj->tx_buff.length = tx_length;
  244. obj->tx_buff.pos = 0;
  245. }
  246. /**
  247. * Configure the RX buffer for an asynchronous write serial transaction
  248. *
  249. * @param obj The serial object.
  250. * @param tx The buffer for sending.
  251. * @param tx_length The number of words to transmit.
  252. */
  253. static void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
  254. {
  255. (void)width;
  256. // Exit if a reception is already on-going
  257. if (serial_rx_active(obj)) {
  258. return;
  259. }
  260. obj->rx_buff.buffer = rx;
  261. obj->rx_buff.length = rx_length;
  262. obj->rx_buff.pos = 0;
  263. }
  264. /**
  265. * Configure events
  266. *
  267. * @param obj The serial object
  268. * @param event The logical OR of the events to configure
  269. * @param enable Set to non-zero to enable events, or zero to disable them
  270. */
  271. static void serial_enable_event(serial_t *obj, int event, uint8_t enable)
  272. {
  273. struct serial_s *obj_s = SERIAL_S(obj);
  274. // Shouldn't have to enable interrupt here, just need to keep track of the requested events.
  275. if (enable) {
  276. obj_s->events |= event;
  277. } else {
  278. obj_s->events &= ~event;
  279. }
  280. }
  281. /**
  282. * Get index of serial object TX IRQ, relating it to the physical peripheral.
  283. *
  284. * @param uart_name i.e. UART_1, UART_2, ...
  285. * @return internal NVIC TX IRQ index of U(S)ART peripheral
  286. */
  287. static IRQn_Type serial_get_irq_n(UARTName uart_name)
  288. {
  289. IRQn_Type irq_n;
  290. switch (uart_name) {
  291. #if defined(USART1_BASE)
  292. case UART_1:
  293. irq_n = USART1_IRQn;
  294. break;
  295. #endif
  296. #if defined(USART2_BASE)
  297. case UART_2:
  298. irq_n = USART2_IRQn;
  299. break;
  300. #endif
  301. #if defined(USART3_BASE)
  302. case UART_3:
  303. irq_n = USART3_IRQn;
  304. break;
  305. #endif
  306. #if defined(UART4_BASE)
  307. case UART_4:
  308. irq_n = UART4_IRQn;
  309. break;
  310. #endif
  311. #if defined(UART5_BASE)
  312. case UART_5:
  313. irq_n = UART5_IRQn;
  314. break;
  315. #endif
  316. #if defined(LPUART1_BASE)
  317. case LPUART_1:
  318. irq_n = LPUART1_IRQn;
  319. break;
  320. #endif
  321. default:
  322. irq_n = (IRQn_Type)0;
  323. }
  324. return irq_n;
  325. }
  326. /******************************************************************************
  327. * MBED API FUNCTIONS
  328. ******************************************************************************/
  329. /**
  330. * Begin asynchronous TX transfer. The used buffer is specified in the serial
  331. * object, tx_buff
  332. *
  333. * @param obj The serial object
  334. * @param tx The buffer for sending
  335. * @param tx_length The number of words to transmit
  336. * @param tx_width The bit width of buffer word
  337. * @param handler The serial handler
  338. * @param event The logical OR of events to be registered
  339. * @param hint A suggestion for how to use DMA with this transfer
  340. * @return Returns number of data transfered, or 0 otherwise
  341. */
  342. int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
  343. {
  344. // TODO: DMA usage is currently ignored
  345. (void) hint;
  346. // Check buffer is ok
  347. MBED_ASSERT(tx != (void *)0);
  348. MBED_ASSERT(tx_width == 8); // support only 8b width
  349. struct serial_s *obj_s = SERIAL_S(obj);
  350. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  351. if (tx_length == 0) {
  352. return 0;
  353. }
  354. // Set up buffer
  355. serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width);
  356. // Set up events
  357. serial_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events
  358. serial_enable_event(obj, event, 1); // Set only the wanted events
  359. // Enable interrupt
  360. IRQn_Type irq_n = serial_get_irq_n(obj_s->uart);
  361. NVIC_ClearPendingIRQ(irq_n);
  362. NVIC_DisableIRQ(irq_n);
  363. NVIC_SetPriority(irq_n, 1);
  364. NVIC_SetVector(irq_n, (uint32_t)handler);
  365. NVIC_EnableIRQ(irq_n);
  366. // the following function will enable UART_IT_TXE and error interrupts
  367. if (HAL_UART_Transmit_IT(huart, (uint8_t *)tx, tx_length) != HAL_OK) {
  368. return 0;
  369. }
  370. return tx_length;
  371. }
  372. /**
  373. * Begin asynchronous RX transfer (enable interrupt for data collecting)
  374. * The used buffer is specified in the serial object, rx_buff
  375. *
  376. * @param obj The serial object
  377. * @param rx The buffer for sending
  378. * @param rx_length The number of words to transmit
  379. * @param rx_width The bit width of buffer word
  380. * @param handler The serial handler
  381. * @param event The logical OR of events to be registered
  382. * @param handler The serial handler
  383. * @param char_match A character in range 0-254 to be matched
  384. * @param hint A suggestion for how to use DMA with this transfer
  385. */
  386. void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
  387. {
  388. // TODO: DMA usage is currently ignored
  389. (void) hint;
  390. /* Sanity check arguments */
  391. MBED_ASSERT(obj);
  392. MBED_ASSERT(rx != (void *)0);
  393. MBED_ASSERT(rx_width == 8); // support only 8b width
  394. struct serial_s *obj_s = SERIAL_S(obj);
  395. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  396. serial_enable_event(obj, SERIAL_EVENT_RX_ALL, 0);
  397. serial_enable_event(obj, event, 1);
  398. // set CharMatch
  399. obj->char_match = char_match;
  400. serial_rx_buffer_set(obj, rx, rx_length, rx_width);
  401. IRQn_Type irq_n = serial_get_irq_n(obj_s->uart);
  402. NVIC_ClearPendingIRQ(irq_n);
  403. NVIC_DisableIRQ(irq_n);
  404. NVIC_SetPriority(irq_n, 0);
  405. NVIC_SetVector(irq_n, (uint32_t)handler);
  406. NVIC_EnableIRQ(irq_n);
  407. // following HAL function will enable the RXNE interrupt + error interrupts
  408. HAL_UART_Receive_IT(huart, (uint8_t *)rx, rx_length);
  409. }
  410. /**
  411. * Attempts to determine if the serial peripheral is already in use for TX
  412. *
  413. * @param obj The serial object
  414. * @return Non-zero if the TX transaction is ongoing, 0 otherwise
  415. */
  416. uint8_t serial_tx_active(serial_t *obj)
  417. {
  418. MBED_ASSERT(obj);
  419. struct serial_s *obj_s = SERIAL_S(obj);
  420. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  421. return (((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_TX) == HAL_UART_STATE_BUSY_TX) ? 1 : 0);
  422. }
  423. /**
  424. * Attempts to determine if the serial peripheral is already in use for RX
  425. *
  426. * @param obj The serial object
  427. * @return Non-zero if the RX transaction is ongoing, 0 otherwise
  428. */
  429. uint8_t serial_rx_active(serial_t *obj)
  430. {
  431. MBED_ASSERT(obj);
  432. struct serial_s *obj_s = SERIAL_S(obj);
  433. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  434. return (((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) ? 1 : 0);
  435. }
  436. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
  437. {
  438. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
  439. __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
  440. }
  441. }
  442. void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
  443. {
  444. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
  445. volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear PE flag
  446. } else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
  447. volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear FE flag
  448. } else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) {
  449. volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear NE flag
  450. } else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
  451. volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear ORE flag
  452. }
  453. }
  454. /**
  455. * The asynchronous TX and RX handler.
  456. *
  457. * @param obj The serial object
  458. * @return Returns event flags if a TX/RX transfer termination condition was met or 0 otherwise
  459. */
  460. int serial_irq_handler_asynch(serial_t *obj)
  461. {
  462. struct serial_s *obj_s = SERIAL_S(obj);
  463. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  464. volatile int return_event = 0;
  465. uint8_t *buf = (uint8_t *)(obj->rx_buff.buffer);
  466. uint8_t i = 0;
  467. // TX PART:
  468. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
  469. if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
  470. // Return event SERIAL_EVENT_TX_COMPLETE if requested
  471. if ((obj_s->events & SERIAL_EVENT_TX_COMPLETE) != 0) {
  472. return_event |= (SERIAL_EVENT_TX_COMPLETE & obj_s->events);
  473. }
  474. }
  475. }
  476. // Handle error events
  477. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
  478. if (__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) {
  479. return_event |= (SERIAL_EVENT_RX_PARITY_ERROR & obj_s->events);
  480. }
  481. }
  482. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
  483. if (__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) {
  484. return_event |= (SERIAL_EVENT_RX_FRAMING_ERROR & obj_s->events);
  485. }
  486. }
  487. if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
  488. if (__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) {
  489. return_event |= (SERIAL_EVENT_RX_OVERRUN_ERROR & obj_s->events);
  490. }
  491. }
  492. HAL_UART_IRQHandler(huart);
  493. // Abort if an error occurs
  494. if ((return_event & SERIAL_EVENT_RX_PARITY_ERROR) ||
  495. (return_event & SERIAL_EVENT_RX_FRAMING_ERROR) ||
  496. (return_event & SERIAL_EVENT_RX_OVERRUN_ERROR)) {
  497. return return_event;
  498. }
  499. //RX PART
  500. if (huart->RxXferSize != 0) {
  501. obj->rx_buff.pos = huart->RxXferSize - huart->RxXferCount;
  502. }
  503. if ((huart->RxXferCount == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
  504. return_event |= (SERIAL_EVENT_RX_COMPLETE & obj_s->events);
  505. }
  506. // Check if char_match is present
  507. if (obj_s->events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
  508. if (buf != NULL) {
  509. for (i = 0; i < obj->rx_buff.pos; i++) {
  510. if (buf[i] == obj->char_match) {
  511. obj->rx_buff.pos = i;
  512. return_event |= (SERIAL_EVENT_RX_CHARACTER_MATCH & obj_s->events);
  513. serial_rx_abort_asynch(obj);
  514. break;
  515. }
  516. }
  517. }
  518. }
  519. return return_event;
  520. }
  521. /**
  522. * Abort the ongoing TX transaction. It disables the enabled interupt for TX and
  523. * flush TX hardware buffer if TX FIFO is used
  524. *
  525. * @param obj The serial object
  526. */
  527. void serial_tx_abort_asynch(serial_t *obj)
  528. {
  529. struct serial_s *obj_s = SERIAL_S(obj);
  530. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  531. __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
  532. __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
  533. // clear flags
  534. __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
  535. // reset states
  536. huart->TxXferCount = 0;
  537. // update handle state
  538. if (huart->gState == HAL_UART_STATE_BUSY_TX_RX) {
  539. huart->gState = HAL_UART_STATE_BUSY_RX;
  540. } else {
  541. huart->gState = HAL_UART_STATE_READY;
  542. }
  543. }
  544. /**
  545. * Abort the ongoing RX transaction It disables the enabled interrupt for RX and
  546. * flush RX hardware buffer if RX FIFO is used
  547. *
  548. * @param obj The serial object
  549. */
  550. void serial_rx_abort_asynch(serial_t *obj)
  551. {
  552. struct serial_s *obj_s = SERIAL_S(obj);
  553. UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
  554. // disable interrupts
  555. __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
  556. __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
  557. __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
  558. // clear flags
  559. __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
  560. volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear errors flag
  561. // reset states
  562. huart->RxXferCount = 0;
  563. // update handle state
  564. if (huart->RxState == HAL_UART_STATE_BUSY_TX_RX) {
  565. huart->RxState = HAL_UART_STATE_BUSY_TX;
  566. } else {
  567. huart->RxState = HAL_UART_STATE_READY;
  568. }
  569. }
  570. #endif /* DEVICE_SERIAL_ASYNCH */
  571. #if DEVICE_SERIAL_FC
  572. /**
  573. * Set HW Control Flow
  574. * @param obj The serial object
  575. * @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
  576. * @param rxflow Pin for the rxflow
  577. * @param txflow Pin for the txflow
  578. */
  579. void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
  580. {
  581. struct serial_s *obj_s = SERIAL_S(obj);
  582. // Determine the UART to use (UART_1, UART_2, ...)
  583. UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
  584. UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
  585. // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
  586. obj_s->uart = (UARTName)pinmap_merge(uart_cts, uart_rts);
  587. MBED_ASSERT(obj_s->uart != (UARTName)NC);
  588. if (type == FlowControlNone) {
  589. // Disable hardware flow control
  590. obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
  591. }
  592. if (type == FlowControlRTS) {
  593. // Enable RTS
  594. MBED_ASSERT(uart_rts != (UARTName)NC);
  595. obj_s->hw_flow_ctl = UART_HWCONTROL_RTS;
  596. obj_s->pin_rts = rxflow;
  597. // Enable the pin for RTS function
  598. pinmap_pinout(rxflow, PinMap_UART_RTS);
  599. }
  600. if (type == FlowControlCTS) {
  601. // Enable CTS
  602. MBED_ASSERT(uart_cts != (UARTName)NC);
  603. obj_s->hw_flow_ctl = UART_HWCONTROL_CTS;
  604. obj_s->pin_cts = txflow;
  605. // Enable the pin for CTS function
  606. pinmap_pinout(txflow, PinMap_UART_CTS);
  607. }
  608. if (type == FlowControlRTSCTS) {
  609. // Enable CTS & RTS
  610. MBED_ASSERT(uart_rts != (UARTName)NC);
  611. MBED_ASSERT(uart_cts != (UARTName)NC);
  612. obj_s->hw_flow_ctl = UART_HWCONTROL_RTS_CTS;
  613. obj_s->pin_rts = rxflow;
  614. obj_s->pin_cts = txflow;
  615. // Enable the pin for CTS function
  616. pinmap_pinout(txflow, PinMap_UART_CTS);
  617. // Enable the pin for RTS function
  618. pinmap_pinout(rxflow, PinMap_UART_RTS);
  619. }
  620. init_uart(obj);
  621. }
  622. #endif /* DEVICE_SERIAL_FC */
  623. #endif /* DEVICE_SERIAL */