USB Libraries Help > USB Device Libraries > USB CDC Device Library > Library Interface > a) Functions > USB_DEVICE_CDC_Write Function
MPLAB Harmony USB Stack
USB_DEVICE_CDC_Write Function

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

The behavior of the write request depends on the flags and size parameter. If the application intends to send more data in a request, then it should use the USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING flag. If there is no more data to be sent in the request, the application must use the USB_DEVICE_CDC_EVENT_WRITE_COMPLETE flag. This is explained in more detail here: 

 

  • If size is a multiple of maxPacketSize and flag is set as

USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE, the write function will append a Zero Length Packet (ZLP) to complete the transfer. 

 

  • If size is a multiple of maxPacketSize and flag is set as

USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING, the write function will not append a ZLP and hence will not complete the transfer. 

 

  • If size is greater than but not a multiple of maxPacketSize and flags is

set as USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE, the write function returns an error code and sets the transferHandle parameter to USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID

 

  • If size is greater than but not a multiple of maxPacketSize and flags is

set as USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING, the write function fails and return an error code and sets the transferHandle parameter to USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID

 

  • If size is less than maxPacketSize and flag is set as

USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE, the write function schedules one packet. 

 

  • If size is less than maxPacketSize and flag is set as

USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING, the write function returns an error code and sets the transferHandle parameter to USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID

 

  • If size is 0 and the flag is set

USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE, the function driver will schedule a Zero Length Packet. 

Completion of the write transfer is indicated by the USB_DEVICE_CDC_EVENT_WRITE_COMPLETE event. The amount of data written along with the transfer handle is returned along with the event.

C
USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Write(
    USB_DEVICE_CDC_INDEX instanceIndex, 
    USB_DEVICE_CDC_TRANSFER_HANDLE * transferHandle, 
    const void * data, 
    size_t size, 
    USB_DEVICE_CDC_TRANSFER_FLAGS flags
);
Preconditions

The function driver should have been configured.

Parameters
Parameters 
Description 
instance 
USB Device CDC Function Driver instance.
 
transferHandle 
Pointer to a USB_DEVICE_CDC_TRANSFER_HANDLE type of variable. This variable will contain the transfer handle in case the write request was successful.
 
data 
pointer to the data buffer that contains the data to written.
 
size 
Size of the data buffer. Refer to the description section for more details on how the size affects the transfer.
 
flags 
Flags that indicate whether the transfer should continue or end. Refer to the description for more details. 
Returns

USB_DEVICE_CDC_RESULT_OK - The write request was successful. transferHandle contains a valid transfer handle. 

USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL - internal request queue is full. The write request could not be added. 

USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID - The specified transfer size and flag parameter are invalid. 

USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_NOT_CONFIGURED - The specified instance is not configured yet. 

USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID - The specified instance was not provisioned in the application and is invalid.

Remarks

While the using the CDC Function Driver with the PIC32MZ USB module, the transmit buffer provided to the USB_DEVICE_CDC_Write function should be placed in coherent memory and aligned at a 16 byte boundary. This can be done by declaring the buffer using the __attribute__((coherent, aligned(16))) attribute. An example is shown here 

 

uint8_t data[256] __attribute__((coherent, aligned(16)));
Example
// Below is a set of examples showing various conditions trying to
// send data with the Write command.  
//
// This assumes that driver was opened successfully.
// Assume maxPacketSize is 64.

USB_DEVICE_CDC_TRANSFER_HANDLE transferHandle;
USB_DEVICE_CDC_RESULT writeRequestHandle;
USB_DEVICE_CDC_INDEX instance;

//-------------------------------------------------------
// In this example we want to send 34 bytes only.

writeRequestResult = USB_DEVICE_CDC_Write(instance,
                        &transferHandle, data, 34, 
                        USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE);

if(USB_DEVICE_CDC_RESULT_OK != writeRequestResult)
{
    //Do Error handling here
}

//-------------------------------------------------------
// In this example we want to send 64 bytes only.
// This will cause a ZLP to be sent.

writeRequestResult = USB_DEVICE_CDC_Write(instance,
                        &transferHandle, data, 64, 
                        USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE);

if(USB_DEVICE_CDC_RESULT_OK != writeRequestResult)
{
    //Do Error handling here
}

//-------------------------------------------------------
// This example will return an error because size is less
// than maxPacketSize and the flag indicates that more
// data is pending.

writeRequestResult = USB_DEVICE_CDC_Write(instanceHandle,
                        &transferHandle, data, 32, 
                        USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING);

//-------------------------------------------------------
// In this example we want to place a request for a 70 byte transfer.
// The 70 bytes will be sent out in a 64 byte transaction and a 6 byte
// transaction completing the transfer.

writeRequestResult = USB_DEVICE_CDC_Write(instanceHandle,
                        &transferHandle, data, 70, 
                        USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE);

if(USB_DEVICE_CDC_RESULT_OK != writeRequestResult)
{
    //Do Error handling here
}

//-------------------------------------------------------
// In this example we want to place a request for a 70 bytes and the flag
// is set to data pending. This will result in an error. The size of data
// when the data pending flag is specified should be a multiple of the
// endpoint size.

writeRequestResult = USB_DEVICE_CDC_Write(instanceHandle,
                        &transferHandle, data, 70, 
                        USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING);

if(USB_DEVICE_CDC_RESULT_OK != writeRequestResult)
{
    //Do Error handling here
}

// The completion of the write request will be indicated by the 
// USB_DEVICE_CDC_EVENT_WRITE_COMPLETE event.