diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index defbf15916ce2..35db9b69dd269 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -38,6 +38,10 @@ INC += -Iasf/common/services/storage/ctrl_access/ INC += -Iasf/common/services/usb/ INC += -Iasf/common/services/usb/class/cdc/ INC += -Iasf/common/services/usb/class/cdc/device/ +INC += -Iasf/common/services/usb/class/hid/ +INC += -Iasf/common/services/usb/class/hid/device/ +INC += -Iasf/common/services/usb/class/hid/device/kbd/ +INC += -Iasf/common/services/usb/class/hid/device/mouse/ INC += -Iasf/common/services/usb/class/msc/ INC += -Iasf/common/services/usb/class/msc/device/ INC += -Iasf/common/services/usb/udc/ @@ -183,6 +187,9 @@ SRC_C = \ asf/common/services/storage/ctrl_access/ctrl_access.c \ asf/common/services/usb/class/cdc/device/udi_cdc.c \ asf/common/services/usb/class/composite/device/udi_composite_desc.c \ + asf/common/services/usb/class/hid/device/udi_hid.c \ + asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.c \ + asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c \ asf/common/services/usb/class/msc/device/udi_msc.c \ asf/common/services/usb/udc/udc.c \ asf/common/utils/interrupt/interrupt_sam_nvic.c \ @@ -221,7 +228,9 @@ SRC_BINDINGS = \ nativeio/SPI.c \ nativeio/UART.c \ neopixel_write/__init__.c \ - time/__init__.c + time/__init__.c \ + usb_hid/__init__.c \ + usb_hid/Device.c SRC_BINDINGS_EXPANDED = $(addprefix shared-bindings/, $(SRC_BINDINGS)) \ $(addprefix common-hal/, $(SRC_BINDINGS)) diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/generic/module_config/conf_usb.h b/atmel-samd/asf/common/services/usb/class/hid/device/generic/module_config/conf_usb.h new file mode 100644 index 0000000000000..1430da240db64 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/generic/module_config/conf_usb.h @@ -0,0 +1,158 @@ +/** + * \file + * + * \brief USB configuration file + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _CONF_USB_H_ +#define _CONF_USB_H_ + +#include "compiler.h" + +#warning You must refill the following definitions with a correct values + +/** + * USB Device Configuration + * @{ + */ + +//! Device definition (mandatory) +#define USB_DEVICE_VENDOR_ID USB_VID_ATMEL +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_ASF_HIDGENERIC +#define USB_DEVICE_MAJOR_VERSION 1 +#define USB_DEVICE_MINOR_VERSION 0 +#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) +#define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) + +//! USB Device string definitions (Optional) +// #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" +// #define USB_DEVICE_PRODUCT_NAME "Product name" +// #define USB_DEVICE_SERIAL_NAME "12...EF" + +/** + * Device speeds support + * @{ + */ +//! To define a Low speed device +//#define USB_DEVICE_LOW_SPEED + +//! To authorize the High speed +#if (UC3A3||UC3A4) +//#define USB_DEVICE_HS_SUPPORT +#endif +//@} + +/** + * USB Device Callbacks definitions (Optional) + * @{ + */ +// #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) +// extern void user_callback_vbus_action(bool b_vbus_high); +// #define UDC_SOF_EVENT() user_callback_sof_action() +// extern void user_callback_sof_action(void); +// #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); +//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature +// #define UDC_REMOTEWAKEUP_ENABLE() user_callback_remotewakeup_enable() +// extern void user_callback_remotewakeup_enable(void); +// #define UDC_REMOTEWAKEUP_DISABLE() user_callback_remotewakeup_disable() +// extern void user_callback_remotewakeup_disable(void); +//! When a extra string descriptor must be supported +//! other than manufacturer, product and serial string +// #define UDC_GET_EXTRA_STRING() +//@} + +//@} + + +/** + * USB Interface Configuration + * @{ + */ +/** + * Configuration of HID Generic interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_GENERIC_ENABLE_EXT() true +#define UDI_HID_GENERIC_DISABLE_EXT() +#define UDI_HID_GENERIC_REPORT_OUT(ptr) +#define UDI_HID_GENERIC_SET_FEATURE(f) +/* + * #define UDI_HID_GENERIC_ENABLE_EXT() my_callback_generic_enable() + * extern bool my_callback_generic_enable(void); + * #define UDI_HID_GENERIC_DISABLE_EXT() my_callback_generic_disable() + * extern void my_callback_generic_disable(void); + * #define UDI_HID_GENERIC_REPORT_OUT(ptr) my_callback_generic_report_out(ptr) + * extern void my_callback_generic_report_out(uint8_t *report); + * #define UDI_HID_GENERIC_SET_FEATURE(f) my_callback_generic_set_feature(f) + * extern void my_callback_generic_set_feature(uint8_t *report_feature); + */ + +//! Sizes of I/O reports +#define UDI_HID_REPORT_IN_SIZE 64 +#define UDI_HID_REPORT_OUT_SIZE 64 +#define UDI_HID_REPORT_FEATURE_SIZE 4 + +//! Sizes of I/O endpoints +#define UDI_HID_GENERIC_EP_SIZE 64 +//@} +//@} + + +/** + * USB Device Driver Configuration + * @{ + */ +//@} + +//! The includes of classes and other headers must be done at the end of this file to avoid compile error +#include "udi_hid_generic_conf.h" + +#endif // _CONF_USB_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic.c b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic.c new file mode 100644 index 0000000000000..aa0df32f95714 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic.c @@ -0,0 +1,313 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) generic interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc.h" +#include "udi_hid.h" +#include "udi_hid_generic.h" +#include + +/** + * \ingroup udi_hid_generic_group + * \defgroup udi_hid_generic_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_hid_generic_enable(void); +void udi_hid_generic_disable(void); +bool udi_hid_generic_setup(void); +uint8_t udi_hid_generic_getsetting(void); + +//! Global structure which contains standard UDI interface for UDC +UDC_DESC_STORAGE udi_api_t udi_api_hid_generic = { + .enable = (bool(*)(void))udi_hid_generic_enable, + .disable = (void (*)(void))udi_hid_generic_disable, + .setup = (bool(*)(void))udi_hid_generic_setup, + .getsetting = (uint8_t(*)(void))udi_hid_generic_getsetting, + .sof_notify = NULL, +}; +//@} + + +/** + * \ingroup udi_hid_generic_group + * \defgroup udi_hid_generic_group_internal Implementation of UDI HID Generic + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal defines and variables to manage HID generic + */ +//@{ + +//! To store current rate of HID generic +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_generic_rate; +//! To store current protocol of HID generic +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_generic_protocol; +//! To signal if the report IN buffer is free (no transfer on going) +static bool udi_hid_generic_b_report_in_free; +//! Report to send +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_generic_report_in[UDI_HID_REPORT_IN_SIZE]; +//! Report to receive +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_generic_report_out[UDI_HID_REPORT_OUT_SIZE]; +//! Report to receive via SetFeature +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_generic_report_feature[UDI_HID_REPORT_FEATURE_SIZE]; + +//@} + +//! HID report descriptor for standard HID generic +UDC_DESC_STORAGE udi_hid_generic_report_desc_t udi_hid_generic_report_desc = { { + 0x06, 0xFF, 0xFF, // 04|2 , Usage Page (vendor defined?) + 0x09, 0x01, // 08|1 , Usage (vendor defined + 0xA1, 0x01, // A0|1 , Collection (Application) + // IN report + 0x09, 0x02, // 08|1 , Usage (vendor defined) + 0x09, 0x03, // 08|1 , Usage (vendor defined) + 0x15, 0x00, // 14|1 , Logical Minimum(0 for signed byte?) + 0x26, 0xFF, 0x00, // 24|1 , Logical Maximum(255 for signed byte?) + 0x75, 0x08, // 74|1 , Report Size(8) = field size in bits = 1 byte + // 94|1 , ReportCount(size) = repeat count of previous item + 0x95, sizeof(udi_hid_generic_report_in), + 0x81, 0x02, // 80|1 , IN report (Data,Variable, Absolute) + // OUT report + 0x09, 0x04, // 08|1 , Usage (vendor defined) + 0x09, 0x05, // 08|1 , Usage (vendor defined) + 0x15, 0x00, // 14|1 , Logical Minimum(0 for signed byte?) + 0x26, 0xFF, 0x00, // 24|1 , Logical Maximum(255 for signed byte?) + 0x75, 0x08, // 74|1 , Report Size(8) = field size in bits = 1 byte + // 94|1 , ReportCount(size) = repeat count of previous item + 0x95, sizeof(udi_hid_generic_report_out), + 0x91, 0x02, // 90|1 , OUT report (Data,Variable, Absolute) + // Feature report + 0x09, 0x06, // 08|1 , Usage (vendor defined) + 0x09, 0x07, // 08|1 , Usage (vendor defined) + 0x15, 0x00, // 14|1 , LogicalMinimum(0 for signed byte) + 0x26, 0xFF, 0x00, // 24|1 , Logical Maximum(255 for signed byte) + 0x75, 0x08, // 74|1 , Report Size(8) =field size in bits = 1 byte + 0x95, sizeof(udi_hid_generic_report_feature), // 94|x , ReportCount in byte + 0xB1, 0x02, // B0|1 , Feature report + 0xC0 // C0|0 , End Collection + } +}; + +/** + * \name Internal routines + */ +//@{ + +/** + * \brief Send a report to HID interface + * + */ +static bool udi_hid_generic_setreport(void); + +/** + * \brief Initialize UDD to receive setfeature data + */ +static void udi_hid_generic_setfeature_valid(void); + +/** + * \brief Callback called when the report is received + * + * \param status UDD_EP_TRANSFER_OK, if transfer is completed + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param nb_sent number of data received + */ +static void udi_hid_generic_report_out_received(udd_ep_status_t status, + iram_size_t nb_received, udd_ep_id_t ep); + +/** + * \brief Enable reception of out report + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_hid_generic_report_out_enable(void); + +/** + * \brief Callback called when the report is sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer is completed + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param nb_sent number of data transfered + */ +static void udi_hid_generic_report_in_sent(udd_ep_status_t status, + iram_size_t nb_sent, udd_ep_id_t ep); + +//@} + + +//-------------------------------------------- +//------ Interface for UDI HID level + +bool udi_hid_generic_enable(void) +{ + // Initialize internal values + udi_hid_generic_rate = 0; + udi_hid_generic_protocol = 0; + udi_hid_generic_b_report_in_free = true; + if (!udi_hid_generic_report_out_enable()) + return false; + return UDI_HID_GENERIC_ENABLE_EXT(); +} + + +void udi_hid_generic_disable(void) +{ + UDI_HID_GENERIC_DISABLE_EXT(); +} + + +bool udi_hid_generic_setup(void) +{ + return udi_hid_setup(&udi_hid_generic_rate, + &udi_hid_generic_protocol, + (uint8_t *) &udi_hid_generic_report_desc, + udi_hid_generic_setreport); +} + + +uint8_t udi_hid_generic_getsetting(void) +{ + return 0; +} + + +static bool udi_hid_generic_setreport(void) +{ + if ((USB_HID_REPORT_TYPE_FEATURE == (udd_g_ctrlreq.req.wValue >> 8)) + && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) + && (sizeof(udi_hid_generic_report_feature) == + udd_g_ctrlreq.req.wLength)) { + // Feature type on report ID 0 + udd_g_ctrlreq.payload = + (uint8_t *) & udi_hid_generic_report_feature; + udd_g_ctrlreq.callback = udi_hid_generic_setfeature_valid; + udd_g_ctrlreq.payload_size = + sizeof(udi_hid_generic_report_feature); + return true; + } + return false; +} + +//-------------------------------------------- +//------ Interface for application + +bool udi_hid_generic_send_report_in(uint8_t *data) +{ + if (!udi_hid_generic_b_report_in_free) + return false; + irqflags_t flags = cpu_irq_save(); + // Fill report + memset(&udi_hid_generic_report_in, 0, + sizeof(udi_hid_generic_report_in)); + memcpy(&udi_hid_generic_report_in, data, + sizeof(udi_hid_generic_report_in)); + udi_hid_generic_b_report_in_free = + !udd_ep_run(UDI_HID_GENERIC_EP_IN, + false, + (uint8_t *) & udi_hid_generic_report_in, + sizeof(udi_hid_generic_report_in), + udi_hid_generic_report_in_sent); + cpu_irq_restore(flags); + return !udi_hid_generic_b_report_in_free; + +} + +//-------------------------------------------- +//------ Internal routines + +static void udi_hid_generic_setfeature_valid(void) +{ + if (sizeof(udi_hid_generic_report_feature) != udd_g_ctrlreq.payload_size) + return; // Bad data + UDI_HID_GENERIC_SET_FEATURE(udi_hid_generic_report_feature); +} + +static void udi_hid_generic_report_out_received(udd_ep_status_t status, + iram_size_t nb_received, udd_ep_id_t ep) +{ + UNUSED(ep); + if (UDD_EP_TRANSFER_OK != status) + return; // Abort reception + + if (sizeof(udi_hid_generic_report_out) == nb_received) { + UDI_HID_GENERIC_REPORT_OUT(udi_hid_generic_report_out); + } + udi_hid_generic_report_out_enable(); +} + + +static bool udi_hid_generic_report_out_enable(void) +{ + return udd_ep_run(UDI_HID_GENERIC_EP_OUT, + false, + (uint8_t *) & udi_hid_generic_report_out, + sizeof(udi_hid_generic_report_out), + udi_hid_generic_report_out_received); +} + + +static void udi_hid_generic_report_in_sent(udd_ep_status_t status, + iram_size_t nb_sent, udd_ep_id_t ep) +{ + UNUSED(status); + UNUSED(nb_sent); + UNUSED(ep); + udi_hid_generic_b_report_in_free = true; +} + +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic.h b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic.h new file mode 100644 index 0000000000000..d09e9c47cc1fc --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic.h @@ -0,0 +1,384 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) generic interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_HID_GENERIC_H_ +#define _UDI_HID_GENERIC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "udc_desc.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_hid_generic_group_udc + * @{ + */ +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_generic; +//@} + +/** + * \ingroup udi_hid_generic_group + * \defgroup udi_hid_generic_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +//! Interface descriptor structure for HID generic +typedef struct { + usb_iface_desc_t iface; + usb_hid_descriptor_t hid; + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_hid_generic_desc_t; + +//! Report descriptor for HID generic +typedef struct { + uint8_t array[53]; +} udi_hid_generic_report_desc_t; + + +//! By default no string associated to this interface +#ifndef UDI_HID_GENERIC_STRING_ID +#define UDI_HID_GENERIC_STRING_ID 0 +#endif + + + +//! Content of HID generic interface descriptor for all speed +#define UDI_HID_GENERIC_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_GENERIC_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_GENERIC,\ + .iface.iInterface = UDI_HID_GENERIC_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_generic_report_desc_t)),\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bEndpointAddress = UDI_HID_GENERIC_EP_IN,\ + .ep_in.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_in.wMaxPacketSize = LE16(UDI_HID_GENERIC_EP_SIZE),\ + .ep_in.bInterval = 4,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bEndpointAddress = UDI_HID_GENERIC_EP_OUT,\ + .ep_out.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_out.wMaxPacketSize = LE16(UDI_HID_GENERIC_EP_SIZE),\ + .ep_out.bInterval = 4,\ + } +//@} + + +/** + * \ingroup udi_hid_group + * \defgroup udi_hid_generic_group USB Device Interface (UDI) for Human Interface Device (HID) Generic Class + * + * Common APIs used by high level application to use this USB class. + * + * See \ref udi_hid_generic_quickstart. + * @{ + */ + +/** + * \brief Routine used to send a report to USB Host + * + * \param data Pointer on the report to send (size = UDI_HID_REPORT_IN_SIZE) + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_generic_send_report_in(uint8_t *data); + +//@} + + +#ifdef __cplusplus +} +#endif + + +/** + * \page udi_hid_generic_quickstart Quick start guide for USB device generic module (UDI generic) + * + * This is the quick start guide for the \ref udi_hid_generic_group + * "USB device generic module (UDI generic)" 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 + * + * AVR4905: ASF - USB Device HID Generic Application. + * + * \section udi_hid_generic_basic_use_case Basic use case + * In this basic use case, the "USB HID Generic (Single Interface Device)" module is used. + * The "USB HID Generic (Composite Device)" module usage is described in \ref udi_hid_generic_use_cases + * "Advanced use cases". + * + * \section udi_hid_generic_basic_use_case_setup Setup steps + * \subsection udi_hid_generic_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_hid_generic_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_hid_generic_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_hid_generic_basic_use_case_usage Usage steps + * + * \subsection udi_hid_generic_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + #define UDI_HID_GENERIC_ENABLE_EXT() my_callback_generic_enable() + extern bool my_callback_generic_enable(void); + #define UDI_HID_GENERIC_DISABLE_EXT() my_callback_generic_disable() + extern void my_callback_generic_disable(void); + #define UDI_HID_GENERIC_REPORT_OUT(ptr) my_callback_generic_report_out(ptr) + extern void my_callback_generic_report_out(uint8_t *report); + #define UDI_HID_GENERIC_SET_FEATURE(f) my_callback_generic_set_feature(f) + extern void my_callback_generic_set_feature(uint8_t *report_feature); + + #define UDI_HID_REPORT_IN_SIZE 64 + #define UDI_HID_REPORT_OUT_SIZE 64 + #define UDI_HID_REPORT_FEATURE_SIZE 4 + #define UDI_HID_GENERIC_EP_SIZE 64 + + #include "udi_hid_generic_conf.h" // At the end of conf_usb.h file +\endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_generic_events = false; + bool my_callback_generic_enable(void) + { + my_flag_autorize_generic_events = true; + return true; + } + void my_callback_generic_disable(void) + { + my_flag_autorize_generic_events = false; + } + + void my_button_press_event(void) + { + if (!my_flag_autorize_generic_events) { + return; + } + uint8_t report[] = {0x00,0x01,0x02...}; + udi_hid_generic_send_report_in(report); + } + + void my_callback_generic_report_out(uint8_t *report) + { + if ((report[0] == MY_VALUE_0) + (report[1] == MY_VALUE_1)) { + // The report is correct + } + } + + void my_callback_generic_set_feature(uint8_t *report_feature) + { + if ((report_feature[0] == MY_VALUE_0) + (report_feature[1] == MY_VALUE_1)) { + // The report feature is correct + } + } +\endcode + * + * \subsection udi_hid_generic_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device generic configuration: + * - \code #define UDI_HID_GENERIC_ENABLE_EXT() my_callback_generic_enable() + extern bool my_callback_generic_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB generic interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_HID_GENERIC_ENABLE_EXT() callback function is called and return true. + * Thus, it is recommended to enable sensors used by the generic in this function. + * - \code #define UDI_HID_GENERIC_DISABLE_EXT() my_callback_generic_disable() + extern void my_callback_generic_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_HID_GENERIC_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable sensors used by the HID generic + * interface in this function. + * - \code #define UDI_HID_GENERIC_REPORT_OUT(ptr) my_callback_generic_report_out(ptr) + extern void my_callback_generic_report_out(uint8_t *report); \endcode + * \note Callback used to receive the OUT report. + * - \code #define UDI_HID_GENERIC_SET_FEATURE(f) my_callback_generic_set_feature(f) + extern void my_callback_generic_set_feature(uint8_t *report_feature); \endcode + * \note Callback used to receive the SET FEATURE report. + * - \code #define UDI_HID_REPORT_IN_SIZE 64 + #define UDI_HID_REPORT_OUT_SIZE 64 + #define UDI_HID_REPORT_FEATURE_SIZE 4 \endcode + * \note The report size are defined by the final application. + * - \code #define UDI_HID_GENERIC_EP_SIZE 64 \endcode + * \note The interrupt endpoint size is defined by the final application. + + * -# Send a IN report: + * - \code uint8_t report[] = {0x00,0x01,0x02...}; + udi_hid_generic_send_report_in(report); \endcode + * + * \section udi_hid_generic_use_cases Advanced use cases + * For more advanced use of the UDI HID generic module, see the following use cases: + * - \subpage udi_hid_generic_use_case_composite + * - \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 + */ + +/** + * \page udi_hid_generic_use_case_composite HID generic in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB HID Generic (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB MSC (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_hid_generic_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_hid_generic_basic_use_case "basic use case" must be followed. + * + * \section udi_hid_generic_use_case_composite_usage Usage steps + * + * \subsection udi_hid_generic_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X+2) + + #define UDI_HID_GENERIC_EP_IN (1 | USB_EP_DIR_IN) + #define UDI_HID_GENERIC_EP_OUT (2 | USB_EP_DIR_OUT) + #define UDI_HID_GENERIC_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_hid_generic_desc_t udi_hid_generic; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_hid_generic, \ + ... +\endcode + * + * \subsection udi_hid_generic_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + // - 8 for low speed + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for HID generic. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 1 for HID generic. + #define USB_DEVICE_MAX_EP (X+2) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint number chosen by you for the generic. + // The endpoint number starting from 1. + #define UDI_HID_GENERIC_EP_IN (1 | USB_EP_DIR_IN) + #define UDI_HID_GENERIC_EP_OUT (2 | USB_EP_DIR_OUT) + // The interface index of an interface starting from 0 + #define UDI_HID_GENERIC_IFACE_NUMBER X \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_hid_generic_desc_t udi_hid_generic; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_hid_generic, \ + ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +#endif // _UDI_HID_GENERIC_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_conf.h b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_conf.h new file mode 100644 index 0000000000000..06a69b5bc2526 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_conf.h @@ -0,0 +1,92 @@ +/** + * \file + * + * \brief Default HID generic configuration for a USB Device + * with a single interface HID + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_HID_GENERIC_CONF_H_ +#define _UDI_HID_GENERIC_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_hid_generic_group_single_desc + * @{ + */ + +//! Control endpoint size +#ifdef USB_DEVICE_HS_SUPPORT +# define USB_DEVICE_EP_CTRL_SIZE 64 +#else +# define USB_DEVICE_EP_CTRL_SIZE 8 +#endif + +//! Endpoint number used by HID generic interface +#define UDI_HID_GENERIC_EP_OUT (2 | USB_EP_DIR_OUT) +#define UDI_HID_GENERIC_EP_IN (1 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_GENERIC_IFACE_NUMBER 0 + + +/** + * \name UDD Configuration + */ +//@{ +//! 2 endpoints used by HID generic standard interface +#undef USB_DEVICE_MAX_EP // undefine this definition in header file +#define USB_DEVICE_MAX_EP 2 +//@} + +//@} + +#ifdef __cplusplus +} +#endif + +#include "udi_hid_generic.h" + +#endif // _UDI_HID_GENERIC_CONF_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_desc.c b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_desc.c new file mode 100644 index 0000000000000..68b4320430383 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_desc.c @@ -0,0 +1,168 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device + * with a single interface HID generic + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_hid.h" +#include "udi_hid_generic.h" + +/** + * \ingroup udi_hid_generic_group + * \defgroup udi_hid_generic_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required + * for USB Device with a single interface HID generic. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Only one interface for this device +#define USB_DEVICE_NB_INTERFACE 1 + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; + udi_hid_generic_desc_t hid_generic; +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for FS and HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .hid_generic = UDI_HID_GENERIC_DESC, +}; + + +/** + * \name UDC structures which contains all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { + &udi_api_hid_generic, +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fshs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc, + .udi_apis = udi_apis, +}}; + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fshs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_fshs, +#endif +}; + +//@} +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_doc.h b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_doc.h new file mode 100644 index 0000000000000..b3397d7fff8b2 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/generic/udi_hid_generic_doc.h @@ -0,0 +1,482 @@ +/** + * \file + * + * \brief USB device driver for Human Interface Device (HID) generic interface. + * + * 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 + * + */ + +/** + * \defgroup asfdoc_udi_hid_generic_group USB Device Interface (UDI) for Human Interface Device Generic (HID Generic) + * + * USB Device Interface (UDI) for Human Interface Device generic (HID generic) provides an + * interface for the configuration and management of USB HID generic device. + * + * The outline of this documentation is as follows: + * - \ref asfdoc_udi_hid_generic_api_overview + * - \ref asfdoc_udi_hid_generic_exqsg + * - \ref asfdoc_udi_hid_generic_config_examples + * + * For more details for Atmel® Software Framework (ASF) USB Device Stack and + * USB Device HID generic, refer to following application notes: + * - + * AVR4900: ASF - USB Device Stack + * - + * AVR4905: ASF - USB Device HID Generic Application + * - + * AVR4920: ASF - USB Device Stack - Compliance and Performance Figures + * - + * AVR4921: ASF - USB Device Stack Differences between ASF V1 and V2 + * + * \section asfdoc_udi_hid_generic_api_overview API Overview + * @{ + */ + +/** + * \name Interface with USB Device Core (UDC) + * + * Structure required by UDC. + * + * @{ + */ + +/** Global structure which contains standard UDI API for UDC. */ +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_generic; +/**@}*/ + +/** + * \name USB Interface Descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + * + * @{ + */ + + /** Interface descriptor structure for HID generic. */ +typedef struct { + /** Standard USB interface descriptor structure */ + usb_iface_desc_t iface; + /** HID Descriptor */ + usb_hid_descriptor_t hid; + /** Standard USB endpoint descriptor structure */ + usb_ep_desc_t ep_in; + /** Standard USB endpoint descriptor structure */ + usb_ep_desc_t ep_out; +} udi_hid_generic_desc_t; + +/** Report descriptor for HID generic. */ +typedef struct { + /** Array to put detailed report data */ + uint8_t array[53]; +} udi_hid_generic_report_desc_t; + + +/** By default no string associated to this interface. */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef UDI_HID_GENERIC_STRING_ID +#define UDI_HID_GENERIC_STRING_ID 0 +#endif + +/** Content of HID generic interface descriptor for all speed. */ +#define UDI_HID_GENERIC_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_GENERIC_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_GENERIC,\ + .iface.iInterface = UDI_HID_GENERIC_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_generic_report_desc_t)),\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bEndpointAddress = UDI_HID_GENERIC_EP_IN,\ + .ep_in.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_in.wMaxPacketSize = LE16(UDI_HID_GENERIC_EP_SIZE),\ + .ep_in.bInterval = 4,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bEndpointAddress = UDI_HID_GENERIC_EP_OUT,\ + .ep_out.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_out.wMaxPacketSize = LE16(UDI_HID_GENERIC_EP_SIZE),\ + .ep_out.bInterval = 4,\ + } +/**@}*/ + +/** + * \name USB Device Interface (UDI) for Human Interface Device (HID) Generic Class + * + * Common APIs used by high level application to use this USB class. + * @{ + */ + +/** + * \brief Routine used to send a report to USB Host + * + * \param[in] data Pointer on the report to send (size = UDI_HID_REPORT_IN_SIZE) + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_generic_send_report_in(uint8_t *data); +/**@}*/ +/**@}*/ + +/** + * \page asfdoc_udi_hid_generic_exqsg Quick Start Guide for USB Device Generic Module (UDI Generic) + * + * This is the quick start guide for the \ref asfdoc_udi_hid_generic_group + * "USB Device Generic Module (UDI Generic)" 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. + * + * \section udi_hid_generic_basic_use_case Basic Use Case + * In this basic use case, the "USB HID generic (Single Interface Device)" module is used. + * The "USB HID generic (Composite Device)" module usage is described in \ref udi_hid_generic_use_cases + * "Advanced Use Cases". + * + * \section udi_hid_generic_basic_use_case_setup Setup Steps + * As a USB device, it follows common USB device setup steps. Refer to + * \ref asfdoc_udc_basic_use_case_setup "USB Device Basic Setup". + * + * \section udi_hid_generic_basic_use_case_usage Usage Steps + * + * \subsection udi_hid_generic_basic_use_case_usage_code Example Code + * Content of conf_usb.h: + * \code + #define UDI_HID_generic_ENABLE_EXT() my_callback_generic_enable() + extern bool my_callback_generic_enable(void); + #define UDI_HID_generic_DISABLE_EXT() my_callback_generic_disable() + extern void my_callback_generic_disable(void); + #include "udi_hid_generic_conf.h" // At the end of conf_usb.h file + \endcode + * + * Add to application C-file: + * \code + #define UDI_HID_GENERIC_ENABLE_EXT() my_callback_generic_enable() + extern bool my_callback_generic_enable(void); + #define UDI_HID_GENERIC_DISABLE_EXT() my_callback_generic_disable() + extern void my_callback_generic_disable(void); + #define UDI_HID_GENERIC_REPORT_OUT(ptr) my_callback_generic_report_out(ptr) + extern void my_callback_generic_report_out(uint8_t *report); + #define UDI_HID_GENERIC_SET_FEATURE(f) my_callback_generic_set_feature(f) + extern void my_callback_generic_set_feature(uint8_t *report_feature); + + #define UDI_HID_REPORT_IN_SIZE 64 + #define UDI_HID_REPORT_OUT_SIZE 64 + #define UDI_HID_REPORT_FEATURE_SIZE 4 + #define UDI_HID_GENERIC_EP_SIZE 64 + + #include "udi_hid_generic_conf.h" // At the end of conf_usb.h file + \endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_generic_events = false; + bool my_callback_generic_enable(void) + { + my_flag_autorize_generic_events = true; + return true; + } + void my_callback_generic_disable(void) + { + my_flag_autorize_generic_events = false; + } + + void my_button_press_event(void) + { + if (!my_flag_autorize_generic_events) { + return; + } + uint8_t report[] = {0x00,0x01,0x02...}; + udi_hid_generic_send_report_in(report); + } + + void my_callback_generic_report_out(uint8_t *report) + { + if ((report[0] == MY_VALUE_0) + (report[1] == MY_VALUE_1)) { + // The report is correct + } + } + + void my_callback_generic_set_feature(uint8_t *report_feature) + { + if ((report_feature[0] == MY_VALUE_0) + (report_feature[1] == MY_VALUE_1)) { + // The report feature is correct + } + } + \endcode + * + * \subsection udi_hid_generic_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device generic configuration: + * \code + #define UDI_HID_GENERIC_ENABLE_EXT() my_callback_generic_enable() + extern bool my_callback_generic_enable(void); + \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB generic interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_HID_GENERIC_ENABLE_EXT() callback function is called and return true. + * Thus, it is recommended to enable sensors used by the generic in this function. + * + * \code + #define UDI_HID_GENERIC_DISABLE_EXT() my_callback_generic_disable() + extern void my_callback_generic_disable(void); + \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_HID_GENERIC_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable sensors used by the HID generic + * interface in this function. + * + * \code + #define UDI_HID_GENERIC_REPORT_OUT(ptr) my_callback_generic_report_out(ptr) + extern void my_callback_generic_report_out(uint8_t *report); + \endcode + * \note Callback used to receive the OUT report. + * + * \code + #define UDI_HID_GENERIC_SET_FEATURE(f) my_callback_generic_set_feature(f) + extern void my_callback_generic_set_feature(uint8_t *report_feature); + \endcode + * \note Callback used to receive the SET FEATURE report. + * + * \code + #define UDI_HID_REPORT_IN_SIZE 64 + #define UDI_HID_REPORT_OUT_SIZE 64 + #define UDI_HID_REPORT_FEATURE_SIZE 4 + \endcode + * \note The report size are defined by the final application. + * + * \code + #define UDI_HID_GENERIC_EP_SIZE 64 + \endcode + * \note The interrupt endpoint size is defined by the final application. + + * -# Send a IN report: + * \code + uint8_t report[] = {0x00,0x01,0x02...}; + udi_hid_generic_send_report_in(report); + \endcode + * + * \section udi_hid_generic_use_cases Advanced Use Cases + * \ifnot ASF_MANUAL + * For more advanced use of the UHI HID generic module, see the following use cases: + * - \subpage udi_hid_generic_use_case_composite + * - \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 + * \else + * For multiple interface use of UDI HID module, see the following: + * - \subpage udi_hid_generic_use_case_composite + * + * For more advanced use of the UDI HID generic module, see the following: + * - \ref asfdoc_udc_use_cases + * \endif + */ + +/** + * \page udi_hid_generic_use_case_composite HID Generic in a Composite Device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB HID Generic (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB MSC (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_hid_generic_use_case_composite_setup Setup Steps + * For the setup code of this use case to work, the + * \ref udi_hid_generic_basic_use_case "Basic Use Case" must be followed. + * + * \section udi_hid_generic_use_case_composite_usage Usage Steps + * + * \subsection udi_hid_generic_use_case_composite_usage_code Example Code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X+2) + + #define UDI_HID_GENERIC_EP_IN (1 | USB_EP_DIR_IN) + #define UDI_HID_GENERIC_EP_OUT (2 | USB_EP_DIR_OUT) + #define UDI_HID_GENERIC_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_hid_generic_desc_t udi_hid_generic; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_hid_generic, \ + ... + \endcode + * + * \subsection udi_hid_generic_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * \code + // Endpoint control size, This must be: + // - 8 for low speed + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for HID generic. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 1 for HID generic. + #define USB_DEVICE_MAX_EP (X+2) + \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * \code + // The endpoint number chosen by you for the generic. + // The endpoint number starting from 1. + #define UDI_HID_GENERIC_EP_IN (1 | USB_EP_DIR_IN) + #define UDI_HID_GENERIC_EP_OUT (2 | USB_EP_DIR_OUT) + // The interface index of an interface starting from 0 + #define UDI_HID_GENERIC_IFACE_NUMBER X + \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * \code + // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_hid_generic_desc_t udi_hid_generic; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_hid_generic = UDI_HID_GENERIC_DESC, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_hid_generic, \ + ... + \endcode + * \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +/** + * \page asfdoc_udi_hid_generic_config_examples Configuration File Examples + * + * \section asfdoc_udi_hid_generic_config_examples_1 conf_usb.h + * \subsection asfdoc_udi_hid_generic_config_examples_1_1 UDI HID GENERIC Single + * \include module_config/conf_usb.h + * \subsection asfdoc_udi_hid_generic_config_examples_1_2 UDI HID GENERIC Multiple (Composite) + * \include composite/device/module_config/conf_usb.h + * + * \section asfdoc_udi_hid_generic_config_examples_2 conf_clock.h + * + * \subsection asfdoc_udi_hid_generic_config_examples_2_1 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/at32uc3c0512c_uc3c_ek/conf_clock.h + * + * \subsection asfdoc_udi_hid_generic_config_examples_2_2 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_clock.h + * + * \section asfdoc_udi_hid_generic_config_examples_3 conf_clocks.h + * + * \subsection asfdoc_udi_hid_generic_config_examples_3_1 SAM D21 Device (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_clocks.h + * + * \section asfdoc_udi_hid_generic_config_examples_4 conf_board.h + * + * \subsection asfdoc_udi_hid_generic_config_examples_4_1 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/at32uc3c0512c_uc3c_ek/conf_board.h + * + * \subsection asfdoc_udi_hid_generic_config_examples_4_2 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_board.h + * + * \subsection asfdoc_udi_hid_generic_config_examples_4_3 SAM D21 Device (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_board.h + */ + +/** + * \page asfdoc_udi_hid_generic_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev.DateComments
42339B12/2015Fixed typos
42339A12/2014Initial release
+ */ \ No newline at end of file diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/kbd/module_config/conf_usb.h b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/module_config/conf_usb.h new file mode 100644 index 0000000000000..85a4ac05814f0 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/module_config/conf_usb.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief USB configuration file + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _CONF_USB_H_ +#define _CONF_USB_H_ + +#include "compiler.h" + +#warning You must refill the following definitions with a correct values + +/** + * USB Device Configuration + * @{ + */ + +//! Device definition (mandatory) +#define USB_DEVICE_VENDOR_ID USB_VID_ATMEL +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_ASF_HIDKEYBOARD +#define USB_DEVICE_MAJOR_VERSION 1 +#define USB_DEVICE_MINOR_VERSION 0 +#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) +#define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) + +//! USB Device string definitions (Optional) +// #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" +// #define USB_DEVICE_PRODUCT_NAME "Product name" +// #define USB_DEVICE_SERIAL_NAME "12...EF" + +/** + * Device speeds support + * @{ + */ +//! To define a Low speed device +//#define USB_DEVICE_LOW_SPEED + +//! To authorize the High speed +#if (UC3A3||UC3A4) +//#define USB_DEVICE_HS_SUPPORT +#endif +//@} + +/** + * USB Device Callbacks definitions (Optional) + * @{ + */ +// #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) +// extern void user_callback_vbus_action(bool b_vbus_high); +// #define UDC_SOF_EVENT() user_callback_sof_action() +// extern void user_callback_sof_action(void); +// #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); +//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature +// #define UDC_REMOTEWAKEUP_ENABLE() user_callback_remotewakeup_enable() +// extern void user_callback_remotewakeup_enable(void); +// #define UDC_REMOTEWAKEUP_DISABLE() user_callback_remotewakeup_disable() +// extern void user_callback_remotewakeup_disable(void); +//! When a extra string descriptor must be supported +//! other than manufacturer, product and serial string +// #define UDC_GET_EXTRA_STRING() +//@} + +//@} + + +/** + * USB Interface Configuration + * @{ + */ +/** + * Configuration of HID Keyboard interface (if used) + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() true +#define UDI_HID_KBD_DISABLE_EXT() +// #define UDI_HID_KBD_ENABLE_EXT() my_callback_keyboard_enable() +// extern bool my_callback_keyboard_enable(void); +// #define UDI_HID_KBD_DISABLE_EXT() my_callback_keyboard_disable() +// extern void my_callback_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) +// #define UDI_HID_KBD_CHANGE_LED(value) my_callback_keyboard_led(value) +// extern void my_callback_keyboard_led(uint8_t value) +//@} +//@} + + +/** + * USB Device Driver Configuration + * @{ + */ +//@} + +//! The includes of classes and other headers must be done at the end of this file to avoid compile error +#include "udi_hid_kbd_conf.h" + +#endif // _CONF_USB_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c new file mode 100644 index 0000000000000..9028cdc2209f2 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c @@ -0,0 +1,391 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) keyboard interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc.h" +#include "udi_hid.h" +#include "udi_hid_kbd.h" +#include + +/** + * \ingroup udi_hid_keyboard_group + * \defgroup udi_hid_keyboard_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ + +bool udi_hid_kbd_enable(void); +void udi_hid_kbd_disable(void); +bool udi_hid_kbd_setup(void); +uint8_t udi_hid_kbd_getsetting(void); + +//! Global structure which contains standard UDI interface for UDC +UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd = { + .enable = (bool(*)(void))udi_hid_kbd_enable, + .disable = (void (*)(void))udi_hid_kbd_disable, + .setup = (bool(*)(void))udi_hid_kbd_setup, + .getsetting = (uint8_t(*)(void))udi_hid_kbd_getsetting, + .sof_notify = NULL, +}; +//@} + + +/** + * \ingroup udi_hid_keyboard_group + * \defgroup udi_hid_keyboard_group_internal Implementation of UDI HID keyboard + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal defines and variables to manage HID keyboard + */ +//@{ + +//! Size of report for standard HID keyboard +#define UDI_HID_KBD_REPORT_SIZE 8 + + +//! To store current rate of HID keyboard +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_kbd_rate; +//! To store current protocol of HID keyboard +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_kbd_protocol; +//! To store report feedback from USB host +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_kbd_report_set; +//! To signal if a valid report is ready to send +static bool udi_hid_kbd_b_report_valid; +//! Report ready to send +static uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE]; +//! Signal if a report transfer is on going +static bool udi_hid_kbd_b_report_trans_ongoing; +//! Buffer used to send report +COMPILER_WORD_ALIGNED + static uint8_t + udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE]; + +//@} + +//! HID report descriptor for standard HID keyboard +UDC_DESC_STORAGE udi_hid_kbd_report_desc_t udi_hid_kbd_report_desc = { + { + 0x05, 0x01, /* Usage Page (Generic Desktop) */ + 0x09, 0x06, /* Usage (Keyboard) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x05, 0x07, /* Usage Page (Keyboard) */ + 0x19, 224, /* Usage Minimum (224) */ + 0x29, 231, /* Usage Maximum (231) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x08, /* Report Count (8) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x81, 0x01, /* Input (Constant) */ + 0x19, 0x00, /* Usage Minimum (0) */ + 0x29, 101, /* Usage Maximum (101) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 101, /* Logical Maximum (101) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x06, /* Report Count (6) */ + 0x81, 0x00, /* Input (Data, Array) */ + 0x05, 0x08, /* Usage Page (LED) */ + 0x19, 0x01, /* Usage Minimum (1) */ + 0x29, 0x05, /* Usage Maximum (5) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x05, /* Report Count (5) */ + 0x91, 0x02, /* Output (Data, Variable, Absolute) */ + 0x95, 0x03, /* Report Count (3) */ + 0x91, 0x01, /* Output (Constant) */ + 0xC0 /* End Collection */ + } +}; + +/** + * \name Internal routines + */ +//@{ + +/** + * \brief Changes keyboard report states (like LEDs) + * + * \param rate New rate value + * + */ +static bool udi_hid_kbd_setreport(void); + +/** + * \brief Send the report + * + * \return \c 1 if send on going, \c 0 if delay. + */ +static bool udi_hid_kbd_send_report(void); + +/** + * \brief Callback called when the report is sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer is completed + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param nb_sent number of data transfered + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, + udd_ep_id_t ep); + +/** + * \brief Callback called to update report from USB host + * udi_hid_kbd_report_set is updated before callback execution + */ +static void udi_hid_kbd_setreport_valid(void); + +//@} + + +//-------------------------------------------- +//------ Interface for UDI HID level + +bool udi_hid_kbd_enable(void) +{ + // Initialize internal values + udi_hid_kbd_rate = 0; + udi_hid_kbd_protocol = 0; + udi_hid_kbd_b_report_trans_ongoing = false; + memset(udi_hid_kbd_report, 0, UDI_HID_KBD_REPORT_SIZE); + udi_hid_kbd_b_report_valid = false; + return UDI_HID_KBD_ENABLE_EXT(); +} + + +void udi_hid_kbd_disable(void) +{ + UDI_HID_KBD_DISABLE_EXT(); +} + + +bool udi_hid_kbd_setup(void) +{ + return udi_hid_setup(&udi_hid_kbd_rate, + &udi_hid_kbd_protocol, + (uint8_t *) &udi_hid_kbd_report_desc, + udi_hid_kbd_setreport); +} + + +uint8_t udi_hid_kbd_getsetting(void) +{ + return 0; +} + + +static bool udi_hid_kbd_setreport(void) +{ + if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8)) + && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) + && (1 == udd_g_ctrlreq.req.wLength)) { + // Report OUT type on report ID 0 from USB Host + udd_g_ctrlreq.payload = &udi_hid_kbd_report_set; + udd_g_ctrlreq.callback = udi_hid_kbd_setreport_valid; + udd_g_ctrlreq.payload_size = 1; + return true; + } + return false; +} + + +//-------------------------------------------- +//------ Interface for application + +bool udi_hid_kbd_modifier_up(uint8_t modifier_id) +{ + irqflags_t flags = cpu_irq_save(); + + // Fill report + udi_hid_kbd_report[0] &= ~(unsigned)modifier_id; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +bool udi_hid_kbd_modifier_down(uint8_t modifier_id) +{ + irqflags_t flags = cpu_irq_save(); + + // Fill report + udi_hid_kbd_report[0] |= modifier_id; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +bool udi_hid_kbd_up(uint8_t key_id) +{ + uint8_t i; + + irqflags_t flags = cpu_irq_save(); + + // Fill report + for (i = 2; i < UDI_HID_KBD_REPORT_SIZE; i++) { + if (0 == udi_hid_kbd_report[i]) { + // Already removed + cpu_irq_restore(flags); + return true; + } + if (key_id == udi_hid_kbd_report[i]) + break; + } + if (UDI_HID_KBD_REPORT_SIZE == i) { + // Already removed + cpu_irq_restore(flags); + return true; + } + // Remove key and shift + while (i < (UDI_HID_KBD_REPORT_SIZE - 1)) { + udi_hid_kbd_report[i] = udi_hid_kbd_report[i + 1]; + i++; + } + udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE - 1] = 0x00; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +bool udi_hid_kbd_down(uint8_t key_id) +{ + uint8_t i; + + irqflags_t flags = cpu_irq_save(); + + // Fill report + for (i = 2; i < UDI_HID_KBD_REPORT_SIZE; i++) { + if (0 == udi_hid_kbd_report[i]) + break; + if (key_id == udi_hid_kbd_report[i]) { + // Already in array + cpu_irq_restore(flags); + return true; + } + } + + if (UDI_HID_KBD_REPORT_SIZE == i) { + // Array full + // TODO manage more than UDI_HID_KBD_REPORT_SIZE key pressed in same time + cpu_irq_restore(flags); + return false; + } + // Add key at the end of array + udi_hid_kbd_report[i] = key_id; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + // Enable IT + cpu_irq_restore(flags); + return true; +} + + +//-------------------------------------------- +//------ Internal routines + +static bool udi_hid_kbd_send_report(void) +{ + if (udi_hid_kbd_b_report_trans_ongoing) + return false; + memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, + UDI_HID_KBD_REPORT_SIZE); + udi_hid_kbd_b_report_valid = false; + udi_hid_kbd_b_report_trans_ongoing = + udd_ep_run( UDI_HID_KBD_EP_IN, + false, + udi_hid_kbd_report_trans, + UDI_HID_KBD_REPORT_SIZE, + udi_hid_kbd_report_sent); + return udi_hid_kbd_b_report_trans_ongoing; +} + +static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, + udd_ep_id_t ep) +{ + UNUSED(status); + UNUSED(nb_sent); + UNUSED(ep); + udi_hid_kbd_b_report_trans_ongoing = false; + if (udi_hid_kbd_b_report_valid) { + udi_hid_kbd_send_report(); + } +} + +static void udi_hid_kbd_setreport_valid(void) +{ + UDI_HID_KBD_CHANGE_LED(udi_hid_kbd_report_set); +} + +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.h b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.h new file mode 100644 index 0000000000000..15818949fe002 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.h @@ -0,0 +1,367 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) keyboard interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDC_HID_KBD_H_ +#define _UDC_HID_KBD_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "udc_desc.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_hid_keyboard_group_udc + * @{ + */ +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd; +//@} + +/** + * \ingroup udi_hid_keyboard_group + * \defgroup udi_hid_keyboard_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +//! Interface descriptor structure for HID keyboard +typedef struct { + usb_iface_desc_t iface; + usb_hid_descriptor_t hid; + usb_ep_desc_t ep; +} udi_hid_kbd_desc_t; + +//! Report descriptor for HID keyboard +typedef struct { + uint8_t array[59]; +} udi_hid_kbd_report_desc_t; + + +//! By default no string associated to this interface +#ifndef UDI_HID_KBD_STRING_ID +#define UDI_HID_KBD_STRING_ID 0 +#endif + +//! HID keyboard endpoints size +#define UDI_HID_KBD_EP_SIZE 8 + +//! Content of HID keyboard interface descriptor for all speed +#define UDI_HID_KBD_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_KBD_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,\ + .iface.iInterface = UDI_HID_KBD_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_kbd_report_desc_t)),\ + .ep.bLength = sizeof(usb_ep_desc_t),\ + .ep.bDescriptorType = USB_DT_ENDPOINT,\ + .ep.bEndpointAddress = UDI_HID_KBD_EP_IN,\ + .ep.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep.wMaxPacketSize = LE16(UDI_HID_KBD_EP_SIZE),\ + .ep.bInterval = 2,\ + } +//@} + + +/** + * \ingroup udi_hid_group + * \defgroup udi_hid_keyboard_group USB Device Interface (UDI) for Human Interface Device (HID) Keyboard Class + * + * Common APIs used by high level application to use this USB class. + * + * See \ref udi_hid_keyboard_quickstart. + * @{ + */ + +/** + * \brief Send events key modifier released + * + * \param modifier_id ID of key modifier + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_modifier_up(uint8_t modifier_id); + +/** + * \brief Send events key modifier pressed + * + * \param modifier_id ID of key modifier + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_modifier_down(uint8_t modifier_id); + + +/** + * \brief Send events key released + * + * \param key_id ID of key + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_up(uint8_t key_id); + +/** + * \brief Send events key pressed + * + * \param key_id ID of key + * + */ +bool udi_hid_kbd_down(uint8_t key_id); + +//@} + +#ifdef __cplusplus +} +#endif + +/** + * \page udi_hid_keyboard_quickstart Quick start guide for USB device keyboard module (UDI keyboard) + * + * This is the quick start guide for the \ref udi_hid_keyboard_group + * "USB device keyboard module (UDI keyboard)" 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 + * + * AVR4904: ASF - USB Device HID Keyboard Application. + * + * \section udi_hid_keyboard_basic_use_case Basic use case + * In this basic use case, the "USB HID Keyboard (Single Interface Device)" module is used. + * The "USB HID Keyboard (Composite Device)" module usage is described in \ref udi_hid_keyboard_use_cases + * "Advanced use cases". + * + * \section udi_hid_keyboard_basic_use_case_setup Setup steps + * \subsection udi_hid_keyboard_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_hid_keyboard_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_hid_keyboard_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_hid_keyboard_basic_use_case_usage Usage steps + * + * \subsection udi_hid_keyboard_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + #define UDI_HID_KBD_ENABLE_EXT() my_callback_keyboard_enable() + extern bool my_callback_keyboard_enable(void); + #define UDI_HID_KBD_DISABLE_EXT() my_callback_keyboard_disable() + extern void my_callback_keyboard_disable(void); + #include "udi_hid_keyboard_conf.h" // At the end of conf_usb.h file +\endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_keyboard_events = false; + bool my_callback_keyboard_enable(void) + { + my_flag_autorize_keyboard_events = true; + return true; + } + void my_callback_keyboard_disable(void) + { + my_flag_autorize_keyboard_events = false; + } + + void my_key_A_press_event(void) + { + if (!my_flag_autorize_keyboard_events) { + return; + } + udi_hid_kbd_up(HID_A); + } +\endcode + * + * \subsection udi_hid_keyboard_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device keyboard configuration: + * - \code #define UDI_HID_KBD_ENABLE_EXT() my_callback_keyboard_enable() + extern bool my_callback_keyboard_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB keyboard interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_HID_KBD_ENABLE_EXT() callback function is called and return true. + * Thus, it is recommended to enable sensors used by the keyboard in this function. + * - \code #define UDI_HID_KBD_DISABLE_EXT() my_callback_keyboard_disable() + extern void my_callback_keyboard_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_HID_KBD_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable sensors used by the keyboard + * in this function. + * -# send keyboard events: + * - \code // Send events key modifier released + udi_hid_kbd_modifier_up(uint8_t modifier_id); + // Send events key modifier pressed + udi_hid_kbd_modifier_down(uint8_t modifier_id); + // Send events key released + udi_hid_kbd_up(uint8_t key_id); + // Send events key pressed + udi_hid_kbd_down(uint8_t key_id); \endcode + * + * \section udi_hid_keyboard_use_cases Advanced use cases + * For more advanced use of the UDI HID keyboard module, see the following use cases: + * - \subpage udi_hid_keyboard_use_case_composite + * - \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 + */ + +/** + * \page udi_hid_keyboard_use_case_composite HID keyboard in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB HID Keyboard (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB MSC (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_hid_keyboard_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_hid_keyboard_basic_use_case "basic use case" must be followed. + * + * \section udi_hid_keyboard_use_case_composite_usage Usage steps + * + * \subsection udi_hid_keyboard_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X+1) + + #define UDI_HID_KBD_EP_IN (X | USB_EP_DIR_IN) + #define UDI_HID_KBD_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_hid_kbd_desc_t udi_hid_kbd; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_hid_kbd, \ + ... +\endcode + * + * \subsection udi_hid_keyboard_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + // - 8 for low speed + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for HID keyboard. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 1 for HID keyboard. + #define USB_DEVICE_MAX_EP (X+1) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint number chosen by you for the keyboard. + // The endpoint number starting from 1. + #define UDI_HID_KBD_EP_IN (X | USB_EP_DIR_IN) + // The interface index of an interface starting from 0 + #define UDI_HID_KBD_IFACE_NUMBER X \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_hid_kbd_desc_t udi_hid_kbd; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_hid_kbd, \ + ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +#endif // _UDC_HID_KBD_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_conf.h b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_conf.h new file mode 100644 index 0000000000000..f423ea1c4e4ad --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_conf.h @@ -0,0 +1,78 @@ +/** + * \file + * + * \brief Default HID keyboard configuration for a USB Device + * with a single interface HID keyboard + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_HID_KBD_CONF_H_ +#define _UDI_HID_KBD_CONF_H_ + +/** + * \addtogroup udi_hid_keyboard_group_single_desc + * @{ + */ + +//! Control endpoint size +#define USB_DEVICE_EP_CTRL_SIZE 8 + +//! Endpoint number used by HID keyboard interface +#define UDI_HID_KBD_EP_IN (1 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 0 + +/** + * \name UDD Configuration + */ +//@{ +//! 1 endpoint used by HID keyboard standard interface +#undef USB_DEVICE_MAX_EP // undefine this definition in header file +#define USB_DEVICE_MAX_EP 1 +//@} + +//@} + +#include "udi_hid_kbd.h" + +#endif // _UDI_HID_KBD_CONF_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c new file mode 100644 index 0000000000000..639ed27402dc5 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c @@ -0,0 +1,167 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device + * with a single interface HID keyboard + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_hid.h" +#include "udi_hid_kbd.h" + +/** + * \ingroup udi_hid_keyboard_group + * \defgroup udi_hid_keyboard_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required + * for USB Device with a single interface HID keyboard. + * + * It is ready to use and do not require more definition. + * @{ + */ + +//! Only one interface for this device +#define USB_DEVICE_NB_INTERFACE 1 + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; + udi_hid_kbd_desc_t hid_kbd; +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for FS and HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .hid_kbd = UDI_HID_KBD_DESC, +}; + + +/** + * \name UDC structures which contains all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { + &udi_api_hid_kbd, +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fshs[1] = {{ + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc, + .udi_apis = udi_apis, +}}; + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fshs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_fshs, +#endif +}; + +//@} +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_doc.h b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_doc.h new file mode 100644 index 0000000000000..68e88620d68e8 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_doc.h @@ -0,0 +1,457 @@ +/** + * \file + * + * \brief USB device driver for Human Interface Device (HID) keyboard interface. + * + * 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 + * + */ + +/** + * \defgroup asfdoc_udi_hid_keyboard_group USB Device Interface (UDI) for Human Interface Device Keyboard (HID Keyboard) + * + * USB Device Interface (UDI) for Human Interface Device Keyboard (HID keyboard) provides an + * interface for the configuration and management of USB HID keyboard device. + * + * The outline of this documentation is as follows: + * - \ref asfdoc_udi_hid_keyboard_api_overview + * - \ref asfdoc_udi_hid_keyboard_exqsg + * - \ref asfdoc_udi_hid_keyboard_config_examples + * + * For more details for Atmel® Software Framework (ASF) USB Device Stack and + * USB Device HID keyboard, refer to following application notes: + * - + * AVR4900: ASF - USB Device Stack + * - + * AVR4904: ASF - USB Device HID Keyboard Application + * - + * AVR4920: ASF - USB Device Stack - Compliance and Performance Figures + * - + * AVR4921: ASF - USB Device Stack Differences between ASF V1 and V2 + * + * \section asfdoc_udi_hid_keyboard_api_overview API Overview + * @{ + */ + +/** + * \name Interface with USB Device Core (UDC) + * + * Variable required by UDC. + * + * @{ + */ + +/** Global structure which contains standard UDI API for UDC. */ +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd; +/**@}*/ + +/** + * \name USB Interface Descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + * + * @{ + */ + + /** Interface descriptor structure for HID keyboard. */ +typedef struct { + /** Standard USB interface descriptor structure */ + usb_iface_desc_t iface; + /** HID Descriptor */ + usb_hid_descriptor_t hid; + /** Standard USB endpoint descriptor structure */ + usb_ep_desc_t ep; +} udi_hid_kbd_desc_t; + +/** Report descriptor for HID keyboard. */ +typedef struct { + /** Array to put detailed report data */ + uint8_t array[59]; +} udi_hid_kbd_report_desc_t; + + +/** By default no string associated to this interface. */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef UDI_HID_KBD_STRING_ID +#define UDI_HID_KBD_STRING_ID 0 +#endif + +/** HID keyboard endpoints size. */ +#define UDI_HID_KBD_EP_SIZE 8 + +/** Content of HID keyboard interface descriptor for all speed. */ +#define UDI_HID_KBD_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_KBD_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,\ + .iface.iInterface = UDI_HID_KBD_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_kbd_report_desc_t)),\ + .ep.bLength = sizeof(usb_ep_desc_t),\ + .ep.bDescriptorType = USB_DT_ENDPOINT,\ + .ep.bEndpointAddress = UDI_HID_KBD_EP_IN,\ + .ep.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep.wMaxPacketSize = LE16(UDI_HID_KBD_EP_SIZE),\ + .ep.bInterval = 2,\ + } +/**@}*/ + +/** + * \name USB Device Interface (UDI) for Human Interface Device (HID) Keyboard Class + * + * Common APIs used by high level application to use this USB class. + * @{ + */ + +/** + * \brief Send events key modifier released + * + * \param[in] modifier_id ID of key modifier + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_modifier_up(uint8_t modifier_id); + +/** + * \brief Send events key modifier pressed + * + * \param[in] modifier_id ID of key modifier + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_modifier_down(uint8_t modifier_id); + + +/** + * \brief Send events key released + * + * \param[in] key_id ID of key + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_up(uint8_t key_id); + +/** + * \brief Send events key pressed + * + * \param[in] key_id ID of key + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_down(uint8_t key_id); +/**@}*/ +/**@}*/ + +/** + * \page asfdoc_udi_hid_keyboard_exqsg Quick Start Guide for USB Device Keyboard Module (UDI Keyboard) + * + * This is the quick start guide for the \ref asfdoc_udi_hid_keyboard_group + * "USB Device Keyboard Module (UDI Keyboard)" 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. + * + * \section udi_hid_keyboard_basic_use_case Basic Use Case + * In this basic use case, the "USB HID keyboard (Single Interface Device)" module is used. + * The "USB HID keyboard (Composite Device)" module usage is described in \ref udi_hid_keyboard_use_cases + * "Advanced Use Cases". + * + * \section udi_hid_keyboard_basic_use_case_setup Setup Steps + * As a USB device, it follows common USB device setup steps. Refer to + * \ref asfdoc_udc_basic_use_case_setup "USB Device Basic Setup". + * + * \section udi_hid_keyboard_basic_use_case_usage Usage Steps + * + * \subsection udi_hid_keyboard_basic_use_case_usage_code Example Code + * Content of conf_usb.h: + * \code + #define UDI_HID_KBD_ENABLE_EXT() my_callback_keyboard_enable() + extern bool my_callback_keyboard_enable(void); + #define UDI_HID_KBD_DISABLE_EXT() my_callback_keyboard_disable() + extern void my_callback_keyboard_disable(void); + #include "udi_hid_keyboard_conf.h" // At the end of conf_usb.h file + \endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_keyboard_events = false; + bool my_callback_keyboard_enable(void) + { + my_flag_autorize_keyboard_events = true; + return true; + } + void my_callback_keyboard_disable(void) + { + my_flag_autorize_keyboard_events = false; + } + + void my_key_A_press_event(void) + { + if (!my_flag_autorize_keyboard_events) { + return; + } + udi_hid_kbd_up(HID_A); + } + \endcode + * + * \subsection udi_hid_keyboard_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device keyboard configuration: + * \code + #define UDI_HID_KBD_ENABLE_EXT() my_callback_keyboard_enable() + extern bool my_callback_keyboard_enable(void); + \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB keyboard interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_HID_KBD_ENABLE_EXT() callback function is called and return true. + * Thus, it is recommended to enable sensors used by the keyboard in this function. + * + * \code + #define UDI_HID_KBD_DISABLE_EXT() my_callback_keyboard_disable() + extern void my_callback_keyboard_disable(void); + \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_HID_KBD_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable sensors used by the keyboard + * in this function. + * + * -# Send keyboard events: + * \code + // Send events key modifier released + udi_hid_kbd_modifier_up(uint8_t modifier_id); + // Send events key modifier pressed + udi_hid_kbd_modifier_down(uint8_t modifier_id); + // Send events key released + udi_hid_kbd_up(uint8_t key_id); + // Send events key pressed + udi_hid_kbd_down(uint8_t key_id); + \endcode + * + * \section udi_hid_keyboard_use_cases Advanced Use Cases + * \ifnot ASF_MANUAL + * For more advanced use of the UHI HID keyboard module, see the following use cases: + * - \subpage udi_hid_keyboard_use_case_composite + * - \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 + * \else + * For multiple interface use of UDI HID module, see the following: + * - \subpage udi_hid_keyboard_use_case_composite + * + * For more advanced use of the UDI HID keyboard module, see the following: + * - \ref asfdoc_udc_use_cases + * \endif + */ + +/** + * \page udi_hid_keyboard_use_case_composite HID Keyboard in a Composite Device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB HID Keyboard (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB MSC (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_hid_keyboard_use_case_composite_setup Setup Steps + * For the setup code of this use case to work, the + * \ref udi_hid_keyboard_basic_use_case "Basic Use Case" must be followed. + * + * \section udi_hid_keyboard_use_case_composite_usage Usage Steps + * + * \subsection udi_hid_keyboard_use_case_composite_usage_code Example Code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X+1) + + #define UDI_HID_KBD_EP_IN (X | USB_EP_DIR_IN) + #define UDI_HID_KBD_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_hid_kbd_desc_t udi_hid_kbd; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_hid_kbd, \ + ... + \endcode + * + * \subsection udi_hid_keyboard_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * \code + // Endpoint control size, This must be: + // - 8 for low speed + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for HID keyboard. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 1 for HID keyboard. + #define USB_DEVICE_MAX_EP (X+1) + \endcode + * + * -# Ensure that conf_usb.h contains the description of + * composite device: + * \code + // The endpoint number chosen by you for the keyboard. + // The endpoint number starting from 1. + #define UDI_HID_KBD_EP_IN (X | USB_EP_DIR_IN) + // The interface index of an interface starting from 0 + #define UDI_HID_KBD_IFACE_NUMBER X + \endcode + * + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * \code + // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_hid_kbd_desc_t udi_hid_kbd; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_hid_kbd = UDI_HID_KBD_DESC, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_hid_kbd, \ + ... + \endcode + * \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +/** + * \page asfdoc_udi_hid_keyboard_config_examples Configuration File Examples + * + * \section asfdoc_udi_hid_keyboard_config_examples_1 conf_usb.h + * \subsection asfdoc_udi_hid_keyboard_config_examples_1_1 UDI HID KBD Single + * \include module_config/conf_usb.h + * \subsection asfdoc_udi_hid_keyboard_config_examples_1_2 UDI HID KBD Multiple (Composite) + * \include composite/device/module_config/conf_usb.h + * + * \section asfdoc_udi_hid_keyboard_config_examples_2 conf_clock.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_2_1 AT32UC3A0, AT32UC3A1, AT32UC3B Devices (USBB) + * \include example/at32uc3b0256_evk1101/conf_clock.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_2_2 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/atuc128d3_stk600-rcuc3d/conf_clock.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_2_3 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_clock.h + * + * \section asfdoc_udi_hid_keyboard_config_examples_3 conf_clocks.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_3_1 SAM D21 Device (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_clocks.h + * + * \section asfdoc_udi_hid_keyboard_config_examples_4 conf_board.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_4_1 AT32UC3A0, AT32UC3A1, AT32UC3B Devices (USBB) + * \include example/at32uc3b0256_evk1101/conf_board.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_4_2 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/atuc128d3_stk600-rcuc3d/conf_board.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_4_3 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_board.h + * + * \subsection asfdoc_udi_hid_keyboard_config_examples_4_4 SAM D21 Device (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_board.h + */ + +/** + * \page asfdoc_udi_hid_kbd_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev.DateComments
42340B12/2015Fixed typos
42340A12/2014Initial release
+ */ \ No newline at end of file diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/mouse/module_config/conf_usb.h b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/module_config/conf_usb.h new file mode 100644 index 0000000000000..82549337a5ff8 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/module_config/conf_usb.h @@ -0,0 +1,142 @@ +/** + * \file + * + * \brief USB configuration file + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _CONF_USB_H_ +#define _CONF_USB_H_ + +#include "compiler.h" + +#warning You must refill the following definitions with a correct values + +/** + * USB Device Configuration + * @{ + */ + +//! Device definition (mandatory) +#define USB_DEVICE_VENDOR_ID USB_VID_ATMEL +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_ASF_HIDMOUSE +#define USB_DEVICE_MAJOR_VERSION 1 +#define USB_DEVICE_MINOR_VERSION 0 +#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) +#define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) + +//! USB Device string definitions (Optional) +// #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" +// #define USB_DEVICE_PRODUCT_NAME "Product name" +// #define USB_DEVICE_SERIAL_NAME "12...EF" + +/** + * Device speeds support + * @{ + */ +//! To define a Low speed device +//#define USB_DEVICE_LOW_SPEED + +//! To authorize the High speed +#if (UC3A3||UC3A4) +//#define USB_DEVICE_HS_SUPPORT +#endif +//@} + +/** + * USB Device Callbacks definitions (Optional) + * @{ + */ +// #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) +// extern void user_callback_vbus_action(bool b_vbus_high); +// #define UDC_SOF_EVENT() user_callback_sof_action() +// extern void user_callback_sof_action(void); +// #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); +//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature +// #define UDC_REMOTEWAKEUP_ENABLE() user_callback_remotewakeup_enable() +// extern void user_callback_remotewakeup_enable(void); +// #define UDC_REMOTEWAKEUP_DISABLE() user_callback_remotewakeup_disable() +// extern void user_callback_remotewakeup_disable(void); +//! When a extra string descriptor must be supported +//! other than manufacturer, product and serial string +// #define UDC_GET_EXTRA_STRING() +//@} + +//@} + + +/** + * USB Interface Configuration + * @{ + */ +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() true +#define UDI_HID_MOUSE_DISABLE_EXT() +// #define UDI_HID_MOUSE_ENABLE_EXT() my_callback_mouse_enable() +// extern bool my_callback_mouse_enable(void); +// #define UDI_HID_MOUSE_DISABLE_EXT() my_callback_mouse_disable() +// extern void my_callback_mouse_disable(void); +//@} +//@} + + +/** + * USB Device Driver Configuration + * @{ + */ +//@} + +//! The includes of classes and other headers must be done at the end of this file to avoid compile error +#include "udi_hid_mouse_conf.h" + +#endif // _CONF_USB_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.c b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.c new file mode 100644 index 0000000000000..bd82022ffeab0 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.c @@ -0,0 +1,353 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) mouse interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc.h" +#include "udi_hid.h" +#include "udi_hid_mouse.h" +#include + +/** + * \ingroup udi_hid_mouse_group + * \defgroup udi_hid_mouse_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_hid_mouse_enable(void); +void udi_hid_mouse_disable(void); +bool udi_hid_mouse_setup(void); +uint8_t udi_hid_mouse_getsetting(void); + +//! Global structure which contains standard UDI interface for UDC +UDC_DESC_STORAGE udi_api_t udi_api_hid_mouse = { + .enable = (bool(*)(void))udi_hid_mouse_enable, + .disable = (void (*)(void))udi_hid_mouse_disable, + .setup = (bool(*)(void))udi_hid_mouse_setup, + .getsetting = (uint8_t(*)(void))udi_hid_mouse_getsetting, + .sof_notify = NULL, +}; +//@} + + +/** + * \ingroup udi_hid_mouse_group + * \defgroup udi_hid_mouse_group_internal Implementation of UDI HID Mouse + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal defines and variables to manage HID mouse + */ +//@{ + +//! Size of report for standard HID mouse +#define UDI_HID_MOUSE_REPORT_SIZE 4 +//! To store current rate of HID mouse +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_mouse_rate; +//! To store current protocol of HID mouse +COMPILER_WORD_ALIGNED + static uint8_t udi_hid_mouse_protocol; +//! To signal if a valid report is ready to send +static bool udi_hid_mouse_b_report_valid; +//! Report ready to send +static uint8_t udi_hid_mouse_report[UDI_HID_MOUSE_REPORT_SIZE]; +//! Signal if a report transfer is on going +static bool udi_hid_mouse_report_trans_ongoing; +//! Buffer used to send report +COMPILER_WORD_ALIGNED + static uint8_t + udi_hid_mouse_report_trans[UDI_HID_MOUSE_REPORT_SIZE]; + + +/** + * \brief Callback for set report setup request + * + * \return \c 1 always, because it is not used on mouse interface + */ +static bool udi_hid_mouse_setreport(void); + +//@} + +//! HID report descriptor for standard HID mouse +UDC_DESC_STORAGE udi_hid_mouse_report_desc_t udi_hid_mouse_report_desc = { + { + 0x05, 0x01, /* Usage Page (Generic Desktop), */ + 0x09, 0x02, /* Usage (Mouse), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x09, 0x01, /* Usage (Pointer), */ + 0xA1, 0x00, /* Collection (Physical), */ + 0x05, 0x09, /* Usage Page (Buttons), */ + 0x19, 0x01, /* Usage Minimum (01), */ + 0x29, 0x03, /* Usage Maximum (03), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x75, 0x05, /* Report Size (5), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x01, /* Input (Constant), */ + 0x05, 0x01, /* Usage Page (Generic Desktop), */ + 0x09, 0x30, /* Usage (X), */ + 0x09, 0x31, /* Usage (Y), */ + 0x09, 0x38, /* Usage (Scroll), */ + 0x15, 0x81, /* Logical Minimum (-127), */ + 0x25, 0x7F, /* Logical Maximum (127), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x06, /* Input (Data, Variable, Relative) */ + 0xC0, /* End Collection, */ + 0xC0, /* End Collection */ + } +}; + +/** + * \name Internal routines + */ +//@{ + +/** + * \brief Moves an axe + * + * \param pos Signed value to move + * \param index_report Index of report to move + * (3=scroll wheel, 2=axe Y, 1=axe X)) + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_hid_mouse_move(int8_t pos, uint8_t index_report); + +/** + * \brief Changes a button state + * + * \param b_state New button state + * \param btn Index of button to change (4=middle, 2=right, 1=left) + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_hid_mouse_btn(bool b_state, uint8_t btn); + +/** + * \brief Send the report + * + * \return \c 1 if send on going, \c 0 if delay. + */ +static bool udi_hid_mouse_send_report(void); + +/** + * \brief Callback called when the report is sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param nb_sent number of data transfered + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static void udi_hid_mouse_report_sent(udd_ep_status_t status, + iram_size_t nb_sent, udd_ep_id_t ep); + +//@} + + +//-------------------------------------------- +//------ Interface for UDI HID level + +bool udi_hid_mouse_enable(void) +{ + // Initialize internal value + udi_hid_mouse_rate = 0; + udi_hid_mouse_protocol = 0; + udi_hid_mouse_report_trans_ongoing = false; + memset(udi_hid_mouse_report, 0, UDI_HID_MOUSE_REPORT_SIZE); + udi_hid_mouse_b_report_valid = false; + return UDI_HID_MOUSE_ENABLE_EXT(); +} + + +void udi_hid_mouse_disable(void) +{ + UDI_HID_MOUSE_DISABLE_EXT(); +} + + +bool udi_hid_mouse_setup(void) +{ + return udi_hid_setup(&udi_hid_mouse_rate, + &udi_hid_mouse_protocol, + (uint8_t *) &udi_hid_mouse_report_desc, + udi_hid_mouse_setreport); +} + + +uint8_t udi_hid_mouse_getsetting(void) +{ + return 0; +} + + +static bool udi_hid_mouse_setreport(void) +{ + return false; +} + + +//-------------------------------------------- +//------ Interface for application + +bool udi_hid_mouse_moveScroll(int8_t pos) +{ + return udi_hid_mouse_move(pos, 3); +} + +bool udi_hid_mouse_moveY(int8_t pos_y) +{ + return udi_hid_mouse_move(pos_y, 2); +} + +bool udi_hid_mouse_moveX(int8_t pos_x) +{ + return udi_hid_mouse_move(pos_x, 1); +} + +bool udi_hid_mouse_btnmiddle(bool b_state) +{ + return udi_hid_mouse_btn(b_state, 0x04); +} + +bool udi_hid_mouse_btnright(bool b_state) +{ + return udi_hid_mouse_btn(b_state, 0x02); +} + +bool udi_hid_mouse_btnleft(bool b_state) +{ + return udi_hid_mouse_btn(b_state, 0x01); +} + + +//-------------------------------------------- +//------ Internal routines + +static bool udi_hid_mouse_move(int8_t pos, uint8_t index_report) +{ + int16_t s16_newpos; + + irqflags_t flags = cpu_irq_save(); + + // Add position in HID mouse report + s16_newpos = (int8_t) udi_hid_mouse_report[index_report]; + s16_newpos += pos; + if ((-127 > s16_newpos) || (127 < s16_newpos)) { + cpu_irq_restore(flags); + return false; // Overflow of report + } + udi_hid_mouse_report[index_report] = (uint8_t) s16_newpos; + + // Valid and send report + udi_hid_mouse_b_report_valid = true; + udi_hid_mouse_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +static bool udi_hid_mouse_btn(bool b_state, uint8_t btn) +{ + // Modify buttons report + if (HID_MOUSE_BTN_DOWN == b_state) + udi_hid_mouse_report[0] |= btn; + else + udi_hid_mouse_report[0] &= ~(unsigned)btn; + // Use mouse move routine + return udi_hid_mouse_move(0, 1); +} + + +static bool udi_hid_mouse_send_report(void) +{ + if (udi_hid_mouse_report_trans_ongoing) + return false; // Transfer on going then send this one after transfer complete + + // Copy report on other array used only for transfer + memcpy(udi_hid_mouse_report_trans, udi_hid_mouse_report, + UDI_HID_MOUSE_REPORT_SIZE); + memset(&udi_hid_mouse_report[1], 0, 3); // Keep status of btn for next report + udi_hid_mouse_b_report_valid = false; + + // Send report + udi_hid_mouse_report_trans_ongoing = + udd_ep_run( UDI_HID_MOUSE_EP_IN, + false, + udi_hid_mouse_report_trans, + UDI_HID_MOUSE_REPORT_SIZE, + udi_hid_mouse_report_sent); + return udi_hid_mouse_report_trans_ongoing; +} + + +static void udi_hid_mouse_report_sent(udd_ep_status_t status, + iram_size_t nb_sent, udd_ep_id_t ep) +{ + UNUSED(ep); + UNUSED(status); + UNUSED(nb_sent); + // Valid report sending + udi_hid_mouse_report_trans_ongoing = false; + if (udi_hid_mouse_b_report_valid) { + // Send new valid report + udi_hid_mouse_send_report(); + } +} + +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.h b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.h new file mode 100644 index 0000000000000..75b966f6e1765 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse.h @@ -0,0 +1,407 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) mouse interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_HID_MOUSE_H_ +#define _UDI_HID_MOUSE_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "udc_desc.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_hid_mouse_group_udc + * @{ + */ +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_mouse; +//@} + +/** + * \ingroup udi_hid_mouse_group + * \defgroup udi_hid_mouse_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +//! Interface descriptor structure for HID mouse +typedef struct { + usb_iface_desc_t iface; + usb_hid_descriptor_t hid; + usb_ep_desc_t ep; +} udi_hid_mouse_desc_t; + +//! Report descriptor for HID mouse +typedef struct { + uint8_t array[25 * 2 + 2 * 1]; +} udi_hid_mouse_report_desc_t; + + +//! By default no string associated to this interface +#ifndef UDI_HID_MOUSE_STRING_ID +#define UDI_HID_MOUSE_STRING_ID 0 +#endif + +//! HID mouse endpoints size +#define UDI_HID_MOUSE_EP_SIZE 8 + +//! Content of HID mouse interface descriptor for all speed +#define UDI_HID_MOUSE_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_MOUSE_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_BOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_MOUSE,\ + .iface.iInterface = UDI_HID_MOUSE_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_mouse_report_desc_t)),\ + .ep.bLength = sizeof(usb_ep_desc_t),\ + .ep.bDescriptorType = USB_DT_ENDPOINT,\ + .ep.bEndpointAddress = UDI_HID_MOUSE_EP_IN,\ + .ep.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep.wMaxPacketSize = LE16(UDI_HID_MOUSE_EP_SIZE),\ + .ep.bInterval = 10,\ + } +//@} +//@} + + +/** + * \ingroup udi_hid_group + * \defgroup udi_hid_mouse_group USB Device Interface (UDI) for Human Interface Device (HID) Mouse Class + * + * Common APIs used by high level application to use this USB class. + * + * See \ref udi_hid_mouse_quickstart. + * @{ + */ + +/** + * \name Interfaces for mouse events + */ +//@{ + +/** + * \brief Move the scroll wheel + * + * \param pos Signed value to move + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_moveScroll(int8_t pos); + +/** + * \brief Move the mouse pointer on Y axe + * + * \param pos_y Signed value to move + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_moveY(int8_t pos_y); + +/** + * \brief Move the mouse pointer on X axe + * + * \param pos_x Signed value to move + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_moveX(int8_t pos_x); +//@} + +/** + * \name Interfaces for buttons events + */ +//@{ + +//! Value to signal a button down (pressed) +#define HID_MOUSE_BTN_DOWN true +//! Value to signal a button up (released) +#define HID_MOUSE_BTN_UP false + +/** + * \brief Changes middle button state + * + * \param b_state New button state + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_btnmiddle(bool b_state); + +/** + * \brief Changes right button state + * + * \param b_state New button state + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_btnright(bool b_state); + +/** + * \brief Changes left button state + * + * \param b_state New button state + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_btnleft(bool b_state); +//@} + +//@} + +#ifdef __cplusplus +} +#endif + +/** + * \page udi_hid_mouse_quickstart Quick start guide for USB device mouse module (UDI mouse) + * + * This is the quick start guide for the \ref udi_hid_mouse_group + * "USB device mouse module (UDI mouse)" 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 + * + * AVR4903: ASF - USB Device HID Mouse Application. + * + * \section udi_hid_mouse_basic_use_case Basic use case + * In this basic use case, the "USB HID Mouse (Single Interface Device)" module is used. + * The "USB HID Mouse (Composite Device)" module usage is described in \ref udi_hid_mouse_use_cases + * "Advanced use cases". + * + * \section udi_hid_mouse_basic_use_case_setup Setup steps + * \subsection udi_hid_mouse_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_hid_mouse_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_hid_mouse_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_hid_mouse_basic_use_case_usage Usage steps + * + * \subsection udi_hid_mouse_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + #define UDI_HID_MOUSE_ENABLE_EXT() my_callback_mouse_enable() + extern bool my_callback_mouse_enable(void); + #define UDI_HID_MOUSE_DISABLE_EXT() my_callback_mouse_disable() + extern void my_callback_mouse_disable(void); + #include "udi_hid_mouse_conf.h" // At the end of conf_usb.h file +\endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_mouse_events = false; + bool my_callback_mouse_enable(void) + { + my_flag_autorize_mouse_events = true; + return true; + } + void my_callback_mouse_disable(void) + { + my_flag_autorize_mouse_events = false; + } + + void my_button_press_event(void) + { + if (!my_flag_autorize_mouse_events) { + return; + } + udi_hid_mouse_btnleft(HID_MOUSE_BTN_DOWN); + } +\endcode + * + * \subsection udi_hid_mouse_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device mouse configuration: + * - \code #define UDI_HID_MOUSE_ENABLE_EXT() my_callback_mouse_enable() + extern bool my_callback_mouse_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB mouse interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_HID_MOUSE_ENABLE_EXT() callback function is called and return true. + * Thus, it is recommended to enable sensors used by the mouse in this function. + * - \code #define UDI_HID_MOUSE_DISABLE_EXT() my_callback_mouse_disable() + extern void my_callback_mouse_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_HID_MOUSE_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable sensors used by the mouse + * in this function. + * -# send mouse events: + * - \code // Sends a value at scroll wheel + udi_hid_mouse_moveScroll(int8_t pos); + // Sends an Y axis value at mouse pointer + udi_hid_mouse_moveY(int8_t pos_y); + // Sends an X axis value at mouse pointer + udi_hid_mouse_moveX(int8_t pos_x); + // Sends a middle click event + udi_hid_mouse_btnmiddle(bool b_state); + // Sends a right click event + udi_hid_mouse_btnright(bool b_state); + // Sends a left click event + udi_hid_mouse_btnleft(bool b_state); \endcode + * + * \section udi_hid_mouse_use_cases Advanced use cases + * For more advanced use of the UDI HID mouse module, see the following use cases: + * - \subpage udi_hid_mouse_use_case_composite + * - \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 + */ + +/** + * \page udi_hid_mouse_use_case_composite HID mouse in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB HID Mouse (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB MSC (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_hid_mouse_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_hid_mouse_basic_use_case "basic use case" must be followed. + * + * \section udi_hid_mouse_use_case_composite_usage Usage steps + * + * \subsection udi_hid_mouse_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X+1) + + #define UDI_HID_MOUSE_EP_IN (X | USB_EP_DIR_IN) + #define UDI_HID_MOUSE_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_hid_mouse, \ + ... +\endcode + * + * \subsection udi_hid_mouse_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + // - 8 for low speed + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for HID mouse. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 1 for HID mouse. + #define USB_DEVICE_MAX_EP (X+1) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint number chosen by you for the mouse. + // The endpoint number starting from 1. + #define UDI_HID_MOUSE_EP_IN (X | USB_EP_DIR_IN) + // The interface index of an interface starting from 0 + #define UDI_HID_MOUSE_IFACE_NUMBER X \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_hid_mouse_desc_t udi_hid_mouse; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_hid_mouse, \ + ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +#endif // _UDI_HID_MOUSE_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_conf.h b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_conf.h new file mode 100644 index 0000000000000..58006c585c1eb --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_conf.h @@ -0,0 +1,84 @@ +/** + * \file + * + * \brief Default HID mouse configuration for a USB Device + * with a single interface HID mouse + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_HID_MOUSE_CONF_H_ +#define _UDI_HID_MOUSE_CONF_H_ + +/** + * \addtogroup udi_hid_mouse_group_single_desc + * @{ + */ + +//! Control endpoint size +#ifdef USB_DEVICE_HS_SUPPORT +# define USB_DEVICE_EP_CTRL_SIZE 64 +#else +# define USB_DEVICE_EP_CTRL_SIZE 8 +#endif + + +//! Endpoint number used by HID mouse interface +#define UDI_HID_MOUSE_EP_IN (1 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 0 + + +/** + * \name UDD Configuration + */ +//@{ +#undef USB_DEVICE_MAX_EP // undefine this definition in header file +//! 1 endpoint used by HID mouse standard interface +#define USB_DEVICE_MAX_EP 1 +//@} + +//@} + +#include "udi_hid_mouse.h" + +#endif // _UDI_HID_MOUSE_CONF_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_desc.c b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_desc.c new file mode 100644 index 0000000000000..4610726967f19 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_desc.c @@ -0,0 +1,193 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface HID mouse + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_hid.h" +#include "udi_hid_mouse.h" + +/** + * \ingroup udi_hid_mouse_group + * \defgroup udi_hid_mouse_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required + * for USB Device with a single interface HID mouse. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Only one interface for this device +#define USB_DEVICE_NB_INTERFACE 1 + +#ifdef USB_DEVICE_LPM_SUPPORT +# define USB_VERSION USB_V2_1 +#else +# define USB_VERSION USB_V2_0 +#endif + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_VERSION), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_VERSION), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +#ifdef USB_DEVICE_LPM_SUPPORT +//! USB Device Qualifier Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_lpm_desc_t udc_device_lpm = { + .bos.bLength = sizeof(usb_dev_bos_desc_t), + .bos.bDescriptorType = USB_DT_BOS, + .bos.wTotalLength = LE16(sizeof(usb_dev_bos_desc_t) + sizeof(usb_dev_capa_ext_desc_t)), + .bos.bNumDeviceCaps = 1, + .capa_ext.bLength = sizeof(usb_dev_capa_ext_desc_t), + .capa_ext.bDescriptorType = USB_DT_DEVICE_CAPABILITY, + .capa_ext.bDevCapabilityType = USB_DC_USB20_EXTENSION, + .capa_ext.bmAttributes = USB_DC_EXT_LPM, +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; + udi_hid_mouse_desc_t hid_mouse; +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for FS and HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .hid_mouse = UDI_HID_MOUSE_DESC, +}; + + +/** + * \name UDC structures which contains all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { + &udi_api_hid_mouse, +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fshs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc, + .udi_apis = udi_apis, +}}; + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fshs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_fshs, +#endif +#ifdef USB_DEVICE_LPM_SUPPORT + .conf_bos = &udc_device_lpm.bos, +#else + .conf_bos = NULL, +#endif +}; + +//@} +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_doc.h b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_doc.h new file mode 100644 index 0000000000000..41e805f46f886 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/mouse/udi_hid_mouse_doc.h @@ -0,0 +1,497 @@ +/** + * \file + * + * \brief USB device driver for Human Interface Device (HID) mouse interface. + * + * 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 + * + */ + +/** + * \defgroup asfdoc_udi_hid_mouse_group USB Device Interface (UDI) for Human Interface Device Mouse (HID Mouse) + * + * USB Device Interface (UDI) for Human Interface Device Mouse (HID mouse) provides an + * interface for the configuration and management of USB HID mouse device. + * + * The outline of this documentation is as follows: + * - \ref asfdoc_udi_hid_mouse_api_overview + * - \ref asfdoc_udi_hid_mouse_exqsg + * - \ref asfdoc_udi_hid_mouse_config_examples + * + * For more details for Atmel® Software Framework (ASF) USB Device Stack and + * USB Device HID Mouse, refer to following application notes: + * - + * AVR4900: ASF - USB Device Stack + * - + * AVR4903: ASF - USB Device HID Mouse Application + * - + * AVR4920: ASF - USB Device Stack - Compliance and Performance Figures + * - + * AVR4921: ASF - USB Device Stack Differences between ASF V1 and V2 + * + * \section asfdoc_udi_hid_mouse_api_overview API Overview + * @{ + */ + +/** + * \name Interface with USB Device Core (UDC) + * + * Structure required by UDC. + * + * @{ + */ + +/** Global structure which contains standard UDI API for UDC. */ +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_mouse; +/**@}*/ + +/** + * \name USB Interface Descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + * + * @{ + */ + + /** Interface descriptor structure for HID mouse. */ +typedef struct { + /** Standard USB interface descriptor structure */ + usb_iface_desc_t iface; + /** HID Descriptor */ + usb_hid_descriptor_t hid; + /** Standard USB endpoint descriptor structure */ + usb_ep_desc_t ep; +} udi_hid_mouse_desc_t; + +/** Report descriptor for HID mouse. */ +typedef struct { + /** Array to put detailed report data */ + uint8_t array[25 * 2 + 2 * 1]; +} udi_hid_mouse_report_desc_t; + + +/** By default no string associated to this interface. */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef UDI_HID_MOUSE_STRING_ID +#define UDI_HID_MOUSE_STRING_ID 0 +#endif + +/** HID mouse endpoints size. */ +#define UDI_HID_MOUSE_EP_SIZE 8 + +/** Content of HID mouse interface descriptor for all speed. */ +#define UDI_HID_MOUSE_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_MOUSE_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_BOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_MOUSE,\ + .iface.iInterface = UDI_HID_MOUSE_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_mouse_report_desc_t)),\ + .ep.bLength = sizeof(usb_ep_desc_t),\ + .ep.bDescriptorType = USB_DT_ENDPOINT,\ + .ep.bEndpointAddress = UDI_HID_MOUSE_EP_IN,\ + .ep.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep.wMaxPacketSize = LE16(UDI_HID_MOUSE_EP_SIZE),\ + .ep.bInterval = 10,\ + } +/**@}*/ + +/** + * \name Interfaces for Mouse Events + * + * @{ + */ + +/** + * \brief Move the scroll wheel + * + * \param[in] pos Signed value to move + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_moveScroll(int8_t pos); + +/** + * \brief Move the mouse pointer on Y axe + * + * \param[in] pos_y Signed value to move + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_moveY(int8_t pos_y); + +/** + * \brief Move the mouse pointer on X axe + * + * \param[in] pos_x Signed value to move + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_moveX(int8_t pos_x); +/**@}*/ + +/** + * \name Interfaces for Buttons Events + * + * @{ + */ + +/** Value to signal a button down (pressed). */ +#define HID_MOUSE_BTN_DOWN true + +/** Value to signal a button up (released). */ +#define HID_MOUSE_BTN_UP false + +/** + * \brief Changes middle button state + * + * \param[in] b_state New button state + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_btnmiddle(bool b_state); + +/** + * \brief Changes right button state + * + * \param[in] b_state New button state + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_btnright(bool b_state); + +/** + * \brief Changes left button state + * + * \param[in] b_state New button state + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_mouse_btnleft(bool b_state); +/**@}*/ +/**@}*/ + +/** + * \page asfdoc_udi_hid_mouse_exqsg Quick Start Guide for USB Device Mouse Module (UDI Mouse) + * + * This is the quick start guide for the \ref asfdoc_udi_hid_mouse_group + * "USB Device Mouse Module (UDI Mouse)" 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. + * + * \section udi_hid_mouse_basic_use_case Basic Use Case + * In this basic use case, the "USB HID Mouse (Single Interface Device)" module is used. + * The "USB HID Mouse (Composite Device)" module usage is described in \ref udi_hid_mouse_use_cases + * "Advanced Use Cases". + * + * \section udi_hid_mouse_basic_use_case_setup Setup Steps + * As a USB device, it follows common USB device setup steps. Refer to + * \ref asfdoc_udc_basic_use_case_setup "USB Device Basic Setup". + * + * \section udi_hid_mouse_basic_use_case_usage Usage Steps + * + * \subsection udi_hid_mouse_basic_use_case_usage_code Example Code + * Content of conf_usb.h: + * \code + #define UDI_HID_MOUSE_ENABLE_EXT() my_callback_mouse_enable() + extern bool my_callback_mouse_enable(void); + #define UDI_HID_MOUSE_DISABLE_EXT() my_callback_mouse_disable() + extern void my_callback_mouse_disable(void); + #include "udi_hid_mouse_conf.h" // At the end of conf_usb.h file + \endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_mouse_events = false; + bool my_callback_mouse_enable(void) + { + my_flag_autorize_mouse_events = true; + return true; + } + void my_callback_mouse_disable(void) + { + my_flag_autorize_mouse_events = false; + } + + void my_button_press_event(void) + { + if (!my_flag_autorize_mouse_events) { + return; + } + udi_hid_mouse_btnleft(HID_MOUSE_BTN_DOWN); + } + \endcode + * + * \subsection udi_hid_mouse_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device mouse configuration: + * \code + #define UDI_HID_MOUSE_ENABLE_EXT() my_callback_mouse_enable() + extern bool my_callback_mouse_enable(void); + \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB mouse interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_HID_MOUSE_ENABLE_EXT() callback function is called and return true. + * Thus, it is recommended to enable sensors used by the mouse in this function. + * + * \code + #define UDI_HID_MOUSE_DISABLE_EXT() my_callback_mouse_disable() + extern void my_callback_mouse_disable(void); + \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_HID_MOUSE_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable sensors used by the mouse + * in this function. + * + * -# Send mouse events: + * \code + // Sends a value at scroll wheel + udi_hid_mouse_moveScroll(int8_t pos); + // Sends an Y axis value at mouse pointer + udi_hid_mouse_moveY(int8_t pos_y); + // Sends an X axis value at mouse pointer + udi_hid_mouse_moveX(int8_t pos_x); + // Sends a middle click event + udi_hid_mouse_btnmiddle(bool b_state); + // Sends a right click event + udi_hid_mouse_btnright(bool b_state); + // Sends a left click event + udi_hid_mouse_btnleft(bool b_state); + \endcode + * + * \section udi_hid_mouse_use_cases Advanced Use Cases + * \ifnot ASF_MANUAL + * For more advanced use of the UHI HID mouse module, see the following use cases: + * - \subpage udi_hid_mouse_use_case_composite + * - \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 + * \else + * For multiple interface use of UDI HID module, see the following: + * - \subpage udi_hid_mouse_use_case_composite + * + * For more advanced use of the UDI HID mouse module, see the following: + * - \ref asfdoc_udc_use_cases + * \endif + */ + +/** + * \page udi_hid_mouse_use_case_composite HID Mouse in a Composite Device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB HID Mouse (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB MSC (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_hid_mouse_use_case_composite_setup Setup Steps + * For the setup code of this use case to work, the + * \ref udi_hid_mouse_basic_use_case "Basic Use Case" must be followed. + * + * \section udi_hid_mouse_use_case_composite_usage Usage Steps + * + * \subsection udi_hid_mouse_use_case_composite_usage_code Example Code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X+1) + + #define UDI_HID_MOUSE_EP_IN (X | USB_EP_DIR_IN) + #define UDI_HID_MOUSE_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_hid_mouse, \ + ... + \endcode + * + * + * \subsection udi_hid_mouse_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * \code + // Endpoint control size, This must be: + // - 8 for low speed + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for HID mouse. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 1 for HID mouse. + #define USB_DEVICE_MAX_EP (X+1) + \endcode + + * -# Ensure that conf_usb.h contains the description of + * composite device: + * \code + // The endpoint number chosen by you for the mouse. + // The endpoint number starting from 1. + #define UDI_HID_MOUSE_EP_IN (X | USB_EP_DIR_IN) + // The interface index of an interface starting from 0 + #define UDI_HID_MOUSE_IFACE_NUMBER X + \endcode + * + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * \code + // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_hid_mouse_desc_t udi_hid_mouse; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_hid_mouse, \ + ... + \endcode + * \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +/** + * \page asfdoc_udi_hid_mouse_config_examples Configuration File Examples + * + * \section asfdoc_udi_hid_mouse_config_examples_1 conf_usb.h + * \subsection asfdoc_udi_hid_mouse_config_examples_1_1 UDI HID MOUSE Single + * \include module_config/conf_usb.h + * \subsection asfdoc_udi_hid_mouse_config_examples_1_2 UDI HID MOUSE Multiple (Composite) + * \include composite/device/module_config/conf_usb.h + * + * \section asfdoc_udi_hid_mouse_config_examples_2 conf_clock.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_2_1 AT32UC3A0, AT32UC3A1, AT32UC3B Devices (USBB) + * \include example/at32uc3a0512_evk1100/conf_clock.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_2_2 AT32UC3A3 and AT32UC3A4 Devices (USBB with High Speed Support) + * \include example/at32uc3a3256_evk1104/conf_clock.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_2_3 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/at32uc3c0512c_uc3c_ek/conf_clock.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_2_4 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_clock.h + * + * \section asfdoc_udi_hid_mouse_config_examples_3 conf_clocks.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_3_1 SAM D21 Device (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_clocks.h + * + * \section asfdoc_udi_hid_mouse_config_examples_4 conf_board.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_4_1 AT32UC3A0, AT32UC3A1, AT32UC3B Devices (USBB) + * \include example/at32uc3a0512_evk1100/conf_board.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_4_2 AT32UC3A3 and AT32UC3A4 Devices (USBB with High Speed Support) + * \include example/at32uc3a3256_evk1104/conf_board.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_4_3 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/at32uc3c0512c_uc3c_ek/conf_board.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_4_4 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_board.h + * + * \subsection asfdoc_udi_hid_mouse_config_examples_4_5 SAM D21 Device (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_board.h + */ + +/** + * \page asfdoc_udi_hid_mouse_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev.DateComments
42341B12/2015Fixed typos
42341A12/2014Initial release
+ */ \ No newline at end of file diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/udi_hid.c b/atmel-samd/asf/common/services/usb/class/hid/device/udi_hid.c new file mode 100644 index 0000000000000..3694b0f0173b8 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/udi_hid.c @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) interface. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc.h" +#include "udi_hid.h" + + +/** + * \ingroup udi_hid_group + * \defgroup udi_hid_group_internal Implementation of HID common library + * @{ + */ + +/** + * \brief Send the specific descriptors requested by SETUP request + * + * \retval true if the descriptor is supported + */ +static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc); + +bool udi_hid_setup( uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void) ) +{ + if (Udd_setup_is_in()) { + // Requests Interface GET + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + // Requests Standard Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + + case USB_REQ_GET_DESCRIPTOR: + return udi_hid_reqstdifaceget_descriptor(report_desc); + } + } + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + + case USB_REQ_HID_GET_REPORT: + return setup_report(); + + case USB_REQ_HID_GET_IDLE: + udd_g_ctrlreq.payload = rate; + udd_g_ctrlreq.payload_size = 1; + return true; + + case USB_REQ_HID_GET_PROTOCOL: + udd_g_ctrlreq.payload = protocol; + udd_g_ctrlreq.payload_size = 1; + return true; + } + } + } + if (Udd_setup_is_out()) { + // Requests Interface SET + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + + case USB_REQ_HID_SET_REPORT: + return setup_report(); + + case USB_REQ_HID_SET_IDLE: + *rate = udd_g_ctrlreq.req.wValue >> 8; + return true; + + case USB_REQ_HID_SET_PROTOCOL: + if (0 != udd_g_ctrlreq.req.wLength) + return false; + *protocol = udd_g_ctrlreq.req.wValue; + return true; + } + } + } + return false; // Request not supported +} + + +//--------------------------------------------- +//------- Internal routines + +static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc) +{ + usb_hid_descriptor_t UDC_DESC_STORAGE *ptr_hid_desc; + + // Get the USB descriptor which is located after the interface descriptor + // This descriptor must be the HID descriptor + ptr_hid_desc = (usb_hid_descriptor_t UDC_DESC_STORAGE *) ((uint8_t *) + udc_get_interface_desc() + sizeof(usb_iface_desc_t)); + if (USB_DT_HID != ptr_hid_desc->bDescriptorType) + return false; + + // The SETUP request can ask for: + // - an USB_DT_HID descriptor + // - or USB_DT_HID_REPORT descriptor + // - or USB_DT_HID_PHYSICAL descriptor + if (USB_DT_HID == (uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + // USB_DT_HID descriptor requested then send it + udd_g_ctrlreq.payload = (uint8_t *) ptr_hid_desc; + udd_g_ctrlreq.payload_size = + min(udd_g_ctrlreq.req.wLength, + ptr_hid_desc->bLength); + return true; + } + // The HID_X descriptor requested must correspond to report type + // included in the HID descriptor + if (ptr_hid_desc->bRDescriptorType == + (uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + // Send HID Report descriptor given by high level + udd_g_ctrlreq.payload = report_desc; + udd_g_ctrlreq.payload_size = + min(udd_g_ctrlreq.req.wLength, + le16_to_cpu(ptr_hid_desc->wDescriptorLength)); + return true; + } + return false; +} + +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/device/udi_hid.h b/atmel-samd/asf/common/services/usb/class/hid/device/udi_hid.h new file mode 100644 index 0000000000000..0edb09c1c3d3b --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/device/udi_hid.h @@ -0,0 +1,85 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) interface definitions. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_HID_H_ +#define _UDI_HID_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udi_group + * \defgroup udi_hid_group USB Device Interface (UDI) for Human Interface Device (HID) + * + * Common library for all Human Interface Device (HID) implementation. + * + * @{ + */ + +/** + * \brief Decode HID setup request + * + * \param rate Pointer on rate of current HID interface + * \param protocol Pointer on protocol of current HID interface + * \param report_desc Pointer on report descriptor of current HID interface + * \param set_report Pointer on set_report callback of current HID interface + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_setup( uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void) ); + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_HID_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/host/mouse/module_config/conf_usb_host.h b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/module_config/conf_usb_host.h new file mode 100644 index 0000000000000..030ee12cd993d --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/module_config/conf_usb_host.h @@ -0,0 +1,132 @@ +/** + * \file + * + * \brief USB host configuration file + * + * 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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _CONF_USB_HOST_H_ +#define _CONF_USB_HOST_H_ + +#include "compiler.h" + +/** + * USB Host Configuration + * @{ + */ + +//! Array of UHI APIs Define the list of UHI supported by USB host. +#define USB_HOST_UHI UHI_HID_MOUSE + +//! Maximum current allowed on Vbus (mA) +#define USB_HOST_POWER_MAX 500 + +//! Authorize the USB HUB support +// #define USB_HOST_HUB_SUPPORT + +//! Authorize the USB host to run in High Speed +#if (UC3A3 || UC3A4) +# define USB_HOST_HS_SUPPORT +#endif + +/** + * USB Host callbacks + * @{ + */ + +//! To notify that the USB mode are switched automatically. +//! This is possible only when ID pin is available. +//#define UHC_MODE_CHANGE(b_host_mode) usb_host_mode_change(b_host_mode) + +//! To notify that the Vbus level has changed +//! Available only in USB hardware with Vbus monitoring. +//#define UHC_VBUS_CHANGE(b_present) usb_host_vbus_change(b_present) + +//! To notify that a Vbus error has occurred +//! Available only in USB hardware with Vbus monitoring. +//#define UHC_VBUS_ERROR() usb_host_vbus_error() + +//! To notify that a device has been connected or disconnected. +//#define UHC_CONNECTION_EVENT(dev,b_present) usb_host_connection_event(dev,b_present) + +//! Called when a USB device or the host have wake up the USB line. +//#define UHC_WAKEUP_EVENT() usb_host_wakeup_event() + +//! Called for each received SOF each 1 ms +//! Note: Available in High and Full speed mode +//#define UHC_SOF_EVENT() usb_host_sof_event() + +//! Called when a USB device configuration must be chosen. +//! Thus, the application can choose either a configuration number for this device +//! or a configuration number 0 to reject it. +//! If callback not defined the configuration 1 is chosen. +//#define UHC_DEVICE_CONF(dev) uint8_t usb_host_device_conf(dev) + +//! Called when a USB device enumeration is completed. +//#define UHC_ENUM_EVENT(dev,b_status) usb_host_enum_event(dev,b_status) + + +//@} + + + +/** + * USB Interface Configuration + * @{ + */ +/** + * Configuration of HID Mouse interface + * @{ + */ +#define UHI_HID_MOUSE_CHANGE(dev,b_plug) +#define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) +#define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) +#define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) +#define UHI_HID_MOUSE_EVENT_MOUVE(x,y,scroll) +//@} +//@} + +//@} + +#include "uhi_hid_mouse.h" + +#endif // _CONF_USB_HOST_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse.c b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse.c new file mode 100644 index 0000000000000..25fbc3f9953d1 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse.c @@ -0,0 +1,268 @@ +/** + * \file + * + * \brief USB host Human Interface Device (HID) mouse driver. + * + * Copyright (C) 2011-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb_host.h" +#include "usb_protocol.h" +#include "uhd.h" +#include "uhc.h" +#include "uhi_hid_mouse.h" +#include + +#ifdef USB_HOST_HUB_SUPPORT +# error USB HUB support is not implemented on UHI mouse +#endif + +/** + * \ingroup uhi_hid_mouse_group + * \defgroup uhi_hid_mouse_group_internal Implementation of UHI HID Mouse + * + * Class internal implementation + * @{ + */ + +/** + * \name Index in HID report for usual HID mouse events + * @{ + */ +#define UHI_HID_MOUSE_BTN 0 +#define UHI_HID_MOUSE_MOV_X 1 +#define UHI_HID_MOUSE_MOV_Y 2 +#define UHI_HID_MOUSE_MOV_SCROLL 3 +//@} + +/** + * \name Structure to store information about USB Device HID mouse + */ +//@{ +typedef struct { + uhc_device_t *dev; + usb_ep_t ep_in; + uint8_t report_size; + uint8_t *report; + uint8_t report_btn_prev; +}uhi_hid_mouse_dev_t; + +static uhi_hid_mouse_dev_t uhi_hid_mouse_dev = { + .dev = NULL, + .report = NULL, + }; + +//@} + + +/** + * \name Internal routines + */ +//@{ +static void uhi_hid_mouse_start_trans_report(usb_add_t add); +static void uhi_hid_mouse_report_reception( + usb_add_t add, + usb_ep_t ep, + uhd_trans_status_t status, + iram_size_t nb_transfered); +//@} + + +/** + * \name Functions required by UHC + * @{ + */ + +uhc_enum_status_t uhi_hid_mouse_install(uhc_device_t* dev) +{ + bool b_iface_supported; + uint16_t conf_desc_lgt; + usb_iface_desc_t *ptr_iface; + + if (uhi_hid_mouse_dev.dev != NULL) { + return UHC_ENUM_SOFTWARE_LIMIT; // Device already allocated + } + conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); + ptr_iface = (usb_iface_desc_t*)dev->conf_desc; + b_iface_supported = false; + while(conf_desc_lgt) { + switch (ptr_iface->bDescriptorType) { + + case USB_DT_INTERFACE: + if ((ptr_iface->bInterfaceClass == HID_CLASS) + && (ptr_iface->bInterfaceProtocol == HID_PROTOCOL_MOUSE) ) { + // USB HID Mouse interface found + // Start allocation endpoint(s) + b_iface_supported = true; + } else { + // Stop allocation endpoint(s) + b_iface_supported = false; + } + break; + + case USB_DT_ENDPOINT: + // Allocation of the endpoint + if (!b_iface_supported) { + break; + } + if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) { + return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail + } + Assert(((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN); + uhi_hid_mouse_dev.ep_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; + uhi_hid_mouse_dev.report_size = + le16_to_cpu(((usb_ep_desc_t*)ptr_iface)->wMaxPacketSize); + uhi_hid_mouse_dev.report = malloc(uhi_hid_mouse_dev.report_size); + if (uhi_hid_mouse_dev.report == NULL) { + Assert(false); + return UHC_ENUM_MEMORY_LIMIT; // Internal RAM allocation fail + } + uhi_hid_mouse_dev.dev = dev; + // All endpoints of all interfaces supported allocated + return UHC_ENUM_SUCCESS; + + default: + // Ignore descriptor + break; + } + Assert(conf_desc_lgt>=ptr_iface->bLength); + conf_desc_lgt -= ptr_iface->bLength; + ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); + } + return UHC_ENUM_UNSUPPORTED; // No interface supported +} + +void uhi_hid_mouse_enable(uhc_device_t* dev) +{ + if (uhi_hid_mouse_dev.dev != dev) { + return; // No interface to enable + } + + // Init value + uhi_hid_mouse_dev.report_btn_prev = 0; + uhi_hid_mouse_start_trans_report(dev->address); + UHI_HID_MOUSE_CHANGE(dev, true); +} + +void uhi_hid_mouse_uninstall(uhc_device_t* dev) +{ + if (uhi_hid_mouse_dev.dev != dev) { + return; // Device not enabled in this interface + } + uhi_hid_mouse_dev.dev = NULL; + Assert(uhi_hid_mouse_dev.report!=NULL); + free(uhi_hid_mouse_dev.report); + UHI_HID_MOUSE_CHANGE(dev, false); +} +//@} + +/** + * \name Internal routines + */ +//@{ + +/** + * \brief Starts the reception of the HID mouse report + * + * \param add USB address to use + */ +static void uhi_hid_mouse_start_trans_report(usb_add_t add) +{ + // Start transfer on interrupt endpoint IN + uhd_ep_run(add, uhi_hid_mouse_dev.ep_in, true, uhi_hid_mouse_dev.report, + uhi_hid_mouse_dev.report_size, 0, uhi_hid_mouse_report_reception); +} + +/** + * \brief Decodes the HID mouse report received + * + * \param add USB address used by the transfer + * \param status Transfer status + * \param nb_transfered Number of data transfered + */ +static void uhi_hid_mouse_report_reception( + usb_add_t add, + usb_ep_t ep, + uhd_trans_status_t status, + iram_size_t nb_transfered) +{ + uint8_t state_prev; + uint8_t state_new; + UNUSED(ep); + + if ((status == UHD_TRANS_NOTRESPONDING) || (status == UHD_TRANS_TIMEOUT)) { + uhi_hid_mouse_start_trans_report(add); + return; // HID mouse transfer restart + } + + if ((status != UHD_TRANS_NOERROR) || (nb_transfered < 4)) { + return; // HID mouse transfer aborted + } + + // Decode buttons + state_prev = uhi_hid_mouse_dev.report_btn_prev; + state_new = uhi_hid_mouse_dev.report[UHI_HID_MOUSE_BTN]; + if ((state_prev & 0x01) != (state_new & 0x01)) { + UHI_HID_MOUSE_EVENT_BTN_LEFT((state_new & 0x01) ? true : false); + } + if ((state_prev & 0x02) != (state_new & 0x02)) { + UHI_HID_MOUSE_EVENT_BTN_RIGHT((state_new & 0x02) ? true : false); + } + if ((state_prev & 0x04) != (state_new & 0x04)) { + UHI_HID_MOUSE_EVENT_BTN_MIDDLE((state_new & 0x04) ? true : false); + } + uhi_hid_mouse_dev.report_btn_prev = state_new; + + // Decode moves + if ((uhi_hid_mouse_dev.report[UHI_HID_MOUSE_MOV_X] != 0) + || (uhi_hid_mouse_dev.report[UHI_HID_MOUSE_MOV_Y] != 0) + || (uhi_hid_mouse_dev.report[UHI_HID_MOUSE_MOV_SCROLL] != 0)) { + UHI_HID_MOUSE_EVENT_MOUVE( + (int8_t)uhi_hid_mouse_dev.report[UHI_HID_MOUSE_MOV_X], + (int8_t)uhi_hid_mouse_dev.report[UHI_HID_MOUSE_MOV_Y], + (int8_t)uhi_hid_mouse_dev.report[UHI_HID_MOUSE_MOV_SCROLL]); + } + + uhi_hid_mouse_start_trans_report(add); +} +//@} + +//@} diff --git a/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse.h b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse.h new file mode 100644 index 0000000000000..a30ca5c40a90d --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse.h @@ -0,0 +1,216 @@ +/** + * \file + * + * \brief USB host driver for Human Interface Device (HID) mouse interface. + * + * Copyright (C) 2011-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UHI_HID_MOUSE_H_ +#define _UHI_HID_MOUSE_H_ + +#include "conf_usb_host.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "uhi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup uhi_hid_mouse_group + * \defgroup uhi_hid_mouse_group_uhc Interface with USB Host Core (UHC) + * + * Define and functions required by UHC. + * + * @{ + */ + +//! Global define which contains standard UHI API for UHC +//! It must be added in USB_HOST_UHI define from conf_usb_host.h file. +#define UHI_HID_MOUSE { \ + .install = uhi_hid_mouse_install, \ + .enable = uhi_hid_mouse_enable, \ + .uninstall = uhi_hid_mouse_uninstall, \ + .sof_notify = NULL, \ +} + +/** + * \name Functions required by UHC + * @{ + */ +extern uhc_enum_status_t uhi_hid_mouse_install(uhc_device_t* dev); +extern void uhi_hid_mouse_enable(uhc_device_t* dev); +extern void uhi_hid_mouse_uninstall(uhc_device_t* dev); +//@} +//@} + +/** + * \ingroup uhi_group + * \defgroup uhi_hid_mouse_group UHI for Human Interface Device Mouse Class + * + * Common APIs used by high level application to use this USB host class. + * + * This API requires only callback definitions in conf_usb_host.h file + * through following defines: + * - \code #define UHI_HID_MOUSE_CHANGE(dev,b_plug) + #define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) + #define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) + #define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) + #define UHI_HID_MOUSE_EVENT_MOUVE(x,y,scroll) \endcode + * + * See \ref uhi_hid_mouse_quickstart. + * @{ + */ +//@} + + +/** + * \page uhi_hid_mouse_quickstart Quick start guide for USB host mouse module (UHI mouse) + * + * This is the quick start guide for the \ref uhi_hid_mouse_group + * "USB host mouse module (UHI mouse)" 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. + * + * \section uhi_hid_mouse_basic_use_case Basic use case + * In this basic use case, the "USB Host HID Mouse (Single Class support)" module is used. + * The "USB Host HID Mouse (Multiple Classes support)" module usage is described + * in \ref uhi_hid_mouse_use_cases "Advanced use cases". + * + * \section uhi_hid_mouse_basic_use_case_setup Setup steps + * \subsection uhi_hid_mouse_basic_use_case_setup_prereq Prerequisites + * \copydetails uhc_basic_use_case_setup_prereq + * \subsection uhi_hid_mouse_basic_use_case_setup_code Example code + * \copydetails uhc_basic_use_case_setup_code + * \subsection uhi_hid_mouse_basic_use_case_setup_flow Workflow + * \copydetails uhc_basic_use_case_setup_flow + * + * \section uhi_hid_mouse_basic_use_case_usage Usage steps + * + * \subsection uhi_hid_mouse_basic_use_case_usage_code Example code + * Content of conf_usb_host.h: + * \code + #define USB_HOST_UHI UHI_HID_MOUSE + #define UHI_HID_MOUSE_CHANGE(dev, b_plug) my_callback_mouse_change(dev, b_plug) + extern bool my_callback_mouse_change(uhc_device_t* dev, bool b_plug); + #define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) my_callback_event_btn_left(b_state) + extern void my_callback_event_btn_left(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) my_callback_event_btn_right(b_state) + extern void my_callback_event_btn_right(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) my_callback_event_btn_middle(b_state) + extern void my_callback_event_btn_middle(bool b_state); + #define UHI_HID_MOUSE_EVENT_MOUVE(x, y, scroll) my_callback_event_mouse(x, y, scroll) + extern void my_callback_event_mouse(int8_t x, int8_t y, int8_t scroll); + #include "uhi_hid_mouse.h" // At the end of conf_usb_host.h file +\endcode + * + * Add to application C-file: + * \code + bool my_callback_mouse_change(uhc_device_t* dev, bool b_plug) + { + if (b_plug) { + my_display_on_mouse_icon(); + } else { + my_display_off_mouse_icon(); + } + } + + void my_callback_event_btn_left(bool b_state) + { + if (b_state) { + // Here mouse button left pressed + } else { + // Here mouse button left released + } + } + + void my_callback_event_mouse(int8_t x, int8_t y, int8_t scroll) + { + if (!x) { + // Here mouse are moved on axe X + cursor_x += x; + } + if (!y) { + // Here mouse are moved on axe Y + cursor_y += y; + } + if (!scroll) { + // Here mouse are moved the wheel + wheel += scroll; + } + } +\endcode + * + * \subsection uhi_hid_mouse_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb_host.h is available and contains the following configuration + * which is the USB host mouse configuration: + * - \code #define USB_HOST_UHI UHI_HID_MOUSE \endcode + * \note It defines the list of UHI supported by USB host. + * - \code #define UHI_HID_MOUSE_CHANGE(dev, b_plug) my_callback_mouse_change(dev, b_plug) + extern bool my_callback_mouse_change(uhc_device_t* dev, bool b_plug); \endcode + * \note This callback is called when a USB device mouse is plugged or unplugged. + * - \code #define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) my_callback_event_btn_left(b_state) + extern void my_callback_event_btn_left(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) my_callback_event_btn_right(b_state) + extern void my_callback_event_btn_right(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) my_callback_event_btn_middle(b_state) + extern void my_callback_event_btn_middle(bool b_state); + #define UHI_HID_MOUSE_EVENT_MOUVE(x, y, scroll) my_callback_event_mouse(x, y, scroll) + extern void my_callback_event_mouse(int8_t x, int8_t y, int8_t scroll) \endcode + * \note These callbacks are called when a USB device mouse event is received. + * + * \section uhi_hid_mouse_use_cases Advanced use cases + * For more advanced use of the UHI HID mouse module, see the following use cases: + * - \subpage uhc_use_case_1 + * - \subpage uhc_use_case_2 + * - \subpage uhc_use_case_3 + */ + + +#ifdef __cplusplus +} +#endif +#endif // _UHI_HID_MOUSE_H_ diff --git a/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse_doc.h b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse_doc.h new file mode 100644 index 0000000000000..2348d7e22d05c --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/host/mouse/uhi_hid_mouse_doc.h @@ -0,0 +1,325 @@ +/** + * \file + * + * \brief USB host driver for Human Interface Device (HID) mouse interface. + * + * 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 + * + */ + +/** + * \defgroup asfdoc_uhi_hid_mouse_group USB Host Interface (UHI) for Human Interface Device Mouse (HID Mouse) + * + * USB Host Interface (UHI) for Human Interface Device Mouse (HID Mouse) provides an + * interface for the configuration and management of USB HID mouse host. + * + * The outline of this documentation is as follows: + * - \ref asfdoc_uhi_hid_mouse_api_overview + * - \ref asfdoc_uhi_hid_mouse_exqsg + * - \ref asfdoc_uhi_hid_mouse_config_examples + * + * For more details for Atmel® Software Framework (ASF) USB Host Stack, + * refer to following application note: + * - + * AVR4950: ASF - USB Host Stack + * + * \section asfdoc_uhi_hid_mouse_api_overview API Overview + * @{ + */ + +/** + * \name Interface with USB Host Core (UHC) + * + * Define and functions required by UHC. + * + * @{ + */ + +/** Global define which contains standard UHI API for UHC. + * + * It must be added in USB_HOST_UHI define from conf_usb_host.h file. */ +/* + * Support and FAQ: visit Atmel Support + */ +#define UHI_HID_MOUSE { \ + .install = uhi_hid_mouse_install, \ + .enable = uhi_hid_mouse_enable, \ + .uninstall = uhi_hid_mouse_uninstall, \ + .sof_notify = NULL, \ +} +/**@}*/ + +/** + * \name Functions Required by UHC + * @{ + */ + +/** + * \brief Install interface + * Allocate interface endpoints if supported. + * + * \param[in] uhc_device_t Device to request + * + * \return Status of the install. + */ +extern uhc_enum_status_t uhi_hid_mouse_install(uhc_device_t* dev); + +/** + * \brief Enable the interface. + * + * Enable a USB interface corresponding to UHI. + * + * \param[in] uhc_device_t Device to request + */ +extern void uhi_hid_mouse_enable(uhc_device_t* dev); + +/** + * \brief Uninstall the interface (if installed). + * + * \param[in] uhc_device_t Device to request + */ +extern void uhi_hid_mouse_uninstall(uhc_device_t* dev); +/**@}*/ + + +/** + * \name UHI for Human Interface Device Mouse Class + * + * Common APIs used by high level application to use this USB host class. + * + * These APIs require only callback definitions in conf_usb_host.h file + * through following defines: + * @{ + */ +#define UHI_HID_MOUSE_CHANGE(dev,b_plug) +#define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) +#define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) +#define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) +#define UHI_HID_MOUSE_EVENT_MOUVE(x,y,scroll) + +/**@}*/ + +/**@}*/ + +/** + * \page asfdoc_uhi_hid_mouse_exqsg Quick Start Guide for USB Host Mouse Module (UHI Mouse) + * + * This is the quick start guide for the \ref asfdoc_uhi_hid_mouse_group + * "USB Host Mouse Module (UHI Mouse)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases highlights 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. + * + * \section uhi_hid_mouse_basic_use_case Basic Use Case + * In this basic use case, the "USB Host HID Mouse (Single Class support)" module is used. + * The "USB Host HID Mouse (Multiple Classes support)" module usage is described + * in \ref uhi_hid_mouse_use_cases "Advanced Use Cases". + * + * \subsection uhi_hid_mouse_basic_use_case_setup Setup Steps + * As a USB host, it follows common USB host setup steps. Refer to + * \ref asfdoc_uhc_basic_use_case_setup "USB Host Basic Setup". + + * + * \subsection uhi_hid_mouse_basic_use_case_usage Usage Steps + * + * \subsubsection uhi_hid_mouse_basic_use_case_usage_code Example Code + * Content of conf_usb_host.h: + + * \code + #define USB_HOST_UHI UHI_HID_MOUSE + #define UHI_HID_MOUSE_CHANGE(dev, b_plug) my_callback_mouse_change(dev, b_plug) + extern bool my_callback_mouse_change(uhc_device_t* dev, bool b_plug); + #define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) my_callback_event_btn_left(b_state) + extern void my_callback_event_btn_left(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) my_callback_event_btn_right(b_state) + extern void my_callback_event_btn_right(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) my_callback_event_btn_middle(b_state) + extern void my_callback_event_btn_middle(bool b_state); + #define UHI_HID_MOUSE_EVENT_MOUVE(x, y, scroll) my_callback_event_mouse(x, y, scroll) + extern void my_callback_event_mouse(int8_t x, int8_t y, int8_t scroll); + #include "uhi_hid_mouse.h" // At the end of conf_usb_host.h file + \endcode + + * + * Add to application C-file: + * \code + bool my_callback_mouse_change(uhc_device_t* dev, bool b_plug) + { + if (b_plug) { + my_display_on_mouse_icon(); + } else { + my_display_off_mouse_icon(); + } + } + + void my_callback_event_btn_left(bool b_state) + { + if (b_state) { + // Here mouse button left pressed + } else { + // Here mouse button left released + } + } + + void my_callback_event_mouse(int8_t x, int8_t y, int8_t scroll) + { + if (!x) { + // Here mouse are moved on axe X + cursor_x += x; + } + if (!y) { + // Here mouse are moved on axe Y + cursor_y += y; + } + if (!scroll) { + // Here mouse are moved the wheel + wheel += scroll; + } + } + \endcode + * + * + * \subsubsection uhi_hid_mouse_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb_host.h is available and contains the following configuration + * which is the USB host mouse configuration: + * + * \code + #define USB_HOST_UHI UHI_HID_MOUSE + \endcode + * \note It defines the list of UHI supported by USB host. + * + * \code + #define UHI_HID_MOUSE_CHANGE(dev, b_plug) my_callback_mouse_change(dev, b_plug) + extern bool my_callback_mouse_change(uhc_device_t* dev, bool b_plug); + \endcode + * \note This callback is called when a USB device mouse is plugged or unplugged. + * + * \code + #define UHI_HID_MOUSE_EVENT_BTN_LEFT(b_state) my_callback_event_btn_left(b_state) + extern void my_callback_event_btn_left(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_RIGHT(b_state) my_callback_event_btn_right(b_state) + extern void my_callback_event_btn_right(bool b_state); + #define UHI_HID_MOUSE_EVENT_BTN_MIDDLE(b_state) my_callback_event_btn_middle(b_state) + extern void my_callback_event_btn_middle(bool b_state); + #define UHI_HID_MOUSE_EVENT_MOUVE(x, y, scroll) my_callback_event_mouse(x, y, scroll) + extern void my_callback_event_mouse(int8_t x, int8_t y, int8_t scroll) + \endcode + * \note These callbacks are called when a USB device mouse event is received. + * + * \section uhi_hid_mouse_use_cases Advanced Use Cases + * \ifnot ASF_MANUAL + * For more advanced use of the UHI HID mouse module, see the following use cases: + * - \subpage uhc_use_case_1 + * - \subpage uhc_use_case_2 + * - \subpage uhc_use_case_3 + * \else + * For more advanced use of the UHI HID mouse module, see the following: + * - \ref asfdoc_uhc_use_cases + * \endif + */ + + +/** + * \page asfdoc_uhi_hid_mouse_config_examples Configuration File Examples + * + * \section asfdoc_uhi_hid_mouse_config_examples_1 conf_usb_host.h + * \subsection asfdoc_uhi_hid_mouse_config_examples_1_1 UHI HID MOUSE Single + * \include module_config/conf_usb_host.h + * \subsection asfdoc_uhi_hid_mouse_config_examples_1_2 UHI HID MOUSE Multiple (Composite) + * \include composite/host/module_config/conf_usb_host.h + * + * \section asfdoc_uhi_hid_mouse_config_examples_2 conf_clock.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_2_1 AT32UC3A0, AT32UC3A1, AT32UC3B Devices (USBB) + * \include example/at32uc3a0512_evk1100/conf_clock.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_2_2 AT32UC3A3 and AT32UC3A4 Devices (USBB with High Speed Support) + * \include example/at32uc3a3256_evk1104/conf_clock.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_2_3 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/at32uc3c0512c_uc3c_ek/conf_clock.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_2_4 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_clock.h + * + * \section asfdoc_uhi_hid_mouse_config_examples_3 conf_clocks.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_3_1 SAM D21 Devices (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_clocks.h + * + * \section asfdoc_uhi_hid_mouse_config_examples_4 conf_board.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_4_1 AT32UC3A0, AT32UC3A1, AT32UC3B Devices (USBB) + * \include example/at32uc3a0512_evk1100/conf_board.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_4_2 AT32UC3A3 and AT32UC3A4 Devices (USBB with High Speed Support) + * \include example/at32uc3a3256_evk1104/conf_board.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_4_3 AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U Devices (USBC) + * \include example/at32uc3c0512c_uc3c_ek/conf_board.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_4_4 SAM3X and SAM3A Devices (UOTGHS: USB OTG High Speed) + * \include example/sam3x8h_sam3x_ek/conf_board.h + * + * \subsection asfdoc_uhi_hid_mouse_config_examples_4_5 SAM D21 Devices (USB) + * \include example/samd21j18a_samd21_xplained_pro/conf_board.h + */ + +/** + * \page asfdoc_uhi_hid_mouse_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev.DateComments
42342B12/2015Fixed typos
42342A12/2014Initial release
+ */ + diff --git a/atmel-samd/asf/common/services/usb/class/hid/usb_protocol_hid.h b/atmel-samd/asf/common/services/usb/class/hid/usb_protocol_hid.h new file mode 100644 index 0000000000000..bea54b01f89e6 --- /dev/null +++ b/atmel-samd/asf/common/services/usb/class/hid/usb_protocol_hid.h @@ -0,0 +1,320 @@ +/** + * \file + * + * \brief USB Human Interface Device (HID) protocol definitions. + * + * Copyright (c) 2009-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 + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _USB_PROTOCOL_HID_H_ +#define _USB_PROTOCOL_HID_H_ + + +/** + * \ingroup usb_protocol_group + * \defgroup usb_hid_protocol USB Human Interface Device (HID) + * protocol definitions + * \brief USB Human Interface Device (HID) protocol definitions + * + * @{ + */ + +//! \name Possible Class value +//@{ +#define HID_CLASS 0x03 +//@} + +//! \name Possible SubClass value +//@{ +//! Interface subclass NO support BOOT protocol +#define HID_SUB_CLASS_NOBOOT 0x00 +//! Interface subclass support BOOT protocol +#define HID_SUB_CLASS_BOOT 0x01 +//@} + +//! \name Possible protocol value +//@{ +//! Protocol generic standard +#define HID_PROTOCOL_GENERIC 0x00 +//! Protocol keyboard standard +#define HID_PROTOCOL_KEYBOARD 0x01 +//! Protocol mouse standard +#define HID_PROTOCOL_MOUSE 0x02 +//@} + + +//! \brief Hid USB requests (bRequest) +enum usb_reqid_hid { + USB_REQ_HID_GET_REPORT = 0x01, + USB_REQ_HID_GET_IDLE = 0x02, + USB_REQ_HID_GET_PROTOCOL = 0x03, + USB_REQ_HID_SET_REPORT = 0x09, + USB_REQ_HID_SET_IDLE = 0x0A, + USB_REQ_HID_SET_PROTOCOL = 0x0B, +}; + +//! \brief HID USB descriptor types +enum usb_descriptor_type_hid { + USB_DT_HID = 0x21, + USB_DT_HID_REPORT = 0x22, + USB_DT_HID_PHYSICAL = 0x23, +}; + +//! \brief HID Type for report descriptor +enum usb_hid_item_report_type { + USB_HID_ITEM_REPORT_TYPE_MAIN = 0, + USB_HID_ITEM_REPORT_TYPE_GLOBAL = 1, + USB_HID_ITEM_REPORT_TYPE_LOCAL = 2, + USB_HID_ITEM_REPORT_TYPE_LONG = 3, +}; + +//! \brief HID report type +enum usb_hid_report_type { + USB_HID_REPORT_TYPE_INPUT = 1, + USB_HID_REPORT_TYPE_OUTPUT = 2, + USB_HID_REPORT_TYPE_FEATURE = 3, +}; + + +//! \brief HID protocol +enum usb_hid_protocol { + USB_HID_PROCOTOL_BOOT = 0, + USB_HID_PROCOTOL_REPORT = 1, +}; + +COMPILER_PACK_SET(1) + +//! \brief HID Descriptor +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< HID descriptor type + le16_t bcdHID; //!< Binary Coded Decimal Spec. release + uint8_t bCountryCode; //!< Hardware target country + uint8_t bNumDescriptors; //!< Number of HID class descriptors to follow + uint8_t bRDescriptorType; //!< Report descriptor type + le16_t wDescriptorLength; //!< Total length of Report descriptor +} usb_hid_descriptor_t; + +COMPILER_PACK_RESET() + + //! \name HID Report type + //! Used by SETUP_HID_GET_REPORT & SETUP_HID_SET_REPORT + //! @{ +#define REPORT_TYPE_INPUT 0x01 +#define REPORT_TYPE_OUTPUT 0x02 +#define REPORT_TYPE_FEATURE 0x03 + //! @} + + //! \name Constants of field DESCRIPTOR_HID + //! @{ +//! Numeric expression identifying the HID Class +//! Specification release (here V1.11) +#define USB_HID_BDC_V1_11 0x0111 +//! Numeric expression specifying the number of class descriptors +//! Note: Always at least one i.e. Report descriptor. +#define USB_HID_NUM_DESC 0x01 + + //! \name Country code + //! @{ +#define USB_HID_NO_COUNTRY_CODE 0 // Not Supported +#define USB_HID_COUNTRY_ARABIC 1 // Arabic +#define USB_HID_COUNTRY_BELGIAN 2 // Belgian +#define USB_HID_COUNTRY_CANADIAN_BILINGUAL 3 // Canadian-Bilingual +#define USB_HID_COUNTRY_CANADIAN_FRENCH 4 // Canadian-French +#define USB_HID_COUNTRY_CZECH_REPUBLIC 5 // Czech Republic +#define USB_HID_COUNTRY_DANISH 6 // Danish +#define USB_HID_COUNTRY_FINNISH 7 // Finnish +#define USB_HID_COUNTRY_FRENCH 8 // French +#define USB_HID_COUNTRY_GERMAN 9 // German +#define USB_HID_COUNTRY_GREEK 10 // Greek +#define USB_HID_COUNTRY_HEBREW 11 // Hebrew +#define USB_HID_COUNTRY_HUNGARY 12 // Hungary +#define USB_HID_COUNTRY_INTERNATIONAL_ISO 13 // International (ISO) +#define USB_HID_COUNTRY_ITALIAN 14 // Italian +#define USB_HID_COUNTRY_JAPAN_KATAKANA 15 // Japan (Katakana) +#define USB_HID_COUNTRY_KOREAN 16 // Korean +#define USB_HID_COUNTRY_LATIN_AMERICAN 17 // Latin American +#define USB_HID_COUNTRY_NETHERLANDS_DUTCH 18 // Netherlands/Dutch +#define USB_HID_COUNTRY_NORWEGIAN 19 // Norwegian +#define USB_HID_COUNTRY_PERSIAN_FARSI 20 // Persian (Farsi) +#define USB_HID_COUNTRY_POLAND 21 // Poland +#define USB_HID_COUNTRY_PORTUGUESE 22 // Portuguese +#define USB_HID_COUNTRY_RUSSIA 23 // Russia +#define USB_HID_COUNTRY_SLOVAKIA 24 // Slovakia +#define USB_HID_COUNTRY_SPANISH 25 // Spanish +#define USB_HID_COUNTRY_SWEDISH 26 // Swedish +#define USB_HID_COUNTRY_SWISS_FRENCH 27 // Swiss/French +#define USB_HID_COUNTRY_SWISS_GERMAN 28 // Swiss/German +#define USB_HID_COUNTRY_SWITZERLAND 29 // Switzerland +#define USB_HID_COUNTRY_TAIWAN 30 // Taiwan +#define USB_HID_COUNTRY_TURKISH_Q 31 // Turkish-Q +#define USB_HID_COUNTRY_UK 32 // UK +#define USB_HID_COUNTRY_US 33 // US +#define USB_HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia +#define USB_HID_COUNTRY_TURKISH_F 35 // Turkish-F + //! @} + //! @} +//! @} + + +//! \name HID KEYS values +//! @{ +#define HID_A 0x04 +#define HID_B 0x05 +#define HID_C 0x06 +#define HID_D 0x07 +#define HID_E 0x08 +#define HID_F 0x09 +#define HID_G 0x0A +#define HID_H 0x0B +#define HID_I 0x0C +#define HID_J 0x0D +#define HID_K 0x0E +#define HID_L 0x0F +#define HID_M 0x10 +#define HID_N 0x11 +#define HID_O 0x12 +#define HID_P 0x13 +#define HID_Q 0x14 +#define HID_R 0x15 +#define HID_S 0x16 +#define HID_T 0x17 +#define HID_U 0x18 +#define HID_V 0x19 +#define HID_W 0x1A +#define HID_X 0x1B +#define HID_Y 0x1C +#define HID_Z 0x1D +#define HID_1 30 +#define HID_2 31 +#define HID_3 32 +#define HID_4 33 +#define HID_5 34 +#define HID_6 35 +#define HID_7 36 +#define HID_8 37 +#define HID_9 38 +#define HID_0 39 +#define HID_ENTER 40 +#define HID_ESCAPE 41 +#define HID_BACKSPACE 42 +#define HID_TAB 43 +#define HID_SPACEBAR 44 +#define HID_UNDERSCORE 45 +#define HID_PLUS 46 +#define HID_OPEN_BRACKET 47 // { +#define HID_CLOSE_BRACKET 48 // } +#define HID_BACKSLASH 49 +#define HID_ASH 50 // # ~ +#define HID_COLON 51 // ; : +#define HID_QUOTE 52 // ' " +#define HID_TILDE 53 +#define HID_COMMA 54 +#define HID_DOT 55 +#define HID_SLASH 56 +#define HID_CAPS_LOCK 57 +#define HID_F1 58 +#define HID_F2 59 +#define HID_F3 60 +#define HID_F4 61 +#define HID_F5 62 +#define HID_F6 63 +#define HID_F7 64 +#define HID_F8 65 +#define HID_F9 66 +#define HID_F10 67 +#define HID_F11 68 +#define HID_F12 69 +#define HID_PRINTSCREEN 70 +#define HID_SCROLL_LOCK 71 +#define HID_PAUSE 72 +#define HID_INSERT 73 +#define HID_HOME 74 +#define HID_PAGEUP 75 +#define HID_DELETE 76 +#define HID_END 77 +#define HID_PAGEDOWN 78 +#define HID_RIGHT 79 +#define HID_LEFT 80 +#define HID_DOWN 81 +#define HID_UP 82 +#define HID_KEYPAD_NUM_LOCK 83 +#define HID_KEYPAD_DIVIDE 84 +#define HID_KEYPAD_AT 85 +#define HID_KEYPAD_MULTIPLY 85 +#define HID_KEYPAD_MINUS 86 +#define HID_KEYPAD_PLUS 87 +#define HID_KEYPAD_ENTER 88 +#define HID_KEYPAD_1 89 +#define HID_KEYPAD_2 90 +#define HID_KEYPAD_3 91 +#define HID_KEYPAD_4 92 +#define HID_KEYPAD_5 93 +#define HID_KEYPAD_6 94 +#define HID_KEYPAD_7 95 +#define HID_KEYPAD_8 96 +#define HID_KEYPAD_9 97 +#define HID_KEYPAD_0 98 + + //! \name HID modifier values + //! @{ +#define HID_MODIFIER_NONE 0x00 +#define HID_MODIFIER_LEFT_CTRL 0x01 +#define HID_MODIFIER_LEFT_SHIFT 0x02 +#define HID_MODIFIER_LEFT_ALT 0x04 +#define HID_MODIFIER_LEFT_UI 0x08 +#define HID_MODIFIER_RIGHT_CTRL 0x10 +#define HID_MODIFIER_RIGHT_SHIFT 0x20 +#define HID_MODIFIER_RIGHT_ALT 0x40 +#define HID_MODIFIER_RIGHT_UI 0x80 + //! @} +//! @} + +//! \name HID KEYS values +//! @{ +#define HID_LED_NUM_LOCK (1<<0) +#define HID_LED_CAPS_LOCK (1<<1) +#define HID_LED_SCROLL_LOCK (1<<2) +#define HID_LED_COMPOSE (1<<3) +#define HID_LED_KANA (1<<4) +//! @} + +#endif // _USB_PROTOCOL_HID_H_ diff --git a/atmel-samd/boards/arduino_zero/conf_usb.h b/atmel-samd/boards/arduino_zero/conf_usb.h index bdd5f9b5ea7a3..9ef8dd836d125 100644 --- a/atmel-samd/boards/arduino_zero/conf_usb.h +++ b/atmel-samd/boards/arduino_zero/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -106,6 +108,59 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 /** * Description of Composite Device @@ -116,27 +171,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +211,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/cplay_m0_flash/conf_usb.h b/atmel-samd/boards/cplay_m0_flash/conf_usb.h index fbf2cc4bf3887..f4ba8eccbf251 100644 --- a/atmel-samd/boards/cplay_m0_flash/conf_usb.h +++ b/atmel-samd/boards/cplay_m0_flash/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -106,6 +108,59 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 /** * Description of Composite Device @@ -116,27 +171,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +211,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/feather_m0_adalogger/conf_usb.h b/atmel-samd/boards/feather_m0_adalogger/conf_usb.h index 0834403c659e0..5a65ed6e64169 100644 --- a/atmel-samd/boards/feather_m0_adalogger/conf_usb.h +++ b/atmel-samd/boards/feather_m0_adalogger/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -106,6 +108,59 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 /** * Description of Composite Device @@ -116,27 +171,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +211,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/feather_m0_basic/conf_usb.h b/atmel-samd/boards/feather_m0_basic/conf_usb.h index 5919bb78644ab..93abf17b76b73 100644 --- a/atmel-samd/boards/feather_m0_basic/conf_usb.h +++ b/atmel-samd/boards/feather_m0_basic/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Two interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -107,6 +109,60 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 + /** * Description of Composite Device * @{ @@ -116,27 +172,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +212,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/feather_m0_flash/conf_usb.h b/atmel-samd/boards/feather_m0_flash/conf_usb.h index 5919bb78644ab..125e42d66f9cc 100644 --- a/atmel-samd/boards/feather_m0_flash/conf_usb.h +++ b/atmel-samd/boards/feather_m0_flash/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -106,6 +108,59 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 /** * Description of Composite Device @@ -116,27 +171,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +211,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/gemma_m0/conf_usb.h b/atmel-samd/boards/gemma_m0/conf_usb.h index d6af74997b142..bfe126bf29b5a 100644 --- a/atmel-samd/boards/gemma_m0/conf_usb.h +++ b/atmel-samd/boards/gemma_m0/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -106,6 +108,59 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 /** * Description of Composite Device @@ -116,27 +171,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +211,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/metro_m0_flash/conf_usb.h b/atmel-samd/boards/metro_m0_flash/conf_usb.h index d6af74997b142..1bbf0b7eeee23 100644 --- a/atmel-samd/boards/metro_m0_flash/conf_usb.h +++ b/atmel-samd/boards/metro_m0_flash/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -107,6 +109,60 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 + /** * Description of Composite Device * @{ @@ -116,27 +172,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +212,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/boards/trinket_m0/conf_usb.h b/atmel-samd/boards/trinket_m0/conf_usb.h index d6af74997b142..bfe126bf29b5a 100644 --- a/atmel-samd/boards/trinket_m0/conf_usb.h +++ b/atmel-samd/boards/trinket_m0/conf_usb.h @@ -29,15 +29,17 @@ extern char serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 -//! Two interfaces for this device (CDC COM + CDC DATA + MSC) -#define USB_DEVICE_NB_INTERFACE 3 +//! Interfaces for this device (CDC COM + CDC DATA + MSC + HID mouse + HID kbd) +#define USB_DEVICE_NB_INTERFACE 5 // (3 | USB_EP_DIR_IN) // CDC Notify endpoint // (4 | USB_EP_DIR_IN) // CDC TX // (5 | USB_EP_DIR_OUT) // CDC RX // (1 | USB_EP_DIR_IN) // MSC IN // (2 | USB_EP_DIR_OUT) // MSC OUT -#define USB_DEVICE_MAX_EP 5 +// (6 | USB_EP_DIR_IN) // HID mouse report +// (7 | USB_EP_DIR_IN) // HID keyboard report +#define USB_DEVICE_MAX_EP 7 #define UDI_CDC_PORT_NB 1 #define UDI_CDC_ENABLE_EXT(port) mp_cdc_enable(port) @@ -106,6 +108,59 @@ extern void mp_msc_disable(void); //! Interface number #define UDI_MSC_IFACE_NUMBER 2 +/** + * Configuration of HID Mouse interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_MOUSE_ENABLE_EXT() mp_mouse_enable() +extern bool mp_mouse_enable(void); +#define UDI_HID_MOUSE_DISABLE_EXT() mp_mouse_disable() +extern void mp_mouse_disable(void); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_MOUSE_STRING_ID 6 + +/** + * USB HID Mouse low level configuration + * In standalone these configurations are defined by the HID Mouse module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_MOUSE_EP_IN (6 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_MOUSE_IFACE_NUMBER 3 +//@} +//@} + +/** + * Configuration of HID Keyboard interface + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() mp_keyboard_enable() +extern bool mp_keyboard_enable(void); +#define UDI_HID_KBD_DISABLE_EXT() mp_keyboard_disable() +extern void mp_keyboard_disable(void); +#define UDI_HID_KBD_CHANGE_LED(value) mp_keyboard_led(value) +extern void mp_keyboard_led(uint8_t); + +//! Enable id string of interface to add an extra USB string +#define UDI_HID_KBD_STRING_ID 7 + +/** + * USB HID Keyboard low level configuration + * In standalone these configurations are defined by the HID Keyboard module. + * For composite device, these configuration must be defined here + * @{ + */ +//! Endpoint numbers definition +#define UDI_HID_KBD_EP_IN (7 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 4 /** * Description of Composite Device @@ -116,27 +171,35 @@ extern void mp_msc_disable(void); usb_iad_desc_t udi_cdc_iad; \ udi_cdc_comm_desc_t udi_cdc_comm; \ udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc + udi_msc_desc_t udi_msc; \ + udi_hid_mouse_desc_t udi_hid_mouse; \ + udi_hid_kbd_desc_t udi_hid_kbd //! USB Interfaces descriptor value for Full Speed #define UDI_COMPOSITE_DESC_FS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS + .udi_msc = UDI_MSC_DESC_FS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interfaces descriptor value for High Speed #define UDI_COMPOSITE_DESC_HS \ .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS + .udi_msc = UDI_MSC_DESC_HS, \ + .udi_hid_mouse = UDI_HID_MOUSE_DESC, \ + .udi_hid_kbd = UDI_HID_KBD_DESC //! USB Interface APIs #define UDI_COMPOSITE_API \ &udi_api_cdc_comm, \ &udi_api_cdc_data, \ - &udi_api_msc + &udi_api_msc, \ + &udi_api_hid_mouse, \ + &udi_api_hid_kbd //@} /** @@ -148,5 +211,7 @@ extern void mp_msc_disable(void); //! The includes of classes and other headers must be done at the end of this file to avoid compile error #include "udi_cdc.h" #include "udi_msc.h" +#include "udi_hid_mouse.h" +#include "udi_hid_kbd.h" #endif diff --git a/atmel-samd/common-hal/usb_hid/Device.c b/atmel-samd/common-hal/usb_hid/Device.c new file mode 100644 index 0000000000000..f8d527c11669f --- /dev/null +++ b/atmel-samd/common-hal/usb_hid/Device.c @@ -0,0 +1,92 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/nlr.h" +#include "common-hal/usb_hid/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/usb_hid/Device.h" + +static void report_sent(udd_ep_status_t status, iram_size_t nb_sent, + udd_ep_id_t ep) { + UNUSED(status); + UNUSED(nb_sent); + for (uint8_t i = 0; i < 2; i++) { + if (ep == usb_hid_devices[i].endpoint) { + usb_hid_devices[i].transaction_ongoing = false; + return; + } + } +} + +bool usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { + if (!self->enabled) { + return true; + } + // Wait for the previous transaction to finish. Shouldn't happen. + uint32_t timeout = 0xffff; + + while (self->transaction_ongoing && timeout > 0) { + timeout--; + } + + if (self->transaction_ongoing) { + return false; + } + + memcpy(self->report_buffer, report, len); + + // Disable interrupts to make sure we save the ongoing state before the + // report_sent interrupt. + common_hal_mcu_disable_interrupts(); + bool ok = udd_ep_run(self->endpoint, false, + self->report_buffer, self->report_length, report_sent); + self->transaction_ongoing = ok; + common_hal_mcu_enable_interrupts(); + return ok; +} + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { + if (len != self->report_length) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Buffer incorrect size. Should be %d bytes.", self->report_length)); + } + if (!self->enabled) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "USB Inactive")); + } + if (!usb_hid_send_report(self, report, len)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "USB Busy")); + } +} + +uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { + return self->usage_page; +} + +uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { + return self->usage; +} diff --git a/atmel-samd/common-hal/usb_hid/Device.h b/atmel-samd/common-hal/usb_hid/Device.h new file mode 100644 index 0000000000000..1b313f9ceba62 --- /dev/null +++ b/atmel-samd/common-hal/usb_hid/Device.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef COMMON_HAL_USB_HID_DEVICE_H +#define COMMON_HAL_USB_HID_DEVICE_H + +#include +#include + +#include "common-hal/usb_hid/types.h" + +bool usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len); + +#endif // COMMON_HAL_USB_HID_DEVICE_H diff --git a/atmel-samd/common-hal/usb_hid/__init__.c b/atmel-samd/common-hal/usb_hid/__init__.c new file mode 100644 index 0000000000000..5fa704cf839b8 --- /dev/null +++ b/atmel-samd/common-hal/usb_hid/__init__.c @@ -0,0 +1,117 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "common-hal/usb_hid/__init__.h" +#include "common-hal/usb_hid/Device.h" +#include "common-hal/usb_hid/types.h" + +#include "shared-bindings/usb_hid/__init__.h" +#include "shared-bindings/usb_hid/Device.h" + +#define UDI_HID_MOUSE_REPORT_SIZE 4 +#define UDI_HID_KBD_REPORT_SIZE 8 + +uint8_t mouse_report_buffer[UDI_HID_MOUSE_REPORT_SIZE]; +uint8_t kbd_report_buffer[UDI_HID_KBD_REPORT_SIZE]; + +usb_hid_device_obj_t usb_hid_devices[2] = { + { + .endpoint = UDI_HID_MOUSE_EP_IN, + .report_length = UDI_HID_MOUSE_REPORT_SIZE, + .report_buffer = mouse_report_buffer, + .usage_page = 0x01, + .usage = 0x02, + .enabled = false, + .transaction_ongoing = false + }, + { + .endpoint = UDI_HID_KBD_EP_IN, + .report_length = UDI_HID_KBD_REPORT_SIZE, + .report_buffer = kbd_report_buffer, + .usage_page = 0x01, + .usage = 0x06, + .enabled = false, + .transaction_ongoing = false + } +}; + +// TODO(tannewt): Make this a mp_obj_tuple_t when it is dynamically allocated. +// until then we hard code it to two entries so LTO is happy. +mp_obj_tuple2_t common_hal_usb_hid_devices = { + .base = { + .type = &mp_type_tuple, + }, + .len = 2, + .items = { + (mp_obj_t) &usb_hid_devices[0], + (mp_obj_t) &usb_hid_devices[1] + } +}; + +void usb_hid_init() { + usb_hid_devices[0].base.type = &usb_hid_device_type; + usb_hid_devices[1].base.type = &usb_hid_device_type; +} + +void usb_hid_reset() { + // We don't actually reset. We just set a report that is empty to prevent + // long keypresses and such. + uint8_t report[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + usb_hid_send_report(&usb_hid_devices[0], report, 4); + usb_hid_send_report(&usb_hid_devices[1], report, 8); +} + +bool mp_mouse_enable(void) +{ + usb_hid_devices[0].enabled = true; + return true; +} + +void mp_mouse_disable(void) +{ + usb_hid_devices[0].enabled = false; +} + +bool mp_keyboard_enable(void) +{ + usb_hid_devices[1].enabled = true; + return true; +} + +void mp_keyboard_disable(void) +{ + usb_hid_devices[1].enabled = false; +} + +void mp_keyboard_led(uint8_t leds) +{ + UNUSED(leds); +} diff --git a/atmel-samd/common-hal/usb_hid/__init__.h b/atmel-samd/common-hal/usb_hid/__init__.h new file mode 100644 index 0000000000000..21f629f137287 --- /dev/null +++ b/atmel-samd/common-hal/usb_hid/__init__.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef COMMON_HAL_USB_HID_H +#define COMMON_HAL_USB_HID_H + +#include +#include + +#include "common-hal/usb_hid/types.h" + +usb_hid_device_obj_t usb_hid_devices[2]; + +void usb_hid_init(void); +void usb_hid_reset(void); + +#endif // COMMON_HAL_USB_HID_H diff --git a/atmel-samd/common-hal/usb_hid/types.h b/atmel-samd/common-hal/usb_hid/types.h new file mode 100644 index 0000000000000..4d72ae0ca946f --- /dev/null +++ b/atmel-samd/common-hal/usb_hid/types.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_COMMON_HAL_USB_HID_TYPES_H__ +#define __MICROPY_INCLUDED_COMMON_HAL_USB_HID_TYPES_H__ + +#include "conf_usb.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + udd_ep_id_t endpoint; + volatile bool transaction_ongoing; + volatile bool enabled; + uint8_t report_length; + uint8_t* report_buffer; + uint8_t usage_page; + uint8_t usage; +} usb_hid_device_obj_t; + +#endif // __MICROPY_INCLUDED_COMMON_HAL_USB_HID_TYPES_H__ diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 44c0e6494892c..5f99292ecadd6 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -25,6 +25,7 @@ #include "common-hal/nativeio/AnalogIn.h" #include "common-hal/nativeio/PWMOut.h" +#include "common-hal/usb_hid/__init__.h" #ifdef EXPRESS_BOARD #include "common-hal/nativeio/types.h" @@ -183,6 +184,8 @@ void reset_samd21(void) { pwmout_reset(); + usb_hid_reset(); + #ifdef CALIBRATE_CRYSTALLESS // If we are on USB lets double check our fine calibration for the clock and // save the new value if its different enough. @@ -515,11 +518,14 @@ int main(void) { // as current dir. init_flash_fs(); + usb_hid_init(); + // Start USB after getting everything going. #ifdef USB_REPL udc_start(); #endif + // Main script is finished, so now go into REPL mode. // The REPL mode can change, or it can request a soft reset. int exit_code = PYEXEC_FORCED_EXIT; diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h index 1803bdf7b38b9..91ae2091f9dfa 100644 --- a/atmel-samd/mpconfigport.h +++ b/atmel-samd/mpconfigport.h @@ -131,6 +131,7 @@ extern const struct _mp_obj_module_t time_module; extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t uheap_module; extern const struct _mp_obj_module_t samd_module; +extern const struct _mp_obj_module_t usb_hid_module; // Internal flash size dependent settings. #if BOARD_FLASH_SIZE > 192000 @@ -151,6 +152,7 @@ extern const struct _mp_obj_module_t samd_module; { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_samd),(mp_obj_t)&samd_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ EXTRA_BUILTIN_MODULES #define MICROPY_PORT_BUILTIN_DEBUG_MODULES \ diff --git a/py/objtuple.h b/py/objtuple.h index 024f38a0d7343..d09e0e8f00d03 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -34,6 +34,13 @@ typedef struct _mp_obj_tuple_t { mp_obj_t items[]; } mp_obj_tuple_t; +// TODO(tannewt): Remove this when we no longer hard code the usb hid tuple. +typedef struct _mp_obj_tuple2_t { + mp_obj_base_t base; + mp_uint_t len; + mp_obj_t items[2]; +} mp_obj_tuple2_t; + typedef struct _mp_rom_obj_tuple_t { mp_obj_base_t base; uint32_t len; @@ -48,6 +55,8 @@ typedef struct _mp_rom_obj_tuple1_t { mp_rom_obj_t items[1]; } mp_rom_obj_tuple1_t; +extern const mp_obj_type_t mp_type_tuple; + void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); mp_obj_t mp_obj_tuple_unary_op(mp_uint_t op, mp_obj_t self_in); mp_obj_t mp_obj_tuple_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs); diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c new file mode 100644 index 0000000000000..3a3cc51705826 --- /dev/null +++ b/shared-bindings/usb_hid/Device.c @@ -0,0 +1,124 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "shared-bindings/usb_hid/Device.h" + +//| .. currentmodule:: usb_hid +//| +//| :class:`Device` -- HID Device +//| ============================================ +//| +//| Usage:: +//| +//| import usb_hid +//| +//| mouse = usb_hid.devices[0] +//| +//| mouse.send_report() +//| + +//| .. class:: Device() +//| +//| Not currently dynamically supported. +//| +STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + return mp_const_none; +} + +//| .. method:: send_report(buf) +//| +//| Send a HID report. +//| +STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); + + common_hal_usb_hid_device_send_report(self, ((uint8_t*) bufinfo.buf), bufinfo.len); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); + +//| .. attribute:: usage_page +//| +//| The usage page of the device. Can be thought of a category. +//| +//| :return: the device's usage page +//| :rtype: int +//| +STATIC mp_obj_t usb_hid_device_obj_get_usage_page(mp_obj_t self_in) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_device_get_usage_page(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_usage_page_obj, usb_hid_device_obj_get_usage_page); + +const mp_obj_property_t usb_hid_device_usage_page_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_hid_device_get_usage_page_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: usage +//| +//| The functionality of the device. For example Keyboard is 0x06 within the +//| generic desktop usage page 0x01. Mouse is 0x02 within the same usage +//| page. +//| +//| :return: the usage within the usage page +//| :rtype: int +//| +STATIC mp_obj_t usb_hid_device_obj_get_usage(mp_obj_t self_in) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_device_get_usage(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_usage_obj, + usb_hid_device_obj_get_usage); + +const mp_obj_property_t usb_hid_device_usage_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_hid_device_get_usage_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, + { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(usb_hid_device_locals_dict, usb_hid_device_locals_dict_table); + +const mp_obj_type_t usb_hid_device_type = { + { &mp_type_type }, + .name = MP_QSTR_Device, + .make_new = usb_hid_device_make_new, + .locals_dict = (mp_obj_t)&usb_hid_device_locals_dict, +}; diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h new file mode 100644 index 0000000000000..08713874e19dc --- /dev/null +++ b/shared-bindings/usb_hid/Device.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ + +#include "common-hal/usb_hid/types.h" + +const mp_obj_type_t usb_hid_device_type; + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len); +uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self); +uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c new file mode 100644 index 0000000000000..a870cb4a1a731 --- /dev/null +++ b/shared-bindings/usb_hid/__init__.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_hid/__init__.h" +#include "shared-bindings/usb_hid/Device.h" + +//| :mod:`usb_hid` --- USB Human Interface Device +//| =========================================================== +//| +//| .. module:: usb_hid +//| :synopsis: USB Human Interface Device +//| :platform: SAMD21 +//| +//| The `usb_hid` module allows you to output data as a HID device. +//| + +//| .. warning:: This module may be dropped from builds without external flash +//| in the future. Please file an issue if this a problem and explain why. +//| + +//| .. attribute:: usb_hid.devices +//| +//| Tuple of all active HID device interfaces. +//| + +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Device +STATIC const mp_rom_map_elem_t usb_hid_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid) }, + { MP_ROM_QSTR(MP_QSTR_devices), MP_ROM_PTR(&common_hal_usb_hid_devices) }, + { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&usb_hid_device_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(usb_hid_module_globals, usb_hid_module_globals_table); + +const mp_obj_module_t usb_hid_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&usb_hid_module_globals, +}; diff --git a/shared-bindings/usb_hid/__init__.h b/shared-bindings/usb_hid/__init__.h new file mode 100644 index 0000000000000..576a3301b8e77 --- /dev/null +++ b/shared-bindings/usb_hid/__init__.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef SHARED_BINDINGS_USB_HID_H +#define SHARED_BINDINGS_USB_HID_H + +#include +#include + +#include "common-hal/nativeio/types.h" + +// TODO(tannewt): Make this a mp_obj_tuple_t when it is dynamically allocated. +// until then we hard code it to two entries so LTO is happy. +extern mp_obj_tuple2_t common_hal_usb_hid_devices; + +#endif // SHARED_BINDINGS_USB_HID_H