Jump to main content

##

# 2.9.4.3 USB_DEVICE_PRINTER_Write Function

## C

    USB_DEVICE_PRINTER_RESULT USB_DEVICE_PRINTER_Write(
        USB_DEVICE_PRINTER_INDEX instanceIndex,
        USB_DEVICE_PRINTER_TRANSFER_HANDLE * transferHandle,
        const void * data,
        size_t size,
        USB_DEVICE_PRINTER_TRANSFER_FLAGS flags
    );

## Description

This function requests a data write to the USB Device PRINTER 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_PRINTER_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_PRINTER_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_PRINTER_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_PRINTER_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_PRINTER_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_PRINTER_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_PRINTER_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_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE, the write function returns an error code and sets the transferHandle parameter to USB_DEVICE_PRINTER_TRANSFER_HANDLE_INVALID.
- If size is greater than but not a multiple of maxPacketSize and flags is set as USB_DEVICE_PRINTER_TRANSFER_FLAGS_MORE_DATA_PENDING, the write function fails and return an error code and sets the transferHandle parameter to USB_DEVICE_PRINTER_TRANSFER_HANDLE_INVALID.
- If size is less than maxPacketSize and flag is set as USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE, the write function schedules one packet.
- If size is less than maxPacketSize and flag is set as USB_DEVICE_PRINTER_TRANSFER_FLAGS_MORE_DATA_PENDING, the write function returns an error code and sets the transferHandle parameter to USB_DEVICE_PRINTER_TRANSFER_HANDLE_INVALID.
- If size is 0 and the flag is set USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE, the function driver will schedule a Zero Length Packet.

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

## Precondition

The function driver should have been configured.

## Parameters

Parameters | Description
instanceIndex | USB Device PRINTER Function Driver instance.
transferHandle | Pointer to a USB_DEVICE_PRINTER_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_PRINTER_RESULT_OK - The write request was successful. transferHandle contains a valid transfer handle.

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

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

USB_DEVICE_PRINTER_RESULT_ERROR_INSTANCE_NOT_CONFIGURED - The specified instance is not configured yet.

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

## 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_PRINTER_TRANSFER_HANDLE transferHandle;
    USB_DEVICE_PRINTER_RESULT writeRequestHandle;
    USB_DEVICE_PRINTER_INDEX instance;

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

    writeRequestResult = USB_DEVICE_PRINTER_Write(instance,
                            &transferHandle, data, 34,
                            USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE);

    if(USB_DEVICE_PRINTER_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_PRINTER_Write(instance,
                            &transferHandle, data, 64,
                            USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE);

    if(USB_DEVICE_PRINTER_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_PRINTER_Write(instanceHandle,
                            &transferHandle, data, 32,
                            USB_DEVICE_PRINTER_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_PRINTER_Write(instanceHandle,
                            &transferHandle, data, 70,
                            USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE);

    if(USB_DEVICE_PRINTER_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_PRINTER_Write(instanceHandle,
                            &transferHandle, data, 70,
                            USB_DEVICE_PRINTER_TRANSFER_FLAGS_MORE_DATA_PENDING);

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

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

## Remarks

While the using the PRINTER Function Driver with the PIC32MZ USB module, the transmit buffer provided to the USB_DEVICE_PRINTER_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)));