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