0% found this document useful (0 votes)
80 views6 pages

CDC Read&Write

This function requests a data read from the USB Device CDC Function Driver Layer. It places a read request with the driver and returns a handle. The read completion is indicated by an event. It checks parameters like instance validity and transfer size, finds a free IRP, submits the request, and returns any errors.

Uploaded by

M1911
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
80 views6 pages

CDC Read&Write

This function requests a data read from the USB Device CDC Function Driver Layer. It places a read request with the driver and returns a handle. The read completion is indicated by an event. It checks parameters like instance validity and transfer size, finds a free IRP, submits the request, and returns any errors.

Uploaded by

M1911
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

// *****************************************************************************

/* Function:
USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Read
(
USB_DEVICE_CDC_INDEX instance,
USB_CDC_DEVICE_TRANSFER_HANDLE * transferHandle,
void * data,
size_t size
);

Summary:
This function requests a data read from the USB Device CDC Function Driver
Layer.

Description:
This function requests a data read from the USB Device CDC Function Driver
Layer. The function places a requests with driver, the request will get
serviced as data is made available by the USB Host. A handle to the request
is returned in the transferHandle parameter. The termination of the request
is indicated by the USB_DEVICE_CDC_EVENT_READ_COMPLETE event. The amount of
data read and the transfer handle associated with the request is returned
along with the event in the pData parameter of the event handler. The
transfer handle expires when event handler for the
USB_DEVICE_CDC_EVENT_READ_COMPLETE exits. If the read request could not be
accepted, the function returns an error code and transferHandle will contain
the value USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID.

If the size parameter is not a multiple of maxPacketSize or is 0, the


function returns USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID in transferHandle
and returns an error code as a return value. If the size parameter is a
multiple of maxPacketSize and the host send less than maxPacketSize data in
any transaction, the transfer completes and the function driver will issue a
USB_DEVICE_CDC_EVENT_READ_COMPLETE event along with the
USB_DEVICE_CDC_EVENT_READ_COMPLETE_DATA data structure. If the size
parameter is a multiple of maxPacketSize and the host sends maxPacketSize
amount of data, and total data received does not exceed size, then the
function driver will wait for the next packet.

Remarks:
Refer to usb_device_cdc.h for usage information.
*/

USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Read
(
USB_DEVICE_CDC_INDEX iCDC ,
USB_DEVICE_CDC_TRANSFER_HANDLE * transferHandle ,
void * data , size_t size
)
{
unsigned int cnt;
unsigned int remainder;
USB_DEVICE_IRP * irp;
USB_DEVICE_CDC_ENDPOINT * endpoint;
USB_DEVICE_CDC_INSTANCE * thisCDCDevice;
OSAL_RESULT osalError;
USB_ERROR irpError;
OSAL_CRITSECT_DATA_TYPE IntState;

/* Check the validity of the function driver index */


if ( iCDC >= USB_DEVICE_CDC_INSTANCES_NUMBER )
{
/* Invalid CDC index */
SYS_ASSERT(false, "Invalid CDC Device Index");
return USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID;
}

thisCDCDevice = &gUSBDeviceCDCInstance[iCDC];
endpoint = &thisCDCDevice->dataInterface.endpoint[USB_DEVICE_CDC_ENDPOINT_RX];
*transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID;

/* Check if the endpoint is configured */


if(!(endpoint->isConfigured))
{
/* This means that the endpoint is not configured yet */
SYS_ASSERT(false, "Endpoint not configured");
return (USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_NOT_CONFIGURED);
}

/* For read the size should be a multiple of endpoint size*/


remainder = size % endpoint->maxPacketSize;

if((size == 0) || (remainder != 0))


{
/* Size is not valid */
SYS_ASSERT(false, "Invalid size in IRP read");
return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID);
}

/* Make sure that we are with in the queue size for this instance */
if(thisCDCDevice->currentQSizeRead >= thisCDCDevice->queueSizeRead)
{
SYS_ASSERT(false, "Read Queue is full");
return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL);
}

/*Obtain mutex to get access to a shared resource, check return value*/


osalError = OSAL_MUTEX_Lock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP,
OSAL_WAIT_FOREVER);
if(osalError != OSAL_RESULT_TRUE)
{
/*Do not proceed lock was not obtained, or error occurred, let user know
about error*/
return (USB_DEVICE_CDC_RESULT_ERROR);
}

/* Loop and find a free IRP in the Q */


for ( cnt = 0; cnt < USB_DEVICE_CDC_QUEUE_DEPTH_COMBINED; cnt ++ )
{
if(gUSBDeviceCDCIRP[cnt].status <
(USB_DEVICE_IRP_STATUS)USB_DEVICE_IRP_FLAG_DATA_PENDING)
{
/* This means the IRP is free. Configure the IRP
* update the current queue size and then submit */

irp = &gUSBDeviceCDCIRP[cnt];
irp->data = data;
irp->size = size;
irp->userData = (uintptr_t) iCDC;
irp->callback = _USB_DEVICE_CDC_ReadIRPCallback;

/* Prevent other tasks pre-empting this sequence of code */


IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH);
/* Update the read queue size */
thisCDCDevice->currentQSizeRead++;
OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState);

*transferHandle = (USB_DEVICE_CDC_TRANSFER_HANDLE)irp;
irpError = USB_DEVICE_IRPSubmit(thisCDCDevice->deviceHandle,
endpoint->address, irp);

/* If IRP Submit function returned any error, then invalidate the


Transfer handle. */
if (irpError != USB_ERROR_NONE )
{
/* Prevent other tasks pre-empting this sequence of code */
IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH);
/* Update the read queue size */
thisCDCDevice->currentQSizeRead--;
OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState);
*transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID;
}

/*Release mutex, done with shared resource*/


osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP);
if(osalError != OSAL_RESULT_TRUE)
{
/*Do not proceed unlock was not complete, or error occurred, let
user know about error*/
return (USB_DEVICE_CDC_RESULT_ERROR);
}

return((USB_DEVICE_CDC_RESULT)irpError);
}
}

/*Release mutex, done with shared resource*/


osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP);
if(osalError != OSAL_RESULT_TRUE)
{
/*Do not proceed unlock was not complete, or error occurred, let user know
about error*/
return (USB_DEVICE_CDC_RESULT_ERROR);
}
/* If here means we could not find a spare IRP */
return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL);
}

// *****************************************************************************
/* Function:
USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Write
(
USB_DEVICE_CDC_INDEX instance,
USB_CDC_DEVICE_TRANSFER_HANDLE * transferHandle,
const void * data,
size_t size,
USB_DEVICE_CDC_TRANSFER_FLAGS flags
);

Summary:
This function requests a data write to the USB Device CDC Function Driver
Layer.

Description:
This function requests a data write to the USB Device CDC Function Driver
Layer. The function places a requests with driver, the request will get
serviced as data is requested by the USB Host. A handle to the request is
returned in the transferHandle parameter. The termination of the request is
indicated by the USB_DEVICE_CDC_EVENT_WRITE_COMPLETE event. The amount of
data written and the transfer handle associated with the request is returned
along with the event in writeCompleteData member of the pData parameter in
the event handler. The transfer handle expires when event handler for the
USB_DEVICE_CDC_EVENT_WRITE_COMPLETE exits. If the read request could not be
accepted, the function returns an error code and transferHandle will contain
the value USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID.

Remarks:
Refer to usb_device_cdc.h for usage information.
*/

USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Write
(
USB_DEVICE_CDC_INDEX iCDC ,
USB_DEVICE_CDC_TRANSFER_HANDLE * transferHandle ,
const void * data , size_t size ,
USB_DEVICE_CDC_TRANSFER_FLAGS flags
)
{
unsigned int cnt;
unsigned int remainder;
USB_DEVICE_IRP * irp;
USB_DEVICE_IRP_FLAG irpFlag = USB_DEVICE_IRP_FLAG_NONE;
USB_DEVICE_CDC_INSTANCE * thisCDCDevice;
USB_DEVICE_CDC_ENDPOINT * endpoint;
OSAL_RESULT osalError;
USB_ERROR irpError;
OSAL_CRITSECT_DATA_TYPE IntState;

/* Check the validity of the function driver index */

if ( iCDC >= USB_DEVICE_CDC_INSTANCES_NUMBER )


{
/* Invalid CDC index */
SYS_ASSERT(false, "Invalid CDC Device Index");
return USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID;
}

/* Initialize the transfer handle, get the instance object


* and the transmit endpoint */

* transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID;
thisCDCDevice = &gUSBDeviceCDCInstance[iCDC];
endpoint = &thisCDCDevice->dataInterface.endpoint[USB_DEVICE_CDC_ENDPOINT_TX];

if(!(endpoint->isConfigured))
{
/* This means that the endpoint is not configured yet */
SYS_ASSERT(false, "Endpoint not configured");
return (USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_NOT_CONFIGURED);
}

if(size == 0)
{
/* Size cannot be zero */
return (USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID);
}

/* Check the flag */

if(flags & USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING)


{
if(size < endpoint->maxPacketSize)
{
/* For a data pending flag, we must atleast get max packet
* size worth data */

return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID);
}

remainder = size % endpoint->maxPacketSize;

if(remainder != 0)
{
size -= remainder;
}

irpFlag = USB_DEVICE_IRP_FLAG_DATA_PENDING;
}
else if(flags & USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE)
{
irpFlag = USB_DEVICE_IRP_FLAG_DATA_COMPLETE;
}

if(thisCDCDevice->currentQSizeWrite >= thisCDCDevice->queueSizeWrite)


{
SYS_ASSERT(false, "Write Queue is full");
return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL);
}

/*Obtain mutex to get access to a shared resource, check return value*/


osalError = OSAL_MUTEX_Lock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP,
OSAL_WAIT_FOREVER);
if(osalError != OSAL_RESULT_TRUE)
{
/*Do not proceed lock was not obtained, or error occurred, let user know
about error*/
return (USB_DEVICE_CDC_RESULT_ERROR);
}

/* loop and find a free IRP in the Q */


for ( cnt = 0; cnt < USB_DEVICE_CDC_QUEUE_DEPTH_COMBINED; cnt ++ )
{
if(gUSBDeviceCDCIRP[cnt].status <
(USB_DEVICE_IRP_STATUS)USB_DEVICE_IRP_FLAG_DATA_PENDING)
{
/* This means the IRP is free */

irp = &gUSBDeviceCDCIRP[cnt];
irp->data = (void *)data;
irp->size = size;

irp->userData = (uintptr_t) iCDC;


irp->callback = _USB_DEVICE_CDC_WriteIRPCallback;
irp->flags = irpFlag;

/* Prevent other tasks pre-empting this sequence of code */


IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH);
/* Update the Write queue size */
thisCDCDevice->currentQSizeWrite++;
OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState);

*transferHandle = (USB_DEVICE_CDC_TRANSFER_HANDLE)irp;

irpError = USB_DEVICE_IRPSubmit(thisCDCDevice->deviceHandle,
endpoint->address, irp);

/* If IRP Submit function returned any error, then invalidate the


Transfer handle. */
if (irpError != USB_ERROR_NONE )
{
/* Prevent other tasks pre-empting this sequence of code */
IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH);
/* Update the Write queue size */
thisCDCDevice->currentQSizeWrite--;
OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState);
*transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID;
}
/*Release mutex, done with shared resource*/
osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP);
if(osalError != OSAL_RESULT_TRUE)
{
/*Do not proceed unlock was not complete, or error occurred, let
user know about error*/
return (USB_DEVICE_CDC_RESULT_ERROR);
}

return((USB_DEVICE_CDC_RESULT)irpError);
}
}

/*Release mutex, done with shared resource*/


osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP);
if(osalError != OSAL_RESULT_TRUE)
{
/*Do not proceed unlock was not complete, or error occurred, let user know
about error*/
return (USB_DEVICE_CDC_RESULT_ERROR);
}
/* If here means we could not find a spare IRP */
return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL);
}

You might also like