Microchip® Advanced Software Framework

Quick Start Guide for USB Device Mass Storage Module (UDI MSC)

This is the quick start guide for the USB Device Interface MSC Module (UDI MSC) with step-by-step instructions on how to configure and use the modules in a selection of use cases.

The use cases contain several code fragments. The code fragments in the steps for setup can be copied into a custom initialization function, while the steps for usage can be copied into, e.g., the main application function.

Basic Use Case

In this basic use case, the "USB MSC (Single Interface Device)" module is used. The "USB MSC (Composite Device)" module usage is described in Advanced Use Cases.

Setup Steps

As a USB device, it follows common USB device setup steps. Refer to USB Device Basic Setup.

The USB MSC interface accesses Memory through Common Abstraction Layer (ctrl_access) in ASF. See Common Abstraction Layer for Memory Interfaces.

Common Abstraction Layer for Memory Interfaces

Common abstraction layer (ctrl_access) can provide interfaces between Memory and USB. In USB MSC UDI the read/write invokes following ctrl_access functions:

extern Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector);
extern Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector);

Then the ctrl_access dispatch the read/write operation to different Logic Unit Numbers (LUNs).

The memory access in ctrl_access is configured through conf_access.h. E.g., to use LUN0 to access virtual memory disk, the configuration should include:

#define LUN_0 ENABLE // Enable LUN0 access
//...
#define VIRTUAL_MEM LUN_0
#define LUN_ID_VIRTUAL_MEM LUN_ID_0
#define LUN_0_INCLUDE "virtual_mem.h" // APIs (complied to ctrl_access)
#define Lun_0_test_unit_ready virtual_test_unit_ready // check disk ready
#define Lun_0_read_capacity virtual_read_capacity // get disk size
#define Lun_0_wr_protect virtual_wr_protect // check protection
#define Lun_0_removal virtual_removal // check if disk is removable
#define Lun_0_usb_read_10 virtual_usb_read_10 // Disk to USB transfer
#define Lun_0_usb_write_10 virtual_usb_write_10 // USB to Disk transfer
#define LUN_0_NAME "\"On-Chip Virtual Memory\""
//...
#define ACCESS_USB true // USB interface.
//...
#define GLOBAL_WR_PROTECT false

Since LUN_0 is defined as a "Virtual Memory", the module to encapsulate the internal or on-board memory to access as a disk is included. The configuration of such a virtual memory disk is in conf_virtual_mem.h. E.g., to use internal RAM to build such a memory disk, the configuration should include:

#define VMEM_NB_SECTOR 48 //Internal RAM 24KB (should > 20KB or PC can not format it)

For more examples of the control access or disk configuration, refer to conf_access.h and conf_virtual_mem.h.

For more Information about Memory Control Access, refer to the online document:

Usage Steps

Example Code

Content of conf_usb.h:

#define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for MSC
#define UDI_MSC_GLOBAL_VENDOR_ID \
'A', 'T', 'M', 'E', 'L', ' ', ' ', ' '
#define UDI_MSC_GLOBAL_PRODUCT_VERSION \
'1', '.', '0', '0'
#define UDI_MSC_ENABLE_EXT() my_callback_msc_enable()
extern bool my_callback_msc_enable(void);
#define UDI_MSC_DISABLE_EXT() my_callback_msc_disable()
extern void my_callback_msc_disable(void);
#include "udi_msc_conf.h" // At the end of conf_usb.h file

Add to application C-file:

static bool my_flag_autorize_msc_transfert = false;
bool my_callback_msc_enable(void)
{
my_flag_autorize_msc_transfert = true;
return true;
}
void my_callback_msc_disable(void)
{
my_flag_autorize_msc_transfert = false;
}
void task(void)
{
}

Workflow

  1. Ensure that conf_usb.h is available and contains the following configuration, which is the USB device MSC configuration:
    #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for MSC
    Note
    The USB serial number is mandatory when a MSC interface is used.
    #define UDI_MSC_GLOBAL_VENDOR_ID \
    'A', 'T', 'M', 'E', 'L', ' ', ' ', ' '
    #define UDI_MSC_GLOBAL_PRODUCT_VERSION \
    '1', '.', '0', '0'
    Note
    The USB MSC interface requires a vendor ID (eight ASCII characters) and a product version (four ASCII characters).
    #define UDI_MSC_ENABLE_EXT() my_callback_msc_enable()
    extern bool my_callback_msc_enable(void);
    Note
    After the device enumeration (detecting and identifying USB devices), the USB host starts the device configuration. When the USB MSC interface from the device is accepted by the host, the USB host enables this interface and the UDI_MSC_ENABLE_EXT() callback function is called and return true. Thus, when this event is received, the tasks which call udi_msc_process_trans() must be enabled.
    #define UDI_MSC_DISABLE_EXT() my_callback_msc_disable()
    extern void my_callback_msc_disable(void);
    Note
    When the USB device is unplugged or is reset by the USB host, the USB interface is disabled and the UDI_MSC_DISABLE_EXT() callback function is called. Thus, it is recommended to disable the task which is called udi_msc_process_trans().
  2. The MSC is automatically linked with memory control access component which provides the memories interfaces. However, the memory data transfers must be done outside USB interrupt routine. This is done in the MSC process ("udi_msc_process_trans()") called by main loop:
    void task(void) {
    }
  3. The MSC speed depends on task periodicity. To get the best speed the notification callback "UDI_MSC_NOTIFY_TRANS_EXT" can be used to wakeup this task (Example, through a mutex):
    #define UDI_MSC_NOTIFY_TRANS_EXT() msc_notify_trans()
    void msc_notify_trans(void) {
    wakeup_my_task();
    }

Advanced Use Cases

For more advanced use of the UDI MSC module, see the following use cases: