1 /*
2 * Copyright 2019 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_common.h"
9 #include "fsl_component_serial_manager.h"
10 #include "fsl_component_serial_port_internal.h"
11
12 #if (defined(SERIAL_PORT_TYPE_VIRTUAL) && (SERIAL_PORT_TYPE_VIRTUAL > 0U))
13
14 #include "fsl_component_serial_port_virtual.h"
15
16 /*******************************************************************************
17 * Definitions
18 ******************************************************************************/
19
20 #ifndef NDEBUG
21 #if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
22 #undef assert
23 #define assert(n)
24 #else
25 /* MISRA C-2012 Rule 17.2 */
26 #undef assert
27 #define assert(n) \
28 while (!(n)) \
29 { \
30 ; \
31 }
32 #endif
33 #endif
34
35 /* Weak function. */
36 #if defined(__GNUC__)
37 #define __WEAK_FUNC __attribute__((weak))
38 #elif defined(__ICCARM__)
39 #define __WEAK_FUNC __weak
40 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
41 #define __WEAK_FUNC __attribute__((weak))
42 #endif
43
44 typedef struct _serial_port_virtual_send_state
45 {
46 serial_manager_callback_t callback;
47 void *callbackParam;
48 } serial_port_virtual_send_state_t;
49
50 typedef struct _serial_port_virtual_recv_state
51 {
52 serial_manager_callback_t callback;
53 void *callbackParam;
54 } serial_port_virtual_recv_state_t;
55
56 /* Define the types for application */
57 typedef struct _serial_port_virtual_state
58 {
59 struct _serial_port_virtual_state *next; /* Next pointer of the interface */
60 serial_port_virtual_send_state_t tx;
61 serial_port_virtual_recv_state_t rx;
62 uint8_t instance; /* The instance of the interface */
63 } serial_port_virtual_state_t;
64
65 /*******************************************************************************
66 * Prototypes
67 ******************************************************************************/
68
69 /*******************************************************************************
70 * Variables
71 ******************************************************************************/
72
73 static serial_port_virtual_state_t *s_serialPortVirtualHead;
74
75 /*******************************************************************************
76 * Code
77 ******************************************************************************/
78
Serial_PortVirtualAddItem(serial_port_virtual_state_t ** head,serial_port_virtual_state_t * node)79 static serial_manager_status_t Serial_PortVirtualAddItem(serial_port_virtual_state_t **head,
80 serial_port_virtual_state_t *node)
81 {
82 serial_port_virtual_state_t *p = *head;
83 uint32_t regPrimask;
84
85 regPrimask = DisableGlobalIRQ();
86
87 if (NULL == p)
88 {
89 *head = node;
90 }
91 else
92 {
93 while (NULL != p->next)
94 {
95 if (p == node)
96 {
97 EnableGlobalIRQ(regPrimask);
98 return kStatus_SerialManager_Error;
99 }
100 p = p->next;
101 }
102
103 p->next = node;
104 }
105 node->next = NULL;
106 EnableGlobalIRQ(regPrimask);
107 return kStatus_SerialManager_Success;
108 }
109
Serial_PortVirtualRemoveItem(serial_port_virtual_state_t ** head,serial_port_virtual_state_t * node)110 static serial_manager_status_t Serial_PortVirtualRemoveItem(serial_port_virtual_state_t **head,
111 serial_port_virtual_state_t *node)
112 {
113 serial_port_virtual_state_t *p = *head;
114 serial_port_virtual_state_t *q = NULL;
115 uint32_t regPrimask;
116
117 regPrimask = DisableGlobalIRQ();
118 while (NULL != p)
119 {
120 if (p == node)
121 {
122 if (NULL == q)
123 {
124 *head = p->next;
125 }
126 else
127 {
128 q->next = p->next;
129 }
130 break;
131 }
132 else
133 {
134 q = p;
135 p = p->next;
136 }
137 }
138 EnableGlobalIRQ(regPrimask);
139 return kStatus_SerialManager_Success;
140 }
141
Serial_PortVirtualGetInstance(uint8_t controller,serial_port_virtual_state_t ** handle)142 static serial_manager_status_t Serial_PortVirtualGetInstance(uint8_t controller, serial_port_virtual_state_t **handle)
143 {
144 serial_port_virtual_state_t *p = s_serialPortVirtualHead;
145 uint32_t regPrimask;
146
147 *handle = NULL;
148 regPrimask = DisableGlobalIRQ();
149 while (NULL != p)
150 {
151 if (p->instance == controller)
152 {
153 *handle = p;
154 break;
155 }
156 }
157 EnableGlobalIRQ(regPrimask);
158 return (NULL != p) ? kStatus_SerialManager_Success : kStatus_SerialManager_Error;
159 }
160
Serial_PortVirtualTxCallback(void * callbackParam,serial_manager_callback_message_t * message,serial_manager_status_t status)161 static void Serial_PortVirtualTxCallback(void *callbackParam,
162 serial_manager_callback_message_t *message,
163 serial_manager_status_t status)
164 {
165 serial_port_virtual_state_t *serialPortVirtual;
166
167 if (NULL != callbackParam)
168 {
169 serialPortVirtual = (serial_port_virtual_state_t *)callbackParam;
170 if (NULL != serialPortVirtual->tx.callback)
171 {
172 serialPortVirtual->tx.callback(serialPortVirtual->tx.callbackParam, message, status);
173 }
174 }
175 }
176
Serial_PortVirtualRxCallback(void * callbackParam,serial_manager_callback_message_t * message,serial_manager_status_t status)177 static void Serial_PortVirtualRxCallback(void *callbackParam,
178 serial_manager_callback_message_t *message,
179 serial_manager_status_t status)
180 {
181 serial_port_virtual_state_t *serialPortVirtual;
182
183 if (NULL != callbackParam)
184 {
185 serialPortVirtual = (serial_port_virtual_state_t *)callbackParam;
186 if (NULL != serialPortVirtual->rx.callback)
187 {
188 serialPortVirtual->rx.callback(serialPortVirtual->rx.callbackParam, message, status);
189 }
190 }
191 }
192
193 __WEAK_FUNC status_t USB_DeviceVcomInit(uint8_t controller);
USB_DeviceVcomInit(uint8_t controller)194 __WEAK_FUNC status_t USB_DeviceVcomInit(uint8_t controller)
195 {
196 return kStatus_Success;
197 }
198
199 __WEAK_FUNC status_t USB_DeviceVcomDeinit(uint8_t controller);
USB_DeviceVcomDeinit(uint8_t controller)200 __WEAK_FUNC status_t USB_DeviceVcomDeinit(uint8_t controller)
201 {
202 return kStatus_Success;
203 }
204
205 __WEAK_FUNC status_t USB_DeviceVcomWrite(uint8_t controller, uint8_t *buffer, uint32_t length);
USB_DeviceVcomWrite(uint8_t controller,uint8_t * buffer,uint32_t length)206 __WEAK_FUNC status_t USB_DeviceVcomWrite(uint8_t controller, uint8_t *buffer, uint32_t length)
207 {
208 serial_port_virtual_state_t *serialPortVirtual;
209 serial_manager_callback_message_t msg;
210
211 if (kStatus_SerialManager_Success != Serial_PortVirtualGetInstance(controller, &serialPortVirtual))
212 {
213 return kStatus_Fail;
214 }
215
216 if ((NULL != serialPortVirtual->tx.callback))
217 {
218 msg.buffer = buffer;
219 msg.length = length;
220 serialPortVirtual->tx.callback(serialPortVirtual->tx.callbackParam, &msg, kStatus_SerialManager_Success);
221 }
222 return kStatus_Success;
223 }
224
225 __WEAK_FUNC status_t USB_DeviceVcomRead(uint8_t controller, uint8_t *buffer, uint32_t length);
USB_DeviceVcomRead(uint8_t controller,uint8_t * buffer,uint32_t length)226 __WEAK_FUNC status_t USB_DeviceVcomRead(uint8_t controller, uint8_t *buffer, uint32_t length)
227 {
228 return kStatus_Fail;
229 }
230
231 __WEAK_FUNC status_t USB_DeviceVcomCancelWrite(uint8_t controller);
USB_DeviceVcomCancelWrite(uint8_t controller)232 __WEAK_FUNC status_t USB_DeviceVcomCancelWrite(uint8_t controller)
233 {
234 return kStatus_Success;
235 }
236
237 __WEAK_FUNC status_t USB_DeviceVcomInstallTxCallback(uint8_t controller,
238 serial_manager_callback_t callback,
239 void *callbackParam);
USB_DeviceVcomInstallTxCallback(uint8_t controller,serial_manager_callback_t callback,void * callbackParam)240 __WEAK_FUNC status_t USB_DeviceVcomInstallTxCallback(uint8_t controller,
241 serial_manager_callback_t callback,
242 void *callbackParam)
243 {
244 return kStatus_Success;
245 }
246
247 __WEAK_FUNC status_t USB_DeviceVcomInstallRxCallback(uint8_t controller,
248 serial_manager_callback_t callback,
249 void *callbackParam);
USB_DeviceVcomInstallRxCallback(uint8_t controller,serial_manager_callback_t callback,void * callbackParam)250 __WEAK_FUNC status_t USB_DeviceVcomInstallRxCallback(uint8_t controller,
251 serial_manager_callback_t callback,
252 void *callbackParam)
253 {
254 return kStatus_Success;
255 }
256
257 __WEAK_FUNC void USB_DeviceVcomIsrFunction(uint8_t controller);
USB_DeviceVcomIsrFunction(uint8_t controller)258 __WEAK_FUNC void USB_DeviceVcomIsrFunction(uint8_t controller)
259 {
260 }
261
Serial_PortVirtualInit(serial_handle_t serialHandle,void * config)262 serial_manager_status_t Serial_PortVirtualInit(serial_handle_t serialHandle, void *config)
263 {
264 serial_port_virtual_state_t *serialPortVirtual;
265 serial_port_virtual_config_t *serialPortVirtualConfig;
266 serial_manager_status_t ret;
267
268 assert(NULL != config);
269 assert(NULL != serialHandle);
270 assert(SERIAL_PORT_VIRTUAL_HANDLE_SIZE >= sizeof(serial_port_virtual_state_t));
271
272 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
273 serialPortVirtualConfig = (serial_port_virtual_config_t *)config;
274
275 serialPortVirtual->instance = (uint8_t)serialPortVirtualConfig->controllerIndex;
276
277 if ((status_t)kStatus_Success != USB_DeviceVcomInit((uint8_t)serialPortVirtualConfig->controllerIndex))
278 {
279 return kStatus_SerialManager_Error;
280 }
281
282 ret = Serial_PortVirtualAddItem(&s_serialPortVirtualHead, serialPortVirtual);
283
284 if (kStatus_SerialManager_Success != ret)
285 {
286 return ret;
287 }
288
289 return kStatus_SerialManager_Success;
290 }
291
Serial_PortVirtualDeinit(serial_handle_t serialHandle)292 serial_manager_status_t Serial_PortVirtualDeinit(serial_handle_t serialHandle)
293 {
294 serial_port_virtual_state_t *serialPortVirtual;
295
296 assert(serialHandle);
297
298 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
299
300 (void)USB_DeviceVcomDeinit(serialPortVirtual->instance);
301
302 (void)Serial_PortVirtualRemoveItem(&s_serialPortVirtualHead, serialPortVirtual);
303
304 return kStatus_SerialManager_Success;
305 }
306
Serial_PortVirtualWrite(serial_handle_t serialHandle,uint8_t * buffer,uint32_t length)307 serial_manager_status_t Serial_PortVirtualWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
308 {
309 serial_port_virtual_state_t *serialPortVirtual;
310
311 assert(serialHandle);
312
313 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
314
315 if (kStatus_Success != USB_DeviceVcomWrite(serialPortVirtual->instance, buffer, length))
316 {
317 return kStatus_SerialManager_Error;
318 }
319
320 return kStatus_SerialManager_Success;
321 }
322
Serial_PortVirtualRead(serial_handle_t serialHandle,uint8_t * buffer,uint32_t length)323 serial_manager_status_t Serial_PortVirtualRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
324 {
325 serial_port_virtual_state_t *serialPortVirtual;
326
327 assert(serialHandle);
328
329 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
330
331 if (kStatus_Success != USB_DeviceVcomRead(serialPortVirtual->instance, buffer, length))
332 {
333 return kStatus_SerialManager_Error;
334 }
335
336 return kStatus_SerialManager_Success;
337 }
338
Serial_PortVirtualCancelWrite(serial_handle_t serialHandle)339 serial_manager_status_t Serial_PortVirtualCancelWrite(serial_handle_t serialHandle)
340 {
341 serial_port_virtual_state_t *serialPortVirtual;
342
343 assert(serialHandle);
344
345 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
346
347 if (kStatus_Success != USB_DeviceVcomCancelWrite(serialPortVirtual->instance))
348 {
349 return kStatus_SerialManager_Error;
350 }
351
352 return kStatus_SerialManager_Success;
353 }
354
Serial_PortVirtualInstallTxCallback(serial_handle_t serialHandle,serial_manager_callback_t callback,void * callbackParam)355 serial_manager_status_t Serial_PortVirtualInstallTxCallback(serial_handle_t serialHandle,
356 serial_manager_callback_t callback,
357 void *callbackParam)
358 {
359 serial_port_virtual_state_t *serialPortVirtual;
360
361 assert(serialHandle);
362
363 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
364
365 serialPortVirtual->tx.callback = callback;
366 serialPortVirtual->tx.callbackParam = callbackParam;
367
368 return (serial_manager_status_t)USB_DeviceVcomInstallTxCallback(serialPortVirtual->instance,
369 Serial_PortVirtualTxCallback, serialHandle);
370 }
371
Serial_PortVirtualInstallRxCallback(serial_handle_t serialHandle,serial_manager_callback_t callback,void * callbackParam)372 serial_manager_status_t Serial_PortVirtualInstallRxCallback(serial_handle_t serialHandle,
373 serial_manager_callback_t callback,
374 void *callbackParam)
375 {
376 serial_port_virtual_state_t *serialPortVirtual;
377
378 assert(serialHandle);
379
380 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
381
382 serialPortVirtual->rx.callback = callback;
383 serialPortVirtual->rx.callbackParam = callbackParam;
384
385 return (serial_manager_status_t)USB_DeviceVcomInstallRxCallback(serialPortVirtual->instance,
386 Serial_PortVirtualRxCallback, serialHandle);
387 }
388
Serial_PortVirtualIsrFunction(serial_handle_t serialHandle)389 void Serial_PortVirtualIsrFunction(serial_handle_t serialHandle)
390 {
391 serial_port_virtual_state_t *serialPortVirtual;
392
393 assert(serialHandle);
394
395 serialPortVirtual = (serial_port_virtual_state_t *)serialHandle;
396
397 USB_DeviceVcomIsrFunction(serialPortVirtual->instance);
398 }
399
400 #endif /* SERIAL_PORT_TYPE_VIRTUAL */
401