RA Flexible Software Package Documentation  Release v6.1.0

 
USB PAUD (r_usb_paud)

This module provides a USB Peripheral Audio Device Class Driver (PAUD). It implements the USB PAUD 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_paud module combines with the r_usb_basic module to provide a USB Peripheral Audio Device Class (PAUD) driver.

Features

The r_usb_paud 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 Code Description
GET MIN 0x82 Minimum setting attribute
GET_MAX 0x83 Maximum setting attribute
GET_RES 0x84 Resolution attribute
SET_CUR 0x01 Current setting attribute
GET_CUR 0x81 Current setting attribute
Request Code Description
CUR 0x01 Current setting attribute
RANGE 0x02 Range attribute

Note:

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

Limitations

Examples

USB PAUD Example

  1. Example code for Audio 1.0
#define A10_FU_ID_0 (5)
#define A10_FU_ID_1 (8)
#define A10_EP_ADDR_OUT (0x02)
#define A10_EP_ADDR_IN (0x81)
#define A10_MUTE_0 (0)
#define A10_MUTE_1 (0x10)
#define A10_VOL_0 (0)
#define A10_VOL_MIN_0 (0)
#define A10_VOL_MAX_0 (0x80)
#define A10_VOL_RES_0 (0x40)
#define A10_VOL_1 (0)
#define A10_VOL_MIN_1 (0)
#define A10_VOL_MAX_1 (0xF0)
#define A10_VOL_RES_1 (0x80)
#define ISO_OUT_IF_NO (0x0001)
#define ISO_IN_IF_NO (0x0002)
#define ISO_IF_ALT_1 (0x0001)
#define ISO_IF_ALT_0 (0x0000)
#define ISO_OUT_MAX_PACKET_SIZE (192)
#define ISO_IN_MAX_PACKET_SIZE (200)
#define APP_BUFFER_SIZE (1024 * 200)
#define BMREQUESTTYPEDIR (0x0080U)
#define VALUE_FF00H (0xFF00)
/******************************************************************************
* Exported global functions (to be accessed by other files)
******************************************************************************/
void usb_paud_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_paud_audio_control_group_t g_audio_control_group;
static usb_paud_audio_control_t g_audio_control[2];
static uint8_t g_paud10_snd_buf[APP_BUFFER_SIZE] = {0};
static uint8_t g_paud10_rcv_buf[ISO_OUT_MAX_PACKET_SIZE] = {0};
static uint32_t g_rcv_index = 0;
static uint32_t g_snd_index = 0;
static volatile bool g_err_flag = false;
static bool b_usb_connected = false;
static fsp_err_t process_usb_events(void);
static void process_usb_audio_class_request(void);
static void process_usb_audio_class_request_out(void);
static void process_usb_audio_class_request_in(void);
static void reset_apl_buffer_info(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_paud_example
* Description : Peripheral Audio application main process
* Arguments : none
* Return value : none
*******************************************************************************************************************/
void usb_paud_example (void)
{
fsp_pack_version_t version = {RESET_VALUE};
fsp_err_t err = FSP_SUCCESS;
#if (BSP_CFG_RTOS == 2)
BaseType_t err_queue = pdFALSE;
#endif
/* Version get API for FLEX pack information */
R_FSP_VersionGet(&version);
/* Audio Class parameter settings */
g_audio_control[0].fu_id = A10_FU_ID_0;
g_audio_control[0].mute = A10_MUTE_0;
g_audio_control[0].volume = A10_VOL_0;
g_audio_control[0].volume_min = A10_VOL_MIN_0;
g_audio_control[0].volume_max = A10_VOL_MAX_0;
g_audio_control[0].volume_res = A10_VOL_RES_0;
g_audio_control[0].ep_addr = A10_EP_ADDR_OUT;
g_audio_control[1].fu_id = A10_FU_ID_1;
g_audio_control[1].mute = A10_MUTE_1;
g_audio_control[1].volume = A10_VOL_1;
g_audio_control[1].volume_min = A10_VOL_MIN_1;
g_audio_control[1].volume_max = A10_VOL_MAX_1;
g_audio_control[1].volume_res = A10_VOL_RES_1;
g_audio_control[1].ep_addr = A10_EP_ADDR_IN;
g_audio_control_group.controls_nb = 2;
g_audio_control_group.p_controls = &g_audio_control[0];
/* Open USB instance */
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* 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 event received */
switch (p_usb_event->event)
{
{
b_usb_connected = true;
break;
}
{
if ((FSP_SUCCESS == p_usb_event->status) || (FSP_ERR_USB_SIZE_SHORT == p_usb_event->status))
{
if ((g_rcv_index + p_usb_event->data_size) < APP_BUFFER_SIZE)
{
memcpy(&g_paud10_snd_buf[g_rcv_index], g_paud10_rcv_buf, p_usb_event->data_size);
}
g_rcv_index += p_usb_event->data_size;
if ((g_rcv_index + ISO_OUT_MAX_PACKET_SIZE) < APP_BUFFER_SIZE)
{
if (b_usb_connected)
{
err = R_USB_Read(&g_basic0_ctrl, g_paud10_rcv_buf, ISO_OUT_MAX_PACKET_SIZE, USB_CLASS_PAUD);
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
break;
}
{
if (FSP_SUCCESS == p_usb_event->status)
{
g_snd_index += ISO_IN_MAX_PACKET_SIZE;
if (g_snd_index >= APP_BUFFER_SIZE)
{
g_snd_index = 0;
}
else
{
if (b_usb_connected)
{
err = R_USB_Write(&g_basic0_ctrl,
&g_paud10_snd_buf[g_snd_index],
ISO_IN_MAX_PACKET_SIZE,
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
break;
}
case USB_STATUS_REQUEST: /* Receive Class Request */
{
process_usb_audio_class_request();
break;
}
{
if (!(USB_HOST_TO_DEV & p_usb_event->setup.request_type) &&
!(USB_STANDARD & p_usb_event->setup.request_type))
{
if (USB_SET_INTERFACE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Streaming (OUT direction) IF ? */
if (ISO_OUT_IF_NO == p_usb_event->setup.request_index)
{
if (ISO_IF_ALT_1 == p_usb_event->setup.request_value)
{
if (b_usb_connected)
{
err = R_USB_Read(&g_basic0_ctrl,
g_paud10_rcv_buf,
ISO_OUT_MAX_PACKET_SIZE,
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
if (ISO_IF_ALT_0 == p_usb_event->setup.request_value)
{
/* Do nothing */
}
}
/* Streaming (IN direction) IF ? */
if (ISO_IN_IF_NO == p_usb_event->setup.request_index)
{
if (ISO_IF_ALT_1 == p_usb_event->setup.request_value)
{
if (b_usb_connected)
{
err = R_USB_Write(&g_basic0_ctrl,
g_paud10_snd_buf,
ISO_IN_MAX_PACKET_SIZE,
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
if (ISO_IF_ALT_0 == p_usb_event->setup.request_value)
{
/* Do nothing */
}
}
}
}
break;
}
{
b_usb_connected = false;
/*Clear the Streamg Data Buffer information */
reset_apl_buffer_info();
break;
}
{
b_usb_connected = true;
break;
}
default:
{
break;
}
}
return err;
}
/*******************************************************************************************************************
* Function Name : process_usb_audio_class_request
* Description : Function processes USB Audio Class Request events
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void process_usb_audio_class_request (void)
{
if (USB_HOST_TO_DEV == (BMREQUESTTYPEDIR & p_usb_event->setup.request_type))
{
/* Data Stage is out-direction. */
process_usb_audio_class_request_out();
}
else if (USB_DEV_TO_HOST & p_usb_event->setup.request_type)
{
/* Data Stage is in-direction. */
process_usb_audio_class_request_in();
}
else
{
/* STALL */
}
}
/*******************************************************************************************************************
* Function Name : process_usb_audio_class_request_out
* Description : Function processes USB Audio Class Request events
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void process_usb_audio_class_request_out (void)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t i;
uint32_t unit_id;
if (USB_ENDPOINT & p_usb_event->setup.request_type)
{
if (USB_PAUD_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if (USB_PAUD_CLOCK_FREQUENCY_CONTROL == p_usb_event->setup.request_value)
{
/* SET_CUR (Sampling Frequency) */
if (A10_EP_ADDR_OUT == p_usb_event->setup.request_index)
{
err = R_USB_PeriControlDataGet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else if (A10_EP_ADDR_IN == p_usb_event->setup.request_index)
{
err = R_USB_PeriControlDataGet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
else if (USB_PAUD_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio_control_group.controls_nb; i++)
{
if (unit_id == g_audio_control_group.p_controls[i].fu_id)
{
if (USB_PAUD_MUTE_CONTROL == p_usb_event->setup.request_value)
{
err = R_USB_PeriControlDataGet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
i].mute,
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
err = R_USB_PeriControlDataGet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
i].volume,
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
}
else
{
/* STALL */
}
}
/*******************************************************************************************************************
* Function Name : process_usb_audio_class_request_in
* Description : Function processes USB Audio Class Request events
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void process_usb_audio_class_request_in (void)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t i;
uint32_t unit_id;
uint32_t size;
if (USB_ENDPOINT & p_usb_event->setup.request_type)
{
if (USB_PAUD_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if (USB_PAUD_CLOCK_FREQUENCY_CONTROL == p_usb_event->setup.request_value)
{
/* GET_CUR (Sampling Frequency) */
if (A10_EP_ADDR_OUT == p_usb_event->setup.request_index)
{
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else if (A10_EP_ADDR_IN == p_usb_event->setup.request_index)
{
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
p_usb_event->setup.request_length);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
/* GET_CUR (MIN/MAX/RES)*/
else if (USB_PAUD_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio_control_group.controls_nb; i++)
{
if (unit_id == g_audio_control_group.p_controls[i].fu_id)
{
if (USB_PAUD_MUTE_CONTROL == p_usb_event->setup.request_value)
{
if (p_usb_event->setup.request_length <
sizeof(g_audio_control_group.p_controls[i].
mute))
{
size = p_usb_event->setup.request_length;
}
else
{
size =
sizeof(g_audio_control_group.p_controls[i].
mute);
}
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
i].mute,
size);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
if (p_usb_event->setup.request_length <
sizeof(g_audio_control_group.p_controls[i].
volume))
{
size = p_usb_event->setup.request_length;
}
else
{
size =
sizeof(g_audio_control_group.p_controls[i].
volume);
}
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
i].volume,
size);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
}
/* GET_MIN */
else if (USB_PAUD_GET_MIN == (p_usb_event->setup.request_type & USB_BREQUEST))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio_control_group.controls_nb; i++)
{
if (unit_id == g_audio_control_group.p_controls[i].fu_id)
{
if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
if (p_usb_event->setup.request_length <
sizeof(g_audio_control_group.p_controls[i].
volume_min))
{
size = p_usb_event->setup.request_length;
}
else
{
size =
sizeof(g_audio_control_group.p_controls[i].
volume_min);
}
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
size);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
}
/* GET_MAX */
else if (USB_PAUD_GET_MAX == (p_usb_event->setup.request_type & USB_BREQUEST))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio_control_group.controls_nb; i++)
{
if (unit_id == g_audio_control_group.p_controls[i].fu_id)
{
if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
if (p_usb_event->setup.request_length <
sizeof(g_audio_control_group.p_controls[i].
volume_max))
{
size = p_usb_event->setup.request_length;
}
else
{
size =
sizeof(g_audio_control_group.p_controls[i].
volume_max);
}
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
size);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
}
/* GET_RES */
else if (USB_PAUD_GET_RES == (p_usb_event->setup.request_type & USB_BREQUEST))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio_control_group.controls_nb; i++)
{
if (unit_id == g_audio_control_group.p_controls[i].fu_id)
{
if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
if (p_usb_event->setup.request_length <
sizeof(g_audio_control_group.p_controls[i].
volume_res))
{
size = p_usb_event->setup.request_length;
}
else
{
size =
sizeof(g_audio_control_group.p_controls[i].
volume_res);
}
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio_control_group.p_controls[
size);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
}
else
{
/* STALL */
}
}
/***********************************************************************************************************************
* @brief Clear the Streamg Data Buffer information.
* @param[in] None
* @retval None
**********************************************************************************************************************/
static void reset_apl_buffer_info (void)
{
memset(g_paud10_snd_buf, 0, sizeof(g_paud10_snd_buf));
g_rcv_index = 0;
g_snd_index = 0;
}
#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
}
}
  1. Example code for Audio 2.0
#define USB_PAUD_CLOCK_SOURCE_UNIT (0x1000U) /* Clock Source Unit ID */
#define A20_CS_ID (0x10)
#define A20_SAMPLING_FREQUENCY (48000)
#define A20_FU_ID_0 (5)
#define A20_FU_ID_1 (8)
#define A20_MUTE (0)
#define A20_VOL_MIN_0 (0)
#define A20_VOL_MAX_0 (100)
#define A20_SET_VOL_0 (50)
#define A20_VOL_MIN_1 (0)
#define A20_VOL_MAX_1 (200)
#define A20_SET_VOL_1 (100)
#define ISO_OUT_IF_NO (0x0001)
#define ISO_IN_IF_NO (0x0002)
#define ISO_IF_ALT_1 (0x0001)
#define ISO_IF_ALT_0 (0x0000)
#define ISO_OUT_MAX_PACKET_SIZE (192)
#define ISO_IN_MAX_PACKET_SIZE (200)
#define APP_BUFFER_SIZE (1024 * 200)
#define RANGE_DATA_TOP2BYTES (0x0001)
#define BMREQUESTTYPEDIR (0x0080U)
#define VAULE_FFH (0xFF)
#define VALUE_FF00H (0xFF00)
/******************************************************************************
* Exported global functions (to be accessed by other files)
******************************************************************************/
void usb_paud_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_paud_audio_control_group_t g_audio20_control_group;
static usb_paud_audio_control_t g_audio20_control[2];
static uint8_t g_paud20_snd_buf[APP_BUFFER_SIZE] = {0};
static uint8_t g_paud20_rcv_buf[ISO_OUT_MAX_PACKET_SIZE] = {0};
static uint32_t g_rcv_index = 0;
static uint32_t g_snd_index = 0;
static volatile bool g_err_flag = false;
static bool b_usb_connected = false;
static fsp_err_t process_usb_events(void);
static void process_usb_audio_class_request(void);
static void reset_apl_buffer_info(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_paud_example
* Description : Peripheral Audio application main process
* Arguments : none
* Return value : none
*******************************************************************************************************************/
void usb_paud_example (void)
{
fsp_pack_version_t version = {RESET_VALUE};
fsp_err_t err = FSP_SUCCESS;
#if (BSP_CFG_RTOS == 2)
BaseType_t err_queue = pdFALSE;
#endif
/* Version get API for FLEX pack information */
R_FSP_VersionGet(&version);
/* Audio Class parameter settings */
g_audio20_control[0].cs_id = A20_CS_ID;
g_audio20_control[0].sam_freq = A20_SAMPLING_FREQUENCY;
g_audio20_control[0].fu_id = A20_FU_ID_0;
g_audio20_control[0].mute = A20_MUTE;
g_audio20_control[0].volume_min = A20_VOL_MIN_0;
g_audio20_control[0].volume_max = A20_VOL_MAX_0;
g_audio20_control[0].volume = A20_SET_VOL_0;
g_audio20_control[1].cs_id = A20_CS_ID;
g_audio20_control[1].sam_freq = A20_SAMPLING_FREQUENCY;
g_audio20_control[1].fu_id = A20_FU_ID_1;
g_audio20_control[1].mute = A20_MUTE;
g_audio20_control[1].volume_min = A20_VOL_MIN_1;
g_audio20_control[1].volume_max = A20_VOL_MAX_1;
g_audio20_control[1].volume = A20_SET_VOL_1;
g_audio20_control_group.controls_nb = 2;
g_audio20_control_group.p_controls = &g_audio20_control[0];
/* Open USB instance */
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* 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 event received */
switch (p_usb_event->event)
{
{
b_usb_connected = true;
break;
}
{
if ((FSP_SUCCESS == p_usb_event->status) || (FSP_ERR_USB_SIZE_SHORT == p_usb_event->status))
{
if ((g_rcv_index + p_usb_event->data_size) < APP_BUFFER_SIZE)
{
memcpy(&g_paud20_snd_buf[g_rcv_index], g_paud20_rcv_buf, p_usb_event->data_size);
}
g_rcv_index += p_usb_event->data_size;
if ((g_rcv_index + ISO_OUT_MAX_PACKET_SIZE) < APP_BUFFER_SIZE)
{
if (b_usb_connected)
{
err = R_USB_Read(&g_basic0_ctrl, g_paud20_rcv_buf, ISO_OUT_MAX_PACKET_SIZE, USB_CLASS_PAUD);
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
break;
}
{
if (FSP_SUCCESS == p_usb_event->status)
{
g_snd_index += ISO_IN_MAX_PACKET_SIZE;
if (g_snd_index >= APP_BUFFER_SIZE)
{
g_snd_index = 0;
}
else
{
if (b_usb_connected)
{
err = R_USB_Write(&g_basic0_ctrl,
&g_paud20_snd_buf[g_snd_index],
ISO_IN_MAX_PACKET_SIZE,
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
break;
}
case USB_STATUS_REQUEST: /* Receive Class Request */
{
process_usb_audio_class_request();
break;
}
{
if (!(USB_HOST_TO_DEV & p_usb_event->setup.request_type) &&
!(USB_STANDARD & p_usb_event->setup.request_type))
{
if (USB_SET_INTERFACE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Streaming (OUT direction) IF ? */
if (ISO_OUT_IF_NO == p_usb_event->setup.request_index)
{
if (ISO_IF_ALT_1 == p_usb_event->setup.request_value)
{
if (b_usb_connected)
{
err = R_USB_Read(&g_basic0_ctrl,
g_paud20_rcv_buf,
ISO_OUT_MAX_PACKET_SIZE,
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
if (ISO_IF_ALT_0 == p_usb_event->setup.request_value)
{
/* Do nothing */
}
}
/* Streaming (IN direction) IF ? */
if (ISO_IN_IF_NO == p_usb_event->setup.request_index)
{
if (ISO_IF_ALT_1 == p_usb_event->setup.request_value)
{
if (b_usb_connected)
{
err = R_USB_Write(&g_basic0_ctrl,
g_paud20_snd_buf,
ISO_IN_MAX_PACKET_SIZE,
}
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
if (ISO_IF_ALT_0 == p_usb_event->setup.request_value)
{
/* Do nothing */
}
}
}
}
break;
}
{
b_usb_connected = false;
/*Clear the Streamg Data Buffer information */
reset_apl_buffer_info();
break;
}
{
b_usb_connected = true;
break;
}
default:
{
break;
}
}
return err;
}
/*******************************************************************************************************************
* Function Name : process_usb_audio_class_request
* Description : Function processes USB Audio Class Request events
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void process_usb_audio_class_request (void)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t i;
uint32_t unit_id;
uint32_t freq;
uint8_t * p_range;
uint8_t volume_range[8];
uint8_t smpl_freq_range[14];
if (USB_HOST_TO_DEV == (BMREQUESTTYPEDIR & p_usb_event->setup.request_type))
{
if (USB_PAUD_CUR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if ((USB_PAUD_CLOCK_FREQUENCY_CONTROL == p_usb_event->setup.request_value) &&
(USB_PAUD_CLOCK_SOURCE_UNIT == p_usb_event->setup.request_index))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
err = R_USB_PeriControlDataGet(&g_basic0_ctrl, (uint8_t *) &freq, p_usb_event->setup.request_length);
if (FSP_SUCCESS == err)
{
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].cs_id)
{
if (0 ==
g_audio20_control_group.p_controls[i].
sam_freq)
{
g_audio20_control_group.p_controls[i].
sam_freq = freq;
}
}
}
}
/* Handle error */
else
{
APP_ERR_TRAP
}
}
else if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].fu_id)
{
err = R_USB_PeriControlDataGet(&g_basic0_ctrl,
(uint8_t *) &g_audio20_control_group.p_controls[
i].volume,
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
else if (USB_DEV_TO_HOST & p_usb_event->setup.request_type)
{
if (USB_PAUD_CUR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if ((USB_PAUD_CLOCK_FREQUENCY_CONTROL == p_usb_event->setup.request_value) &&
(USB_PAUD_CLOCK_SOURCE_UNIT == p_usb_event->setup.request_index))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].cs_id)
{
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio20_control_group.p_controls[
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
else if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].fu_id)
{
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio20_control_group.p_controls[
i].volume,
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
else if (USB_PAUD_MUTE_CONTROL == p_usb_event->setup.request_value)
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].fu_id)
{
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
(uint8_t *) &g_audio20_control_group.p_controls[
i].mute,
p_usb_event->setup.request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
else
{
/* STALL */
}
}
else if (USB_PAUD_RANGE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if ((USB_PAUD_CLOCK_FREQUENCY_CONTROL == p_usb_event->setup.request_value) &&
(USB_PAUD_CLOCK_SOURCE_UNIT == p_usb_event->setup.request_index))
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].cs_id)
{
p_range = smpl_freq_range;
*p_range++ = (uint8_t) (RANGE_DATA_TOP2BYTES & VAULE_FFH);
*p_range++ = (uint8_t) ((RANGE_DATA_TOP2BYTES >> 8) & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq) & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq >> 8) & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq >> 16) & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq >> 24) & VAULE_FFH);
*p_range++ =
(uint8_t) (g_audio20_control_group.p_controls[i].
sam_freq & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq >>
8) & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq >> 16) & VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
sam_freq >> 24) & VAULE_FFH);
*p_range++ = (uint8_t) 0x00;
*p_range++ = (uint8_t) 0x00;
*p_range++ = (uint8_t) 0x00;
*p_range++ = (uint8_t) 0x00;
if (sizeof(smpl_freq_range) < p_usb_event->setup.request_length)
{
err =
R_USB_PeriControlDataSet(&g_basic0_ctrl, smpl_freq_range, sizeof(smpl_freq_range));
}
else
{
err = R_USB_PeriControlDataSet(&g_basic0_ctrl,
smpl_freq_range,
p_usb_event->setup.request_length);
}
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
else if (USB_PAUD_VOLUME_CONTROL == p_usb_event->setup.request_value)
{
unit_id = (uint32_t) (p_usb_event->setup.request_index & VALUE_FF00H);
unit_id = unit_id >> 8;
for (i = 0; i < g_audio20_control_group.controls_nb; i++)
{
if (unit_id ==
g_audio20_control_group.p_controls[i].fu_id)
{
p_range = volume_range;
*p_range++ = (uint8_t) (RANGE_DATA_TOP2BYTES & VAULE_FFH);
*p_range++ = (uint8_t) ((RANGE_DATA_TOP2BYTES >> 8) & VAULE_FFH);
*p_range++ =
(uint8_t) (g_audio20_control_group.p_controls[i].
volume_min &
VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
volume_min >>
8) & VAULE_FFH);
*p_range++ =
(uint8_t) (g_audio20_control_group.p_controls[i].
volume_max &
VAULE_FFH);
*p_range++ =
(uint8_t) ((g_audio20_control_group.p_controls[i].
volume_max >>
8) & VAULE_FFH);
if (1 <
g_audio20_control_group.p_controls[i].
volume_res)
{
*p_range++ =
(uint8_t) (g_audio20_control_group.p_controls[i].
volume_res &
VAULE_FFH);
*p_range =
(uint8_t) ((g_audio20_control_group.p_controls[i].
volume_res >> 8) & VAULE_FFH);
}
else
{
*p_range++ = (uint8_t) (RANGE_DATA_TOP2BYTES & VAULE_FFH);
*p_range = (uint8_t) ((RANGE_DATA_TOP2BYTES >> 8) & VAULE_FFH);
}
err =
R_USB_PeriControlDataSet(&g_basic0_ctrl, (uint8_t *) volume_range, sizeof(volume_range));
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
break;
}
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
else
{
/* STALL */
}
}
/***********************************************************************************************************************
* @brief Clear the Streamg Data Buffer information.
* @param[in] None
* @retval None
**********************************************************************************************************************/
static void reset_apl_buffer_info (void)
{
memset(g_paud20_snd_buf, 0, sizeof(g_paud20_snd_buf));
g_rcv_index = 0;
g_snd_index = 0;
}
#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 PAUD descriptors can be found in ra/fsp/src/r_usb_paud/r_usb_paud_descriptor.c.template. Also, please be sure to use your vendor ID.