Atmel Software Framework

Quick start guide for USB Device Vendor module (UDI Vendor)

This is the quick start guide for the USB device interface Vendor module (UDI Vendor) 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.

Also, you can refer to application note AVR4901: ASF - USB Device Vendor Class Application.

Basic use case

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

Setup steps

Prerequisites

This module is based on USB device stack full interrupt driven, and supporting Sleep manager sleepmgr. For AVR and SAM3/4 devices the Clock Management clock services is supported. For SAMD devices the asfdoc_sam0_system_clock_group clock driver is supported.

The following procedure must be executed to setup the project correctly:

  • Specify the clock configuration:
    • XMEGA USB devices need 48MHz clock input.
      XMEGA USB devices need CPU frequency higher than 12MHz.
      You can use either an internal RC48MHz auto calibrated by Start of Frames or an external OSC.
    • UC3 and SAM3/4 devices without USB high speed support need 48MHz clock input.
      You must use a PLL and an external OSC.
    • UC3 and SAM3/4 devices with USB high speed support need 12MHz clock input.
      You must use an external OSC.
    • UC3 devices with USBC hardware need CPU frequency higher than 25MHz.
    • SAMD devices without USB high speed support need 48MHz clock input.
      You should use DFLL with USBCRM.
  • In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. (Not mandatory for all boards)
  • Enable interrupts
  • Initialize the clock service

The usage of Sleep manager sleepmgr service is optional, but recommended to reduce power consumption:

  • Initialize the sleep manager service
  • Activate sleep mode when the application is in IDLE state

conf_clock.h examples with USB support.

for AVR and SAM3/4 devices, add to the initialization code:

For SAMD devices, add to the initialization code:

system_init();
sleepmgr_init(); // Optional

Add to the main IDLE loop:

sleepmgr_enter_sleep(); // Optional

Example code

Content of conf_usb.h:

#define USB_DEVICE_VENDOR_ID 0x03EB
#define USB_DEVICE_PRODUCT_ID 0xXXXX
#define USB_DEVICE_MAJOR_VERSION 1
#define USB_DEVICE_MINOR_VERSION 0
#define USB_DEVICE_POWER 100
#define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED

Add to application C-file:

void usb_init(void)
{
}

Workflow

  1. Ensure that conf_usb.h is available and contains the following configuration which is the main USB device configuration:
// Vendor ID provided by USB org (ATMEL 0x03EB)
#define USB_DEVICE_VENDOR_ID 0x03EB // Type Word
// Product ID (Atmel PID referenced in usb_atmel.h)
#define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word
// Major version of the device
#define USB_DEVICE_MAJOR_VERSION 1 // Type Byte
// Minor version of the device
#define USB_DEVICE_MINOR_VERSION 0 // Type Byte
// Maximum device power (mA)
#define USB_DEVICE_POWER 100 // Type 9-bits
// USB attributes to enable features
#define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags
  1. Call the USB device stack start function to enable stack and start USB:
    • Note
      In case of USB dual roles (Device and Host) managed through USB OTG connector (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles.

Usage steps

Example code

Content of conf_usb.h:

* #define UDI_VENDOR_ENABLE_EXT() my_callback_vendor_enable()
* extern bool my_callback_vendor_enable(void);
* #define UDI_VENDOR_DISABLE_EXT() my_callback_vendor_disable()
* extern void my_callback_vendor_disable(void);
*
* #define UDI_VENDOR_SETUP_OUT_RECEIVED() my_vendor_setup_out_received()
* extern bool my_vendor_setup_out_received(void);
* #define UDI_VENDOR_SETUP_IN_RECEIVED() my_vendor_setup_in_received()
* extern bool my_vendor_setup_in_received(void);
*
* #define UDI_VENDOR_EPS_SIZE_INT_FS 64
* #define UDI_VENDOR_EPS_SIZE_BULK_FS 64
* #define UDI_VENDOR_EPS_SIZE_ISO_FS 256
* #define UDI_VENDOR_EPS_SIZE_INT_HS 64
* #define UDI_VENDOR_EPS_SIZE_BULK_HS 512
* #define UDI_VENDOR_EPS_SIZE_ISO_HS 64
* #include "udi_vendor_conf.h" // At the end of conf_usb.h file

Add to application C-file:

static bool my_flag_autorize_vendor_transfert = false;
bool my_callback_vendor_enable(void)
{
my_flag_autorize_vendor_transfert = true;
return true;
}
void my_callback_vendor_disable(void)
{
my_flag_autorize_vendor_transfert = false;
}
uint8_t global_buffer[X];
void task(void)
{
if (my_flag_autorize_vendor_transfert) {
// Enable a transfer on OUT interrupt endpoint
global_buffer,
sizeof(global_buffer),
NULL);
// Enable a transfer on IN interrupt endpoint
global_buffer,
sizeof(global_buffer),
NULL);
...
}
}

Workflow

  1. Ensure that conf_usb.h is available and contains the following configuration which is the USB device Vendor configuration:
    • #define UDI_VENDOR_ENABLE_EXT() my_callback_vendor_enable()
      extern bool my_callback_vendor_enable(void);
      Note
      After the device enumeration (detecting and identifying USB devices), the USB host starts the device configuration. When the USB Vendor interface from the device is accepted by the host, the USB host enables this interface and the UDI_VENDOR_ENABLE_EXT() callback function is called and return true. Thus, when this event is received, the Vendor transfers can start.
    • #define UDI_VENDOR_DISABLE_EXT() my_callback_vendor_disable()
      extern void my_callback_vendor_disable(void);
      Note
      When the USB device is unplugged or is reset by the USB host, the USB interface is disabled and the UDI_VENDOR_DISABLE_EXT() callback function is called. Thus, it is recommended to disable the data Vendor transfer.
    • #define UDI_VENDOR_SETUP_OUT_RECEIVED() my_vendor_setup_out_received()
      extern bool my_vendor_setup_out_received(void);
      #define UDI_VENDOR_SETUP_IN_RECEIVED() my_vendor_setup_in_received()
      extern bool my_vendor_setup_in_received(void);
      Note
      The control requests for the interface Vendor will be processed through these both callbacks.
    • #define UDI_VENDOR_EPS_SIZE_INT_FS 64
      #define UDI_VENDOR_EPS_SIZE_BULK_FS 64
      #define UDI_VENDOR_EPS_SIZE_ISO_FS 256
      #define UDI_VENDOR_EPS_SIZE_INT_HS 64
      #define UDI_VENDOR_EPS_SIZE_BULK_HS 512
      #define UDI_VENDOR_EPS_SIZE_ISO_HS 64
      Note
      The endpoint size is defined by the final application, and can be disabled if the full speed size is zero.
  2. The Vendor transfers on interrupt, bulk and isochronous endpoints are done through these functions:

Advanced use cases

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