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"
40 #include "usb_device_config.h"
42 #include "usb_device.h"
44 #include "usb_device_cdc_acm.h"
45 #include "usb_device_ch9.h"
47 #include "usb_device_descriptor.h"
48 #include "virtual_com.h"
49 #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
50 #include "fsl_sysmpu.h"
51 #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
52 #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
59 /* Provided by users. */
60 extern void USB_DeviceClockInit(void);
61 extern void USB_DeviceIsrEnable(void);
62 extern void USB_DeviceIsrDisable(void);
63 /*******************************************************************************
65 ******************************************************************************/
67 /*******************************************************************************
69 ******************************************************************************/
71 static uint8_t cdc_rx_buf_space[1024];
72 static uint8_t cdc_tx_buf_space[1024] alignas(4);
74 static struct ringbuf cdc_rx_buf =
75 RINGBUF_INIT (cdc_rx_buf_space, sizeof (cdc_rx_buf_space));
77 struct buffer cdc_tx_buf;
79 /* Data structure of virtual com device */
80 usb_cdc_vcom_struct_t s_cdcVcom;
82 /* Line codinig of cdc device */
83 static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
84 /* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
85 (LINE_CODING_DTERATE >> 0U) & 0x000000FFU,
86 (LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
87 (LINE_CODING_DTERATE >> 16U) & 0x000000FFU,
88 (LINE_CODING_DTERATE >> 24U) & 0x000000FFU,
89 LINE_CODING_CHARFORMAT,
90 LINE_CODING_PARITYTYPE,
91 LINE_CODING_DATABITS};
93 /* Abstract state of cdc device */
94 static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
95 (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
97 /* Country code of cdc device */
98 static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
99 (COUNTRY_SETTING >> 8U) & 0x00FFU};
101 /* CDC ACM information */
102 static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0};
104 /* Data buffer for receiving and sending*/
105 static uint8_t s_currRecvBuf[DATA_BUFF_SIZE];
106 static volatile uint32_t s_recvSize = 0;
107 static volatile uint8_t s_sendComplete = 0;
108 static uint32_t s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
109 /*******************************************************************************
111 ******************************************************************************/
113 /*******************************************************************************
115 ******************************************************************************/
117 * @brief Interrupt in pipe callback function.
119 * This function serves as the callback function for interrupt in pipe.
121 * @param handle The USB device handle.
122 * @param message The endpoint callback message
123 * @param callbackParam The parameter of the callback.
125 * @return A USB error code or kStatus_USB_Success.
127 usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle,
128 usb_device_endpoint_callback_message_struct_t *message,
131 usb_status_t error = kStatus_USB_Error;
137 * @brief Bulk in pipe callback function.
139 * This function serves as the callback function for bulk in pipe.
141 * @param handle The USB device handle.
142 * @param message The endpoint callback message
143 * @param callbackParam The parameter of the callback.
145 * @return A USB error code or kStatus_USB_Success.
147 usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
148 usb_device_endpoint_callback_message_struct_t *message,
151 usb_status_t error = kStatus_USB_Error;
153 if ((message->length != 0) && (!(message->length % s_usbBulkMaxPacketSize)))
155 /* If the last packet is the size of endpoint, then send also zero-ended packet,
156 ** meaning that we want to inform the host that we do not have any additional
157 ** data, so it can flush the output.
159 USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);
161 else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
163 if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0)))
165 /* User: add your own code for send complete event */
167 USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
168 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
169 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
170 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
171 USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
175 else if ((0 == s_sendComplete) && (1 == s_cdcVcom.attach) && (0 == s_cdcVcom.startTransactions))
186 * @brief Bulk out pipe callback function.
188 * This function serves as the callback function for bulk out pipe.
190 * @param handle The USB device handle.
191 * @param message The endpoint callback message
192 * @param callbackParam The parameter of the callback.
194 * @return A USB error code or kStatus_USB_Success.
196 usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
197 usb_device_endpoint_callback_message_struct_t *message,
200 usb_status_t error = kStatus_USB_Error;
201 if (USB_UNINITIALIZED_VAL_32 == message->length)
203 s_recvSize = 0xFFFFFFFFU;
205 else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
207 s_recvSize = message->length;
208 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
209 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
210 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
211 USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
215 for (uint32_t offset = 0; s_recvSize-- > 0; offset++) {
216 if (ringbuf_is_full (&cdc_rx_buf))
219 ringbuf_write (&cdc_rx_buf, s_currRecvBuf[offset]);
227 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
228 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
229 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
230 USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
233 USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
243 * @brief Get the setup packet buffer.
245 * This function provides the buffer for setup packet.
247 * @param handle The USB device handle.
248 * @param setupBuffer The pointer to the address of setup packet buffer.
250 * @return A USB error code or kStatus_USB_Success.
252 usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
254 static uint32_t cdcVcomSetup[2];
255 if (NULL == setupBuffer)
257 return kStatus_USB_InvalidParameter;
259 *setupBuffer = (usb_setup_struct_t *)&cdcVcomSetup;
260 return kStatus_USB_Success;
264 * @brief Get the setup packet data buffer.
266 * This function gets the data buffer for setup packet.
268 * @param handle The USB device handle.
269 * @param setup The pointer to the setup packet.
270 * @param length The pointer to the length of the data buffer.
271 * @param buffer The pointer to the address of setup packet data buffer.
273 * @return A USB error code or kStatus_USB_Success.
275 usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
276 usb_setup_struct_t *setup,
280 static uint8_t setupOut[8];
281 if ((NULL == buffer) || ((*length) > sizeof(setupOut)))
283 return kStatus_USB_InvalidRequest;
286 return kStatus_USB_Success;
290 * @brief Configure remote wakeup feature.
292 * This function configures the remote wakeup feature.
294 * @param handle The USB device handle.
295 * @param enable 1: enable, 0: disable.
297 * @return A USB error code or kStatus_USB_Success.
299 usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
301 return kStatus_USB_InvalidRequest;
305 * @brief CDC class specific callback function.
307 * This function handles the CDC class specific requests.
309 * @param handle The USB device handle.
310 * @param setup The pointer to the setup packet.
311 * @param length The pointer to the length of the data buffer.
312 * @param buffer The pointer to the address of setup packet data buffer.
314 * @return A USB error code or kStatus_USB_Success.
316 usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
317 usb_setup_struct_t *setup,
321 usb_status_t error = kStatus_USB_InvalidRequest;
323 usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
325 uint16_t *uartBitmap;
326 if (setup->wIndex != USB_CDC_VCOM_COMM_INTERFACE_INDEX)
331 switch (setup->bRequest)
333 case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
335 case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
337 case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE:
338 if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
340 *buffer = s_abstractState;
342 else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
344 *buffer = s_countryCode;
349 error = kStatus_USB_Success;
351 case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE:
352 if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
354 *buffer = s_abstractState;
355 *length = COMM_FEATURE_DATA_SIZE;
357 else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
359 *buffer = s_countryCode;
360 *length = COMM_FEATURE_DATA_SIZE;
365 error = kStatus_USB_Success;
367 case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE:
369 case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING:
370 *buffer = s_lineCoding;
371 *length = LINE_CODING_SIZE;
372 error = kStatus_USB_Success;
374 case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING:
375 *buffer = s_lineCoding;
376 error = kStatus_USB_Success;
378 case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE:
380 acmInfo->dteStatus = setup->wValue;
381 /* activate/deactivate Tx carrier */
382 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
384 acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
388 acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
391 /* activate carrier and DTE */
392 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
394 acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
398 acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
401 /* Indicates to DCE if DTE is present or not */
402 acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;
404 /* Initialize the serial state buffer */
405 acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
406 acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF; /* bNotification */
407 acmInfo->serialStateBuf[2] = 0x00; /* wValue */
408 acmInfo->serialStateBuf[3] = 0x00;
409 acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
410 acmInfo->serialStateBuf[5] = 0x00;
411 acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
412 acmInfo->serialStateBuf[7] = 0x00;
413 /* Notifiy to host the line state */
414 acmInfo->serialStateBuf[4] = setup->wIndex;
415 /* Lower byte of UART BITMAP */
416 uartBitmap = (uint16_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
417 *uartBitmap = acmInfo->uartState;
418 len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
419 error = USB_DeviceSendRequest(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
422 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
424 /* To do: CARRIER_ACTIVATED */
428 /* To do: CARRIER_DEACTIVATED */
430 if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
433 if (1 == s_cdcVcom.attach)
435 s_cdcVcom.startTransactions = 1;
436 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
437 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
438 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
439 USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
445 /* DTE_DEACTIVATED */
446 if (1 == s_cdcVcom.attach)
448 s_cdcVcom.startTransactions = 0;
453 case USB_DEVICE_CDC_REQUEST_SEND_BREAK:
463 * @brief USB device callback function.
465 * This function handles the usb device specific requests.
467 * @param handle The USB device handle.
468 * @param event The USB device event type.
469 * @param param The parameter of the device specific request.
471 * @return A USB error code or kStatus_USB_Success.
473 usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
475 usb_status_t error = kStatus_USB_Error;
476 uint8_t *temp8 = (uint8_t *)param;
480 case kUSB_DeviceEventBusReset:
482 USB_DeviceControlPipeInit(s_cdcVcom.deviceHandle);
483 s_cdcVcom.attach = 0;
484 #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)) || \
485 (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
486 if (kStatus_USB_Success ==
487 USB_DeviceGetStatus(s_cdcVcom.deviceHandle, kUSB_DeviceStatusSpeed, &s_cdcVcom.speed))
489 USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
494 case kUSB_DeviceEventSetConfiguration:
497 s_cdcVcom.attach = 1;
498 s_cdcVcom.currentConfiguration = *temp8;
499 if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
501 usb_device_endpoint_init_struct_t epInitStruct;
502 usb_device_endpoint_callback_struct_t endpointCallback;
504 /* Initiailize endpoint for interrupt pipe */
505 endpointCallback.callbackFn = USB_DeviceCdcAcmInterruptIn;
506 endpointCallback.callbackParam = handle;
508 epInitStruct.zlt = 0;
509 epInitStruct.transferType = USB_ENDPOINT_INTERRUPT;
510 epInitStruct.endpointAddress = USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT |
511 (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
512 if (USB_SPEED_HIGH == s_cdcVcom.speed)
514 epInitStruct.maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
518 epInitStruct.maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
521 USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
523 /* Initiailize endpoints for bulk pipe */
524 endpointCallback.callbackFn = USB_DeviceCdcAcmBulkIn;
525 endpointCallback.callbackParam = handle;
527 epInitStruct.zlt = 0;
528 epInitStruct.transferType = USB_ENDPOINT_BULK;
529 epInitStruct.endpointAddress =
530 USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
531 if (USB_SPEED_HIGH == s_cdcVcom.speed)
533 epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
537 epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
540 USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
542 endpointCallback.callbackFn = USB_DeviceCdcAcmBulkOut;
543 endpointCallback.callbackParam = handle;
545 epInitStruct.zlt = 0;
546 epInitStruct.transferType = USB_ENDPOINT_BULK;
547 epInitStruct.endpointAddress =
548 USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
549 if (USB_SPEED_HIGH == s_cdcVcom.speed)
551 epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
555 epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
558 USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
560 if (USB_SPEED_HIGH == s_cdcVcom.speed)
562 s_usbBulkMaxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
566 s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
569 USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
581 * @brief USB configure endpoint function.
583 * This function configure endpoint status.
585 * @param handle The USB device handle.
586 * @param ep Endpoint address.
587 * @param status A flag to indicate whether to stall the endpoint. 1: stall, 0: unstall.
589 * @return A USB error code or kStatus_USB_Success.
591 usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
595 return USB_DeviceStallEndpoint(handle, ep);
599 return USB_DeviceUnstallEndpoint(handle, ep);
604 flush_tx_buffer (void *user_data, void *vbuf, size_t bufsiz, size_t count)
608 /* Don't write data unless link is open. */
609 if (s_cdcVcom.attach != 1 || s_cdcVcom.startTransactions != 1)
612 USB_DeviceSendRequest (user_data, USB_CDC_VCOM_BULK_IN_ENDPOINT,
615 /* Wait for USB_DeviceCdcAcmBulkIn() to set s_sendComplete. */
616 while (!s_sendComplete)
620 /* Reset for the next write. */
626 /* See virtual_com.h for documentation of this function. */
628 USB_VcomInit (uint16_t vid, uint16_t pid)
630 usb_device_handle deviceHandle = NULL;
632 USB_DeviceClockInit();
634 #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
635 SYSMPU_Enable(SYSMPU, 0);
636 #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
638 s_cdcVcom.speed = USB_SPEED_FULL;
639 s_cdcVcom.attach = 0;
640 s_cdcVcom.deviceHandle = NULL;
642 USB_DeviceSetVendorId(vid);
643 USB_DeviceSetProductId(pid);
645 if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &s_cdcVcom.deviceHandle))
651 deviceHandle = s_cdcVcom.deviceHandle;
653 buffer_init (&cdc_tx_buf, cdc_tx_buf_space, sizeof (cdc_tx_buf_space),
654 flush_tx_buffer, deviceHandle);
656 USB_DeviceIsrEnable();
657 USB_DeviceRun(s_cdcVcom.deviceHandle);
662 /* See virtual_com.h for documentation of this function. */
664 USB_VcomDeinit (void)
666 if (s_cdcVcom.deviceHandle == NULL)
669 USB_DeviceStop (s_cdcVcom.deviceHandle);
670 USB_DeviceDeinit (s_cdcVcom.deviceHandle);
671 s_cdcVcom.deviceHandle = NULL;
673 USB_DeviceIsrDisable();
675 /* XXX: We are not stopping the USBOTG clock yet. */
679 USB0_IRQHandler (void)
681 USB_DeviceKhciIsrFunction (s_cdcVcom.deviceHandle);
684 bool usb_serial_read (char *c)
686 if (ringbuf_is_empty (&cdc_rx_buf)) {
687 if (!s_recvSize || s_recvSize == (uint32_t) -1)
688 USB_DeviceRecvRequest (s_cdcVcom.deviceHandle,
689 USB_CDC_VCOM_BULK_OUT_ENDPOINT,
691 s_usbBulkMaxPacketSize);
696 *c = ringbuf_read (&cdc_rx_buf);