1 /*
2  * Copyright 2018-2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __HAL_UART_ADAPTER_H__
10 #define __HAL_UART_ADAPTER_H__
11 
12 #include "fsl_common.h"
13 #if defined(SDK_OS_FREE_RTOS)
14 #include "FreeRTOS.h"
15 #endif
16 
17 /*!
18  * @addtogroup UART_Adapter
19  * @{
20  */
21 
22 /*******************************************************************************
23  * Definitions
24  ******************************************************************************/
25 
26 /*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable) */
27 #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
28 #define UART_ADAPTER_NON_BLOCKING_MODE (1U)
29 #else
30 #ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
31 #define UART_ADAPTER_NON_BLOCKING_MODE (0U)
32 #else
33 #define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE
34 #endif
35 #endif
36 
37 #if defined(__GIC_PRIO_BITS)
38 #ifndef HAL_UART_ISR_PRIORITY
39 #define HAL_UART_ISR_PRIORITY (25U)
40 #endif
41 #else
42 #if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
43 #ifndef HAL_UART_ISR_PRIORITY
44 #define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
45 #endif
46 #else
47 /* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
48  * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
49  * priority is 3 (2^2 - 1). So, the default value is 3.
50  */
51 #ifndef HAL_UART_ISR_PRIORITY
52 #define HAL_UART_ISR_PRIORITY (3U)
53 #endif
54 #endif
55 #endif
56 
57 #ifndef HAL_UART_ADAPTER_LOWPOWER
58 #define HAL_UART_ADAPTER_LOWPOWER (0U)
59 #endif /* HAL_UART_ADAPTER_LOWPOWER */
60 
61 /*! @brief Enable or disable uart hardware FIFO mode (1 - enable, 0 - disable) */
62 #ifndef HAL_UART_ADAPTER_FIFO
63 #define HAL_UART_ADAPTER_FIFO (1U)
64 #endif /* HAL_UART_ADAPTER_FIFO */
65 
66 #if (defined(SERIAL_PORT_TYPE_UART_DMA) && (SERIAL_PORT_TYPE_UART_DMA > 0U))
67 #ifndef HAL_UART_DMA_ENABLE
68 #define HAL_UART_DMA_ENABLE (1U)
69 #endif
70 #endif
71 
72 #ifndef HAL_UART_DMA_ENABLE
73 #define HAL_UART_DMA_ENABLE (0U)
74 #endif /* HAL_UART_DMA_ENABLE */
75 
76 /*! @brief Enable or disable uart DMA adapter int mode (1 - enable, 0 - disable) */
77 #ifndef HAL_UART_DMA_INIT_ENABLE
78 #define HAL_UART_DMA_INIT_ENABLE (1U)
79 #endif /* HAL_SPI_MASTER_DMA_INIT_ENABLE */
80 
81 /*! @brief Definition of uart dma adapter software idleline detection timeout value in ms. */
82 #ifndef HAL_UART_DMA_IDLELINE_TIMEOUT
83 #define HAL_UART_DMA_IDLELINE_TIMEOUT (1U)
84 #endif /* HAL_UART_DMA_IDLELINE_TIMEOUT */
85 
86 /*! @brief Definition of uart adapter handle size. */
87 #if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
88 #define HAL_UART_HANDLE_SIZE       (92U + HAL_UART_ADAPTER_LOWPOWER * 16U + HAL_UART_DMA_ENABLE * 4U)
89 #define HAL_UART_BLOCK_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U + HAL_UART_DMA_ENABLE * 4U)
90 #else
91 #define HAL_UART_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U + HAL_UART_DMA_ENABLE * 4U)
92 #endif
93 
94 /*! @brief Definition of uart dma adapter handle size. */
95 #if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
96 #if (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
97 #define HAL_UART_DMA_HANDLE_SIZE (124U + HAL_UART_ADAPTER_LOWPOWER * 36U)
98 #elif (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
99 #define HAL_UART_DMA_HANDLE_SIZE (140U + HAL_UART_ADAPTER_LOWPOWER * 36U)
100 #else
101 #error This SOC does not have DMA or EDMA available!
102 #endif
103 #endif /* HAL_UART_DMA_ENABLE */
104 
105 /*!
106  * @brief Defines the uart handle
107  *
108  * This macro is used to define a 4 byte aligned uart handle.
109  * Then use "(hal_uart_handle_t)name" to get the uart handle.
110  *
111  * The macro should be global and could be optional. You could also define uart handle by yourself.
112  *
113  * This is an example,
114  * @code
115  * UART_HANDLE_DEFINE(uartHandle);
116  * @endcode
117  *
118  * @param name The name string of the uart handle.
119  */
120 #define UART_HANDLE_DEFINE(name) uint32_t name[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
121 
122 #if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
123 #define UART_DMA_HANDLE_DEFINE(name) \
124     uint32_t name[((HAL_UART_DMA_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
125 #endif
126 
127 /*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */
128 #ifndef HAL_UART_TRANSFER_MODE
129 #define HAL_UART_TRANSFER_MODE (0U)
130 #endif
131 
132 /*! @brief The handle of uart adapter. */
133 typedef void *hal_uart_handle_t;
134 
135 /*! @brief The handle of uart dma adapter. */
136 typedef void *hal_uart_dma_handle_t;
137 
138 /*! @brief UART status */
139 typedef enum _hal_uart_status
140 {
141     kStatus_HAL_UartSuccess = kStatus_Success,                       /*!< Successfully */
142     kStatus_HAL_UartTxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */
143     kStatus_HAL_UartRxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */
144     kStatus_HAL_UartTxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */
145     kStatus_HAL_UartRxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */
146     kStatus_HAL_UartBaudrateNotSupport =
147         MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */
148     kStatus_HAL_UartProtocolError = MAKE_STATUS(
149         kStatusGroup_HAL_UART,
150         6),                                                        /*!< Error occurs for Noise, Framing, Parity, etc.
151                                                                         For transactional transfer, The up layer needs to abort the transfer and then starts again */
152     kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */
153 } hal_uart_status_t;
154 
155 /*! @brief UART parity mode. */
156 typedef enum _hal_uart_parity_mode
157 {
158     kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */
159     kHAL_UartParityEven     = 0x2U, /*!< Parity even enabled */
160     kHAL_UartParityOdd      = 0x3U, /*!< Parity odd enabled */
161 } hal_uart_parity_mode_t;
162 
163 /*! @brief UART stop bit count. */
164 typedef enum _hal_uart_stop_bit_count
165 {
166     kHAL_UartOneStopBit = 0U, /*!< One stop bit */
167     kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */
168 } hal_uart_stop_bit_count_t;
169 
170 /*! @brief UART configuration structure. */
171 typedef struct _hal_uart_config
172 {
173     uint32_t srcClock_Hz;                   /*!< Source clock */
174     uint32_t baudRate_Bps;                  /*!< Baud rate  */
175     hal_uart_parity_mode_t parityMode;      /*!< Parity mode, disabled (default), even, odd */
176     hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
177     uint8_t enableRx;                       /*!< Enable RX */
178     uint8_t enableTx;                       /*!< Enable TX */
179     uint8_t enableRxRTS;                    /*!< Enable RX RTS */
180     uint8_t enableTxCTS;                    /*!< Enable TX CTS */
181     uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the
182                            SOC corresponding RM.
183                            Invalid instance value will cause initialization failure. */
184 #if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u))
185     uint8_t txFifoWatermark;
186     uint8_t rxFifoWatermark;
187 #endif
188 } hal_uart_config_t;
189 
190 #if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
191 /*! @brief UART DMA status */
192 typedef enum _hal_uart_dma_status
193 {
194     kStatus_HAL_UartDmaSuccess  = 0U,
195     kStatus_HAL_UartDmaRxIdle   = (1U << 1U),
196     kStatus_HAL_UartDmaRxBusy   = (1U << 2U),
197     kStatus_HAL_UartDmaTxIdle   = (1U << 3U),
198     kStatus_HAL_UartDmaTxBusy   = (1U << 4U),
199     kStatus_HAL_UartDmaIdleline = (1U << 5U),
200     kStatus_HAL_UartDmaError    = (1U << 6U),
201 } hal_uart_dma_status_t;
202 
203 typedef struct _dma_mux_configure_t
204 {
205     union
206     {
207         struct
208         {
209             uint8_t dma_mux_instance;
210             uint32_t rx_request;
211             uint32_t tx_request;
212         } dma_dmamux_configure;
213     };
214 } dma_mux_configure_t;
215 typedef struct _dma_channel_mux_configure_t
216 {
217     union
218     {
219         struct
220         {
221             uint32_t dma_rx_channel_mux;
222             uint32_t dma_tx_channel_mux;
223         } dma_dmamux_configure;
224     };
225 } dma_channel_mux_configure_t;
226 
227 typedef struct _hal_uart_dma_config_t
228 {
229     uint8_t uart_instance;
230     uint8_t dma_instance;
231     uint8_t rx_channel;
232     uint8_t tx_channel;
233     void *dma_mux_configure;
234     void *dma_channel_mux_configure;
235 } hal_uart_dma_config_t;
236 #endif /* HAL_UART_DMA_ENABLE */
237 
238 /*! @brief UART transfer callback function. */
239 typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam);
240 
241 #if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
242 typedef struct _dma_callback_msg
243 {
244     hal_uart_dma_status_t status;
245     uint8_t *data;
246     uint32_t dataSize;
247 } hal_dma_callback_msg_t;
248 
249 /*! @brief UART transfer callback function. */
250 typedef void (*hal_uart_dma_transfer_callback_t)(hal_uart_dma_handle_t handle,
251                                                  hal_dma_callback_msg_t *msg,
252                                                  void *callbackParam);
253 #endif /* HAL_UART_DMA_ENABLE */
254 
255 /*! @brief UART transfer structure. */
256 typedef struct _hal_uart_transfer
257 {
258     uint8_t *data;   /*!< The buffer of data to be transfer.*/
259     size_t dataSize; /*!< The byte count to be transfer. */
260 } hal_uart_transfer_t;
261 
262 /*******************************************************************************
263  * API
264  ******************************************************************************/
265 
266 #if defined(__cplusplus)
267 extern "C" {
268 #endif /* _cplusplus */
269 
270 /*!
271  * @name Initialization and deinitialization
272  * @{
273  */
274 
275 /*!
276  * @brief Initializes a UART instance with the UART handle and the user configuration structure.
277  *
278  * This function configures the UART module with user-defined settings. The user can configure the configuration
279  * structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by
280  * the caller. Example below shows how to use this API to configure the UART.
281  *  @code
282  *   UART_HANDLE_DEFINE(g_UartHandle);
283  *   hal_uart_config_t config;
284  *   config.srcClock_Hz = 48000000;
285  *   config.baudRate_Bps = 115200U;
286  *   config.parityMode = kHAL_UartParityDisabled;
287  *   config.stopBitCount = kHAL_UartOneStopBit;
288  *   config.enableRx = 1;
289  *   config.enableTx = 1;
290  *   config.enableRxRTS = 0;
291  *   config.enableTxCTS = 0;
292  *   config.instance = 0;
293  *   HAL_UartInit((hal_uart_handle_t)g_UartHandle, &config);
294  *  @endcode
295  *
296  * @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller.
297  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
298  * You can define the handle in the following two ways:
299  * #UART_HANDLE_DEFINE(handle);
300  * or
301  * uint32_t handle[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
302  * @param config Pointer to user-defined configuration structure.
303  * @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source.
304  * @retval kStatus_HAL_UartSuccess UART initialization succeed
305  */
306 hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *uart_config);
307 
308 /*!
309  * @brief Deinitializes a UART instance.
310  *
311  * This function waits for TX complete, disables TX and RX, and disables the UART clock.
312  *
313  * @param handle UART handle pointer.
314  * @retval kStatus_HAL_UartSuccess UART de-initialization succeed
315  */
316 hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle);
317 
318 /*! @}*/
319 
320 /*!
321  * @name Blocking bus Operations
322  * @{
323  */
324 
325 /*!
326  * @brief Reads RX data register using a blocking method.
327  *
328  * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
329  * have data, and reads data from the RX register.
330  *
331  * @note The function #HAL_UartReceiveBlocking and the function HAL_UartTransferReceiveNonBlocking
332  * cannot be used at the same time.
333  * And, the function HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function.
334  *
335  * @param handle UART handle pointer.
336  * @param data Start address of the buffer to store the received data.
337  * @param length Size of the buffer.
338  * @retval kStatus_HAL_UartError An error occurred while receiving data.
339  * @retval kStatus_HAL_UartParityError A parity error occurred while receiving data.
340  * @retval kStatus_HAL_UartSuccess Successfully received all data.
341  */
342 hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
343 
344 /*!
345  * @brief Writes to the TX register using a blocking method.
346  *
347  * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
348  * to have room and writes data to the TX buffer.
349  *
350  * @note The function #HAL_UartSendBlocking and the function HAL_UartTransferSendNonBlocking
351  * cannot be used at the same time.
352  * And, the function HAL_UartTransferAbortSend cannot be used to abort the transmission of this function.
353  *
354  * @param handle UART handle pointer.
355  * @param data Start address of the data to write.
356  * @param length Size of the data to write.
357  * @retval kStatus_HAL_UartSuccess Successfully sent all data.
358  */
359 hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length);
360 
361 /*! @}*/
362 
363 #if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
364 #if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
365 
366 /*!
367  * @name Transactional
368  * @note The transactional API and the functional API cannot be used at the same time. The macro
369  * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
370  * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
371  * @{
372  */
373 
374 /*!
375  * @brief Installs a callback and callback parameter.
376  *
377  * This function is used to install the callback and callback parameter for UART module.
378  * When any status of the UART changed, the driver will notify the upper layer by the installed callback
379  * function. And the status is also passed as status parameter when the callback is called.
380  *
381  * @param handle UART handle pointer.
382  * @param callback The callback function.
383  * @param callbackParam The parameter of the callback function.
384  * @retval kStatus_HAL_UartSuccess Successfully install the callback.
385  */
386 hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
387                                                   hal_uart_transfer_callback_t callback,
388                                                   void *callbackParam);
389 
390 /*!
391  * @brief Receives a buffer of data using an interrupt method.
392  *
393  * This function receives data using an interrupt method. This is a non-blocking function, which
394  * returns directly without waiting for all data to be received.
395  * The receive request is saved by the UART driver.
396  * When the new data arrives, the receive request is serviced first.
397  * When all data is received, the UART driver notifies the upper layer
398  * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
399  *
400  * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
401  * cannot be used at the same time.
402  *
403  * @param handle UART handle pointer.
404  * @param transfer UART transfer structure, see #hal_uart_transfer_t.
405  * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
406  * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
407  * @retval kStatus_HAL_UartError An error occurred.
408  */
409 hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
410 
411 /*!
412  * @brief Transmits a buffer of data using the interrupt method.
413  *
414  * This function sends data using an interrupt method. This is a non-blocking function, which
415  * returns directly without waiting for all data to be written to the TX register. When
416  * all data is written to the TX register in the ISR, the UART driver calls the callback
417  * function and passes the @ref kStatus_UART_TxIdle as status parameter.
418  *
419  * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
420  * cannot be used at the same time.
421  *
422  * @param handle UART handle pointer.
423  * @param transfer UART transfer structure. See #hal_uart_transfer_t.
424  * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
425  * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
426  * @retval kStatus_HAL_UartError An error occurred.
427  */
428 hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);
429 
430 /*!
431  * @brief Gets the number of bytes that have been received.
432  *
433  * This function gets the number of bytes that have been received.
434  *
435  * @param handle UART handle pointer.
436  * @param count Receive bytes count.
437  * @retval kStatus_HAL_UartError An error occurred.
438  * @retval kStatus_Success Get successfully through the parameter \p count.
439  */
440 hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count);
441 
442 /*!
443  * @brief Gets the number of bytes written to the UART TX register.
444  *
445  * This function gets the number of bytes written to the UART TX
446  * register by using the interrupt method.
447  *
448  * @param handle UART handle pointer.
449  * @param count Send bytes count.
450  * @retval kStatus_HAL_UartError An error occurred.
451  * @retval kStatus_Success Get successfully through the parameter \p count.
452  */
453 hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count);
454 
455 /*!
456  * @brief Aborts the interrupt-driven data receiving.
457  *
458  * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
459  * how many bytes are not received yet.
460  *
461  * @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of
462  * the function #HAL_UartReceiveBlocking.
463  *
464  * @param handle UART handle pointer.
465  * @retval kStatus_Success Get successfully abort the receiving.
466  */
467 hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle);
468 
469 /*!
470  * @brief Aborts the interrupt-driven data sending.
471  *
472  * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
473  * how many bytes are not sent out.
474  *
475  * @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of
476  * the function #HAL_UartSendBlocking.
477  *
478  * @param handle UART handle pointer.
479  * @retval kStatus_Success Get successfully abort the sending.
480  */
481 hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle);
482 
483 /*! @}*/
484 
485 #else
486 
487 /*!
488  * @name Functional API with non-blocking mode.
489  * @note The functional API and the transactional API cannot be used at the same time. The macro
490  * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
491  * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
492  * @{
493  */
494 
495 /*!
496  * @brief Installs a callback and callback parameter.
497  *
498  * This function is used to install the callback and callback parameter for UART module.
499  * When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback
500  * function. And the status is also passed as status parameter when the callback is called.
501  *
502  * @param handle UART handle pointer.
503  * @param callback The callback function.
504  * @param callbackParam The parameter of the callback function.
505  * @retval kStatus_HAL_UartSuccess Successfully install the callback.
506  */
507 hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
508                                           hal_uart_transfer_callback_t callback,
509                                           void *callbackParam);
510 
511 /*!
512  * @brief Receives a buffer of data using an interrupt method.
513  *
514  * This function receives data using an interrupt method. This is a non-blocking function, which
515  * returns directly without waiting for all data to be received.
516  * The receive request is saved by the UART adapter.
517  * When the new data arrives, the receive request is serviced first.
518  * When all data is received, the UART adapter notifies the upper layer
519  * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
520  *
521  * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking
522  * cannot be used at the same time.
523  *
524  * @param handle UART handle pointer.
525  * @param data Start address of the data to write.
526  * @param length Size of the data to write.
527  * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
528  * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
529  * @retval kStatus_HAL_UartError An error occurred.
530  */
531 hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
532 
533 /*!
534  * @brief Transmits a buffer of data using the interrupt method.
535  *
536  * This function sends data using an interrupt method. This is a non-blocking function, which
537  * returns directly without waiting for all data to be written to the TX register. When
538  * all data is written to the TX register in the ISR, the UART driver calls the callback
539  * function and passes the @ref kStatus_UART_TxIdle as status parameter.
540  *
541  * @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking
542  * cannot be used at the same time.
543  *
544  * @param handle UART handle pointer.
545  * @param data Start address of the data to write.
546  * @param length Size of the data to write.
547  * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
548  * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
549  * @retval kStatus_HAL_UartError An error occurred.
550  */
551 hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);
552 
553 /*!
554  * @brief Gets the number of bytes that have been received.
555  *
556  * This function gets the number of bytes that have been received.
557  *
558  * @param handle UART handle pointer.
559  * @param count Receive bytes count.
560  * @retval kStatus_HAL_UartError An error occurred.
561  * @retval kStatus_Success Get successfully through the parameter \p count.
562  */
563 hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
564 
565 /*!
566  * @brief Gets the number of bytes written to the UART TX register.
567  *
568  * This function gets the number of bytes written to the UART TX
569  * register by using the interrupt method.
570  *
571  * @param handle UART handle pointer.
572  * @param count Send bytes count.
573  * @retval kStatus_HAL_UartError An error occurred.
574  * @retval kStatus_Success Get successfully through the parameter \p count.
575  */
576 hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
577 
578 /*!
579  * @brief Aborts the interrupt-driven data receiving.
580  *
581  * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
582  * how many bytes are not received yet.
583  *
584  * @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of
585  * the function #HAL_UartReceiveBlocking.
586  *
587  * @param handle UART handle pointer.
588  * @retval kStatus_Success Get successfully abort the receiving.
589  */
590 hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle);
591 
592 /*!
593  * @brief Aborts the interrupt-driven data sending.
594  *
595  * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
596  * how many bytes are not sent out.
597  *
598  * @note The function #HAL_UartAbortSend cannot be used to abort the transmission of
599  * the function #HAL_UartSendBlocking.
600  *
601  * @param handle UART handle pointer.
602  * @retval kStatus_Success Get successfully abort the sending.
603  */
604 hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle);
605 
606 /*! @}*/
607 
608 #endif
609 #endif
610 
611 #if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))
612 
613 /*!
614  * @brief Initializes a UART dma instance with the UART dma handle and the user configuration structure.
615  *
616  * This function configures the UART dma module with user-defined settings. The user can configure the configuration
617  * structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_DMA_HANDLE_SIZE allocated
618  * by the caller. Example below shows how to use this API to configure the UART.
619  *  @code
620  *
621  *  Init TimerManager, only used in UART without Idleline interrupt
622  *  timer_config_t timerConfig;
623  *  timerConfig.srcClock_Hz    = 16000000;
624  *  timerConfig.instance       = 0;
625  *  TM_Init(&timerConfig);
626  *
627  *  Init the DMA module
628  *  DMA_Init(DMA0);
629  *
630  *  Define a uart dma handle
631  *  UART_HANDLE_DEFINE(g_uartHandle);
632  *  UART_DMA_HANDLE_DEFINE(g_UartDmaHandle);
633  *
634  *  Configure uart settings
635  *  hal_uart_config_t uartConfig;
636  *  uartConfig.srcClock_Hz  = 48000000;
637  *  uartConfig.baudRate_Bps = 115200;
638  *  uartConfig.parityMode   = kHAL_UartParityDisabled;
639  *  uartConfig.stopBitCount = kHAL_UartOneStopBit;
640  *  uartConfig.enableRx     = 1;
641  *  uartConfig.enableTx     = 1;
642  *  uartConfig.enableRxRTS  = 0;
643  *  uartConfig.enableTxCTS  = 0;
644  *  uartConfig.instance     = 0;
645  *
646  *  Init uart
647  *  HAL_UartInit((hal_uart_handle_t *)g_uartHandle, &uartConfig);
648  *
649  *  Configure uart dma settings
650  *  hal_uart_dma_config_t dmaConfig;
651  *  dmaConfig.uart_instance = 0;
652  *  dmaConfig.dma_instance  = 0;
653  *  dmaConfig.rx_channel    = 0;
654  *  dmaConfig.tx_channel    = 1;
655  *
656  *  Init uart dma
657  *  HAL_UartDMAInit((hal_uart_handle_t *)g_uartHandle, (hal_uart_dma_handle_t *)g_uartDmaHandle, &dmaConfig);
658  *  @endcode
659  *
660  * @param handle UART handle pointer.
661  * @param dmaHandle Pointer to point to a memory space of size #HAL_UART_DMA_HANDLE_SIZE allocated by the caller.
662  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
663  * You can define the handle in the following two ways:
664  * #UART_DMA_HANDLE_DEFINE(handle);
665  * or
666  * uint32_t handle[((HAL_UART_DMA_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
667  * @param dmaConfig Pointer to user-defined configuration structure.
668  * @retval kStatus_HAL_UartDmaError UART dma initialization failed.
669  * @retval kStatus_HAL_UartDmaSuccess UART dma initialization succeed.
670  */
671 hal_uart_dma_status_t HAL_UartDMAInit(hal_uart_handle_t handle,
672                                       hal_uart_dma_handle_t dmaHandle,
673                                       hal_uart_dma_config_t *dmaConfig);
674 
675 /*!
676  * @brief Deinitializes a UART DMA instance.
677  *
678  * This function will abort uart dma receive/send transfer and deinitialize UART.
679  *
680  * @param handle UART handle pointer.
681  * @retval kStatus_HAL_UartDmaSuccess UART DMA de-initialization succeed
682  */
683 hal_uart_dma_status_t HAL_UartDMADeinit(hal_uart_handle_t handle);
684 
685 /*!
686  * @brief Installs a callback and callback parameter.
687  *
688  * This function is used to install the callback and callback parameter for UART DMA module.
689  * When any status of the UART DMA changed, the driver will notify the upper layer by the installed callback
690  * function. And the status is also passed as status parameter when the callback is called.
691  *
692  * @param handle UART handle pointer.
693  * @param callback The callback function.
694  * @param callbackParam The parameter of the callback function.
695  * @retval kStatus_HAL_UartDmaSuccess Successfully install the callback.
696  */
697 hal_uart_dma_status_t HAL_UartDMATransferInstallCallback(hal_uart_handle_t handle,
698                                                          hal_uart_dma_transfer_callback_t callback,
699                                                          void *callbackParam);
700 
701 /*!
702  * @brief Receives a buffer of data using an dma method.
703  *
704  * This function receives data using an dma method. This is a non-blocking function, which
705  * returns directly without waiting for all data to be received.
706  * The receive request is saved by the UART DMA driver.
707  * When all data is received, the UART DMA adapter notifies the upper layer
708  * through a callback function and passes the status parameter @ref kStatus_HAL_UartDmaRxIdle.
709  *
710  * When an idleline is detected, the UART DMA adapter notifies the upper layer through a callback function,
711  * and passes the status parameter @ref kStatus_HAL_UartDmaIdleline. For the UARTs without hardware idleline
712  * interrupt(like usart), it will use a software idleline detection method with the help of TimerManager.
713  *
714  * When the soc support cache, uplayer should do cache maintain operations for transfer buffer before call this API.
715  *
716  * @param handle UART handle pointer.
717  * @param data data Start address of the buffer to store the received data.
718  * @param length Size of the buffer.
719  * @param receiveAll Idleline interrupt will not end transfer process if set true.
720  * @retval kStatus_HAL_UartDmaSuccess Successfully start the data receive.
721  * @retval kStatus_HAL_UartDmaRxBusy Previous receive request is not finished.
722  */
723 hal_uart_dma_status_t HAL_UartDMATransferReceive(hal_uart_handle_t handle,
724                                                  uint8_t *data,
725                                                  size_t length,
726                                                  bool receiveAll);
727 
728 /*!
729  * @brief Transmits a buffer of data using an dma method.
730  *
731  * This function sends data using an dma method. This is a non-blocking function, which
732  * returns directly without waiting for all data to be written to the TX register. When
733  * all data is written to the TX register by DMA, the UART DMA driver calls the callback
734  * function and passes the @ref kStatus_HAL_UartDmaTxIdle as status parameter.
735  *
736  * When the soc support cache, uplayer should do cache maintain operations for transfer buffer before call this API.
737  *
738  * @param handle UART handle pointer.
739  * @param data data Start address of the data to write.
740  * @param length Size of the data to write.
741  * @retval kStatus_HAL_UartDmaSuccess Successfully start the data transmission.
742  * @retval kStatus_HAL_UartDmaTxBusy Previous send request is not finished.
743  */
744 hal_uart_dma_status_t HAL_UartDMATransferSend(hal_uart_handle_t handle, uint8_t *data, size_t length);
745 
746 /*!
747  * @brief Gets the number of bytes that have been received.
748  *
749  * This function gets the number of bytes that have been received.
750  *
751  * @param handle UART handle pointer.
752  * @param reCount Receive bytes count.
753  * @retval kStatus_HAL_UartDmaError An error occurred.
754  * @retval kStatus_HAL_UartDmaSuccess Get successfully through the parameter \p reCount.
755  */
756 hal_uart_dma_status_t HAL_UartDMAGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);
757 
758 /*!
759  * @brief Gets the number of bytes written to the UART TX register.
760  *
761  * This function gets the number of bytes written to the UART TX
762  * register by using the DMA method.
763  *
764  * @param handle UART handle pointer.
765  * @param count Send bytes count.
766  * @retval kStatus_HAL_UartDmaError An error occurred.
767  * @retval kStatus_HAL_UartDmaSuccess Get successfully through the parameter \p seCount.
768  */
769 hal_uart_dma_status_t HAL_UartDMAGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);
770 
771 /*!
772  * @brief Aborts the DMA-driven data receiving.
773  *
774  * This function aborts the DMA-driven data receiving.
775  *
776  * @param handle UART handle pointer.
777  * @retval kStatus_HAL_UartDmaSuccess Get successfully abort the receiving.
778  */
779 hal_uart_dma_status_t HAL_UartDMAAbortReceive(hal_uart_handle_t handle);
780 
781 /*!
782  * @brief Aborts the DMA-driven data sending.
783  *
784  * This function aborts the DMA-driven data sending.
785  *
786  * @param handle UART handle pointer.
787  * @retval kStatus_Success Get successfully abort the sending.
788  */
789 hal_uart_dma_status_t HAL_UartDMAAbortSend(hal_uart_handle_t handle);
790 #endif /* HAL_UART_DMA_ENABLE */
791 
792 /*!
793  * @brief Prepares to enter low power consumption.
794  *
795  * This function is used to prepare to enter low power consumption.
796  *
797  * @param handle UART handle pointer.
798  * @retval kStatus_HAL_UartSuccess Successful operation.
799  * @retval kStatus_HAL_UartError An error occurred.
800  */
801 hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle);
802 
803 /*!
804  * @brief Restores from low power consumption.
805  *
806  * This function is used to restore from low power consumption.
807  *
808  * @param handle UART handle pointer.
809  * @retval kStatus_HAL_UartSuccess Successful operation.
810  * @retval kStatus_HAL_UartError An error occurred.
811  */
812 hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle);
813 
814 #if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
815 /*!
816  * @brief UART IRQ handle function.
817  *
818  * This function handles the UART transmit and receive IRQ request.
819  *
820  * @param handle UART handle pointer.
821  */
822 void HAL_UartIsrFunction(hal_uart_handle_t handle);
823 #endif
824 
825 #if defined(__cplusplus)
826 }
827 #endif
828 /*! @}*/
829 #endif /* __HAL_UART_ADAPTER_H__ */
830