RA Flexible Software Package Documentation  Release v5.2.0

 
USB Peripheral Vendor class (r_usb_pvnd)

Functions

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

Overview

USB Peripheral Vendor class works by combining r_usb_basic module.

How to Configuration

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

r_usb_pvendor1.png
Select USB Peripheral Vendor Class
r_usb_pvendor2.png
USB Peripheral Vendor Class Stack

API

Use the following APIs in Peripheral 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.
FSP driver pipe configuration behaviors for the PVND Class, when it is used with the Composite PCDC+PVND Class is mentioned below.


For example:

Descriptor

Template for Vendor class descriptor can be found in ra/fsp/src/r_usb_pvnd folder. Also, please be sure to use your vendor ID.

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)
    #if (BSP_CFG_RTOS == 2) /* FreeRTOS */
    /******************************************************************************
    * 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) /* FreeRTOS */
    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};
    uint32_t request_length = 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) /* FreeRTOS */
    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;
    g_usb_on_usb.usedPipesGet(&g_basic0_ctrl, &used_pipe, USB_CLASS_PVND);
    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;
    }
    }
    }
    }
    break;
    }
    {
    if (FSP_ERR_USB_FAILED != event_info.status)
    {
    if (bulk_out_pipe == event_info.pipe)
    {
    buf_type = BUF_BULK;
    pipe = bulk_in_pipe;
    }
    else if (int_out_pipe == event_info.pipe)
    {
    buf_type = BUF_INT;
    pipe = int_in_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_in_pipe == event_info.pipe)
    {
    buf_type = BUF_BULK;
    if (1 == is_zlp[buf_type])
    {
    pipe = bulk_out_pipe;
    }
    }
    else if (int_in_pipe == event_info.pipe)
    {
    buf_type = BUF_INT;
    if (1 == is_zlp[buf_type])
    {
    pipe = int_out_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))
    {
    g_usb_on_usb.periControlStatusSet(&g_basic0_ctrl, USB_SETUP_STATUS_ACK);
    }
    else if (USB_SET_VENDOR == (event_info.setup.request_type & USB_BREQUEST))
    {
    request_length = event_info.setup.request_length;
    g_usb_on_usb.periControlDataGet(&g_basic0_ctrl, &g_request_buf[0], request_length);
    }
    else if (USB_GET_VENDOR == (event_info.setup.request_type & USB_BREQUEST))
    {
    g_usb_on_usb.periControlDataSet(&g_basic0_ctrl, &g_request_buf[0], request_length);
    }
    else
    {
    /* Nothing */
    }
    break;
    }
    {
    if (USB_GET_VENDOR == (event_info.setup.request_type & USB_BREQUEST))
    {
    g_usb_on_usb.pipeRead(&g_basic0_ctrl, &g_buf[BUF_BULK][0], BUF_SIZE, bulk_out_pipe);
    g_usb_on_usb.pipeRead(&g_basic0_ctrl, &g_buf[BUF_INT][0], BUF_SIZE, int_out_pipe);
    }
    break;
    }
    {
    break;
    }
    default:
    {
    break;
    }
    }
    }
    } /* End of function usb_pvnd_example() */
    /******************************************************************************
    * 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
    ******************************************************************************/