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