141 changes: 141 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_control_abort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_control_abort PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles control request Abort of the USB CCID device. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* slot Slot to abort */
/* seq Sequence number of message */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq)
{

UX_DEVICE_CLASS_CCID_PARAMETER *parameter;
UX_DEVICE_CLASS_CCID_HANDLES *handles;
UX_DEVICE_CLASS_CCID_SLOT *ccid_slot;
UX_SLAVE_TRANSFER *transfer_in, *transfer_out;
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *msg;

/* Get parameter. */
parameter = &ccid -> ux_device_class_ccid_parameter;
handles = parameter -> ux_device_class_ccid_handles;

/* Check if slot is available. */
if (slot >= parameter -> ux_device_class_ccid_max_n_slots)
return(UX_INVALID_PARAMETER);

/* Check if command is supported. */
if (handles -> ux_device_class_ccid_handles_abort == UX_NULL)
return(UX_FUNCTION_NOT_SUPPORTED);

/* Get slot to process. */
ccid_slot = &ccid -> ux_device_class_ccid_slots[slot];

/* Check if message header received. */
transfer_out = &ccid -> ux_device_class_ccid_endpoint_out ->
ux_slave_endpoint_transfer_request;
if (transfer_out -> ux_slave_transfer_request_actual_length <
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH)
{

/* Message header not available, cancel current bulk OUT transfer. */
_ux_device_stack_transfer_abort(transfer_out, UX_ABORTED);
}
else
{

/* Message header available, check message. */
msg = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *)
transfer_out -> ux_slave_transfer_request_data_pointer;

/* Check if abort applies to the slot. */
if (msg -> bSlot == (UCHAR)slot)
{

/* Yes, aborting current message, cancel current bulk OUT transfer. */
_ux_device_stack_transfer_abort(transfer_out, UX_ABORTED);
}
else
{

/* Aborting another slot. */

/* Check slot busy. */
if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner >= 0)
{

/* Possible sending something, abort IN transfer. */
transfer_in = &ccid -> ux_device_class_ccid_endpoint_in ->
ux_slave_endpoint_transfer_request;
_ux_device_stack_transfer_abort(transfer_in, UX_ABORTED);
}
}
}

/* Set aborting state. */
ccid_slot -> ux_device_class_ccid_slot_aborting = UX_TRUE;
ccid_slot -> ux_device_class_ccid_slot_aborting_seq = (UCHAR)seq;

/* Invoke control abort to let application do something. */
handles -> ux_device_class_ccid_handles_abort(slot, UX_NULL);
return(UX_SUCCESS);
}
167 changes: 167 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_control_request.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_control_request PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function manages the requests sent by the host on the control */
/* endpoints with a CLASS or VENDOR SPECIFIC type. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid class */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Transfer request */
/* _ux_device_class_ccid_request_abort Abort slot */
/* _ux_utility_memory_copy Copy memory */
/* */
/* CALLED BY */
/* */
/* CCID Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_control_request(UX_SLAVE_CLASS_COMMAND *command)
{
UX_DEVICE_CLASS_CCID *ccid;
UX_DEVICE_CLASS_CCID_PARAMETER *parameter;
UX_SLAVE_CLASS *ccid_class;
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_DEVICE *device;
ULONG request;
UCHAR seq, slot;
ULONG request_length;
ULONG transmit_length;
UCHAR *transmit_buffer;

/* Get the class container. */
ccid_class = command -> ux_slave_class_command_class_ptr;

/* Get the class instance in the container. */
ccid = (UX_DEVICE_CLASS_CCID *) ccid_class -> ux_slave_class_instance;

/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;

/* Get the pointer to the transfer request associated with the control endpoint. */
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;

/* Extract all necessary fields of the request. */
request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST);

/* Pickup the request length. */
request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH);

/* Here we proceed only the standard request we know of at the device level. */
switch (request)
{

case UX_DEVICE_CLASS_CCID_ABORT:
slot = transfer_request -> ux_slave_transfer_request_setup[UX_SETUP_VALUE];
seq = transfer_request -> ux_slave_transfer_request_setup[UX_SETUP_VALUE + 1];
return _ux_device_class_ccid_control_abort(ccid, slot, seq);

case UX_DEVICE_CLASS_CCID_GET_CLOCK_FREQUENCIES:
parameter = &ccid -> ux_device_class_ccid_parameter;

/* Check bNumClockSuppored. */
if (parameter -> ux_device_class_ccid_clocks == UX_NULL ||
parameter -> ux_device_class_ccid_n_clocks == 0)
return(UX_ERROR);

/* Calculate transmit length. */
transmit_length = parameter -> ux_device_class_ccid_n_clocks;
if (UX_OVERFLOW_CHECK_MULC_ULONG(transmit_length, 4))
return(UX_ERROR);
transmit_length <<= 2;

/* Update transmit buffer. */
transmit_buffer = (UCHAR *)parameter -> ux_device_class_ccid_clocks;
break;

case UX_DEVICE_CLASS_CCID_GET_DATA_RATES:
parameter = &ccid -> ux_device_class_ccid_parameter;

/* Check bNumDataRateSuppored. */
if (parameter -> ux_device_class_ccid_data_rates == UX_NULL ||
parameter -> ux_device_class_ccid_n_data_rates == 0)
return(UX_ERROR);

/* Calculate transmit length. */
transmit_length = parameter -> ux_device_class_ccid_n_data_rates;
if (UX_OVERFLOW_CHECK_MULC_ULONG(transmit_length, 4))
return(UX_ERROR);
transmit_length <<= 2;

/* Update transmit buffer. */
transmit_buffer = (UCHAR *)parameter -> ux_device_class_ccid_data_rates;
break ;

default:

/* Unknown function. It's not handled. */
return(UX_ERROR);
}

/* Limit transmit length. */
transmit_length = UX_MIN(transmit_length, UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH);
transmit_length = UX_MIN(transmit_length, request_length);

/* Copy data to transmit. */
_ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
transmit_buffer, transmit_length); /* Use case of memcpy is verified. */

/* Transmit. */
_ux_device_stack_transfer_request(transfer_request, transmit_length, request_length);

/* It's handled. */
return(UX_SUCCESS);
}
110 changes: 110 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_deactivate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_deactivate PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deactivate an instance of the ccid class. */
/* */
/* INPUT */
/* */
/* command Pointer to a class command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_all_request_abort */
/* Abort all transfers */
/* */
/* CALLED BY */
/* */
/* CCID Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_deactivate(UX_SLAVE_CLASS_COMMAND *command)
{

UX_DEVICE_CLASS_CCID *ccid;
UX_SLAVE_CLASS *ccid_class;
UX_SLAVE_ENDPOINT *endpoint;

/* Get the class container. */
ccid_class = command -> ux_slave_class_command_class_ptr;

/* Get the class instance in the container. */
ccid = (UX_DEVICE_CLASS_CCID *) ccid_class -> ux_slave_class_instance;

/* Terminate the transactions pending on the endpoints. */
endpoint = ccid -> ux_device_class_ccid_endpoint_out;
_ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET);

endpoint = ccid -> ux_device_class_ccid_endpoint_in;
_ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET);

endpoint = ccid -> ux_device_class_ccid_endpoint_notify;
if (endpoint)
_ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET);

/* If there is a deactivate function call it. */
if (ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_deactivate != UX_NULL)
{

/* Invoke the application. */
ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_deactivate(ccid);
}

/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CCID_DEACTIVATE, ccid, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)

/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_UNREGISTER(ccid);

/* Return completion status. */
return(UX_SUCCESS);
}
146 changes: 146 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_entry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_entry PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the entry point of the device CCID class. It */
/* will be called by the device stack enumeration module when the */
/* host has sent a SET_CONFIGURATION command and the ccid interface */
/* needs to be mounted. */
/* */
/* INPUT */
/* */
/* command Pointer to class command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_class_ccid_initialize Initialize ccid class */
/* _ux_device_class_ccid_uninitialize Uninitialize ccid class */
/* _ux_device_class_ccid_activate Activate ccid class */
/* _ux_device_class_ccid_deactivate Deactivate ccid class */
/* _ux_device_class_ccid_control_request Request control */
/* */
/* CALLED BY */
/* */
/* USBX Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_entry(UX_SLAVE_CLASS_COMMAND *command)
{

UINT status;


/* The command request will tell us we need to do here, either a enumeration
query, an activation or a deactivation. */
switch (command -> ux_slave_class_command_request)
{

case UX_SLAVE_CLASS_COMMAND_INITIALIZE:

/* Call the init function of the CCID class. */
status = _ux_device_class_ccid_initialize(command);

/* Return the completion status. */
return(status);

case UX_SLAVE_CLASS_COMMAND_UNINITIALIZE:

/* Call the init function of the CCID class. */
status = _ux_device_class_ccid_uninitialize(command);

/* Return the completion status. */
return(status);

case UX_SLAVE_CLASS_COMMAND_QUERY:

/* Check the CLASS definition in the interface descriptor. */
if (command -> ux_slave_class_command_class == UX_DEVICE_CLASS_CCID_CLASS)
return(UX_SUCCESS);
else
return(UX_NO_CLASS_MATCH);

case UX_SLAVE_CLASS_COMMAND_ACTIVATE:

/* The activate command is used when the host has sent a SET_CONFIGURATION command
and this interface has to be mounted. Both Bulk endpoints have to be mounted
and the ccid thread needs to be activated. */
status = _ux_device_class_ccid_activate(command);

/* Return the completion status. */
return(status);

case UX_SLAVE_CLASS_COMMAND_DEACTIVATE:

/* The deactivate command is used when the device has been extracted.
The device endpoints have to be dismounted and the ccid thread canceled. */
status = _ux_device_class_ccid_deactivate(command);

/* Return the completion status. */
return(status);

case UX_SLAVE_CLASS_COMMAND_REQUEST:

/* The request command is used when the host sends a command on the control endpoint. */
status = _ux_device_class_ccid_control_request(command);

/* Return the completion status. */
return(status);

default:

/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)

/* Return an error. */
return(UX_FUNCTION_NOT_SUPPORTED);
}
}
133 changes: 133 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_hardware_error.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_hardware_error PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function indicates hardware error of the USB CCID device. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* slot Slot inserted */
/* error Error code */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_hardware_error(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG error)
{

UX_DEVICE_CLASS_CCID_SLOT *ccid_slot;
UX_DEVICE_CLASS_CCID_RUNNER *runner;
UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp;

/* Sanity check. */
if (slot >= ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots)
return(UX_INVALID_PARAMETER);

/* Get slot instance. */
ccid_slot = ccid -> ux_device_class_ccid_slots;
ccid_slot += slot;

/* Lock states. */
_ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex);

/* Check error. */
if (!(ccid_slot -> ux_device_class_ccid_slot_flags & UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR))
{

/* Save error and error code. */
ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR;
ccid_slot -> ux_device_class_ccid_slot_hw_error = (UCHAR)error;
ccid_slot -> ux_device_class_ccid_slot_hw_error_seq = 0;

/* Slot deactivated. */
ccid_slot -> ux_device_class_ccid_slot_icc_status = UX_DEVICE_CLASS_CCID_ICC_INACTIVE;

/* Check if command is pending, update response buffer. */
if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner >= 0)
{

/* Get running things. */
runner = ccid -> ux_device_class_ccid_runners;
runner += ccid_slot -> ux_device_class_ccid_slot_runner;
rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *)
runner -> ux_device_class_ccid_runner_response;

/* Response: (1,1,HW_ERROR). */
rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(1, 1);
rsp -> bError = UX_DEVICE_CLASS_CCID_HW_ERROR;
}
}

/* Notify if interrupt endpoint exists. */
if (ccid -> ux_device_class_ccid_endpoint_notify)
{
ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE;

/* Unlock states. */
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);

/* Wakeup interrupt notification. */
_ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore);
return(UX_SUCCESS);
}

/* Unlock states. */
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);

/* Return transfer status. */
return(UX_SUCCESS);
}
120 changes: 120 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_icc_insert.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_icc_insert PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function indicates card insertion of the USB CCID device. */
/* */
/* Note if seq_start is TRUE, application must invoke _auto_seq_done */
/* later to indicate the sequence end, with final card status. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* slot Slot inserted */
/* seq_start Auto activation sequence on */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_icc_insert(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq_start)
{

UX_DEVICE_CLASS_CCID_SLOT *ccid_slot;

/* Sanity check. */
if (slot >= ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots)
return(UX_INVALID_PARAMETER);

/* Get slot instance. */
ccid_slot = ccid -> ux_device_class_ccid_slots;
ccid_slot += slot;

/* Lock states. */
_ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex);

/* Return success if already card inserted. */
if (ccid_slot -> ux_device_class_ccid_slot_icc_status != UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT)
{
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);
return(UX_SUCCESS);
}

/* Update card status (INACTIVE). */
ccid_slot -> ux_device_class_ccid_slot_icc_status = UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_INACTIVE;

/* Auto sequencing started? */
if (seq_start)
ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING;

/* Notify if interrupt endpoint exists. */
if (ccid -> ux_device_class_ccid_endpoint_notify)
{
ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE;

/* Unlock states. */
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);

/* Wakeup interrupt notification. */
_ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore);
return(UX_SUCCESS);
}

/* Unlock states. */
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);

/* Return transfer status. */
return(UX_SUCCESS);
}
113 changes: 113 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_icc_remove.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_icc_remove PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function indicates card removal of the USB CCID device. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* slot Slot removed */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_icc_remove(UX_DEVICE_CLASS_CCID *ccid, ULONG slot)
{

UX_DEVICE_CLASS_CCID_SLOT *ccid_slot;

/* Sanity check. */
if (slot >= ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots)
return(UX_INVALID_PARAMETER);

/* Get slot instance. */
ccid_slot = ccid -> ux_device_class_ccid_slots;
ccid_slot += slot;

/* Lock states. */
_ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex);

/* Return success if already card removed. */
if (ccid_slot -> ux_device_class_ccid_slot_icc_status == UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT)
{
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);
return(UX_SUCCESS);
}

/* Update card status (NOT_PRESENT). */
ccid_slot -> ux_device_class_ccid_slot_icc_status = UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_NOT_PRESENT;

/* Clear sequencing. */
ccid_slot -> ux_device_class_ccid_slot_flags &= (UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING;

/* Clear errors. */
ccid_slot -> ux_device_class_ccid_slot_hw_error = 0;
ccid_slot -> ux_device_class_ccid_slot_flags &= (UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR;

/* Notify if interrupt endpoint exists. */
if (ccid -> ux_device_class_ccid_endpoint_notify)
{
ccid_slot -> ux_device_class_ccid_slot_flags |= UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE;
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);
_ux_device_semaphore_put(&ccid -> ux_device_class_ccid_notify_semaphore);
return(UX_SUCCESS);
}
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);

/* Return transfer status. */
return(UX_SUCCESS);
}
439 changes: 439 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_initialize.c

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"

#if !defined(UX_DEVICE_STANDALONE)
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_notify_thread_entry PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the thread of the CCID interrupt IN endpoint. It */
/* is waiting for the application event to start interrupt IN. */
/* */
/* INPUT */
/* */
/* ccid_inst Address of ccid class */
/* container (32-bit) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Request transfer */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
VOID _ux_device_class_ccid_notify_thread_entry(ULONG ccid_inst)
{

UX_SLAVE_DEVICE *device;
UX_DEVICE_CLASS_CCID *ccid;
UX_DEVICE_CLASS_CCID_SLOT *slot;
UX_DEVICE_CLASS_CCID_PARAMETER *parameter;
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_TRANSFER *transfer;
UCHAR *buffer;
ULONG length;
INT i;
UCHAR icc_mask;
UINT byte_pos, bits_pos;
UINT status;

/* Cast properly the ccid instance. */
UX_THREAD_EXTENSION_PTR_GET(ccid, UX_DEVICE_CLASS_CCID, ccid_inst)

/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;

/* This thread runs forever but can be suspended or resumed by the user application. */
status = UX_SUCCESS;
while(1)
{

/* Error cases. */
if (status != UX_SUCCESS)
{

/* We need to suspend ourselves. We will be resumed by the
application if needed. */
_ux_utility_thread_suspend(&ccid -> ux_device_class_ccid_notify_thread);
status = UX_SUCCESS;
continue;
}
status = UX_ERROR;

/* Check device state. */
if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
continue;

/* Check endpoint. */
endpoint = ccid -> ux_device_class_ccid_endpoint_notify;
if (endpoint == UX_NULL)
continue;
transfer = &endpoint -> ux_slave_endpoint_transfer_request;

/* Wait event. */
status = _ux_utility_semaphore_get(&ccid -> ux_device_class_ccid_notify_semaphore,
UX_WAIT_FOREVER);
if (status != UX_SUCCESS)
continue;

/* Build slot change/hardware error message. */
buffer = transfer -> ux_slave_transfer_request_data_pointer;
length = 0;

/* By default no message. */
buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] = 0;

/* Build slot hardware error message. */
parameter = &ccid -> ux_device_class_ccid_parameter;

_ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex);

slot = ccid -> ux_device_class_ccid_slots;
for (i = 0; i < parameter -> ux_device_class_ccid_max_n_slots; i ++)
{

/* Check if there is hardware error notification. */
if (slot -> ux_device_class_ccid_slot_flags &
UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_HW_ERROR)
{
slot -> ux_device_class_ccid_slot_flags &=
(UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_HW_ERROR;
buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] =
UX_DEVICE_CLASS_CCID_RDR_TO_PC_HARDWARE_ERROR;
buffer[UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SLOT] = (UCHAR)i;
buffer[UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_SEQ] =
slot -> ux_device_class_ccid_slot_hw_error_seq;
buffer[UX_DEVICE_CLASS_CCID_OFFSET_HW_ERROR_CODE] =
slot -> ux_device_class_ccid_slot_hw_error;
length = 4;
break;
}

/* Next slot. */
slot ++;
}

/* Build slot changes message. */
if (buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] == 0)
{

/* Scan slots. */
slot = ccid -> ux_device_class_ccid_slots;
for (i = 0, byte_pos = 1; ; byte_pos ++)
{
/* Reset bits. */
buffer[byte_pos] = 0;

/* Scan 4 slots. */
for(bits_pos = 0; bits_pos < 8; bits_pos += 2)
{

/* Slot state bit. */
icc_mask = (UCHAR)((slot -> ux_device_class_ccid_slot_icc_status ==
UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_NOT_PRESENT) ?
0u : 1u);

/* Check if there is change notification. */
if (slot -> ux_device_class_ccid_slot_flags &
UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE)
{
slot -> ux_device_class_ccid_slot_flags &=
(UCHAR)~UX_DEVICE_CLASS_CCID_FLAG_NOTIFY_CHANGE;

/* Message type. */
buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] =
UX_DEVICE_CLASS_CCID_RDR_TO_PC_NOTIFY_SLOT_CHANGE;

/* Slot change bit. */
icc_mask |= (UCHAR)0x02u;
}

/* Modify bits. */
buffer[byte_pos] |= (UCHAR)(icc_mask << bits_pos);

/* Next slot. */
i ++;
if (i >= parameter -> ux_device_class_ccid_max_n_slots)
break;
slot ++;
}
if (i >= parameter -> ux_device_class_ccid_max_n_slots)
break;
}

/* Buffer length should include last byte. */
length = byte_pos + 1;
}

_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);

/* Check message to see if there is message to send. */
if (buffer[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] == 0)
continue;

/* Send request. */
status = _ux_device_stack_transfer_request(transfer, length, length);
}
}
#endif
101 changes: 101 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_response.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_response PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sends bulk IN response of the USB CCID device. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* buffer Pointer to data buffer */
/* length Data length */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_response(UX_DEVICE_CLASS_CCID *ccid, UCHAR *buffer, ULONG length)
{

UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_TRANSFER *transfer;
UINT status;

/* Get bulk IN endpoint. */
endpoint = ccid -> ux_device_class_ccid_endpoint_in;

/* Get transfer request. */
transfer = &endpoint -> ux_slave_endpoint_transfer_request;

/* Lock bulk IN. */
_ux_device_mutex_on(&ccid -> ux_device_class_ccid_response_mutex);

/* Prepare data to transfer. */
if (length > 0 && buffer != UX_NULL &&
transfer -> ux_slave_transfer_request_data_pointer != buffer)
{
_ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
buffer, length); /* Use case of memcpy is verified. */
}

/* Transfer data. */
status = _ux_device_stack_transfer_request(transfer, length, length);

/* Unlock bulk IN. */
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_response_mutex);

/* Return transfer status. */
return(status);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


#if !defined(UX_DEVICE_STANDALONE)
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_runner_thread_entry PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the thread of the CCID command handling. It */
/* is waiting for the event to start command processing. */
/* */
/* INPUT */
/* */
/* ccid_runner Address of CCID runner (32b) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Request transfer */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
VOID _ux_device_class_ccid_runner_thread_entry(ULONG ccid_runner)
{

UX_SLAVE_DEVICE *device;
UX_DEVICE_CLASS_CCID *ccid;
UX_DEVICE_CLASS_CCID_PARAMETER *parameter;
UX_DEVICE_CLASS_CCID_HANDLE *handles;
UX_DEVICE_CLASS_CCID_HANDLE handle;
UX_DEVICE_CLASS_CCID_RUNNER *runner;
UX_DEVICE_CLASS_CCID_SLOT *slot;
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *cmd;
UX_DEVICE_CLASS_CCID_COMMAND_SETT *cmd_sett;
UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *rsp;
UX_DEVICE_CLASS_CCID_MESSAGES messages;
ULONG event_mask, flags;
ULONG cmd_checks;
UINT status;

/* Cast properly the ccid runner. */
UX_THREAD_EXTENSION_PTR_GET(runner, UX_DEVICE_CLASS_CCID_RUNNER, ccid_runner)

/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;

/* Get CCID instance. */
ccid = runner -> ux_device_class_ccid_runner_ccid;

/* Get CCID parameter. */
parameter = &ccid -> ux_device_class_ccid_parameter;

/* Get event mask to wait. */
event_mask = 1u << runner -> ux_device_class_ccid_runner_id;

/* This thread runs forever but can be suspended or resumed by the user application. */
status = UX_SUCCESS;
while(1)
{

/* Check device state. */
if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
{
_ux_utility_thread_suspend(&runner -> ux_device_class_ccid_runner_thread);
continue;
}

/* Wait signal. */
status = _ux_utility_event_flags_get(&ccid -> ux_device_class_ccid_events,
event_mask, UX_OR_CLEAR, &flags, UX_WAIT_FOREVER);
if (status != UX_SUCCESS)
{
_ux_utility_thread_suspend(&runner -> ux_device_class_ccid_runner_thread);
continue;
}

/* We have a command to process. */
cmd = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *)
runner -> ux_device_class_ccid_runner_command;
rsp = (UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS_HEADER *)
runner -> ux_device_class_ccid_runner_response;

/* Slot to handle. */
slot = ccid -> ux_device_class_ccid_slots;
slot += runner -> ux_device_class_ccid_runner_slot;

/* Command settings. */
cmd_sett = (UX_DEVICE_CLASS_CCID_COMMAND_SETT *)_ux_device_class_ccid_command_sett;
cmd_sett += runner -> ux_device_class_ccid_runner_command_index;

/* Message to pass to application. */
messages.ux_device_class_ccid_messages_pc_to_rdr = (UCHAR *)cmd;
messages.ux_device_class_ccid_messages_rdr_to_pc = (UCHAR *)rsp;

/* Internal checks. */
cmd_checks = (ULONG)cmd_sett -> ux_device_class_ccid_command_sett_flags;
cmd_checks &= (ULONG)slot -> ux_device_class_ccid_slot_flags;

/* Check hardware error! */
if (cmd_checks & UX_DEVICE_CLASS_CCID_FLAG_HW_ERROR)
{

/* Response: (1,1,HW_ERROR). */
rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(1, 1);
rsp -> bError = UX_DEVICE_CLASS_CCID_HW_ERROR;
}

/* Check auto sequencing! */
else if (cmd_checks & UX_DEVICE_CLASS_CCID_FLAG_AUTO_SEQUENCING)
{

/* Response: (1,1,BUSY_WITH_AUTO_SEQUENCE). */
rsp -> bStatus = UX_DEVICE_CLASS_CCID_SLOT_STATUS(1, 1);
rsp -> bError = UX_DEVICE_CLASS_CCID_BUSY_WITH_AUTO_SEQUENCE;
}

/* Process command, application can fill status. */
else
{

handles = (UX_DEVICE_CLASS_CCID_HANDLE *)parameter -> ux_device_class_ccid_handles;
handle = handles[(INT)cmd_sett -> ux_device_class_ccid_command_sett_handle_index];

/* Initialize response length based on type. */
switch(rsp -> bMessageType)
{
case UX_DEVICE_CLASS_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQ:

/* Length fixed to 10+8. */
messages.ux_device_class_ccid_messages_rdr_to_pc_length = 18;
UX_DEVICE_CLASS_CCID_MESSAGE_LENGTH_SET(rsp, 8);
break;

case UX_DEVICE_CLASS_CCID_RDR_TO_PC_SLOT_STATUS:

/* Length fixed to 10. */
messages.ux_device_class_ccid_messages_rdr_to_pc_length =
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH;
break;

default:

/* There is possible data, set length to max transfer length. */
messages.ux_device_class_ccid_messages_rdr_to_pc_length =
parameter -> ux_device_class_ccid_max_transfer_length;
break;
}

/* Invoke application callback. */
status = handle(cmd -> bSlot, &messages);

/* Save application status updates. */

/* Save bmICCStatus. */
slot -> ux_device_class_ccid_slot_icc_status = rsp->bStatus &
UX_DEVICE_CLASS_CCID_SLOT_STATUS_ICC_MASK;

/* Save bClockStatus. */
slot -> ux_device_class_ccid_slot_clock_status = rsp->bClockStatus;
}

/* If failed (aborted), no response. */
if (status != UX_SUCCESS)
continue;
if (slot -> ux_device_class_ccid_slot_aborting)
continue;

/* Send response. */
_ux_device_class_ccid_response(ccid, (UCHAR *)rsp,
messages.ux_device_class_ccid_messages_rdr_to_pc_length);

_ux_device_mutex_on(&ccid -> ux_device_class_ccid_mutex);

/* Free runner. */
runner -> ux_device_class_ccid_runner_slot = -1;
ccid -> ux_device_class_ccid_n_busy --;

/* Clear slot busy. */
slot -> ux_device_class_ccid_slot_runner = -1;

_ux_device_mutex_off(&ccid -> ux_device_class_ccid_mutex);
}
}
#endif
365 changes: 365 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_thread_entry.c

Large diffs are not rendered by default.

128 changes: 128 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_time_extension.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_time_extension PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sends bulk IN time_extension of the USB CCID device. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* slot Slot to extend time */
/* wt BWT (T=1) or WWT (T=0) */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_time_extension(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG wt)
{

UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_TRANSFER *transfer;
UX_DEVICE_CLASS_CCID_SLOT *ccid_slot;
UX_DEVICE_CLASS_CCID_RUNNER *runner;
UCHAR *rsp, *runner_rsp;
UINT status;

/* Get slot. */
ccid_slot = ccid -> ux_device_class_ccid_slots;
ccid_slot += slot;

/* Check slot state. */
if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner < 0)
return(UX_INVALID_STATE);

/* Get runner. */
runner = ccid -> ux_device_class_ccid_runners;
runner += ccid_slot -> ux_device_class_ccid_slot_runner;

/* Get bulk IN endpoint. */
endpoint = ccid -> ux_device_class_ccid_endpoint_in;

/* Get transfer request. */
transfer = &endpoint -> ux_slave_endpoint_transfer_request;

/* Lock bulk IN. */
_ux_device_mutex_on(&ccid -> ux_device_class_ccid_response_mutex);

/* Get response buffer. */
rsp = transfer -> ux_slave_transfer_request_data_pointer;
runner_rsp = runner -> ux_device_class_ccid_runner_response;

/* Fill response. */
rsp[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_MESSAGE_TYPE];
rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH] = 0;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH+1] = 0;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH+2] = 0;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_LENGTH+3] = 0;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_SLOT] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_SLOT];
rsp[UX_DEVICE_CLASS_CCID_OFFSET_SEQ] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_SEQ];
rsp[UX_DEVICE_CLASS_CCID_OFFSET_STATUS] = runner_rsp[UX_DEVICE_CLASS_CCID_OFFSET_STATUS] |
UX_DEVICE_CLASS_CCID_SLOT_STATUS_TIME_EXTENSION;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_ERROR] = (UCHAR)wt;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_CHAIN_PARAMETER] = 0;
rsp[UX_DEVICE_CLASS_CCID_OFFSET_CHAIN_PARAMETER+1] = 0;

/* Transfer data. */
status = _ux_device_stack_transfer_request(transfer,
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH,
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH);

/* Unlock bulk IN. */
_ux_device_mutex_off(&ccid -> ux_device_class_ccid_response_mutex);

/* Return transfer status. */
return(status);
}
114 changes: 114 additions & 0 deletions common/usbx_device_classes/src/ux_device_class_ccid_uninitialize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/

/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/

#define UX_SOURCE_CODE


/* Include necessary system files. */

#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"


/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_uninitialize PORTABLE C */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function uninitialize the USB CCID device. */
/* */
/* INPUT */
/* */
/* command Pointer to ccid command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_free Free memory */
/* _ux_device_mutex_delete Delete mutex */
/* _ux_utility_event_flags_delete Delete event flags */
/* _ux_utility_thread_delete Delete thread */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
{

UX_DEVICE_CLASS_CCID *ccid;
UX_SLAVE_CLASS *ccid_class;
#if !defined(UX_DEVICE_STANDALONE)
UX_DEVICE_CLASS_CCID_RUNNER *runner;
ULONG i;
#endif

/* Get the class container. */
ccid_class = command -> ux_slave_class_command_class_ptr;

/* Get the CCID instance. */
ccid = (UX_DEVICE_CLASS_CCID *)ccid_class -> ux_slave_class_instance;

/* Sanity check. */
if (ccid != UX_NULL)
{

/* Free allocated resources. */
#if !defined(UX_DEVICE_STANDALONE)
_ux_device_thread_delete(&ccid -> ux_device_class_ccid_notify_thread);
_ux_device_thread_delete(&ccid -> ux_device_class_ccid_thread);
for (i = 0;
i < ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_busy_slots;
i ++)
{
runner = &ccid -> ux_device_class_ccid_runners[i];
_ux_device_thread_delete(&runner -> ux_device_class_ccid_runner_thread);
}
_ux_device_event_flags_delete(&ccid -> ux_device_class_ccid_events);
_ux_device_mutex_delete(&ccid -> ux_device_class_ccid_mutex);
_ux_device_semaphore_delete(&ccid -> ux_device_class_ccid_notify_semaphore);
_ux_device_mutex_delete(&ccid -> ux_device_class_ccid_response_mutex);
#endif

/* Free instance memory. */
_ux_utility_memory_free(ccid);
}

/* Return completion status. */
return(UX_SUCCESS);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_bulkin_thread PORTABLE C */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
Expand Down Expand Up @@ -83,6 +83,10 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* used whole buffer for write,*/
/* refined macros names, */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
VOID _ux_device_class_cdc_acm_bulkin_thread(ULONG cdc_acm_class)
Expand Down Expand Up @@ -162,10 +166,10 @@ ULONG sent_length;
{

/* Check the length remaining to send. */
if (total_length > endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)
if (total_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH)

/* We can't fit all the length. */
transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
transfer_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;

else

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_initialize PORTABLE C */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
Expand All @@ -59,7 +59,7 @@
/* _ux_utility_memory_allocate Allocate memory */
/* _ux_utility_memory_free Free memory */
/* _ux_utility_mutex_create Create mutex */
/* _ux_utility_mutex_delete Delete mutex */
/* _ux_device_mutex_delete Delete mutex */
/* */
/* CALLED BY */
/* */
Expand All @@ -81,6 +81,8 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* added standalone support, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_initialize(UX_SLAVE_CLASS_COMMAND *command)
Expand Down Expand Up @@ -138,7 +140,7 @@ UINT status;
{

/* Delete the endpoint IN mutex. */
_ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex);
_ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex);

/* Free the resources. */
_ux_utility_memory_free(cdc_acm);
Expand Down Expand Up @@ -261,8 +263,8 @@ UINT status;
_ux_utility_event_flags_delete(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group);
if (cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack)
_ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack);
_ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex);
_ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex);
_ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_utility_memory_free(cdc_acm);
return(status);
}
Expand Down
14 changes: 8 additions & 6 deletions common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_read PORTABLE C */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
Expand Down Expand Up @@ -64,7 +64,7 @@
/* */
/* _ux_device_stack_transfer_request Transfer request */
/* _ux_utility_memory_copy Copy memory */
/* _ux_utility_mutex_off Release mutex */
/* _ux_device_mutex_off Release mutex */
/* */
/* CALLED BY */
/* */
Expand All @@ -84,6 +84,8 @@
/* resulting in version 6.1.9 */
/* 01-31-2022x Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1.10 */
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_read(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer,
Expand Down Expand Up @@ -142,7 +144,7 @@ ULONG local_requested_length;
}

/* Protect this thread. */
_ux_utility_mutex_on(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_device_mutex_on(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);

/* All CDC reading are on the endpoint OUT, from the host. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
Expand Down Expand Up @@ -192,7 +194,7 @@ ULONG local_requested_length;

/* We are done. */
/* Free Mutex resource. */
_ux_utility_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_device_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);

/* Return with success. */
return(UX_SUCCESS);
Expand All @@ -203,7 +205,7 @@ ULONG local_requested_length;
{

/* Free Mutex resource. */
_ux_utility_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_device_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);

/* We got an error. */
return(status);
Expand All @@ -212,7 +214,7 @@ ULONG local_requested_length;


/* Free Mutex resource. */
_ux_utility_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_device_mutex_off(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);

/* Check why we got here, either completion or device was extracted. */
if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_uninitialize PORTABLE C */
/* 6.1.10 */
/* 6.1.11 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
Expand All @@ -53,7 +53,7 @@
/* */
/* CALLS */
/* */
/* _ux_utility_mutex_delete Delete Mutex */
/* _ux_device_mutex_delete Delete Mutex */
/* _ux_utility_memory_free Free used local memory */
/* */
/* CALLED BY */
Expand All @@ -76,6 +76,8 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* added standalone support, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1.11 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
Expand All @@ -97,10 +99,10 @@ UX_SLAVE_CLASS *class;
#if !defined(UX_DEVICE_STANDALONE)

/* Delete the IN endpoint mutex. */
_ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex);
_ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex);

/* Out Mutex. */
_ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);
_ux_device_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex);

#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE

Expand Down
Loading