2.5.4.1 USB_DEVICE_CDC_EventHandlerSet Function

C

USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_EventHandlerSet(
    USB_DEVICE_CDC_INDEX iCDC, 
    USB_DEVICE_CDC_EVENT_HANDLER eventHandler, 
    uintptr_t context
);

Summary

This function registers a event handler for the specified CDC function driver instance. This function should be called by the client when it receives a SET CONFIGURATION event from the device layer. A event handler must be registered for function driver to respond to function driver specific commands. If the event handler is not registered, the device layer will stall function driver specific commands and the USB device may not function.

Precondition

This function should be called when the function driver has been initialized as a result of a set configuration.

Parameters

Parameters Description
iCDC Instance of the CDC Function Driver.
eventHandler A pointer to event handler function.
context Application specific context that is returned in the event handler.

Returns

USB_DEVICE_CDC_RESULT_OK - The operation was successful

USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID - The specified instance does not exist

USB_DEVICE_CDC_RESULT_ERROR_PARAMETER_INVALID - The eventHandler parameter is NULL

Example

// This code snippet shows an example registering an event handler. Here
// the application specifies the context parameter as a pointer to an
// application object (appObject) that should be associated with this 
// instance of the CDC function driver.

// Application states
typedef enum
{
    //Application's state machine's initial state.
    APP_STATE_INIT=0,
    APP_STATE_SERVICE_TASKS,
    APP_STATE_WAIT_FOR_CONFIGURATION, 
} APP_STATES;

USB_DEVICE_HANDLE usbDeviceHandle;

APP_STATES appState; 

// Get Line Coding Data 
USB_CDC_LINE_CODING getLineCodingData;

// Control Line State 
USB_CDC_CONTROL_LINE_STATE controlLineStateData;

// Set Line Coding Data 
USB_CDC_LINE_CODING setLineCodingData;

USB_DEVICE_CDC_RESULT result;

USB_DEVICE_CDC_EVENT_RESPONSE APP_USBDeviceCDCEventHandler 
(
    USB_DEVICE_CDC_INDEX instanceIndex ,
    USB_DEVICE_CDC_EVENT event ,
    void* pData, 
    uintptr_t context 
)
{
    // Event Handling comes here
    
    switch(event) 
    {
        case USB_DEVICE_CDC_EVENT_GET_LINE_CODING:
                // This means the host wants to know the current line
                // coding. This is a control transfer request. Use the
                // USB_DEVICE_ControlSend() function to send the data to
                // host.  

                USB_DEVICE_ControlSend(usbDeviceHandle,
                    &getLineCodingData, sizeof(USB_CDC_LINE_CODING));

        break;
        
        case USB_DEVICE_CDC_EVENT_SET_LINE_CODING:

            // This means the host wants to set the line coding.
            // This is a control transfer request. Use the
            // USB_DEVICE_ControlReceive() function to receive the
            // data from the host 

            USB_DEVICE_ControlReceive(usbDeviceHandle,
                    &setLineCodingData, sizeof(USB_CDC_LINE_CODING));

        break;
        
        case USB_DEVICE_CDC_EVENT_SET_CONTROL_LINE_STATE:

            // This means the host is setting the control line state.
            // Read the control line state. We will accept this request
            // for now.
            controlLineStateData.dtr = ((USB_CDC_CONTROL_LINE_STATE *)pData)->dtr; 
            controlLineStateData.carrier = ((USB_CDC_CONTROL_LINE_STATE *)pData)->carrier; 
            USB_DEVICE_ControlStatus(usbDeviceHandle, USB_DEVICE_CONTROL_STATUS_OK);

        break;
        
        case USB_DEVICE_CDC_EVENT_CONTROL_TRANSFER_DATA_RECEIVED:

            // The data stage of the last control transfer is
            // complete. For now we accept all the data 

            USB_DEVICE_ControlStatus(usbDeviceHandle, USB_DEVICE_CONTROL_STATUS_OK);
            
        break;
        
            case USB_DEVICE_CDC_EVENT_CONTROL_TRANSFER_DATA_SENT:

            // This means the GET LINE CODING function data is valid. We dont
            // do much with this data in this demo. 
        break;
        
        case USB_DEVICE_CDC_EVENT_SEND_BREAK:

            // This means that the host is requesting that a break of the
            // specified duration be sent. 
            USB_DEVICE_ControlStatus(usbDeviceHandle, USB_DEVICE_CONTROL_STATUS_OK);    
        
        break;
      
        case USB_DEVICE_CDC_EVENT_READ_COMPLETE:
            // This means that the host has sent some data
            break;
            
        case USB_DEVICE_CDC_EVENT_WRITE_COMPLETE:
            // This means that the host has sent some data 
            break;
        
        default:
            break; 
    }

    return USB_DEVICE_CDC_EVENT_RESPONSE_NONE;
}

// This is the application device layer event handler function.

USB_DEVICE_EVENT_RESPONSE APP_USBDeviceEventHandler
(
    USB_DEVICE_EVENT event,
    void * pData, 
    uintptr_t context
)
{
    USB_SETUP_PACKET * setupPacket;
    switch(event)
    {
        case USB_DEVICE_EVENT_POWER_DETECTED:
            // This event in generated when VBUS is detected. Attach the device 
            USB_DEVICE_Attach(usbDeviceHandle);
            break;
            
        case USB_DEVICE_EVENT_POWER_REMOVED:
            // This event is generated when VBUS is removed. Detach the device
            USB_DEVICE_Detach (usbDeviceHandle);
            break; 
            
        case USB_DEVICE_EVENT_CONFIGURED:
            // This event indicates that Host has set Configuration in the Device. 
            // Register CDC Function driver Event Handler.  
            USB_DEVICE_CDC_EventHandlerSet(USB_DEVICE_CDC_INDEX_0, APP_USBDeviceCDCEventHandler, (uintptr_t)0);
            break;
            
        case USB_DEVICE_EVENT_CONTROL_TRANSFER_SETUP_REQUEST:
            // This event indicates a Control transfer setup stage has been completed. 
            setupPacket = (USB_SETUP_PACKET *)pData;
            
            // Parse the setup packet and respond with a USB_DEVICE_ControlSend(), 
            // USB_DEVICE_ControlReceive or USB_DEVICE_ControlStatus(). 
            
            break; 
            
        case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_SENT:
            // This event indicates that a Control transfer Data has been sent to Host.   
            break; 
            
        case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_RECEIVED:
            // This event indicates that a Control transfer Data has been received from Host.
            break; 
            
        case USB_DEVICE_EVENT_CONTROL_TRANSFER_ABORTED:
            // This event indicates a control transfer was aborted. 
            break; 
            
        case USB_DEVICE_EVENT_SUSPENDED:
            break;
            
        case USB_DEVICE_EVENT_RESUMED:
            break;
            
        case USB_DEVICE_EVENT_ERROR:
            break;
            
        case USB_DEVICE_EVENT_RESET:
            break;
            
        case USB_DEVICE_EVENT_SOF:
            // This event indicates an SOF is detected on the bus. The  USB_DEVICE_SOF_EVENT_ENABLE
            // macro should be defined to get this event. 
            break;
        default:
            break;
    }
}


void APP_Tasks ( void )
{
    // Check the application's current state.
    switch ( appState )
    {
        // Application's initial state. 
        case APP_STATE_INIT:
            // Open the device layer 
            usbDeviceHandle = USB_DEVICE_Open( USB_DEVICE_INDEX_0,
                DRV_IO_INTENT_READWRITE );

            if(usbDeviceHandle != USB_DEVICE_HANDLE_INVALID)
            {
                // Register a callback with device layer to get event notification 
                USB_DEVICE_EventHandlerSet(usbDeviceHandle,
                    APP_USBDeviceEventHandler, 0);
                appState = APP_STATE_WAIT_FOR_CONFIGURATION;
            }
            else
            {
                // The Device Layer is not ready to be opened. We should try
                // gain later. 
            }
            break; 

        case APP_STATE_SERVICE_TASKS:
            break; 

            // The default state should never be executed. 
        default:
            break; 
    }
}

Remarks

None.