RA Flexible Software Package Documentation  Release v6.6.0

 
USB PUVC (r_usb_puvc)

This module provides a USB Peripheral Video Device Class Driver (PUVC). It implements the USB PUVC Interface.

Functions

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

Detailed Description

Overview

The r_usb_puvc module combines with the r_usb_basic module to provide USB Peripheral Video Device Class (PUVC) driver.

Features

The r_usb_puvc module has the following key features:

Clock Configuration

Refer to the USB (r_usb_basic) module.

Pin Configuration

Refer to the USB (r_usb_basic) module.

Usage Notes

Class Requests (Host to Peripheral)

This driver notifies the application when receiving the following class requests:

Request Request Code Description
SET_CUR 0x01 Set the current value of the control
GET_CUR 0x81 Get the current value of the control
GET_MIN 0x82 Get the minimum value of the control parameter
GET_MAX 0x83 Get the maximum value of the control parameter

Note:

For details about each device class, please refer to Video Class specification.

Transfer Type

This driver uses the following transfer type for the streaming data transfer.

Note:

This driver does not support Bulk transfer.

Limitations

Examples

USB PUVC Example

#define APP_VIDEO_DATA_BUFFER_SIZE (1024 * 20)
#define BMREQUESTTYPEDIR (0x0080U) /* bmRequestType (b7) */
#define BMREQUESTTYPETYPE (0x0060U) /* bmRequestType (b6-5) */
#define VIDEO_PROBE_NOT_SET 0
#define ISO_IF_ALT_0 (0x0000)
#define VALUE_FFH (0xFF)
#define VALUE_34 (34)
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DEVICE_TIME)
#define APP_DEVICE_CLOCK_FREQUENCY_100_MHZ (0x05F5E100U) /* PCLKD(100MHz) */
#define APP_DEVICE_CLOCK_FREQUENCY APP_DEVICE_CLOCK_FREQUENCY_100_MHZ
#endif
/* @r_usb_puvc_descriptor.c.template */
#define USB_UVC_MAX_VIDEO_FRAME_BUFFER_SIZE_150000 (0x000249F0U) /* 150000 */
#define USB_UVC_MAX_VIDEO_FRAME_BUFFER_SIZE USB_UVC_MAX_VIDEO_FRAME_BUFFER_SIZE_150000
#define USB_PUVC_MAX_PACKET_SIZE_800 (0x320) /* 800 */
#define USB_PUVC_MAX_PACKET_SIZE_1024 (0x400) /* 1024 */
#define USB_PUVC_MAX_PACKET_SIZE USB_PUVC_MAX_PACKET_SIZE_1024
/******************************************************************************
* Exported global functions (to be accessed by other files)
******************************************************************************/
void usb_puvc_example(void);
#if (BSP_CFG_RTOS == 2)
void usb_apl_callback(usb_event_info_t * p_event_info, usb_hdl_t handler, usb_onoff_t state);
#endif
/******************************************************************************
* Private global variables and functions
******************************************************************************/
static usb_puvc_video_probe_control_t g_video_probe_control;
static usb_puvc_video_probe_control_t g_video_commit_control;
static uint8_t g_control_buf[VALUE_34] = {0}; /* Data buffer for the data stage of class requests */
static uint8_t g_snd_buf[APP_VIDEO_DATA_BUFFER_SIZE] = {0}; /* Video data buffer used for isochronous IN transfer */
static uint32_t g_total_send_length = 0; /* Total transmitted video data size */
static volatile bool g_err_flag = false;
static bool b_usb_connected = false;
static uint16_t g_current_alt = 0;
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DEVICE_TIME)
static uint32_t g_pre_scr_device_clock_count = 0;
static double_t g_total_elapsed_time_in_a_frame_s = 0;
static void puvc_app_device_clock_init(void);
static uint32_t puvc_app_device_clock_get(void);
#endif
static fsp_err_t process_usb_events(void);
static void puvc_app_video_class_request(void);
static void puvc_app_video_class_request_out(void);
static void puvc_app_video_class_request_out_complete(void);
static void puvc_app_video_class_request_in(void);
static void puvc_app_video_data_init(uint8_t * p_video_data);
static void puvc_app_video_header_make(usb_puvc_video_payload_header_t * p_header);
static void puvc_app_video_data_make(uint8_t * p_video_data);
static void puvc_app_data_buffer_clear(void);
static void handle_error(fsp_err_t err, char * err_str);
extern const usb_cfg_t g_basic0_cfg;
extern usb_instance_ctrl_t g_basic0_ctrl;
#if (BSP_CFG_RTOS == 2)
static volatile usb_event_info_t * p_usb_event = NULL;
#else
static usb_event_info_t event_info = {0};
static volatile usb_event_info_t * p_usb_event = &event_info;
#endif
#if (BSP_CFG_RTOS == 2)
extern QueueHandle_t g_queue;
#endif
/*******************************************************************************************************************
* Function Name : usb_puvc_example
* Description : Peripheral Video Application Main Process
* Arguments : none
* Return value : none
*******************************************************************************************************************/
void usb_puvc_example (void)
{
fsp_err_t err = FSP_SUCCESS;
#if (BSP_CFG_RTOS == 2)
BaseType_t err_queue = pdFALSE;
#endif
/* Initialize the data that is set or referenced in Class Requests (Video Streaming Requests) */
g_video_probe_control.hint = VIDEO_PROBE_NOT_SET;
g_video_probe_control.format_index = VIDEO_PROBE_NOT_SET;
g_video_probe_control.frame_index = VIDEO_PROBE_NOT_SET;
g_video_probe_control.frame_interval = VIDEO_PROBE_NOT_SET;
g_video_probe_control.key_frame_rate = VIDEO_PROBE_NOT_SET;
g_video_probe_control.frame_rate = VIDEO_PROBE_NOT_SET;
g_video_probe_control.comp_quality = VIDEO_PROBE_NOT_SET;
g_video_probe_control.comp_windows_size = VIDEO_PROBE_NOT_SET;
g_video_probe_control.delay = VIDEO_PROBE_NOT_SET;
g_video_probe_control.max_video_frame_size = USB_UVC_MAX_VIDEO_FRAME_BUFFER_SIZE;
g_video_probe_control.max_payload_transfer_size = USB_PUVC_MAX_PACKET_SIZE;
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DAMMY)
g_video_probe_control.clock_frequency = VIDEO_PROBE_NOT_SET;
#else
g_video_probe_control.clock_frequency = APP_DEVICE_CLOCK_FREQUENCY;
#endif
g_video_probe_control.framing_info = VIDEO_PROBE_NOT_SET;
g_video_probe_control.prefered_version = VIDEO_PROBE_NOT_SET;
g_video_probe_control.min_version = VIDEO_PROBE_NOT_SET;
g_video_probe_control.max_version = VIDEO_PROBE_NOT_SET;
/* Open USB instance */
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DEVICE_TIME)
puvc_app_device_clock_init();
#endif
/* USB Opened successfully. */
while (true)
{
/* Handle error if queue send fails*/
if (true == g_err_flag)
{
handle_error(FSP_ERR_ABORTED, "\r\nError in sending usb event through queue\r\n");
}
#if (BSP_CFG_RTOS == 2)
/* Receive message from queue */
err_queue = xQueueReceive(g_queue, &p_usb_event, (portMAX_DELAY));
/* Handle error */
if (pdTRUE != err_queue)
{
handle_error(FSP_ERR_ABORTED, "\r\nError in receiving event through queue\r\n");
}
#else
/* Obtain USB related events */
err = R_USB_EventGet(&event_info, &event_info.event);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
#endif
/* process USB events */
err = process_usb_events();
handle_error(err, "\r\nprocess_usb_events failed.\r\n");
}
}
/*******************************************************************************************************************
* Function Name : process_usb_events
* Description : Function processes USB events
* Arguments : none
* Return value : Any Other Error code apart from FSP_SUCCESS on Unsuccessful operation
*******************************************************************************************************************/
fsp_err_t process_usb_events (void)
{
fsp_err_t err = FSP_SUCCESS;
usb_puvc_video_payload_header_t uvc_header;
/* USB event received */
switch (p_usb_event->event)
{
{
b_usb_connected = true;
break;
}
{
/* Normal Request (Isochronous IN Transfer) Completion Event */
if ((true == b_usb_connected) && (0 < g_current_alt))
{
if (FSP_SUCCESS == p_usb_event->status)
{
if (APP_VIDEO_DATA_BUFFER_SIZE >
(g_total_send_length + g_video_probe_control.max_payload_transfer_size))
{
g_total_send_length += g_video_probe_control.max_payload_transfer_size;
}
else
{
g_total_send_length = 0;
}
/* Set the video data */
puvc_app_video_data_make(g_snd_buf + g_total_send_length);
/* Set the UVC header (the first 12 bytes of the video data) */
puvc_app_video_header_make(&uvc_header);
memcpy(g_snd_buf + g_total_send_length, &uvc_header, sizeof(uvc_header));
/* Continue the Video data transmission (isochronous IN transfer request) */
err = R_USB_Write(&g_basic0_ctrl,
g_snd_buf + g_total_send_length,
g_video_probe_control.max_payload_transfer_size,
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
break;
}
{
/* This event indicates that the device has received a control transfer request
* (i.e., a class request) since SET_CONFIGURATION. */
if (b_usb_connected)
{
/* Check if it's a class request */
if (USB_CLASS == (p_usb_event->setup.request_type & BMREQUESTTYPETYPE))
{
puvc_app_video_class_request();
}
else
{
/* Do nothing */
}
}
break;
}
{
/* This event indicates that a control transfer request
* (SET_INTERFACE issued after SET_CONFIGURATION or
* class request issued after SET_CONFIGURATION)
* has been completed. */
if (b_usb_connected)
{
/* Check if it's a standard request */
if (USB_STANDARD == (p_usb_event->setup.request_type & BMREQUESTTYPETYPE))
{
/* Check the direction */
if (USB_HOST_TO_DEV == (p_usb_event->setup.request_type & BMREQUESTTYPEDIR))
{
/* Check if it's SET_INTERFACE */
if (USB_SET_INTERFACE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Check the ALT number */
if (ISO_IF_ALT_0 < p_usb_event->setup.request_value)
{
/* SET_INTERFACE (IF=1/ALT=1) has been completed */
/* Save the current ALT */
g_current_alt = p_usb_event->setup.request_value;
/* Initialize and set the video data */
puvc_app_video_data_init(g_snd_buf);
/* Set the UVC header (the first 12 bytes of the video data) */
puvc_app_video_header_make(&uvc_header);
memcpy(g_snd_buf, &uvc_header, sizeof(uvc_header));
/* Start the Video data transmission (isochronous IN transfer request) */
err = R_USB_Write(&g_basic0_ctrl,
g_snd_buf,
g_video_probe_control.max_payload_transfer_size,
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* SET_INTERFACE (IF=1/ALT=0) has been completed.
* In other words, Host stopped video streaming. */
if (0 != g_current_alt)
{
/* Clear the current ALT */
g_current_alt = 0;
/* As a precaution, the application will also terminate the send request.
* (Assuming a send request was made after receiving SET_INTERFACE(ALT=0)) */
}
/* Clear the data that is set or referenced in Class Requests (Video Streaming Requests) */
memset(&g_video_probe_control, 0, sizeof(g_video_probe_control));
memset(&g_video_commit_control, 0, sizeof(g_video_commit_control));
}
g_total_send_length = 0;
}
}
}
/* Check if it's a class request */
else if (USB_CLASS == (p_usb_event->setup.request_type & BMREQUESTTYPETYPE))
{
/* Check the direction */
if (USB_HOST_TO_DEV == (p_usb_event->setup.request_type & BMREQUESTTYPEDIR))
{
puvc_app_video_class_request_out_complete();
}
else
{
/* Do nothing */
}
}
else
{
/* Do nothing */
}
}
break;
}
{
b_usb_connected = false;
g_current_alt = 0;
/* Clear the video data buffer information */
puvc_app_data_buffer_clear();
g_total_send_length = 0;
break;
}
{
b_usb_connected = true;
break;
}
default:
{
break;
}
}
return err;
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_class_request
* Description : Depending on the direction of the data stage of the received class request,
* this function calls the appropriate internal function.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_class_request (void)
{
/* Check the direction */
if (USB_HOST_TO_DEV == (BMREQUESTTYPEDIR & p_usb_event->setup.request_type))
{
/* Data Stage is out-direction */
puvc_app_video_class_request_out();
}
else if (USB_DEV_TO_HOST & p_usb_event->setup.request_type)
{
/* Data Stage is in-direction */
puvc_app_video_class_request_in();
}
else
{
/* STALL */
}
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_class_request_out
* Description : This function requests data stage transfer in the OUT direction.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_class_request_out (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Check if the request is SET_CUR */
if ((USB_PUVC_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(USB_INTERFACE == (p_usb_event->setup.request_type & USB_INTERFACE)))
{
/* Check which interface is being targeted */
if (0 == p_usb_event->setup.request_index)
{
/* Received request is Video Control Request (for Video Control Interface) */
/* This application does not support Video Control Requests, so it issues a STALL. */
}
else
{
/* Received request is Video Streaming Request (for Video Streaming Interface) */
/* Check if the request is for Probe Control or Commit Control */
if ((USB_PUVC_VS_PROBE_CONTROL == p_usb_event->setup.request_value) ||
(USB_PUVC_VS_COMMIT_CONTROL == p_usb_event->setup.request_value))
{
err = R_USB_PeriControlDataGet(&g_basic0_ctrl,
(uint8_t *) g_control_buf,
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* STALL */
}
}
}
else
{
/* STALL */
}
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_class_request_out_complete
* Description : This function is called when data stage transfer in the OUT direction is complete.
* This function retrieves the received data.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_class_request_out_complete (void)
{
/* Check if the request is SET_CUR */
if ((USB_PUVC_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(USB_INTERFACE == (p_usb_event->setup.request_type & USB_INTERFACE)))
{
/* Check which interface is being targeted */
if (0 == p_usb_event->setup.request_index)
{
/* Completed request is Video Control Request (for Video Control Interface) */
/* This application does not support Video Control Requests, so it will do nothing */
}
else
{
/* Completed request is Video Streaming Request (for Video Streaming Interface) */
/* Check if the request is for Probe Control */
if (USB_PUVC_VS_PROBE_CONTROL == p_usb_event->setup.request_value)
{
/* Save the data received in the data stage */
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.hint)
{
g_video_probe_control.hint = (uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET]);
g_video_probe_control.hint |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET + 1] << 8);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.format_index)
{
g_video_probe_control.format_index =
g_control_buf[USB_PUVC_PROBE_COMMIT_FORMAT_INDEX_OFFSET];
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.frame_index)
{
g_video_probe_control.frame_index =
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INDEX_OFFSET];
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.frame_interval)
{
g_video_probe_control.frame_interval =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET]);
g_video_probe_control.frame_interval |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET + 1] << 8);
g_video_probe_control.frame_interval |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET + 2] << 16);
g_video_probe_control.frame_interval |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET + 3] << 24);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.key_frame_rate)
{
g_video_probe_control.key_frame_rate =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET]);
g_video_probe_control.key_frame_rate |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET + 1] << 8);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.frame_rate)
{
g_video_probe_control.frame_rate =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET]);
g_video_probe_control.frame_rate |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET + 1] << 8);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.comp_quality)
{
g_video_probe_control.comp_quality =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET]);
g_video_probe_control.comp_quality |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET + 1] << 8);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.comp_windows_size)
{
g_video_probe_control.comp_windows_size =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET]);
g_video_probe_control.comp_windows_size |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET + 1] << 8);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.delay)
{
g_video_probe_control.delay = (uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET]);
g_video_probe_control.delay |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET + 1] << 8);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.max_video_frame_size)
{
g_video_probe_control.max_video_frame_size =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET]);
g_video_probe_control.max_video_frame_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET + 1] << 8);
g_video_probe_control.max_video_frame_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET + 2] << 16);
g_video_probe_control.max_video_frame_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET + 3] << 24);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.max_payload_transfer_size)
{
g_video_probe_control.max_payload_transfer_size =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET]);
g_video_probe_control.max_payload_transfer_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET + 1] << 8);
g_video_probe_control.max_payload_transfer_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET + 2] << 16);
g_video_probe_control.max_payload_transfer_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET + 3] << 24);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.clock_frequency)
{
g_video_probe_control.clock_frequency =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET]);
g_video_probe_control.clock_frequency |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET + 1] << 8);
g_video_probe_control.clock_frequency |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET + 2] << 16);
g_video_probe_control.clock_frequency |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET + 3] << 24);
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.framing_info)
{
g_video_probe_control.framing_info =
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAMING_INFO_OFFSET];
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.prefered_version)
{
g_video_probe_control.prefered_version =
g_control_buf[USB_PUVC_PROBE_COMMIT_PREFERRED_VERSION_OFFSET];
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.min_version)
{
g_video_probe_control.min_version =
g_control_buf[USB_PUVC_PROBE_COMMIT_MIN_VERSION_OFFSET];
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.max_version)
{
g_video_probe_control.max_version =
g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VERSION_OFFSET];
}
/* If the format index, frame index, and frame interval are saved,
* the maximum video frame buffer size and maximum packet size are set
* in preparation for the next request (GET_CUR). */
if (((VIDEO_PROBE_NOT_SET != g_video_probe_control.format_index) &&
(VIDEO_PROBE_NOT_SET != g_video_probe_control.frame_index)) &&
(VIDEO_PROBE_NOT_SET != g_video_probe_control.frame_interval))
{
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.max_video_frame_size)
{
g_video_probe_control.max_video_frame_size = USB_UVC_MAX_VIDEO_FRAME_BUFFER_SIZE;
}
if (VIDEO_PROBE_NOT_SET == g_video_probe_control.max_payload_transfer_size)
{
g_video_probe_control.max_payload_transfer_size = USB_PUVC_MAX_PACKET_SIZE;
}
}
}
/* Check if the request is for Commit Control */
else if (USB_PUVC_VS_COMMIT_CONTROL == p_usb_event->setup.request_value)
{
/* Save the data received in the data stage */
g_video_commit_control.hint = (uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET]);
g_video_commit_control.hint |= (uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET + 1] << 8);
g_video_commit_control.format_index =
g_control_buf[USB_PUVC_PROBE_COMMIT_FORMAT_INDEX_OFFSET];
g_video_commit_control.frame_index =
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INDEX_OFFSET];
g_video_commit_control.frame_interval =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET]);
g_video_commit_control.frame_interval |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET + 1] << 8);
g_video_commit_control.frame_interval |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET + 2] << 16);
g_video_commit_control.frame_interval |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET + 3] << 24);
g_video_commit_control.key_frame_rate =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET]);
g_video_commit_control.key_frame_rate |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET + 1] << 8);
g_video_commit_control.frame_rate =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET]);
g_video_commit_control.frame_rate |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET + 1] << 8);
g_video_commit_control.comp_quality =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET]);
g_video_commit_control.comp_quality |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET + 1] << 8);
g_video_commit_control.comp_windows_size =
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET]);
g_video_commit_control.comp_windows_size |=
(uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET + 1] << 8);
g_video_commit_control.delay = (uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET]);
g_video_commit_control.delay |= (uint16_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET + 1] << 8);
g_video_commit_control.max_video_frame_size =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET]);
g_video_commit_control.max_video_frame_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET + 1] << 8);
g_video_commit_control.max_video_frame_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET + 2] << 16);
g_video_commit_control.max_video_frame_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET + 3] << 24);
g_video_commit_control.max_payload_transfer_size =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET]);
g_video_commit_control.max_payload_transfer_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET + 1] << 8);
g_video_commit_control.max_payload_transfer_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET + 2] << 16);
g_video_commit_control.max_payload_transfer_size |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET + 3] << 24);
g_video_commit_control.clock_frequency =
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET]);
g_video_commit_control.clock_frequency |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET + 1] << 8);
g_video_commit_control.clock_frequency |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET + 2] << 16);
g_video_commit_control.clock_frequency |=
(uint32_t) (g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET + 3] << 24);
g_video_commit_control.framing_info =
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAMING_INFO_OFFSET];
g_video_commit_control.prefered_version =
g_control_buf[USB_PUVC_PROBE_COMMIT_PREFERRED_VERSION_OFFSET];
g_video_commit_control.min_version =
g_control_buf[USB_PUVC_PROBE_COMMIT_MIN_VERSION_OFFSET];
g_video_commit_control.max_version =
g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VERSION_OFFSET];
}
else
{
/* Do nothing */
}
}
}
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_class_request_in
* Description : This function requests data stage transfer in the IN direction.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_class_request_in (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Check if the request is GET_CUR */
if ((USB_PUVC_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(USB_INTERFACE == (p_usb_event->setup.request_type & USB_INTERFACE)))
{
/* Check which interface is being targeted */
if (0 == p_usb_event->setup.request_index)
{
/* Received request is Video Control Request (for Video Control Interface) */
/* This application does not support Video Control Requests, so it issues a STALL. */
}
else
{
/* Received request is Video Streaming Request (for Video Streaming Interface) */
/* Check if the request is for Probe Control */
if (USB_PUVC_VS_PROBE_CONTROL == p_usb_event->setup.request_value)
{
/* Copy the contents of the Probe Control to the data buffer for the data stage */
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET], (void *) &g_video_probe_control.hint,
sizeof(g_video_probe_control.hint));
g_control_buf[USB_PUVC_PROBE_COMMIT_FORMAT_INDEX_OFFSET] = g_video_probe_control.format_index;
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INDEX_OFFSET] = g_video_probe_control.frame_index;
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET],
(void *) &g_video_probe_control.frame_interval,
sizeof(g_video_probe_control.frame_interval));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET],
(void *) &g_video_probe_control.key_frame_rate,
sizeof(g_video_probe_control.key_frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET],
(void *) &g_video_probe_control.frame_rate,
sizeof(g_video_probe_control.frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET],
(void *) &g_video_probe_control.comp_quality,
sizeof(g_video_probe_control.comp_quality));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET],
(void *) &g_video_probe_control.comp_windows_size,
sizeof(g_video_probe_control.comp_windows_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET],
(void *) &g_video_probe_control.delay,
sizeof(g_video_probe_control.delay));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET],
(void *) &g_video_probe_control.max_video_frame_size,
sizeof(g_video_probe_control.max_video_frame_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET],
(void *) &g_video_probe_control.max_payload_transfer_size,
sizeof(g_video_probe_control.max_payload_transfer_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET],
(void *) &g_video_probe_control.clock_frequency,
sizeof(g_video_probe_control.clock_frequency));
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAMING_INFO_OFFSET] = g_video_probe_control.framing_info;
g_control_buf[USB_PUVC_PROBE_COMMIT_PREFERRED_VERSION_OFFSET] = g_video_probe_control.prefered_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MIN_VERSION_OFFSET] = g_video_probe_control.min_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VERSION_OFFSET] = g_video_probe_control.max_version;
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) g_control_buf,
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
/* Check if the request is for Commit Control */
else if (USB_PUVC_VS_COMMIT_CONTROL == p_usb_event->setup.request_value)
{
/* Copy the contents of the Commit Control to the data buffer for the data stage */
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET], (void *) &g_video_commit_control.hint,
sizeof(g_video_commit_control.hint));
g_control_buf[USB_PUVC_PROBE_COMMIT_FORMAT_INDEX_OFFSET] = g_video_commit_control.format_index;
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INDEX_OFFSET] = g_video_commit_control.frame_index;
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET],
(void *) &g_video_commit_control.frame_interval,
sizeof(g_video_commit_control.frame_interval));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET],
(void *) &g_video_commit_control.key_frame_rate,
sizeof(g_video_commit_control.key_frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET],
(void *) &g_video_commit_control.frame_rate,
sizeof(g_video_commit_control.frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET],
(void *) &g_video_commit_control.comp_quality,
sizeof(g_video_commit_control.comp_quality));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET],
(void *) &g_video_commit_control.comp_windows_size,
sizeof(g_video_commit_control.comp_windows_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET],
(void *) &g_video_commit_control.delay,
sizeof(g_video_commit_control.delay));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET],
(void *) &g_video_commit_control.max_video_frame_size,
sizeof(g_video_commit_control.max_video_frame_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET],
(void *) &g_video_commit_control.max_payload_transfer_size,
sizeof(g_video_commit_control.max_payload_transfer_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET],
(void *) &g_video_commit_control.clock_frequency,
sizeof(g_video_commit_control.clock_frequency));
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAMING_INFO_OFFSET] = g_video_commit_control.framing_info;
g_control_buf[USB_PUVC_PROBE_COMMIT_PREFERRED_VERSION_OFFSET] = g_video_commit_control.prefered_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MIN_VERSION_OFFSET] = g_video_commit_control.min_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VERSION_OFFSET] = g_video_commit_control.max_version;
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) g_control_buf,
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* STALL */
}
}
}
/* Check if the request is GET_MIN or GET_MAX */
else if (((USB_PUVC_GET_MIN == (p_usb_event->setup.request_type & USB_BREQUEST)) ||
(USB_PUVC_GET_MAX == (p_usb_event->setup.request_type & USB_BREQUEST))) &&
(USB_INTERFACE == (p_usb_event->setup.request_type & USB_INTERFACE)))
{
/* Check which interface is being targeted */
if (0 == p_usb_event->setup.request_index)
{
/* Received request is Video Control Request (for Video Control Interface) */
/* This application does not support Video Control Requests, so it issues a STALL. */
}
else
{
/* Received request is Video Streaming Request (for Video Streaming Interface) */
/* Check if the request is for Probe Control */
if (USB_PUVC_VS_PROBE_CONTROL == p_usb_event->setup.request_value)
{
/* Copy the contents of the Probe Control to the data buffer for the data stage */
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET], (void *) &g_video_probe_control.hint,
sizeof(g_video_probe_control.hint));
g_control_buf[USB_PUVC_PROBE_COMMIT_FORMAT_INDEX_OFFSET] = g_video_probe_control.format_index;
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INDEX_OFFSET] = g_video_probe_control.frame_index;
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET],
(void *) &g_video_probe_control.frame_interval,
sizeof(g_video_probe_control.frame_interval));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET],
(void *) &g_video_probe_control.key_frame_rate,
sizeof(g_video_probe_control.key_frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET],
(void *) &g_video_probe_control.frame_rate,
sizeof(g_video_probe_control.frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET],
(void *) &g_video_probe_control.comp_quality,
sizeof(g_video_probe_control.comp_quality));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET],
(void *) &g_video_probe_control.comp_windows_size,
sizeof(g_video_probe_control.comp_windows_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET],
(void *) &g_video_probe_control.delay,
sizeof(g_video_probe_control.delay));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET],
(void *) &g_video_probe_control.max_video_frame_size,
sizeof(g_video_probe_control.max_video_frame_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET],
(void *) &g_video_probe_control.max_payload_transfer_size,
sizeof(g_video_probe_control.max_payload_transfer_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET],
(void *) &g_video_probe_control.clock_frequency,
sizeof(g_video_probe_control.clock_frequency));
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAMING_INFO_OFFSET] = g_video_probe_control.framing_info;
g_control_buf[USB_PUVC_PROBE_COMMIT_PREFERRED_VERSION_OFFSET] = g_video_probe_control.prefered_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MIN_VERSION_OFFSET] = g_video_probe_control.min_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VERSION_OFFSET] = g_video_probe_control.max_version;
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) g_control_buf,
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
/* Check if the request is for Commit Control */
else if (USB_PUVC_VS_COMMIT_CONTROL == p_usb_event->setup.request_value)
{
/* Copy the contents of the Commit Control to the data buffer for the data stage */
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_HINT_OFFSET], (void *) &g_video_commit_control.hint,
sizeof(g_video_commit_control.hint));
g_control_buf[USB_PUVC_PROBE_COMMIT_FORMAT_INDEX_OFFSET] = g_video_commit_control.format_index;
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INDEX_OFFSET] = g_video_commit_control.frame_index;
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_FRAME_INTERVAL_OFFSET],
(void *) &g_video_commit_control.frame_interval,
sizeof(g_video_commit_control.frame_interval));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_KEY_FRAME_RATE_OFFSET],
(void *) &g_video_commit_control.key_frame_rate,
sizeof(g_video_commit_control.key_frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_PFRAME_RATE_OFFSET],
(void *) &g_video_commit_control.frame_rate,
sizeof(g_video_commit_control.frame_rate));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_QUALITY_OFFSET],
(void *) &g_video_commit_control.comp_quality,
sizeof(g_video_commit_control.comp_quality));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_COMP_WINDOW_SIZE_OFFSET],
(void *) &g_video_commit_control.comp_windows_size,
sizeof(g_video_commit_control.comp_windows_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_DELAY_OFFSET],
(void *) &g_video_commit_control.delay,
sizeof(g_video_commit_control.delay));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VIDEO_FRAME_SIZE_OFFSET],
(void *) &g_video_commit_control.max_video_frame_size,
sizeof(g_video_commit_control.max_video_frame_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_PAYLOAD_TRANSFER_SIZE_OFFSET],
(void *) &g_video_commit_control.max_payload_transfer_size,
sizeof(g_video_commit_control.max_payload_transfer_size));
memcpy(&g_control_buf[USB_PUVC_PROBE_COMMIT_CLOCK_FREQUENCY_OFFSET],
(void *) &g_video_commit_control.clock_frequency,
sizeof(g_video_commit_control.clock_frequency));
g_control_buf[USB_PUVC_PROBE_COMMIT_FRAMING_INFO_OFFSET] = g_video_commit_control.framing_info;
g_control_buf[USB_PUVC_PROBE_COMMIT_PREFERRED_VERSION_OFFSET] = g_video_commit_control.prefered_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MIN_VERSION_OFFSET] = g_video_commit_control.min_version;
g_control_buf[USB_PUVC_PROBE_COMMIT_MAX_VERSION_OFFSET] = g_video_commit_control.max_version;
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) g_control_buf,
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* STALL */
}
}
}
else
{
/* STALL */
}
}
/*******************************************************************************************************************
* Function Name : puvc_app_data_buffer_clear
* Description : Clear the application's video data buffer
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void puvc_app_data_buffer_clear (void)
{
memset(g_snd_buf, 0, sizeof(g_snd_buf));
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_header_make
* Description : Create header information for video data
* Arguments : usb_puvc_video_payload_header_t * p_header
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_header_make (usb_puvc_video_payload_header_t * p_header)
{
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DAMMY)
p_header->header_length = 0x0C; /* HLE */
p_header->bit_field_header = 0x00; /* BFH : Not support SCR and PTS */
memset(p_header->presentation_time, 0, sizeof(p_header->presentation_time)); /* PTS */
memset(p_header->source_clock_reference_time, 0, sizeof(p_header->source_clock_reference_time)); /* SCR (D31..D0) */
memset(p_header->source_clock_reference_sof_taken_counter, 0,
sizeof(p_header->source_clock_reference_sof_taken_counter)); /* SCR (D42..D32) */
#else
/* --------------
* Not supported
* -------------*/
#endif
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_data_make
* Description : Create video data for one isochronous transfer
* Arguments : uint8_t * p_video_data
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_data_make (uint8_t * p_video_data)
{
FSP_PARAMETER_NOT_USED(p_video_data);
/* --------------
* Not supported
* -------------*/
}
/*******************************************************************************************************************
* Function Name : puvc_app_video_data_init
* Description : Initialize the video data
* Arguments : uint8_t * p_video_data
* Return value : none
*******************************************************************************************************************/
static void puvc_app_video_data_init (uint8_t * p_video_data)
{
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DAMMY)
uint32_t i = 0;
uint32_t j = 0;
uint8_t * p_video_work = p_video_data;
p_video_work = p_video_work + sizeof(usb_puvc_video_payload_header_t);
for ( ; i < (APP_VIDEO_DATA_BUFFER_SIZE - sizeof(usb_puvc_video_payload_header_t)); i++)
{
if (i % (VALUE_FFH + 1))
{
(p_video_work)[i] = (uint8_t) i;
}
else
{
(p_video_work)[i] = (uint8_t) j;
j++;
}
}
#else
/* --------------
* Not supported
* -------------*/
#endif
}
#if (APP_VIDEO_DATA == APP_VIDEO_DATA_DEVICE_TIME)
/*******************************************************************************************************************
* Function Name : puvc_app_device_clock_init
* Description : Initializes the GPT used for calculating a device clock information in the UVC Header.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
void puvc_app_device_clock_init (void)
{
fsp_err_t err = FSP_SUCCESS;
R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
R_GPT_Start(&g_timer0_ctrl);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
} /* End of function puvc_app_device_clock_init */
/*******************************************************************************************************************
* Function Name : puvc_app_device_clock_get
* Description : Get the device's clock count.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
uint32_t puvc_app_device_clock_get (void)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t clock_count;
err = R_GPT_StatusGet(&g_timer0_ctrl, &status);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
return status.counter;
} /* End of function puvc_app_device_clock_get */
#endif
#if (BSP_CFG_RTOS == 2)
/*******************************************************************************************************************
* Function Name : usb_apl_callback
* Description : This function is callback for USB
* Arguments : usb_event_info_t *p_event_info
* : usb_hdl_t handler
* : usb_onoff_t on_off
* Return value : Any Other Error code apart from FSP_SUCCESS on Unsuccessful operation
*******************************************************************************************************************/
void usb_apl_callback (usb_event_info_t * p_event_info, usb_hdl_t handler, usb_onoff_t state)
{
/* Send event received to queue */
if (pdTRUE != (xQueueSend(g_queue, (const void *) &p_event_info, (TickType_t) (RESET_VALUE))))
{
g_err_flag = true;
}
}
#endif
/*******************************************************************************************************************
* Function Name : handle_error
* Description : Print and traps error
* Arguments : fsp_err_t err
* : char * err_str
* Return value : none
*******************************************************************************************************************/
static void handle_error (fsp_err_t err, char * err_str)
{
if (FSP_SUCCESS != err)
{
if (FSP_SUCCESS != R_USB_Close(&g_basic0_ctrl))
{
/* R_USB_Close API Failed */
APP_ERR_TRAP
}
APP_ERR_TRAP
}
}

Descriptor

A template for PUVC descriptors can be found in ra/fsp/src/r_usb_puvc/r_usb_puvc_descriptor.c.template. Also, please be sure to use your vendor ID.