Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 66 additions & 46 deletions common/usbx_device_classes/inc/ux_device_class_cdc_acm.h
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
*
* SPDX-License-Identifier: MIT
**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** USBX Component */
/** */
/** CDC Class */
/** */
/**************************************************************************/
/**************************************************************************/

/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_cdc_acm.h PORTABLE C */
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_cdc_acm.h PORTABLE C */
/* 6.3.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the equivalences for the USBX Device Class CDC */
/* ACM component. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* */
/* This file defines the equivalences for the USBX Device Class CDC */
/* ACM component. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
/* used UX prefix to refer to */
Expand Down Expand Up @@ -69,15 +69,15 @@
#ifndef UX_DEVICE_CLASS_CDC_ACM_H
#define UX_DEVICE_CLASS_CDC_ACM_H

/* Determine if a C++ compiler is being used. If so, ensure that standard
C is used to process the API information. */
/* Determine if a C++ compiler is being used. If so, ensure that standard
C is used to process the API information. */

#ifdef __cplusplus
#ifdef __cplusplus

/* Yes, C++ compiler is present. Use standard C. */
extern "C" {
/* Yes, C++ compiler is present. Use standard C. */
extern "C" {

#endif
#endif

/* Internal option: enable the basic USBX error checking. This define is typically used
while debugging application. */
Expand All @@ -89,6 +89,12 @@ extern "C" {

/* #define UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP */


/* Option: enable CDC ACM interrupt notifications (Serial State / Line State Change).
When defined, the CDC ACM device class can send status notifications to the host
via an Interrupt IN endpoint (if present in the interface). */
/* #define UX_DEVICE_CLASS_CDC_ACM_ENABLE_NOTIFICATIONS */

/* Option: bulk out endpoint / read buffer size, must be larger than max packet size in framework, and aligned in 4-bytes. */
#ifndef UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE
#define UX_DEVICE_CLASS_CDC_ACM_READ_BUFFER_SIZE 512
Expand Down Expand Up @@ -116,7 +122,8 @@ extern "C" {


/* Define CDC Class USB Class constants. */
#define UX_SLAVE_CLASS_CDC_ACM_CLASS 10
#define UX_SLAVE_CLASS_CDC_ACM_CONTROL_CLASS 0x02
#define UX_SLAVE_CLASS_CDC_ACM_DATA_CLASS 0x0A

/* Device CDC Requests */
#define UX_SLAVE_CLASS_CDC_ACM_SEND_ENCAPSULATED_COMMAND 0x00
Expand Down Expand Up @@ -172,6 +179,15 @@ extern "C" {
#define UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_DTR 1
#define UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_RTS 2

/* Define CDC ACM UART state bitmap (Serial State data). */
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_DCD 0x0001
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_DSR 0x0002
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_BREAK 0x0004
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_RING_SIGNAL 0x0008
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_FRAMING 0x0010
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_PARITY 0x0020
#define UX_DEVICE_CLASS_CDC_ACM_UART_STATE_OVERRUN 0x0040

/* Define Transfer direction bits. */
#define UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_XMIT 1
#define UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_RCV 2
Expand Down Expand Up @@ -253,6 +269,10 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT
UCHAR ux_slave_class_cdc_acm_data_rts_state;
UCHAR reserved[3];

#if defined(UX_DEVICE_CLASS_CDC_ACM_ENABLE_NOTIFICATIONS)
USHORT ux_device_class_cdc_acm_serial_state;
#endif

#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
#if !defined(UX_DEVICE_STANDALONE)
UX_THREAD ux_slave_class_cdc_acm_bulkin_thread;
Expand Down Expand Up @@ -289,23 +309,23 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT

/* Define some CDC Class structures */

typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER_STRUCT
typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER_STRUCT
{
ULONG ux_slave_class_cdc_acm_parameter_baudrate;
UCHAR ux_slave_class_cdc_acm_parameter_stop_bit;
UCHAR ux_slave_class_cdc_acm_parameter_parity;
UCHAR ux_slave_class_cdc_acm_parameter_data_bit;

} UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER;

typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER_STRUCT
typedef struct UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER_STRUCT
{
UCHAR ux_slave_class_cdc_acm_parameter_rts;
UCHAR ux_slave_class_cdc_acm_parameter_dtr;

} UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER;

typedef struct UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER_STRUCT
typedef struct UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER_STRUCT
{
UINT (*ux_device_class_cdc_acm_parameter_write_callback)(struct UX_SLAVE_CLASS_CDC_ACM_STRUCT *cdc_acm, UINT status, ULONG length);
UINT (*ux_device_class_cdc_acm_parameter_read_callback)(struct UX_SLAVE_CLASS_CDC_ACM_STRUCT *cdc_acm, UINT status, UCHAR *data_pointer, ULONG length);
Expand All @@ -316,22 +336,22 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER_STRUCT

/* Requests - Ethernet Networking Control Model */

#define UX_SLAVE_CLASS_CDC_ACM_SEND_ENCAPSULATED_COMMAND 0x00
#define UX_SLAVE_CLASS_CDC_ACM_SEND_ENCAPSULATED_COMMAND 0x00
/* Issues a command in the format of the supported control
protocol. The intent of this mechanism is to support
networking devices (e.g., host-based cable modems)
that require an additional vendor-defined interface for
media specific hardware configuration and
management. */
#define UX_SLAVE_CLASS_CDC_ACM_GET_ENCAPSULATED_RESPONSE 0x01
#define UX_SLAVE_CLASS_CDC_ACM_GET_ENCAPSULATED_RESPONSE 0x01
/* Requests a response in the format of the supported
control protocol. */
#define UX_SLAVE_CLASS_CDC_ACM_SET_ETHERNET_MULTICAST_FILTERS 0x40
#define UX_SLAVE_CLASS_CDC_ACM_SET_ETHERNET_MULTICAST_FILTERS 0x40
/* As applications are loaded and unloaded on the host,
the networking transport will instruct the device's MAC
driver to change settings of the Networking device's
multicast filters. */
#define UX_SLAVE_CLASS_CDC_ACM_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x41
#define UX_SLAVE_CLASS_CDC_ACM_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x41
/* Some hosts are able to conserve energy and stay quiet
in a 'sleeping' state while not being used. USB
Networking devices may provide special pattern filtering
Expand All @@ -340,13 +360,13 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER_STRUCT
host (e.g., an incoming web browser connection).
Primitives are needed in management plane to negotiate
the setting of these special filters */
#define UX_SLAVE_CLASS_CDC_ACM_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x42
#define UX_SLAVE_CLASS_CDC_ACM_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x42
/* Retrieves the status of the above power management
pattern filter setting */
#define UX_SLAVE_CLASS_CDC_ACM_SET_ETHERNET_PACKET_FILTER 0x43
#define UX_SLAVE_CLASS_CDC_ACM_SET_ETHERNET_PACKET_FILTER 0x43
/* Sets device filter for running a network analyzer
application on the host machine */
#define UX_SLAVE_CLASS_CDC_ACM_GET_ETHERNET_STATISTIC 0x44
#define UX_SLAVE_CLASS_CDC_ACM_GET_ETHERNET_STATISTIC 0x44
/* Retrieves Ethernet device statistics such as frames
transmitted, frames received, and bad frames received. */

Expand All @@ -363,20 +383,20 @@ UINT _ux_device_class_cdc_acm_deactivate(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_cdc_acm_initialize(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_cdc_acm_uninitialize(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_cdc_acm_write(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
UINT _ux_device_class_cdc_acm_write(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_device_class_cdc_acm_read(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
UINT _ux_device_class_cdc_acm_read(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_device_class_cdc_acm_ioctl(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, ULONG ioctl_function,
VOID *parameter);
VOID _ux_device_class_cdc_acm_bulkin_thread(ULONG class_pointer);
VOID _ux_device_class_cdc_acm_bulkout_thread(ULONG class_pointer);
UINT _ux_device_class_cdc_acm_write_with_callback(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
UINT _ux_device_class_cdc_acm_write_with_callback(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
ULONG requested_length);

UINT _ux_device_class_cdc_acm_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
UINT _ux_device_class_cdc_acm_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_device_class_cdc_acm_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
UINT _ux_device_class_cdc_acm_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length);

UINT _ux_device_class_cdc_acm_tasks_run(VOID *instance);
Expand Down Expand Up @@ -419,10 +439,10 @@ UINT _uxe_device_class_cdc_acm_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR

#endif

/* Determine if a C++ compiler is being used. If so, complete the standard
C conditional started above. */
/* Determine if a C++ compiler is being used. If so, complete the standard
C conditional started above. */
#ifdef __cplusplus
}
#endif
}
#endif

#endif /* UX_DEVICE_CLASS_CDC_ACM_H */
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
*
* SPDX-License-Identifier: MIT
**************************************************************************/

Expand All @@ -13,7 +13,7 @@
/** */
/** USBX Component */
/** */
/** Device CDC_ACM Class */
/** Device CDC ACM Class */
/** */
/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -123,11 +123,19 @@ ULONG sent_length;
/* This is the first time we are activated. We need the interface to the class. */
interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface;

/* Locate data interface. */
if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass != UX_SLAVE_CLASS_CDC_ACM_DATA_CLASS)
{
/* So the next interface is data interface. */
interface_ptr = interface_ptr -> ux_slave_interface_next_interface;
}

/* Locate the endpoints. */
endpoint = interface_ptr -> ux_slave_interface_first_endpoint;

/* Check the endpoint direction, if IN we have the correct endpoint. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN)
if (((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) ||
((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) != UX_BULK_ENDPOINT))
{

/* So the next endpoint has to be the IN endpoint. */
Expand Down Expand Up @@ -278,8 +286,9 @@ ULONG sent_length;
}
}

/* We need to suspend ourselves. We will be resumed by the device enumeration module or when a change of alternate setting happens. */
_ux_device_thread_suspend(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread);
/* We need to suspend ourselves. We will be resumed by the device enumeration
module or when a change of alternate setting happens. */
_ux_device_thread_suspend(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread);
}
}
#endif
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
*
* SPDX-License-Identifier: MIT
**************************************************************************/

Expand All @@ -13,7 +13,7 @@
/** */
/** USBX Component */
/** */
/** Device CDC_ACM Class */
/** Device CDC ACM Class */
/** */
/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -108,11 +108,19 @@ UINT status;
/* This is the first time we are activated. We need the interface to the class. */
interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface;

/* Locate data interface. */
if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass != UX_SLAVE_CLASS_CDC_ACM_DATA_CLASS)
{
/* So the next interface is data interface. */
interface_ptr = interface_ptr -> ux_slave_interface_next_interface;
}

/* Locate the endpoints. */
endpoint = interface_ptr -> ux_slave_interface_first_endpoint;

/* Check the endpoint direction, if OUT we have the correct endpoint. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT)
if (((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT) ||
((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) != UX_BULK_ENDPOINT))
{

/* So the next endpoint has to be the OUT endpoint. */
Expand Down
Loading
Loading