RA Flexible Software Package Documentation  Release v6.4.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:

Supported Devices

Device GroupDevices
RA2RA2A1, RA2L2
RA4RA4E1, RA4E2, RA4L1, RA4M1, RA4M2, RA4M3, RA4W1
RA6RA6E1, RA6E2, RA6M1, RA6M2, RA6M3, RA6M4, RA6M5, RA6T3
RA8RA8D1, RA8D2, RA8E1, RA8E2, RA8M1, RA8M2, RA8P1, RA8T1, RA8T2

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.