USB Libraries Help > USB Host Libraries > USB CDC Host Library > Using the Library > How the Library Works > Event Handling
MPLAB Harmony USB Stack
Event Handling

The CDC Host Client Driver presents an event driven interface to the application. The CDC Host Client Driver requires the application client to set two event handlers for meaningful operation:

  • The Attach event handler is not client specific and is registered before the USB_HOST_BusEnable function is called. This event handler and the attach event is discussed in the Detecting Device Attach section.
  • The client specific command, data transfer and detach events. The CDC Class specific command request events are discussed in the Sending Class Specific Control Transfers section. The data transfer related events are discussed in the Reading and Writing Data section. Some general points about these events are discussed below.

A request to send a command or transfer data typically completes after the command request or transfer function has exited. The application must then use the CDC Host Client Driver event to track the completion of this command or data transfer request. In a case where multiple data transfers are queued, the transfer handles can be used to identify the transfer requests. 

The application must use the USB_HOST_CDC_EventHandlerSet function to register a client specific event handler. This event handler will be called when a command, data transfer or detach event has occurred and should be registered before the client request for command or a data transfer. The following code shows an example of registering an event handler. 

Example:  

/* This code shows an example of setting an event handler and an example
 * event handler. For the full set of events that the CDC Host Client generates,
 * refer to USB_HOST_CDC_EVENT enumeration description */

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. See the call to
     * USB_HOST_CDC_EventHandlerSet() function. */

    USB_HOST_CDC_EVENT_ACM_SET_LINE_CODING_COMPLETE_DATA * setLineCodingEventData;
    USB_HOST_CDC_EVENT_ACM_SET_CONTROL_LINE_STATE_COMPLETE_DATA * setControlLineStateEventData;
    USB_HOST_CDC_EVENT_WRITE_COMPLETE_DATA * writeCompleteEventData;
    USB_HOST_CDC_EVENT_READ_COMPLETE_DATA * readCompleteEventData;

    switch(event)
    {
        case USB_HOST_CDC_EVENT_ACM_SET_LINE_CODING_COMPLETE:

            /* This means the application requested Set Line Coding request is
             * complete. */
            setLineCodingEventData = (USB_HOST_CDC_EVENT_ACM_SET_LINE_CODING_COMPLETE_DATA *)(eventData);
            appData.controlRequestDone = true;
            appData.controlRequestResult = setLineCodingEventData->result;
            break;

        case USB_HOST_CDC_EVENT_ACM_SET_CONTROL_LINE_STATE_COMPLETE:

            /* This means the application requested Set Control Line State
             * request has completed. */
            setControlLineStateEventData = (USB_HOST_CDC_EVENT_ACM_SET_CONTROL_LINE_STATE_COMPLETE_DATA *)(eventData);
            appData.controlRequestDone = true;
            appData.controlRequestResult = setControlLineStateEventData->result;
            break;

        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;

        case USB_HOST_CDC_EVENT_DEVICE_DETACHED:

            /* The device was detached */
            appData.deviceWasDetached = true;
            break;

        default:
            break;
    }

    return(USB_HOST_CDC_EVENT_RESPONE_NONE);
}


void APP_Tasks(void)
{
    switch(appData.state)
    {
        /* The application states that enable the bus and wait for device attach
         * are not shown here for brevity */
        case APP_STATE_OPEN_DEVICE:

            /* In this state the application opens the attached device */
            appData.cdcHostHandle = USB_HOST_CDC_Open(appData.cdcObj);
            if(appData.cdcHostHandle != USB_HOST_CDC_HANDLE_INVALID)
            {
                /* The driver was opened successfully. Set the event handler
                 * and then go to the next state. */
                USB_HOST_CDC_EventHandlerSet(appData.cdcHostHandle, APP_USBHostCDCEventHandler, (uintptr_t)0);
                appData.state = APP_STATE_SET_LINE_CODING;
            }
            break;

        default:
            break;

    }
}