RA Flexible Software Package Documentation  Release v6.4.0

 
USB HAUD (r_usb_haud)

Functions

fsp_err_t R_USB_HAUD_DeviceInfoGet (usb_ctrl_t *const p_api_ctrl, usb_haud_device_info_t *p_info, uint8_t device_address)
 Check audio version of connected device. More...
 
fsp_err_t R_USB_HAUD_ClockSourceGet (usb_ctrl_t *const p_api_ctrl, usb_haud_sampling_t *p_info, uint8_t direction, uint8_t device_address)
 Get the Clock Souuce (Audio 2.0 support only) More...
 
fsp_err_t R_USB_HAUD_AlternateNumberGet (usb_ctrl_t *const p_api_ctrl, usb_haud_sampling_t *p_info, uint8_t direction, uint8_t device_address)
 Get the alternate number for SET_INTERFACE. (Audio 1.0 support only) More...
 
fsp_err_t R_USB_HAUD_PipeSet (usb_ctrl_t *const p_api_ctrl, uint32_t interface_number, uint32_t alternate_number, uint8_t device_address)
 Find the interface descriptor for streaming data transfer and configure the pipe. More...
 

Detailed Description

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

Features

The r_usb_haud module has the following key features:

Supported Devices

Device GroupDevices
RA4RA4E1, RA4L1, RA4M1, RA4M2, RA4M3, RA4W1
RA6RA6E1, RA6M1, RA6M2, RA6M3, RA6M4, RA6M5
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
SET_CUR 0x01 Current setting attribute
GET_CUR 0x81 Current setting attribute

Note:

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

Limitations

Examples

USB HAUD Example

  1. Example code for Audio 1.0
#define CONTROL_BUFFER_SIZE (256)
#define AUDIO_BUFFER_SIZE (3 * 1024) + 1024
#define REQUEST_SIZE (3 * 1024)
#define FIRST_PACKET_TEST_SIZE (200) /* for Test Device (USBX-PAUD Sample Project : EK-RA6M5 Board) */
/* The first 200 bytes of the loopback data are all 0x00. */
#define READ_REQUEST_SIZE (REQUEST_SIZE + FIRST_PACKET_TEST_SIZE)
#define BMREQUESTTYPEDIR (0x0080U)
#define BMREQUESTTYPETYPE (0x0060U)
#define ALT_NUM_0 (0)
#define SAMPLING_FREQUENCY_CHANNNELS (2)
#define SAMPLING_FREQUENCY_FREQUENCY (48000)
#define SAMPLING_FREQUENCY_RESOLUTION (16)
#define SAMPLING_FREQUENCY_DATA_SIZE (3)
/******************************************************************************
* Exported global functions (to be accessed by other files)
******************************************************************************/
void usb_haud_example(void);
#if (BSP_CFG_RTOS == 2)
void usb_apl_callback(usb_event_info_t * p_event_info, usb_hdl_t cur_task, usb_onoff_t usb_state);
#endif
/******************************************************************************
* Private global variables and functions
******************************************************************************/
#if (BSP_CFG_RTOS == 2)
static volatile usb_event_info_t * p_usb_event = NULL;
extern QueueHandle_t g_usb_queue;
#else
static usb_event_info_t event_info = {0};
static volatile usb_event_info_t * p_usb_event = &event_info;
#endif
/* Private variables */
static uint8_t g_buf[CONTROL_BUFFER_SIZE] BSP_ALIGN_VARIABLE(4) = {RESET_VALUE}; // Class request data buffer
static uint8_t g_send_buffer[AUDIO_BUFFER_SIZE] BSP_ALIGN_VARIABLE(4);
static uint8_t g_recv_buffer[AUDIO_BUFFER_SIZE] BSP_ALIGN_VARIABLE(4);
static uint8_t g_usb_dummy = RESET_VALUE; // dummy variable to send
static volatile bool g_err_flag = false; // flag bit
static uint8_t g_device_address = 0;
static uint32_t g_completed_read_transfer_length_total = 0;
static usb_haud_sampling_t g_sampling_tx;
static usb_haud_sampling_t g_sampling_rx;
/* Private functions */
static void haud_app_data_buffer_init(void);
static void haud_app_standard_request_complete(void);
static void haud_app_audio_class_request_complete(void);
static fsp_err_t haud_app_interface_set(uint32_t value, uint32_t index);
static fsp_err_t haud_app_sampling_frequency_set(uint8_t ep_address, uint32_t frequency);
static fsp_err_t haud_app_sampling_frequency_get(uint8_t ep_address);
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;
/*******************************************************************************************************************
* Function Name : usb_haud_example
* Description : Host Audio application main process
* Arguments : none
* Return value : none
*******************************************************************************************************************/
void usb_haud_example (void)
{
fsp_err_t err = FSP_SUCCESS;
#if (BSP_CFG_RTOS == 2)
BaseType_t err_queue = USB_FALSE;
#endif
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
/* Error Handle */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
haud_app_data_buffer_init();
while (true)
{
/* Handle error if queue send fails*/
if (true == g_err_flag)
{
handle_error(FSP_ERR_ABORTED, "Error in sending usb event through queue");
}
#if (BSP_CFG_RTOS == 2)
/* Receive message from queue and analyzing the received message*/
err_queue = xQueueReceive(g_usb_queue, &p_usb_event, (portMAX_DELAY));
/* Handle error */
if (USB_TRUE != err_queue)
{
handle_error(FSP_ERR_ABORTED, "Error in receiving USB event message through queue");
}
#else
/* Obtain USB related events */
err = R_USB_EventGet(&event_info, &event_info.event);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
#endif
switch (p_usb_event->event)
{
{
g_device_address = p_usb_event->device_address;
/* Get device information (Audio version) */
err = R_USB_HAUD_DeviceInfoGet(&g_basic0_ctrl, &device_info, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
if (USB_HAUD_PROTOCOL_IP_VERSION_01_00 == device_info.protocol)
{
g_sampling_tx.channels = SAMPLING_FREQUENCY_CHANNNELS;
g_sampling_tx.frequency = SAMPLING_FREQUENCY_FREQUENCY;
g_sampling_tx.resolution = SAMPLING_FREQUENCY_RESOLUTION;
/* Get Alternate number for Isochronous-OUT IF */
err =
R_USB_HAUD_AlternateNumberGet(&g_basic0_ctrl, &g_sampling_tx, USB_EP_DIR_OUT, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* SET_INTERFACE (Use the acquired ALT number) */
err = haud_app_interface_set(g_sampling_tx.alternate_number, g_sampling_tx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* Do nothing. (Audio 2.0 and later are not supported.) */
}
break;
}
{
if ((FSP_SUCCESS == p_usb_event->status) || (FSP_ERR_USB_SIZE_SHORT == p_usb_event->status))
{
g_completed_read_transfer_length_total += p_usb_event->data_size;
if (READ_REQUEST_SIZE > g_completed_read_transfer_length_total)
{
err = R_USB_Read(&g_basic0_ctrl,
g_recv_buffer + g_completed_read_transfer_length_total,
g_sampling_rx.max_packet_size,
g_device_address);
/* Handle Error */
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Read API FAILED**");
}
}
else
{
if (0 == memcmp(g_send_buffer, g_recv_buffer + FIRST_PACKET_TEST_SIZE, REQUEST_SIZE))
{
/* SET_INTERFACE (ALT number : 0) */
err = haud_app_interface_set(ALT_NUM_0, g_sampling_rx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
APP_ERR_TRAP
}
}
}
else
{
APP_ERR_TRAP
}
break;
}
{
if (FSP_SUCCESS == p_usb_event->status)
{
/* SET_INTERFACE (ALT number : 0) */
err = haud_app_interface_set(ALT_NUM_0, g_sampling_tx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
APP_ERR_TRAP
}
break;
}
{
switch (BMREQUESTTYPETYPE & p_usb_event->setup.request_type)
{
{
haud_app_standard_request_complete();
break;
}
case USB_CLASS:
{
haud_app_audio_class_request_complete();
break;
}
}
break;
}
{
memset(&g_sampling_tx, 0, sizeof(g_sampling_tx));
memset(&g_sampling_rx, 0, sizeof(g_sampling_rx));
g_device_address = 0;
g_completed_read_transfer_length_total = 0;
break;
}
default:
{
/* No operation to do */
break;
}
}
}
} /* End of function usb_haud_example */
/*******************************************************************************************************************
* Function Name : haud_app_data_buffer_init
* Description : Initializes test write data.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_data_buffer_init (void)
{
uint32_t i = 0;
uint32_t j = 0;
/* Set data to the send buffer. */
for ( ; i < AUDIO_BUFFER_SIZE; i++)
{
if (i % (VALUE_FFH + 1))
{
(g_send_buffer)[i] = (uint8_t) i;
}
else
{
(g_send_buffer)[i] = (uint8_t) j;
j++;
}
}
} /* End of function haud_app_data_buffer_init */
/*******************************************************************************************************************
* Function Name : haud_app_standard_request_complete
* Description : Standard request (such as SET_INTERFACE) completion event processing.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_standard_request_complete (void)
{
fsp_err_t err = FSP_SUCCESS;
if (USB_SET_INTERFACE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if ((g_sampling_tx.interface_number == p_usb_event->setup.request_index) &&
(g_sampling_tx.alternate_number == p_usb_event->setup.request_value))
{
g_sampling_tx.alternate_setting = USB_TRUE;
err = R_USB_HAUD_PipeSet(&g_basic0_ctrl,
g_sampling_tx.interface_number,
g_sampling_tx.alternate_number,
g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
g_sampling_tx.frequency_setting = USB_TRUE;
/* If there is only one frequency, no need to set it to device. */
if ((g_sampling_tx.p_sampling_descriptor[7] == 1) || /* bSamFreqType : There is one frequency */
((g_sampling_tx.p_sampling_descriptor[7] == 0) && /* bSamFreqType : There is Low(=High) frequency */
(g_sampling_tx.
p_sampling_descriptor[8] == g_sampling_tx.p_sampling_descriptor[11]) && /* tSamFreq (low) */
(g_sampling_tx.
p_sampling_descriptor[9] == g_sampling_tx.p_sampling_descriptor[12]) && /* tSamFreq (middle) */
(g_sampling_tx.
p_sampling_descriptor[10] == g_sampling_tx.p_sampling_descriptor[13]))) /* tSamFreq (high)*/
{
g_sampling_tx.frequency_setting = USB_FALSE; /* No need to set frequency */
}
if (g_sampling_tx.frequency_setting)
{
/* Send SET_CUR requests to set frequency. */
err = haud_app_sampling_frequency_set(g_sampling_tx.endpoint_address, g_sampling_tx.frequency);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
else if ((g_sampling_tx.interface_number == p_usb_event->setup.request_index) &&
(ALT_NUM_0 == p_usb_event->setup.request_value))
{
g_sampling_tx.alternate_setting = USB_FALSE;
g_sampling_rx.channels = SAMPLING_FREQUENCY_CHANNNELS;
g_sampling_rx.frequency = SAMPLING_FREQUENCY_FREQUENCY;
g_sampling_rx.resolution = SAMPLING_FREQUENCY_RESOLUTION;
/* Get Alternate number for Isochronous-IN IF */
err = R_USB_HAUD_AlternateNumberGet(&g_basic0_ctrl, &g_sampling_rx, USB_EP_DIR_IN, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* SET_INTERFACE (Use the acquired ALT number) */
err = haud_app_interface_set(g_sampling_rx.alternate_number, g_sampling_rx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else if ((g_sampling_rx.interface_number == p_usb_event->setup.request_index) &&
(g_sampling_rx.alternate_number == p_usb_event->setup.request_value))
{
g_sampling_rx.alternate_setting = USB_TRUE;
err = R_USB_HAUD_PipeSet(&g_basic0_ctrl,
g_sampling_rx.interface_number,
g_sampling_rx.alternate_number,
g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
g_sampling_rx.frequency_setting = USB_TRUE;
/* If there is only one frequency, no need to set it to device. */
if ((g_sampling_rx.p_sampling_descriptor[7] == 1) || /* bSamFreqType : There is one frequency */
((g_sampling_rx.p_sampling_descriptor[7] == 0) && /* bSamFreqType : There is Low(=High) frequency */
(g_sampling_rx.
p_sampling_descriptor[8] == g_sampling_rx.p_sampling_descriptor[11]) && /* tSamFreq (low) */
(g_sampling_rx.
p_sampling_descriptor[9] == g_sampling_rx.p_sampling_descriptor[12]) && /* tSamFreq (middle) */
(g_sampling_rx.
p_sampling_descriptor[10] == g_sampling_rx.p_sampling_descriptor[13]))) /* tSamFreq (high) */
{
g_sampling_rx.frequency_setting = USB_FALSE; /* No need to set frequency */
}
if (g_sampling_rx.frequency_setting)
{
/* Send SET_CUR requests to set frequency. */
err = haud_app_sampling_frequency_set(g_sampling_rx.endpoint_address, g_sampling_rx.frequency);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
else if ((g_sampling_rx.interface_number == p_usb_event->setup.request_index) &&
(ALT_NUM_0 == p_usb_event->setup.request_value))
{
g_sampling_rx.alternate_setting = USB_FALSE;
}
else
{
APP_ERR_TRAP
}
}
} /* End of function haud_app_standard_request_complete */
/*******************************************************************************************************************
* Function Name : haud_app_audio_class_request_complete
* Description : Audio class request completion event processing.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_audio_class_request_complete (void)
{
uint32_t value;
fsp_err_t err = FSP_SUCCESS;
/* SET_CUR (Isochronous-OUT IF's EP) completed */
if ((USB_HAUD_AUDIO10_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_tx.endpoint_address == p_usb_event->setup.request_index))
{
/* GET_CUR Request (Check whether the sampling frequency specified by SET_CUR has been set on the device.) */
err = haud_app_sampling_frequency_get(g_sampling_tx.endpoint_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
/* SET_CUR (Isochronous-IN IF's EP) completed */
else if ((USB_HAUD_AUDIO10_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_rx.endpoint_address == p_usb_event->setup.request_index))
{
/* GET_CUR Request (Check whether the sampling frequency specified by SET_CUR has been set on the device.) */
err = haud_app_sampling_frequency_get(g_sampling_rx.endpoint_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
/* GET_CUR (Isochronous-OUT IF's EP) completed */
else if ((USB_HAUD_AUDIO10_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_tx.endpoint_address == p_usb_event->setup.request_index))
{
/* The fourth byte has no data so it is cleared. */
g_buf[3] = 0;
value = (ULONG) g_buf[0];
value |= (ULONG) g_buf[1] << 8;
value |= (ULONG) g_buf[2] << 16;
value |= (ULONG) g_buf[3] << 24;
if (value != g_sampling_tx.frequency)
{
/* Sampling frequency requested is not set to device. */
APP_ERR_TRAP
}
/* Data Write (Isochronous-OUT) */
err =
R_USB_Write(&g_basic0_ctrl, (uint8_t *) g_send_buffer, REQUEST_SIZE, g_device_address);
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Write API FAILED**");
}
}
/* GET_CUR (Isochronous-IN IF's EP) completed */
else if ((USB_HAUD_AUDIO10_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_rx.endpoint_address == p_usb_event->setup.request_index))
{
/* The fourth byte has no data so it is cleared. */
g_buf[3] = 0;
value = (ULONG) g_buf[0];
value |= (ULONG) g_buf[1] << 8;
value |= (ULONG) g_buf[2] << 16;
value |= (ULONG) g_buf[3] << 24;
if (value != g_sampling_rx.frequency)
{
/* Sampling frequency requested is not set to device. */
APP_ERR_TRAP
}
/* Data Read (Isochronous-IN) */
err = R_USB_Read(&g_basic0_ctrl, g_recv_buffer, g_sampling_rx.max_packet_size, g_device_address);
/* Handle Error */
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Read API FAILED**");
}
}
else
{
APP_ERR_TRAP
}
} /* End of function haud_app_audio_class_request_complete */
/*******************************************************************************************************************
* Function Name : haud_app_interface_set
* Description : This function does a SET_INTERFACE with the specified Alternate number and interface number.
* Arguments : uint32_t value : Alternate number
* : uint32_t index : Interface number
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_interface_set (uint32_t value, uint32_t index)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
setup.request_value = (uint16_t) value;
setup.request_index = (uint16_t) index;
setup.request_length = 0;
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, &g_usb_dummy, g_device_address);
return err;
} /* End of function haud_app_interface_set */
/*******************************************************************************************************************
* Function Name : haud_app_sampling_frequency_set
* Description : This function sets the sampling frequency on the device using the SET_CUR request.
* Arguments : uint8_t ep_address : End Point Address
* : uint32_t frequency : Sampling Furequency
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_sampling_frequency_set (uint8_t ep_address, uint32_t frequency)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
setup.request_type = USB_HAUD_AUDIO10_SET_CUR | USB_HOST_TO_DEV | USB_CLASS | USB_ENDPOINT;
setup.request_value = USB_HAUD_AUDIO10_EP_SAMPLING_FREQ_CONTROL << 8;
setup.request_index = (uint16_t) ep_address;
setup.request_length = SAMPLING_FREQUENCY_DATA_SIZE;
g_buf[0] = (uint8_t) frequency;
g_buf[1] = (uint8_t) (frequency >> 8);
g_buf[2] = (uint8_t) (frequency >> 16);
g_buf[3] = 0;
/* Request Control transfer */
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, g_buf, g_device_address);
return err;
} /* End of function haud_app_sampling_frequency_set */
/*******************************************************************************************************************
* Function Name : haud_app_sampling_frequency_get
* Description : This function uses a GET_CUR request to get the sampling frequency of the device.
* Arguments : uint8_t ep_address : End Point Address
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_sampling_frequency_get (uint8_t ep_address)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
setup.request_type = USB_HAUD_AUDIO10_GET_CUR | USB_DEV_TO_HOST | USB_CLASS | USB_ENDPOINT;
setup.request_value = USB_HAUD_AUDIO10_EP_SAMPLING_FREQ_CONTROL << 8;
setup.request_index = ep_address;
setup.request_length = SAMPLING_FREQUENCY_DATA_SIZE;
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, g_buf, g_device_address);
return err;
} /* End of function haud_app_sampling_frequency_get */
/*******************************************************************************************************************
* 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)
{
fsp_err_t error = FSP_SUCCESS;
/* close opened USB module */
error = R_USB_Close(&g_basic0_ctrl);
/* Handle error */
if (FSP_SUCCESS != error)
{
APP_ERR_TRAP
}
} /* End of function handle_error() */
#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 usb_state
* Return value : none
*******************************************************************************************************************/
void usb_apl_callback (usb_event_info_t * p_event_info, usb_hdl_t handler, usb_onoff_t usb_state)
{
/* Send event received to queue */
if (USB_TRUE != (xQueueSend(g_usb_queue, (const void *) &p_event_info, (TickType_t) (NO_WAIT_TIME))))
{
g_err_flag = true;
}
} /* End of function usb_rtos_callback */
#endif
  1. Example code for Audio 2.0
#define CONTROL_BUFFER_SIZE (256)
#define AUDIO_BUFFER_SIZE (3 * 1024) + 1024
#define REQUEST_SIZE (3 * 1024)
#define FIRST_PACKET_TEST_SIZE (200) /* for Test Device (USBX-PAUD Sample Project : EK-RA6M5 Board) */
/* The first 200 bytes of the loopback data are all 0x00. */
#define READ_REQUEST_SIZE (REQUEST_SIZE + FIRST_PACKET_TEST_SIZE)
#define BMREQUESTTYPEDIR (0x0080U)
#define BMREQUESTTYPETYPE (0x0060U)
#define ALT_NUM_0 (0)
#define SAMPLING_FREQUENCY_CHANNNELS (2)
#define SAMPLING_FREQUENCY_FREQUENCY (48000)
#define SAMPLING_FREQUENCY_RESOLUTION (16)
#define SAMPLING_FREQUENCY_DATA_SIZE_2 (2)
#define SAMPLING_FREQUENCY_DATA_SIZE_3 (3)
#define SAMPLING_FREQUENCY_DATA_SIZE_14 (14)
#define SAMPLING_FREQUENCY_SUB_RANGE (4 * 3)
/******************************************************************************
* Exported global functions (to be accessed by other files)
******************************************************************************/
void usb_haud_example(void);
#if (BSP_CFG_RTOS == 2)
void usb_apl_callback(usb_event_info_t * p_event_info, usb_hdl_t cur_task, usb_onoff_t usb_state);
#endif
/******************************************************************************
* Private global variables and functions
******************************************************************************/
#if (BSP_CFG_RTOS == 2)
static volatile usb_event_info_t * p_usb_event = NULL;
extern QueueHandle_t g_usb_queue;
#else
static usb_event_info_t event_info = {0};
static volatile usb_event_info_t * p_usb_event = &event_info;
#endif
/* Private variables */
static uint8_t g_buf[CONTROL_BUFFER_SIZE] BSP_ALIGN_VARIABLE(4) = {RESET_VALUE}; // Class request data buffer
static uint8_t g_send_buffer[AUDIO_BUFFER_SIZE] BSP_ALIGN_VARIABLE(4);
static uint8_t g_recv_buffer[AUDIO_BUFFER_SIZE] BSP_ALIGN_VARIABLE(4);
static uint8_t g_usb_dummy = RESET_VALUE; // dummy variable to send
static volatile bool g_err_flag = false; // flag bit
static uint8_t g_device_address = 0;
static uint8_t g_device_protocol = VALUE_FFH;
static uint32_t g_completed_read_transfer_length_total = 0;
static uint32_t g_num_sub_ranges = 0;
static usb_haud_sampling_t g_sampling_tx;
static usb_haud_sampling_t g_sampling_rx;
/* Private functions */
static void haud_app_data_buffer_init(void);
static void haud_app_standard_request_complete_aud10(void);
static void haud_app_standard_request_complete_aud20(void);
static void haud_app_audio_class_request_complete_aud10(void);
static void haud_app_audio_class_request_complete_aud20(void);
static fsp_err_t haud_app_interface_set(uint32_t value, uint32_t index);
static fsp_err_t haud_app_sampling_frequency_set(uint8_t ep_address, uint32_t frequency);
static fsp_err_t haud_app_sampling_frequency_get_aud10(uint8_t ep_address);
static fsp_err_t haud_app_sampling_frequency_get_aud20(uint8_t ep_address, uint16_t length);
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;
/*******************************************************************************************************************
* Function Name : usb_haud_example
* Description : Host Audio application main process
* Arguments : none
* Return value : none
*******************************************************************************************************************/
void usb_haud_example (void)
{
fsp_err_t err = FSP_SUCCESS;
#if (BSP_CFG_RTOS == 2)
BaseType_t err_queue = USB_FALSE;
#endif
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
/* Error Handle */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
haud_app_data_buffer_init();
while (true)
{
/* Handle error if queue send fails*/
if (true == g_err_flag)
{
handle_error(FSP_ERR_ABORTED, "Error in sending usb event through queue");
}
#if (BSP_CFG_RTOS == 2)
/* Receive message from queue and analyzing the received message*/
err_queue = xQueueReceive(g_usb_queue, &p_usb_event, (portMAX_DELAY));
/* Handle error */
if (USB_TRUE != err_queue)
{
handle_error(FSP_ERR_ABORTED, "Error in receiving USB event message through queue");
}
#else
/* Obtain USB related events */
err = R_USB_EventGet(&event_info, &event_info.event);
/* Handle error */
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
#endif
switch (p_usb_event->event)
{
{
g_device_address = p_usb_event->device_address;
/* Get device information (Audio version) */
err = R_USB_HAUD_DeviceInfoGet(&g_basic0_ctrl, &device_info, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
if (USB_HAUD_PROTOCOL_IP_VERSION_01_00 == device_info.protocol)
{
g_device_protocol = USB_HAUD_PROTOCOL_IP_VERSION_01_00;
g_sampling_tx.channels = SAMPLING_FREQUENCY_CHANNNELS;
g_sampling_tx.frequency = SAMPLING_FREQUENCY_FREQUENCY;
g_sampling_tx.resolution = SAMPLING_FREQUENCY_RESOLUTION;
/* Get Alternate number for Isochronous-OUT IF */
err =
R_USB_HAUD_AlternateNumberGet(&g_basic0_ctrl, &g_sampling_tx, USB_EP_DIR_OUT, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* SET_INTERFACE (Use the acquired ALT number) */
err = haud_app_interface_set(g_sampling_tx.alternate_number, g_sampling_tx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else if (USB_HAUD_PROTOCOL_IP_VERSION_02_00 == device_info.protocol)
{
g_device_protocol = USB_HAUD_PROTOCOL_IP_VERSION_02_00;
g_sampling_tx.channels = SAMPLING_FREQUENCY_CHANNNELS;
g_sampling_tx.frequency = SAMPLING_FREQUENCY_FREQUENCY;
g_sampling_tx.resolution = SAMPLING_FREQUENCY_RESOLUTION;
err =
R_USB_HAUD_ClockSourceGet(&g_basic0_ctrl, &g_sampling_tx, USB_EP_DIR_OUT, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
err = haud_app_sampling_frequency_get_aud20(USB_EP_DIR_OUT, SAMPLING_FREQUENCY_DATA_SIZE_2);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* Do nothing. (not supported) */
}
break;
}
{
if ((FSP_SUCCESS == p_usb_event->status) || (FSP_ERR_USB_SIZE_SHORT == p_usb_event->status))
{
g_completed_read_transfer_length_total += p_usb_event->data_size;
if (READ_REQUEST_SIZE > g_completed_read_transfer_length_total)
{
err = R_USB_Read(&g_basic0_ctrl,
g_recv_buffer + g_completed_read_transfer_length_total,
g_sampling_rx.max_packet_size,
g_device_address);
/* Handle Error */
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Read API FAILED**");
}
}
else
{
if (0 == memcmp(g_send_buffer, g_recv_buffer + FIRST_PACKET_TEST_SIZE, REQUEST_SIZE))
{
/* SET_INTERFACE (ALT number : 0) */
err = haud_app_interface_set(ALT_NUM_0, g_sampling_rx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
APP_ERR_TRAP
}
}
}
else
{
APP_ERR_TRAP
}
break;
}
{
if (FSP_SUCCESS == p_usb_event->status)
{
/* SET_INTERFACE (ALT number : 0) */
err = haud_app_interface_set(ALT_NUM_0, g_sampling_tx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
APP_ERR_TRAP
}
break;
}
{
switch (BMREQUESTTYPETYPE & p_usb_event->setup.request_type)
{
{
if (USB_HAUD_PROTOCOL_IP_VERSION_01_00 == g_device_protocol)
{
haud_app_standard_request_complete_aud10();
}
else if (USB_HAUD_PROTOCOL_IP_VERSION_02_00 == g_device_protocol)
{
haud_app_standard_request_complete_aud20();
}
else
{
/* Do nothing */
}
break;
}
case USB_CLASS:
{
if (USB_HAUD_PROTOCOL_IP_VERSION_01_00 == g_device_protocol)
{
haud_app_audio_class_request_complete_aud10();
}
else if (USB_HAUD_PROTOCOL_IP_VERSION_02_00 == g_device_protocol)
{
haud_app_audio_class_request_complete_aud20();
}
else
{
/* Do nothing */
}
break;
}
}
break;
}
{
memset(&g_sampling_tx, 0, sizeof(g_sampling_tx));
memset(&g_sampling_rx, 0, sizeof(g_sampling_rx));
g_device_address = 0;
g_device_protocol = VALUE_FFH;
g_num_sub_ranges = 0;
g_completed_read_transfer_length_total = 0;
break;
}
default:
{
/* No operation to do */
break;
}
}
}
} /* End of function usb_haud_example */
/*******************************************************************************************************************
* Function Name : haud_app_data_buffer_init
* Description : Initializes test write data.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_data_buffer_init (void)
{
uint32_t i = 0;
uint32_t j = 0;
/* Set data to the send buffer. */
for ( ; i < AUDIO_BUFFER_SIZE; i++)
{
if (i % (VALUE_FFH + 1))
{
(g_send_buffer)[i] = (uint8_t) i;
}
else
{
(g_send_buffer)[i] = (uint8_t) j;
j++;
}
}
} /* End of function haud_app_data_buffer_init */
/*******************************************************************************************************************
* Function Name : haud_app_standard_request_complete_aud10
* Description : Standard request (such as SET_INTERFACE) completion event processing.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_standard_request_complete_aud10 (void)
{
fsp_err_t err = FSP_SUCCESS;
if (USB_SET_INTERFACE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if ((g_sampling_tx.interface_number == p_usb_event->setup.request_index) &&
(g_sampling_tx.alternate_number == p_usb_event->setup.request_value))
{
g_sampling_tx.alternate_setting = USB_TRUE;
err = R_USB_HAUD_PipeSet(&g_basic0_ctrl,
g_sampling_tx.interface_number,
g_sampling_tx.alternate_number,
g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
g_sampling_tx.frequency_setting = USB_TRUE;
/* If there is only one frequency, no need to set it to device. */
if ((g_sampling_tx.p_sampling_descriptor[7] == 1) || /* bSamFreqType : There is one frequency */
((g_sampling_tx.p_sampling_descriptor[7] == 0) && /* bSamFreqType : There is Low(=High) frequency */
(g_sampling_tx.
p_sampling_descriptor[8] == g_sampling_tx.p_sampling_descriptor[11]) && /* tSamFreq (low) */
(g_sampling_tx.
p_sampling_descriptor[9] == g_sampling_tx.p_sampling_descriptor[12]) && /* tSamFreq (middle) */
(g_sampling_tx.
p_sampling_descriptor[10] == g_sampling_tx.p_sampling_descriptor[13]))) /* tSamFreq (high)*/
{
g_sampling_tx.frequency_setting = USB_FALSE; /* No need to set frequency */
}
if (g_sampling_tx.frequency_setting)
{
/* Send SET_CUR requests to set frequency. */
err = haud_app_sampling_frequency_set(g_sampling_tx.endpoint_address, g_sampling_tx.frequency);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
else if ((g_sampling_tx.interface_number == p_usb_event->setup.request_index) &&
(ALT_NUM_0 == p_usb_event->setup.request_value))
{
g_sampling_tx.alternate_setting = USB_FALSE;
g_sampling_rx.channels = SAMPLING_FREQUENCY_CHANNNELS;
g_sampling_rx.frequency = SAMPLING_FREQUENCY_FREQUENCY;
g_sampling_rx.resolution = SAMPLING_FREQUENCY_RESOLUTION;
/* Get Alternate number for Isochronous-IN IF */
err = R_USB_HAUD_AlternateNumberGet(&g_basic0_ctrl, &g_sampling_rx, USB_EP_DIR_IN, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* SET_INTERFACE (Use the acquired ALT number) */
err = haud_app_interface_set(g_sampling_rx.alternate_number, g_sampling_rx.interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else if ((g_sampling_rx.interface_number == p_usb_event->setup.request_index) &&
(g_sampling_rx.alternate_number == p_usb_event->setup.request_value))
{
g_sampling_rx.alternate_setting = USB_TRUE;
err = R_USB_HAUD_PipeSet(&g_basic0_ctrl,
g_sampling_rx.interface_number,
g_sampling_rx.alternate_number,
g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
g_sampling_rx.frequency_setting = USB_TRUE;
/* If there is only one frequency, no need to set it to device. */
if ((g_sampling_rx.p_sampling_descriptor[7] == 1) || /* bSamFreqType : There is one frequency */
((g_sampling_rx.p_sampling_descriptor[7] == 0) && /* bSamFreqType : There is Low(=High) frequency */
(g_sampling_rx.
p_sampling_descriptor[8] == g_sampling_rx.p_sampling_descriptor[11]) && /* tSamFreq (low) */
(g_sampling_rx.
p_sampling_descriptor[9] == g_sampling_rx.p_sampling_descriptor[12]) && /* tSamFreq (middle) */
(g_sampling_rx.
p_sampling_descriptor[10] == g_sampling_rx.p_sampling_descriptor[13]))) /* tSamFreq (high) */
{
g_sampling_rx.frequency_setting = USB_FALSE; /* No need to set frequency */
}
if (g_sampling_rx.frequency_setting)
{
/* Send SET_CUR requests to set frequency. */
err = haud_app_sampling_frequency_set(g_sampling_rx.endpoint_address, g_sampling_rx.frequency);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
else if ((g_sampling_rx.interface_number == p_usb_event->setup.request_index) &&
(ALT_NUM_0 == p_usb_event->setup.request_value))
{
g_sampling_rx.alternate_setting = USB_FALSE;
}
else
{
APP_ERR_TRAP
}
}
} /* End of function haud_app_standard_request_complete_aud10 */
/*******************************************************************************************************************
* Function Name : haud_app_standard_request_complete_aud20
* Description : Standard request (such as SET_INTERFACE) completion event processing.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_standard_request_complete_aud20 (void)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t request_size;
if (USB_SET_INTERFACE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
if ((g_sampling_tx.interface_number == p_usb_event->setup.request_index) &&
(g_sampling_tx.alternate_number == p_usb_event->setup.request_value))
{
g_sampling_tx.alternate_setting = USB_TRUE;
err = R_USB_HAUD_PipeSet(&g_basic0_ctrl,
g_sampling_tx.interface_number,
g_sampling_tx.alternate_number,
g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
/* Data Write (Isochronous-OUT) */
err =
R_USB_Write(&g_basic0_ctrl, (uint8_t *) g_send_buffer, REQUEST_SIZE, g_device_address);
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Write API FAILED**");
}
}
else if ((g_sampling_tx.interface_number == p_usb_event->setup.request_index) &&
(ALT_NUM_0 == p_usb_event->setup.request_value))
{
g_sampling_tx.alternate_setting = USB_FALSE;
/* Starts processing related to obtaining an ALT number for isochronous IN transfer. */
g_sampling_rx.channels = SAMPLING_FREQUENCY_CHANNNELS;
g_sampling_rx.frequency = SAMPLING_FREQUENCY_FREQUENCY;
g_sampling_rx.resolution = SAMPLING_FREQUENCY_RESOLUTION;
err =
R_USB_HAUD_ClockSourceGet(&g_basic0_ctrl, &g_sampling_rx, USB_EP_DIR_IN, g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
err = haud_app_sampling_frequency_get_aud20(USB_EP_DIR_IN, SAMPLING_FREQUENCY_DATA_SIZE_2);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else if ((g_sampling_rx.interface_number == p_usb_event->setup.request_index) &&
(g_sampling_rx.alternate_number == p_usb_event->setup.request_value))
{
g_sampling_rx.alternate_setting = USB_TRUE;
err = R_USB_HAUD_PipeSet(&g_basic0_ctrl,
g_sampling_rx.interface_number,
g_sampling_rx.alternate_number,
g_device_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
if (0 == READ_REQUEST_SIZE % g_sampling_rx.max_packet_size)
{
request_size = READ_REQUEST_SIZE;
}
else
{
request_size =
(uint32_t) (g_sampling_rx.max_packet_size *
((READ_REQUEST_SIZE / g_sampling_rx.max_packet_size) + 1));
}
/* Data Read (Isochronous-IN) */
err = R_USB_Read(&g_basic0_ctrl, g_recv_buffer, request_size, g_device_address);
/* Handle Error */
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Read API FAILED**");
}
}
else if ((g_sampling_rx.interface_number == p_usb_event->setup.request_index) &&
(ALT_NUM_0 == p_usb_event->setup.request_value))
{
g_sampling_rx.alternate_setting = USB_FALSE;
}
else
{
APP_ERR_TRAP
}
}
} /* End of function haud_app_standard_request_complete_aud20 */
/*******************************************************************************************************************
* Function Name : haud_app_audio_class_request_complete_aud10
* Description : Audio class request completion event processing.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_audio_class_request_complete_aud10 (void)
{
uint32_t value;
fsp_err_t err = FSP_SUCCESS;
/* SET_CUR (Isochronous-OUT IF's EP) completed */
if ((USB_HAUD_AUDIO10_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_tx.endpoint_address == p_usb_event->setup.request_index))
{
/* GET_CUR Request (Check whether the sampling frequency specified by SET_CUR has been set on the device.) */
err = haud_app_sampling_frequency_get_aud10(g_sampling_tx.endpoint_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
/* SET_CUR (Isochronous-IN IF's EP) completed */
else if ((USB_HAUD_AUDIO10_SET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_rx.endpoint_address == p_usb_event->setup.request_index))
{
/* GET_CUR Request (Check whether the sampling frequency specified by SET_CUR has been set on the device.) */
err = haud_app_sampling_frequency_get_aud10(g_sampling_rx.endpoint_address);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
/* GET_CUR (Isochronous-OUT IF's EP) completed */
else if ((USB_HAUD_AUDIO10_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_tx.endpoint_address == p_usb_event->setup.request_index))
{
/* The fourth byte has no data so it is cleared. */
g_buf[3] = 0;
value = (ULONG) g_buf[0];
value |= (ULONG) g_buf[1] << 8;
value |= (ULONG) g_buf[2] << 16;
value |= (ULONG) g_buf[3] << 24;
if (value != g_sampling_tx.frequency)
{
/* Sampling frequency requested is not set to device. */
APP_ERR_TRAP
}
/* Data Write (Isochronous-OUT) */
err =
R_USB_Write(&g_basic0_ctrl, (uint8_t *) g_send_buffer, REQUEST_SIZE, g_device_address);
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Write API FAILED**");
}
}
/* GET_CUR (Isochronous-IN IF's EP) completed */
else if ((USB_HAUD_AUDIO10_GET_CUR == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(g_sampling_rx.endpoint_address == p_usb_event->setup.request_index))
{
/* The fourth byte has no data so it is cleared. */
g_buf[3] = 0;
value = (ULONG) g_buf[0];
value |= (ULONG) g_buf[1] << 8;
value |= (ULONG) g_buf[2] << 16;
value |= (ULONG) g_buf[3] << 24;
if (value != g_sampling_rx.frequency)
{
/* Sampling frequency requested is not set to device. */
APP_ERR_TRAP
}
/* Data Read (Isochronous-IN) */
err = R_USB_Read(&g_basic0_ctrl, g_recv_buffer, g_sampling_rx.max_packet_size, g_device_address);
/* Handle Error */
if (FSP_SUCCESS != err)
{
handle_error(err, "**R_USB_Read API FAILED**");
}
}
else
{
APP_ERR_TRAP
}
} /* End of function haud_app_audio_class_request_complete_aud10 */
/*******************************************************************************************************************
* Function Name : haud_app_audio_class_request_complete_aud20
* Description : Audio class request completion event processing.
* Arguments : none
* Return value : none
*******************************************************************************************************************/
static void haud_app_audio_class_request_complete_aud20 (void)
{
uint32_t value;
uint32_t offset;
uint32_t request_length;
uint8_t direction;
fsp_err_t err = FSP_SUCCESS;
uint32_t frequency_low;
uint32_t frequency_high;
usb_haud_sampling_t * p_haud_sampling;
uint8_t * p_buf;
/* RANGE(IN) completed */
if ((USB_HAUD_AUDIO20_RANGE == (p_usb_event->setup.request_type & USB_BREQUEST)) &&
(USB_DEV_TO_HOST == (p_usb_event->setup.request_type & BMREQUESTTYPEDIR)))
{
if (g_sampling_tx.interface_number == (uint32_t) (p_usb_event->setup.request_index & VALUE_FFH))
{
/* Isochronous-OUT IF */
direction = USB_EP_DIR_OUT;
p_haud_sampling = &g_sampling_tx;
}
else
{
/* Isochronous-IN IF */
direction = USB_EP_DIR_IN;
p_haud_sampling = &g_sampling_rx;
}
if (SAMPLING_FREQUENCY_DATA_SIZE_2 == p_usb_event->setup.request_length)
{
/* Get wNumSubRanges */
g_num_sub_ranges = (uint32_t) (*(uint16_t *) g_buf);
if (0 == g_num_sub_ranges)
{
APP_ERR_TRAP
}
/* Calculate parameter length */
request_length = g_num_sub_ranges * SAMPLING_FREQUENCY_SUB_RANGE;
if (request_length > VALUE_FFFFH)
{
APP_ERR_TRAP
}
request_length += 2;
if (request_length > VALUE_FFFFH)
{
APP_ERR_TRAP
}
err = haud_app_sampling_frequency_get_aud20(direction, (uint16_t) request_length);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
else
{
/* Parse ranges */
for (offset = 2; offset < p_usb_event->setup.request_length; offset += SAMPLING_FREQUENCY_SUB_RANGE)
{
p_buf = g_buf;
/* Save frequency (low) */
value = (uint32_t) *(p_buf++ + offset);
value |= ((uint32_t) *(p_buf++ + offset) << 8);
value |= ((uint32_t) *(p_buf++ + offset) << 16);
value |= ((uint32_t) *(p_buf++ + offset) << 24);
frequency_low = value;
frequency_low *= p_haud_sampling->clock_numerator;
frequency_low /= p_haud_sampling->clock_denominator;
/* Save frequency (high) */
value = (uint32_t) *(p_buf++ + offset);
value |= ((uint32_t) *(p_buf++ + offset) << 8);
value |= ((uint32_t) *(p_buf++ + offset) << 16);
value |= ((uint32_t) *(p_buf++ + offset) << 24);
frequency_high = value;
frequency_high *= p_haud_sampling->clock_numerator;
frequency_high /= p_haud_sampling->clock_denominator;
/* Check channels */
if (p_haud_sampling->channels != p_haud_sampling->found_channels)
{
APP_ERR_TRAP
}
/* Check resolution */
if (p_haud_sampling->resolution != p_haud_sampling->found_resolution)
{
APP_ERR_TRAP
}
/* Check frequency */
if ((frequency_low > p_haud_sampling->frequency) ||
(frequency_high < p_haud_sampling->frequency))
{
APP_ERR_TRAP
}
/* Sampling frequency settings and confirmation are OK */
/* SET_INTERFACE (Use the acquired ALT number) */
err = haud_app_interface_set(p_haud_sampling->alternate_number, p_haud_sampling->interface_number);
if (FSP_SUCCESS != err)
{
APP_ERR_TRAP
}
}
}
}
} /* End of function haud_app_audio_class_request_complete_aud20 */
/*******************************************************************************************************************
* Function Name : haud_app_interface_set
* Description : This function does a SET_INTERFACE with the specified Alternate number and interface number.
* Arguments : uint32_t value : Alternate number
* : uint32_t index : Interface number
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_interface_set (uint32_t value, uint32_t index)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
setup.request_value = (uint16_t) value;
setup.request_index = (uint16_t) index;
setup.request_length = 0;
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, &g_usb_dummy, g_device_address);
return err;
} /* End of function haud_app_interface_set */
/*******************************************************************************************************************
* Function Name : haud_app_sampling_frequency_set
* Description : This function sets the sampling frequency on the device using the SET_CUR request.
* Arguments : uint8_t ep_address : End Point Address
* : uint32_t frequency : Sampling Furequency
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_sampling_frequency_set (uint8_t ep_address, uint32_t frequency)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
setup.request_type = USB_HAUD_AUDIO10_SET_CUR | USB_HOST_TO_DEV | USB_CLASS | USB_ENDPOINT;
setup.request_value = USB_HAUD_AUDIO10_EP_SAMPLING_FREQ_CONTROL << 8;
setup.request_index = (uint16_t) ep_address;
setup.request_length = SAMPLING_FREQUENCY_DATA_SIZE_3;
g_buf[0] = (uint8_t) frequency;
g_buf[1] = (uint8_t) (frequency >> 8);
g_buf[2] = (uint8_t) (frequency >> 16);
g_buf[3] = 0;
/* Request Control transfer */
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, g_buf, g_device_address);
return err;
} /* End of function haud_app_sampling_frequency_set */
/*******************************************************************************************************************
* Function Name : haud_app_sampling_frequency_get_aud10
* Description : This function uses a GET_CUR request to get the sampling frequency of the device.
* Arguments : uint8_t ep_address : End Point Address
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_sampling_frequency_get_aud10 (uint8_t ep_address)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
if (USB_HAUD_PROTOCOL_IP_VERSION_01_00 == g_device_protocol)
{
setup.request_type = USB_HAUD_AUDIO10_GET_CUR | USB_DEV_TO_HOST | USB_CLASS | USB_ENDPOINT;
setup.request_value = USB_HAUD_AUDIO10_EP_SAMPLING_FREQ_CONTROL << 8;
setup.request_index = ep_address;
setup.request_length = SAMPLING_FREQUENCY_DATA_SIZE_3;
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, g_buf, g_device_address);
}
else
{
err = FSP_ERR_USB_FAILED;
}
return err;
} /* End of function haud_app_sampling_frequency_get_aud10 */
/*******************************************************************************************************************
* Function Name : haud_app_sampling_frequency_get_aud20
* Description : This function uses a RANGE(IN) request to get the sampling frequency of the device.
* Arguments : uint8_t ep_address : End Point Address
* : uint16_t length : Request length
* Return value : fsp_err_t err : Result of a control transfer request
*******************************************************************************************************************/
static fsp_err_t haud_app_sampling_frequency_get_aud20 (uint8_t ep_address, uint16_t length)
{
fsp_err_t err = FSP_SUCCESS;
usb_setup_t setup;
if (USB_HAUD_PROTOCOL_IP_VERSION_02_00 == g_device_protocol)
{
if (USB_EP_DIR_OUT == (ep_address & USB_EP_DIR))
{
if (0 != g_sampling_tx.clock_source_id)
{
setup.request_type = USB_HAUD_AUDIO20_RANGE | USB_DEV_TO_HOST | USB_CLASS | USB_INTERFACE;
setup.request_value = 0 | USB_HAUD_AUDIO20_CS_SAM_FREQ_CONTROL << 8;
setup.request_index =
(uint16_t) (g_sampling_tx.interface_number | (g_sampling_tx.clock_source_id << 8));
setup.request_length = length;
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, g_buf, g_device_address);
}
}
else
{
if (0 != g_sampling_rx.clock_source_id)
{
setup.request_type = USB_HAUD_AUDIO20_RANGE | USB_DEV_TO_HOST | USB_CLASS | USB_INTERFACE;
setup.request_value = 0 | USB_HAUD_AUDIO20_CS_SAM_FREQ_CONTROL << 8;
setup.request_index =
(uint16_t) (g_sampling_rx.interface_number | (g_sampling_rx.clock_source_id << 8));
setup.request_length = length;
err = R_USB_HostControlTransfer(&g_basic0_ctrl, &setup, g_buf, g_device_address);
}
}
}
else
{
err = FSP_ERR_USB_FAILED;
}
return err;
} /* End of function haud_app_sampling_frequency_get_aud20 */
/*******************************************************************************************************************
* 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)
{
fsp_err_t error = FSP_SUCCESS;
/* close opened USB module */
error = R_USB_Close(&g_basic0_ctrl);
/* Handle error */
if (FSP_SUCCESS != error)
{
APP_ERR_TRAP
}
} /* End of function handle_error() */
#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 usb_state
* Return value : none
*******************************************************************************************************************/
void usb_apl_callback (usb_event_info_t * p_event_info, usb_hdl_t handler, usb_onoff_t usb_state)
{
/* Send event received to queue */
if (USB_TRUE != (xQueueSend(g_usb_queue, (const void *) &p_event_info, (TickType_t) (NO_WAIT_TIME))))
{
g_err_flag = true;
}
} /* End of function usb_rtos_callback */
#endif

Function Documentation

◆ R_USB_HAUD_DeviceInfoGet()

fsp_err_t R_USB_HAUD_DeviceInfoGet ( usb_ctrl_t *const  p_api_ctrl,
usb_haud_device_info_t p_info,
uint8_t  device_address 
)

Check audio version of connected device.

Return values
FSP_SUCCESSSuccessfully completed.
FSP_ERR_USB_FAILEDThe function could not be completed successfully.
FSP_ERR_ASSERTIONParameter Null pointer error.
FSP_ERR_USB_PARAMETERParameter error.
Note
(1). Interrupt function.
(2). Callback function ( for RTOS ).

◆ R_USB_HAUD_ClockSourceGet()

fsp_err_t R_USB_HAUD_ClockSourceGet ( usb_ctrl_t *const  p_api_ctrl,
usb_haud_sampling_t p_info,
uint8_t  direction,
uint8_t  device_address 
)

Get the Clock Souuce (Audio 2.0 support only)

Restriction: This API does not support fallback handling if a Clock Source descriptor is not found.

Return values
FSP_SUCCESSSuccessfully completed.
FSP_ERR_USB_FAILEDThe function could not be completed successfully.
FSP_ERR_ASSERTIONParameter Null pointer error.
FSP_ERR_USB_PARAMETERParameter error.
Note
(1). Interrupt function.
(2). Callback function ( for RTOS ).

◆ R_USB_HAUD_AlternateNumberGet()

fsp_err_t R_USB_HAUD_AlternateNumberGet ( usb_ctrl_t *const  p_api_ctrl,
usb_haud_sampling_t p_info,
uint8_t  direction,
uint8_t  device_address 
)

Get the alternate number for SET_INTERFACE. (Audio 1.0 support only)

Return values
FSP_SUCCESSSuccessfully completed.
FSP_ERR_USB_FAILEDThe function could not be completed successfully.
FSP_ERR_ASSERTIONParameter Null pointer error.
FSP_ERR_USB_PARAMETERParameter error.
Note
(1). Interrupt function.
(2). Callback function ( for RTOS ).

◆ R_USB_HAUD_PipeSet()

fsp_err_t R_USB_HAUD_PipeSet ( usb_ctrl_t *const  p_api_ctrl,
uint32_t  interface_number,
uint32_t  alternate_number,
uint8_t  device_address 
)

Find the interface descriptor for streaming data transfer and configure the pipe.

Return values
FSP_SUCCESSSuccessfully completed.
FSP_ERR_USB_FAILEDThe function could not be completed successfully.
FSP_ERR_ASSERTIONParameter Null pointer error.
FSP_ERR_USB_PARAMETERParameter error.
Note
(1). Interrupt function.
(2). Callback function ( for RTOS ).