RA Flexible Software Package Documentation  Release v5.6.0

 
Azure RTOS USBX Port (rm_usbx_port)

Functions

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

Overview

This USB driver works by combining USBX and r_usb_basic module.

How to Configuration

Using a class other than Composite(Pereipheral), HMSC and OTG.

The following describes how to configure USBX using PCDC as an example.

rm_usbx_pcdc1.png
Select USB Device Class
rm_usbx_pcdc3.png
Select using USB Pipe

Using Composite (Peripheral)

rm_usbx_composite1.png
Select USB Composite
rm_usbx_composite2.png
USB Composite Stack
rm_usbx_composite3.png
Select Device Classes
rm_usbx_composite4.png
Delete USB Basic instance

Using HMSC.

Since HMSC is used in a different way from other USBX modules, the usage is described below.

rm_usbx_hmsc1.png
Select USB Device Class
rm_usbx_hmsc2.svg
FileX on USBX Stack

Using OTG.

The following describes how to configure USBX OTG.

rm_usbx_otg_irq.png
Select USB Device Class for OTG
rm_usbx_otg_stack.png
Select USB Device Class for OTG
rm_usbx_otg_usb_basic.png
Select USB Device Class
rm_usbx_otg_pin.png
USB Pin Setting
rm_usbx_otg_irq_pin.png
IRQ Pin Setting

Using Hub

Note

HMSC uses FileX.

For more information on FileX, please refer to the following URL.

https://docs.microsoft.com/en-us/azure/rtos/filex/

OTG

Offset Field Size Value Description
0 bLength 1 5 Size of Descriptor
1 bDescriptor Type1 9 OTG type = 9
2 bmAttribute 1 3 or 2 D1: HNP support
D0: SRP support
3 bcdOTG 2 0x200 Binary Code Descimal

Known Issues

Limitations

timer_ticks.png
Specify value of Timer Ticks Per Second
thread_priority.png
Specify value of Thread priority
rm_usbx_hmsc_filex.png
Check the fx checkbox

Descriptor

Templates for USBX descriptors can be found in ra/fsp/src/rm_usbx_port folder. Also, please be sure to use your vendor ID.
Change the descriptor.c.template file for each class as follows if High-speed mode is used.

There are two types of templates for PHID descriptor.
Keyboard templates should be referred to rm_usbx_phid_descriptor_keyboard.c.template.
Mouse templates should be referred to rm_usbx_phid_descriptor_mouse.c.template.

Examples

USBX PCDC Example

PCDC loopback example is as follows.

#define VALUE_105 (105)
#define VALUE_2 (2)
#define VALUE_103 (103)
#define VALUE_93 (93)
/******************************************************************************
* Function Name : ux_cdc_device0_instance_activate
* Description : Get instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_cdc_device0_instance_activate (void * cdc_instance)
{
/* Save the CDC instance. */
g_cdc = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
}
/******************************************************************************
* End of function ux_cdc_device0_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_deactivate
* Description : Clear instance
* Arguments : void * cdc_instance : Pointer to area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
FSP_PARAMETER_NOT_USED(cdc_instance);
g_cdc = UX_NULL;
}
/******************************************************************************
* End of function ux_cdc_device0_instance_deactivate
******************************************************************************/
/******************************************************************************
* Function Name : apl_status_change_cb
* Description : USB callback function for USB status change
* Arguments : ULONG status : USB status
* Return value : UX_SUCCESS
******************************************************************************/
UINT apl_status_change_cb (ULONG status)
{
switch (status)
{
case UX_DEVICE_ATTACHED:
g_attach = USB_YES;
break;
case UX_DEVICE_REMOVED:
g_attach = USB_NO;
break;
default:
break;
}
return UX_SUCCESS;
}
/******************************************************************************
* End of function apl_status_change_cb
******************************************************************************/
/******************************************************************************
* Function Name : usbx_pcdc_sample
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_pcdc_sample (void)
{
fsp_err_t err;
uint32_t ret;
uint32_t size;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_device_stack_initialize(g_device_framework_hi_speed,
VALUE_103,
g_device_framework_full_speed,
VALUE_93,
g_string_framework,
VALUE_105,
g_language_id_framework,
VALUE_2,
apl_status_change_cb);
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_activate = ux_cdc_device0_instance_activate;
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_deactivate =
ux_cdc_device0_instance_deactivate;
ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name,
_ux_device_class_cdc_acm_entry,
1,
0x00,
(void *) &g_ux_device_class_cdc_acm0_parameter);
err = g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS == err)
{
while (1)
{
if (USB_YES == g_attach)
{
while (g_cdc == UX_NULL)
{
;
}
ret = _ux_device_class_cdc_acm_read(g_cdc, g_buf, DATA_LEN, &g_actual_length);
if (UX_SUCCESS == ret)
{
size = g_actual_length;
_ux_device_class_cdc_acm_write(g_cdc, g_buf, size, &g_actual_length);
}
}
}
}
}
/******************************************************************************
* End of function usbx_pcdc_sample
******************************************************************************/

USBX HCDC Example

The main functions of the HCDC loopback example are as follows:

  1. Virtual UART control settings are configured by transmitting the class request SET_LINE_CODING to the CDC device.
  2. Sends receive (Bulk In transfer) requests to a CDC peripheral device and receives data.
  3. Loops received data back to the peripheral by means of Bulk Out transfers.

The main loop performs loopback processing in which data received from a CDC peripheral device is transmitted unaltered back to the peripheral.

#define VALUE_100 (100)
UINT ux_host_usr_event_notification (ULONG event, UX_HOST_CLASS * host_class, VOID * instance)
{
if (UX_FSP_DEVICE_INSERTION == event) /* Check if there is a device insertion. */
{
p_cdc_acm = (UX_HOST_CLASS_CDC_ACM *) instance;
if (UX_HOST_CLASS_CDC_DATA_CLASS !=
p_cdc_acm->ux_host_class_cdc_acm_interface->ux_interface_descriptor.bInterfaceClass)
{
if (UX_NULL != p_cdc_acm->ux_host_class_cdc_acm_next_instance)
{
/* It seems the DATA class is on the second interface. Or we hope ! */
p_cdc_acm = p_cdc_acm->ux_host_class_cdc_acm_next_instance;
/* Check again this interface, if this is not the data interface, we give up. */
if (p_cdc_acm->ux_host_class_cdc_acm_interface->ux_interface_descriptor.bInterfaceClass !=
UX_HOST_CLASS_CDC_DATA_CLASS)
{
/* We did not find a proper data interface. */
p_cdc_acm = UX_NULL;
}
}
}
if (p_cdc_acm != UX_NULL)
{
tx_event_flags_set(&g_cdcacm_activate_event_flags0, CDCACM_FLAG, TX_OR);
}
}
else if (event == UX_FSP_DEVICE_REMOVAL) /* Check if there is a device removal. */
{
tx_event_flags_set(&g_cdcacm_activate_event_flags0, ~CDCACM_FLAG, TX_AND);
p_cdc_acm = UX_NULL;
}
else
{
/* None */
}
return UX_SUCCESS;
}
void buffer_clear (uint8_t * p)
{
uint16_t counter;
for (counter = 0; counter < DATA_LEN; counter++)
{
*p = 0U;
}
}
/******************************************************************************
* Function Name : usbx_hcdc_sample
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
/* CDCACM Host Thread entry function */
void usbx_hcdc_sample (void)
{
uint32_t status;
ULONG actual_flags;
uint16_t counter = 0;
for (counter = 0; counter < DATA_LEN; counter++)
{
g_write_buf[counter] = (uint8_t) counter;
}
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_host_stack_initialize(ux_host_usr_event_notification);
g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
while (1)
{
tx_event_flags_get(&g_cdcacm_activate_event_flags0, CDCACM_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
if (UX_NULL != p_cdc_acm)
{
if (0 == g_is_communicate)
{
tx_thread_sleep(VALUE_100);
g_is_communicate = 1;
}
if (UX_NULL != p_cdc_acm)
{
status = ux_host_class_cdc_acm_write(p_cdc_acm, g_write_buf, DATA_LEN, &g_write_actual_length);
if ((UX_SUCCESS == status) && (DATA_LEN == g_write_actual_length))
{
g_read_actual_length = 0;
buffer_clear(g_read_buf);
if (UX_NULL != p_cdc_acm)
{
status = ux_host_class_cdc_acm_read(p_cdc_acm, g_read_buf, DATA_LEN, &g_read_actual_length);
if ((UX_SUCCESS == status) && (DATA_LEN == g_read_actual_length))
{
for (counter = 0; counter < DATA_LEN; counter++)
{
if ((uint8_t) counter != g_read_buf[counter])
{
while (1)
{
;
}
}
} /* for */
}
} /* UX_NULL != p_cdc_acm */
}
} /* UX_NULL != p_cdc_acm */
}
}
}

USBX PMSC Example

PMSC storage example is as follows.

const rm_block_media_cfg_t g_rm_block_media0_cfg =
{.p_extend = NULL, .p_callback = NULL, .p_context = NULL, };
rm_block_media_info_t g_rm_block_info0 =
{.sector_size_bytes = STRG_MEDIASIZE, .num_sectors = STRG_TOTALSECT, .reentrant = false, .write_protected = false, };
rm_block_media_instance_t g_rm_block_media0 =
{.p_api = &g_rm_block_media_on_user_media, .p_ctrl = &g_rm_block_info0, .p_cfg = &g_rm_block_media0_cfg, };
/******************************************************************************
* Function Name : usbx_pmsc_sample
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_pmsc_sample (void)
{
fsp_err_t err;
UINT ret;
ULONG size;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_device_stack_initialize(g_device_framework_hi_speed,
60,
g_device_framework_full_speed,
50,
g_string_framework,
93,
g_language_id_framework,
2,
UX_NULL);
err = g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS == err)
{
while (1)
{
;
}
}
}

USBX HMSC Example

HMSC storage example is as follows. See usbx_hmsc_sample for the basic operation of HMSC. Also, please refer to usbx_hmsc_sample_format for the format of the USB memory.

#define UX_STORAGE_BUFFER_SIZE (64 * 1024)
#define EVENT_USB_PLUG_IN (1UL << 0)
#define EVENT_USB_PLUG_OUT (1UL << 1)
#define MEMPOOL_SIZE (63488)
#define DATA_LEN (2048)
#define VALUE_32 (32)
#define VALUE_100 (100)
#define VALUE_200 (200)
#define VALUE_256 (256)
#define VALUE_1024 (1024)
#define DEVICE_INSERTION (0x01U)
#define DEVICE_REMOVAL (0x02U)
static uint16_t g_read_buf[UX_STORAGE_BUFFER_SIZE];
static uint16_t g_write_buf[UX_STORAGE_BUFFER_SIZE];
static FX_FILE g_file;
static UCHAR g_fx_media0_media_memory[UX_STORAGE_BUFFER_SIZE];
static uint8_t g_ux_pool_memory[MEMPOOL_SIZE];
static FX_MEDIA * g_p_media = UX_NULL;
TX_EVENT_FLAGS_GROUP g_usb_plug_events;
UINT usb_host_plug_event_notification(ULONG usb_event, UX_HOST_CLASS * host_class, VOID * instance);
UINT ux_system_host_storage_fx_media_get(UX_HOST_CLASS_STORAGE * instance,
UX_HOST_CLASS_STORAGE_MEDIA ** p_storage_media,
FX_MEDIA ** p_fx_media);
static UINT apl_change_function (ULONG event, UX_HOST_CLASS * host_class, VOID * instance)
{
UINT status = UX_SUCCESS;
UX_HOST_CLASS * class;
UX_HOST_CLASS_STORAGE * storage;
UX_HOST_CLASS_STORAGE_MEDIA * storage_media;
/* Check if there is a device insertion. */
if (DEVICE_INSERTION == event)
{
status = ux_host_stack_class_get(_ux_system_host_class_storage_name, &class);
if (UX_SUCCESS != status)
{
return status;
}
status = ux_host_stack_class_instance_get(class, 0, (void **) &storage);
if (UX_SUCCESS != status)
{
return status;
}
if (UX_HOST_CLASS_INSTANCE_LIVE != storage->ux_host_class_storage_state)
{
return UX_ERROR;
}
storage_media = class->ux_host_class_media;
g_p_media = &storage_media->ux_host_class_storage_media;
tx_event_flags_set(&g_usb_plug_events, EVENT_USB_PLUG_IN, TX_OR);
}
else if (DEVICE_REMOVAL == event) /* Check if there is a device removal. */
{
g_p_media = UX_NULL;
tx_event_flags_set(&g_usb_plug_events, EVENT_USB_PLUG_OUT, TX_OR);
}
else
{
/* None */
}
return status;
}
/******************************************************************************
* Function Name : usbx_hmsc_sample
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_hmsc_sample (void)
{
ULONG actual_length = 0;
ULONG actual_flags;
UINT tx_return;
UINT fx_return;
uint16_t data_count = 0;
FX_MEDIA * p_media = UX_NULL;
CHAR volume[VALUE_32];
fx_system_initialize();
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_host_stack_initialize(apl_change_function);
tx_event_flags_create(&g_usb_plug_events, (CHAR *) "USB Plug Event Flags");
g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
while (1)
{
// Wait until device inserted.
tx_return = tx_event_flags_get(&g_usb_plug_events,
EVENT_USB_PLUG_IN,
TX_OR_CLEAR,
&actual_flags,
TX_WAIT_FOREVER);
if (TX_SUCCESS != tx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
// Get the pointer to FileX Media Control Block for a USB flash device
p_media = g_p_media;
// Retrieve the volume name of the opened media from the Data sector
fx_return = fx_media_volume_get(p_media, volume, FX_DIRECTORY_SECTOR);
if (FX_SUCCESS == fx_return)
{
// Set the default directory in the opened media, arbitrary name called "firstdir"
fx_directory_default_set(p_media, "firstdir");
// Suspend this thread for 200 time-ticks
tx_thread_sleep(VALUE_100);
// Try to open the file, 'counter.txt'.
fx_return = fx_file_open(p_media, &g_file, "counter.txt", (FX_OPEN_FOR_READ | FX_OPEN_FOR_WRITE));
if (FX_SUCCESS != fx_return)
{
// The 'counter.txt' file is not found, so create a new file
fx_return = fx_file_create(p_media, "counter.txt");
if (FX_SUCCESS != fx_return)
{
break;
}
// Open that file
fx_return = fx_file_open(p_media, &g_file, "counter.txt", (FX_OPEN_FOR_READ | FX_OPEN_FOR_WRITE));
if (FX_SUCCESS != fx_return)
{
break;
}
}
// Already open a file, then read the file in blocks
// Set a specified byte offset for reading
fx_return = fx_file_seek(&g_file, 0);
if (FX_SUCCESS == fx_return)
{
fx_return = fx_file_read(&g_file, g_read_buf, DATA_LEN, &actual_length);
if ((FX_SUCCESS == fx_return) || (FX_END_OF_FILE == fx_return))
{
if (data_count == VALUE_1024)
{
// empty file
data_count = 0;
}
for (uint16_t data_max_count = data_count; data_count < (data_max_count + VALUE_256); data_count++)
{
g_write_buf[data_count] = data_count;
}
// Set the specified byte offset for writing
fx_return = fx_file_seek(&g_file, 0);
if (FX_SUCCESS == fx_return)
{
// Write the file in blocks
fx_return = fx_file_write(&g_file, g_write_buf, DATA_LEN);
if (FX_SUCCESS == fx_return)
{
}
else
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
}
}
}
else
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
// Close already opened file
fx_return = fx_file_close(&g_file);
if (FX_SUCCESS != fx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
tx_thread_sleep(VALUE_200);
}
else
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
/* flush the media */
fx_return = fx_media_flush(p_media);
if (FX_SUCCESS != fx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
/* close the media */
fx_return = fx_media_close(p_media);
if (FX_SUCCESS != fx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
// Wait for unplugging the USB
tx_event_flags_get(&g_usb_plug_events, EVENT_USB_PLUG_OUT, TX_OR_CLEAR, &actual_flags, TX_WAIT_FOREVER);
} // while(1)
}
void usbx_hmsc_sample_format (void)
{
ULONG actual_flags;
UINT tx_return;
UINT status = UX_SUCCESS;
FX_MEDIA * p_media = UX_NULL;
fx_system_initialize();
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_host_stack_initialize(apl_change_function);
tx_event_flags_create(&g_usb_plug_events, (CHAR *) "USB Plug Event Flags");
g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
// Wait until device inserted.
tx_return = tx_event_flags_get(&g_usb_plug_events, EVENT_USB_PLUG_IN, TX_OR_CLEAR, &actual_flags, TX_WAIT_FOREVER);
if (TX_SUCCESS != tx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
// Get the pointer to FileX Media Control Block for a USB flash device
p_media = g_p_media;
memset(g_fx_media0_media_memory, 0x00, sizeof(g_fx_media0_media_memory));
status = fx_media_format(p_media, // Pointer to FileX media control block.
p_media->fx_media_driver_entry, // Driver entry
p_media->fx_media_driver_info, // Pointer to Block Media Driver
g_fx_media0_media_memory, // Media buffer pointer
p_media->fx_media_memory_size, // Media buffer size
"sample", // Volume Name
p_media->fx_media_number_of_FATs, // Number of FATs
p_media->fx_media_root_directory_entries, // Directory Entries
p_media->fx_media_hidden_sectors, // Hidden sectors
(ULONG) p_media->fx_media_total_sectors, // Total sectors
p_media->fx_media_bytes_per_sector, // Sector size
p_media->fx_media_sectors_per_cluster, // Sectors per cluster
p_media->fx_media_heads, // Heads (disk media)
p_media->fx_media_sectors_per_track);
if ((uint8_t) FX_SUCCESS != status)
{
__BKPT(0);
}
}

USBX PHID Example

PHID keyboard example is as follows.

/******************************************************************************
* Function Name : usbx_phid_keyboard_sample
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_phid_keyboard_sample (void)
{
UX_SLAVE_CLASS_HID_EVENT hid_event;
UCHAR key;
fsp_err_t err;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_device_stack_initialize(NULL,
0,
g_device_framework_full_speed,
#if defined(APL_OUT_TRANSFER)
VALUE_59,
#else /* defined(APL_OUT_TRANSFER) */
VALUE_52,
#endif /* defined(APL_OUT_TRANSFER) */
g_string_framework,
VALUE_53,
g_language_id_framework,
VALUE_2,
apl_status_change_cb);
g_ux_device_class_hid_parameter.ux_slave_class_hid_instance_activate = ux_hid_instance_activate;
g_ux_device_class_hid_parameter.ux_slave_class_hid_instance_deactivate = ux_hid_instance_deactivate;
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_report_address = g_apl_report;
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_report_length = REPORT_DESCRIPTOR_LENGTH;
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_callback = apl_hid_set_report_cb;
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_report_id = 0;
#if defined(APL_OUT_TRANSFER)
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_receiver_initialize =
ux_device_class_hid_receiver_initialize;
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_receiver_event_max_number = 16;
g_ux_device_class_hid_parameter.ux_device_class_hid_parameter_receiver_event_max_length = DATA_LEN;
#endif /* defined(APL_OUT_TRANSFER) */
ux_device_stack_class_register(_ux_system_slave_class_hid_name,
_ux_device_class_hid_entry,
1,
0x00,
(void *) &g_ux_device_class_hid_parameter);
/* Set the first key to 'a' which is 04. */
key = 0x04;
/* reset the HID event structure. */
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
err = g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS == err)
{
while (1)
{
if (USB_NO == g_suspend)
{
while (UX_NULL == g_hid)
{
/* Then wait. */
tx_thread_sleep(10);
}
/* 5sec wait */
usb_cpu_delay_xms((uint16_t) VALUE_5000);
/* Then insert a key into the keyboard event. Length is fixed to 8. */
hid_event.ux_device_class_hid_event_length = 8;
/* First byte is a modifier byte. */
hid_event.ux_device_class_hid_event_buffer[0] = 0;
/* Second byte is reserved. */
hid_event.ux_device_class_hid_event_buffer[1] = 0;
/* The 6 next bytes are keys. We only have one key here. */
hid_event.ux_device_class_hid_event_buffer[2] = key;
if (UX_NULL != g_hid)
{
/* Set the keyboard event. */
ux_device_class_hid_event_set(g_hid, &hid_event);
}
/* Next event has the key depressed. */
hid_event.ux_device_class_hid_event_buffer[2] = 0;
/* Length is fixed to 8. */
hid_event.ux_device_class_hid_event_length = 8;
if (UX_NULL != g_hid)
{
/* Set the keyboard event. */
ux_device_class_hid_event_set(g_hid, &hid_event);
/* Are we at the end of alphabet ? */
if (key != (0x04 + 26))
{
/* Next key. */
key++;
}
else
{
/* Start over again. */
key = 0x04;
}
}
#if defined(APL_OUT_TRANSFER)
if (UX_NULL != g_hid)
{
status = ux_device_class_hid_receiver_event_get(g_hid, &hid_out_event);
if (UX_SUCCESS == status)
{
for (i = 0; i < hid_out_event.ux_device_class_hid_received_event_length; i++)
{
g_out_buf[i] = *(hid_out_event.ux_device_class_hid_received_event_data + i);
}
ux_device_class_hid_receiver_event_free(g_hid);
}
}
#endif /* defined(APL_OUT_TRANSFER) */
}
else
{
if (USB_NO == g_remote_wakeup)
{
tx_thread_sleep(VALUE_10000);
/* Remote wakeup processing */
g_remote_wakeup = USB_YES;
ux_device_stack_host_wakeup();
}
}
}
}
}

USBX HHID Example

HHID user interface example is as follows.

void keyboard_update_task (ULONG thread_input)
{
ULONG usbx_return_value;
/* keyboard button masks, set by ux_host_class_hid_keyboard_buttons_get call */
ULONG keyboard_key = 0;
/* keyboard state masks, set by ux_host_class_hid_keyboard_buttons_get call */
ULONG keyboard_state = 0;
#if defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT)
UX_HOST_CLASS_HID_KEYBOARD * keyboard_instance;
ULONG i;
UX_HOST_CLASS_HID_CLIENT_REPORT client_report;
UX_HOST_CLASS_HID_REPORT hid_report;
for (i = 0; i < (OUT_DATA_LEN / 4); i++)
{
g_buf[i] = i;
}
#endif /* defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT) */
FSP_PARAMETER_NOT_USED(thread_input);
while (1)
{
if (UX_NULL != hid_keyboard_client)
{
usbx_return_value = ux_host_class_hid_keyboard_key_get(
(UX_HOST_CLASS_HID_KEYBOARD *) hid_keyboard_client->ux_host_class_hid_client_local_instance,
&keyboard_key,
&keyboard_state);
if ((usbx_return_value == UX_SUCCESS) || (usbx_return_value == UX_NO_KEY_PRESS))
{
hid_devices_info.device_connected = KEYBOARD_DEVICE;
hid_devices_info.key = keyboard_key;
hid_devices_info.keyboard_status = keyboard_state;
/* Clear the states for next read */
keyboard_key = 0;
keyboard_state = 0;
/* copy the keyboard states to queue */
tx_queue_send(&device_parameters, &hid_devices_info, TX_NO_WAIT);
#if defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT)
hid_report.ux_host_class_hid_report_id = 0;
hid_report.ux_host_class_hid_report_type = UX_HOST_CLASS_HID_REPORT_TYPE_OUTPUT;
hid_report.ux_host_class_hid_report_byte_length = OUT_DATA_LEN;
client_report.ux_host_class_hid_client_report = &hid_report;
client_report.ux_host_class_hid_client_report_buffer = g_buf;
client_report.ux_host_class_hid_client_report_length = OUT_DATA_LEN;
client_report.ux_host_class_hid_client_report_flags = UX_HOST_CLASS_HID_REPORT_RAW;
keyboard_instance =
(UX_HOST_CLASS_HID_KEYBOARD *) hid_keyboard_client->ux_host_class_hid_client_local_instance;
/* HID Out Transfer */
ux_host_class_hid_report_set((UX_HOST_CLASS_HID *) keyboard_instance->ux_host_class_hid_keyboard_hid,
&client_report);
#endif /* defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT) */
}
}
tx_thread_sleep(10);
}
}
void mouse_update_task (ULONG thread_input)
{
/* mouse button masks, set by ux_host_class_hid_mouse_buttons_get call */
ULONG mouse_buttons;
/* X co-ordinate displacement of mouse */
SLONG mouse_x_position = 0;
/* Y co-ordinate displacement of mouse */
SLONG mouse_y_position = 0;
/* variable to hold USBX return values */
ULONG usbx_return_value;
FSP_PARAMETER_NOT_USED(thread_input);
while (1)
{
if (UX_SUCCESS != hid_mouse_client)
{
usbx_return_value = ux_host_class_hid_mouse_buttons_get(
(UX_HOST_CLASS_HID_MOUSE *) hid_mouse_client->ux_host_class_hid_client_local_instance,
&mouse_buttons);
if (UX_SUCCESS == usbx_return_value)
{
usbx_return_value = ux_host_class_hid_mouse_position_get(
(UX_HOST_CLASS_HID_MOUSE *) hid_mouse_client->ux_host_class_hid_client_local_instance,
&mouse_x_position,
&mouse_y_position);
}
if (UX_SUCCESS == usbx_return_value)
{
hid_devices_info.device_connected = MOUSE_DEVICE;
hid_devices_info.key = mouse_buttons;
hid_devices_info.mouse_direction_X = mouse_x_position;
hid_devices_info.mouse_direction_Y = mouse_y_position;
tx_queue_send(&device_parameters, &hid_devices_info, TX_NO_WAIT);
}
}
tx_thread_sleep(10);
}
}
void usbx_hhid_sample (void)
{
uint8_t i;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_host_stack_initialize(ux_system_host_hid_change_function);
g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
tx_thread_create(&keyboard_update,
(CHAR *) "keyboard_update_task",
keyboard_update_task,
(ULONG) NULL,
&keyboard_update_stack,
2048,
22,
2,
1,
TX_AUTO_START);
tx_thread_create(&mouse_update,
(CHAR *) "mouse_update_task",
mouse_update_task,
(ULONG) NULL,
&mouse_update_stack,
1024,
22,
2,
1,
TX_AUTO_START);
while (1)
{
for (i = 0; i < UX_HOST_CLASS_HID_MAX_CLIENTS; i++)
{
/* Check whether the instance registered? through USB HID device insertion callback? */
if (UX_NULL != hid_class_keyboard_instance[i])
{
UX_HOST_CLASS_HID_CLIENT * hid_client = hid_class_keyboard_instance[i]->ux_host_class_hid_client;
hid_keyboard_client = hid_client;
tx_thread_sleep(10);
}
/* Check whether the instance registered? through USB HID device insertion callback? */
if (UX_NULL != hid_class_mouse_instance[i])
{
UX_HOST_CLASS_HID_CLIENT * hid_client = hid_class_mouse_instance[i]->ux_host_class_hid_client;
hid_mouse_client = hid_client;
tx_thread_sleep(10);
}
/* If multiple similar type devices are connected, allow them one by one share data with application */
tx_thread_sleep(10);
}
}
}

USBX PAUD Example

PAUD example is as follows.

#define VALUE_275 (275)
#define VALUE_226 (226)
#define VALUE_93 (93)
#define VALUE_2 (2)
#define STACK_SIZE (1024U)
#define NUM_OF_FRAME (8U)
#define USB_MAX_PACKET_SIZE_IN (200U)
#define USB_MAX_PACKET_SZIE_OUT (192U)
#define USB_APL_ON (1U)
#define USB_APL_OFF (0U)
/*** Please enable the following macro when supporting High-speed. ***/
// #define APL_AUDIO_20
/*********************************************************************/
static uint8_t g_read_buf[NUM_OF_FRAME][USB_MAX_PACKET_SZIE_OUT];
static uint8_t g_write_buf[USB_MAX_PACKET_SIZE_IN];
static UX_DEVICE_CLASS_AUDIO * volatile g_p_audio = UX_NULL;
static volatile uint8_t g_read_wp = 0U;
static volatile uint32_t g_read_alternate_setting = USB_APL_OFF;
static volatile uint32_t g_write_alternate_setting = USB_APL_OFF;
static volatile uint8_t g_apl_usb_status = USB_APL_DETACH;
#ifdef APL_AUDIO_20
static UX_DEVICE_CLASS_AUDIO20_CONTROL_GROUP g_audio20_control_group;
static UX_DEVICE_CLASS_AUDIO20_CONTROL g_audio20_control[2];
#else /* APL_AUDIO_20 */
static UX_DEVICE_CLASS_AUDIO10_CONTROL_GROUP g_audio_control_group;
static UX_DEVICE_CLASS_AUDIO10_CONTROL g_audio_control[2];
#endif /* APL_AUDIO_20 */
/******************************************************************************
* Function Name : apl_status_change_cb
* Description : USB callback function for USB status change
* Arguments : ULONG status : USB status
* Return value : UX_SUCCESS
******************************************************************************/
static UINT apl_status_change_cb (ULONG status)
{
switch (status)
{
case UX_DEVICE_ATTACHED:
{
g_apl_usb_status = USB_APL_DEFAULT;
break;
}
case UX_DEVICE_CONFIGURED:
{
g_apl_usb_status = USB_APL_CONFIGURED;
break;
}
case UX_DEVICE_REMOVED:
{
g_apl_usb_status = USB_APL_DETACH;
g_read_wp = 0U;
g_read_alternate_setting = USB_APL_OFF;
g_write_alternate_setting = USB_APL_OFF;
break;
}
case UX_DEVICE_SUSPENDED:
{
if (USB_APL_CONFIGURED == g_apl_usb_status)
{
g_apl_usb_status = USB_APL_SUSPEND;
}
break;
}
case UX_DEVICE_RESUMED:
{
if (USB_APL_SUSPEND == g_apl_usb_status)
{
g_apl_usb_status = USB_APL_CONFIGURED;
}
break;
}
default:
{
break;
}
}
return UX_SUCCESS;
}
/******************************************************************************
* End of function apl_status_change_cb
******************************************************************************/
/******************************************************************************
* Function Name : apl_audio_read_instance_activate
* Description : Get instance
* Arguments : void * p_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void apl_audio_instance_activate (void * p_instance)
{
/* Save the CDC instance. */
g_p_audio = (UX_DEVICE_CLASS_AUDIO *) p_instance;
}
/******************************************************************************
* End of function apl_audio_read_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : apl_audio_read_instance_deactivate
* Description : Clear instance
* Arguments : void * p_instance : Pointer to area store the instance pointer
* Return value : none
******************************************************************************/
static void apl_audio_instance_deactivate (void * p_instance)
{
g_p_audio = UX_NULL;
}
/******************************************************************************
* End of function apl_audio_read_instance_deactivate
******************************************************************************/
#ifdef APL_AUDIO_20
/******************************************************************************
* Function Name : apl_audio20_request_process
* Description : Audio20 Control Request Processing
* Arguments : UX_DEVICE_CLASS_AUDIO * : Pointer to Audio instance
* : UX_SLAVE_TRANSFER * : Pointer to UX_SLAVE_TRANSFER structure
* Return value : UX_SUCCESS
******************************************************************************/
static UINT apl_audio20_request_process (UX_DEVICE_CLASS_AUDIO * p_audio, UX_SLAVE_TRANSFER * p_transfer)
{
UINT ux_err;
uint8_t i;
uint8_t number;
ux_err = ux_device_class_audio20_control_process(p_audio, p_transfer, &g_audio20_control_group);
if (UX_SUCCESS == ux_err)
{
/* Request handled, check changes */
number = (uint8_t) g_audio20_control_group.ux_device_class_audio20_control_group_controls_nb;
for (i = 0; i < number; i++)
{
switch (g_audio20_control[i].ux_device_class_audio20_control_changed)
{
case UX_DEVICE_CLASS_AUDIO20_CONTROL_MUTE_CHANGED:
{
g_control_mute[i] = g_audio20_control[i].ux_device_class_audio20_control_mute[0];
break;
}
case UX_DEVICE_CLASS_AUDIO20_CONTROL_VOLUME_CHANGED:
{
g_control_volume[i] = g_audio20_control[i].ux_device_class_audio20_control_volume[0];
break;
}
default:
{
break;
}
}
}
}
return UX_SUCCESS;
}
/******************************************************************************
* End of function apl_audio20_request_process
******************************************************************************/
#else /* APL_AUDIO_20 */
/******************************************************************************
* Function Name : apl_audio10_request_process
* Description : Audio10 Control Request Processing
* Arguments : UX_DEVICE_CLASS_AUDIO * : Pointer to Audio instance
* : UX_SLAVE_TRANSFER * : Pointer to UX_SLAVE_TRANSFER structure
* Return value : UX_SUCCESS
******************************************************************************/
static UINT apl_audio10_request_process (UX_DEVICE_CLASS_AUDIO * p_audio, UX_SLAVE_TRANSFER * p_transfer)
{
UINT ux_err;
uint8_t i;
uint8_t number;
ux_err = ux_device_class_audio10_control_process(p_audio, p_transfer, &g_audio_control_group);
if (UX_SUCCESS == ux_err)
{
/* Request handled, check changes */
number = (uint8_t) g_audio_control_group.ux_device_class_audio10_control_group_controls_nb;
for (i = 0; i < number; i++)
{
switch (g_audio_control[i].ux_device_class_audio10_control_changed)
{
case UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED:
{
g_control_mute[i] = g_audio_control[i].ux_device_class_audio10_control_mute[0];
break;
}
case UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED:
{
g_control_volume[i] = g_audio_control[i].ux_device_class_audio10_control_volume[0];;
break;
}
default:
{
break;
}
}
}
}
return UX_SUCCESS;
}
/******************************************************************************
* End of function apl_audio10_request_process
******************************************************************************/
#endif /* APL_AUDIO_20 */
/******************************************************************************
* Function Name : apl_audio_read_change
* Description : Callback function called when switching alternate setting value of OUT transfer
* Arguments : UX_DEVICE_CLASS_AUDIO_STREAM * : Pointer to UX_DEVICE_CLASS_AUDIO_STREAM structure
* : ULONG : Alternate Setting Value
* Return value : UX_SUCCESS
******************************************************************************/
static void apl_audio_read_change (UX_DEVICE_CLASS_AUDIO_STREAM * p_stream, ULONG alternate_setting)
{
UINT ux_err;
if (USB_APL_ON == alternate_setting)
{
ux_device_class_audio_reception_start(p_stream);
}
else
{
if (USB_APL_ON == g_read_alternate_setting)
{
/* Alternate Setting 1 --> 0 */
g_read_wp = 0U;
}
}
g_read_alternate_setting = alternate_setting;
}
/******************************************************************************
* End of function apl_audio_read_change
******************************************************************************/
/******************************************************************************
* Function Name : apl_audio_read_done
* Description : Callback function called when completing of OUT transfer reception
* Arguments : UX_DEVICE_CLASS_AUDIO_STREAM * : Pointer to UX_DEVICE_CLASS_AUDIO_STREAM structure
* : ULONG : Actual Length
* Return value : UX_SUCCESS
******************************************************************************/
static void apl_audio_read_done (UX_DEVICE_CLASS_AUDIO_STREAM * p_stream, ULONG actual_length)
{
UINT ux_err;
UCHAR * p_buffer;
ULONG length;
UINT i;
FSP_PARAMETER_NOT_USED(actual_length);
if (USB_APL_ON == g_read_alternate_setting)
{
ux_err = ux_device_class_audio_read_frame_get(p_stream, &p_buffer, &length);
if (UX_SUCCESS == ux_err)
{
for (i = 0; i < length; i++)
{
g_read_buf[g_read_wp][i] = *(p_buffer + i);
}
g_read_wp++;
g_read_wp %= NUM_OF_FRAME;
ux_device_class_audio_read_frame_free(p_stream);
}
}
}
/******************************************************************************
* End of function apl_audio_read_done
******************************************************************************/
/******************************************************************************
* Function Name : apl_audio_write_change
* Description : Callback function called when switching alternate setting value of IN transfer
* Arguments : UX_DEVICE_CLASS_AUDIO_STREAM * : Pointer to UX_DEVICE_CLASS_AUDIO_STREAM structure
* : ULONG : Alternate Setting Value
* Return value : UX_SUCCESS
******************************************************************************/
static void apl_audio_write_change (UX_DEVICE_CLASS_AUDIO_STREAM * p_stream, ULONG alternate_setting)
{
UINT ux_err;
if (USB_APL_ON == alternate_setting)
{
ux_err = ux_device_class_audio_frame_write(p_stream, g_write_buf, USB_MAX_PACKET_SIZE_IN);
if (UX_SUCCESS == ux_err)
{
ux_device_class_audio_transmission_start(p_stream);
}
}
g_write_alternate_setting = alternate_setting;
}
/******************************************************************************
* End of function apl_audio_write_change
******************************************************************************/
/******************************************************************************
* Function Name : apl_audio_write_done
* Description : Callback function called when completing of IN transfer transmission
* Arguments : UX_DEVICE_CLASS_AUDIO_STREAM * : Pointer to UX_DEVICE_CLASS_AUDIO_STREAM structure
* : ULONG : Actual Length
* Return value : None
******************************************************************************/
static void apl_audio_write_done (UX_DEVICE_CLASS_AUDIO_STREAM * p_stream, ULONG actual_length)
{
FSP_PARAMETER_NOT_USED(actual_length);
if (USB_APL_ON == g_write_alternate_setting)
{
ux_device_class_audio_frame_write(p_stream, g_write_buf, USB_MAX_PACKET_SIZE_IN);
}
}
/******************************************************************************
* End of function apl_audio_write_done
******************************************************************************/
/******************************************************************************
* Function Name : usbx_paudio_apl_init
* Description : Initialization processing
* Arguments : None
* Return value : None
******************************************************************************/
void usbx_paudio_apl_init (void)
{
fsp_err_t err;
UINT ux_err;
uint16_t i = 0;
UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER audio_stream_parameter[2];
UX_DEVICE_CLASS_AUDIO_PARAMETER audio_parameter;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
ux_device_stack_initialize(g_device_framework_hi_speed,
VALUE_275,
g_device_framework_full_speed,
VALUE_226,
g_string_framework,
VALUE_93,
g_language_id_framework,
VALUE_2,
apl_status_change_cb);
/* Read Initialization */
audio_stream_parameter[0].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_change =
apl_audio_read_change;
audio_stream_parameter[0].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_frame_done =
apl_audio_read_done;
audio_stream_parameter[0].ux_device_class_audio_stream_parameter_thread_stack_size = STACK_SIZE;
audio_stream_parameter[0].ux_device_class_audio_stream_parameter_max_frame_buffer_nb = NUM_OF_FRAME;
audio_stream_parameter[0].ux_device_class_audio_stream_parameter_max_frame_buffer_size = USB_MAX_PACKET_SZIE_OUT;
audio_stream_parameter[0].ux_device_class_audio_stream_parameter_thread_entry =
ux_device_class_audio_read_thread_entry;
/* Write Initialization */
audio_stream_parameter[1].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_change =
apl_audio_write_change;
audio_stream_parameter[1].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_frame_done =
apl_audio_write_done;
audio_stream_parameter[1].ux_device_class_audio_stream_parameter_thread_stack_size = STACK_SIZE;
audio_stream_parameter[1].ux_device_class_audio_stream_parameter_max_frame_buffer_nb = NUM_OF_FRAME;
audio_stream_parameter[1].ux_device_class_audio_stream_parameter_max_frame_buffer_size = USB_MAX_PACKET_SIZE_IN;
audio_stream_parameter[1].ux_device_class_audio_stream_parameter_thread_entry =
ux_device_class_audio_write_thread_entry;
audio_parameter.ux_device_class_audio_parameter_callbacks.ux_slave_class_audio_instance_activate =
apl_audio_instance_activate;
audio_parameter.ux_device_class_audio_parameter_callbacks.ux_slave_class_audio_instance_deactivate =
apl_audio_instance_deactivate;
audio_parameter.ux_device_class_audio_parameter_callbacks.ux_device_class_audio_control_process
#ifdef APL_AUDIO_20
= apl_audio20_request_process;
#else
= apl_audio10_request_process;
#endif
audio_parameter.ux_device_class_audio_parameter_streams_nb = 2;
audio_parameter.ux_device_class_audio_parameter_streams = &audio_stream_parameter[0];
ux_err =
ux_device_stack_class_register(_ux_system_slave_class_audio_name,
_ux_device_class_audio_entry,
1,
0x00,
(void *) &audio_parameter);
if (UX_SUCCESS != ux_err)
{
USB_APL_AUDIO_ERROR();
}
#ifdef APL_AUDIO_20
g_audio20_control[0].ux_device_class_audio20_control_cs_id = 0x10;
g_audio20_control[0].ux_device_class_audio20_control_sampling_frequency = 48000;
g_audio20_control[0].ux_device_class_audio20_control_fu_id = 5;
g_audio20_control[0].ux_device_class_audio20_control_mute[0] = 0;
g_audio20_control[0].ux_device_class_audio20_control_volume_min[0] = 0;
g_audio20_control[0].ux_device_class_audio20_control_volume_max[0] = 100;
g_audio20_control[0].ux_device_class_audio20_control_volume[0] = 50;
g_audio20_control[1].ux_device_class_audio20_control_cs_id = 0x10;
g_audio20_control[1].ux_device_class_audio20_control_sampling_frequency = 48000;
g_audio20_control[1].ux_device_class_audio20_control_fu_id = 8;
g_audio20_control[1].ux_device_class_audio20_control_mute[0] = 0;
g_audio20_control[1].ux_device_class_audio20_control_volume_min[0] = 0;
g_audio20_control[1].ux_device_class_audio20_control_volume_max[0] = 200;
g_audio20_control[1].ux_device_class_audio20_control_volume[0] = 100;
g_audio20_control_group.ux_device_class_audio20_control_group_controls_nb = 2;
g_audio20_control_group.ux_device_class_audio20_control_group_controls = &g_audio20_control[0];
#else /* APL_AUDIO_20 */
g_audio_control[0].ux_device_class_audio10_control_fu_id = 5;
g_audio_control[0].ux_device_class_audio10_control_mute[0] = 0;
g_audio_control[0].ux_device_class_audio10_control_volume[0] = 0;
g_audio_control[0].ux_device_class_audio10_control_volume_min[0] = 0;
g_audio_control[0].ux_device_class_audio10_control_volume_max[0] = 0x80;
g_audio_control[0].ux_device_class_audio10_control_volume_res[0] = 0x40;
g_audio_control[1].ux_device_class_audio10_control_fu_id = 8;
g_audio_control[1].ux_device_class_audio10_control_mute[0] = 0x10;
g_audio_control[1].ux_device_class_audio10_control_volume[0] = 0x00;
g_audio_control[1].ux_device_class_audio10_control_volume_min[0] = 0;
g_audio_control[1].ux_device_class_audio10_control_volume_max[0] = 0xF0;
g_audio_control[1].ux_device_class_audio10_control_volume_res[0] = 0x80;
g_audio_control_group.ux_device_class_audio10_control_group_controls_nb = 2;
g_audio_control_group.ux_device_class_audio10_control_group_controls = &g_audio_control[0];
#endif /* APL_AUDIO_20 */
for (i = 0; i < USB_MAX_PACKET_SIZE_IN; i++)
{
g_write_buf[i] = (UCHAR) (i & 0xFF);
}
err = g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
USB_APL_AUDIO_ERROR();
}
}
/******************************************************************************
* End of function usbx_paudio_apl_init
******************************************************************************/
/******************************************************************************
* Function Name : usbx_paudio_apl
* Description : Application task for USB Audio
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_paud_sample (void)
{
usbx_paudio_apl_init();
while (1)
{
switch (g_apl_usb_status)
{
case USB_APL_CONFIGURED:
{
/* Application Processing */
break;
}
case USB_APL_DETACH:
{
break;
}
case USB_APL_SUSPEND:
{
break;
}
default:
{
break;
}
}
}
}

USBX PPRN Example

PPRN example is as follows.

Note: Define "2" to "DEMO_PROTOCOL" macro when supporting IN transfer and define "1" to "DEMO_PROTOCOL" macro when not supporting IN transfer.

/******************************************************************************
* Macro definitions
******************************************************************************/
#define DEMO_PROTOCOL (1U) /* 1-Uni-dir, 2-Bi-dir */
#define DEMO_STACK_SIZE 1024
/* USBx device configuration settings */
#define DEVICE_FRAME_LENGTH_HIGH_SPEED (53U) + ((DEMO_PROTOCOL > 1) ? 7 : 0) /* Length of g_device_framework_hi_speed[] */
#define DEVICE_FRAME_LENGTH_FULL_SPEED (43U) + ((DEMO_PROTOCOL > 1) ? 7 : 0) /* Length of g_device_framework_full_speed[] */
#define STRING_FRAMEWORK_LENGTH (53U) /* Length of g_string_framework[]. If edit g_string_framework[], need to change this value. */
#define LANGUAGE_ID_FRAME_WORK_LENGTH (2U)
#define CONFIG_NUMB (1U)
#define INTERFACE_NUMB0 (0x00)
#define INTERFACE_NUMB1 (0x01)
#define MEMPOOL_SIZE (18432U)
#define BYTE_SIZE (4U)
#define DATA_LEN (512U)
#define MAX_PACKET_SIZE_HS (512U)
#define MAX_PACKET_SIZE_FS (64U)
#define PRINTER_DEVICE_ID_LENGTH (91U) /* Length of printer_device_id[]. If edit printer_device_id[], need to change this value. */
/******************************************************************************
* Exported global variables and functions (to be accessed by other files)
******************************************************************************/
extern uint8_t g_device_framework_full_speed[];
extern uint8_t g_device_framework_hi_speed[];
extern uint8_t g_string_framework[];
extern uint8_t g_language_id_framework[];
extern uint8_t printer_device_id[];
static union _PRINTER_PORT_STATUS
{
struct
{
uint8_t reserved : 3;
uint8_t not_error : 1;
uint8_t select : 1;
uint8_t paper_empty : 1;
} bm;
uint8_t value;
} device_printer_port_status;
static struct TEST_DATA_STRUCT
{
uint32_t mem_usage_max;
uint32_t mem_usage;
} test_data = {0, 0};
/******************************************************************************
* Global functions and variables
******************************************************************************/
extern uint32_t usb_peri_usbx_initialize(uint32_t dcd_io);
/******************************************************************************
* Private global variables and functions
******************************************************************************/
static void ux_printer_instance_activate(void * printer_instance);
static void ux_printer_instance_deactivate(void * printer_instance);
static void ux_printer_soft_reset(void * printer_instance);
/* Mempool size of 18k is required for USBX device class pre built libraries
* and it is valid only if it with default USBX configurations. */
static uint32_t g_ux_pool_memory[(MEMPOOL_SIZE + DEMO_STACK_SIZE * 3) / BYTE_SIZE];
static UX_DEVICE_CLASS_PRINTER_PARAMETER device_printer_parameter;
static UX_DEVICE_CLASS_PRINTER * device_printer = UX_NULL;
static uint8_t device_printer_buffer[DATA_LEN];
uint8_t _ux_system_slave_class_prn_name[] = "ux_device_class_printer";
/* Define local function prototypes. */
void demo_thread_entry(uint32_t thread_input);
void printer_read_thread_entry(uint32_t thread_input);
void printer_write_thread_entry(uint32_t thread_input);
/* Define global data structures. */
static TX_THREAD demo_thread;
static TX_THREAD printer_read_thread;
#if DEMO_PROTOCOL > 1
static TX_THREAD printer_write_thread;
#endif
/******************************************************************************
* Function Name : ux_printer_instance_activate
* Description : Get instance
* Arguments : void * printer_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_printer_instance_activate (void * printer_instance)
{
if (device_printer == UX_NULL)
{
device_printer = (UX_DEVICE_CLASS_PRINTER *) printer_instance;
ux_device_class_printer_ioctl(device_printer,
UX_DEVICE_CLASS_PRINTER_IOCTL_PORT_STATUS_SET,
(void *) device_printer_port_status.value);
}
}
/******************************************************************************
* End of function ux_printer_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_printer_instance_deactivate
* Description : Clear instance
* Arguments : void * printer_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_printer_instance_deactivate (void * printer_instance)
{
if ((void *) device_printer == printer_instance)
{
device_printer = UX_NULL;
}
}
/******************************************************************************
* End of function ux_printer_instance_deactivate
******************************************************************************/
/******************************************************************************
* Function Name : ux_printer_soft_reset
* Description : This function does nothing in particular.
* Arguments : void * printer_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_printer_soft_reset (void * printer_instance)
{
}
/******************************************************************************
* End of function ux_printer_soft_reset
******************************************************************************/
/******************************************************************************
* Function Name : usbx_pprn_sample
* Description : Initialization for Peripheral Printer
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_pprn_sample (void)
{
/* To check ux api return status */
UINT status = UX_SUCCESS;
/* To check fsp api return status */
fsp_err_t err = FSP_SUCCESS;
uint8_t * stack_pointer;
uint8_t * memory_pointer;
/* ux_system_initialization */
stack_pointer = (uint8_t *) g_ux_pool_memory;
memory_pointer = stack_pointer + DEMO_STACK_SIZE * 3;
ux_system_initialize(memory_pointer, MEMPOOL_SIZE, UX_NULL, 0x00);
/* ux_device stack initialization */
ux_device_stack_initialize(g_device_framework_hi_speed,
DEVICE_FRAME_LENGTH_HIGH_SPEED,
g_device_framework_full_speed,
DEVICE_FRAME_LENGTH_FULL_SPEED,
g_string_framework,
STRING_FRAMEWORK_LENGTH,
g_language_id_framework,
LANGUAGE_ID_FRAME_WORK_LENGTH,
UX_NULL);
/* Set the parameters for callback when insertion/extraction of a printer device. */
_ux_utility_memory_set(&device_printer_parameter, 0, sizeof(device_printer_parameter));
_ux_utility_short_put_big_endian(printer_device_id, PRINTER_DEVICE_ID_LENGTH);
device_printer_port_status.value = UX_DEVICE_CLASS_PRINTER_SELECT | UX_DEVICE_CLASS_PRINTER_NOT_ERROR;
device_printer_parameter.ux_device_class_printer_device_id = printer_device_id;
device_printer_parameter.ux_device_class_printer_instance_activate = ux_printer_instance_activate;
device_printer_parameter.ux_device_class_printer_instance_deactivate = ux_printer_instance_deactivate;
device_printer_parameter.ux_device_class_printer_soft_reset = ux_printer_soft_reset;
/* ux_device stack class registration */
ux_device_stack_class_register(_ux_system_slave_class_prn_name,
_ux_device_class_printer_entry,
CONFIG_NUMB,
INTERFACE_NUMB0,
(void *) &device_printer_parameter);
/* Open usb driver */
R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
/* Create the main demo thread. */
tx_thread_create(&demo_thread,
"tx demo",
demo_thread_entry,
0,
stack_pointer,
DEMO_STACK_SIZE,
20,
20,
1,
TX_AUTO_START);
stack_pointer += DEMO_STACK_SIZE;
/* Create the printer read thread. */
tx_thread_create(&printer_read_thread,
"read_thread",
printer_read_thread_entry,
0,
stack_pointer,
DEMO_STACK_SIZE,
20,
20,
1,
TX_AUTO_START);
stack_pointer += DEMO_STACK_SIZE;
#if DEMO_PROTOCOL > 1
/* Create the main demo thread. */
tx_thread_create(&printer_write_thread,
"write_thread",
printer_write_thread_entry,
0,
stack_pointer,
DEMO_STACK_SIZE,
20,
20,
1,
TX_AUTO_START);
#endif
}
/******************************************************************************
* End of function usbx_pprn_sample
******************************************************************************/
/******************************************************************************
* Function Name : apl_mem_usage_update
* Description : Update memory usage
* Arguments : none
* Return value : none
******************************************************************************/
static void apl_mem_usage_update (void)
{
uint32_t mem_total;
/* Update memory usage. */
mem_total = _ux_system->ux_system_regular_memory_pool_size + (uint32_t) (
(uint8_t *) _ux_system->ux_system_regular_memory_pool_start -
(uint8_t *) _ux_system);
test_data.mem_usage = mem_total - _ux_system->ux_system_regular_memory_pool_free;
#ifdef UX_ENABLE_MEMORY_STATISTICS
test_data.mem_usage_max = mem_total - _ux_system->ux_system_regular_memory_pool_min_free;
#else /* Not accurate, there could be alloc/free between checks. */
if (test_data.mem_usage > test_data.mem_usage_max)
{
test_data.mem_usage_max = test_data.mem_usage;
}
#endif
}
/******************************************************************************
* End of function apl_mem_usage_update
******************************************************************************/
/******************************************************************************
* Function Name : apl_minus
* Description : Adjust timer
* Arguments : uint32_t v_origin
* : uint32_t v_minus
* : uint32_t wrap
* Return value : Adjusted Tick Value
******************************************************************************/
static uint32_t apl_minus (uint32_t v_origin, uint32_t v_minus, uint32_t wrap)
{
if (v_origin >= v_minus)
{
return v_origin - v_minus;
}
else
{
return v_origin + (wrap - v_minus);
}
}
/******************************************************************************
* End of function apl_mem_usage_update
******************************************************************************/
/******************************************************************************
* Function Name : demo_thread_entry
* Description : Printer Demo Thread
* Arguments : uint32_t thread_input
* Return value : none
******************************************************************************/
void demo_thread_entry (uint32_t thread_input)
{
uint32_t tick0, tick1, diff;
uint32_t pmem = 0;
uint8_t port_status = device_printer_port_status.value;
/* Not currently using thread_input. */
FSP_PARAMETER_NOT_USED(thread_input);
/* Standalone stack: run tasks in application thread loop. */
while (1)
{
/* Update memory usage. */
apl_mem_usage_update();
/* Let other threads to run. */
tx_thread_sleep(1);
/* Do status change check. */
if (device_printer &&
(port_status != device_printer_port_status.value))
{
ux_device_class_printer_ioctl(device_printer,
UX_DEVICE_CLASS_PRINTER_IOCTL_PORT_STATUS_SET,
(void *) device_printer_port_status.value);
port_status = device_printer_port_status.value;
}
/* Check time passed and update speed every 1s. */
tick1 = tx_time_get();
diff = apl_minus(tick1, tick0, 0xFFFFFFFF);
if (diff < TX_TIMER_TICKS_PER_SECOND)
{
continue;
}
tick0 = tick1;
/* Print results. */
if ((pmem != test_data.mem_usage_max))
{
pmem = test_data.mem_usage_max;
}
}
}
/******************************************************************************
* End of function demo_thread_entry
******************************************************************************/
/******************************************************************************
* Function Name : printer_read_thread_entry
* Description : USB read operation and echo back the first part of user input on serial terminal.
* Arguments : uint32_t thread_input
* Return value : none
******************************************************************************/
void printer_read_thread_entry (uint32_t thread_input)
{
UINT status;
uint32_t actual_length;
UINT i;
/* Not currently using thread_input. */
FSP_PARAMETER_NOT_USED(thread_input);
while (1)
{
if (device_printer == UX_NULL)
{
/* Wait a while before next check. */
tx_thread_sleep(10);
continue;
}
status = ux_device_class_printer_read(device_printer, device_printer_buffer, DATA_LEN, &actual_length);
if (status != UX_SUCCESS)
{
continue;
}
if (actual_length == 0)
{
continue;
}
}
}
/******************************************************************************
* End of function printer_read_thread_entry
******************************************************************************/
/******************************************************************************
* Function Name : printer_write_thread_entry
* Description : Periodically checks the printer status.
* Arguments : uint32_t thread_input
* Return value : none
******************************************************************************/
void printer_write_thread_entry (uint32_t thread_input)
{
uint8_t port_status = device_printer_port_status.value;
/* Not currently using thread_input. */
FSP_PARAMETER_NOT_USED(thread_input);
while (1)
{
/* Wait 2s. */
tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND * 2);
if (device_printer &&
(port_status != device_printer_port_status.value))
{
/* Send status and other information here. */
port_status = device_printer_port_status.value;
}
}
}

USBX HPRN Example

HPRN example is as follows.

#include "r_usb_basic.h"
#include "r_usb_basic_cfg.h"
#include "ux_api.h"
#include "ux_system.h"
#include "ux_host_class_printer.h"
/******************************************************************************
* Macro definitions
*****************************************************************************/
#define DATA_LEN (1030U)
#define MAX_REQUEST_SIZE (2048U)
#define MEMPOOL_SIZE (18432)
#define HPRN_FLAG ((uint32_t) 0x0001)
#define VALUE_4 (4)
#define MOD_VAL (50)
#define READ_LEN (64)
#define WAIT_TIME (50)
#define SUCCESS (0U)
#define UX_FSP_DEVICE_INSERTION (0x01U)
#define UX_FSP_DEVICE_REMOVAL (0x02U)
#define RESET_VALUE (0x00)
/* Private function */
static UINT ux_host_usr_event_notification(ULONG event, UX_HOST_CLASS * host_class, VOID * instance);
/* A pointer to store Printer instance. */
static UX_HOST_CLASS_PRINTER * p_printer = UX_NULL;
static ULONG g_write_actual_length = RESET_VALUE;
static ULONG g_read_actual_length = RESET_VALUE;
static uint8_t g_read_buf[DATA_LEN] = {RESET_VALUE};
static uint8_t g_read_buf1[DATA_LEN] = {RESET_VALUE};
static uint8_t g_write_buf[DATA_LEN] = {RESET_VALUE};
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / VALUE_4];
/* HPRN Thread entry function */
void hprn_thread_entry (void)
{
uint32_t status = RESET_VALUE;
ULONG actual_flags = RESET_VALUE;
uint16_t count = RESET_VALUE;
ULONG port_status = RESET_VALUE;
/* ux_system_initialization */
ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
/* ux host stack initialization */
ux_host_stack_initialize(ux_host_usr_event_notification);
/* Open usb driver */
R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
/*Fill the write buffer*/
for (count = RESET_VALUE; count < DATA_LEN; count++)
{
g_write_buf[count] = (uint8_t) count;
}
while (true)
{
/* retrieves event flags from the specified event flags group.*/
tx_event_flags_get(&g_printer_activate_event_flags0, HPRN_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
if (UX_NULL != p_printer)
{
/* GET_PORT_STATUS */
ux_host_class_printer_status_get(p_printer, &port_status);
/*Send the data to device*/
ux_host_class_printer_write(p_printer, g_write_buf, DATA_LEN, &g_write_actual_length);
/* Clear the buffer */
memset(g_read_buf, RESET_VALUE, sizeof(g_read_buf));
/* USB receives the data echoed back */
ux_host_class_printer_read(p_printer, g_read_buf, MAX_REQUEST_SIZE, &g_read_actual_length);
/*compare loop-back data*/
if (SUCCESS != (memcmp(g_read_buf, g_write_buf, sizeof(g_read_buf))))
{
return;
}
tx_thread_sleep(WAIT_TIME);
}
}
}
static UINT ux_host_usr_event_notification (ULONG event, UX_HOST_CLASS * host_class, VOID * instance)
{
if (_ux_utility_memory_compare(_ux_system_host_class_printer_name, host_class,
_ux_utility_string_length_get(_ux_system_host_class_printer_name)) ==
UX_SUCCESS)
{
/* Check if there is a device insertion. */
if (UX_FSP_DEVICE_INSERTION == event)
{
p_printer = (UX_HOST_CLASS_PRINTER *) instance;
if (UX_NULL != p_printer)
{
/* This sets or clears event flags in an event flags group */
tx_event_flags_set(&g_printer_activate_event_flags0, HPRN_FLAG, TX_OR);
}
}
/* Check if there is a device removal */
else if (UX_FSP_DEVICE_REMOVAL == event)
{
/* This sets or clears event flags in an event flags group */
tx_event_flags_set(&g_printer_activate_event_flags0, ~HPRN_FLAG, TX_AND);
p_printer = UX_NULL;
}
else
{
/*do nothing */
}
}
return UX_SUCCESS;
}

USBX HUVC Example

HUVC example is as follows.

/***********************************************************************************************************************
* Macro definitions
***********************************************************************************************************************/
#define RESET_VALUE (0x00)
#define MEMPOOL_SIZE (18432)
#define VALUE_4 (4)
#define EVENTFLAG_USB_DEVICE_INSERTED (0x01)
/* Define the number of buffers used in this demo. */
#define MAX_NUM_BUFFERS 2
#define USBFS_ISO_PIPE_MAX_PAKCET_SIZE (256)
/***********************************************************************************************************************
* Private function prototypes
***********************************************************************************************************************/
VOID uvc_transfer_request_done_callback(UX_TRANSFER * transfer_request);
VOID uvc_parameter_interval_list(UX_HOST_CLASS_VIDEO * video);
UINT uvc_parameter_frame_list(UX_HOST_CLASS_VIDEO * video);
VOID uvc_parameter_list(UX_HOST_CLASS_VIDEO * video);
VOID uvc_process_function(UX_HOST_CLASS_VIDEO * video);
UINT ux_host_usr_event_notification(ULONG event, UX_HOST_CLASS * host_class, VOID * instance);
/***********************************************************************************************************************
* Private global variables
***********************************************************************************************************************/
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / VALUE_4];
/* video class instance */
UX_HOST_CLASS_VIDEO * volatile video_host_class;
TX_EVENT_FLAGS_GROUP g_device_insert_eventflag;
TX_SEMAPHORE g_data_received_semaphore;
/* video buffer */
UCHAR g_video_buffer[10 * 1024];
/* Name string of VS types */
struct
{
int type;
char * name;
} vs_type_name[] =
{
{UX_HOST_CLASS_VIDEO_VS_UNDEFINED, "UX_HOST_CLASS_VIDEO_VS_UNDEFINED" },
{UX_HOST_CLASS_VIDEO_VS_INPUT_HEADER, "UX_HOST_CLASS_VIDEO_VS_INPUT_HEADER" },
{UX_HOST_CLASS_VIDEO_VS_OUTPUT_HEADER, "UX_HOST_CLASS_VIDEO_VS_OUTPUT_HEADER" },
{UX_HOST_CLASS_VIDEO_VS_STILL_IMAGE_FRAME, "UX_HOST_CLASS_VIDEO_VS_STILL_IMAGE_FRAME" },
{UX_HOST_CLASS_VIDEO_VS_FORMAT_UNCOMPRESSED, "UX_HOST_CLASS_VIDEO_VS_FORMAT_UNCOMPRESSED" },
{UX_HOST_CLASS_VIDEO_VS_FRAME_UNCOMPRESSED, "UX_HOST_CLASS_VIDEO_VS_FRAME_UNCOMPRESSED" },
{UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG, "UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG" },
{UX_HOST_CLASS_VIDEO_VS_FRAME_MJPEG, "UX_HOST_CLASS_VIDEO_VS_FRAME_MJPEG" },
{UX_HOST_CLASS_VIDEO_VS_FORMAT_MPEG2TS, "UX_HOST_CLASS_VIDEO_VS_FORMAT_MPEG2TS" },
{UX_HOST_CLASS_VIDEO_VS_FORMAT_DV, "UX_HOST_CLASS_VIDEO_VS_FORMAT_DV" },
{UX_HOST_CLASS_VIDEO_VS_COLORFORMAT, "UX_HOST_CLASS_VIDEO_VS_COLORFORMAT" },
{UX_HOST_CLASS_VIDEO_VS_FORMAT_FRAME_BASED, "UX_HOST_CLASS_VIDEO_VS_FORMAT_FRAME_BASED" },
{UX_HOST_CLASS_VIDEO_VS_FRAME_FRAME_BASED, "UX_HOST_CLASS_VIDEO_VS_FRAME_FRAME_BASED" },
{UX_HOST_CLASS_VIDEO_VS_FORMAT_STREAM_BASED, "UX_HOST_CLASS_VIDEO_VS_FORMAT_STREAM_BASED" }
};
/* HUVC Thread entry function */
void usbx_huvc_sample (void)
{
uint32_t status = RESET_VALUE;
ULONG actual_flags = RESET_VALUE;
fsp_err_t err = FSP_SUCCESS;
/* ux_system_initialization */
status = ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
if (UX_SUCCESS != status)
{
while (1)
{
;
}
}
/* ux host stack initialization */
status = ux_host_stack_initialize(ux_host_usr_event_notification);
if (UX_SUCCESS != status)
{
while (1)
{
;
}
}
/* Open usb driver */
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
tx_event_flags_create(&g_device_insert_eventflag, (CHAR *) "Device Insert Event Flags");
tx_semaphore_create(&g_data_received_semaphore, "payload semaphore", 0);
while (1)
{
/* Suspend here until a USBX Host Class Instance gets ready. */
tx_event_flags_get(&g_device_insert_eventflag,
EVENTFLAG_USB_DEVICE_INSERTED,
TX_OR,
(ULONG *) &actual_flags,
TX_WAIT_FOREVER);
/* This delay is required for now to get valid ISO IN UX_ENDPOINT instance. */
tx_thread_sleep(100);
if (UX_NULL != video_host_class)
{
uvc_process_function(video_host_class);
}
}
}
/* USBX Host event notification callback function */
UINT ux_host_usr_event_notification (ULONG event, UX_HOST_CLASS * host_class, VOID * instance)
{
if (UX_SUCCESS ==
_ux_utility_memory_compare(_ux_system_host_class_video_name, host_class,
_ux_utility_string_length_get(_ux_system_host_class_video_name)))
{
if (UX_DEVICE_INSERTION == event) /* Check if there is a device insertion. */
{
video_host_class = instance;
/* Set the event flag to let application know the device insertion. */
tx_event_flags_set(&g_device_insert_eventflag, EVENTFLAG_USB_DEVICE_INSERTED, TX_OR);
}
else if (UX_DEVICE_REMOVAL == event)
{
/* Clear the event flag in case the camera was removed before the application could clear it. */
tx_event_flags_set(&g_device_insert_eventflag, (ULONG) ~EVENTFLAG_USB_DEVICE_INSERTED, TX_AND);
video_host_class = NULL;
}
}
return UX_SUCCESS;
}
/* Video data received callback function. */
VOID uvc_transfer_request_done_callback (UX_TRANSFER * transfer_request)
{
/* This is the callback function invoked by UVC class after a packet of
* data is received. */
/* The actual number of bytes being received into the data buffer is
* recorded in tranfer_request -> ux_transfer_request_actual_length. */
/* Since this callback function executes in the USB host controller
* thread, a semaphore is released so the application can pick up the
* video data in application thread. */
FSP_PARAMETER_NOT_USED(transfer_request);
tx_semaphore_put(&g_data_received_semaphore);
}
/* Show the interval types */
VOID uvc_parameter_interval_list (UX_HOST_CLASS_VIDEO * video)
{
UX_HOST_CLASS_VIDEO_FRAME_DESCRIPTOR frame_descriptor;
ULONG min_frame_interval;
ULONG max_frame_interval;
ULONG frame_interval_step;
int i;
/* Make the descriptor machine independent. */
_ux_utility_descriptor_parse(video->ux_host_class_video_current_frame_address,
_ux_system_class_video_frame_descriptor_structure,
UX_HOST_CLASS_VIDEO_FRAME_DESCRIPTOR_ENTRIES,
(UCHAR *) &frame_descriptor);
/* Check the frame interval type. */
if (0 == frame_descriptor.bFrameIntervalType)
{
/* Frame interval type is continuous. */
min_frame_interval = _ux_utility_long_get(video->ux_host_class_video_current_frame_address + 26);
max_frame_interval = _ux_utility_long_get(video->ux_host_class_video_current_frame_address + 30);
frame_interval_step = _ux_utility_long_get(video->ux_host_class_video_current_frame_address + 34);
FSP_PARAMETER_NOT_USED(min_frame_interval);
FSP_PARAMETER_NOT_USED(max_frame_interval);
FSP_PARAMETER_NOT_USED(frame_interval_step);
}
}
/* Show the frame resolutions */
UINT uvc_parameter_frame_list (UX_HOST_CLASS_VIDEO * video)
{
ULONG frame_index;
UX_HOST_CLASS_VIDEO_PARAMETER_FRAME_DATA frame_parameter;
UINT status = UX_SUCCESS;
/* frame resolutions */
for (frame_index = 1; frame_index <= video->ux_host_class_video_number_frames; frame_index++)
{
/* Get frame data for current frame index. */
frame_parameter.ux_host_class_video_parameter_frame_requested = frame_index;
status = _ux_host_class_video_frame_data_get(video, &frame_parameter);
if (UX_SUCCESS != status)
{
return status;
}
/* Save the current frame index. */
video->ux_host_class_video_current_frame = frame_index;
uvc_parameter_interval_list(video);
}
return status;
}
/* Show the device parameters */
VOID uvc_parameter_list (UX_HOST_CLASS_VIDEO * video)
{
ULONG format_index;
UX_HOST_CLASS_VIDEO_PARAMETER_FORMAT_DATA format_parameter;
UINT status = UX_SUCCESS;
int i;
/* format types */
for (format_index = 1; format_index <= video->ux_host_class_video_number_formats; format_index++)
{
/* Get format data for current format index. */
format_parameter.ux_host_class_video_parameter_format_requested = format_index;
status = _ux_host_class_video_format_data_get(video, &format_parameter);
if (UX_SUCCESS == status)
{
/* Save number of frames in the video instance. */
video->ux_host_class_video_number_frames =
format_parameter.ux_host_class_video_parameter_number_frame_descriptors;
uvc_parameter_frame_list(video);
}
}
}
VOID uvc_process_function (UX_HOST_CLASS_VIDEO * video)
{
/* This demo uses two buffers. One buffer is used by video device while the
* application consumes data in the other buffer. */
UCHAR * buffer_ptr[MAX_NUM_BUFFERS];
/* Index variable keeping track of the current buffer being used by the video device. */
ULONG buffer_index;
/* Maximum buffer requirement reported by the video device. */
ULONG max_buffer_size;
UINT status;
ULONG actual_flags;
UINT frame_count;
UX_HOST_CLASS_VIDEO_PARAMETER_CHANNEL channel;
/* List parameters */
uvc_parameter_list(video);
/* Set video parameters. This setting value is a dummy.
* Depending on the application, set the necessary parameters. */
status = ux_host_class_video_frame_parameters_set(video, UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG, 176, 144, 333333);
/* Set the user callback function of video class. */
ux_host_class_video_transfer_callback_set(video, uvc_transfer_request_done_callback);
/* Find out the maximum memory buffer size for the video configuration
* set above. */
max_buffer_size = ux_host_class_video_max_payload_get(video);
/* USBFS's Max Packet Size is 256 */
if (0 == g_basic0_cfg.module_number) /* 0 : USBFS */
{
if (max_buffer_size > USBFS_ISO_PIPE_MAX_PAKCET_SIZE)
{
max_buffer_size = USBFS_ISO_PIPE_MAX_PAKCET_SIZE;
}
}
/* Clear semaphore to zero */
while (1)
{
if (TX_NO_INSTANCE == tx_semaphore_get(&g_data_received_semaphore, 0))
{
break;
}
}
if (0 == g_basic0_cfg.module_number) /* 0 : USBFS */
{
video->ux_host_class_video_transfer_request_start_index = 0;
video->ux_host_class_video_transfer_request_end_index = 0;
channel.ux_host_class_video_parameter_format_requested = video->ux_host_class_video_current_format;
channel.ux_host_class_video_parameter_frame_requested = video->ux_host_class_video_current_frame;
channel.ux_host_class_video_parameter_frame_interval_requested =
video->ux_host_class_video_current_frame_interval;
channel.ux_host_class_video_parameter_channel_bandwidth_selection = max_buffer_size;
status = ux_host_class_video_ioctl(video, UX_HOST_CLASS_VIDEO_IOCTL_CHANNEL_START, &channel);
}
else
{
/* Start video transfer. */
status = ux_host_class_video_start(video);
if (UX_SUCCESS != status)
{
/* Setting these to zero is a hack since we're mixing old and new APIs (new API does this and is required for reads). */
video->ux_host_class_video_transfer_request_start_index = 0;
video->ux_host_class_video_transfer_request_end_index = 0;
channel.ux_host_class_video_parameter_format_requested =
video->ux_host_class_video_current_format;
channel.ux_host_class_video_parameter_frame_requested =
video->ux_host_class_video_current_frame;
channel.ux_host_class_video_parameter_frame_interval_requested =
video->ux_host_class_video_current_frame_interval;
channel.ux_host_class_video_parameter_channel_bandwidth_selection = 1024;
status = ux_host_class_video_ioctl(video, UX_HOST_CLASS_VIDEO_IOCTL_CHANNEL_START, &channel);
}
}
/* Allocate space for video buffer. */
for (buffer_index = 0; buffer_index < MAX_NUM_BUFFERS; buffer_index++)
{
buffer_ptr[buffer_index] = &g_video_buffer[max_buffer_size * buffer_index];
}
buffer_index = 0;
frame_count = 0;
while (1)
{
/* Add the buffer back for video transfer. */
ux_host_class_video_transfer_buffer_add(video, buffer_ptr[buffer_index]);
/* Increment the buffer_index, and wrap to zero if it exceeds the
* maximum number of buffers. */
buffer_index = (buffer_index + 1);
if (buffer_index >= MAX_NUM_BUFFERS)
{
buffer_index = 0;
}
/* Suspend here until a transfer callback is called. */
status = tx_semaphore_get(&g_data_received_semaphore, 100);
if (TX_SUCCESS != status)
{
/* Check camera status */
status = tx_event_flags_get(&g_device_insert_eventflag,
EVENTFLAG_USB_DEVICE_INSERTED,
TX_OR,
(ULONG *) &actual_flags,
0);
if (TX_SUCCESS == status)
{
/* Stop video transfer. */
ux_host_class_video_stop(video);
}
break;
}
/* Received data. The callback function needs to obtain the actual
* number of bytes received, so the application routine can read the
* correct amount of data from the buffer. */
/* Application can now consume video data while the video device stores
* the data into the other buffer. */
frame_count++;
}
}

USBX DFU Example

DFU example is as follows.

/******************************************************************************
* Macro definitions
******************************************************************************/
#define CDCACM_FLAG ((ULONG) 0x0001)
#define CDCACM_ACTIVATE_FLAG ((ULONG) 0x0004)
#define CDCACM_DEACTIVATE_FLAG ((ULONG) 0x0008)
#define DFU_FLAG ((ULONG) 0x0001)
#define DFU_ACTIVATE_FLAG ((ULONG) 0x0004)
#define DFU_DEACTIVATE_FLAG ((ULONG) 0x0008)
#define DFU_DETACH_REQUEST_FLAG ((ULONG) 0x0200)
#define RESET_VALUE (0U)
#define CONFIG_NUMB1 (1U)
#define CONFIG_NUMB0 (0U)
#define INTERFACE_NUMB0 (0U)
#define INTERFACE_NUMB1 (1U)
#define INTERFACE_NUMB2 (2U)
#define DFU_DEVICE_FRAME_LENGTH_FULL_SPEED (45U)
#define DFU_STRING_FRAMEWORK_LENGTH (94U)
#define DFU_FIRM_UPDATE_MAX_TRY (1U)
/******************************************************************************
* Exported global variables and functions (to be accessed by other files)
******************************************************************************/
extern uint8_t g_device_framework_full_speed[];
extern uint8_t g_device_framework_hi_speed[];
extern uint8_t g_language_id_framework[];
extern uint8_t g_string_framework[];
extern uint8_t g_dfu_device_framework_full_speed[];
extern uint8_t g_dfu_string_framework[];
extern uint32_t usb_peri_usbx_initialize(uint32_t dcd_io);
/******************************************************************************
* Global functions and variables
******************************************************************************/
UINT usbx_status_callback(ULONG status);
/******************************************************************************
* Private global variables and functions
******************************************************************************/
static void ux_cdc_device0_instance_activate(void * cdc_instance);
static void ux_cdc_device0_instance_deactivate(void * cdc_instance);
static void usbx_pcdc_operations(void);
/* Mempool size of 18k is required for USBX device class pre built libraries
* and it is valid only if it with default USBX configurations. */
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / BYTE_SIZE];
static UX_SLAVE_CLASS_CDC_ACM_PARAMETER g_ux_device_class_cdc_acm0_parameter;
static UX_SLAVE_CLASS_CDC_ACM * g_cdc;
static ULONG g_actual_length;
static uint8_t g_buf[DATA_LEN];
static UX_SLAVE_CLASS_DFU_PARAMETER g_ux_device_class_dfu_parameter;
static UX_SLAVE_CLASS_DFU * g_dfu;
static UINT g_dfu_firmware_update_done_count = 0;
static void dfu_register_function(UINT if_num);
static void mode_change_dfu_to_cdc(void);
static void mode_change_cdc_to_dfu(void);
static UINT dfu_dammy_write(VOID * dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG * media_status);
static UINT dfu_dammy_get_status(VOID * dfu, ULONG * media_status);
static UINT dfu_dammy_notify(VOID * dfu, ULONG notification);
/* PCDC ACM & DFU Thread entry function */
void pcdc_dfu_thread_entry (void)
{
/* To check ux api return status */
UINT status = UX_SUCCESS;
/* To check fsp api return status */
fsp_err_t err = FSP_SUCCESS;
ULONG actual_flags = 0x0000;
UX_SLAVE_CLASS_DFU * dfu;
UCHAR state;
/* ux_system_initialization */
status = ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
/* ux_device stack initialization */
status = ux_device_stack_initialize(g_device_framework_hi_speed,
DEVICE_FRAME_LENGTH_HIGH_SPEED,
g_device_framework_full_speed,
DEVICE_FRAME_LENGTH_FULL_SPEED,
g_string_framework,
STRING_FRAMEWORK_LENGTH,
g_language_id_framework,
LANGUAGE_ID_FRAME_WORK_LENGTH,
&usbx_status_callback);
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_activate = ux_cdc_device0_instance_activate;
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_deactivate =
ux_cdc_device0_instance_deactivate;
/* ux_device stack class registration */
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name,
_ux_device_class_cdc_acm_entry,
CONFIG_NUMB1,
INTERFACE_NUMB0,
(void *) &g_ux_device_class_cdc_acm0_parameter);
/* ux_device stack class registration (DFU)*/
dfu_register_function(INTERFACE_NUMB2); /* Input : IF number */
/* Open usb driver */
err = R_USB_Open(&g_basic1_ctrl, &g_basic1_cfg);
/* wait for enumeration event */
status = tx_event_flags_get(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
if ((actual_flags & CDCACM_ACTIVATE_FLAG) && (TX_SUCCESS == status))
{
/* do nothing */
}
else if (!(actual_flags & CDCACM_ACTIVATE_FLAG))
{
/* do nothing */
}
/* usb pcdc operations will echo the user input on serial terminal*/
while (true)
{
state = ux_device_class_dfu_state_get(dfu);
if (UX_SYSTEM_DFU_STATE_APP_IDLE == state)
{
usbx_pcdc_operations();
}
tx_thread_sleep(1);
tx_event_flags_get(&g_cdcacm_event_flags0, CDCACM_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
if (actual_flags & CDCACM_FLAG)
{
if (actual_flags & DFU_DETACH_REQUEST_FLAG)
{
state = ux_device_class_dfu_state_get(dfu);
if (UX_SYSTEM_DFU_STATE_APP_DETACH == state)
{
mode_change_cdc_to_dfu();
}
else if (UX_SYSTEM_DFU_STATE_DFU_MANIFEST_WAIT_RESET == state)
{
mode_change_dfu_to_cdc();
}
tx_event_flags_set(&g_cdcacm_event_flags0, ~(DFU_DETACH_REQUEST_FLAG), TX_AND);
}
}
tx_thread_sleep(100);
}
}
/******************************************************************************
* Function Name : usbx_pcdc_operations
* Description : In this function, it performs the usb write/read operation and echo back the user input on serial terminal
* Arguments : none
* Return value : none
******************************************************************************/
static void usbx_pcdc_operations (void)
{
UX_SLAVE_CLASS_DFU * dfu;
UCHAR state;
UINT status = UX_SUCCESS;
uint32_t data_size = RESET_VALUE;
volatile UX_SLAVE_DEVICE * device;
device = &_ux_system_slave->ux_system_slave_device;
/* Wait until usb device is configured to slave */
if (device->ux_slave_device_state != UX_DEVICE_CONFIGURED)
{
return;
}
/* Clear the buffer */
memset(g_buf, RESET_VALUE, sizeof(g_buf));
/* USB Reads the input data from the user from serial terminal */
status = ux_device_class_cdc_acm_read(g_cdc, g_buf, DATA_LEN, &g_actual_length);
/* update the data length from the read input */
data_size = g_actual_length;
state = ux_device_class_dfu_state_get(dfu);
if (UX_SYSTEM_DFU_STATE_APP_DETACH == state)
{
return;
}
/* Write back the read data on to the serial terminal */
status = ux_device_class_cdc_acm_write(g_cdc, g_buf, data_size, &g_actual_length);
if (g_actual_length == device->ux_slave_device_descriptor.bMaxPacketSize0)
{
/* 0-Length-Packet */
ux_device_class_cdc_acm_write(g_cdc, g_buf, 0, &g_actual_length);
}
}
/******************************************************************************
* End of function usbx_pcdc_operations
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_activate
* Description : Get instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_cdc_device0_instance_activate (void * cdc_instance)
{
/* Save the CDC instance. */
g_cdc = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR);
}
/******************************************************************************
* End of function ux_cdc_device0_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_deactivate
*
* Description : Clear instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
FSP_PARAMETER_NOT_USED(cdc_instance);
g_cdc = UX_NULL;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_DEACTIVATE_FLAG, TX_OR);
}
/******************************************************************************
* End of function ux_cdc_device0_instance_deactivate
******************************************************************************/
/******************************************************************************
* Function Name : ux_dfu_device0_instance_activate
* Description : Get instance
* Arguments : void * dfu_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_dfu_device0_instance_activate (void * dfu_instance)
{
/* Save the DFU instance. */
g_dfu = (UX_SLAVE_CLASS_DFU *) dfu_instance;
tx_event_flags_set(&g_dfu_event_flags0, DFU_ACTIVATE_FLAG, TX_OR);
}
/******************************************************************************
* End of function ux_dfu_device0_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_dfu_device0_instance_deactivate
* Description : Clear dfu_instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_dfu_device0_instance_deactivate (void * dfu_instance)
{
FSP_PARAMETER_NOT_USED(dfu_instance);
g_dfu = UX_NULL;
tx_event_flags_set(&g_dfu_event_flags0, DFU_DEACTIVATE_FLAG, TX_OR);
}
/******************************************************************************
* End of function ux_dfu_device0_instance_deactivate
******************************************************************************/
/******************************************************************************
* Function Name : usbx_status_callback
* Description : Callback on device state change
* Arguments : ULONG status : New USB Device Status
* Return value : 0
******************************************************************************/
UINT usbx_status_callback (ULONG status)
{
UX_SLAVE_CLASS_DFU * dfu;
UCHAR state;
switch (status)
{
case UX_DEVICE_ATTACHED:
{
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_FLAG, TX_OR);
break;
}
case UX_DEVICE_REMOVED:
{
tx_event_flags_set(&g_cdcacm_event_flags0, ~CDCACM_FLAG, TX_AND);
break;
}
case UX_DEVICE_FORCE_DISCONNECT:
{
state = ux_device_class_dfu_state_get(dfu);
if ((UX_SYSTEM_DFU_STATE_APP_DETACH == state) ||
(UX_SYSTEM_DFU_STATE_DFU_MANIFEST_WAIT_RESET == state))
{
tx_event_flags_set(&g_cdcacm_event_flags0, DFU_DETACH_REQUEST_FLAG, TX_OR);
}
break;
}
default:
{
/* do nothing */
break;
}
}
return 0;
}
/******************************************************************************
* Function Name : dfu_register_function
* Description : Register the DFU class device
* Arguments : UINT if_num : Interface number
* Return value : none
******************************************************************************/
static void dfu_register_function (UINT if_num)
{
UINT status = UX_SUCCESS;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_instance_activate = ux_dfu_device0_instance_activate;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_instance_deactivate =
ux_dfu_device0_instance_deactivate;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_framework =
g_dfu_device_framework_full_speed;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_framework_length =
DFU_DEVICE_FRAME_LENGTH_FULL_SPEED;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_write = dfu_dammy_write;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_get_status = dfu_dammy_get_status;
g_ux_device_class_dfu_parameter.ux_slave_class_dfu_parameter_notify = dfu_dammy_notify;
status =
ux_device_stack_class_register(_ux_system_slave_class_dfu_name,
ux_device_class_dfu_entry,
CONFIG_NUMB1,
if_num,
(void *) &g_ux_device_class_dfu_parameter);
if (UX_SUCCESS != status)
{
while (1)
{
tx_thread_sleep(1);
}
}
}
/******************************************************************************
* End of function dfu_register_function
******************************************************************************/
/******************************************************************************
* Function Name : dfu_dammy_write
* Description : Write firmware data to media (e.g. non-volatile memory)
* Arguments : VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status
* Return value : UX_SUCCESS (or write err result)
******************************************************************************/
static UINT dfu_dammy_write (VOID * dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG * media_status)
{
return UX_SUCCESS;
}
/******************************************************************************
* End of function dfu_dammy_write
******************************************************************************/
/******************************************************************************
* Function Name : dfu_dammy_get_status
* Description : Outputs the status of writing firmware data to media (e.g. non-volatile memory)
* Arguments : VOID *dfu, ULONG *media_status
* Return value : UX_SUCCESS
******************************************************************************/
static UINT dfu_dammy_get_status (VOID * dfu, ULONG * media_status)
{
*media_status = UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK;
return UX_SUCCESS;
}
/******************************************************************************
* End of function dfu_dammy_get_status
******************************************************************************/
/******************************************************************************
* Function Name : dfu_dammy_notify
* Description : Notifications about transferring firmware data to applications
* Arguments : VOID *dfu, ULONG notification
* Return value : UX_SUCCESS
******************************************************************************/
static UINT dfu_dammy_notify (VOID * dfu, ULONG notification)
{
return UX_SUCCESS;
}
/******************************************************************************
* End of function dfu_dammy_notify
******************************************************************************/
/******************************************************************************
* Function Name : mode_change_cdc_to_dfu
* Description : Switch from normal mode (CDC+DFU) to DFU mode.
* Arguments : none
* Return value : none
******************************************************************************/
static void mode_change_cdc_to_dfu (void)
{
INT err;
UX_SLAVE_CLASS_DFU * dfu;
UCHAR state;
UINT status;
if (DFU_FIRM_UPDATE_MAX_TRY <= g_dfu_firmware_update_done_count)
{
return;
}
err = R_USB_Close(&g_basic1_ctrl);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, _ux_device_class_cdc_acm_entry);
status = ux_device_stack_class_unregister(_ux_system_slave_class_dfu_name, _ux_device_class_dfu_entry);
status = ux_device_stack_uninitialize();
status = ux_device_stack_initialize(UX_NULL,
UX_NULL,
g_dfu_device_framework_full_speed,
DFU_DEVICE_FRAME_LENGTH_FULL_SPEED,
g_dfu_string_framework,
DFU_STRING_FRAMEWORK_LENGTH,
g_language_id_framework,
LANGUAGE_ID_FRAME_WORK_LENGTH,
&usbx_status_callback);
dfu_register_function(INTERFACE_NUMB0); /* Input : IF number */
err = R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
}
/******************************************************************************
* End of function mode_change_cdc_to_dfu
******************************************************************************/
/******************************************************************************
* Function Name : mode_change_dfu_to_cdc
* Description : Switches from DFU mode to normal mode (CDC+DFU).
* Arguments : none
* Return value : none
******************************************************************************/
static void mode_change_dfu_to_cdc (void)
{
UX_SLAVE_CLASS_DFU * dfu;
UCHAR state;
UINT status;
INT err;
if (DFU_FIRM_UPDATE_MAX_TRY <= g_dfu_firmware_update_done_count)
{
return;
}
g_dfu_firmware_update_done_count++;
err = R_USB_Close(&g_basic0_ctrl);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
status = ux_device_stack_class_unregister(_ux_system_slave_class_dfu_name, _ux_device_class_dfu_entry);
status = ux_device_stack_uninitialize();
status = ux_device_stack_initialize(g_device_framework_hi_speed,
DEVICE_FRAME_LENGTH_HIGH_SPEED,
g_device_framework_full_speed,
DEVICE_FRAME_LENGTH_FULL_SPEED,
g_string_framework,
STRING_FRAMEWORK_LENGTH,
g_language_id_framework,
LANGUAGE_ID_FRAME_WORK_LENGTH,
&usbx_status_callback);
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name,
_ux_device_class_cdc_acm_entry,
CONFIG_NUMB1,
INTERFACE_NUMB0,
(void *) &g_ux_device_class_cdc_acm0_parameter);
dfu_register_function(INTERFACE_NUMB2); /* Input:IF number */
err = R_USB_Open(&g_basic1_ctrl, &g_basic1_cfg);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
}

USBX Composite Example

USBX Composite (PCDC + PMSC) example is as follows.

/* Mempool size of 14k is required for USBX device class pre built libraries
* and it is valid only if it with default USBX configurations. */
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / BYTE_SIZE];
static ULONG actual_flags = RESET_VALUE;
/* Mempool size of 18k is required for USBX device class pre built libraries
* and it is valid only if it with default USBX configurations. */
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / BYTE_SIZE];
static UX_SLAVE_CLASS_CDC_ACM_PARAMETER g_ux_device_class_cdc_acm0_parameter;
static UX_SLAVE_CLASS_CDC_ACM * g_cdc;
static ULONG g_actual_length;
static uint8_t g_buf[DATA_LEN];
static bool b_print_status = false;
/* Private function declarations. */
UINT usbx_status_callback(ULONG status);
static void ux_cdc_device0_instance_activate(void * cdc_instance);
static void ux_cdc_device0_instance_deactivate(void * cdc_instance);
static void usb_connection_status_check(void);
static void usbx_pcdc_operations(void);
/******************************************************************************
* Function Name : usbx_composite_pcdc_mmsc_sample
* Description : Application Thread entry function
* Arguments : none
* Return value : none
******************************************************************************/
void usbx_composite_pcdc_mmsc_sample (void)
{
/* ux_system_initialization */
ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
/* ux_device stack initialization */
ux_device_stack_initialize(g_device_framework_hi_speed,
DEVICE_FRAME_LENGTH_HIGH_SPEED,
g_device_framework_full_speed,
DEVICE_FRAME_LENGTH_FULL_SPEED,
g_string_framework,
STRING_FRAMEWORK_LENGTH,
g_language_id_framework,
LANGUAGE_ID_FRAME_WORK_LENGTH,
&usbx_status_callback);
/* The activate command is used when the host has sent a SET_CONFIGURATION command
* and this interface has to be mounted. Both Bulk endpoints have to be mounted
* and the cdc_acm thread needs to be activated. */
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_activate = ux_cdc_device0_instance_activate;
/* The deactivate command is used when the device has been extracted.
* The device endpoints have to be dismounted and the cdc_acm thread canceled. */
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_deactivate =
ux_cdc_device0_instance_deactivate;
/* ux_device stack class registration */
ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name,
_ux_device_class_cdc_acm_entry,
CONFIG_NUMB,
INTERFACE_NUMB0,
(void *) &g_ux_device_class_cdc_acm0_parameter);
/* Open usb driver */
R_USB_Open(&g_basic0_ctrl, &g_basic0_cfg);
/* Wait until device inserted.*/
tx_event_flags_get(&g_msc_event_flags0, USB_MSC_PLUG_IN, TX_AND_CLEAR, &actual_flags, TX_WAIT_FOREVER);
if (USB_MSC_PLUG_IN == actual_flags)
{
; /* USB MSC device is plugged in */
}
/* Reset the event flag */
actual_flags = RESET_VALUE;
while (true)
{
/* Check if USB is plugged out.*/
tx_event_flags_get(&g_msc_event_flags0, USB_MSC_PLUG_OUT, TX_AND_CLEAR, &actual_flags, TX_NO_WAIT);
if (USB_MSC_PLUG_OUT == (actual_flags & USB_MSC_PLUG_OUT))
{
/* Reset the event flag */
actual_flags = RESET_VALUE;
}
/* Check if USB is plugged in. */
tx_event_flags_get(&g_msc_event_flags0, USB_MSC_PLUG_IN, TX_AND_CLEAR, &actual_flags, TX_NO_WAIT);
if (USB_MSC_PLUG_IN == (actual_flags & USB_MSC_PLUG_IN))
{
/* Reset the event flag */
actual_flags = RESET_VALUE;
}
usbx_pcdc_operations();
tx_thread_sleep(1);
}
}
/******************************************************************************
* End of function usbx_composite_pcdc_mmsc_sample
******************************************************************************/
/******************************************************************************
* Function Name : usbx_status_callback
* Description : In this function, usb callback events will be captured into one variable.
* Arguments : ULONG status : USB status. Whenever any event occurred, status gets update.
* Return value : UX_SUCCESS
******************************************************************************/
UINT usbx_status_callback (ULONG status)
{
switch (status)
{
case UX_DEVICE_ATTACHED:
{
/* Set USB PLUG-IN event.*/
tx_event_flags_set(&g_msc_event_flags0, USB_MSC_PLUG_IN, TX_OR);
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_FLAG, TX_OR);
break;
}
case UX_DEVICE_REMOVED:
{
/* Set USB PLUG-OUT event.*/
tx_event_flags_set(&g_msc_event_flags0, USB_MSC_PLUG_OUT, TX_OR);
tx_event_flags_set(&g_cdcacm_event_flags0, ~CDCACM_FLAG, TX_AND);
break;
}
default:
{
/* do nothing */
break;
}
}
return 0;
}
/******************************************************************************
* End of function usbx_status_callback
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_activate
* Description : Get instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_cdc_device0_instance_activate (void * cdc_instance)
{
/* Save the CDC instance. */
g_cdc = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR);
}
/******************************************************************************
* End of function ux_cdc_device0_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_deactivate
* Description : Clear instance
* Arguments : void * cdc_instance : Pointer to area store the instance pointer
* Return value : none
******************************************************************************/
static void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
FSP_PARAMETER_NOT_USED(cdc_instance);
g_cdc = UX_NULL;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_DEACTIVATE_FLAG, TX_OR);
}
/******************************************************************************
* End of function ux_cdc_device0_instance_deactivate
******************************************************************************/
/******************************************************************************
* Function Name : usb_connection_status_check
* Description : In this function, checks the USB device status
* and notifies the user by printing the status message
* Arguments : none
* Return value : none
******************************************************************************/
static void usb_connection_status_check (void)
{
ULONG actual_flags = RESET_VALUE;
/* wait for usb connection event */
tx_event_flags_get(&g_cdcacm_event_flags0, CDCACM_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
if (actual_flags & CDCACM_FLAG)
{
if (true != b_print_status)
{
b_print_status = true; // flag is updated
}
else
{
/* do nothing */
}
}
else
{
b_print_status = false; // clear the flag
while (!(actual_flags & CDCACM_FLAG))
{
; /* wait until the event update */
}
}
}
/******************************************************************************
* End of function usb_connection_status_check
******************************************************************************/
/******************************************************************************
* Function Name : usbx_pcdc_operations
* Description : In this function, it performs the usb write/read operation
* and echo back the user input on serial terminal
* Arguments : none
* Return value : none
******************************************************************************/
static void usbx_pcdc_operations (void)
{
uint32_t data_size = RESET_VALUE;
volatile UX_SLAVE_DEVICE * device;
device = &_ux_system_slave->ux_system_slave_device;
/* Verify the status of usb */
usb_connection_status_check();
tx_event_flags_get(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
/* USB writes the display message on serial terminal */
ux_device_class_cdc_acm_write(g_cdc,
(UCHAR *) "\r\nEnter any Key to echo back the entered data \r\nUser Input :",
WRITE_DATA_LEN,
&g_actual_length);
/* Clear the buffer */
memset(g_buf, RESET_VALUE, sizeof(g_buf));
/* USB Reads the input data from the user from serial terminal */
ux_device_class_cdc_acm_read(g_cdc, g_buf, DATA_LEN, &g_actual_length);
/* update the data length from the read input */
data_size = g_actual_length;
/* Write back the read data on to the serial terminal */
ux_device_class_cdc_acm_write(g_cdc, g_buf, data_size, &g_actual_length);
}
/******************************************************************************
* End of function usbx_pcdc_operations
******************************************************************************/

USBX OTG Example

OTG example is as follows.

#define VALUE_108 (108)
#define VALUE_105 (105)
#define VALUE_98 (98)
#define VALUE_2 (2)
static volatile ULONG g_apl_status_peri = 0;
volatile uint8_t g_apl_state = UX_DEVICE_REMOVED;
static volatile ULONG g_apl_usb_mode = UX_OTG_MODE_IDLE;
static volatile ULONG g_change_device_mode = UX_OTG_MODE_IDLE;
static UX_HOST_CLASS_CDC_ACM * g_p_cdc_acm_host = UX_NULL;
static UX_SLAVE_CLASS_CDC_ACM * volatile g_p_cdc_peri = UX_NULL;
/******************************************************************************
* Function Name : apl_status_change_cb
* Description : USB callback function for USB status change
* Arguments : ULONG status : USB status
* Return value : UX_SUCCESS
******************************************************************************/
UINT apl_status_change_cb (ULONG status)
{
// Debug OTG-A Detach
if ((UX_DEVICE_REMOVED == g_apl_status_peri) && (UX_DEVICE_RESUMED == status))
{
return UX_SUCCESS;
}
g_apl_status_peri = status;
return UX_SUCCESS;
}
/******************************************************************************
* End of function apl_status_change_cb
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_activate
* Description : Get instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
void ux_cdc_device0_instance_activate (void * cdc_instance)
{
/* Save the CDC instance. */
g_p_cdc_peri = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
}
/******************************************************************************
* End of function ux_cdc_device0_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_deactivate
* Description : Clear instance
* Arguments : void * cdc_instance : Pointer to area store the instance pointer
* Return value : none
******************************************************************************/
void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
FSP_PARAMETER_NOT_USED(cdc_instance);
g_p_cdc_peri = UX_NULL;
}
/* USB OTG Application */
/******************************************************************************
* Function Name : apl_device_swich_complete_cb
* Description : Callback function called when switcning Host or Peri
* Arguments : UX_OTG_MODE_SLAVE/UX_OTG_MODE_HOST/UX_OTG_MODE_IDLE
* Return value : none
******************************************************************************/
void apl_device_swich_complete_cb (ULONG mode)
{
if (UX_OTG_MODE_SLAVE == mode)
{
_ux_system_otg->ux_system_otg_slave_role_swap_flag = 0;
}
g_change_device_mode = mode;
}
/******************************************************************************
* Function Name : otg_host_apl
* Description : OTG sample program
* Arguments : none
* Return value : none
******************************************************************************/
void apl_otg_sample (void)
{
uint8_t is_host_request_flag = USB_NO;
uint8_t is_host_apl_complete = USB_NO;
fsp_err_t err;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
// B device initialization
ux_device_stack_initialize(UX_NULL,
UX_NULL,
g_device_framework_full_speed,
VALUE_98,
g_string_framework,
VALUE_105,
g_language_id_framework,
VALUE_2,
apl_status_change_cb);
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_activate = ux_cdc_device0_instance_activate;
g_ux_device_class_cdc_acm0_parameter.ux_slave_class_cdc_acm_instance_deactivate =
ux_cdc_device0_instance_deactivate;
ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name,
_ux_device_class_cdc_acm_entry,
1,
0x00,
(void *) &g_ux_device_class_cdc_acm0_parameter);
// A device initialization
ux_host_stack_initialize(ux_host_usr_event_notification);
R_USB_OtgCallbackSet(&g_basic0_ctrl, apl_device_swich_complete_cb);
#if defined(APL_USB_OTG_A_DEVICE)
err = R_ICU_ExternalIrqOpen(&g_external_irq0_ctrl, &g_external_irq0_cfg);
assert(FSP_SUCCESS == err);
err = R_ICU_ExternalIrqEnable(&g_external_irq0_ctrl);
assert(FSP_SUCCESS == err);
#endif
err = g_usb_on_usb.open(&g_basic0_ctrl, &g_basic0_cfg);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
#if defined(APL_USB_OTG_A_DEVICE)
while (1)
{
if (UX_OTG_MODE_HOST == g_change_device_mode)
{
break;
}
}
#endif /* defined(APL_USB_OTG_A_DEVICE) */
while (1)
{
if (g_change_device_mode != g_apl_usb_mode)
{
g_apl_usb_mode = g_change_device_mode;
switch (g_apl_usb_mode)
{
case UX_OTG_MODE_HOST:
{
is_host_request_flag = USB_NO;
if (USB_NO == is_host_apl_complete)
{
otg_host_apl();
is_host_apl_complete = USB_YES;
}
break;
}
case UX_OTG_MODE_SLAVE:
{
is_host_apl_complete = USB_NO;
if (USB_NO == is_host_request_flag)
{
err = otg_peri_apl();
if (0 == err)
{
if (UX_OTG_FEATURE_A_HNP_SUPPORT ==
(_ux_system_otg->ux_system_otg_slave_set_feature_flag & UX_OTG_FEATURE_A_HNP_SUPPORT))
{
_ux_system_otg->ux_system_otg_slave_role_swap_flag = UX_OTG_HOST_REQUEST_FLAG;
is_host_request_flag = USB_YES;
}
}
}
break;
}
default:
{
/* UX_MODE_IDLE */
is_host_request_flag = USB_NO;
is_host_apl_complete = USB_NO;
break;
}
}
}
}
}
/******************************************************************************
* End of function apl_otg_sample
******************************************************************************/
/* USB Host Application */
/******************************************************************************
* Function Name : ux_host_usr_event_notification
* Description : Callback function called when completing USB event
* Arguments : ULONG event : Completed USB Event
* : UX_HOST_CLASS *host_class : Pointer to UX_HOST_CLASS structure
* : VOID * instance : Pointer to HCDC instance
* Return value : UX_SUCCESS
******************************************************************************/
UINT ux_host_usr_event_notification (ULONG event, UX_HOST_CLASS * host_class, VOID * instance)
{
(void) host_class;
if (UX_DEVICE_INSERTION == event) /* Check if there is a device insertion. */
{
g_p_cdc_host = (UX_HOST_CLASS_CDC_ACM *) instance;
if (UX_HOST_CLASS_CDC_DATA_CLASS !=
g_p_cdc_host->ux_host_class_cdc_acm_interface->ux_interface_descriptor.bInterfaceClass)
{
/* It seems the DATA class is on the second interface. Or we hope ! */
g_p_cdc_host = g_p_cdc_host->ux_host_class_cdc_acm_next_instance;
/* Check again this interface, if this is not the data interface, we give up. */
if (UX_HOST_CLASS_CDC_DATA_CLASS !=
g_p_cdc_host->ux_host_class_cdc_acm_interface->ux_interface_descriptor.bInterfaceClass)
{
/* We did not find a proper data interface. */
g_p_cdc_host = UX_NULL;
}
}
if (UX_NULL != g_p_cdc_host)
{
g_host_apl_event = UX_DEVICE_INSERTION;
}
tx_thread_wait_abort(&new_thread0);
}
else if ((UX_DEVICE_REMOVAL == event) || (UX_DEVICE_DISCONNECTION == event)) /* Check if there is a device removal. */
{
g_host_apl_event = UX_DEVICE_REMOVAL;
g_p_cdc_host = UX_NULL;
}
return UX_SUCCESS;
}
/******************************************************************************
* End of function ux_host_usr_event_notification
******************************************************************************/
/******************************************************************************
* Function Name : otg_host_apl
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
void otg_host_apl (void)
{
ULONG status;
m
for (counter = 0; counter < DATA_LEN; counter++)
{
g_write_buf_host[counter] = (uint8_t) counter;
}
g_host_apl_event = 0;
while (1)
{
if (UX_DEVICE_INSERTION == g_host_apl_event)
{
g_host_apl_event = 0;
for (countor = 0; countor < 5000; countor++)
{
if (0 == g_is_communicate)
{
tx_thread_sleep(100);
g_is_communicate = 1;
}
g_write_actual_length = 0;
status = ux_host_class_cdc_acm_write(g_p_cdc_host,
g_write_buf_host,
DATA_LEN,
&g_write_actual_length_host);
if ((UX_SUCCESS == status) && (DATA_LEN == g_write_actual_length_host))
{
g_read_actual_length_host = 0;
buffer_clear(g_host_read_buf);
status = ux_host_class_cdc_acm_read(g_p_cdc_host,
g_read_buf_host,
DATA_LEN,
&g_read_actual_length_host);
if ((UX_SUCCESS == status) && (DATA_LEN == g_read_actual_length_host))
{
for (counter = 0; counter < DATA_LEN; counter++)
{
if ((uint8_t) counter != g_read_buf_host[counter])
{
while (1)
{
;
}
}
}
}
else
{
break;
}
}
else
{
break;
}
}
}
else if (UX_DEVICE_REMOVAL == g_host_apl_event)
{
g_host_apl_event = 0;
break;
}
}
}
/******************************************************************************
* End of function otg_host_apl
******************************************************************************/
/* USB Peripheral Application */
/******************************************************************************
* Function Name : ux_cdc_device0_instance_activate
* Description : Get instance
* Arguments : void * cdc_instance : Pointer to the area store the instance pointer
* Return value : none
******************************************************************************/
void ux_cdc_device0_instance_activate (void * cdc_instance)
{
/* Save the CDC instance. */
g_p_cdc_peri = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
}
/******************************************************************************
* End of function ux_cdc_device0_instance_activate
******************************************************************************/
/******************************************************************************
* Function Name : ux_cdc_device0_instance_deactivate
* Description : Clear instance
* Arguments : void * cdc_instance : Pointer to area store the instance pointer
* Return value : none
******************************************************************************/
void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
FSP_PARAMETER_NOT_USED(cdc_instance);
g_p_cdc_peri = UX_NULL;
}
/******************************************************************************
* End of function ux_cdc_device0_instance_deactivate
******************************************************************************/
/******************************************************************************
* Function Name : otg_peri_apl
* Description : Application task (loopback processing)
* Arguments : none
* Return value : none
******************************************************************************/
uint8_t otg_peri_apl (void)
{
UINT ret;
ULONG size;
uint16_t counter = 0;
g_apl_status_peri = 0;
for (counter = 0; counter < 5000; )
{
if (UX_DEVICE_CONFIGURED == g_apl_status_peri)
{
while (g_p_cdc_peri == UX_NULL)
{
;
}
ret = _ux_device_class_cdc_acm_read(g_p_cdc_peri, g_buf_peri, DATA_LEN, &g_actual_length_peri);
if (UX_SUCCESS == ret)
{
size = g_actual_length_peri;
ux_device_class_cdc_acm_write(g_p_cdc_peri, g_buf_peri, size, &g_actual_length_peri);
counter++;
}
}
else if (UX_DEVICE_REMOVED == g_apl_status_peri)
{
if (0 != counter)
{
break;
}
}
}
if (5000 == counter)
{
return APL_SUCCESS;
}
return APL_ERROR;
}
/******************************************************************************
* End of function otg_peri_apl
******************************************************************************/