1 /*
2  * Copyright 2018-2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __SERIAL_MANAGER_H__
10 #define __SERIAL_MANAGER_H__
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup serialmanager
16  * @{
17  */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 /*! @brief Enable or disable serial manager non-blocking mode (1 - enable, 0 - disable) */
23 #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
24 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE == 0U))
25 #error When SERIAL_MANAGER_NON_BLOCKING_MODE=0, DEBUG_CONSOLE_TRANSFER_NON_BLOCKING can not be set.
26 #else
27 #define SERIAL_MANAGER_NON_BLOCKING_MODE (1U)
28 #endif
29 #else
30 #ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
31 #define SERIAL_MANAGER_NON_BLOCKING_MODE (0U)
32 #endif
33 #endif
34 
35 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
36 /*! @brief Enable or disable serial manager dual(block and non-block) mode (1 - enable, 0 - disable) */
37 #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
38 #else
39 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
40 #ifndef SERIAL_MANAGER_NON_BLOCKING_DUAL_MODE
41 #define SERIAL_MANAGER_NON_BLOCKING_DUAL_MODE (1U)
42 #endif
43 #endif
44 #endif
45 #ifndef SERIAL_MANAGER_NON_BLOCKING_DUAL_MODE
46 #define SERIAL_MANAGER_NON_BLOCKING_DUAL_MODE (0U)
47 #endif
48 #endif
49 
50 /*! @brief Enable or disable uart port (1 - enable, 0 - disable) */
51 #ifndef SERIAL_PORT_TYPE_UART
52 #define SERIAL_PORT_TYPE_UART (0U)
53 #endif
54 
55 /*! @brief Enable or disable USB CDC port (1 - enable, 0 - disable) */
56 #ifndef SERIAL_PORT_TYPE_USBCDC
57 #define SERIAL_PORT_TYPE_USBCDC (0U)
58 #endif
59 
60 /*! @brief Enable or disable SWO port (1 - enable, 0 - disable) */
61 #ifndef SERIAL_PORT_TYPE_SWO
62 #define SERIAL_PORT_TYPE_SWO (0U)
63 #endif
64 
65 /*! @brief Enable or disable USB CDC virtual port (1 - enable, 0 - disable) */
66 #ifndef SERIAL_PORT_TYPE_VIRTUAL
67 #define SERIAL_PORT_TYPE_VIRTUAL (0U)
68 #endif
69 
70 /*! @brief Enable or disable rPMSG port (1 - enable, 0 - disable) */
71 #ifndef SERIAL_PORT_TYPE_RPMSG
72 #define SERIAL_PORT_TYPE_RPMSG (0U)
73 #endif
74 
75 /*! @brief Enable or disable SerialManager_Task() handle TX to prevent recursive calling */
76 #ifndef SERIAL_MANAGER_TASK_HANDLE_TX
77 #define SERIAL_MANAGER_TASK_HANDLE_TX (0U)
78 #endif
79 #if (defined(SERIAL_MANAGER_TASK_HANDLE_TX) && (SERIAL_MANAGER_TASK_HANDLE_TX > 0U))
80 #ifndef OSA_USED
81 #error When SERIAL_MANAGER_TASK_HANDLE_TX=1, OSA_USED must be set.
82 #endif
83 #endif
84 
85 /*! @brief Set the default delay time in ms used by SerialManager_WriteTimeDelay(). */
86 #ifndef SERIAL_MANAGER_WRITE_TIME_DELAY_DEFAULT_VALUE
87 #define SERIAL_MANAGER_WRITE_TIME_DELAY_DEFAULT_VALUE (1U)
88 #endif
89 
90 /*! @brief Set the default delay time in ms used by SerialManager_ReadTimeDelay(). */
91 #ifndef SERIAL_MANAGER_READ_TIME_DELAY_DEFAULT_VALUE
92 #define SERIAL_MANAGER_READ_TIME_DELAY_DEFAULT_VALUE (1U)
93 #endif
94 
95 /*! @brief Enable or disable SerialManager_Task() handle RX data available notify */
96 #ifndef SERIAL_MANAGER_TASK_HANDLE_RX_AVAILABLE_NOTIFY
97 #define SERIAL_MANAGER_TASK_HANDLE_RX_AVAILABLE_NOTIFY (0U)
98 #endif
99 #if (defined(SERIAL_MANAGER_TASK_HANDLE_RX_AVAILABLE_NOTIFY) && (SERIAL_MANAGER_TASK_HANDLE_RX_AVAILABLE_NOTIFY > 0U))
100 #ifndef OSA_USED
101 #error When SERIAL_MANAGER_TASK_HANDLE_RX_AVAILABLE_NOTIFY=1, OSA_USED must be set.
102 #endif
103 #endif
104 
105 /*! @brief Set serial manager write handle size */
106 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
107 #define SERIAL_MANAGER_WRITE_HANDLE_SIZE       (44U)
108 #define SERIAL_MANAGER_READ_HANDLE_SIZE        (44U)
109 #define SERIAL_MANAGER_WRITE_BLOCK_HANDLE_SIZE (4U)
110 #define SERIAL_MANAGER_READ_BLOCK_HANDLE_SIZE  (4U)
111 #else
112 #define SERIAL_MANAGER_WRITE_HANDLE_SIZE       (4U)
113 #define SERIAL_MANAGER_READ_HANDLE_SIZE        (4U)
114 #define SERIAL_MANAGER_WRITE_BLOCK_HANDLE_SIZE (4U)
115 #define SERIAL_MANAGER_READ_BLOCK_HANDLE_SIZE  (4U)
116 #endif
117 
118 #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
119 #include "fsl_component_serial_port_uart.h"
120 #endif
121 
122 #if (defined(SERIAL_PORT_TYPE_RPMSG) && (SERIAL_PORT_TYPE_RPMSG > 0U))
123 #include "fsl_component_serial_port_rpmsg.h"
124 #endif
125 
126 #if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
127 
128 #if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
129 #error The serial manager blocking mode cannot be supported for USB CDC.
130 #endif
131 
132 #include "fsl_component_serial_port_usb.h"
133 #endif
134 
135 #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
136 #include "fsl_component_serial_port_swo.h"
137 #endif
138 
139 #if (defined(SERIAL_PORT_TYPE_VIRTUAL) && (SERIAL_PORT_TYPE_VIRTUAL > 0U))
140 
141 #if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
142 #error The serial manager blocking mode cannot be supported for USB CDC.
143 #endif
144 
145 #include "fsl_component_serial_port_virtual.h"
146 #endif
147 
148 #define SERIAL_MANAGER_HANDLE_SIZE_TEMP 0U
149 #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
150 
151 #if (SERIAL_PORT_UART_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
152 #undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
153 #define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_UART_HANDLE_SIZE
154 #endif
155 
156 #endif
157 
158 #if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
159 
160 #if (SERIAL_PORT_USB_CDC_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
161 #undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
162 #define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_CDC_HANDLE_SIZE
163 #endif
164 
165 #endif
166 
167 #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
168 
169 #if (SERIAL_PORT_SWO_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
170 #undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
171 #define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_SWO_HANDLE_SIZE
172 #endif
173 
174 #endif
175 
176 #if (defined(SERIAL_PORT_TYPE_VIRTUAL) && (SERIAL_PORT_TYPE_VIRTUAL > 0U))
177 
178 #if (SERIAL_PORT_VIRTUAL_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
179 #undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
180 #define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_VIRTUAL_HANDLE_SIZE
181 #endif
182 
183 #endif
184 
185 #if (defined(SERIAL_PORT_TYPE_RPMSG) && (SERIAL_PORT_TYPE_RPMSG > 0U))
186 
187 #if (SERIAL_PORT_RPMSG_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
188 #undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
189 #define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_RPMSG_HANDLE_SIZE
190 
191 #endif
192 
193 #endif
194 
195 /*! @brief SERIAL_PORT_UART_HANDLE_SIZE/SERIAL_PORT_USB_CDC_HANDLE_SIZE + serial manager dedicated size */
196 #if ((defined(SERIAL_MANAGER_HANDLE_SIZE_TEMP) && (SERIAL_MANAGER_HANDLE_SIZE_TEMP > 0U)))
197 #else
198 #error SERIAL_PORT_TYPE_UART, SERIAL_PORT_TYPE_USBCDC, SERIAL_PORT_TYPE_SWO and SERIAL_PORT_TYPE_VIRTUAL should not be cleared at same time.
199 #endif
200 
201 #if defined(OSA_USED)
202 #include "fsl_component_common_task.h"
203 #endif
204 /*! @brief Macro to determine whether use common task. */
205 #ifndef SERIAL_MANAGER_USE_COMMON_TASK
206 #define SERIAL_MANAGER_USE_COMMON_TASK (0U)
207 #if (defined(COMMON_TASK_ENABLE) && (COMMON_TASK_ENABLE == 0U))
208 #undef SERIAL_MANAGER_USE_COMMON_TASK
209 #define SERIAL_MANAGER_USE_COMMON_TASK (0U)
210 #endif
211 #endif
212 
213 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
214 #if (defined(OSA_USED) && !(defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U)))
215 #include "fsl_os_abstraction.h"
216 #endif
217 #endif
218 
219 #if defined(OSA_USED)
220 #include "fsl_component_common_task.h"
221 #endif
222 /*! @brief Macro to determine whether use common task. */
223 #ifndef SERIAL_MANAGER_USE_COMMON_TASK
224 #define SERIAL_MANAGER_USE_COMMON_TASK (0U)
225 #if (defined(COMMON_TASK_ENABLE) && (COMMON_TASK_ENABLE == 0U))
226 #undef SERIAL_MANAGER_USE_COMMON_TASK
227 #define SERIAL_MANAGER_USE_COMMON_TASK (0U)
228 #endif
229 #endif
230 
231 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
232 #if (defined(OSA_USED) && !(defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U)))
233 #include "fsl_os_abstraction.h"
234 #endif
235 #endif
236 
237 /*! @brief Definition of serial manager handle size. */
238 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
239 #if (defined(OSA_USED) && !(defined(SERIAL_MANAGER_USE_COMMON_TASK) && (SERIAL_MANAGER_USE_COMMON_TASK > 0U)))
240 #define SERIAL_MANAGER_HANDLE_SIZE \
241     (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 124U + OSA_TASK_HANDLE_SIZE + OSA_EVENT_HANDLE_SIZE)
242 #else /*defined(OSA_USED)*/
243 #define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 124U)
244 #endif /*defined(OSA_USED)*/
245 #define SERIAL_MANAGER_BLOCK_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 16U)
246 #else
247 #define SERIAL_MANAGER_HANDLE_SIZE       (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 12U)
248 #define SERIAL_MANAGER_BLOCK_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 12U)
249 #endif
250 
251 /*!
252  * @brief Defines the serial manager handle
253  *
254  * This macro is used to define a 4 byte aligned serial manager handle.
255  * Then use "(serial_handle_t)name" to get the serial manager handle.
256  *
257  * The macro should be global and could be optional. You could also define serial manager handle by yourself.
258  *
259  * This is an example,
260  * @code
261  * SERIAL_MANAGER_HANDLE_DEFINE(serialManagerHandle);
262  * @endcode
263  *
264  * @param name The name string of the serial manager handle.
265  */
266 #define SERIAL_MANAGER_HANDLE_DEFINE(name) \
267     uint32_t name[((SERIAL_MANAGER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
268 #define SERIAL_MANAGER_BLOCK_HANDLE_DEFINE(name) \
269     uint32_t name[((SERIAL_MANAGER_BLOCK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
270 /*!
271  * @brief Defines the serial manager write handle
272  *
273  * This macro is used to define a 4 byte aligned serial manager write handle.
274  * Then use "(serial_write_handle_t)name" to get the serial manager write handle.
275  *
276  * The macro should be global and could be optional. You could also define serial manager write handle by yourself.
277  *
278  * This is an example,
279  * @code
280  * SERIAL_MANAGER_WRITE_HANDLE_DEFINE(serialManagerwriteHandle);
281  * @endcode
282  *
283  * @param name The name string of the serial manager write handle.
284  */
285 #define SERIAL_MANAGER_WRITE_HANDLE_DEFINE(name) \
286     uint32_t name[((SERIAL_MANAGER_WRITE_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
287 #define SERIAL_MANAGER_WRITE_BLOCK_HANDLE_DEFINE(name) \
288     uint32_t name[((SERIAL_MANAGER_WRITE_BLOCK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
289 /*!
290  * @brief Defines the serial manager read handle
291  *
292  * This macro is used to define a 4 byte aligned serial manager read handle.
293  * Then use "(serial_read_handle_t)name" to get the serial manager read handle.
294  *
295  * The macro should be global and could be optional. You could also define serial manager read handle by yourself.
296  *
297  * This is an example,
298  * @code
299  * SERIAL_MANAGER_READ_HANDLE_DEFINE(serialManagerReadHandle);
300  * @endcode
301  *
302  * @param name The name string of the serial manager read handle.
303  */
304 #define SERIAL_MANAGER_READ_HANDLE_DEFINE(name) \
305     uint32_t name[((SERIAL_MANAGER_READ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
306 #define SERIAL_MANAGER_READ_BLOCK_HANDLE_DEFINE(name) \
307     uint32_t name[((SERIAL_MANAGER_READ_BLOCK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
308 
309 /*! @brief Macro to set serial manager task priority. */
310 #ifndef SERIAL_MANAGER_TASK_PRIORITY
311 #define SERIAL_MANAGER_TASK_PRIORITY (2U)
312 #endif
313 
314 /*! @brief Macro to set serial manager task stack size. */
315 #ifndef SERIAL_MANAGER_TASK_STACK_SIZE
316 #define SERIAL_MANAGER_TASK_STACK_SIZE (1000U)
317 #endif
318 
319 /*! @brief The handle of the serial manager module */
320 typedef void *serial_handle_t;
321 
322 /*! @brief The write handle of the serial manager module */
323 typedef void *serial_write_handle_t;
324 
325 /*! @brief The read handle of the serial manager module */
326 typedef void *serial_read_handle_t;
327 
328 /*! @brief serial port type*/
329 typedef enum _serial_port_type
330 {
331     kSerialPort_Uart = 1U, /*!< Serial port UART */
332     kSerialPort_UsbCdc,    /*!< Serial port USB CDC */
333     kSerialPort_Swo,       /*!< Serial port SWO */
334     kSerialPort_Virtual,   /*!< Serial port Virtual */
335     kSerialPort_Rpmsg,     /*!< Serial port RPMSG */
336 } serial_port_type_t;
337 
338 /*! @brief serial manager type*/
339 typedef enum _serial_manager_type
340 {
341     kSerialManager_NonBlocking = 0x0U,    /*!< None blocking handle*/
342     kSerialManager_Blocking    = 0x8F41U, /*!< Blocking handle*/
343 } serial_manager_type_t;
344 /*! @brief serial manager config structure*/
345 typedef struct _serial_manager_config
346 {
347 #if defined(SERIAL_MANAGER_NON_BLOCKING_MODE)
348     uint8_t *ringBuffer;     /*!< Ring buffer address, it is used to buffer data received by the hardware.
349                                   Besides, the memory space cannot be free during the lifetime of the serial
350                                   manager module. */
351     uint32_t ringBufferSize; /*!< The size of the ring buffer */
352 #endif
353     serial_port_type_t type;         /*!< Serial port type */
354     serial_manager_type_t blockType; /*!< Serial manager port type */
355     void *portConfig;                /*!< Serial port configuration */
356 } serial_manager_config_t;
357 
358 /*! @brief serial manager error code*/
359 typedef enum _serial_manager_status
360 {
361     kStatus_SerialManager_Success = kStatus_Success,                            /*!< Success */
362     kStatus_SerialManager_Error   = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 1), /*!< Failed */
363     kStatus_SerialManager_Busy    = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 2), /*!< Busy */
364     kStatus_SerialManager_Notify  = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 3), /*!< Ring buffer is not empty */
365     kStatus_SerialManager_Canceled =
366         MAKE_STATUS(kStatusGroup_SERIALMANAGER, 4), /*!< the non-blocking request is canceled */
367     kStatus_SerialManager_HandleConflict = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 5), /*!< The handle is opened */
368     kStatus_SerialManager_RingBufferOverflow =
369         MAKE_STATUS(kStatusGroup_SERIALMANAGER, 6), /*!< The ring buffer is overflowed */
370     kStatus_SerialManager_NotConnected = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 7), /*!< The host is not connected */
371 } serial_manager_status_t;
372 
373 /*! @brief Callback message structure */
374 typedef struct _serial_manager_callback_message
375 {
376     uint8_t *buffer; /*!< Transferred buffer */
377     uint32_t length; /*!< Transferred data length */
378 } serial_manager_callback_message_t;
379 
380 /*! @brief callback function */
381 typedef void (*serial_manager_callback_t)(void *callbackParam,
382                                           serial_manager_callback_message_t *message,
383                                           serial_manager_status_t status);
384 
385 /*******************************************************************************
386  * API
387  ******************************************************************************/
388 
389 #if defined(__cplusplus)
390 extern "C" {
391 #endif /* _cplusplus */
392 
393 /*!
394  * @brief Initializes a serial manager module with the serial manager handle and the user configuration structure.
395  *
396  * This function configures the Serial Manager module with user-defined settings.
397  * The user can configure the configuration structure.
398  * The parameter serialHandle is a pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE
399  * allocated by the caller.
400  * The Serial Manager module supports three types of serial port, UART (includes UART, USART, LPSCI, LPUART, etc), USB
401  * CDC and swo.
402  * Please refer to #serial_port_type_t for serial port setting.
403  * These three types can be set by using #serial_manager_config_t.
404  *
405  * Example below shows how to use this API to configure the Serial Manager.
406  * For UART,
407  *  @code
408  *   #define SERIAL_MANAGER_RING_BUFFER_SIZE (256U)
409  *   static SERIAL_MANAGER_HANDLE_DEFINE(s_serialHandle);
410  *   static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
411  *
412  *   serial_manager_config_t config;
413  *   serial_port_uart_config_t uartConfig;
414  *   config.type = kSerialPort_Uart;
415  *   config.ringBuffer = &s_ringBuffer[0];
416  *   config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
417  *   uartConfig.instance = 0;
418  *   uartConfig.clockRate = 24000000;
419  *   uartConfig.baudRate = 115200;
420  *   uartConfig.parityMode = kSerialManager_UartParityDisabled;
421  *   uartConfig.stopBitCount = kSerialManager_UartOneStopBit;
422  *   uartConfig.enableRx = 1;
423  *   uartConfig.enableTx = 1;
424  *   uartConfig.enableRxRTS = 0;
425  *   uartConfig.enableTxCTS = 0;
426  *   config.portConfig = &uartConfig;
427  *   SerialManager_Init((serial_handle_t)s_serialHandle, &config);
428  *  @endcode
429  * For USB CDC,
430  *  @code
431  *   #define SERIAL_MANAGER_RING_BUFFER_SIZE (256U)
432  *   static SERIAL_MANAGER_HANDLE_DEFINE(s_serialHandle);
433  *   static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
434  *
435  *   serial_manager_config_t config;
436  *   serial_port_usb_cdc_config_t usbCdcConfig;
437  *   config.type = kSerialPort_UsbCdc;
438  *   config.ringBuffer = &s_ringBuffer[0];
439  *   config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
440  *   usbCdcConfig.controllerIndex = kSerialManager_UsbControllerKhci0;
441  *   config.portConfig = &usbCdcConfig;
442  *   SerialManager_Init((serial_handle_t)s_serialHandle, &config);
443  *  @endcode
444  *
445  * @param serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the caller.
446  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
447  * You can define the handle in the following two ways:
448  * #SERIAL_MANAGER_HANDLE_DEFINE(serialHandle);
449  * or
450  * uint32_t serialHandle[((SERIAL_MANAGER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
451  * @param config Pointer to user-defined configuration structure.
452  * @retval kStatus_SerialManager_Error An error occurred.
453  * @retval kStatus_SerialManager_Success The Serial Manager module initialization succeed.
454  */
455 serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, const serial_manager_config_t *config);
456 
457 /*!
458  * @brief De-initializes the serial manager module instance.
459  *
460  * This function de-initializes the serial manager module instance. If the opened writing or
461  * reading handle is not closed, the function will return kStatus_SerialManager_Busy.
462  *
463  * @param serialHandle The serial manager module handle pointer.
464  * @retval kStatus_SerialManager_Success The serial manager de-initialization succeed.
465  * @retval kStatus_SerialManager_Busy Opened reading or writing handle is not closed.
466  */
467 serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle);
468 
469 /*!
470  * @brief Opens a writing handle for the serial manager module.
471  *
472  * This function Opens a writing handle for the serial manager module. If the serial manager needs to
473  * be used in different tasks, the task should open a dedicated write handle for itself by calling
474  * #SerialManager_OpenWriteHandle. Since there can only one buffer for transmission for the writing
475  * handle at the same time, multiple writing handles need to be opened when the multiple transmission
476  * is needed for a task.
477  *
478  * @param serialHandle The serial manager module handle pointer.
479  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
480  * @param writeHandle The serial manager module writing handle pointer.
481  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
482  * You can define the handle in the following two ways:
483  * #SERIAL_MANAGER_WRITE_HANDLE_DEFINE(writeHandle);
484  * or
485  * uint32_t writeHandle[((SERIAL_MANAGER_WRITE_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
486  * @retval kStatus_SerialManager_Error An error occurred.
487  * @retval kStatus_SerialManager_HandleConflict The writing handle was opened.
488  * @retval kStatus_SerialManager_Success The writing handle is opened.
489  *
490  * Example below shows how to use this API to write data.
491  * For task 1,
492  *  @code
493  *   static SERIAL_MANAGER_WRITE_HANDLE_DEFINE(s_serialWriteHandle1);
494  *   static uint8_t s_nonBlockingWelcome1[] = "This is non-blocking writing log for task1!\r\n";
495  *   SerialManager_OpenWriteHandle((serial_handle_t)serialHandle, (serial_write_handle_t)s_serialWriteHandle1);
496  *   SerialManager_InstallTxCallback((serial_write_handle_t)s_serialWriteHandle1,
497  *                                    Task1_SerialManagerTxCallback,
498  *                                    s_serialWriteHandle1);
499  *   SerialManager_WriteNonBlocking((serial_write_handle_t)s_serialWriteHandle1,
500  *                                   s_nonBlockingWelcome1,
501  *                                   sizeof(s_nonBlockingWelcome1) - 1U);
502  *  @endcode
503  * For task 2,
504  *  @code
505  *   static SERIAL_MANAGER_WRITE_HANDLE_DEFINE(s_serialWriteHandle2);
506  *   static uint8_t s_nonBlockingWelcome2[] = "This is non-blocking writing log for task2!\r\n";
507  *   SerialManager_OpenWriteHandle((serial_handle_t)serialHandle, (serial_write_handle_t)s_serialWriteHandle2);
508  *   SerialManager_InstallTxCallback((serial_write_handle_t)s_serialWriteHandle2,
509  *                                    Task2_SerialManagerTxCallback,
510  *                                    s_serialWriteHandle2);
511  *   SerialManager_WriteNonBlocking((serial_write_handle_t)s_serialWriteHandle2,
512  *                                   s_nonBlockingWelcome2,
513  *                                   sizeof(s_nonBlockingWelcome2) - 1U);
514  *  @endcode
515  */
516 serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle);
517 
518 /*!
519  * @brief Closes a writing handle for the serial manager module.
520  *
521  * This function Closes a writing handle for the serial manager module.
522  *
523  * @param writeHandle The serial manager module writing handle pointer.
524  * @retval kStatus_SerialManager_Success The writing handle is closed.
525  */
526 serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle);
527 
528 /*!
529  * @brief Opens a reading handle for the serial manager module.
530  *
531  * This function Opens a reading handle for the serial manager module. The reading handle can not be
532  * opened multiple at the same time. The error code kStatus_SerialManager_Busy would be returned when
533  * the previous reading handle is not closed. And there can only be one buffer for receiving for the
534  * reading handle at the same time.
535  *
536  * @param serialHandle The serial manager module handle pointer.
537  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
538  * @param readHandle The serial manager module reading handle pointer.
539  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
540  * You can define the handle in the following two ways:
541  * #SERIAL_MANAGER_READ_HANDLE_DEFINE(readHandle);
542  * or
543  * uint32_t readHandle[((SERIAL_MANAGER_READ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
544  * @retval kStatus_SerialManager_Error An error occurred.
545  * @retval kStatus_SerialManager_Success The reading handle is opened.
546  * @retval kStatus_SerialManager_Busy Previous reading handle is not closed.
547  *
548  * Example below shows how to use this API to read data.
549  *  @code
550  *   static SERIAL_MANAGER_READ_HANDLE_DEFINE(s_serialReadHandle);
551  *   SerialManager_OpenReadHandle((serial_handle_t)serialHandle, (serial_read_handle_t)s_serialReadHandle);
552  *   static uint8_t s_nonBlockingBuffer[64];
553  *   SerialManager_InstallRxCallback((serial_read_handle_t)s_serialReadHandle,
554  *                                    APP_SerialManagerRxCallback,
555  *                                    s_serialReadHandle);
556  *   SerialManager_ReadNonBlocking((serial_read_handle_t)s_serialReadHandle,
557  *                                  s_nonBlockingBuffer,
558  *                                  sizeof(s_nonBlockingBuffer));
559  *  @endcode
560  */
561 serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle);
562 
563 /*!
564  * @brief Closes a reading for the serial manager module.
565  *
566  * This function Closes a reading for the serial manager module.
567  *
568  * @param readHandle The serial manager module reading handle pointer.
569  * @retval kStatus_SerialManager_Success The reading handle is closed.
570  */
571 serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle);
572 
573 /*!
574  * @brief Transmits data with the blocking mode.
575  *
576  * This is a blocking function, which polls the sending queue, waits for the sending queue to be empty.
577  * This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
578  * And There can only one buffer for transmission for the writing handle at the same time.
579  *
580  * @note The function #SerialManager_WriteBlocking and the function SerialManager_WriteNonBlocking
581  * cannot be used at the same time.
582  * And, the function SerialManager_CancelWriting cannot be used to abort the transmission of this function.
583  *
584  * @param writeHandle The serial manager module handle pointer.
585  * @param buffer Start address of the data to write.
586  * @param length Length of the data to write.
587  * @retval kStatus_SerialManager_Success Successfully sent all data.
588  * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
589  * @retval kStatus_SerialManager_Error An error occurred.
590  */
591 serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle,
592                                                     uint8_t *buffer,
593                                                     uint32_t length);
594 
595 /*!
596  * @brief Reads data with the blocking mode.
597  *
598  * This is a blocking function, which polls the receiving buffer, waits for the receiving buffer to be full.
599  * This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
600  * And There can only one buffer for receiving for the reading handle at the same time.
601  *
602  * @note The function #SerialManager_ReadBlocking and the function SerialManager_ReadNonBlocking
603  * cannot be used at the same time.
604  * And, the function SerialManager_CancelReading cannot be used to abort the transmission of this function.
605  *
606  * @param readHandle The serial manager module handle pointer.
607  * @param buffer Start address of the data to store the received data.
608  * @param length The length of the data to be received.
609  * @retval kStatus_SerialManager_Success Successfully received all data.
610  * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
611  * @retval kStatus_SerialManager_Error An error occurred.
612  */
613 serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length);
614 
615 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
616 /*!
617  * @brief Transmits data with the non-blocking mode.
618  *
619  * This is a non-blocking function, which returns directly without waiting for all data to be sent.
620  * When all data is sent, the module notifies the upper layer through a TX callback function and passes
621  * the status parameter @ref kStatus_SerialManager_Success.
622  * This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
623  * And There can only one buffer for transmission for the writing handle at the same time.
624  *
625  * @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
626  * cannot be used at the same time. And, the TX callback is mandatory before the function could be used.
627  *
628  * @param writeHandle The serial manager module handle pointer.
629  * @param buffer Start address of the data to write.
630  * @param length Length of the data to write.
631  * @retval kStatus_SerialManager_Success Successfully sent all data.
632  * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
633  * @retval kStatus_SerialManager_Error An error occurred.
634  */
635 serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
636                                                        uint8_t *buffer,
637                                                        uint32_t length);
638 
639 /*!
640  * @brief Reads data with the non-blocking mode.
641  *
642  * This is a non-blocking function, which returns directly without waiting for all data to be received.
643  * When all data is received, the module driver notifies the upper layer
644  * through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Success.
645  * This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
646  * And There can only one buffer for receiving for the reading handle at the same time.
647  *
648  * @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
649  * cannot be used at the same time. And, the RX callback is mandatory before the function could be used.
650  *
651  * @param readHandle The serial manager module handle pointer.
652  * @param buffer Start address of the data to store the received data.
653  * @param length The length of the data to be received.
654  * @retval kStatus_SerialManager_Success Successfully received all data.
655  * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
656  * @retval kStatus_SerialManager_Error An error occurred.
657  */
658 serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle,
659                                                       uint8_t *buffer,
660                                                       uint32_t length);
661 
662 /*!
663  * @brief Tries to read data.
664  *
665  * The function tries to read data from internal ring buffer. If the ring buffer is not empty, the data will be
666  * copied from ring buffer to up layer buffer. The copied length is the minimum of the ring buffer and up layer length.
667  * After the data is copied, the actual data length is passed by the parameter length.
668  * And There can only one buffer for receiving for the reading handle at the same time.
669  *
670  * @param readHandle The serial manager module handle pointer.
671  * @param buffer Start address of the data to store the received data.
672  * @param length The length of the data to be received.
673  * @param receivedLength Length received from the ring buffer directly.
674  * @retval kStatus_SerialManager_Success Successfully received all data.
675  * @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
676  * @retval kStatus_SerialManager_Error An error occurred.
677  */
678 serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
679                                               uint8_t *buffer,
680                                               uint32_t length,
681                                               uint32_t *receivedLength);
682 
683 /*!
684  * @brief Cancels unfinished send transmission.
685  *
686  * The function cancels unfinished send transmission. When the transfer is canceled, the module notifies the upper layer
687  * through a TX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
688  *
689  * @note The function #SerialManager_CancelWriting cannot be used to abort the transmission of
690  * the function #SerialManager_WriteBlocking.
691  *
692  * @param writeHandle The serial manager module handle pointer.
693  * @retval kStatus_SerialManager_Success Get successfully abort the sending.
694  * @retval kStatus_SerialManager_Error An error occurred.
695  */
696 serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle);
697 
698 /*!
699  * @brief Cancels unfinished receive transmission.
700  *
701  * The function cancels unfinished receive transmission. When the transfer is canceled, the module notifies the upper
702  * layer
703  * through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
704  *
705  * @note The function #SerialManager_CancelReading cannot be used to abort the transmission of
706  * the function #SerialManager_ReadBlocking.
707  *
708  * @param readHandle The serial manager module handle pointer.
709  * @retval kStatus_SerialManager_Success Get successfully abort the receiving.
710  * @retval kStatus_SerialManager_Error An error occurred.
711  */
712 serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle);
713 
714 /*!
715  * @brief Installs a TX callback and callback parameter.
716  *
717  * This function is used to install the TX callback and callback parameter for the serial manager module.
718  * When any status of TX transmission changed, the driver will notify the upper layer by the installed callback
719  * function. And the status is also passed as status parameter when the callback is called.
720  *
721  * @param writeHandle The serial manager module handle pointer.
722  * @param callback The callback function.
723  * @param callbackParam The parameter of the callback function.
724  * @retval kStatus_SerialManager_Success Successfully install the callback.
725  */
726 serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
727                                                         serial_manager_callback_t callback,
728                                                         void *callbackParam);
729 
730 /*!
731  * @brief Installs a RX callback and callback parameter.
732  *
733  * This function is used to install the RX callback and callback parameter for the serial manager module.
734  * When any status of RX transmission changed, the driver will notify the upper layer by the installed callback
735  * function. And the status is also passed as status parameter when the callback is called.
736  *
737  * @param readHandle The serial manager module handle pointer.
738  * @param callback The callback function.
739  * @param callbackParam The parameter of the callback function.
740  * @retval kStatus_SerialManager_Success Successfully install the callback.
741  */
742 serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
743                                                         serial_manager_callback_t callback,
744                                                         void *callbackParam);
745 
746 #endif
747 
748 /*!
749  * @brief Prepares to enter low power consumption.
750  *
751  * This function is used to prepare to enter low power consumption.
752  *
753  * @param serialHandle The serial manager module handle pointer.
754  * @retval kStatus_SerialManager_Success Successful operation.
755  */
756 serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle);
757 
758 /*!
759  * @brief Restores from low power consumption.
760  *
761  * This function is used to restore from low power consumption.
762  *
763  * @param serialHandle The serial manager module handle pointer.
764  * @retval kStatus_SerialManager_Success Successful operation.
765  */
766 serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle);
767 
768 #if defined(__cplusplus)
769 }
770 #endif
771 /*! @} */
772 #endif /* __SERIAL_MANAGER_H__ */
773