This USB driver works by combining USBX and r_usb_basic module.
The following describes how to configure USBX using PCDC as an example.
Since HMSC is used in a different way from other USBX modules, the usage is described below.
For more information on FileX, please refer to the following URL.
Templates for USBX descriptors can be found in rx/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.
PCDC loopback example is as follows.
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);
}
}