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.
Select [New Stack]->[Connectivity]->[Azure RTOS PCDC]
Select USB Device Class
Select the USB pipe to use.
Select using USB Pipe
Using Composite (Peripheral)
Select [New Stack]->[Connectivity]->[USB Composite]
Select USB Composite
The following is displayed when selecting [USB Composite].
USB Composite Stack
Select the supported 2 device classes as follows.
Select Device Classes
Delete the "g_basic1" instance manually.
Delete USB Basic instance
Using HMSC.
Since HMSC is used in a different way from other USBX modules, the usage is described below.
Select [New Stack]->[Storage]->[Azure RTOS FileX on USBX]
Select USB Device Class
The following is displayed when selecting Filex on USBX.
rm_usbx_hmsc2.svg
FileX on USBX Stack
Using OTG.
The following describes how to configure USBX OTG.
Select USB Device Class for OTG
Be sure to set the following to each item in "r_icu".
Set "7" to "Channel" item.
Set "Both Edges" to "Trigger" item.
Set "Enabled" to "Digital Filtering" item.
Set "usb_otg_irq_callback" to "Callback" item.
Select USB Device Class for OTG
Be sure to set the following to each item in "r_usb_basic".
Set "Full Speed" to "USB Speed" item.
Set "USB_IP0 Port" to "USB Module Number".
Set "Not Supported" to "USBFS Resume Priority".
Select USB Device Class
Set the following pins for USB (r_usb_basic)
USB Pin Setting
Set the following pins for IRQ (r_icu)
IRQ Pin Setting
Using Hub
When the user uses the following device class, the user can use USB Hub.
Host Communication Device Class (HCDC)
Host Human Interface Device Class (HHID)
Host Mass Storage Class (HMSC)
Host Printer Class (HPRN)
Also be sure to set the pipe number to the following items. Can not specify "NO USE" to the following items when using Hub.
Bulk In Pipe 2
Bulk Out Pipe 2
Interrupt In Pipe 2
Interrupt In PIpe 3
Note
Please ignore the suspend or resume event occurs when attaching or detaching the USB cable.
The following are notes on using the ux_host_class_cdc_acm_read function or the ux_device_class_cdc_acm_read function
Please specify a multiple of MaxPacketSize to the 3rd argument(requested_length) since if the value of the 3rd argument is not multiple of MaxPacketSize, all data sent by USB Host or USB Peripheral may not be received correctly.
Please specify start address of the area allocated a size larger than 3rd argument(requested_length) to the 2nd argument(data_pointer or buffer).
There is no stack for the Hub; please select the stack for USB Host even when using the Hub.
Depending on the Hub used, it may be necessary to supply power to the Hub.
HUVC does not support USB Hub.
HMSC uses FileX.
For more information on FileX, please refer to the following URL.
https://docs.microsoft.com/en-us/azure/rtos/filex/
OTG
Be able to set UX_OTG_HOST_REQUEST_FLAG in USB Peripheral mode or call ux_host_stack_role_swap() function in USB Host mode when data other than control transfer is not being transferred.
Register the callback function for the application using R_USB_OtgCallbackSet() function. This callback function is called when switching the operation mode(UX_OTG_MODE_IDLE/UX_OTG_MODE_SLAVE/UX_OTG_MODE_HOST).
Use R_USB_OtgSRP() function when doing SRP(Session Request Protocol). The R_USB_OtgSRP() function does not support VBUS pulsing.
After starting up MCU, USB is initialized as USB peripheral mode until connecting A cable.
Please ignore the suspend or resume event occurs when attaching or detaching the USB cable.
When A cable is connected, USB module is initialized as USB Host mode.
Call R_ICU_ExternalIrqOpen() and R_ICU_ExternalIrqEnable() function in the application program since the IRQ interrupt is used to detect attaching or detaching of A cable.
Add the OTG descriptor in the configuration descriptor in each descriptor file.
Offset Field Size Value Description
0 bLength 1 5 Size of Descriptor
1 bDescriptor Type 1 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
There is compatibility issue for FileX on USBX stack in FSP 5.0.0 while importing from FSP 4.6.0 or earlier. Please refer to "GitHub Issue" about this workaround.
Limitations
Specify value of Timer Ticks Per Second
Set the Thread priority to a value of 21.
Specify value of Thread priority
Call the following functions in the following order after calling the R_USB_Close() function.
Peripheral
PCDC / PHID / PPRN
ux_device_stack_class_unregister
ux_device_stack_uninitialize
PMSC
ux_device_stack_uninitialize
Host
ux_host_stack_uninitialize
USBX Composite (Peripheral) supports the following composite device.
USBX Composite (PCDC + PMSC) has the following notes.
When the user select "Safely Remove Hardware and Eject Media" on Windows and eject the mass storage (PMSC), the Windows Explorer for PMSC does not disappear. But PMSC driver works properly.
PMSC may not work properly when USBX Composite Device(PCDC+PMSC) is connected to linux machine (USB Host).If the user encounter this issue, please update Linux OS.
The FAT file format that HMSC supports is FAT32, FAT16 and FAT12.
When using USBX HMSC, please be sure to check the "fx" checkbox(red frame) of the pack the user is using in the "Components" tab(green frame) as shown below.
Check the fx checkbox
When using USBX HPRN, if the internal buffer of the printer is full, USB data transfer speed drops significantly.
When using USBX HHID, please use Wired device.
USBX HUVC driver does not support Full-speed.
USBX HUVC driver does not support the following APIs.
ux_host_class_video_transfer_buffers_add
ux_host_class_video_read
Note the following when using ux_host_class_video_transfer_buffer_add fucntion (USBX HUVC API)
Please call ux_host_class_video_transfer_buffer_add fucntion after cofirming that the callback function for data reception completion is called when calling this API again. This callback function is registerd by ux_host_class_video_transfer_callback_set function in the application program.
Please specify a 4-byte alignment address for the 2nd argument (buffer ) of ux_host_class_video_transfer_buffer_add fucntion when using DMA transfer.
Note the following when using ux_host_class_video_start fucntion (USBX HUVC API)
The USBHS module does not support the high-bandwidth isochronous transfer (image below), the maximum packet size for isochronous transfer is 1024 bytes and supports only one transaction per microframe.
High Bandwidth Isochronous Transfer
This module does not support the MCU(RA4M1 and RA2A1) since the RAM size is small.
Please specify the correct framework size to the 2nd argument(device_framework_length_high_speed) and the 4th argument(device_framework_length_full_speed) in "ux_device_stack_initialize" function. If incorrect size is specified, USB driver does not work properly.
The following is the limitation when using OTG.
The user can not use High-speed module(USB_IP1).
The DMA transfer is not supported.
The MSC is not supported.
The user can not use USB Hub.
The followings are the limitation when using USB Hub.
The USB driver allocates USB PIPE9 for USB Hub. The user can not specify "USB PIPE9" when using USB Hub.
The user can not connect the Hub device under the Hub down port.
For HCDC, the user can not connect more than 2 CDC devices to USB Hub.
For HPRN, the user can not connect more than 2 PRN devices to USB Hub.
For HHID, the user can not connect more than 3 HID devices to USB Hub.
For HMSC, the user can not connect more than 3 MSC devices to USB Hub.
The user can not use USB PIPE1, PIPE2, PIPE3, PIPE8 and PIPE9 when using the follwoing MCU.
Please use USB Host DFU tool described in the chapter "USB Device DFU Class" in the following page.
https://learn.microsoft.com/en-us/azure/rtos/usbx/usbx-device-stack-supplemental-2
USBX DFU can upgrade the firmware only once after resetting MCU.
USBX DFU does not support the upload feature.
ux_device_class_cdc_acm_read() API, throughput/speed may be similar in following cases.
Read operation in double buffer mode when compared to single buffer mode.
Read operation in continuous transfer mode when compared to non-continious transfer mode.
Because of the USBX CDC device stack limits the read transfer size buffer to single packet (ie. wMaxPacketSize as per Full-speed or High-speed USB port). Please refer Azure RTOS USBX documentation for more information.
ux_host_class_cdc_acm_write() and ux_host_class_cdc_acm_read() API, throughput/speed on high-speed port may be similar for CPU read and write operation in double buffer mode when compared to single buffer mode because of the FSP driver limits the maximum transfer request length size to 512 bytes (UX_FSP_MAX_BULK_PAYLOAD).
ux_host_class_cdc_acm_write() and ux_host_class_cdc_acm_read() API, throughput/speed may be less for DMA read and write operation when compared to CPU mode because of the FSP driver limits the maximum transfer request length size to 512 bytes(UX_FSP_MAX_BULK_PAYLOAD).
ux_host_class_cdc_acm_write() and ux_host_class_cdc_acm_read() API, throughput/speed may be less for DMA read and write operation compared to USB FreeRTOS HCDC DMA because of the FSP driver limits the maximum transfer request length size to 512 bytes (UX_FSP_MAX_BULK_PAYLOAD).
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.
rm_usbx_pcdc_descriptor.c.template
Comment on lines 108 and 243.
Delete the "//" on lines 109 and 242.
rm_usbx_pmsc_descriptor.c.template
Comment on lines 78 and 153.
Delete the "//" on lines 79 and 152.
rm_usbx_paud_descriptor.c.template
Comment on lines 167 and 485.
Delete the "//" on lines 168 and 486.
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)
static void ux_cdc_device0_instance_activate (void * cdc_instance)
{
g_cdc = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
}
static void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
g_cdc = UX_NULL;
}
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;
}
void usbx_pcdc_sample (void )
{
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);
}
}
}
}
}
USBX HCDC Example
The main functions of the HCDC loopback example are as follows:
Virtual UART control settings are configured by transmitting the class request SET_LINE_CODING to the CDC device.
Sends receive (Bulk In transfer) requests to a CDC peripheral device and receives data.
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)
{
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)
{
p_cdc_acm = p_cdc_acm->ux_host_class_cdc_acm_next_instance;
if (p_cdc_acm->ux_host_class_cdc_acm_interface->ux_interface_descriptor.bInterfaceClass !=
UX_HOST_CLASS_CDC_DATA_CLASS)
{
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)
{
tx_event_flags_set(&g_cdcacm_activate_event_flags0, ~CDCACM_FLAG, TX_AND);
p_cdc_acm = UX_NULL;
}
else
{
}
return UX_SUCCESS;
}
void buffer_clear (uint8_t * p)
{
uint16_t counter;
for (counter = 0; counter < DATA_LEN; counter++)
{
*p = 0U;
}
}
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)
{
;
}
}
}
}
}
}
}
}
}
}
USBX PMSC Example
PMSC storage example is as follows.
{.
p_extend = NULL, .p_callback = NULL, .p_context = NULL, };
{.
sector_size_bytes = STRG_MEDIASIZE, .num_sectors = STRG_TOTALSECT, .reentrant =
false , .write_protected =
false , };
{.
p_api = &g_rm_block_media_on_user_media, .p_ctrl = &g_rm_block_info0, .p_cfg = &g_rm_block_media0_cfg, };
void usbx_pmsc_sample (void )
{
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;
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)
{
g_p_media = UX_NULL;
tx_event_flags_set(&g_usb_plug_events, EVENT_USB_PLUG_OUT, TX_OR);
}
else
{
}
return status;
}
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)
{
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);
}
p_media = g_p_media;
fx_return = fx_media_volume_get(p_media, volume, FX_DIRECTORY_SECTOR);
if (FX_SUCCESS == fx_return)
{
fx_directory_default_set(p_media, "firstdir" );
tx_thread_sleep(VALUE_100);
fx_return = fx_file_open(p_media, &g_file, "counter.txt" , (FX_OPEN_FOR_READ | FX_OPEN_FOR_WRITE));
if (FX_SUCCESS != fx_return)
{
fx_return = fx_file_create(p_media, "counter.txt" );
if (FX_SUCCESS != fx_return)
{
break ;
}
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 ;
}
}
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)
{
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;
}
fx_return = fx_file_seek(&g_file, 0);
if (FX_SUCCESS == fx_return)
{
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);
}
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);
}
fx_return = fx_media_flush(p_media);
if (FX_SUCCESS != fx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
fx_return = fx_media_close(p_media);
if (FX_SUCCESS != fx_return)
{
tx_thread_sleep(TX_WAIT_FOREVER);
}
tx_event_flags_get(&g_usb_plug_events, EVENT_USB_PLUG_OUT, TX_OR_CLEAR, &actual_flags, TX_WAIT_FOREVER);
}
}
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);
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);
}
p_media = g_p_media;
memset(g_fx_media0_media_memory, 0x00, sizeof (g_fx_media0_media_memory));
status = fx_media_format(p_media,
p_media->fx_media_driver_entry,
p_media->fx_media_driver_info,
g_fx_media0_media_memory,
p_media->fx_media_memory_size,
"sample" ,
p_media->fx_media_number_of_FATs,
p_media->fx_media_root_directory_entries,
p_media->fx_media_hidden_sectors,
(ULONG) p_media->fx_media_total_sectors,
p_media->fx_media_bytes_per_sector,
p_media->fx_media_sectors_per_cluster,
p_media->fx_media_heads,
p_media->fx_media_sectors_per_track);
if ((uint8_t) FX_SUCCESS != status)
{
__BKPT(0);
}
}
USBX PHID Example
PHID keyboard example is as follows.
void usbx_phid_keyboard_sample (void )
{
UX_SLAVE_CLASS_HID_EVENT hid_event;
UCHAR key;
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
VALUE_52,
#endif
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
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);
key = 0x04;
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)
{
tx_thread_sleep(10);
}
usb_cpu_delay_xms((uint16_t) VALUE_5000);
hid_event.ux_device_class_hid_event_length = 8;
hid_event.ux_device_class_hid_event_buffer[0] = 0;
hid_event.ux_device_class_hid_event_buffer[1] = 0;
hid_event.ux_device_class_hid_event_buffer[2] = key;
if (UX_NULL != g_hid)
{
ux_device_class_hid_event_set(g_hid, &hid_event);
}
hid_event.ux_device_class_hid_event_buffer[2] = 0;
hid_event.ux_device_class_hid_event_length = 8;
if (UX_NULL != g_hid)
{
ux_device_class_hid_event_set(g_hid, &hid_event);
if (key != (0x04 + 26))
{
key++;
}
else
{
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
}
else
{
if (USB_NO == g_remote_wakeup)
{
tx_thread_sleep(VALUE_10000);
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;
ULONG keyboard_key = 0;
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
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;
keyboard_key = 0;
keyboard_state = 0;
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;
ux_host_class_hid_report_set((UX_HOST_CLASS_HID *) keyboard_instance->ux_host_class_hid_keyboard_hid,
&client_report);
#endif
}
}
tx_thread_sleep(10);
}
}
void mouse_update_task (ULONG thread_input)
{
ULONG mouse_buttons;
SLONG mouse_x_position = 0;
SLONG mouse_y_position = 0;
ULONG usbx_return_value;
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++)
{
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);
}
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);
}
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)
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
static UX_DEVICE_CLASS_AUDIO10_CONTROL_GROUP g_audio_control_group;
static UX_DEVICE_CLASS_AUDIO10_CONTROL g_audio_control[2];
#endif
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;
}
static void apl_audio_instance_activate (void * p_instance)
{
g_p_audio = (UX_DEVICE_CLASS_AUDIO *) p_instance;
}
static void apl_audio_instance_deactivate (void * p_instance)
{
g_p_audio = UX_NULL;
}
#ifdef APL_AUDIO_20
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)
{
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;
}
#else
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)
{
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;
}
#endif
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)
{
g_read_wp = 0U;
}
}
g_read_alternate_setting = alternate_setting;
}
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;
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);
}
}
}
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;
}
static void apl_audio_write_done (UX_DEVICE_CLASS_AUDIO_STREAM * p_stream, ULONG 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);
}
}
void usbx_paudio_apl_init (void )
{
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);
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;
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
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
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();
}
}
void usbx_paud_sample (void )
{
usbx_paudio_apl_init();
while (1)
{
switch (g_apl_usb_status)
{
case USB_APL_CONFIGURED:
{
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.
#define DEMO_PROTOCOL (1U)
#define DEMO_STACK_SIZE 1024
#define DEVICE_FRAME_LENGTH_HIGH_SPEED (53U) + ((DEMO_PROTOCOL > 1) ? 7 : 0)
#define DEVICE_FRAME_LENGTH_FULL_SPEED (43U) + ((DEMO_PROTOCOL > 1) ? 7 : 0)
#define STRING_FRAMEWORK_LENGTH (53U)
#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)
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};
extern uint32_t usb_peri_usbx_initialize(uint32_t dcd_io);
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);
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" ;
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);
static TX_THREAD demo_thread;
static TX_THREAD printer_read_thread;
#if DEMO_PROTOCOL > 1
static TX_THREAD printer_write_thread;
#endif
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);
}
}
static void ux_printer_instance_deactivate (void * printer_instance)
{
if ((void *) device_printer == printer_instance)
{
device_printer = UX_NULL;
}
}
static void ux_printer_soft_reset (void * printer_instance)
{
}
void usbx_pprn_sample (void )
{
UINT status = UX_SUCCESS;
uint8_t * stack_pointer;
uint8_t * memory_pointer;
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_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);
_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_register(_ux_system_slave_class_prn_name,
_ux_device_class_printer_entry,
CONFIG_NUMB,
INTERFACE_NUMB0,
(void *) &device_printer_parameter);
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;
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
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
}
static void apl_mem_usage_update (void )
{
uint32_t mem_total;
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
if (test_data.mem_usage > test_data.mem_usage_max)
{
test_data.mem_usage_max = test_data.mem_usage;
}
#endif
}
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);
}
}
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;
while (1)
{
apl_mem_usage_update();
tx_thread_sleep(1);
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;
}
tick1 = tx_time_get();
diff = apl_minus(tick1, tick0, 0xFFFFFFFF);
if (diff < TX_TIMER_TICKS_PER_SECOND)
{
continue ;
}
tick0 = tick1;
if ((pmem != test_data.mem_usage_max))
{
pmem = test_data.mem_usage_max;
}
}
}
void printer_read_thread_entry (uint32_t thread_input)
{
UINT status;
uint32_t actual_length;
UINT i;
while (1)
{
if (device_printer == UX_NULL)
{
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 ;
}
}
}
void printer_write_thread_entry (uint32_t thread_input)
{
uint8_t port_status = device_printer_port_status.value;
while (1)
{
tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND * 2);
if (device_printer &&
(port_status != device_printer_port_status.value))
{
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"
#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)
static UINT ux_host_usr_event_notification(ULONG event, UX_HOST_CLASS * host_class,
VOID * 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];
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_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
ux_host_stack_initialize(ux_host_usr_event_notification);
for (count = RESET_VALUE; count < DATA_LEN; count++)
{
g_write_buf[count] = (uint8_t) count;
}
while (true )
{
tx_event_flags_get(&g_printer_activate_event_flags0, HPRN_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
if (UX_NULL != p_printer)
{
ux_host_class_printer_status_get(p_printer, &port_status);
ux_host_class_printer_write(p_printer, g_write_buf, DATA_LEN, &g_write_actual_length);
memset(g_read_buf, RESET_VALUE, sizeof (g_read_buf));
ux_host_class_printer_read(p_printer, g_read_buf, MAX_REQUEST_SIZE, &g_read_actual_length);
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)
{
if (UX_FSP_DEVICE_INSERTION == event)
{
p_printer = (UX_HOST_CLASS_PRINTER *) instance;
if (UX_NULL != p_printer)
{
tx_event_flags_set(&g_printer_activate_event_flags0, HPRN_FLAG, TX_OR);
}
}
else if (UX_FSP_DEVICE_REMOVAL == event)
{
tx_event_flags_set(&g_printer_activate_event_flags0, ~HPRN_FLAG, TX_AND);
p_printer = UX_NULL;
}
else
{
}
}
return UX_SUCCESS;
}
USBX HUVC Example
HUVC example is as follows.
#define RESET_VALUE (0x00)
#define MEMPOOL_SIZE (18432)
#define VALUE_4 (4)
#define EVENTFLAG_USB_DEVICE_INSERTED (0x01)
#define MAX_NUM_BUFFERS 2
#define USBFS_ISO_PIPE_MAX_PAKCET_SIZE (256)
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);
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / VALUE_4];
UX_HOST_CLASS_VIDEO * volatile video_host_class;
TX_EVENT_FLAGS_GROUP g_device_insert_eventflag;
TX_SEMAPHORE g_data_received_semaphore;
UCHAR g_video_buffer[10 * 1024];
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" }
};
void usbx_huvc_sample (void )
{
uint32_t status = RESET_VALUE;
ULONG actual_flags = RESET_VALUE;
status = ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
if (UX_SUCCESS != status)
{
while (1)
{
;
}
}
status = ux_host_stack_initialize(ux_host_usr_event_notification);
if (UX_SUCCESS != status)
{
while (1)
{
;
}
}
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)
{
tx_event_flags_get(&g_device_insert_eventflag,
EVENTFLAG_USB_DEVICE_INSERTED,
TX_OR,
(ULONG *) &actual_flags,
TX_WAIT_FOREVER);
tx_thread_sleep(100);
if (UX_NULL != video_host_class)
{
uvc_process_function(video_host_class);
}
}
}
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)
{
video_host_class = instance;
tx_event_flags_set(&g_device_insert_eventflag, EVENTFLAG_USB_DEVICE_INSERTED, TX_OR);
}
else if (UX_DEVICE_REMOVAL == event)
{
tx_event_flags_set(&g_device_insert_eventflag, (ULONG) ~EVENTFLAG_USB_DEVICE_INSERTED, TX_AND);
video_host_class = NULL;
}
}
return UX_SUCCESS;
}
VOID uvc_transfer_request_done_callback (UX_TRANSFER * transfer_request)
{
tx_semaphore_put(&g_data_received_semaphore);
}
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;
_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);
if (0 == frame_descriptor.bFrameIntervalType)
{
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);
}
}
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;
for (frame_index = 1; frame_index <= video->ux_host_class_video_number_frames; 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;
}
video->ux_host_class_video_current_frame = frame_index;
uvc_parameter_interval_list(video);
}
return status;
}
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;
for (format_index = 1; format_index <= video->ux_host_class_video_number_formats; 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)
{
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)
{
UCHAR * buffer_ptr[MAX_NUM_BUFFERS];
ULONG buffer_index;
ULONG max_buffer_size;
UINT status;
ULONG actual_flags;
UINT frame_count;
UX_HOST_CLASS_VIDEO_PARAMETER_CHANNEL channel;
uvc_parameter_list(video);
status = ux_host_class_video_frame_parameters_set(video, UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG, 176, 144, 333333);
ux_host_class_video_transfer_callback_set(video, uvc_transfer_request_done_callback);
max_buffer_size = ux_host_class_video_max_payload_get(video);
if (0 == g_basic0_cfg.module_number)
{
if (max_buffer_size > USBFS_ISO_PIPE_MAX_PAKCET_SIZE)
{
max_buffer_size = USBFS_ISO_PIPE_MAX_PAKCET_SIZE;
}
}
while (1)
{
if (TX_NO_INSTANCE == tx_semaphore_get(&g_data_received_semaphore, 0))
{
break ;
}
}
if (0 == g_basic0_cfg.module_number)
{
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
{
status = ux_host_class_video_start(video);
if (UX_SUCCESS != status)
{
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);
}
}
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)
{
ux_host_class_video_transfer_buffer_add(video, buffer_ptr[buffer_index]);
buffer_index = (buffer_index + 1);
if (buffer_index >= MAX_NUM_BUFFERS)
{
buffer_index = 0;
}
status = tx_semaphore_get(&g_data_received_semaphore, 100);
if (TX_SUCCESS != status)
{
status = tx_event_flags_get(&g_device_insert_eventflag,
EVENTFLAG_USB_DEVICE_INSERTED,
TX_OR,
(ULONG *) &actual_flags,
0);
if (TX_SUCCESS == status)
{
ux_host_class_video_stop(video);
}
break ;
}
frame_count++;
}
}
USBX DFU Example
DFU example is as follows.
#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)
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);
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 usbx_pcdc_operations(void );
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);
void pcdc_dfu_thread_entry (void )
{
UINT status = UX_SUCCESS;
ULONG actual_flags = 0x0000;
UX_SLAVE_CLASS_DFU * dfu;
UCHAR state;
status = ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
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;
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);
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))
{
}
else if (!(actual_flags & CDCACM_ACTIVATE_FLAG))
{
}
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);
}
}
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;
if (device->ux_slave_device_state != UX_DEVICE_CONFIGURED)
{
return ;
}
memset(g_buf, RESET_VALUE, sizeof (g_buf));
status = ux_device_class_cdc_acm_read(g_cdc, g_buf, DATA_LEN, &g_actual_length);
data_size = g_actual_length;
state = ux_device_class_dfu_state_get(dfu);
if (UX_SYSTEM_DFU_STATE_APP_DETACH == state)
{
return ;
}
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)
{
ux_device_class_cdc_acm_write(g_cdc, g_buf, 0, &g_actual_length);
}
}
static void ux_cdc_device0_instance_activate (void * cdc_instance)
{
g_cdc = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR);
}
static void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
g_cdc = UX_NULL;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_DEACTIVATE_FLAG, TX_OR);
}
static void ux_dfu_device0_instance_activate (void * dfu_instance)
{
g_dfu = (UX_SLAVE_CLASS_DFU *) dfu_instance;
tx_event_flags_set(&g_dfu_event_flags0, DFU_ACTIVATE_FLAG, TX_OR);
}
static void ux_dfu_device0_instance_deactivate (void * dfu_instance)
{
g_dfu = UX_NULL;
tx_event_flags_set(&g_dfu_event_flags0, DFU_DEACTIVATE_FLAG, TX_OR);
}
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 :
{
break ;
}
}
return 0;
}
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);
}
}
}
static UINT dfu_dammy_write (
VOID * dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG * media_status)
{
return 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;
}
static UINT dfu_dammy_notify (
VOID * dfu, ULONG notification)
{
return UX_SUCCESS;
}
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 ;
}
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);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
}
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++;
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);
if (FSP_SUCCESS != err)
{
while (1)
{
;
}
}
}
USBX Composite Example
USBX Composite (PCDC + PMSC) example is as follows.
static uint32_t g_ux_pool_memory[MEMPOOL_SIZE / BYTE_SIZE];
static ULONG actual_flags = RESET_VALUE;
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 ;
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 );
void usbx_composite_pcdc_mmsc_sample (void )
{
ux_system_initialize(g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, RESET_VALUE);
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_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);
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)
{
;
}
actual_flags = RESET_VALUE;
while (true )
{
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))
{
actual_flags = RESET_VALUE;
}
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))
{
actual_flags = RESET_VALUE;
}
usbx_pcdc_operations();
tx_thread_sleep(1);
}
}
UINT usbx_status_callback (ULONG status)
{
switch (status)
{
case UX_DEVICE_ATTACHED:
{
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:
{
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 :
{
break ;
}
}
return 0;
}
static void ux_cdc_device0_instance_activate (void * cdc_instance)
{
g_cdc = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR);
}
static void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
g_cdc = UX_NULL;
tx_event_flags_set(&g_cdcacm_event_flags0, CDCACM_DEACTIVATE_FLAG, TX_OR);
}
static void usb_connection_status_check (void )
{
ULONG actual_flags = RESET_VALUE;
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 ;
}
else
{
}
}
else
{
b_print_status = false ;
while (!(actual_flags & CDCACM_FLAG))
{
;
}
}
}
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;
usb_connection_status_check();
tx_event_flags_get(&g_cdcacm_event_flags0, CDCACM_ACTIVATE_FLAG, TX_OR, &actual_flags, TX_WAIT_FOREVER);
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);
memset(g_buf, RESET_VALUE, sizeof (g_buf));
ux_device_class_cdc_acm_read(g_cdc, g_buf, DATA_LEN, &g_actual_length);
data_size = g_actual_length;
ux_device_class_cdc_acm_write(g_cdc, g_buf, data_size, &g_actual_length);
}
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;
UINT apl_status_change_cb (ULONG status)
{
if ((UX_DEVICE_REMOVED == g_apl_status_peri) && (UX_DEVICE_RESUMED == status))
{
return UX_SUCCESS;
}
g_apl_status_peri = status;
return UX_SUCCESS;
}
void ux_cdc_device0_instance_activate (void * cdc_instance)
{
g_p_cdc_peri = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
}
void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
g_p_cdc_peri = UX_NULL;
}
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;
}
void apl_otg_sample (void )
{
uint8_t is_host_request_flag = USB_NO;
uint8_t is_host_apl_complete = USB_NO;
ux_system_initialize((CHAR *) g_ux_pool_memory, MEMPOOL_SIZE, UX_NULL, 0);
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);
ux_host_stack_initialize(ux_host_usr_event_notification);
#if defined(APL_USB_OTG_A_DEVICE)
assert(FSP_SUCCESS == err);
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
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 :
{
is_host_request_flag = USB_NO;
is_host_apl_complete = USB_NO;
break ;
}
}
}
}
}
UINT ux_host_usr_event_notification (ULONG event, UX_HOST_CLASS * host_class,
VOID * instance)
{
(void) host_class;
if (UX_DEVICE_INSERTION == event)
{
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)
{
g_p_cdc_host = g_p_cdc_host->ux_host_class_cdc_acm_next_instance;
if (UX_HOST_CLASS_CDC_DATA_CLASS !=
g_p_cdc_host->ux_host_class_cdc_acm_interface->ux_interface_descriptor.bInterfaceClass)
{
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))
{
g_host_apl_event = UX_DEVICE_REMOVAL;
g_p_cdc_host = UX_NULL;
}
return UX_SUCCESS;
}
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 ;
}
}
}
void ux_cdc_device0_instance_activate (void * cdc_instance)
{
g_p_cdc_peri = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
}
void ux_cdc_device0_instance_deactivate (void * cdc_instance)
{
g_p_cdc_peri = UX_NULL;
}
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;
}