1070 lines
37 KiB
C
1070 lines
37 KiB
C
/*
|
|
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016 - 2020, 2023 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "fsl_common.h"
|
|
#include "fsl_component_serial_manager.h"
|
|
#include "fsl_component_serial_port_internal.h"
|
|
|
|
#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
|
|
#include "usb_device_config.h"
|
|
#include "usb.h"
|
|
#include "usb_device.h"
|
|
|
|
#include "usb_device_class.h"
|
|
#include "usb_device_cdc_acm.h"
|
|
#include "usb_device_ch9.h"
|
|
|
|
#include "usb_device_descriptor.h"
|
|
#include "fsl_component_serial_port_usb.h"
|
|
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
|
|
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
|
#include "usb_phy.h"
|
|
#endif
|
|
#endif
|
|
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
|
|
#include "fsl_sysmpu.h"
|
|
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
|
|
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
#ifndef NDEBUG
|
|
#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
|
|
#undef assert
|
|
#define assert(n)
|
|
#else
|
|
/* MISRA C-2012 Rule 17.2 */
|
|
#undef assert
|
|
#define assert(n) \
|
|
while (!(n)) \
|
|
{ \
|
|
; \
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
|
|
#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
|
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
|
|
#define DATA_BUFF_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
|
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
|
#define DATA_BUFF_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
|
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
|
#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
|
#endif
|
|
|
|
/* Currently configured line coding */
|
|
#define LINE_CODING_SIZE (0x07)
|
|
#define LINE_CODING_DTERATE (115200)
|
|
#define LINE_CODING_CHARFORMAT (0x00)
|
|
#define LINE_CODING_PARITYTYPE (0x00)
|
|
#define LINE_CODING_DATABITS (0x08)
|
|
|
|
/* Communications feature */
|
|
#define COMM_FEATURE_DATA_SIZE (0x02)
|
|
#define STATUS_ABSTRACT_STATE (0x0000)
|
|
#define COUNTRY_SETTING (0x0000)
|
|
|
|
/* Notification of serial state */
|
|
#define NOTIF_PACKET_SIZE (0x08)
|
|
#define UART_BITMAP_SIZE (0x02)
|
|
#define NOTIF_REQUEST_TYPE (0xA1)
|
|
|
|
typedef struct _serial_usb_send_state
|
|
{
|
|
serial_manager_callback_t callback;
|
|
void *callbackParam;
|
|
uint8_t *buffer;
|
|
uint32_t length;
|
|
volatile uint8_t busy;
|
|
volatile uint8_t waiting4Prime;
|
|
} serial_usb_send_state_t;
|
|
|
|
typedef struct _serial_usb_recv_state
|
|
{
|
|
serial_manager_callback_t callback;
|
|
void *callbackParam;
|
|
volatile uint8_t busy;
|
|
} serial_usb_recv_state_t;
|
|
|
|
/* Define the information relates to abstract control model */
|
|
typedef struct _usb_cdc_acm_info
|
|
{
|
|
uint8_t serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE]; /* Serial state buffer of the CDC device to notify the
|
|
serial state to host. */
|
|
bool dtePresent; /* A flag to indicate whether DTE is present. */
|
|
uint16_t breakDuration; /* Length of time in milliseconds of the break signal */
|
|
uint8_t dteStatus; /* Status of data terminal equipment */
|
|
uint8_t currentInterface; /* Current interface index. */
|
|
uint16_t uartState; /* UART state of the CDC device. */
|
|
} usb_cdc_acm_info_t;
|
|
|
|
/* Define the types for application */
|
|
typedef struct _serial_usb_cdc_state
|
|
{
|
|
struct _serial_usb_cdc_state *next; /* Next pointer of the interface */
|
|
usb_device_handle deviceHandle; /* USB device handle. */
|
|
class_handle_t cdcAcmHandle; /* USB CDC ACM class handle. */
|
|
serial_usb_send_state_t tx;
|
|
serial_usb_recv_state_t rx;
|
|
volatile uint8_t attach; /* A flag to indicate whether a usb device is attached. 1: attached, 0: not attached */
|
|
uint8_t speed; /* Speed of USB device. USB_SPEED_FULL/USB_SPEED_LOW/USB_SPEED_HIGH. */
|
|
volatile uint8_t
|
|
startTransactions; /* A flag to indicate whether a CDC device is ready to transmit and receive data. */
|
|
uint8_t currentConfiguration; /* Current configuration value. */
|
|
uint8_t currentInterfaceAlternateSetting[USB_CDC_VCOM_INTERFACE_COUNT]; /* Current alternate setting value for each
|
|
interface. */
|
|
uint8_t instance; /* The instance of the interface */
|
|
uint8_t irqNumber; /* The IRQ number of the interface */
|
|
} serial_usb_cdc_state_t;
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
static void USB_DeviceIsrEnable(serial_usb_cdc_state_t *serialUsbCdc);
|
|
#if USB_DEVICE_CONFIG_USE_TASK
|
|
void USB_DeviceTaskFn(void *deviceHandle);
|
|
#endif
|
|
|
|
static usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param);
|
|
static usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
static serial_usb_cdc_state_t *s_UsbCdcHead;
|
|
|
|
/* Line codinig of cdc device */
|
|
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
|
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 */
|
|
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
|
static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
|
|
(STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
|
|
|
|
/* Country code of cdc device */
|
|
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
|
static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
|
|
(COUNTRY_SETTING >> 8U) & 0x00FFU};
|
|
|
|
/* CDC ACM information */
|
|
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static usb_cdc_acm_info_t s_usbCdcAcmInfo;
|
|
/* Data buffer for receiving and sending*/
|
|
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_currRecvBuf[DATA_BUFF_SIZE];
|
|
|
|
/* USB device class information */
|
|
static usb_device_class_config_struct_t s_cdcAcmConfig[1] = {{
|
|
USB_DeviceCdcVcomCallback,
|
|
0,
|
|
&g_UsbDeviceCdcVcomConfig,
|
|
}};
|
|
|
|
/* USB device class configuration information */
|
|
static usb_device_class_config_list_struct_t s_cdcAcmConfigList = {
|
|
s_cdcAcmConfig,
|
|
USB_DeviceCallback,
|
|
1,
|
|
};
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
static serial_usb_cdc_state_t *USB_DeviceGetInstanceFromDeviceHandle(serial_usb_cdc_state_t *head,
|
|
usb_device_handle deviceHandle)
|
|
{
|
|
while (NULL != head)
|
|
{
|
|
if (head->deviceHandle == deviceHandle)
|
|
{
|
|
return head;
|
|
}
|
|
head = head->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static serial_usb_cdc_state_t *USB_DeviceGetInstanceFromClassHandle(serial_usb_cdc_state_t *head,
|
|
class_handle_t ClassHandle)
|
|
{
|
|
while (NULL != head)
|
|
{
|
|
if (head->cdcAcmHandle == ClassHandle)
|
|
{
|
|
return head;
|
|
}
|
|
head = head->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static usb_status_t USB_DeviceAddItem(serial_usb_cdc_state_t **head, serial_usb_cdc_state_t *node)
|
|
{
|
|
serial_usb_cdc_state_t *p = *head;
|
|
uint32_t regPrimask;
|
|
|
|
regPrimask = DisableGlobalIRQ();
|
|
|
|
if (NULL == p)
|
|
{
|
|
*head = node;
|
|
}
|
|
else
|
|
{
|
|
while (NULL != p->next)
|
|
{
|
|
if (p == node)
|
|
{
|
|
EnableGlobalIRQ(regPrimask);
|
|
return kStatus_USB_Error;
|
|
}
|
|
p = p->next;
|
|
}
|
|
|
|
p->next = node;
|
|
}
|
|
node->next = NULL;
|
|
EnableGlobalIRQ(regPrimask);
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
static usb_status_t USB_DeviceRemoveItem(serial_usb_cdc_state_t **head, serial_usb_cdc_state_t *node)
|
|
{
|
|
serial_usb_cdc_state_t *p = *head;
|
|
serial_usb_cdc_state_t *q = NULL;
|
|
uint32_t regPrimask;
|
|
|
|
regPrimask = DisableGlobalIRQ();
|
|
while (NULL != p)
|
|
{
|
|
if (p == node)
|
|
{
|
|
if (NULL == q)
|
|
{
|
|
*head = p->next;
|
|
}
|
|
else
|
|
{
|
|
q->next = p->next;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
q = p;
|
|
p = p->next;
|
|
}
|
|
}
|
|
EnableGlobalIRQ(regPrimask);
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief CDC class specific callback function.
|
|
*
|
|
* This function handles the CDC class specific requests.
|
|
*
|
|
* @param handle The CDC ACM class handle.
|
|
* @param event The CDC ACM class event type.
|
|
* @param param The parameter of the class specific request.
|
|
*
|
|
* @return A USB error code or kStatus_USB_Success.
|
|
*/
|
|
static usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
uint32_t len;
|
|
uint8_t *uartBitmap;
|
|
usb_device_cdc_acm_request_param_struct_t *acmReqParam;
|
|
usb_device_endpoint_callback_message_struct_t *epCbParam;
|
|
usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
|
|
serial_manager_callback_message_t msg;
|
|
usb_status_t error = kStatus_USB_InvalidRequest;
|
|
|
|
serialUsbCdc = USB_DeviceGetInstanceFromClassHandle(s_UsbCdcHead, handle);
|
|
if (NULL == serialUsbCdc)
|
|
{
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param;
|
|
epCbParam = (usb_device_endpoint_callback_message_struct_t *)param;
|
|
switch ((usb_device_cdc_acm_event_t)event)
|
|
{
|
|
case kUSB_DeviceCdcEventSendResponse:
|
|
{
|
|
if (1U == serialUsbCdc->attach)
|
|
{
|
|
if ((epCbParam->length != 0U) &&
|
|
(0U == (epCbParam->length % g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize)))
|
|
{
|
|
/* 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.
|
|
*/
|
|
error = USB_DeviceCdcAcmSend(handle, (uint8_t)USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0U);
|
|
}
|
|
else
|
|
{
|
|
serialUsbCdc->tx.busy = 0;
|
|
|
|
if ((NULL != serialUsbCdc->tx.callback))
|
|
{
|
|
serial_manager_status_t serialManagerStatus = kStatus_SerialManager_Success;
|
|
msg.buffer = serialUsbCdc->tx.buffer;
|
|
msg.length = serialUsbCdc->tx.length;
|
|
error = kStatus_USB_Success;
|
|
if (USB_UNINITIALIZED_VAL_32 == epCbParam->length)
|
|
{
|
|
serialManagerStatus = kStatus_SerialManager_Canceled;
|
|
}
|
|
serialUsbCdc->tx.callback(serialUsbCdc->tx.callbackParam, &msg, serialManagerStatus);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceCdcEventRecvResponse:
|
|
{
|
|
serialUsbCdc->rx.busy = 0U;
|
|
if ((1U == serialUsbCdc->startTransactions))
|
|
{
|
|
serial_manager_status_t callbackStatus = kStatus_SerialManager_Success;
|
|
|
|
if ((NULL != serialUsbCdc->rx.callback))
|
|
{
|
|
msg.buffer = epCbParam->buffer;
|
|
msg.length = epCbParam->length;
|
|
error = kStatus_USB_Success;
|
|
if (USB_UNINITIALIZED_VAL_32 == msg.length)
|
|
{
|
|
msg.length = 0U;
|
|
callbackStatus = kStatus_SerialManager_Canceled;
|
|
}
|
|
serialUsbCdc->rx.callback(serialUsbCdc->rx.callbackParam, &msg, callbackStatus);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceCdcEventSerialStateNotif:
|
|
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0;
|
|
if ((0U != serialUsbCdc->startTransactions) && (0U != serialUsbCdc->tx.waiting4Prime))
|
|
{
|
|
serialUsbCdc->tx.waiting4Prime = 0U;
|
|
serialUsbCdc->tx.busy = 1U;
|
|
if (kStatus_USB_Success != USB_DeviceCdcAcmSend(serialUsbCdc->cdcAcmHandle,
|
|
USB_CDC_VCOM_BULK_IN_ENDPOINT, serialUsbCdc->tx.buffer,
|
|
serialUsbCdc->tx.length))
|
|
{
|
|
serialUsbCdc->tx.busy = 0U;
|
|
}
|
|
}
|
|
error = kStatus_USB_Success;
|
|
break;
|
|
case kUSB_DeviceCdcEventSendEncapsulatedCommand:
|
|
break;
|
|
case kUSB_DeviceCdcEventGetEncapsulatedResponse:
|
|
break;
|
|
case kUSB_DeviceCdcEventSetCommFeature:
|
|
if ((uint16_t)USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
|
|
{
|
|
if (1U == acmReqParam->isSetup)
|
|
{
|
|
*(acmReqParam->buffer) = s_abstractState;
|
|
*(acmReqParam->length) = sizeof(s_abstractState);
|
|
}
|
|
else
|
|
{
|
|
/* no action, data phase, s_abstractState has been assigned */
|
|
}
|
|
error = kStatus_USB_Success;
|
|
}
|
|
else if ((uint16_t)USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
|
|
{
|
|
if (1U == acmReqParam->isSetup)
|
|
{
|
|
*(acmReqParam->buffer) = s_countryCode;
|
|
*(acmReqParam->length) = sizeof(s_countryCode);
|
|
}
|
|
else
|
|
{
|
|
/* no action, data phase, s_countryCode has been assigned */
|
|
}
|
|
error = kStatus_USB_Success;
|
|
}
|
|
else
|
|
{
|
|
/* MISRA C-2012 Rule 15.7 */
|
|
}
|
|
break;
|
|
case kUSB_DeviceCdcEventGetCommFeature:
|
|
if ((uint16_t)USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
|
|
{
|
|
*(acmReqParam->buffer) = s_abstractState;
|
|
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
|
|
error = kStatus_USB_Success;
|
|
}
|
|
else if ((uint16_t)USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
|
|
{
|
|
*(acmReqParam->buffer) = s_countryCode;
|
|
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
|
|
error = kStatus_USB_Success;
|
|
}
|
|
else
|
|
{
|
|
/* MISRA C-2012 Rule 15.7 */
|
|
}
|
|
break;
|
|
case kUSB_DeviceCdcEventClearCommFeature:
|
|
break;
|
|
case kUSB_DeviceCdcEventGetLineCoding:
|
|
*(acmReqParam->buffer) = s_lineCoding;
|
|
*(acmReqParam->length) = LINE_CODING_SIZE;
|
|
error = kStatus_USB_Success;
|
|
break;
|
|
case kUSB_DeviceCdcEventSetLineCoding:
|
|
{
|
|
if (1U == acmReqParam->isSetup)
|
|
{
|
|
*(acmReqParam->buffer) = s_lineCoding;
|
|
*(acmReqParam->length) = sizeof(s_lineCoding);
|
|
}
|
|
else
|
|
{
|
|
/* no action, data phase, s_lineCoding has been assigned */
|
|
}
|
|
}
|
|
error = kStatus_USB_Success;
|
|
break;
|
|
case kUSB_DeviceCdcEventSetControlLineState:
|
|
{
|
|
error = kStatus_USB_Success;
|
|
s_usbCdcAcmInfo.dteStatus = (uint8_t)acmReqParam->setupValue;
|
|
/* activate/deactivate Tx carrier */
|
|
if (0U != (acmInfo->dteStatus & (uint8_t)USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION))
|
|
{
|
|
acmInfo->uartState |= (uint16_t)USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
|
|
}
|
|
else
|
|
{
|
|
acmInfo->uartState &= ~((uint16_t)USB_DEVICE_CDC_UART_STATE_TX_CARRIER);
|
|
}
|
|
|
|
/* activate carrier and DTE */
|
|
if (0U != (acmInfo->dteStatus & (uint8_t)USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE))
|
|
{
|
|
acmInfo->uartState |= (uint16_t)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 =
|
|
(0U != (acmInfo->dteStatus & (uint8_t)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_NOTIF_SERIAL_STATE; /* 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] = (uint8_t)acmReqParam->interfaceIndex;
|
|
/* Lower byte of UART BITMAP */
|
|
uartBitmap = (uint8_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
|
|
uartBitmap[0] = (uint8_t)(acmInfo->uartState & 0xFFu);
|
|
uartBitmap[1] = (uint8_t)((acmInfo->uartState >> 8) & 0xFFu);
|
|
len = (uint32_t)NOTIF_PACKET_SIZE + (uint32_t)UART_BITMAP_SIZE;
|
|
if (0U == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState)
|
|
{
|
|
error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
|
|
if (kStatus_USB_Success != error)
|
|
{
|
|
/* MISRA C-2012 Rule 17.2 */
|
|
/* (void)usb_echo("kUSB_DeviceCdcEventSetControlLineState error!"); */
|
|
}
|
|
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1;
|
|
}
|
|
|
|
/* Update status */
|
|
if (0U != (acmInfo->dteStatus & (uint8_t)USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION))
|
|
{
|
|
/* To do: CARRIER_ACTIVATED */
|
|
}
|
|
else
|
|
{
|
|
/* To do: CARRIER_DEACTIVATED */
|
|
}
|
|
if (0U != (acmInfo->dteStatus & (uint8_t)USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE))
|
|
{
|
|
/* DTE_ACTIVATED */
|
|
if (1U == serialUsbCdc->attach)
|
|
{
|
|
serialUsbCdc->startTransactions = 1U;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* DTE_DEACTIVATED */
|
|
if (1U == serialUsbCdc->attach)
|
|
{
|
|
serialUsbCdc->startTransactions = 0U;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceCdcEventSendBreak:
|
|
break;
|
|
default:; /* MISRA C-2012 Rule 16.4 */
|
|
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.
|
|
*/
|
|
static usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
usb_status_t error = kStatus_USB_InvalidRequest;
|
|
uint16_t *temp16 = (uint16_t *)param;
|
|
uint8_t *temp8 = (uint8_t *)param;
|
|
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
|
|
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
|
|
usb_status_t usbState;
|
|
#endif
|
|
|
|
serialUsbCdc = USB_DeviceGetInstanceFromDeviceHandle(s_UsbCdcHead, handle);
|
|
if (NULL == serialUsbCdc)
|
|
{
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
|
|
switch ((usb_device_event_t)event)
|
|
{
|
|
case kUSB_DeviceEventBusReset:
|
|
{
|
|
serialUsbCdc->attach = 0U;
|
|
serialUsbCdc->startTransactions = 0U;
|
|
error = kStatus_USB_Success;
|
|
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
|
|
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
|
|
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
|
|
usbState = USB_DeviceClassGetSpeed(serialUsbCdc->instance, &serialUsbCdc->speed);
|
|
(void)usbState; /* Fix MISRA C-2012 Rule 2.2: declared but never referenced */
|
|
if (kStatus_USB_Success == usbState)
|
|
{
|
|
(void)USB_DeviceSetSpeed(handle, serialUsbCdc->speed);
|
|
}
|
|
#endif
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventSetConfiguration:
|
|
if (NULL != param)
|
|
{
|
|
serialUsbCdc->attach = 1U;
|
|
serialUsbCdc->currentConfiguration = *temp8;
|
|
if ((uint8_t)USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
|
|
{
|
|
/* Schedule buffer for receive */
|
|
(void)Serial_UsbCdcRead(serialUsbCdc, s_currRecvBuf,
|
|
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
|
|
error = kStatus_USB_Success;
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventSetInterface:
|
|
if (0U != serialUsbCdc->attach)
|
|
{
|
|
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
|
|
uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);
|
|
if (interface < (uint8_t)USB_CDC_VCOM_INTERFACE_COUNT)
|
|
{
|
|
serialUsbCdc->currentInterfaceAlternateSetting[interface] = alternateSetting;
|
|
error = kStatus_USB_Success;
|
|
}
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventGetConfiguration:
|
|
break;
|
|
case kUSB_DeviceEventGetInterface:
|
|
break;
|
|
case kUSB_DeviceEventGetDeviceDescriptor:
|
|
if (NULL != param)
|
|
{
|
|
error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param);
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventGetConfigurationDescriptor:
|
|
if (NULL != param)
|
|
{
|
|
error = USB_DeviceGetConfigurationDescriptor(handle,
|
|
(usb_device_get_configuration_descriptor_struct_t *)param);
|
|
}
|
|
break;
|
|
case kUSB_DeviceEventGetStringDescriptor:
|
|
if (NULL != param)
|
|
{
|
|
/* Get device string descriptor request */
|
|
error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);
|
|
}
|
|
break;
|
|
default:
|
|
/* MISRA C-2012 Rule 16.4 */
|
|
break;
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U))
|
|
#ifndef SERIAL_PORT_USB_CDC_USB_OTG2_IRQ_HANDLER_DISABLE
|
|
void USB_OTG2_IRQHandler(void);
|
|
void USB_OTG2_IRQHandler(void)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc = s_UsbCdcHead;
|
|
|
|
while (NULL != serialUsbCdc)
|
|
{
|
|
if ((uint8_t)kSerialManager_UsbControllerEhci1 == serialUsbCdc->instance)
|
|
{
|
|
USB_DeviceEhciIsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
serialUsbCdc = serialUsbCdc->next;
|
|
}
|
|
}
|
|
#endif /* SERIAL_PORT_USB_CDC_USB_OTG2_IRQ_HANDLER_DISABLE */
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
|
|
#ifndef SERIAL_PORT_USB_CDC_USBHS_IRQ_HANDLER_DISABLE
|
|
void USBHS_IRQHandler(void);
|
|
void USBHS_IRQHandler(void)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc = s_UsbCdcHead;
|
|
|
|
while (NULL != serialUsbCdc)
|
|
{
|
|
if ((uint8_t)kSerialManager_UsbControllerEhci0 == serialUsbCdc->instance)
|
|
{
|
|
USB_DeviceEhciIsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
serialUsbCdc = serialUsbCdc->next;
|
|
}
|
|
SDK_ISR_EXIT_BARRIER;
|
|
}
|
|
#endif /* SERIAL_PORT_USB_CDC_USBHS_IRQ_HANDLER_DISABLE */
|
|
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 1U)
|
|
#if defined(FSL_FEATURE_USBHS_EHCI_COUNT) && (FSL_FEATURE_USBHS_EHCI_COUNT > 1U)
|
|
#ifndef SERIAL_PORT_USB_CDC_USB1_IRQ_HANDLER_DISABLE
|
|
void USB1_IRQHandler(void);
|
|
void USB1_IRQHandler(void)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc = s_UsbCdcHead;
|
|
|
|
while (serialUsbCdc)
|
|
{
|
|
if ((kSerialManager_UsbControllerEhci1 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceEhciIsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
serialUsbCdc = serialUsbCdc->next;
|
|
}
|
|
SDK_ISR_EXIT_BARRIER;
|
|
}
|
|
#endif /* SERIAL_PORT_USB_CDC_USB1_IRQ_HANDLER_DISABLE */
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
|
|
#ifndef SERIAL_PORT_USB_CDC_USB0_IRQ_HANDLER_DISABLE
|
|
void USB0_IRQHandler(void);
|
|
void USB0_IRQHandler(void)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc = s_UsbCdcHead;
|
|
|
|
while (NULL != serialUsbCdc)
|
|
{
|
|
if (((uint8_t)kSerialManager_UsbControllerKhci0 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceKhciIsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
serialUsbCdc = serialUsbCdc->next;
|
|
}
|
|
SDK_ISR_EXIT_BARRIER;
|
|
}
|
|
#endif /* SERIAL_PORT_USB_CDC_USB0_IRQ_HANDLER_DISABLE */
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
|
#ifndef SERIAL_PORT_USB_CDC_USB0_IRQ_HANDLER_DISABLE
|
|
void USB0_IRQHandler(void);
|
|
void USB0_IRQHandler(void)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc = s_UsbCdcHead;
|
|
|
|
while (NULL != serialUsbCdc)
|
|
{
|
|
if (((uint8_t)kSerialManager_UsbControllerLpcIp3511Fs0 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceLpcIp3511IsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
serialUsbCdc = serialUsbCdc->next;
|
|
}
|
|
SDK_ISR_EXIT_BARRIER;
|
|
}
|
|
#endif /* SERIAL_PORT_USB_CDC_USB0_IRQ_HANDLER_DISABLE */
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
|
#ifndef SERIAL_PORT_USB_CDC_USB1_IRQ_HANDLER_DISABLE
|
|
void USB1_IRQHandler(void);
|
|
void USB1_IRQHandler(void)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc = s_UsbCdcHead;
|
|
|
|
while (NULL != serialUsbCdc)
|
|
{
|
|
if (((uint8_t)kSerialManager_UsbControllerLpcIp3511Hs0 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceLpcIp3511IsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
serialUsbCdc = serialUsbCdc->next;
|
|
}
|
|
SDK_ISR_EXIT_BARRIER;
|
|
}
|
|
#endif /* SERIAL_PORT_USB_CDC_USB1_IRQ_HANDLER_DISABLE */
|
|
#endif
|
|
|
|
static void USB_DeviceIsrEnable(serial_usb_cdc_state_t *serialUsbCdc)
|
|
{
|
|
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
|
|
IRQn_Type usbDeviceEhciIrq[] = USBHS_IRQS;
|
|
serialUsbCdc->irqNumber =
|
|
(uint8_t)usbDeviceEhciIrq[serialUsbCdc->instance - (uint8_t)kSerialManager_UsbControllerEhci0];
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
|
|
IRQn_Type usbDeviceKhciIrq[] = USB_IRQS;
|
|
serialUsbCdc->irqNumber =
|
|
(uint8_t)usbDeviceKhciIrq[serialUsbCdc->instance - (uint8_t)kSerialManager_UsbControllerKhci0];
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
|
IRQn_Type usbDeviceIP3511Irq[] = USB_IRQS;
|
|
serialUsbCdc->irqNumber =
|
|
(uint8_t)usbDeviceIP3511Irq[serialUsbCdc->instance - (uint8_t)kSerialManager_UsbControllerLpcIp3511Fs0];
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
|
IRQn_Type usbDeviceIP3511Irq[] = USBHSD_IRQS;
|
|
serialUsbCdc->irqNumber =
|
|
(uint8_t)usbDeviceIP3511Irq[serialUsbCdc->instance - (uint8_t)kSerialManager_UsbControllerLpcIp3511Hs0];
|
|
#endif
|
|
|
|
/* Install isr, set priority, and enable IRQ. */
|
|
#if defined(__GIC_PRIO_BITS)
|
|
GIC_SetPriority((IRQn_Type)serialUsbCdc->irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
|
|
#else
|
|
NVIC_SetPriority((IRQn_Type)serialUsbCdc->irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
|
|
#endif
|
|
(void)EnableIRQ((IRQn_Type)serialUsbCdc->irqNumber);
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcInit(serial_handle_t serialHandle, void *config)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
serial_port_usb_cdc_config_t *usbCdcConfig;
|
|
usb_status_t usbState;
|
|
|
|
assert(config);
|
|
assert(serialHandle);
|
|
assert(SERIAL_PORT_USB_CDC_HANDLE_SIZE >= sizeof(serial_usb_cdc_state_t));
|
|
|
|
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
|
|
SYSMPU_Enable(SYSMPU, (bool)false);
|
|
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
|
|
|
|
usbCdcConfig = (serial_port_usb_cdc_config_t *)config;
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
serialUsbCdc->speed = USB_SPEED_FULL;
|
|
serialUsbCdc->instance = (uint8_t)usbCdcConfig->controllerIndex;
|
|
|
|
usbState = USB_DeviceClassInit(serialUsbCdc->instance, &s_cdcAcmConfigList, &serialUsbCdc->deviceHandle);
|
|
if (kStatus_USB_Success != usbState)
|
|
{
|
|
return kStatus_SerialManager_Error;
|
|
}
|
|
else
|
|
{
|
|
serialUsbCdc->cdcAcmHandle = s_cdcAcmConfigList.config->classHandle;
|
|
}
|
|
|
|
(void)USB_DeviceAddItem(&s_UsbCdcHead, serialUsbCdc);
|
|
|
|
USB_DeviceIsrEnable(serialUsbCdc);
|
|
|
|
/*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/
|
|
SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
|
|
(void)USB_DeviceRun(serialUsbCdc->deviceHandle);
|
|
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcDeinit(serial_handle_t serialHandle)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
usb_status_t usbState;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
usbState = USB_DeviceClassDeinit(serialUsbCdc->instance);
|
|
if (kStatus_USB_Success != usbState)
|
|
{
|
|
return kStatus_SerialManager_Error;
|
|
}
|
|
else
|
|
{
|
|
(void)USB_DeviceRemoveItem(&s_UsbCdcHead, serialUsbCdc);
|
|
}
|
|
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
uint32_t needToPrime = 0;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
if (0U != serialUsbCdc->tx.busy)
|
|
{
|
|
return kStatus_SerialManager_Busy;
|
|
}
|
|
|
|
#if (defined(USB_CDC_SERIAL_MANAGER_RUN_NO_HOST) && (USB_CDC_SERIAL_MANAGER_RUN_NO_HOST == 1))
|
|
/* Prevents SerialManager_Write from blocking when no USB Host is attached */
|
|
if ((serialUsbCdc->attach == 0U))
|
|
{
|
|
return kStatus_SerialManager_NotConnected;
|
|
}
|
|
|
|
/* Prevents SerialManager_Write from blocking when USB Host is attached but CDC terminal is closed */
|
|
if ((serialUsbCdc->attach == 1U) && (serialUsbCdc->startTransactions == 0U))
|
|
{
|
|
return kStatus_SerialManager_NotConnected;
|
|
}
|
|
#endif /* USB_CDC_SERIAL_MANAGER_RUN_NO_HOST == 1 */
|
|
|
|
serialUsbCdc->tx.busy = 1U;
|
|
serialUsbCdc->tx.waiting4Prime = 0U;
|
|
|
|
serialUsbCdc->tx.buffer = buffer;
|
|
serialUsbCdc->tx.length = length;
|
|
|
|
if (0U != serialUsbCdc->attach)
|
|
{
|
|
needToPrime = 1U;
|
|
}
|
|
|
|
if (0U != needToPrime)
|
|
{
|
|
if (kStatus_USB_Success !=
|
|
USB_DeviceCdcAcmSend(serialUsbCdc->cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, buffer, length))
|
|
{
|
|
serialUsbCdc->tx.busy = 0U;
|
|
return kStatus_SerialManager_Error;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
serialUsbCdc->tx.waiting4Prime = 1;
|
|
}
|
|
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
uint8_t *primeBuffer;
|
|
uint32_t primeLength;
|
|
uint32_t regPrimask;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
if (0U == serialUsbCdc->attach)
|
|
{
|
|
return kStatus_SerialManager_Error;
|
|
}
|
|
|
|
regPrimask = DisableGlobalIRQ();
|
|
if (0U != serialUsbCdc->rx.busy)
|
|
{
|
|
EnableGlobalIRQ(regPrimask);
|
|
return kStatus_SerialManager_Busy;
|
|
}
|
|
serialUsbCdc->rx.busy = 1U;
|
|
EnableGlobalIRQ(regPrimask);
|
|
|
|
if (length < g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize)
|
|
{
|
|
serialUsbCdc->rx.busy = 0U;
|
|
return kStatus_SerialManager_Error;
|
|
}
|
|
|
|
if (NULL == buffer)
|
|
{
|
|
primeBuffer = s_currRecvBuf;
|
|
primeLength = g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize;
|
|
}
|
|
else
|
|
{
|
|
primeBuffer = buffer;
|
|
primeLength = length;
|
|
}
|
|
/* Schedule buffer for next receive event */
|
|
|
|
if (kStatus_USB_Success !=
|
|
USB_DeviceCdcAcmRecv(serialUsbCdc->cdcAcmHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, primeBuffer, primeLength))
|
|
{
|
|
serialUsbCdc->rx.busy = 0U;
|
|
return kStatus_SerialManager_Error;
|
|
}
|
|
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcCancelWrite(serial_handle_t serialHandle)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
(void)USB_DeviceCancel(serialUsbCdc->deviceHandle, (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT) |
|
|
(uint8_t)USB_CDC_VCOM_BULK_IN_ENDPOINT);
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcInstallTxCallback(serial_handle_t serialHandle,
|
|
serial_manager_callback_t callback,
|
|
void *callbackParam)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
serialUsbCdc->tx.callback = callback;
|
|
serialUsbCdc->tx.callbackParam = callbackParam;
|
|
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
serial_manager_status_t Serial_UsbCdcInstallRxCallback(serial_handle_t serialHandle,
|
|
serial_manager_callback_t callback,
|
|
void *callbackParam)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
serialUsbCdc->rx.callback = callback;
|
|
serialUsbCdc->rx.callbackParam = callbackParam;
|
|
|
|
return kStatus_SerialManager_Success;
|
|
}
|
|
|
|
void Serial_UsbCdcIsrFunction(serial_handle_t serialHandle)
|
|
{
|
|
serial_usb_cdc_state_t *serialUsbCdc;
|
|
|
|
assert(serialHandle);
|
|
|
|
serialUsbCdc = (serial_usb_cdc_state_t *)serialHandle;
|
|
|
|
#if 0
|
|
DisableIRQ((IRQn_Type)serialUsbCdc->irqNumber);
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
|
|
if (((uint8_t)kSerialManager_UsbControllerEhci0 == serialUsbCdc->instance) ||
|
|
((uint8_t)kSerialManager_UsbControllerEhci1 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceEhciIsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
|
|
if (((uint8_t)kSerialManager_UsbControllerKhci0 == serialUsbCdc->instance) ||
|
|
((uint8_t)kSerialManager_UsbControllerKhci1 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceKhciIsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
#endif
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
|
if (((uint8_t)kSerialManager_UsbControllerLpcIp3511Fs0 == serialUsbCdc->instance) ||
|
|
((uint8_t)kSerialManager_UsbControllerLpcIp3511Fs1 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceLpcIp3511IsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
#endif
|
|
|
|
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
|
if (((uint8_t)kSerialManager_UsbControllerLpcIp3511Hs0 == serialUsbCdc->instance) ||
|
|
((uint8_t)kSerialManager_UsbControllerLpcIp3511Hs1 == serialUsbCdc->instance))
|
|
{
|
|
USB_DeviceLpcIp3511IsrFunction(serialUsbCdc->deviceHandle);
|
|
}
|
|
#endif
|
|
#if 0
|
|
EnableIRQ((IRQn_Type)serialUsbCdc->irqNumber);
|
|
#endif
|
|
}
|
|
#endif
|