RA Flexible Software Package Documentation  Release v5.2.0

 
USB Host Vendor class (r_usb_hvnd)

Functions

Refer to USB (r_usb_basic) for the common API (r_usb_basic) to be called from the application.

Overview

USB Host Vendor class works by combining r_usb_basic module.

How to Configuration

The following shows FSP configuration procedure for USB Host Vendor class.

r_usb_hvendor1.png
Select USB Host Vendor Class
r_usb_hvendor2.png
USB Host Vendor Class Stack

API

Use the following APIs in Host Vendor class application program.

USB PIPE Allocation

The USB driver allocates USB PIPE by analyzing the descriptor of USB device in Vendor class.
The USB PIPE related to the Endpoint Descriptor are allocated in order from USB PIPE1 according to the description order of the Endpoint Descriptor.

Examples

This application program processes the follwoing after the enumeration completes with USB device.

  1. Getting USB Pipe Infomattion
  2. Vendor Class Request Processing
  3. Loopback processing of bulk transfer and interrupt transfer.
    /******************************************************************************
    * Macro definitions
    ******************************************************************************/
    /* for Vendor Class Request */
    #define USB_SET_VENDOR_NO_DATA (0x0000U)
    #define USB_SET_VENDOR (0x0100U)
    #define USB_GET_VENDOR (0x0200U)
    #define SET_VENDOR_NO_DATA (USB_SET_VENDOR_NO_DATA | USB_HOST_TO_DEV | USB_VENDOR | USB_INTERFACE)
    #define SET_VENDOR (USB_SET_VENDOR | USB_HOST_TO_DEV | USB_VENDOR | USB_INTERFACE)
    #define GET_VENDOR (USB_GET_VENDOR | USB_DEV_TO_HOST | USB_VENDOR | USB_INTERFACE)
    #if (BSP_CFG_RTOS == 2)
    /******************************************************************************
    * Function Name : usb_apl_callback
    * Description : Callback function for Application program
    * Arguments : usb_event_info_t *p_api_event : Control structure for USB API.
    * : usb_hdl_t cur_task : Task Handle
    * : uint8_t usb_state : USB_ON(USB_STATUS_REQUEST) / USB_OFF
    * Return value : none
    ******************************************************************************/
    void usb_apl_callback (usb_event_info_t * p_api_event, usb_hdl_t cur_task, usb_onoff_t usb_state)
    {
    (void) usb_state;
    (void) cur_task;
    xQueueSend(g_apl_mbx_hdl, (const void *) &p_api_event, (TickType_t) (0));
    } /* End of function usb_apl_callback() */
    #endif /* (BSP_CFG_RTOS == 2) */
    /******************************************************************************
    * Function Name : usb_pvnd_example
    * Description : Peripheral Vendor Class application main process
    * Arguments : none
    * Return value : none
    ******************************************************************************/
    void usb_pvnd_example (void)
    {
    #if (BSP_CFG_RTOS == 2)
    usb_event_info_t * p_mess;
    #endif
    usb_status_t event;
    usb_event_info_t event_info;
    uint8_t bulk_out_pipe = 0; /* Bulk Out Pipe */
    uint8_t bulk_in_pipe = 0; /* Bulk In Pipe */
    uint8_t int_out_pipe = 0; /* Interrupt Out Pipe */
    uint8_t int_in_pipe = 0; /* Interrupt In Pipe */
    uint16_t buf_type = 0;
    uint8_t pipe = 0;
    uint8_t is_zlp[2] = {0, 0};
    uint16_t used_pipe = 0;
    usb_pipe_t pipe_info;
    g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
    while (1)
    {
    #if (BSP_CFG_RTOS == 2)
    xQueueReceive(g_apl_mbx_hdl, (void *) &p_mess, portMAX_DELAY);
    event_info = *p_mess;
    event = event_info.event;
    #else /* (BSP_CFG_RTOS == 2) */
    g_usb_on_usb.eventGet(&event_info, &event);
    #endif /* (BSP_CFG_RTOS == 2) */
    switch (event)
    {
    {
    buffer_init();
    is_zlp[0] = 0;
    is_zlp[1] = 0;
    /* Get USB Pipe Information */
    g_usb_on_usb.usedPipesGet(&g_basic0_ctrl, &used_pipe, ADDRESS1);
    for (pipe = START_PIPE; pipe < END_PIPE; pipe++)
    {
    if (0 != (used_pipe & (1 << pipe)))
    {
    g_usb_on_usb.pipeInfoGet(&g_basic0_ctrl, &pipe_info, pipe);
    if (USB_EP_DIR_IN != (pipe_info.endpoint & USB_EP_DIR_IN))
    {
    /* Out Transfer */
    if (USB_TRANSFER_TYPE_BULK == pipe_info.transfer_type)
    {
    buf_type = BUF_BULK;
    bulk_out_pipe = pipe;
    }
    else
    {
    buf_type = BUF_INT;
    int_out_pipe = pipe;
    }
    }
    else
    {
    /* In Transfer */
    if (USB_TRANSFER_TYPE_BULK == pipe_info.transfer_type)
    {
    buf_type = BUF_BULK;
    bulk_in_pipe = pipe;
    }
    else
    {
    buf_type = BUF_INT;
    int_in_pipe = pipe;
    }
    }
    }
    }
    /* Send Vendor Class Request */
    class_request_set_vendor_no_data(&g_basic0_ctrl, event_info.device_address);
    break;
    }
    {
    if (FSP_ERR_USB_FAILED != event_info.status)
    {
    if (bulk_in_pipe == event_info.pipe)
    {
    buf_type = BUF_BULK;
    pipe = bulk_out_pipe;
    }
    else if (int_in_pipe == event_info.pipe)
    {
    buf_type = BUF_INT;
    pipe = int_out_pipe;
    }
    else
    {
    while (1)
    {
    ;
    }
    }
    buffer_check(buf_type, event_info.data_size);
    g_usb_on_usb.pipeWrite(&g_basic0_ctrl, &g_buf[buf_type][0], event_info.data_size, pipe);
    }
    break;
    }
    {
    if (bulk_out_pipe == event_info.pipe)
    {
    buf_type = BUF_BULK;
    if (1 == is_zlp[buf_type])
    {
    pipe = bulk_in_pipe;
    }
    }
    else if (int_out_pipe == event_info.pipe)
    {
    buf_type = BUF_INT;
    if (1 == is_zlp[buf_type])
    {
    pipe = int_in_pipe;
    }
    }
    else
    {
    /* Nothing */
    }
    if (1 == is_zlp[buf_type])
    {
    is_zlp[buf_type] = 0;
    buffer_clear(buf_type);
    g_usb_on_usb.pipeRead(&g_basic0_ctrl, &g_buf[buf_type][0], BUF_SIZE, pipe);
    }
    else
    {
    is_zlp[buf_type] = 1;
    g_usb_on_usb.pipeWrite(&g_basic0_ctrl, 0, 0, event_info.pipe); /* Send ZLP */
    }
    break;
    }
    {
    if (USB_SET_VENDOR_NO_DATA == (event_info.setup.request_type & USB_BREQUEST))
    {
    class_request_set_vendor(&g_basic0_ctrl, event_info.device_address);
    }
    else if (USB_SET_VENDOR == (event_info.setup.request_type & USB_BREQUEST))
    {
    class_request_get_vendor(&g_basic0_ctrl, event_info.device_address);
    }
    else if (USB_GET_VENDOR == (event_info.setup.request_type & USB_BREQUEST))
    {
    buffer_init();
    /* Bulk Out Transfer */
    g_usb_on_usb.pipeWrite(&g_basic0_ctrl, &g_buf[BUF_BULK][0], (BUF_SIZE - USB_APL_MXPS),
    bulk_out_pipe);
    /* Interrupt Out Transfer */
    g_usb_on_usb.pipeWrite(&g_basic0_ctrl, &g_buf[BUF_INT][0], (BUF_SIZE - USB_APL_MXPS), int_out_pipe);
    }
    else
    {
    /* Unsupported request */
    }
    break;
    }
    {
    break;
    }
    default:
    {
    break;
    }
    }
    }
    } /* End of function usb_pvnd_example() */
    /******************************************************************************
    * Function Name : class_request_set_vendor
    * Description : Send Vendor Class Request (SET_VENDOR) to USB device.
    * Arguments : none
    * Return value : none
    ******************************************************************************/
    static void class_request_set_vendor (usb_instance_ctrl_t * p_ctrl, uint8_t device_address)
    {
    usb_setup_t setup;
    uint16_t i;
    for (i = 0; i < REQ_SIZE; i++)
    {
    g_request_buf[i] = (uint8_t) i;
    }
    setup.request_type = SET_VENDOR; /* bRequestCode:SET_VENDOR, bmRequestType */
    setup.request_value = 0x0000; /* wValue:Zero */
    setup.request_index = 0x0000; /* wIndex:Interface */
    setup.request_length = REQ_SIZE; /* wLength: Data Length */
    /* Request Control transfer */
    g_usb_on_usb.hostControlTransfer(p_ctrl, &setup, &g_request_buf[0], device_address);
    } /* End of function class_request_set_vendor() */
    /******************************************************************************
    * Function Name : class_request_set_vendor_no_data
    * Description : Send Vendor Class Request (SET_VENDOR_NO_DATA) to USB device.
    * Arguments : none
    * Return value : none
    ******************************************************************************/
    static void class_request_set_vendor_no_data (usb_instance_ctrl_t * p_ctrl, uint8_t device_address)
    {
    usb_setup_t setup;
    uint16_t i;
    for (i = 0; i < REQ_SIZE; i++)
    {
    g_request_buf[i] = (uint8_t) i;
    }
    setup.request_type = SET_VENDOR_NO_DATA; /* bRequestCode:SET_VENDOR_NO_DATA, bmRequestType */
    setup.request_value = 0x0000; /* wValue:Zero */
    setup.request_index = 0x0000; /* wIndex:Interface */
    setup.request_length = 0x0000; /* wLength: Data Length */
    /* Request Control transfer */
    g_usb_on_usb.hostControlTransfer(p_ctrl, &setup, &g_request_buf[0], device_address);
    } /* End of function class_request_set_vendor_no_data() */
    /******************************************************************************
    * Function Name : class_request_get_vendor
    * Description : Send Vendor Class Request (GET_VENDOR) to USB device.
    * Arguments : none
    * Return value : none
    ******************************************************************************/
    static void class_request_get_vendor (usb_instance_ctrl_t * p_ctrl, uint8_t device_address)
    {
    usb_setup_t setup;
    uint16_t i;
    for (i = 0; i < REQ_SIZE; i++)
    {
    g_request_buf[i] = 0;
    }
    setup.request_type = GET_VENDOR; /* bRequestCode:GET_VENDOR, bmRequestType */
    setup.request_value = 0x0000; /* wValue:Zero */
    setup.request_index = 0x0000; /* wIndex:Interface */
    setup.request_length = REQ_SIZE; /* wLength: Data Length */
    /* Request Control transfer */
    g_usb_on_usb.hostControlTransfer(p_ctrl, &setup, &g_request_buf[0], device_address);
    } /* End of function class_request_get_vendor() */
    /******************************************************************************
    * Function Name : buffer_init
    * Description : buffer initialization
    * Arguments : none
    * Return value : none
    ******************************************************************************/
    static void buffer_init (void)
    {
    uint16_t i;
    uint16_t j;
    for (j = 0; j < 2; j++)
    {
    for (i = 0; i < BUF_SIZE; i++)
    {
    g_buf[j][i] = (uint8_t) i;
    }
    }
    } /* End of function buffer_init() */
    /******************************************************************************
    * Function Name : buffer_check
    * Description : buffer check
    * Arguments : buf_type : buffer number
    * Return value : none
    ******************************************************************************/
    static void buffer_check (uint16_t buf_type, uint32_t size)
    {
    uint16_t i;
    for (i = 0; i < (uint16_t) size; i++)
    {
    if ((uint8_t) (i & USB_VALUE_FF) != g_buf[buf_type][i])
    {
    while (1)
    {
    ;
    }
    }
    }
    } /* End of function buffer_check() */
    /******************************************************************************
    * Function Name : buffer_clear
    * Description : buffer clear
    * Arguments : buf_type : buffer number
    * Return value : none
    ******************************************************************************/
    static void buffer_clear (uint16_t buf_type)
    {
    uint16_t i;
    for (i = 0; i < BUF_SIZE; i++)
    {
    g_buf[buf_type][i] = 0;
    }
    } /* End of function buffer_clear() */
    /******************************************************************************
    * End of function usb_mcu_init
    ******************************************************************************/