2 * The Clear BSD License
3 * Copyright (c) 2015, Freescale Semiconductor, Inc.
4 * Copyright 2016-2017 NXP
7 * Redistribution and use in source and binary forms, with or without modification,
8 * are permitted (subject to the limitations in the disclaimer below) provided
9 * that the following conditions are met:
11 * o Redistributions of source code must retain the above copyright notice, this list
12 * of conditions and the following disclaimer.
14 * o Redistributions in binary form must reproduce the above copyright notice, this
15 * list of conditions and the following disclaimer in the documentation and/or
16 * other materials provided with the distribution.
18 * o Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
22 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "fsl_device_registers.h"
39 #include "usb_device_config.h"
41 #include "usb_device.h"
43 #include "usb_device_cdc_acm.h"
44 #include "usb_device_ch9.h"
46 #include "usb_device_descriptor.h"
47 #include "virtual_com.h"
48 #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
49 #include "fsl_sysmpu.h"
50 #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
51 #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
57 /* Provided by users. */
58 extern void USB_DeviceClockInit(void);
59 extern void USB_DeviceIsrEnable(void);
60 /*******************************************************************************
62 ******************************************************************************/
64 /*******************************************************************************
66 ******************************************************************************/
68 static uint8_t cdc_rx_buf_space[1024];
70 static struct ringbuf cdc_rx_buf =
71 RINGBUF_INIT (cdc_rx_buf_space, sizeof (cdc_rx_buf_space));
73 /* Data structure of virtual com device */
74 usb_cdc_vcom_struct_t s_cdcVcom;
76 /* Line codinig of cdc device */
77 static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
78 /* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
79 (LINE_CODING_DTERATE >> 0U) & 0x000000FFU,
80 (LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
81 (LINE_CODING_DTERATE >> 16U) & 0x000000FFU,
82 (LINE_CODING_DTERATE >> 24U) & 0x000000FFU,
83 LINE_CODING_CHARFORMAT,
84 LINE_CODING_PARITYTYPE,
85 LINE_CODING_DATABITS};
87 /* Abstract state of cdc device */
88 static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
89 (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
91 /* Country code of cdc device */
92 static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
93 (COUNTRY_SETTING >> 8U) & 0x00FFU};
95 /* CDC ACM information */
96 static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0};
98 /* Data buffer for receiving and sending*/
99 static uint8_t s_currRecvBuf[DATA_BUFF_SIZE];
100 volatile static uint32_t s_recvSize = 0;
101 volatile static uint32_t s_sendSize = 0;
102 volatile static uint8_t s_sendComplete = 0;
103 volatile static uint8_t s_currRecvIndex = 0;
104 static uint32_t s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
105 /*******************************************************************************
107 ******************************************************************************/
109 /*******************************************************************************
111 ******************************************************************************/
113 * @brief Interrupt in pipe callback function.
115 * This function serves as the callback function for interrupt in pipe.
117 * @param handle The USB device handle.
118 * @param message The endpoint callback message
119 * @param callbackParam The parameter of the callback.
121 * @return A USB error code or kStatus_USB_Success.
123 usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle,
124 usb_device_endpoint_callback_message_struct_t *message,
127 usb_status_t error = kStatus_USB_Error;
133 * @brief Bulk in pipe callback function.
135 * This function serves as the callback function for bulk in pipe.
137 * @param handle The USB device handle.
138 * @param message The endpoint callback message
139 * @param callbackParam The parameter of the callback.
141 * @return A USB error code or kStatus_USB_Success.
143 usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
144 usb_device_endpoint_callback_message_struct_t *message,
147 usb_status_t error = kStatus_USB_Error;
149 if ((message->length != 0) && (!(message->length % s_usbBulkMaxPacketSize)))
151 /* If the last packet is the size of endpoint, then send also zero-ended packet,
152 ** meaning that we want to inform the host that we do not have any additional
153 ** data, so it can flush the output.
155 USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);
157 else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
159 if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0)))
161 /* User: add your own code for send complete event */
163 USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
164 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
165 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
166 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
167 USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
171 else if ((0 == s_sendComplete) && (1 == s_cdcVcom.attach) && (0 == s_cdcVcom.startTransactions))
182 * @brief Bulk out pipe callback function.
184 * This function serves as the callback function for bulk out pipe.
186 * @param handle The USB device handle.
187 * @param message The endpoint callback message
188 * @param callbackParam The parameter of the callback.
190 * @return A USB error code or kStatus_USB_Success.
192 usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
193 usb_device_endpoint_callback_message_struct_t *message,
196 usb_status_t error = kStatus_USB_Error;
197 if (USB_UNINITIALIZED_VAL_32 == message->length)
199 s_recvSize = 0xFFFFFFFFU;
201 else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
203 s_recvSize = message->length;
204 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
205 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
206 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
207 USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
211 for (uint32_t offset = 0; s_recvSize-- > 0; offset++) {
212 if (ringbuf_is_full (&cdc_rx_buf))
215 ringbuf_write (&cdc_rx_buf, s_currRecvBuf[offset]);
223 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
224 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
225 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
226 USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
229 USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
239 * @brief Get the setup packet buffer.
241 * This function provides the buffer for setup packet.
243 * @param handle The USB device handle.
244 * @param setupBuffer The pointer to the address of setup packet buffer.
246 * @return A USB error code or kStatus_USB_Success.
248 usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
250 static uint32_t cdcVcomSetup[2];
251 if (NULL == setupBuffer)
253 return kStatus_USB_InvalidParameter;
255 *setupBuffer = (usb_setup_struct_t *)&cdcVcomSetup;
256 return kStatus_USB_Success;
260 * @brief Get the setup packet data buffer.
262 * This function gets the data buffer for setup packet.
264 * @param handle The USB device handle.
265 * @param setup The pointer to the setup packet.
266 * @param length The pointer to the length of the data buffer.
267 * @param buffer The pointer to the address of setup packet data buffer.
269 * @return A USB error code or kStatus_USB_Success.
271 usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
272 usb_setup_struct_t *setup,
276 static uint8_t setupOut[8];
277 if ((NULL == buffer) || ((*length) > sizeof(setupOut)))
279 return kStatus_USB_InvalidRequest;
282 return kStatus_USB_Success;
286 * @brief Configure remote wakeup feature.
288 * This function configures the remote wakeup feature.
290 * @param handle The USB device handle.
291 * @param enable 1: enable, 0: disable.
293 * @return A USB error code or kStatus_USB_Success.
295 usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
297 return kStatus_USB_InvalidRequest;
301 * @brief CDC class specific callback function.
303 * This function handles the CDC class specific requests.
305 * @param handle The USB device handle.
306 * @param setup The pointer to the setup packet.
307 * @param length The pointer to the length of the data buffer.
308 * @param buffer The pointer to the address of setup packet data buffer.
310 * @return A USB error code or kStatus_USB_Success.
312 usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
313 usb_setup_struct_t *setup,
317 usb_status_t error = kStatus_USB_InvalidRequest;
319 usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
321 uint16_t *uartBitmap;
322 if (setup->wIndex != USB_CDC_VCOM_COMM_INTERFACE_INDEX)
327 switch (setup->bRequest)
329 case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
331 case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
333 case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE:
334 if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
336 *buffer = s_abstractState;
338 else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
340 *buffer = s_countryCode;
345 error = kStatus_USB_Success;
347 case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE:
348 if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
350 *buffer = s_abstractState;
351 *length = COMM_FEATURE_DATA_SIZE;
353 else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
355 *buffer = s_countryCode;
356 *length = COMM_FEATURE_DATA_SIZE;
361 error = kStatus_USB_Success;
363 case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE:
365 case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING:
366 *buffer = s_lineCoding;
367 *length = LINE_CODING_SIZE;
368 error = kStatus_USB_Success;
370 case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING:
371 *buffer = s_lineCoding;
372 error = kStatus_USB_Success;
374 case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE:
376 acmInfo->dteStatus = setup->wValue;
377 /* activate/deactivate Tx carrier */
378 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
380 acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
384 acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
387 /* activate carrier and DTE */
388 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
390 acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
394 acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
397 /* Indicates to DCE if DTE is present or not */
398 acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;
400 /* Initialize the serial state buffer */
401 acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
402 acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF; /* bNotification */
403 acmInfo->serialStateBuf[2] = 0x00; /* wValue */
404 acmInfo->serialStateBuf[3] = 0x00;
405 acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
406 acmInfo->serialStateBuf[5] = 0x00;
407 acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
408 acmInfo->serialStateBuf[7] = 0x00;
409 /* Notifiy to host the line state */
410 acmInfo->serialStateBuf[4] = setup->wIndex;
411 /* Lower byte of UART BITMAP */
412 uartBitmap = (uint16_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
413 *uartBitmap = acmInfo->uartState;
414 len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
415 error = USB_DeviceSendRequest(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
418 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
420 /* To do: CARRIER_ACTIVATED */
424 /* To do: CARRIER_DEACTIVATED */
426 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
429 if (1 == s_cdcVcom.attach)
431 s_cdcVcom.startTransactions = 1;
432 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
433 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
434 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
435 USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
441 /* DTE_DEACTIVATED */
442 if (1 == s_cdcVcom.attach)
444 s_cdcVcom.startTransactions = 0;
449 case USB_DEVICE_CDC_REQUEST_SEND_BREAK:
459 * @brief USB device callback function.
461 * This function handles the usb device specific requests.
463 * @param handle The USB device handle.
464 * @param event The USB device event type.
465 * @param param The parameter of the device specific request.
467 * @return A USB error code or kStatus_USB_Success.
469 usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
471 usb_status_t error = kStatus_USB_Error;
472 uint8_t *temp8 = (uint8_t *)param;
476 case kUSB_DeviceEventBusReset:
478 USB_DeviceControlPipeInit(s_cdcVcom.deviceHandle);
479 s_cdcVcom.attach = 0;
480 #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)) || \
481 (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
482 if (kStatus_USB_Success ==
483 USB_DeviceGetStatus(s_cdcVcom.deviceHandle, kUSB_DeviceStatusSpeed, &s_cdcVcom.speed))
485 USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
490 case kUSB_DeviceEventSetConfiguration:
493 s_cdcVcom.attach = 1;
494 s_cdcVcom.currentConfiguration = *temp8;
495 if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
497 usb_device_endpoint_init_struct_t epInitStruct;
498 usb_device_endpoint_callback_struct_t endpointCallback;
500 /* Initiailize endpoint for interrupt pipe */
501 endpointCallback.callbackFn = USB_DeviceCdcAcmInterruptIn;
502 endpointCallback.callbackParam = handle;
504 epInitStruct.zlt = 0;
505 epInitStruct.transferType = USB_ENDPOINT_INTERRUPT;
506 epInitStruct.endpointAddress = USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT |
507 (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
508 if (USB_SPEED_HIGH == s_cdcVcom.speed)
510 epInitStruct.maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
514 epInitStruct.maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
517 USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
519 /* Initiailize endpoints for bulk pipe */
520 endpointCallback.callbackFn = USB_DeviceCdcAcmBulkIn;
521 endpointCallback.callbackParam = handle;
523 epInitStruct.zlt = 0;
524 epInitStruct.transferType = USB_ENDPOINT_BULK;
525 epInitStruct.endpointAddress =
526 USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
527 if (USB_SPEED_HIGH == s_cdcVcom.speed)
529 epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
533 epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
536 USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
538 endpointCallback.callbackFn = USB_DeviceCdcAcmBulkOut;
539 endpointCallback.callbackParam = handle;
541 epInitStruct.zlt = 0;
542 epInitStruct.transferType = USB_ENDPOINT_BULK;
543 epInitStruct.endpointAddress =
544 USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
545 if (USB_SPEED_HIGH == s_cdcVcom.speed)
547 epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
551 epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
554 USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
556 if (USB_SPEED_HIGH == s_cdcVcom.speed)
558 s_usbBulkMaxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
562 s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
565 USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
577 * @brief USB configure endpoint function.
579 * This function configure endpoint status.
581 * @param handle The USB device handle.
582 * @param ep Endpoint address.
583 * @param status A flag to indicate whether to stall the endpoint. 1: stall, 0: unstall.
585 * @return A USB error code or kStatus_USB_Success.
587 usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
591 return USB_DeviceStallEndpoint(handle, ep);
595 return USB_DeviceUnstallEndpoint(handle, ep);
599 /* See virtual_com.h for documentation of this function. */
600 void USB_VcomWriteBlocking(usb_device_handle baseAddr, const uint8_t *buf, size_t count)
602 while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
605 USB_DeviceSendRequest((usb_device_handle)baseAddr, USB_CDC_VCOM_BULK_IN_ENDPOINT, (uint8_t *)buf, count);
606 while (!s_sendComplete)
612 /* See virtual_com.h for documentation of this function. */
613 status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t count)
615 status_t error = kStatus_Success;
616 size_t bufIndex = 0U, bytesToReceive = 0U;
619 /* Waiting for the USB ready. */
620 while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
626 /* If no receive request. */
629 if (kStatus_USB_Success !=
630 USB_DeviceRecvRequest(baseAddr, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize))
636 /* Waiting for data received by virtual com. */
637 while (s_recvSize <= 0)
641 /* When receive request is error. */
642 if (0xFFFFFFFFU == s_recvSize)
644 /* Waiting for the USB ready and transfer started. */
645 while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
652 bytesToReceive = MIN(count, s_recvSize);
653 memcpy((void *)&buf[bufIndex], s_currRecvBuf + s_currRecvIndex, bytesToReceive);
654 count -= bytesToReceive;
655 s_recvSize -= bytesToReceive;
656 bufIndex += bytesToReceive;
657 s_currRecvIndex += bytesToReceive;
659 } while (0U != count);
663 /* See virtual_com.h for documentation of this function. */
664 usb_device_handle USB_VcomInit(void)
666 usb_device_handle deviceHandle = NULL;
668 USB_DeviceClockInit();
670 #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
671 SYSMPU_Enable(SYSMPU, 0);
672 #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
674 s_cdcVcom.speed = USB_SPEED_FULL;
675 s_cdcVcom.attach = 0;
676 s_cdcVcom.deviceHandle = NULL;
678 if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &s_cdcVcom.deviceHandle))
684 deviceHandle = s_cdcVcom.deviceHandle;
685 USB_DeviceIsrEnable();
686 USB_DeviceRun(s_cdcVcom.deviceHandle);
691 /* See virtual_com.h for documentation of this function. */
692 void USB_VcomDeinit(usb_device_handle deviceHandle)
694 USB_DeviceStop(deviceHandle);
695 USB_DeviceDeinit(deviceHandle);
696 s_cdcVcom.deviceHandle = NULL;
697 #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
698 USB_EhciPhyDeinit(CONTROLLER_ID);
700 #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
701 CLOCK_DisableUsbfs0Clock();
703 #if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
704 /* enable USB IP clock, user code. */
705 CLOCK_DisableClock(kCLOCK_Usbd0);
706 #endif /* USB_DEVICE_CONFIG_LPCIP3511FS */
708 #if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
709 /* enable USB IP clock,user code. */
710 #endif /* USB_DEVICE_CONFIG_LPCIP3511HS */
714 USB0_IRQHandler (void)
716 USB_DeviceKhciIsrFunction (s_cdcVcom.deviceHandle);
719 bool usb_serial_read (char *c)
721 if (ringbuf_is_empty (&cdc_rx_buf)) {
722 if (!s_recvSize || s_recvSize == (uint32_t) -1)
723 USB_DeviceRecvRequest (s_cdcVcom.deviceHandle,
724 USB_CDC_VCOM_BULK_OUT_ENDPOINT,
726 s_usbBulkMaxPacketSize);
731 *c = ringbuf_read (&cdc_rx_buf);