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