USB Libraries Help > USB Host Libraries > USB CDC Host Library > Using the Library > How the Library Works > Reading and Writing Data
MPLAB Harmony USB Stack
Reading and Writing Data

The application can use the USB_HOST_CDC_Read and USB_HOST_CDC_Write functions to transfer data to the attached CDC device. While calling these function, the client handle specifies the target CDC device and the event handler function to which the events should be sent. It is possible for multiple client to open the same instance of the CDC Host Client Driver instance and transfer data to the attached CDC Device. 

Calling the USB_HOST_CDC_Read and USB_HOST_CDC_Write functions while a read/write transfer is already in progress will cause the transfer result to be queued. If the transfer was successfully queued or scheduled, the USB_HOST_CDC_Read and USB_HOST_CDC_Write functions will return a valid transfer handle. This transfer handle identifies the transfer request. The application clients can use the transfer handles to keep track of multiple queued transfers. When a transfer completes, the CDC Host Client Driver generates an event. The following tables shows the event and the event data associated with the event. 

Table 1: Read  

Function 
Event 
USB_HOST_CDC_EVENT_READ_COMPLETE 
Event Data Type 

Table 2: Write

Function 
Event 
USB_HOST_CDC_EVENT_WRITE_COMPLETE 
Event Data Type 

The event data contains information on the amount of data transferred, completion status and the transfer handle of the transfer. The following code shows an example of reading and writing data. 

Example:  

/* In this code example, the USB_HOST_CDC_Read and the USB_HOST_CDC_Write
 * functions are used to read and write data. The event related to the read and
 * write operations are handled in the APP_USBHostCDCEventHandler function. */

USB_HOST_CDC_EVENT_RESPONSE APP_USBHostCDCEventHandler
(
    USB_HOST_CDC_HANDLE cdcHandle,
    USB_HOST_CDC_EVENT event,
    void * eventData,
    uintptr_t context
)
{
    /* This function is called when a CDC Host event has occurred. A pointer to
     * this function is registered after opening the device. */

    USB_HOST_CDC_EVENT_WRITE_COMPLETE_DATA * writeCompleteEventData;
    USB_HOST_CDC_EVENT_READ_COMPLETE_DATA * readCompleteEventData;

    switch(event)
    {
        case USB_HOST_CDC_EVENT_WRITE_COMPLETE:

            /* This means an application requested write has completed */
            appData.writeTransferDone = true;
            writeCompleteEventData = (USB_HOST_CDC_EVENT_WRITE_COMPLETE_DATA *)(eventData);
            appData.writeTransferResult = writeCompleteEventData->result;
            break;

        case USB_HOST_CDC_EVENT_READ_COMPLETE:

            /* This means an application requested write has completed */
            appData.readTransferDone = true;
            readCompleteEventData = (USB_HOST_CDC_EVENT_READ_COMPLETE_DATA *)(eventData);
            appData.readTransferResult = readCompleteEventData->result;
            break;

        default:
            break;
    }

    return(USB_HOST_CDC_EVENT_RESPONE_NONE);
}

void APP_Tasks(void)
{
    switch(appData.state)
    {
        /* The application states that wait for device attach and open the CDC
         * Host Client Driver are not shown here for brevity */

        case APP_STATE_SEND_PROMPT_TO_DEVICE:

            /* The prompt is sent to the device here. The write transfer done
             * flag is updated in the event handler. */

            appData.writeTransferDone = false;
            result = USB_HOST_CDC_Write(appData.cdcHostHandle, NULL, prompt, 8);

            if(result == USB_HOST_CDC_RESULT_SUCCESS)
            {
                appData.state = APP_STATE_WAIT_FOR_PROMPT_SEND_COMPLETE;
            }
            break;

        case APP_STATE_WAIT_FOR_PROMPT_SEND_COMPLETE:

            /* Here we check if the write transfer is done */
            if(appData.writeTransferDone)
            {
                if(appData.writeTransferResult == USB_HOST_CDC_RESULT_SUCCESS)
                {
                    /* Now to get data from the device */
                    appData.state = APP_STATE_GET_DATA_FROM_DEVICE;
                }
                else
                {
                    /* Try sending the prompt again. */
                    appData.state = APP_STATE_SEND_PROMPT_TO_DEVICE;
                }
            }

            break;

        case APP_STATE_GET_DATA_FROM_DEVICE:

            /* Here we request data from the device */
            appData.readTransferDone = false;
            result = USB_HOST_CDC_Read(appData.cdcHostHandle, NULL, appData.inDataArray, 1);
            if(result == USB_HOST_CDC_RESULT_SUCCESS)
            {
                appData.state = APP_STATE_WAIT_FOR_DATA_FROM_DEVICE;
            }
            break;

        case APP_STATE_WAIT_FOR_DATA_FROM_DEVICE:

            /* Wait for data from device. */
            if(appData.readTransferDone)
            {
                if(appData.readTransferResult == USB_HOST_CDC_RESULT_SUCCESS)
                {
                    /* Do something with the data here */
                }
            }

            break;

        default:
            break;
    }
}