/** * \file * * \brief USB Device Controller (UDC) * * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. * * \asf_license_start * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an * Atmel microcontroller product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * \asf_license_stop * */ /** * \if ASF_MANUAL * \defgroup asfdoc_udc_group USB Device Controller (UDC) * * The UDC provides a high-level abstraction of the USB device. * You can use these functions to control the main device state * (start/attach/wakeup). * * All USB Device Interface (UDI) in USB Device Stack is based on UDC to support * USB enumeration. * * This documentation describes common USB Device usage based on UDC, as follow: * - \ref asfdoc_udc_api_overview * - \ref asfdoc_udc_basic_use_case_setup * - \ref asfdoc_udc_use_cases * * \section asfdoc_udc_api_overview API Overview * @{ * */ /** * \brief Authorizes the VBUS event * * \return True, if the VBUS monitoring is possible. * * See \ref asfdoc_udc_vbus_monitoring for more details. * */ static inline bool udc_include_vbus_monitoring(void) { return udd_include_vbus_monitoring(); } /** * \brief Start the USB Device stack */ void udc_start(void); /** * \brief Stop the USB Device stack */ void udc_stop(void); /** * \brief Attach device to the bus when possible * * \warning If a VBUS control is included in driver, * then it will attach device when an acceptable VBUS * level from the host is detected. */ static inline void udc_attach(void) { udd_attach(); } /** * \brief Detaches the device from the bus * * The driver must remove pull-up on USB line D- or D+. */ static inline void udc_detach(void) { udd_detach(); } /** * \brief The USB driver sends a resume signal called \e "Upstream Resume" * * This is authorized only when the remote wakeup feature is enabled by host. */ static inline void udc_remotewakeup(void) { udd_send_remotewakeup(); } /** * \brief Returns a pointer on the current interface descriptor * * \return Pointer on the current interface descriptor. */ usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); /** * @} * \endif */ /* * Support and FAQ: visit Atmel Support */ /** * \page asfdoc_udc_basic_use_case_setup USB Device Basic Setup * * \section asfdoc_udc_device_cfg Custom Configuration * * The following USB Device configuration must be included in the conf_usb.h * file of the application: * * \b 1. USB_DEVICE_VENDOR_ID (Word). * * Vendor ID provided by USB org (Atmel 0x03EB). * * \b 2. USB_DEVICE_PRODUCT_ID (Word). * * Product ID (Referenced in usb_atmel.h). * * \b 3. USB_DEVICE_MAJOR_VERSION (Byte). * * Major version of the device. * * \b 4. USB_DEVICE_MINOR_VERSION (Byte). * * Minor version of the device. * * \b 5. USB_DEVICE_MANUFACTURE_NAME (string). * * ASCII name for the manufacture. * * \b 6. USB_DEVICE_PRODUCT_NAME (string). * * ASCII name for the product. * * \b 7. USB_DEVICE_SERIAL_NAME (string). * * ASCII name to enable and set a serial number. * * \b 8. USB_DEVICE_POWER (Numeric). * * (unit mA) Maximum device power. * * \b 9. USB_DEVICE_ATTR (Byte). * * USB attributes available: * - USB_CONFIG_ATTR_SELF_POWERED * - USB_CONFIG_ATTR_REMOTE_WAKEUP * * \note If remote wake is enabled, this defines remotewakeup callbacks. * * \b 10. USB_DEVICE_LOW_SPEED (Only defined). * * Force the USB Device to run in low speed. * * \b 11. USB_DEVICE_HS_SUPPORT (Only defined). * * Authorize the USB Device to run in high speed. * * \b 12. USB_DEVICE_MAX_EP (Byte). * * Define the maximum endpoint number used by the USB Device. * * This one is already defined in the UDI default configuration. * E.g.: * - When endpoint control 0x00, endpoint 0x01, and * endpoint 0x82 is used, then USB_DEVICE_MAX_EP=2 * - When only endpoint control 0x00 is used, then USB_DEVICE_MAX_EP=0 * - When endpoint 0x01 and endpoint 0x81 is used, then USB_DEVICE_MAX_EP=1 * (configuration not possible on USBB interface) * * \section asfdoc_udc_vbus_monitoring VBUS Monitoring * * The VBUS monitoring is used only for USB SELF Power application. * * - By default the USB device is automatically attached when VBUS is high * or when USB starts for devices without internal VBUS monitoring. * conf_usb.h file does not contain definition USB_DEVICE_ATTACH_AUTO_DISABLE. * \code //#define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode * * - Add custom VBUS monitoring. conf_usb.h file contains define * USB_DEVICE_ATTACH_AUTO_DISABLE: * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode * User C-file contains: * \code // Authorize VBUS monitoring if (!udc_include_vbus_monitoring()) { // Implement custom VBUS monitoring via GPIO or other } Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other { // Attach USB Device udc_attach(); } \endcode * * - Case of battery charging. conf_usb.h file contains define * USB_DEVICE_ATTACH_AUTO_DISABLE: * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode * User C-file contains: * \code Event VBUS present() // VBUS interrupt or GPIO interrupt or .. { // Authorize battery charging, but wait key press to start USB. } Event Key press() { // Stop batteries charging // Start USB udc_attach(); } \endcode * * \section asfdoc_udc_basic_use_case_setup USB Device Setup Steps * * \subsection asfdoc_udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites * * Common prerequisites for all USB devices. * * This module is based on USB device stack full interrupt driven, and supporting * \ref sleepmgr_group "sleepmgr". * For AVR® and Atmel® | SMART ARM®-based SAM3/4 devices the * \ref clk_group "clock services" is supported. * For SAM D21 devices the \ref asfdoc_sam0_system_clock_group "clock driver" is supported. * * The following procedure must be executed to set up 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 RC 48MHz 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 * - SAM D21 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 \ref sleepmgr_group "sleep manager" service is optional, but recommended to reduce power * consumption: * - Initialize the sleep manager service * - Activate sleep mode when the application is in IDLE state * * For AVR and SAM3/4 devices, add to the initialization code: * \code sysclk_init(); irq_initialize_vectors(); cpu_irq_enable(); board_init(); sleepmgr_init(); // Optional \endcode * * For SAM D21 devices, add to the initialization code: * \code system_init(); irq_initialize_vectors(); cpu_irq_enable(); sleepmgr_init(); // Optional \endcode * * Add to the main IDLE loop: * \code sleepmgr_enter_sleep(); // Optional \endcode * * \subsection asfdoc_udc_basic_use_case_setup_code USB Device Controller (UDC) - Example Code * Common example code for all USB devices. * * Content of conf_usb.h: * \code #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 \endcode * * Add to application C-file: * \code void usb_init(void) { udc_start(); } \endcode * * \subsection asfdoc_udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow * Common workflow for all USB devices. * * -# Ensure that conf_usb.h is available and contains the following configuration, * which is the main USB device configuration: * \code // 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 \endcode * * -# Call the USB device stack start function to enable stack and start USB: * \code udc_start(); \endcode * * \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(). * Refer to section "Dual roles" for further information in the application note: * * Atmel AVR4950: ASF - USB Host Stack * * \section udc_conf_clock conf_clock.h Examples * * Content of XMEGA conf_clock.h: * \code // Configuration based on internal RC: // USB clock need of 48MHz #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC #define CONFIG_OSC_RC32_CAL 48000000UL #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 \endcode * * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, and AT32UC3B devices (USBB): * \code // Configuration based on 12MHz external OSC: #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 #define CONFIG_PLL1_MUL 8 #define CONFIG_PLL1_DIV 2 #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) \endcode * * Content of conf_clock.h for AT32UC3A3 and AT32UC3A4 devices (USBB with high speed support): * \code // Configuration based on 12MHz external OSC: #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) \endcode * * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, and ATUCXXL4U devices (USBC): * \code // Configuration based on 12MHz external OSC: #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 #define CONFIG_PLL1_MUL 8 #define CONFIG_PLL1_DIV 2 #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) // CPU clock need of clock > 25MHz to run with USBC #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 \endcode * * Content of conf_clock.h for SAM3S, SAM3SD, and SAM4S devices (UPD: USB Peripheral Device): * \code // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL #define CONFIG_PLL1_MUL 16 #define CONFIG_PLL1_DIV 2 // USB Clock Source Options (Fusb = FpllX / USB_div) #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 #define CONFIG_USBCLK_DIV 2 \endcode * * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): * \code // USB Clock Source fixed at UPLL. \endcode * * Content of conf_clock.h for SAM3X and SAM3A devices (UOTGHS: USB OTG High Speed): * \code // USB Clock Source fixed at UPLL. #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL #define CONFIG_USBCLK_DIV 1 \endcode * * Content of conf_clocks.h for SAM D21 devices (USB): * \code // System clock bus configuration # define CONF_CLOCK_FLASH_WAIT_STATES 2 // USB Clock Source fixed at DFLL. // SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop # define CONF_CLOCK_DFLL_ENABLE true # define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY # define CONF_CLOCK_DFLL_ON_DEMAND true // Set this to true to configure the GCLK when running clocks_init. // If set to false, none of the GCLK generators will be configured in clocks_init(). # define CONF_CLOCK_CONFIGURE_GCLK true // Configure GCLK generator 0 (Main Clock) # define CONF_CLOCK_GCLK_0_ENABLE true # define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY true # define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL # define CONF_CLOCK_GCLK_0_PRESCALER 1 # define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false \endcode * */ /** * \if ASF_MANUAL * \page asfdoc_udc_use_cases USB Device Advanced Use Cases * - \subpage udc_use_case_1 * - \subpage udc_use_case_2 * - \subpage udc_use_case_3 * - \subpage udc_use_case_5 * - \subpage udc_use_case_6 * \endif */ /** * \page udc_use_case_1 Change USB Speed * * In this use case, the USB device is used with different USB speeds. * * \section udc_use_case_1_setup Setup Steps * * Prior to implement this use case, be sure to have already * applied the UDI module "basic use case". * * \section udc_use_case_1_usage Usage Steps * * \subsection udc_use_case_1_usage_code Example Code * Content of conf_usb.h: * \code #if // Low speed #define USB_DEVICE_LOW_SPEED // #define USB_DEVICE_HS_SUPPORT #elif // Full speed // #define USB_DEVICE_LOW_SPEED // #define USB_DEVICE_HS_SUPPORT #elif // High speed // #define USB_DEVICE_LOW_SPEED #define USB_DEVICE_HS_SUPPORT #endif \endcode * * \subsection udc_use_case_1_usage_flow Workflow * -# Ensure that conf_usb.h is available and contains the following parameters * required for a USB device low speed (1.5Mbit/s): * \code #define USB_DEVICE_LOW_SPEED //#define USB_DEVICE_HS_SUPPORT \endcode * -# Ensure that conf_usb.h contains the following parameters * required for a USB device full speed (12Mbit/s): * \code //#define USB_DEVICE_LOW_SPEED //#define USB_DEVICE_HS_SUPPORT \endcode * -# Ensure that conf_usb.h contains the following parameters * required for a USB device high speed (480Mbit/s): * \code //#define USB_DEVICE_LOW_SPEED #define USB_DEVICE_HS_SUPPORT \endcode */ /** * \page udc_use_case_2 Use USB Strings * * In this use case, the usual USB strings are added in the USB device. * * \section udc_use_case_2_setup Setup Steps * Prior to implement this use case, be sure to have already * applied the UDI module "basic use case". * * \section udc_use_case_2_usage Usage Steps * * \subsection udc_use_case_2_usage_code Example Code * Content of conf_usb.h: * \code #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" #define USB_DEVICE_PRODUCT_NAME "Product name" #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode * * \subsection udc_use_case_2_usage_flow Workflow * -# Ensure that conf_usb.h is available and contains the following parameters * required to enable different USB strings: * \code // Static ASCII name for the manufacture #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode * \code // Static ASCII name for the product #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode * \code // Static ASCII name to enable and set a serial number #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode */ /** * \page udc_use_case_3 Use USB Remote Wakeup Feature * * In this use case, the USB remote wakeup feature is enabled. * * \section udc_use_case_3_setup Setup Steps * Prior to implement this use case, be sure to have already * applied the UDI module "basic use case". * * \section udc_use_case_3_usage Usage Steps * * \subsection udc_use_case_3_usage_code Example Code * Content of conf_usb.h: * \code #define USB_DEVICE_ATTR \ (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() extern void my_callback_remotewakeup_enable(void); #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() extern void my_callback_remotewakeup_disable(void); \endcode * * Add to application C-file: * \code void my_callback_remotewakeup_enable(void) { // Enable application wakeup events (e.g. enable GPIO interrupt) } void my_callback_remotewakeup_disable(void) { // Disable application wakeup events (e.g. disable GPIO interrupt) } void my_interrupt_event(void) { udc_remotewakeup(); } \endcode * * \subsection udc_use_case_3_usage_flow Workflow * -# Ensure that conf_usb.h is available and contains the following parameters * required to enable the remote wakeup feature: * \code // Authorizes the remote wakeup feature #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode * \code // Define callback called when the host enables the remotewakeup feature #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() extern void my_callback_remotewakeup_enable(void); \endcode * \code // Define callback called when the host disables the remotewakeup feature #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() extern void my_callback_remotewakeup_disable(void); \endcode * -# Send a remote wakeup (USB upstream): * \code udc_remotewakeup(); \endcode */ /** * \page udc_use_case_5 Bus Power Application Recommendations * * In this use case, the USB device bus power feature is enabled. * This feature requires a correct power consumption management. * * \section udc_use_case_5_setup Setup Steps * Prior to implement this use case, be sure to have already * applied the UDI module "basic use case". * * \section udc_use_case_5_usage Usage Steps * * \subsection udc_use_case_5_usage_code Example Code * Content of conf_usb.h: * \code #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) #define UDC_SUSPEND_EVENT() user_callback_suspend_action() extern void user_callback_suspend_action(void) #define UDC_RESUME_EVENT() user_callback_resume_action() extern void user_callback_resume_action(void) \endcode * * Add to application C-file: * \code void user_callback_suspend_action(void) { // Disable hardware component to reduce power consumption } void user_callback_resume_action(void) { // Re-enable hardware component } \endcode * * \subsection udc_use_case_5_usage_flow Workflow * -# Ensure that conf_usb.h is available and contains the following parameters: * \code // Authorizes the BUS power feature #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode * \code // Define callback called when the host suspend the USB line #define UDC_SUSPEND_EVENT() user_callback_suspend_action() extern void user_callback_suspend_action(void); \endcode * \code // Define callback called when the host or device resume the USB line #define UDC_RESUME_EVENT() user_callback_resume_action() extern void user_callback_resume_action(void); \endcode * -# Reduce power consumption in suspend mode (max. 2.5mA on VBUS): * \code void user_callback_suspend_action(void) { turn_off_components(); } \endcode */ /** * \page udc_use_case_6 USB Dynamic Serial Number * * In this use case, the USB serial strings are dynamic. * For a static serial string refer to \ref udc_use_case_2. * * \section udc_use_case_6_setup Setup Steps * Prior to implement this use case, be sure to have already * applied the UDI module "basic use case". * * \section udc_use_case_6_usage Usage Steps * * \subsection udc_use_case_6_usage_code Example Code * Content of conf_usb.h: * \code #define USB_DEVICE_SERIAL_NAME #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 extern uint8_t serial_number[]; \endcode * * Add to application C-file: * \code uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; void init_build_usb_serial_number(void) { serial_number[0] = 'A'; serial_number[1] = 'B'; ... serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; } \endcode * * \subsection udc_use_case_6_usage_flow Workflow * -# Ensure that conf_usb.h is available and contains the following parameters * required to enable a USB serial number string dynamically: * \code #define USB_DEVICE_SERIAL_NAME // Define this empty #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array extern uint8_t serial_number[]; // Declare external serial array \endcode * -# Before starting USB stack, initialize the serial array: * \code uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; void init_build_usb_serial_number(void) { serial_number[0] = 'A'; serial_number[1] = 'B'; ... serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; } \endcode */