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