RA Flexible Software Package Documentation  Release v5.2.0

 
USB Composite (r_usb_composite)

Functions

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

Overview

USB composite device works as a USB Peripheral by combining two peripheral device classes and r_usb_basic module.
This USB driver supports the following composite devices:

  1. PCDC + PMSC
  2. PCDC + PHID
  3. PHID + PMSC
  4. PCDC + PCDC
  5. PHID + PHID
  6. PCDC + PVND

How to Configuration

The following shows FSP configuration procedure for USB composite device.

r_usb_composite1.png
Select USB Composite
r_usb_composite2.png
USB Composite Stack
r_usb_composite3.png
Select Device Classes
Note
  1. Be sure to select "USB PCDC driver on r_usb_pcdc" and "USB PCDC 2channel driver on r_usb_pcdc" when configurating for "PCDC + PCDC".
  2. Be sure to select "USB PHID driver on r_usb_phid" and "USB PHID 2channel driver on r_usb_phid" when configurating for "PHID + PHID".


r_usb_composite4.png
Delete USB Basic Instance
Note
  1. Delete the "g_basic1" instance manually since this instance is not used in composite device. (Refer to the blue frame in the above figure.)
  2. The error is output when selecting the following device classes.
    1. PMSC + PMSC
r_usb_composite5.png
Device Class Selection Error

Limitations

Notes

Please determine by the member "pipe" in "usb_event_info" structure when getting PCDC channel number which the write event is completed in PCDC + PCDC.
Don't refer to the member "type" in "usb_event_info" structure.

Descriptor

Templates for composite device descriptors can be found in ra/fsp/src/r_usb_composite folder. Also, please be sure to use your vendor ID.

  1. r_usb_pcdc_pmsc_descriptor.c.template (for PCDC + PMSC)
  2. r_usb_pcdc_phid_descriptor.c.template (for PCDC + PHID)
  3. r_usb_phid_pmsc_descriptor.c.template (for PHID + PMSC)
  4. r_usb_pcdc_pcdc_descriptor.c.template (for PCDC + PCDC)
  5. r_usb_phid_phid_descriptor.c.template (for PHID + PHID)
  6. r_usb_pcdc_pvnd_descriptor.c.template (for PCDC + PVND)

Examples

USB COMPOSITE Example

void main_task (void)
{
#if (BSP_CFG_RTOS == 2)
usb_event_info_t * p_mess;
#endif
usb_event_info_t usb_event;
usb_status_t event;
uint8_t * p_idle_value;
uint8_t sw_data;
usb_info_t info;
fsp_err_t ret_code = FSP_SUCCESS;
uint8_t send_data[16] BSP_ALIGN_VARIABLE(4);
uint8_t req_comp_flag = 0;
uint8_t count = 0;
g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
set_key_data(g_buf_phid);
/* Loop back between PC(TerminalSoft) and USB MCU */
while (1)
{
#if (BSP_CFG_RTOS == 2)
USB_APL_RCV_MSG(USB_APL_MBX, (usb_msg_t **) &p_mess);
usb_event = *p_mess;
event = usb_event.event;
#else /* (BSP_CFG_RTOS == 2) */
R_USB_EventGet(&usb_event, &event);
#endif /* (BSP_CFG_RTOS == 2) */
switch (event)
{
{
g_status = NO_WRITING;
g_usb_on_usb.read(&g_basic0_ctrl, g_buf, DATA_LEN, USB_CLASS_PCDC);
break;
}
{
if (usb_event.type == USB_CLASS_PCDC)
{
g_usb_on_usb.read(&g_basic0_ctrl, g_buf, DATA_LEN, USB_CLASS_PCDC);
}
else if (usb_event.type == USB_CLASS_PHID)
{
if (DATA_WRITING == g_status)
{
g_status = ZERO_WRITING;
g_usb_on_usb.write(&g_basic0_ctrl, (uint8_t *) g_zero_data, DATA_LEN_PHID, USB_CLASS_PHID); /* Sending the zero data (8 bytes) */
}
else if (g_status == ZERO_WRITING)
{
g_status = NO_WRITING;
}
}
break;
}
{
if (usb_event.type == USB_CLASS_PCDC)
{
g_usb_on_usb.write(&g_basic0_ctrl, g_buf, usb_event.data_size, USB_CLASS_PCDC);
if (req_comp_flag == 1)
{
if (g_status == NO_WRITING)
{
count++;
g_status = DATA_WRITING;
g_usb_on_usb.write(&g_basic0_ctrl, g_buf_phid, DATA_LEN_PHID, USB_CLASS_PHID);
}
}
}
break;
}
case USB_STATUS_REQUEST: /* Receive Class Request */
{
if (USB_PCDC_SET_LINE_CODING == (usb_event.setup.request_type & USB_BREQUEST))
{
R_USB_PeriControlDataGet(&g_basic0_ctrl, (uint8_t *) &g_line_coding, LINE_CODING_LENGTH);
}
else if (USB_PCDC_GET_LINE_CODING == (usb_event.setup.request_type & USB_BREQUEST))
{
R_USB_PeriControlDataSet(&g_basic0_ctrl, (uint8_t *) &g_line_coding, LINE_CODING_LENGTH);
}
else if (USB_SET_REPORT == (usb_event.setup.request_type & USB_BREQUEST))
{
g_usb_on_usb.read(&g_basic0_ctrl, (uint8_t *) &g_numlock, 2, USB_CLASS_PHID); /* Get the NumLock data (NumLock data is not used) */
}
else if (USB_GET_DESCRIPTOR == (usb_event.setup.request_type & USB_BREQUEST))
{
if (USB_GET_REPORT_DESCRIPTOR == usb_event.setup.request_value)
{
g_usb_on_usb.periControlDataSet(&g_basic0_ctrl,
(uint8_t *) g_apl_report,
USB_RECEIVE_REPORT_DESCRIPTOR);
}
else if (USB_GET_HID_DESCRIPTOR == usb_event.setup.request_value)
{
for (uint8_t i = 0; i < USB_RECEIVE_HID_DESCRIPTOR; i++)
{
send_data[i] = g_apl_configuration[84 + i];
}
/* Configuration Descriptor address set. */
g_usb_on_usb.periControlDataSet(&g_basic0_ctrl, send_data, USB_RECEIVE_HID_DESCRIPTOR);
}
else
{
g_usb_on_usb.periControlStatusSet(&g_basic0_ctrl, USB_SETUP_STATUS_STALL);
}
}
else if (USB_SET_IDLE == (usb_event.setup.request_type & USB_BREQUEST))
{
/* Get SetIdle value */
p_idle_value = (uint8_t *) &usb_event.setup.request_value;
g_idle = p_idle_value[1];
g_usb_on_usb.periControlStatusSet(&g_basic0_ctrl, USB_SETUP_STATUS_ACK);
}
else if (USB_GET_IDLE == (usb_event.setup.request_type & USB_BREQUEST))
{
g_usb_on_usb.periControlDataSet(&g_basic0_ctrl, &g_idle, 1);
}
else if (USB_SET_PROTOCOL == (usb_event.setup.request_type & USB_BREQUEST))
{
g_usb_on_usb.periControlStatusSet(&g_basic0_ctrl, USB_SETUP_STATUS_ACK);
}
else if (USB_GET_PROTOCOL == (usb_event.setup.request_type & USB_BREQUEST))
{
g_usb_on_usb.periControlStatusSet(&g_basic0_ctrl, USB_SETUP_STATUS_STALL);
}
else
{
g_usb_on_usb.periControlStatusSet(&g_basic0_ctrl, USB_SETUP_STATUS_STALL);
}
break;
}
case USB_STATUS_REQUEST_COMPLETE: /* Complete Class Request */
{
if (USB_SET_IDLE == (usb_event.setup.request_type & USB_BREQUEST))
{
p_idle_value = (uint8_t *) &usb_event.setup.request_value;
g_idle = p_idle_value[1];
}
else if (USB_SET_PROTOCOL == (usb_event.setup.request_type & USB_BREQUEST))
{
/* None */
/* g_protocol = event_info.setup.value; */
}
else
{
req_comp_flag = 1;
}
break;
}
{
break;
}
default:
{
break;
}
}
}
} /* End of function usb_main() */
void set_key_data (uint8_t * p_buf)
{
static uint8_t key_data;
key_data = KBD_CODE_A;
*(p_buf + 2) = key_data;
}
#if (BSP_CFG_RTOS == 2)
/******************************************************************************
* Function Name : usb_apl_rec_msg
* Description : Receive a message to the specified id (mailbox).
* Argument : uint8_t id : ID number (mailbox).
* : usb_msg_t** mess : Message pointer
* : usb_tm_t tm : Timeout Value
* Return : uint16_t : USB_OK / USB_ERROR
******************************************************************************/
usb_er_t usb_apl_rec_msg (uint8_t id, usb_msg_t ** mess, usb_tm_t tm)
{
BaseType_t err;
QueueHandle_t handle;
usb_er_t result;
(void) tm;
if (NULL == mess)
{
return USB_APL_ERROR;
}
handle = (*(g_apl_mbx_table[id]));
*mess = NULL;
err = xQueueReceive(handle, (void *) mess, (portMAX_DELAY));
if ((pdTRUE == err) && (NULL != (*mess)))
{
result = USB_APL_OK;
}
else
{
result = USB_APL_ERROR;
}
return result;
}
/******************************************************************************
* End of function usb_apl_rec_msg
******************************************************************************/
/******************************************************************************
* Function Name : usb_apl_snd_msg
* Description : Send a message to the specified id (mailbox).
* Argument : uint8_t id : ID number (mailbox).
* : usb_msg_t* mess : Message pointer
* Return : usb_er_t : USB_OK / USB_ERROR
******************************************************************************/
usb_er_t usb_apl_snd_msg (uint8_t id, usb_msg_t * mess)
{
BaseType_t err;
QueueHandle_t handle;
usb_er_t result;
if (NULL == mess)
{
return USB_APL_ERROR;
}
handle = (*(g_apl_mbx_table[id]));
err = xQueueSend(handle, (const void *) &mess, (TickType_t) (0));
if (pdTRUE == err)
{
result = USB_APL_OK;
}
else
{
result = USB_APL_ERROR;
}
return result;
}
/******************************************************************************
* End of function usb_apl_snd_msg
******************************************************************************/
#endif /* #if (BSP_CFG_RTOS == 2) */
/******************************************************************************
* Includes <System Includes> , "Project Includes"
******************************************************************************/
#include "r_usb_basic.h"
#include "r_usb_pcdc_api.h"
#include "r_usb_pcdc_cfg.h"
/******************************************************************************
* Macro definitions
******************************************************************************/
#define DATA_LEN 2048
#define RESET_VALUE 0
#define INT_EVT_TSK_STACK_SIZE 1024 /* Stack size of Event notification thread for vendor class's Interrupt IN/OUT test */
#define INT_EVT_TSK_PRI 2 /* Priority of Event notification thread for vendor class's Interrupt IN/OUT test */
#define BUF_SIZE (2048) /* Buffer size */
#define REQ_SIZE (20) /* Request buffer size */
#define USB_VALUE_FF (0xFFU) /* FF macro */
#define USB_APL_MXPS (64U)
#define START_PIPE (USB_PIPE1) /* Start pipe number */
#define END_PIPE (USB_PIPE9 + 1) /* Total pipe */
/* for Vendor Class Request */
#define USB_SET_VENDOR_NO_DATA (0x0000U)
#define USB_SET_VENDOR (0x0100U)
#define USB_GET_VENDOR (0x0200U)
#define SET_VENDOR_NO_DATA (USB_SET_VENDOR_NO_DATA | USB_HOST_TO_DEV | USB_VENDOR | USB_INTERFACE)
#define SET_VENDOR (USB_SET_VENDOR | USB_HOST_TO_DEV | USB_VENDOR | USB_INTERFACE)
#define GET_VENDOR (USB_GET_VENDOR | USB_DEV_TO_HOST | USB_VENDOR | USB_INTERFACE)
#define DELAY (10U) /* Delay for print */
#define USB_STATUS_VENDOR_INTIN_TEST ((usb_status_t) 0x01)
#define USB_STATUS_VENDOR_INTOUT_TEST ((usb_status_t) 0x02)
#define USB_STATUS_COM_IN_TEST ((usb_status_t) 0x03)
#define USB_STATUS_RE_INIT_TEST ((usb_status_t) 0x04)
#define HS_MAX_PACKET_SIZE (512)
#define FS_MAX_PACKET_SIZE (64)
#define VALUE_A1H (0xA1)
#define LINE_CODING_LENGTH (0x07U)
/******************************************************************************
* Private global variables and functions
******************************************************************************/
static uint8_t g_cdc_buf[BUF_SIZE] = {RESET_VALUE}; /* Data buffer for PCDC Normal Request */
static uint8_t g_vnd_buf[BUF_SIZE] = {RESET_VALUE}; /* Data buffer for PVND Normal Request */
static uint8_t g_request_buf[REQ_SIZE] = {RESET_VALUE}; /* Data buffer for PVND Class Request */
static uint8_t g_bulk_in_pipe = RESET_VALUE; /* Bulk In Pipe */
static uint8_t g_bulk_out_pipe = RESET_VALUE; /* Bulk Out Pipe */
static uint8_t g_interrupt_in_pipe = RESET_VALUE; /* Interrupt In Pipe */
static uint8_t g_interrupt_out_pipe = RESET_VALUE; /* Interrupt Out Pipe */
static uint16_t g_max_packet_size = USB_APL_MXPS;
/* Variable to capture USB event. */
static volatile usb_event_info_t * p_usb_event = NULL;
static volatile bool g_err_flag = false;
static bool b_usb_attach = false;
static usb_pcdc_linecoding_t g_line_coding;
#if (BSP_CFG_RTOS == 2)
static TaskHandle_t g_app_interrupt_event_notify_tsk_hdl;
#endif /* (BSP_CFG_RTOS == 2) */
static uint32_t g_interrupt_in_test_flag = 0;
static uint32_t g_interrupt_out_test_flag = 0;
static uint32_t g_interrupt_out_times = 0;
static uint32_t g_interrupt_com_event = 0;
static uint8_t g_interrupt_in_com_data[8] = {VALUE_A1H, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint32_t g_test_reinit_flag = 0;
/* Interrupt Event for Application */
#if (BSP_CFG_RTOS == 2)
static usb_event_info_t g_event_info2;
static usb_event_info_t * g_p_event_info2;
#else
static usb_event_info_t g_usb_event;
static usb_status_t g_event;
static uint32_t g_event2;
#endif
extern const usb_cfg_t g_basic0_cfg;
usb_instance_ctrl_t g_basic0_ctrl;
/* Function definitions */
static fsp_err_t process_usb_events(void);
static fsp_err_t process_usb_events_for_interrupt(void);
static fsp_err_t usb_configured_event_process(void);
static fsp_err_t usb_status_request(void);
static void handle_error(fsp_err_t err);
static fsp_err_t buffer_check(uint32_t length);
void usb_composite_thread_entry(void * pvParameters);
#if (BSP_CFG_RTOS == 2)
/******************************************************************************
* Function Name : usb_app_interrupt_event_task
* Description : Event notification thread for Interrupt IN/OUT test.
* Argument : void * pvParameters : Ipointer to pvParameters
* Return : none
******************************************************************************/
void usb_app_interrupt_event_task (void * pvParameters)
{
while (1)
{
if (1 == g_interrupt_in_test_flag)
{
g_interrupt_in_test_flag = 0;
g_event_info2.event = USB_STATUS_VENDOR_INTIN_TEST;
g_p_event_info2 = &g_event_info2;
/* Send Interrupt-IN event to queue */
if (pdTRUE != (xQueueSend(g_event_queue, (const void *) &g_p_event_info2, (TickType_t) (RESET_VALUE))))
{
g_err_flag = true;
}
}
if (1 == g_interrupt_out_test_flag)
{
g_interrupt_out_test_flag = 0;
g_event_info2.event = USB_STATUS_VENDOR_INTOUT_TEST;
g_p_event_info2 = &g_event_info2;
/* Send Interrupt-OUT event to queue */
if (pdTRUE != (xQueueSend(g_event_queue, (const void *) &g_p_event_info2, (TickType_t) (RESET_VALUE))))
{
g_err_flag = true;
}
}
if (0 != g_interrupt_com_event)
{
g_interrupt_com_event = 0;
g_event_info2.event = USB_STATUS_COM_IN_TEST;
g_p_event_info2 = &g_event_info2;
/* Send Interrupt-IN event to queue */
if (pdTRUE != (xQueueSend(g_event_queue, (const void *) &g_p_event_info2, (TickType_t) (RESET_VALUE))))
{
g_err_flag = true;
}
}
if (0 != g_test_reinit_flag)
{
g_test_reinit_flag = 0;
g_event_info2.event = USB_STATUS_RE_INIT_TEST;
g_p_event_info2 = &g_event_info2;
/* Send RE_INIT_TEST event to queue */
if (pdTRUE != (xQueueSend(g_event_queue, (const void *) &g_p_event_info2, (TickType_t) (RESET_VALUE))))
{
g_err_flag = true;
}
}
vTaskDelay(100);
}
}
/******************************************************************************
* End of function usb_app_interrupt_event_task
******************************************************************************/
#endif /* (BSP_CFG_RTOS == 2) */
/******************************************************************************
* Function Name : usb_composite_thread_entry
* Description : Peripheral CDC & Vendor application main process
* Arguments : none
* Return value : none
******************************************************************************/
void usb_composite_thread_entry (void * pvParameters)
{
FSP_PARAMETER_NOT_USED(pvParameters);
fsp_err_t err = FSP_SUCCESS;
#if (BSP_CFG_RTOS == 2)
BaseType_t err_queue = pdFALSE;
BaseType_t err_task = pdFALSE;
#endif /* (BSP_CFG_RTOS == 2) */
/* Open USB instance */
R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
if (USB_SPEED_FS == g_basic0_cfg.usb_speed)
{
g_max_packet_size = FS_MAX_PACKET_SIZE;
}
else
{
g_max_packet_size = HS_MAX_PACKET_SIZE;
}
#if (BSP_CFG_RTOS == 2)
err_task = xTaskCreate((TaskFunction_t) usb_app_interrupt_event_task,
"INT_EVT_TSK",
INT_EVT_TSK_STACK_SIZE,
NULL,
INT_EVT_TSK_PRI,
&g_app_interrupt_event_notify_tsk_hdl);
if (pdPASS != err_task)
{
return;
}
#endif
while (true)
{
/* Handle error if queue send fails*/
if (true == g_err_flag)
{
handle_error(FSP_ERR_ABORTED);
}
#if (BSP_CFG_RTOS == 2)
/* Receive message from queue */
err_queue = xQueueReceive(g_event_queue, &p_usb_event, (portMAX_DELAY));
/* Handle error */
if (pdTRUE != err_queue)
{
handle_error(FSP_ERR_ABORTED);
}
if (pdTRUE == err_queue)
{
if (p_usb_event == &g_event_info2)
{
/* process Application Interrupt events */
err = process_usb_events_for_interrupt();
handle_error(err);
}
else
{
/* process USB events */
err = process_usb_events();
handle_error(err);
}
}
#else /* (BSP_CFG_RTOS == 2) */
R_USB_EventGet(&g_usb_event, &g_event);
if (USB_STATUS_NONE == g_event)
{
/* Interrupt IN Test Event for Vendor Class */
if (1 == g_interrupt_in_test_flag)
{
g_interrupt_in_test_flag = 0;
g_event2 = USB_STATUS_VENDOR_INTIN_TEST;
err = process_usb_events_for_interrupt();
}
/* Interrupt OUT Test Event for Vendor Class */
else if (1 == g_interrupt_out_test_flag)
{
g_interrupt_out_test_flag = 0;
g_event2 = USB_STATUS_VENDOR_INTOUT_TEST;
err = process_usb_events_for_interrupt();
}
/* Interrupt IN Test Event for COM Class */
else if (0 != g_interrupt_com_event)
{
g_interrupt_com_event = 0;
g_event2 = USB_STATUS_COM_IN_TEST;
err = process_usb_events_for_interrupt();
}
/* ReInit Test Event */
else if (0 != g_test_reinit_flag)
{
g_test_reinit_flag = 0;
g_event2 = USB_STATUS_RE_INIT_TEST;
err = process_usb_events_for_interrupt();
}
else
{
err = process_usb_events();
}
}
else
{
p_usb_event = &g_usb_event;
err = process_usb_events();
}
handle_error(err);
#endif
}
}
/******************************************************************************
* End of function usb_composite_thread_entry
******************************************************************************/
/******************************************************************************
* 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.
******************************************************************************/
static fsp_err_t process_usb_events (void)
{
fsp_err_t err = FSP_SUCCESS;
/* USB event received */
#if (BSP_CFG_RTOS == 2)
switch (p_usb_event->event)
#else /* (BSP_CFG_RTOS == 2) */
switch (g_event)
#endif /* (BSP_CFG_RTOS == 2) */
{
case USB_STATUS_CONFIGURED: /* Configured State */
{
/* Process USB configured event */
usb_configured_event_process();
/* [PCDC] Read data from terminal software */
R_USB_Read(&g_basic0_ctrl, g_cdc_buf, g_max_packet_size, USB_CLASS_PCDC);
/* [PVND] Read data from ra_usb_hvnd.exe */
memset(g_vnd_buf, RESET_VALUE, BUF_SIZE);
err = R_USB_PipeRead(&g_basic0_ctrl, &g_vnd_buf[RESET_VALUE], BUF_SIZE, g_bulk_out_pipe);
break;
}
case USB_STATUS_WRITE_COMPLETE: /* Write Complete State */
{
if (b_usb_attach)
{
/* [PCDC] Read data from terminal software */
if ((USB_CFG_PCDC_BULK_IN == p_usb_event->pipe) && (FSP_ERR_USB_FAILED != p_usb_event->status))
{
err = R_USB_Read(&g_basic0_ctrl, g_cdc_buf, g_max_packet_size, USB_CLASS_PCDC);
}
/* [PVND] Read data from ra_usb_hvnd.exe */
if ((g_bulk_in_pipe == p_usb_event->pipe) && (FSP_ERR_USB_FAILED != p_usb_event->status))
{
memset(g_vnd_buf, RESET_VALUE, BUF_SIZE);
/* Read data back */
err = R_USB_PipeRead(&g_basic0_ctrl, &g_vnd_buf[RESET_VALUE], BUF_SIZE, g_bulk_out_pipe);
}
}
else
{
// Do Nothing as USB is removed and not connected yet.
}
break;
}
case USB_STATUS_READ_COMPLETE: /* Read Complete State */
{
if (b_usb_attach)
{
/* PCDC */
if ((USB_CFG_PCDC_BULK_OUT == p_usb_event->pipe) && (FSP_ERR_USB_FAILED != p_usb_event->status))
{
/* Write back the read data from terminal software to it. */
err = R_USB_Write(&g_basic0_ctrl, g_cdc_buf, p_usb_event->data_size, USB_CLASS_PCDC);
}
/* PVND */
if ((g_bulk_out_pipe == p_usb_event->pipe) && (FSP_ERR_USB_FAILED != p_usb_event->status))
{
/* Data comparison read from host */
err = buffer_check(p_usb_event->data_size);
if (FSP_SUCCESS == err)
{
/* Write data back to host */
R_USB_PipeWrite(&g_basic0_ctrl, &g_vnd_buf[RESET_VALUE], p_usb_event->data_size,
g_bulk_in_pipe);
}
else
{
return FSP_ERR_USB_FAILED;
}
}
}
else
{
// Do Nothing as USB is removed and not connected yet.
}
break;
}
case USB_STATUS_REQUEST: /* Receive Class Request */
{
/* Perform usb status request operation.*/
err = usb_status_request();
break;
}
case USB_STATUS_REQUEST_COMPLETE: /* Request Complete State */
{
// Do Nothing.
break;
}
{
/* Reset the usb attached flag as indicating usb is removed.*/
b_usb_attach = false;
memset(g_cdc_buf, RESET_VALUE, sizeof(g_cdc_buf));
memset(g_vnd_buf, RESET_VALUE, sizeof(g_vnd_buf));
break;
}
{
/* set the usb attached flag*/
b_usb_attach = true;
break;
}
default:
{
break;
}
}
return err;
}
/******************************************************************************
* End of function process_usb_events
******************************************************************************/
/******************************************************************************
* Function Name : process_usb_events_for_interrupt
* Description : Function processes Application events (Interrupt IN/OUT Request ).
* Arguments : none
* Return value : Any Other Error code apart from FSP_SUCCESS on Unsuccessful operation.
******************************************************************************/
static fsp_err_t process_usb_events_for_interrupt (void)
{
fsp_err_t err = FSP_SUCCESS;
uint8_t pipe = RESET_VALUE;
/* USB event received */
#if (BSP_CFG_RTOS == 2)
switch (p_usb_event->event)
#else /* (BSP_CFG_RTOS == 2) */
switch (g_event2)
#endif /* (BSP_CFG_RTOS == 2) */
{
case USB_STATUS_VENDOR_INTIN_TEST:
{
pipe = g_interrupt_in_pipe;
err = R_USB_PipeWrite(&g_basic0_ctrl, (uint8_t *) "interrupt-in-test", strlen("interrupt-in-test"), pipe);
break;
}
case USB_STATUS_VENDOR_INTOUT_TEST:
{
pipe = g_interrupt_out_pipe;
err = R_USB_PipeRead(&g_basic0_ctrl, &g_vnd_buf[RESET_VALUE], (BUF_SIZE), pipe);
if (FSP_SUCCESS == err)
{
g_interrupt_out_times++;
}
break;
}
case USB_STATUS_COM_IN_TEST:
{
pipe = USB_CFG_PCDC_INT_IN;
err = R_USB_PipeWrite(&g_basic0_ctrl, g_interrupt_in_com_data, sizeof(g_interrupt_in_com_data), pipe);
break;
}
case USB_STATUS_RE_INIT_TEST:
{
g_usb_on_usb.close(&g_basic0_ctrl);
g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
break;
}
default:
{
break;
}
}
return err;
}
/******************************************************************************
* End of function process_usb_events_for_interrupt
******************************************************************************/
/******************************************************************************
* Function Name : usb_configured_event_process
* Description : Function processes USB configured event (for vendor class).
* Arguments : none
* Return value : Any Other Error code apart from FSP_SUCCESS on Unsuccessful operation.
******************************************************************************/
static fsp_err_t usb_configured_event_process (void)
{
fsp_err_t err = FSP_SUCCESS;
uint16_t used_pipe = RESET_VALUE;
usb_pipe_t pipe_info = {RESET_VALUE};
uint8_t pipe = RESET_VALUE;
/* Get USB Pipe Information */
err = R_USB_UsedPipesGet(&g_basic0_ctrl, &used_pipe, USB_CLASS_PVND);
if (FSP_SUCCESS == err)
{
for (pipe = START_PIPE; pipe < END_PIPE; pipe++)
{
/* check for the used pipe */
if ((used_pipe & (START_PIPE << pipe)) != RESET_VALUE)
{
/* Get the pipe Info */
err = R_USB_PipeInfoGet(&g_basic0_ctrl, &pipe_info, pipe);
if (USB_EP_DIR_IN != (pipe_info.endpoint & USB_EP_DIR_IN))
{
/* Out Transfer */
if (USB_TRANSFER_TYPE_BULK == pipe_info.transfer_type)
{
if (pipe != USB_CFG_PCDC_BULK_OUT)
{
g_bulk_out_pipe = pipe;
}
}
else if (USB_TRANSFER_TYPE_INT == pipe_info.transfer_type)
{
g_interrupt_out_pipe = pipe;
}
else
{
/* Do nothing */
}
}
else
{
/* In Transfer */
if (USB_TRANSFER_TYPE_BULK == pipe_info.transfer_type)
{
if (pipe != USB_CFG_PCDC_BULK_IN)
{
g_bulk_in_pipe = pipe;
}
}
else if (USB_TRANSFER_TYPE_INT == pipe_info.transfer_type)
{
if (pipe != USB_CFG_PCDC_INT_IN)
{
g_interrupt_in_pipe = pipe;
}
}
else
{
/* Do nothing */
}
}
}
else
{
/* Do nothing */
}
}
}
return err;
}
/******************************************************************************
* End of function usb_configured_event_process
******************************************************************************/
/******************************************************************************
* Function Name : usb_status_request
* Description : Function processes usb status request.
* Arguments : none
* Return value : Any Other Error code apart from FSP_SUCCESS on Unsuccessful operation.
******************************************************************************/
static fsp_err_t usb_status_request (void)
{
fsp_err_t err = FSP_SUCCESS;
uint16_t request_length = RESET_VALUE;
/* Check for the specific CDC class request IDs */
if (USB_PCDC_SET_LINE_CODING == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Get the class request.*/
err = R_USB_PeriControlDataGet(&g_basic0_ctrl, (uint8_t *) &g_line_coding, LINE_CODING_LENGTH);
}
else if (USB_PCDC_GET_LINE_CODING == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Set the class request.*/
err = R_USB_PeriControlDataSet(&g_basic0_ctrl, (uint8_t *) &g_line_coding, LINE_CODING_LENGTH);
}
else if (USB_PCDC_SET_CONTROL_LINE_STATE == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Set the usb status as ACK response.*/
}
else if (USB_SET_VENDOR_NO_DATA == (p_usb_event->setup.request_type & USB_BREQUEST))
{
/* Set ACk to host */
}
else if (USB_SET_VENDOR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
request_length = p_usb_event->setup.request_length;
/* Get data length from host */
err = R_USB_PeriControlDataGet(&g_basic0_ctrl, &g_request_buf[RESET_VALUE], request_length);
}
else if (USB_GET_VENDOR == (p_usb_event->setup.request_type & USB_BREQUEST))
{
request_length = p_usb_event->setup.request_length;
/* Set data length in peripheral */
err = R_USB_PeriControlDataSet(&g_basic0_ctrl, &g_request_buf[RESET_VALUE], request_length);
}
else
{
// Do Nothing.
}
return err;
}
/******************************************************************************
* End of function usb_status_request
******************************************************************************/
#if (BSP_CFG_RTOS == 2)
/******************************************************************************
* Function Name : usb_composite_callback
* Description : Callback function for Application program
* Arguments : usb_event_info_t *p_event_info : Control structure for USB API.
* usb_hdl_t handler : Task Handle
* usb_onoff_t usbon_off_state : USB_ON(USB_STATUS_REQUEST) / USB_OFF
* Return value : none
******************************************************************************/
void usb_composite_callback (usb_event_info_t * p_event_info, usb_hdl_t handler, usb_onoff_t on_off)
{
/* Send event received to queue */
if (pdTRUE != (xQueueSend(g_event_queue, (const void *) &p_event_info, (TickType_t) (RESET_VALUE))))
{
g_err_flag = true;
}
}
/******************************************************************************
* End of function usb_composite_callback
******************************************************************************/
#endif /* (BSP_CFG_RTOS == 2) */
/******************************************************************************
* Function Name : handle_error
* Description : Closes the USB module , Print and traps error.
* Arguments : fsp_err_t err : error status
* Return value : none
******************************************************************************/
static void handle_error (fsp_err_t err)
{
if (FSP_SUCCESS != err)
{
R_USB_Close(&g_basic0_ctrl);
}
}
/******************************************************************************
* End of function handle_error
******************************************************************************/
/******************************************************************************
* Function Name : buffer_check
* Description : Check data received from vendor host tools
* Arguments : uint32_t length : data length
* char * err_str : error string
* Return value : Any Other Error code apart from FSP_SUCCESS on Unsuccessful operation.
******************************************************************************/
static fsp_err_t buffer_check (uint32_t length)
{
for (uint16_t cnt = RESET_VALUE; cnt < (uint16_t) length; cnt++)
{
if ((uint8_t) (cnt & USB_VALUE_FF) != g_vnd_buf[cnt])
{
}
}
return FSP_SUCCESS;
}
/******************************************************************************
* End of function buffer_check
******************************************************************************/