USB Libraries Help > USB Device Libraries > USB Device Printer Library > Using the Library > How the Library Works > Sending Data
MPLAB Harmony USB Stack
Sending Data

 

The application may need to send data to the USB Printer Host incase the Printer device supports Bi-directional interface type. This is done by using the USB_DEVICE_PRINTER_Write function. 

 

Sending Data to the USB Host 

 

The application can send data to the Host by using the USB_DEVICE_Printer_Write function. This function returns a transfer handle that allows the application to track the write request. The request is completed when the Host has requested the data. The completion of the write transfer is indicated by a USB_DEVICE_PRINTER_EVENT_WRITE_COMPLETE event. 

A write request could fail if the function driver instance transfer queue is full. 

The USB_DEVICE_PRINTER_Write function also allows the application to send data to the host without ending the transfer. This is done by specifying the USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_PENDING flag. The application can use this option when the data to be sent is not readily available or when the application is memory constrained. The combination of the transfer flag and the transfer size affects how the function driver sends the data to the host: 

• If size is a multiple of maxPacketSize (the IN endpoint size), and the 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 the flag is set as 

USB_DEVICE_PRINTER_TRANSFER_FLAGS_MORE_DATA_PENDING, the write function will not append a ZLP and therefore, will not complete the transfer 

• If size is greater than but not a multiple of maxPacketSize, and the flag is set as 

USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE, the write function schedules length/maxPacketSize) packets and one packet for the residual data. 

• If size if greater than but not a multiple of maxPacketSize, and the 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 less than maxPacketSize, and the flag is set as USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE, the write function schedules one packet 

• If size is less than maxPacketSize, and the 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 

 

The following code shows a set of examples of various conditions attempting to send data with the USB_DEVICE_PRINTER_Write function. 

 

Example 1  

// This example assume that the maxPacketSize is 64.
USB_DEVICE_PRINTER_TRANSFER_HANDLE transferHandle;
USB_DEVICE_PRINTER_INDEX instance;
USB_DEVICE_PRINTER_RESULT writeRequestResult;
uint8_t data[34];
// 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
}

 

Example 2

//-------------------------------------------------------
// In this example we want to send 64 bytes only.
// This will cause a ZLP to be sent.
USB_DEVICE_PRINTER_TRANSFER_HANDLE transferHandle;
USB_DEVICE_PRINTER_INDEX instance;
USB_DEVICE_PRINTER_RESULT writeRequestResult;
uint8_t data[64];
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
}

 

Example 3

//-------------------------------------------------------
// This example will return an error because size is less
// than maxPacketSize and the flag indicates that more
// data is pending.
USB_DEVICE_PRINTER_TRANSFER_HANDLE transferHandle;
USB_DEVICE_PRINTER_INDEX instance;
USB_DEVICE_PRINTER_RESULT writeRequestResult;
uint8_t data[64];
writeRequestResult = USB_DEVICE_PRINTER_Write(instance,&transferHandle, data, 32,
USB_DEVICE_PRINTER_TRANSFER_FLAGS_MORE_DATA_PENDING);

 

 

Example 4

//-------------------------------------------------------
// 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.

USB_DEVICE_PRINTER_TRANSFER_HANDLE transferHandle;
USB_DEVICE_PRINTER_INDEX instance;
USB_DEVICE_PRINTER_RESULT writeRequestResult;
uint8_t data[70];
writeRequestResult = USB_DEVICE_PRINTER_Write(instance,&transferHandle, data, 70,
USB_DEVICE_PRINTER_TRANSFER_FLAGS_DATA_COMPLETE);

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

 

 

Example 5

//-------------------------------------------------------
// In this example we want to place a request for a 70 bytes to be sent
// but that we don't end the transfer as more data is coming. 64 bytes
// of the 70 will be sent out and the USB_DEVICE_PRINTER_EVENT_WRITE_COMPLETE
// with 64 bytes. This indicates that the extra 6 bytes weren't
// sent because it would cause the end of the transfer. Thus the
// user needs to add these 6 bytes back to the buffer for the next group
// of data that needs to be sent out.

USB_DEVICE_PRINTER_TRANSFER_HANDLE transferHandle;
USB_DEVICE_PRINTER_INDEX instance;
USB_DEVICE_PRINTER_RESULT writeRequestResult;
uint8_t data[70];
writeRequestResult = USB_DEVICE_PRINTER_Write(instance,&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.