123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- /*
- * The Clear BSD License
- * Copyright (c) 2015, Freescale Semiconductor, Inc.
- * Copyright 2016-2017 NXP
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted (subject to the limitations in the disclaimer below) provided
- * that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or
- * other materials provided with the distribution.
- *
- * o Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "fsl_device_registers.h"
- #include "clock_config.h"
- #include "board.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include "usb_device_config.h"
- #include "usb.h"
- #include "usb_device.h"
- #include "usb_device_cdc_acm.h"
- #include "usb_device_ch9.h"
- #include "usb_device_descriptor.h"
- #include "virtual_com.h"
- #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
- #include "fsl_sysmpu.h"
- #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
- #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
- #include "usb_phy.h"
- #endif
- /* Provided by users. */
- extern void USB_DeviceClockInit(void);
- extern void USB_DeviceIsrEnable(void);
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- /* Data structure of virtual com device */
- usb_cdc_vcom_struct_t s_cdcVcom;
- /* Line codinig of cdc device */
- static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
- /* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
- (LINE_CODING_DTERATE >> 0U) & 0x000000FFU,
- (LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
- (LINE_CODING_DTERATE >> 16U) & 0x000000FFU,
- (LINE_CODING_DTERATE >> 24U) & 0x000000FFU,
- LINE_CODING_CHARFORMAT,
- LINE_CODING_PARITYTYPE,
- LINE_CODING_DATABITS};
- /* Abstract state of cdc device */
- static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
- (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
- /* Country code of cdc device */
- static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
- (COUNTRY_SETTING >> 8U) & 0x00FFU};
- /* CDC ACM information */
- static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0};
- /* Data buffer for receiving and sending*/
- static uint8_t s_currRecvBuf[DATA_BUFF_SIZE];
- volatile static uint32_t s_recvSize = 0;
- volatile static uint32_t s_sendSize = 0;
- volatile static uint8_t s_sendComplete = 0;
- volatile static uint8_t s_currRecvIndex = 0;
- static uint32_t s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief Interrupt in pipe callback function.
- *
- * This function serves as the callback function for interrupt in pipe.
- *
- * @param handle The USB device handle.
- * @param message The endpoint callback message
- * @param callbackParam The parameter of the callback.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle,
- usb_device_endpoint_callback_message_struct_t *message,
- void *callbackParam)
- {
- usb_status_t error = kStatus_USB_Error;
- return error;
- }
- /*!
- * @brief Bulk in pipe callback function.
- *
- * This function serves as the callback function for bulk in pipe.
- *
- * @param handle The USB device handle.
- * @param message The endpoint callback message
- * @param callbackParam The parameter of the callback.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
- usb_device_endpoint_callback_message_struct_t *message,
- void *callbackParam)
- {
- usb_status_t error = kStatus_USB_Error;
- if ((message->length != 0) && (!(message->length % s_usbBulkMaxPacketSize)))
- {
- /* If the last packet is the size of endpoint, then send also zero-ended packet,
- ** meaning that we want to inform the host that we do not have any additional
- ** data, so it can flush the output.
- */
- USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);
- }
- else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
- {
- if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0)))
- {
- /* User: add your own code for send complete event */
- s_sendComplete = 1;
- #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
- defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
- defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
- USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
- #endif
- }
- }
- else if ((0 == s_sendComplete) && (1 == s_cdcVcom.attach) && (0 == s_cdcVcom.startTransactions))
- {
- s_sendComplete = 1;
- }
- else
- {
- }
- return error;
- }
- /*!
- * @brief Bulk out pipe callback function.
- *
- * This function serves as the callback function for bulk out pipe.
- *
- * @param handle The USB device handle.
- * @param message The endpoint callback message
- * @param callbackParam The parameter of the callback.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
- usb_device_endpoint_callback_message_struct_t *message,
- void *callbackParam)
- {
- usb_status_t error = kStatus_USB_Error;
- if (USB_UNINITIALIZED_VAL_32 == message->length)
- {
- s_recvSize = 0xFFFFFFFFU;
- }
- else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
- {
- s_recvSize = message->length;
- #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
- defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
- defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
- USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
- #endif
- if (!s_recvSize)
- {
- #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
- defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
- defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
- USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
- #endif
- }
- }
- else
- {
- }
- return error;
- }
- /*!
- * @brief Get the setup packet buffer.
- *
- * This function provides the buffer for setup packet.
- *
- * @param handle The USB device handle.
- * @param setupBuffer The pointer to the address of setup packet buffer.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
- {
- static uint32_t cdcVcomSetup[2];
- if (NULL == setupBuffer)
- {
- return kStatus_USB_InvalidParameter;
- }
- *setupBuffer = (usb_setup_struct_t *)&cdcVcomSetup;
- return kStatus_USB_Success;
- }
- /*!
- * @brief Get the setup packet data buffer.
- *
- * This function gets the data buffer for setup packet.
- *
- * @param handle The USB device handle.
- * @param setup The pointer to the setup packet.
- * @param length The pointer to the length of the data buffer.
- * @param buffer The pointer to the address of setup packet data buffer.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
- usb_setup_struct_t *setup,
- uint32_t *length,
- uint8_t **buffer)
- {
- static uint8_t setupOut[8];
- if ((NULL == buffer) || ((*length) > sizeof(setupOut)))
- {
- return kStatus_USB_InvalidRequest;
- }
- *buffer = setupOut;
- return kStatus_USB_Success;
- }
- /*!
- * @brief Configure remote wakeup feature.
- *
- * This function configures the remote wakeup feature.
- *
- * @param handle The USB device handle.
- * @param enable 1: enable, 0: disable.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
- {
- return kStatus_USB_InvalidRequest;
- }
- /*!
- * @brief CDC class specific callback function.
- *
- * This function handles the CDC class specific requests.
- *
- * @param handle The USB device handle.
- * @param setup The pointer to the setup packet.
- * @param length The pointer to the length of the data buffer.
- * @param buffer The pointer to the address of setup packet data buffer.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
- usb_setup_struct_t *setup,
- uint32_t *length,
- uint8_t **buffer)
- {
- usb_status_t error = kStatus_USB_InvalidRequest;
- usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
- uint32_t len;
- uint16_t *uartBitmap;
- if (setup->wIndex != USB_CDC_VCOM_COMM_INTERFACE_INDEX)
- {
- return error;
- }
- switch (setup->bRequest)
- {
- case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
- break;
- case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
- break;
- case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE:
- if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
- {
- *buffer = s_abstractState;
- }
- else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
- {
- *buffer = s_countryCode;
- }
- else
- {
- }
- error = kStatus_USB_Success;
- break;
- case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE:
- if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
- {
- *buffer = s_abstractState;
- *length = COMM_FEATURE_DATA_SIZE;
- }
- else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
- {
- *buffer = s_countryCode;
- *length = COMM_FEATURE_DATA_SIZE;
- }
- else
- {
- }
- error = kStatus_USB_Success;
- break;
- case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE:
- break;
- case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING:
- *buffer = s_lineCoding;
- *length = LINE_CODING_SIZE;
- error = kStatus_USB_Success;
- break;
- case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING:
- *buffer = s_lineCoding;
- error = kStatus_USB_Success;
- break;
- case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE:
- {
- acmInfo->dteStatus = setup->wValue;
- /* activate/deactivate Tx carrier */
- if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
- {
- acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
- }
- else
- {
- acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
- }
- /* activate carrier and DTE */
- if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
- {
- acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
- }
- else
- {
- acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
- }
- /* Indicates to DCE if DTE is present or not */
- acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;
- /* Initialize the serial state buffer */
- acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
- acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF; /* bNotification */
- acmInfo->serialStateBuf[2] = 0x00; /* wValue */
- acmInfo->serialStateBuf[3] = 0x00;
- acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
- acmInfo->serialStateBuf[5] = 0x00;
- acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
- acmInfo->serialStateBuf[7] = 0x00;
- /* Notifiy to host the line state */
- acmInfo->serialStateBuf[4] = setup->wIndex;
- /* Lower byte of UART BITMAP */
- uartBitmap = (uint16_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
- *uartBitmap = acmInfo->uartState;
- len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
- error = USB_DeviceSendRequest(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
- /* Update status */
- if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
- {
- /* To do: CARRIER_ACTIVATED */
- }
- else
- {
- /* To do: CARRIER_DEACTIVATED */
- }
- if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
- {
- /* DTE_ACTIVATED */
- if (1 == s_cdcVcom.attach)
- {
- s_cdcVcom.startTransactions = 1;
- #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
- defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
- defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
- USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
- #endif
- }
- }
- else
- {
- /* DTE_DEACTIVATED */
- if (1 == s_cdcVcom.attach)
- {
- s_cdcVcom.startTransactions = 0;
- }
- }
- }
- break;
- case USB_DEVICE_CDC_REQUEST_SEND_BREAK:
- break;
- default:
- break;
- }
- return error;
- }
- /*!
- * @brief USB device callback function.
- *
- * This function handles the usb device specific requests.
- *
- * @param handle The USB device handle.
- * @param event The USB device event type.
- * @param param The parameter of the device specific request.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
- {
- usb_status_t error = kStatus_USB_Error;
- uint8_t *temp8 = (uint8_t *)param;
- switch (event)
- {
- case kUSB_DeviceEventBusReset:
- {
- USB_DeviceControlPipeInit(s_cdcVcom.deviceHandle);
- s_cdcVcom.attach = 0;
- #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)) || \
- (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
- if (kStatus_USB_Success ==
- USB_DeviceGetStatus(s_cdcVcom.deviceHandle, kUSB_DeviceStatusSpeed, &s_cdcVcom.speed))
- {
- USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
- }
- #endif
- }
- break;
- case kUSB_DeviceEventSetConfiguration:
- if (param)
- {
- s_cdcVcom.attach = 1;
- s_cdcVcom.currentConfiguration = *temp8;
- if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
- {
- usb_device_endpoint_init_struct_t epInitStruct;
- usb_device_endpoint_callback_struct_t endpointCallback;
- /* Initiailize endpoint for interrupt pipe */
- endpointCallback.callbackFn = USB_DeviceCdcAcmInterruptIn;
- endpointCallback.callbackParam = handle;
- epInitStruct.zlt = 0;
- epInitStruct.transferType = USB_ENDPOINT_INTERRUPT;
- epInitStruct.endpointAddress = USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT |
- (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
- if (USB_SPEED_HIGH == s_cdcVcom.speed)
- {
- epInitStruct.maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
- }
- else
- {
- epInitStruct.maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
- }
- USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
- /* Initiailize endpoints for bulk pipe */
- endpointCallback.callbackFn = USB_DeviceCdcAcmBulkIn;
- endpointCallback.callbackParam = handle;
- epInitStruct.zlt = 0;
- epInitStruct.transferType = USB_ENDPOINT_BULK;
- epInitStruct.endpointAddress =
- USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
- if (USB_SPEED_HIGH == s_cdcVcom.speed)
- {
- epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
- }
- else
- {
- epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
- }
- USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
- endpointCallback.callbackFn = USB_DeviceCdcAcmBulkOut;
- endpointCallback.callbackParam = handle;
- epInitStruct.zlt = 0;
- epInitStruct.transferType = USB_ENDPOINT_BULK;
- epInitStruct.endpointAddress =
- USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
- if (USB_SPEED_HIGH == s_cdcVcom.speed)
- {
- epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
- }
- else
- {
- epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
- }
- USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
- if (USB_SPEED_HIGH == s_cdcVcom.speed)
- {
- s_usbBulkMaxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
- }
- else
- {
- s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
- }
- }
- }
- break;
- default:
- break;
- }
- return error;
- }
- /*!
- * @brief USB configure endpoint function.
- *
- * This function configure endpoint status.
- *
- * @param handle The USB device handle.
- * @param ep Endpoint address.
- * @param status A flag to indicate whether to stall the endpoint. 1: stall, 0: unstall.
- *
- * @return A USB error code or kStatus_USB_Success.
- */
- usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
- {
- if (status)
- {
- return USB_DeviceStallEndpoint(handle, ep);
- }
- else
- {
- return USB_DeviceUnstallEndpoint(handle, ep);
- }
- }
- /* See virtual_com.h for documentation of this function. */
- void USB_VcomWriteBlocking(usb_device_handle baseAddr, const uint8_t *buf, size_t count)
- {
- while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
- {
- __NOP();
- };
- USB_DeviceSendRequest((usb_device_handle)baseAddr, USB_CDC_VCOM_BULK_IN_ENDPOINT, (uint8_t *)buf, count);
- while (!s_sendComplete)
- {
- __NOP();
- };
- s_sendComplete = 0;
- }
- /* See virtual_com.h for documentation of this function. */
- status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t count)
- {
- status_t error = kStatus_Success;
- size_t bufIndex = 0U, bytesToReceive = 0U;
- assert(count != 0U);
- /* Waiting for the USB ready. */
- while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
- {
- __NOP();
- };
- do
- {
- /* If no receive request. */
- if (s_recvSize <= 0)
- {
- if (kStatus_USB_Success !=
- USB_DeviceRecvRequest(baseAddr, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize))
- {
- return kStatus_Fail;
- }
- s_currRecvIndex = 0;
- }
- /* Waiting for data received by virtual com. */
- while (s_recvSize <= 0)
- {
- __NOP();
- };
- /* When receive request is error. */
- if (0xFFFFFFFFU == s_recvSize)
- {
- /* Waiting for the USB ready and transfer started. */
- while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
- {
- __NOP();
- };
- s_recvSize = 0;
- }
- else
- {
- bytesToReceive = MIN(count, s_recvSize);
- memcpy((void *)&buf[bufIndex], s_currRecvBuf + s_currRecvIndex, bytesToReceive);
- count -= bytesToReceive;
- s_recvSize -= bytesToReceive;
- bufIndex += bytesToReceive;
- s_currRecvIndex += bytesToReceive;
- }
- } while (0U != count);
- return error;
- }
- /* See virtual_com.h for documentation of this function. */
- usb_device_handle USB_VcomInit(void)
- {
- usb_device_handle deviceHandle = NULL;
- USB_DeviceClockInit();
- #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
- SYSMPU_Enable(SYSMPU, 0);
- #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
- s_cdcVcom.speed = USB_SPEED_FULL;
- s_cdcVcom.attach = 0;
- s_cdcVcom.deviceHandle = NULL;
- if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &s_cdcVcom.deviceHandle))
- {
- deviceHandle = NULL;
- }
- else
- {
- deviceHandle = s_cdcVcom.deviceHandle;
- USB_DeviceIsrEnable();
- USB_DeviceRun(s_cdcVcom.deviceHandle);
- }
- return deviceHandle;
- }
- /* See virtual_com.h for documentation of this function. */
- void USB_VcomDeinit(usb_device_handle deviceHandle)
- {
- USB_DeviceStop(deviceHandle);
- USB_DeviceDeinit(deviceHandle);
- s_cdcVcom.deviceHandle = NULL;
- #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
- USB_EhciPhyDeinit(CONTROLLER_ID);
- #endif
- #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
- CLOCK_DisableUsbfs0Clock();
- #endif
- #if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
- /* enable USB IP clock, user code. */
- CLOCK_DisableClock(kCLOCK_Usbd0);
- #endif /* USB_DEVICE_CONFIG_LPCIP3511FS */
- #if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
- /* enable USB IP clock,user code. */
- #endif /* USB_DEVICE_CONFIG_LPCIP3511HS */
- }
|