diff options
Diffstat (limited to 'arduino/cores/nRF5/usb')
50 files changed, 10974 insertions, 0 deletions
diff --git a/arduino/cores/nRF5/usb/USBSerial.cpp b/arduino/cores/nRF5/usb/USBSerial.cpp new file mode 100755 index 0000000..f8086e4 --- /dev/null +++ b/arduino/cores/nRF5/usb/USBSerial.cpp @@ -0,0 +1,118 @@ +/**************************************************************************/ +/*! + @file USBSerial.cpp + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Adafruit Industries (adafruit.com) + All rights reserved. + + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. +*/ +/**************************************************************************/ + +#ifdef NRF52840_XXAA + +#include "USBSerial.h" +#include "Arduino.h" +#include "tusb.h" + + +USBSerial Serial; + +USBSerial::USBSerial(void) +{ + +} + +// Baud and config is ignore in CDC +void USBSerial::begin (uint32_t baud) +{ +} +void USBSerial::begin (uint32_t baud, uint8_t config) +{ +} + +void USBSerial::end(void) +{ + // nothing to do +} + +USBSerial::operator bool() +{ + return tud_cdc_connected(); +} + +int USBSerial::available(void) +{ + return tud_cdc_available(); +} + +int USBSerial::peek(void) +{ + return tud_cdc_peek(0); +} + +int USBSerial::read(void) +{ + return (int) tud_cdc_read_char(); +} + +size_t USBSerial::readBytes(char *buffer, size_t length) +{ + return tud_cdc_read(buffer, length); +} + +void USBSerial::flush(void) +{ + tud_cdc_write_flush(); +} + +size_t USBSerial::write(uint8_t ch) +{ + return tud_cdc_write_char((char) ch); +} + +size_t USBSerial::write(const uint8_t *buffer, size_t size) +{ + size_t remain = size; + while ( remain && tud_cdc_connected() ) + { + size_t wrcount = tud_cdc_write(buffer, remain); + remain -= wrcount; + buffer += wrcount; + + // Write FIFO is full, flush and re-try + if ( remain ) + { + tud_cdc_write_flush(); + } + } + + return size - remain; +} + +#endif // NRF52840_XXAA diff --git a/arduino/cores/nRF5/usb/USBSerial.h b/arduino/cores/nRF5/usb/USBSerial.h new file mode 100755 index 0000000..d6a91a0 --- /dev/null +++ b/arduino/cores/nRF5/usb/USBSerial.h @@ -0,0 +1,74 @@ +/**************************************************************************/ +/*! + @file USBSerial.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Adafruit Industries (adafruit.com) + All rights reserved. + + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. +*/ +/**************************************************************************/ + +#ifndef USBSERIAL_H_ +#define USBSERIAL_H_ + +#ifdef NRF52840_XXAA + +#include "Stream.h" + +class USBSerial : public Stream +{ +public: + USBSerial(void); + + void setPins(uint8_t pin_rx, uint8_t pin_tx) { (void) pin_rx; (void) pin_tx; } + void begin(uint32_t baud_count); + void begin(uint32_t baud, uint8_t config); + void end(void); + + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + operator bool(); + + size_t readBytes(char *buffer, size_t length); + size_t readBytes(uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } +}; + + +extern USBSerial Serial; + +#endif + +#endif /* USBSERIAL_H_ */ diff --git a/arduino/cores/nRF5/usb/tinyusb/LICENSE b/arduino/cores/nRF5/usb/tinyusb/LICENSE new file mode 100755 index 0000000..4a8afaa --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/LICENSE @@ -0,0 +1,26 @@ +BSD License
+
+Copyright (c) 2018, hathach (tinyusb.org)
+All rights reserved.
+
+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. Neither the name of the copyright holders nor the
+names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
diff --git a/arduino/cores/nRF5/usb/tinyusb/README.md b/arduino/cores/nRF5/usb/tinyusb/README.md new file mode 100755 index 0000000..51b6c09 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/README.md @@ -0,0 +1,79 @@ +# tinyusb #
+
+<!-- START doctoc generated TOC please keep comment here to allow auto update -->
+<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
+**Table of Contents**
+
+- [Features](#features)
+ - [Host](#host)
+ - [Device](#device)
+ - [RTOS](#rtos)
+ - [Supported MCUs](#supported-mcus)
+ - [Toolchains](#toolchains)
+- [Getting Started](#getting-started)
+- [License](#license)
+- [How Can I Help](#how-can-i-help)
+ - [Donate Time](#donate-time)
+ - [Donate Money](#donate-money)
+
+<!-- END doctoc generated TOC please keep comment here to allow auto update -->
+
+tinyusb is an open-source (BSD-licensed) USB Host/Device/OTG stack for embedded micro-controllers, especially ARM MCUs. It is designed to be user-friendly in term of configuration and out-of-the-box running experience.
+
+In addition to running without an RTOS, tinyusb is an OS-awared stack that can run across RTOS vendors. For the purpose of eliminating bugs as soon as possible, the stack is developed using [Test-Driven Development (TDD)](tests/readme.md) approach. More documents and API reference can be found at http://docs.tinyusb.org
+
+
+
+## Features ##
+
+### Host ###
+
+- HID Mouse
+- HID Keyboard
+- HID Generic (comming soon)
+- Communication Device Class (CDC)
+- Mass Storage Class (MSC)
+- Hub currnetly only support 1 level of hub (due to my laziness)
+
+### Device ###
+
+- HID Mouse
+- HID Keyboard
+- HID Generic (comming soon)
+- Communication Class (CDC)
+- Mass Storage Class (MSC)
+
+### RTOS ###
+
+Currently the following OS are supported with tinyusb out of the box with a simple change of CFG_TUSB_OS macro.
+
+- **None OS**
+- **FreeRTOS**
+- **CMSIS RTX**
+
+### Toolchains ###
+
+You can compile with any of following toolchains, however, the stack requires C99 to build with
+
+- lpcxpresso
+- Keil MDK
+- IAR Workbench
+
+### Supported MCUs ###
+
+The stack supports the following MCUs
+
+ - LPC11uxx
+ - LPC13uxx (12 bit ADC)
+ - LPC175x_6x
+ - LPC43xx
+
+[Here is the list of supported Boards](boards/readme.md) in the code base
+
+## Getting Started ##
+
+[Here is the details for getting started](doxygen/getting_started.md) with the stack.
+
+## License ##
+
+BSD license for most of the code base, but each file is individually licensed especially those in *vendor* folder. Please make sure you understand all the license term for files you use in your project. [Full license is here](tinyusb/license.md)
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc.h b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc.h new file mode 100755 index 0000000..1b127ad --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc.h @@ -0,0 +1,412 @@ +/**************************************************************************/
+/*!
+ @file cdc.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_class
+ * \defgroup ClassDriver_CDC Communication Device Class (CDC)
+ * Currently only Abstract Control Model subclass is supported
+ * @{ */
+
+#ifndef _TUSB_CDC_H__
+#define _TUSB_CDC_H__
+
+#include "common/tusb_common.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \defgroup ClassDriver_CDC_Common Common Definitions
+ * @{ */
+
+
+/// CDC Pipe ID, used to indicate which pipe the API is addressing to (Notification, Out, In)
+typedef enum
+{
+ CDC_PIPE_NOTIFICATION , ///< Notification pipe
+ CDC_PIPE_DATA_IN , ///< Data in pipe
+ CDC_PIPE_DATA_OUT , ///< Data out pipe
+ CDC_PIPE_ERROR , ///< Invalid Pipe ID
+}cdc_pipeid_t;
+
+//--------------------------------------------------------------------+
+// CDC COMMUNICATION INTERFACE CLASS
+//--------------------------------------------------------------------+
+/// Communication Interface Subclass Codes
+typedef enum
+{
+ CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2]
+ CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL , ///< Abstract Control Model [USBPSTN1.2]
+ CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL , ///< Telephone Control Model [USBPSTN1.2]
+ CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL , ///< Multi-Channel Control Model [USBISDN1.2]
+ CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL , ///< CAPI Control Model [USBISDN1.2]
+ CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL , ///< Ethernet Networking Control Model [USBECM1.2]
+ CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL , ///< ATM Networking Control Model [USBATM1.2]
+ CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL , ///< Wireless Handset Control Model [USBWMC1.1]
+ CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT , ///< Device Management [USBWMC1.1]
+ CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL , ///< Mobile Direct Line Model [USBWMC1.1]
+ CDC_COMM_SUBCLASS_OBEX , ///< OBEX [USBWMC1.1]
+ CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model [USBEEM1.0]
+} cdc_comm_sublcass_type_t;
+
+/// Communication Interface Protocol Codes
+typedef enum
+{
+ CDC_COMM_PROTOCOL_ATCOMMAND = 0x01 , ///< AT Commands: V.250 etc
+ CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 , ///< AT Commands defined by PCCA-101
+ CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO , ///< AT Commands defined by PCCA-101 & Annex O
+ CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 , ///< AT Commands defined by GSM 07.07
+ CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 , ///< AT Commands defined by 3GPP 27.007
+ CDC_COMM_PROTOCOL_ATCOMMAND_CDMA , ///< AT Commands defined by TIA for CDMA
+ CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model
+} cdc_comm_protocol_type_t;
+
+//------------- SubType Descriptor in COMM Functional Descriptor -------------//
+/// Communication Interface SubType Descriptor
+typedef enum
+{
+ CDC_FUNC_DESC_HEADER = 0x00 , ///< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface.
+ CDC_FUNC_DESC_CALL_MANAGEMENT = 0x01 , ///< Call Management Functional Descriptor.
+ CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT = 0x02 , ///< Abstract Control Management Functional Descriptor.
+ CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT = 0x03 , ///< Direct Line Management Functional Descriptor.
+ CDC_FUNC_DESC_TELEPHONE_RINGER = 0x04 , ///< Telephone Ringer Functional Descriptor.
+ CDC_FUNC_DESC_TELEPHONE_CALL_AND_LINE_STATE_REPORTING_CAPACITY = 0x05 , ///< Telephone Call and Line State Reporting Capabilities Functional Descriptor.
+ CDC_FUNC_DESC_UNION = 0x06 , ///< Union Functional Descriptor
+ CDC_FUNC_DESC_COUNTRY_SELECTION = 0x07 , ///< Country Selection Functional Descriptor
+ CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES = 0x08 , ///< Telephone Operational ModesFunctional Descriptor
+ CDC_FUNC_DESC_USB_TERMINAL = 0x09 , ///< USB Terminal Functional Descriptor
+ CDC_FUNC_DESC_NETWORK_CHANNEL_TERMINAL = 0x0A , ///< Network Channel Terminal Descriptor
+ CDC_FUNC_DESC_PROTOCOL_UNIT = 0x0B , ///< Protocol Unit Functional Descriptor
+ CDC_FUNC_DESC_EXTENSION_UNIT = 0x0C , ///< Extension Unit Functional Descriptor
+ CDC_FUNC_DESC_MULTICHANEL_MANAGEMENT = 0x0D , ///< Multi-Channel Management Functional Descriptor
+ CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT = 0x0E , ///< CAPI Control Management Functional Descriptor
+ CDC_FUNC_DESC_ETHERNET_NETWORKING = 0x0F , ///< Ethernet Networking Functional Descriptor
+ CDC_FUNC_DESC_ATM_NETWORKING = 0x10 , ///< ATM Networking Functional Descriptor
+ CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL = 0x11 , ///< Wireless Handset Control Model Functional Descriptor
+ CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL = 0x12 , ///< Mobile Direct Line Model Functional Descriptor
+ CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL = 0x13 , ///< MDLM Detail Functional Descriptor
+ CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL = 0x14 , ///< Device Management Model Functional Descriptor
+ CDC_FUNC_DESC_OBEX = 0x15 , ///< OBEX Functional Descriptor
+ CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor
+ CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor
+ CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor
+ CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 ///< OBEX Service Identifier Functional Descriptor
+}cdc_func_desc_type_t;
+
+//--------------------------------------------------------------------+
+// CDC DATA INTERFACE CLASS
+//--------------------------------------------------------------------+
+
+// SUBCLASS code of Data Interface is not used and should/must be zero
+/// Data Interface Protocol Codes
+typedef enum{
+ CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI
+ CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC
+ CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, ///< Transparent
+ CDC_DATA_PROTOCOL_Q921_MANAGEMENT = 0x50, ///< Management protocol for Q.921 data link protocol
+ CDC_DATA_PROTOCOL_Q921_DATA_LINK = 0x51, ///< Data link protocol for Q.931
+ CDC_DATA_PROTOCOL_Q921_TEI_MULTIPLEXOR = 0x52, ///< TEI-multiplexor for Q.921 data link protocol
+ CDC_DATA_PROTOCOL_V42BIS_DATA_COMPRESSION = 0x90, ///< Data compression procedures
+ CDC_DATA_PROTOCOL_EURO_ISDN = 0x91, ///< Euro-ISDN protocol control
+ CDC_DATA_PROTOCOL_V24_RATE_ADAPTION_TO_ISDN = 0x92, ///< V.24 rate adaptation to ISDN
+ CDC_DATA_PROTOCOL_CAPI_COMMAND = 0x93, ///< CAPI Commands
+ CDC_DATA_PROTOCOL_HOST_BASED_DRIVER = 0xFD, ///< Host based driver. Note: This protocol code should only be used in messages between host and device to identify the host driver portion of a protocol stack.
+ CDC_DATA_PROTOCOL_IN_PROTOCOL_UNIT_FUNCTIONAL_DESCRIPTOR = 0xFE ///< The protocol(s) are described using a ProtocolUnit Functional Descriptors on Communications Class Interface
+}cdc_data_protocol_type_t;
+
+//--------------------------------------------------------------------+
+// MANAGEMENT ELEMENT REQUEST (CONTROL ENDPOINT)
+//--------------------------------------------------------------------+
+/// Communication Interface Management Element Request Codes
+typedef enum
+{
+ CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface
+ CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface.
+
+ CDC_REQUEST_SET_COMM_FEATURE = 0x02,
+ CDC_REQUEST_GET_COMM_FEATURE = 0x03,
+ CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04,
+
+ CDC_REQUEST_SET_AUX_LINE_STATE = 0x10,
+ CDC_REQUEST_SET_HOOK_STATE = 0x11,
+ CDC_REQUEST_PULSE_SETUP = 0x12,
+ CDC_REQUEST_SEND_PULSE = 0x13,
+ CDC_REQUEST_SET_PULSE_TIME = 0x14,
+ CDC_REQUEST_RING_AUX_JACK = 0x15,
+
+ CDC_REQUEST_SET_LINE_CODING = 0x20,
+ CDC_REQUEST_GET_LINE_CODING = 0x21,
+ CDC_REQUEST_SET_CONTROL_LINE_STATE = 0x22,
+ CDC_REQUEST_SEND_BREAK = 0x23,
+
+ CDC_REQUEST_SET_RINGER_PARMS = 0x30,
+ CDC_REQUEST_GET_RINGER_PARMS = 0x31,
+ CDC_REQUEST_SET_OPERATION_PARMS = 0x32,
+ CDC_REQUEST_GET_OPERATION_PARMS = 0x33,
+ CDC_REQUEST_SET_LINE_PARMS = 0x34,
+ CDC_REQUEST_GET_LINE_PARMS = 0x35,
+ CDC_REQUEST_DIAL_DIGITS = 0x36,
+ CDC_REQUEST_SET_UNIT_PARAMETER = 0x37,
+ CDC_REQUEST_GET_UNIT_PARAMETER = 0x38,
+ CDC_REQUEST_CLEAR_UNIT_PARAMETER = 0x39,
+ CDC_REQUEST_GET_PROFILE = 0x3A,
+
+ CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
+ CDC_REQUEST_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
+ CDC_REQUEST_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
+ CDC_REQUEST_SET_ETHERNET_PACKET_FILTER = 0x43,
+ CDC_REQUEST_GET_ETHERNET_STATISTIC = 0x44,
+
+ CDC_REQUEST_SET_ATM_DATA_FORMAT = 0x50,
+ CDC_REQUEST_GET_ATM_DEVICE_STATISTICS = 0x51,
+ CDC_REQUEST_SET_ATM_DEFAULT_VC = 0x52,
+ CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53,
+
+ CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60,
+}cdc_management_request_t;
+
+//--------------------------------------------------------------------+
+// MANAGEMENT ELEMENENT NOTIFICATION (NOTIFICATION ENDPOINT)
+//--------------------------------------------------------------------+
+/// Communication Interface Management Element Notification Codes
+typedef enum
+{
+ NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status.
+ RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request.
+
+ AUX_JACK_HOOK_STATE = 0x08,
+ RING_DETECT = 0x09,
+
+ SERIAL_STATE = 0x20,
+
+ CALL_STATE_CHANGE = 0x28,
+ LINE_STATE_CHANGE = 0x29,
+ CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred
+ MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40,
+}cdc_notification_request_t;
+
+//--------------------------------------------------------------------+
+// FUNCTIONAL DESCRIPTOR (COMMUNICATION INTERFACE)
+//--------------------------------------------------------------------+
+/// Header Functional Descriptor (Communication Interface)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal
+}cdc_desc_func_header_t;
+
+/// Union Functional Descriptor (Communication Interface)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ uint8_t bControlInterface ; ///< Interface number of Communication Interface
+ uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
+}cdc_desc_func_union_t;
+
+#define cdc_desc_func_union_n_t(no_slave)\
+ struct ATTR_PACKED { \
+ uint8_t bLength ;\
+ uint8_t bDescriptorType ;\
+ uint8_t bDescriptorSubType ;\
+ uint8_t bControlInterface ;\
+ uint8_t bSubordinateInterface[no_slave] ;\
+}
+
+/// Country Selection Functional Descriptor (Communication Interface)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
+ uint16_t wCountryCode[] ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country.
+}cdc_desc_func_country_selection_t;
+
+#define cdc_desc_func_country_selection_n_t(no_country) \
+ struct ATTR_PACKED {\
+ uint8_t bLength ;\
+ uint8_t bDescriptorType ;\
+ uint8_t bDescriptorSubType ;\
+ uint8_t iCountryCodeRelDate ;\
+ uint16_t wCountryCode[no_country] ;\
+}
+
+//--------------------------------------------------------------------+
+// PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS
+//--------------------------------------------------------------------+
+
+/// \brief Call Management Functional Descriptor
+/// \details This functional descriptor describes the processing of calls for the Communications Class interface.
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+
+ struct {
+ uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface.
+ uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself.
+ uint8_t : 0;
+ } bmCapabilities;
+
+ uint8_t bDataInterface;
+}cdc_desc_func_call_management_t;
+
+
+typedef struct ATTR_PACKED
+{
+ uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
+ uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.
+ uint8_t support_send_break : 1; ///< Device supports the request Send_Break
+ uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection.
+ uint8_t : 0;
+}cdc_acm_capability_t;
+
+TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler");
+
+/// \brief Abstract Control Management Functional Descriptor
+/// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ cdc_acm_capability_t bmCapabilities ;
+}cdc_desc_func_acm_t;
+
+/// \brief Direct Line Management Functional Descriptor
+/// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ struct {
+ uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit.
+ uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State.
+ uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time.
+ uint8_t : 0;
+ } bmCapabilities;
+}cdc_desc_func_direct_line_management_t;
+
+/// \brief Telephone Ringer Functional Descriptor
+/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface,
+/// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ uint8_t bRingerVolSteps ;
+ uint8_t bNumRingerPatterns ;
+}cdc_desc_func_telephone_ringer_t;
+
+/// \brief Telephone Operational Modes Functional Descriptor
+/// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by
+/// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ struct {
+ uint8_t simple_mode : 1;
+ uint8_t standalone_mode : 1;
+ uint8_t computer_centric_mode : 1;
+ uint8_t : 0;
+ } bmCapabilities;
+}cdc_desc_func_telephone_operational_modes_t;
+
+/// \brief Telephone Call and Line State Reporting Capabilities Descriptor
+/// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a
+/// telephone device to report optional call and line states.
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ struct {
+ uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone
+ uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states.
+ uint32_t caller_id : 1; ///< 0 : Does not report caller ID. 1 : Reports caller ID information.
+ uint32_t incoming_distinctive : 1; ///< 0 : Reports only incoming ringing. 1 : Reports incoming distinctive ringing patterns.
+ uint32_t dual_tone_multi_freq : 1; ///< 0 : Cannot report dual tone multi-frequency (DTMF) digits input remotely over the telephone line. 1 : Can report DTMF digits input remotely over the telephone line.
+ uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification
+ uint32_t : 0;
+ } bmCapabilities;
+}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
+
+static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
+{
+ return p_desc[2];
+}
+
+//--------------------------------------------------------------------+
+// Requests
+//--------------------------------------------------------------------+
+typedef struct ATTR_PACKED
+{
+ uint32_t bit_rate;
+ uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits
+ uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
+ uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
+} cdc_line_coding_t;
+
+TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct");
+
+typedef struct ATTR_PACKED
+{
+ uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR.
+ uint16_t half_duplex_carrier_control : 1;
+ uint16_t : 14;
+} cdc_line_control_state_t;
+
+TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
+
+/** @} */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_device.c b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_device.c new file mode 100755 index 0000000..a6f1f1f --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_device.c @@ -0,0 +1,368 @@ +/**************************************************************************/
+/*!
+ @file cdc_device.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_CDC)
+
+#define _TINY_USB_SOURCE_FILE_
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "cdc_device.h"
+#include "device/usbd_pvt.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+typedef struct
+{
+ uint8_t itf_num;
+ uint8_t ep_notif;
+ uint8_t ep_in;
+ uint8_t ep_out;
+
+ // Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
+ uint8_t line_state;
+
+ /*------------- From this point, data is not cleared by bus reset -------------*/
+ char wanted_char;
+ CFG_TUSB_MEM_ALIGN cdc_line_coding_t line_coding;
+
+ // FIFO
+ tu_fifo_t rx_ff;
+ tu_fifo_t tx_ff;
+
+ uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE];
+ uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE];
+
+ osal_mutex_def_t rx_ff_mutex;
+ osal_mutex_def_t tx_ff_mutex;
+
+ // Endpoint Transfer buffer
+ CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EPSIZE];
+ CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EPSIZE];
+
+}cdcd_interface_t;
+
+#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+CFG_TUSB_ATTR_USBRAM static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
+
+//--------------------------------------------------------------------+
+// APPLICATION API
+//--------------------------------------------------------------------+
+bool tud_cdc_n_connected(uint8_t itf)
+{
+ // DTR (bit 0) active is considered as connected
+ return BIT_TEST_(_cdcd_itf[itf].line_state, 0);
+}
+
+uint8_t tud_cdc_n_get_line_state (uint8_t itf)
+{
+ return _cdcd_itf[itf].line_state;
+}
+
+void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding)
+{
+ (*coding) = _cdcd_itf[itf].line_coding;
+}
+
+void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted)
+{
+ _cdcd_itf[itf].wanted_char = wanted;
+}
+
+
+//--------------------------------------------------------------------+
+// READ API
+//--------------------------------------------------------------------+
+uint32_t tud_cdc_n_available(uint8_t itf)
+{
+ return tu_fifo_count(&_cdcd_itf[itf].rx_ff);
+}
+
+char tud_cdc_n_read_char(uint8_t itf)
+{
+ char ch;
+ return tu_fifo_read(&_cdcd_itf[itf].rx_ff, &ch) ? ch : (-1);
+}
+
+uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize)
+{
+ return tu_fifo_read_n(&_cdcd_itf[itf].rx_ff, buffer, bufsize);
+}
+
+char tud_cdc_n_peek(uint8_t itf, int pos)
+{
+ char ch;
+ return tu_fifo_peek_at(&_cdcd_itf[itf].rx_ff, pos, &ch) ? ch : (-1);
+}
+
+void tud_cdc_n_read_flush (uint8_t itf)
+{
+ tu_fifo_clear(&_cdcd_itf[itf].rx_ff);
+}
+
+//--------------------------------------------------------------------+
+// WRITE API
+//--------------------------------------------------------------------+
+
+uint32_t tud_cdc_n_write_char(uint8_t itf, char ch)
+{
+ return tud_cdc_n_write(itf, &ch, 1);
+}
+
+uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize)
+{
+ uint16_t ret = tu_fifo_write_n(&_cdcd_itf[itf].tx_ff, buffer, bufsize);
+
+#if 0 // TODO issue with circuitpython's REPL
+ // flush if queue more than endpoint size
+ if ( tu_fifo_count(&_cdcd_itf[itf].tx_ff) >= CFG_TUD_CDC_EPSIZE )
+ {
+ tud_cdc_n_write_flush(itf);
+ }
+#endif
+
+ return ret;
+}
+
+bool tud_cdc_n_write_flush (uint8_t itf)
+{
+ cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
+ TU_VERIFY( !dcd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in) ); // skip if previous transfer not complete
+
+ uint16_t count = tu_fifo_read_n(&_cdcd_itf[itf].tx_ff, p_cdc->epin_buf, CFG_TUD_CDC_EPSIZE);
+ if ( count )
+ {
+ TU_VERIFY( tud_cdc_n_connected(itf) ); // fifo is empty if not connected
+ TU_ASSERT( dcd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_in, p_cdc->epin_buf, count) );
+ }
+
+ return true;
+}
+
+
+//--------------------------------------------------------------------+
+// USBD Driver API
+//--------------------------------------------------------------------+
+void cdcd_init(void)
+{
+ tu_memclr(_cdcd_itf, sizeof(_cdcd_itf));
+
+ for(uint8_t i=0; i<CFG_TUD_CDC; i++)
+ {
+ cdcd_interface_t* ser = &_cdcd_itf[i];
+
+ ser->wanted_char = -1;
+
+ // default line coding is : stop bit = 1, parity = none, data bits = 8
+ ser->line_coding.bit_rate = 115200;
+ ser->line_coding.stop_bits = 0;
+ ser->line_coding.parity = 0;
+ ser->line_coding.data_bits = 8;
+
+ // config fifo
+ tu_fifo_config(&ser->rx_ff, ser->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, 1, true);
+ tu_fifo_config_mutex(&ser->rx_ff, osal_mutex_create(&ser->rx_ff_mutex));
+
+ tu_fifo_config(&ser->tx_ff, ser->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, 1, false);
+ tu_fifo_config_mutex(&ser->tx_ff, osal_mutex_create(&ser->tx_ff_mutex));
+ }
+}
+
+void cdcd_reset(uint8_t rhport)
+{
+ (void) rhport;
+
+ for(uint8_t i=0; i<CFG_TUD_CDC; i++)
+ {
+ tu_memclr(&_cdcd_itf[i], ITF_MEM_RESET_SIZE);
+ tu_fifo_clear(&_cdcd_itf[i].rx_ff);
+ tu_fifo_clear(&_cdcd_itf[i].tx_ff);
+ }
+}
+
+tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
+{
+ if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS;
+
+ if ( !(tu_within(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
+ 0xff == p_interface_desc->bInterfaceProtocol) )
+ {
+ return TUSB_ERROR_CDC_UNSUPPORTED_PROTOCOL;
+ }
+
+ // Find available interface
+ cdcd_interface_t * p_cdc = NULL;
+ for(uint8_t i=0; i<CFG_TUD_CDC; i++)
+ {
+ if ( _cdcd_itf[i].ep_in == 0 )
+ {
+ p_cdc = &_cdcd_itf[i];
+ break;
+ }
+ }
+
+ //------------- Control Interface -------------//
+ p_cdc->itf_num = p_interface_desc->bInterfaceNumber;
+
+ uint8_t const * p_desc = descriptor_next ( (uint8_t const *) p_interface_desc );
+ (*p_length) = sizeof(tusb_desc_interface_t);
+
+ // Communication Functional Descriptors
+ while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] )
+ {
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = descriptor_next(p_desc);
+ }
+
+ if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
+ { // notification endpoint if any
+ TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED);
+
+ p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
+
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = descriptor_next(p_desc);
+ }
+
+ //------------- Data Interface (if any) -------------//
+ if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
+ (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
+ {
+ // next to endpoint descritpor
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = descriptor_next(p_desc);
+
+ // Open endpoint pair with usbd helper
+ tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) p_desc;
+ TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
+
+ (*p_length) += 2*sizeof(tusb_desc_endpoint_t);
+ }
+
+ // Prepare for incoming data
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE), TUSB_ERROR_DCD_EDPT_XFER);
+
+ return TUSB_ERROR_NONE;
+}
+
+tusb_error_t cdcd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request)
+{
+ OSAL_SUBTASK_BEGIN
+
+ //------------- Class Specific Request -------------//
+ if (p_request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
+
+ // TODO Support multiple interfaces
+ uint8_t const itf = 0;
+ cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
+
+ if ( (CDC_REQUEST_GET_LINE_CODING == p_request->bRequest) || (CDC_REQUEST_SET_LINE_CODING == p_request->bRequest) )
+ {
+ uint16_t len = tu_min16(sizeof(cdc_line_coding_t), p_request->wLength);
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, &p_cdc->line_coding, len);
+
+ // Invoke callback
+ if (CDC_REQUEST_SET_LINE_CODING == p_request->bRequest)
+ {
+ if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding);
+ }
+ }
+ else if (CDC_REQUEST_SET_CONTROL_LINE_STATE == p_request->bRequest )
+ {
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction); // ACK control request
+
+ // CDC PSTN v1.2 section 6.3.12
+ // Bit 0: Indicates if DTE is present or not.
+ // This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready)
+ // Bit 1: Carrier control for half-duplex modems.
+ // This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
+ p_cdc->line_state = (uint8_t) p_request->wValue;
+
+ // Invoke callback
+ if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, BIT_TEST_(p_request->wValue, 0), BIT_TEST_(p_request->wValue, 1));
+ }
+ else
+ {
+ dcd_control_stall(rhport); // stall unsupported request
+ }
+
+ OSAL_SUBTASK_END
+}
+
+tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes)
+{
+ // TODO Support multiple interfaces
+ uint8_t const itf = 0;
+ cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
+
+ // receive new data
+ if ( ep_addr == p_cdc->ep_out )
+ {
+ char const wanted = p_cdc->wanted_char;
+
+ for(uint32_t i=0; i<xferred_bytes; i++)
+ {
+ tu_fifo_write(&p_cdc->rx_ff, &p_cdc->epout_buf[i]);
+
+ // Check for wanted char and invoke callback if needed
+ if ( tud_cdc_rx_wanted_cb && ( wanted != -1 ) && ( wanted == p_cdc->epout_buf[i] ) )
+ {
+ tud_cdc_rx_wanted_cb(itf, wanted);
+ }
+ }
+
+ // invoke receive callback (if there is still data)
+ if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
+
+ // prepare for next
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE), TUSB_ERROR_DCD_EDPT_XFER );
+ }
+
+ // nothing to do with in and notif endpoint
+
+ return TUSB_ERROR_NONE;
+}
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_device.h b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_device.h new file mode 100755 index 0000000..2e03793 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_device.h @@ -0,0 +1,128 @@ +/**************************************************************************/
+/*!
+ @file cdc_device.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_CDC_DEVICE_H_
+#define _TUSB_CDC_DEVICE_H_
+
+#include "common/tusb_common.h"
+#include "device/usbd.h"
+#include "cdc.h"
+
+//--------------------------------------------------------------------+
+// Class Driver Configuration
+//--------------------------------------------------------------------+
+#ifndef CFG_TUD_CDC_EPSIZE
+#define CFG_TUD_CDC_EPSIZE 64
+#endif
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \addtogroup CDC_Serial Serial
+ * @{
+ * \defgroup CDC_Serial_Device Device
+ * @{ */
+
+//--------------------------------------------------------------------+
+// APPLICATION API (Multiple Interfaces)
+// CFG_TUD_CDC > 1
+//--------------------------------------------------------------------+
+bool tud_cdc_n_connected (uint8_t itf);
+uint8_t tud_cdc_n_get_line_state (uint8_t itf);
+void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding);
+void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted);
+
+uint32_t tud_cdc_n_available (uint8_t itf);
+char tud_cdc_n_read_char (uint8_t itf);
+uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize);
+void tud_cdc_n_read_flush (uint8_t itf);
+char tud_cdc_n_peek (uint8_t itf, int pos);
+
+uint32_t tud_cdc_n_write_char (uint8_t itf, char ch);
+uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
+bool tud_cdc_n_write_flush (uint8_t itf);
+
+//--------------------------------------------------------------------+
+// APPLICATION API (Interface0)
+//--------------------------------------------------------------------+
+static inline bool tud_cdc_connected (void) { return tud_cdc_n_connected(0); }
+static inline uint8_t tud_cdc_get_line_state (void) { return tud_cdc_n_get_line_state(0); }
+static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) { return tud_cdc_n_get_line_coding(0, coding);}
+static inline void tud_cdc_set_wanted_char (char wanted) { tud_cdc_n_set_wanted_char(0, wanted); }
+
+static inline uint32_t tud_cdc_available (void) { return tud_cdc_n_available(0); }
+static inline char tud_cdc_read_char (void) { return tud_cdc_n_read_char(0); }
+static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) { return tud_cdc_n_read(0, buffer, bufsize); }
+static inline void tud_cdc_read_flush (void) { tud_cdc_n_read_flush(0); }
+static inline char tud_cdc_peek (int pos) { return tud_cdc_n_peek(0, pos); }
+
+static inline uint32_t tud_cdc_write_char (char ch) { return tud_cdc_n_write_char(0, ch); }
+static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); }
+static inline bool tud_cdc_write_flush (void) { return tud_cdc_n_write_flush(0); }
+
+//--------------------------------------------------------------------+
+// APPLICATION CALLBACK API (WEAK is optional)
+//--------------------------------------------------------------------+
+ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf);
+ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char);
+ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
+ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding);
+
+//--------------------------------------------------------------------+
+// USBD-CLASS DRIVER API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+void cdcd_init (void);
+tusb_error_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+tusb_error_t cdcd_control_request_st (uint8_t rhport, tusb_control_request_t const * p_request);
+tusb_error_t cdcd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes);
+void cdcd_reset (uint8_t rhport);
+
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CDC_DEVICE_H_ */
+
+/** @} */
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_rndis.h b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_rndis.h new file mode 100755 index 0000000..c69c831 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/cdc/cdc_rndis.h @@ -0,0 +1,313 @@ +/**************************************************************************/
+/*!
+ @file cdc_rndis.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup ClassDriver_CDC Communication Device Class (CDC)
+ * \defgroup CDC_RNDIS Remote Network Driver Interface Specification (RNDIS)
+ * @{
+ * \defgroup CDC_RNDIS_Common Common Definitions
+ * @{ */
+
+#ifndef _TUSB_CDC_RNDIS_H_
+#define _TUSB_CDC_RNDIS_H_
+
+#include "cdc.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifdef __CC_ARM
+#pragma diag_suppress 66 // Suppress Keil warnings #66-D: enumeration value is out of "int" range
+#endif
+
+/// RNDIS Message Types
+typedef enum
+{
+ RNDIS_MSG_PACKET = 0x00000001UL, ///< The host and device use this to send network data to one another.
+
+ RNDIS_MSG_INITIALIZE = 0x00000002UL, ///< Sent by the host to initialize the device.
+ RNDIS_MSG_INITIALIZE_CMPLT = 0x80000002UL, ///< Device response to an initialize message.
+
+ RNDIS_MSG_HALT = 0x00000003UL, ///< Sent by the host to halt the device. This does not have a response. It is optional for the device to send this message to the host.
+
+ RNDIS_MSG_QUERY = 0x00000004UL, ///< Sent by the host to send a query OID.
+ RNDIS_MSG_QUERY_CMPLT = 0x80000004UL, ///< Device response to a query OID.
+
+ RNDIS_MSG_SET = 0x00000005UL, ///< Sent by the host to send a set OID.
+ RNDIS_MSG_SET_CMPLT = 0x80000005UL, ///< Device response to a set OID.
+
+ RNDIS_MSG_RESET = 0x00000006UL, ///< Sent by the host to perform a soft reset on the device.
+ RNDIS_MSG_RESET_CMPLT = 0x80000006UL, ///< Device response to reset message.
+
+ RNDIS_MSG_INDICATE_STATUS = 0x00000007UL, ///< Sent by the device to indicate its status or an error when an unrecognized message is received.
+
+ RNDIS_MSG_KEEP_ALIVE = 0x00000008UL, ///< During idle periods, sent every few seconds by the host to check that the device is still responsive. It is optional for the device to send this message to check if the host is active.
+ RNDIS_MSG_KEEP_ALIVE_CMPLT = 0x80000008UL ///< The device response to a keepalivemessage. The host can respond with this message to a keepalive message from the device when the device implements the optional KeepAliveTimer.
+}rndis_msg_type_t;
+
+/// RNDIS Message Status Values
+typedef enum
+{
+ RNDIS_STATUS_SUCCESS = 0x00000000UL, ///< Success
+ RNDIS_STATUS_FAILURE = 0xC0000001UL, ///< Unspecified error
+ RNDIS_STATUS_INVALID_DATA = 0xC0010015UL, ///< Invalid data error
+ RNDIS_STATUS_NOT_SUPPORTED = 0xC00000BBUL, ///< Unsupported request error
+ RNDIS_STATUS_MEDIA_CONNECT = 0x4001000BUL, ///< Device is connected to a network medium.
+ RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000CUL ///< Device is disconnected from the medium.
+}rndis_msg_status_t;
+
+#ifdef __CC_ARM
+#pragma diag_default 66 // return Keil 66 to normal severity
+#endif
+
+//--------------------------------------------------------------------+
+// MESSAGE STRUCTURE
+//--------------------------------------------------------------------+
+
+//------------- Initialize -------------//
+/// \brief Initialize Message
+/// \details This message MUST be sent by the host to initialize the device.
+typedef struct {
+ uint32_t type ; ///< Message type, must be \ref RNDIS_MSG_INITIALIZE
+ uint32_t length ; ///< Message length in bytes, must be 0x18
+ uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device.
+ uint32_t major_version ; ///< The major version of the RNDIS Protocol implemented by the host.
+ uint32_t minor_version ; ///< The minor version of the RNDIS Protocol implemented by the host
+ uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the host expects to receive from the device.
+}rndis_msg_initialize_t;
+
+/// \brief Initialize Complete Message
+/// \details This message MUST be sent by the device in response to an initialize message.
+typedef struct {
+ uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_INITIALIZE_CMPLT
+ uint32_t length ; ///< Message length in bytes, must be 0x30
+ uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_initialize_t to which this message is a response.
+ uint32_t status ; ///< The initialization status of the device, has value from \ref rndis_msg_status_t
+ uint32_t major_version ; ///< the highest-numbered RNDIS Protocol version supported by the device.
+ uint32_t minor_version ; ///< the highest-numbered RNDIS Protocol version supported by the device.
+ uint32_t device_flags ; ///< MUST be set to 0x000000010. Other values are reserved for future use.
+ uint32_t medium ; ///< is 0x00 for RNDIS_MEDIUM_802_3
+ uint32_t max_packet_per_xfer ; ///< The maximum number of concatenated \ref RNDIS_MSG_PACKET messages that the device can handle in a single bus transfer to it. This value MUST be at least 1.
+ uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the device expects to receive from the host.
+ uint32_t packet_alignment_factor ; ///< The byte alignment the device expects for each RNDIS message that is part of a multimessage transfer to it. The value is specified as an exponent of 2; for example, the host uses 2<SUP>{PacketAlignmentFactor}</SUP> as the alignment value.
+ uint32_t reserved[2] ;
+} rndis_msg_initialize_cmplt_t;
+
+//------------- Query -------------//
+/// \brief Query Message
+/// \details This message MUST be sent by the host to query an OID.
+typedef struct {
+ uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY
+ uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer
+ uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device.
+ uint32_t oid ; ///< The integer value of the host operating system-defined identifier, for the parameter of the device being queried for.
+ uint32_t buffer_length ; ///< The length, in bytes, of the input data required for the OID query. This MUST be set to 0 when there is no input data associated with the OID.
+ uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the input data for the query is located in the message. This value MUST be set to 0 when there is no input data associated with the OID.
+ uint32_t reserved ;
+ uint8_t oid_buffer[] ; ///< Flexible array contains the input data supplied by the host, required for the OID query request processing by the device, as per the host NDIS specification.
+} rndis_msg_query_t, rndis_msg_set_t;
+
+TU_VERIFY_STATIC(sizeof(rndis_msg_query_t) == 28, "Make sure flexible array member does not affect layout");
+
+/// \brief Query Complete Message
+/// \details This message MUST be sent by the device in response to a query OID message.
+typedef struct {
+ uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY_CMPLT
+ uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer
+ uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_query_t to which this message is a response.
+ uint32_t status ; ///< The status of processing for the query request, has value from \ref rndis_msg_status_t.
+ uint32_t buffer_length ; ///< The length, in bytes, of the data in the response to the query. This MUST be set to 0 when there is no OIDInputBuffer.
+ uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the response data for the query is located in the message. This MUST be set to 0 when there is no \ref oid_buffer.
+ uint8_t oid_buffer[] ; ///< Flexible array member contains the response data to the OID query request as specified by the host.
+} rndis_msg_query_cmplt_t;
+
+TU_VERIFY_STATIC(sizeof(rndis_msg_query_cmplt_t) == 24, "Make sure flexible array member does not affect layout");
+
+//------------- Reset -------------//
+/// \brief Reset Message
+/// \details This message MUST be sent by the host to perform a soft reset on the device.
+typedef struct {
+ uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET
+ uint32_t length ; ///< Message length in bytes, MUST be 0x06
+ uint32_t reserved ;
+} rndis_msg_reset_t;
+
+/// \brief Reset Complete Message
+/// \details This message MUST be sent by the device in response to a reset message.
+typedef struct {
+ uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET_CMPLT
+ uint32_t length ; ///< Message length in bytes, MUST be 0x10
+ uint32_t status ; ///< The status of processing for the \ref rndis_msg_reset_t, has value from \ref rndis_msg_status_t.
+ uint32_t addressing_reset ; ///< This field indicates whether the addressing information, which is the multicast address list or packet filter, has been lost during the reset operation. This MUST be set to 0x00000001 if the device requires that the host to resend addressing information or MUST be set to zero otherwise.
+} rndis_msg_reset_cmplt_t;
+
+//typedef struct {
+// uint32_t type;
+// uint32_t length;
+// uint32_t status;
+// uint32_t buffer_length;
+// uint32_t buffer_offset;
+// uint32_t diagnostic_status; // optional
+// uint32_t diagnostic_error_offset; // optional
+// uint32_t status_buffer[0]; // optional
+//} rndis_msg_indicate_status_t;
+
+/// \brief Keep Alive Message
+/// \details This message MUST be sent by the host to check that device is still responsive. It is optional for the device to send this message to check if the host is active
+typedef struct {
+ uint32_t type ; ///< Message Type
+ uint32_t length ; ///< Message length in bytes, MUST be 0x10
+ uint32_t request_id ;
+} rndis_msg_keep_alive_t, rndis_msg_halt_t;
+
+/// \brief Set Complete Message
+/// \brief This message MUST be sent in response to a the request message
+typedef struct {
+ uint32_t type ; ///< Message Type
+ uint32_t length ; ///< Message length in bytes, MUST be 0x10
+ uint32_t request_id ; ///< must be the same as requesting message
+ uint32_t status ; ///< The status of processing for the request message request by the device to which this message is the response.
+} rndis_msg_set_cmplt_t, rndis_msg_keep_alive_cmplt_t;
+
+/// \brief Packet Data Message
+/// \brief This message MUST be used by the host and the device to send network data to one another.
+typedef struct {
+ uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_PACKET
+ uint32_t length ; ///< Message length in bytes, The total length of this RNDIS message including the header, payload, and padding.
+ uint32_t data_offset ; ///< Specifies the offset, in bytes, from the start of this \a data_offset field of this message to the start of the data. This MUST be an integer multiple of 4.
+ uint32_t data_length ; ///< Specifies the number of bytes in the payload of this message.
+ uint32_t out_of_band_data_offet ; ///< Specifies the offset, in bytes, of the first out-of-band data record from the start of the DataOffset field in this message. MUST be an integer multiple of 4 when out-of-band data is present or set to 0 otherwise. When there are multiple out-ofband data records, each subsequent record MUST immediately follow the previous out-of-band data record.
+ uint32_t out_of_band_data_length ; ///< Specifies, in bytes, the total length of the out-of-band data.
+ uint32_t num_out_of_band_data_elements ; ///< Specifies the number of out-of-band records in this message.
+ uint32_t per_packet_info_offset ; ///< Specifies the offset, in bytes, of the start of per-packet-info data record from the start of the \a data_offset field in this message. MUST be an integer multiple of 4 when per-packet-info data record is present or MUST be set to 0 otherwise. When there are multiple per-packet-info data records, each subsequent record MUST immediately follow the previous record.
+ uint32_t per_packet_info_length ; ///< Specifies, in bytes, the total length of per-packetinformation contained in this message.
+ uint32_t reserved[2] ;
+ uint32_t payload[0] ; ///< Network data contained in this message.
+
+ // uint8_t padding[0]
+ // Additional bytes of zeros added at the end of the message to comply with
+ // the internal and external padding requirements. Internal padding SHOULD be as per the
+ // specification of the out-of-band data record and per-packet-info data record. The external
+ //padding size SHOULD be determined based on the PacketAlignmentFactor field specification
+ //in REMOTE_NDIS_INITIALIZE_CMPLT message by the device, when multiple
+ //REMOTE_NDIS_PACKET_MSG messages are bundled together in a single bus-native message.
+ //In this case, all but the very last REMOTE_NDIS_PACKET_MSG MUST respect the
+ //PacketAlignmentFactor field.
+
+ // rndis_msg_packet_t [0] : (optional) more packet if multiple packet per bus transaction is supported
+} rndis_msg_packet_t;
+
+
+typedef struct {
+ uint32_t size ; ///< Length, in bytes, of this header and appended data and padding. This value MUST be an integer multiple of 4.
+ uint32_t type ; ///< MUST be as per host operating system specification.
+ uint32_t offset ; ///< The byte offset from the beginning of this record to the beginning of data.
+ uint32_t data[0] ; ///< Flexible array contains data
+} rndis_msg_out_of_band_data_t, rndis_msg_per_packet_info_t;
+
+//--------------------------------------------------------------------+
+// NDIS Object ID
+//--------------------------------------------------------------------+
+
+/// NDIS Object ID
+typedef enum
+{
+ //------------- General Required OIDs -------------//
+ RNDIS_OID_GEN_SUPPORTED_LIST = 0x00010101, ///< List of supported OIDs
+ RNDIS_OID_GEN_HARDWARE_STATUS = 0x00010102, ///< Hardware status
+ RNDIS_OID_GEN_MEDIA_SUPPORTED = 0x00010103, ///< Media types supported (encoded)
+ RNDIS_OID_GEN_MEDIA_IN_USE = 0x00010104, ///< Media types in use (encoded)
+ RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105, ///<
+ RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106, ///< Maximum frame size in bytes
+ RNDIS_OID_GEN_LINK_SPEED = 0x00010107, ///< Link speed in units of 100 bps
+ RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108, ///< Transmit buffer space
+ RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109, ///< Receive buffer space
+ RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010A, ///< Minimum amount of storage, in bytes, that a single packet occupies in the transmit buffer space of the NIC
+ RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010B, ///< Amount of storage, in bytes, that a single packet occupies in the receive buffer space of the NIC
+ RNDIS_OID_GEN_VENDOR_ID = 0x0001010C, ///< Vendor NIC code
+ RNDIS_OID_GEN_VENDOR_DESCRIPTION = 0x0001010D, ///< Vendor network card description
+ RNDIS_OID_GEN_CURRENT_PACKET_FILTER = 0x0001010E, ///< Current packet filter (encoded)
+ RNDIS_OID_GEN_CURRENT_LOOKAHEAD = 0x0001010F, ///< Current lookahead size in bytes
+ RNDIS_OID_GEN_DRIVER_VERSION = 0x00010110, ///< NDIS version number used by the driver
+ RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111, ///< Maximum total packet length in bytes
+ RNDIS_OID_GEN_PROTOCOL_OPTIONS = 0x00010112, ///< Optional protocol flags (encoded)
+ RNDIS_OID_GEN_MAC_OPTIONS = 0x00010113, ///< Optional NIC flags (encoded)
+ RNDIS_OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114, ///< Whether the NIC is connected to the network
+ RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115, ///< The maximum number of send packets the driver can accept per call to its MiniportSendPacketsfunction
+
+ //------------- General Optional OIDs -------------//
+ RNDIS_OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116, ///< Vendor-assigned version number of the driver
+ RNDIS_OID_GEN_SUPPORTED_GUIDS = 0x00010117, ///< The custom GUIDs (Globally Unique Identifier) supported by the miniport driver
+ RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118, ///< List of network-layer addresses associated with the binding between a transport and the driver
+ RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119, ///< Size of packets' additional headers
+ RNDIS_OID_GEN_MEDIA_CAPABILITIES = 0x00010201, ///<
+ RNDIS_OID_GEN_PHYSICAL_MEDIUM = 0x00010202, ///< Physical media supported by the miniport driver (encoded)
+
+ //------------- 802.3 Objects (Ethernet) -------------//
+ RNDIS_OID_802_3_PERMANENT_ADDRESS = 0x01010101, ///< Permanent station address
+ RNDIS_OID_802_3_CURRENT_ADDRESS = 0x01010102, ///< Current station address
+ RNDIS_OID_802_3_MULTICAST_LIST = 0x01010103, ///< Current multicast address list
+ RNDIS_OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104, ///< Maximum size of multicast address list
+} rndis_oid_type_t;
+
+/// RNDIS Packet Filter Bits \ref RNDIS_OID_GEN_CURRENT_PACKET_FILTER.
+typedef enum
+{
+ RNDIS_PACKET_TYPE_DIRECTED = 0x00000001, ///< Directed packets. Directed packets contain a destination address equal to the station address of the NIC.
+ RNDIS_PACKET_TYPE_MULTICAST = 0x00000002, ///< Multicast address packets sent to addresses in the multicast address list.
+ RNDIS_PACKET_TYPE_ALL_MULTICAST = 0x00000004, ///< All multicast address packets, not just the ones enumerated in the multicast address list.
+ RNDIS_PACKET_TYPE_BROADCAST = 0x00000008, ///< Broadcast packets.
+ RNDIS_PACKET_TYPE_SOURCE_ROUTING = 0x00000010, ///< All source routing packets. If the protocol driver sets this bit, the NDIS library attempts to act as a source routing bridge.
+ RNDIS_PACKET_TYPE_PROMISCUOUS = 0x00000020, ///< Specifies all packets regardless of whether VLAN filtering is enabled or not and whether the VLAN identifier matches or not.
+ RNDIS_PACKET_TYPE_SMT = 0x00000040, ///< SMT packets that an FDDI NIC receives.
+ RNDIS_PACKET_TYPE_ALL_LOCAL = 0x00000080, ///< All packets sent by installed protocols and all packets indicated by the NIC that is identified by a given NdisBindingHandle.
+ RNDIS_PACKET_TYPE_GROUP = 0x00001000, ///< Packets sent to the current group address.
+ RNDIS_PACKET_TYPE_ALL_FUNCTIONAL = 0x00002000, ///< All functional address packets, not just the ones in the current functional address.
+ RNDIS_PACKET_TYPE_FUNCTIONAL = 0x00004000, ///< Functional address packets sent to addresses included in the current functional address.
+ RNDIS_PACKET_TYPE_MAC_FRAME = 0x00008000, ///< NIC driver frames that a Token Ring NIC receives.
+ RNDIS_PACKET_TYPE_NO_LOCAL = 0x00010000,
+} rndis_packet_filter_type_t;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CDC_RNDIS_H_ */
+
+/** @} */
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/custom/custom_device.c b/arduino/cores/nRF5/usb/tinyusb/src/class/custom/custom_device.c new file mode 100755 index 0000000..509a65a --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/custom/custom_device.c @@ -0,0 +1,107 @@ +/**************************************************************************/
+/*!
+ @file custom_device.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_CUSTOM_CLASS)
+
+#define _TINY_USB_SOURCE_FILE_
+
+#include "common/tusb_common.h"
+#include "custom_device.h"
+#include "device/usbd_pvt.h"
+
+/*------------------------------------------------------------------*/
+/* MACRO TYPEDEF CONSTANT ENUM
+ *------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------*/
+/* VARIABLE DECLARATION
+ *------------------------------------------------------------------*/
+typedef struct {
+ uint8_t itf_num;
+
+ uint8_t ep_in;
+ uint8_t ep_out;
+
+} cusd_interface_t;
+
+static cusd_interface_t _cusd_itf;
+
+/*------------------------------------------------------------------*/
+/* FUNCTION DECLARATION
+ *------------------------------------------------------------------*/
+void cusd_init(void)
+{
+ tu_varclr(&_cusd_itf);
+}
+
+tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
+{
+ cusd_interface_t* p_itf = &_cusd_itf;
+
+ // Open endpoint pair with usbd helper
+ tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_itf );
+ TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_itf->ep_out, &p_itf->ep_in) );
+
+ p_itf->itf_num = p_desc_itf->bInterfaceNumber;
+
+ (*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
+
+ // TODO Prepare for incoming data
+// TU_ASSERT( dcd_edpt_xfer(rhport, p_itf->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_DCD_EDPT_XFER );
+
+ return TUSB_ERROR_NONE;
+}
+
+tusb_error_t cusd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request)
+{
+ return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
+}
+
+tusb_error_t cusd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes)
+{
+ return TUSB_ERROR_NONE;
+}
+
+void cusd_reset(uint8_t rhport)
+{
+
+}
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/custom/custom_device.h b/arduino/cores/nRF5/usb/tinyusb/src/class/custom/custom_device.h new file mode 100755 index 0000000..9285bbc --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/custom/custom_device.h @@ -0,0 +1,73 @@ +/**************************************************************************/
+/*!
+ @file custom_device.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_CUSTOM_DEVICE_H_
+#define _TUSB_CUSTOM_DEVICE_H_
+
+#include "common/tusb_common.h"
+#include "device/usbd.h"
+
+//--------------------------------------------------------------------+
+// APPLICATION API (Multiple Root Ports)
+// Should be used only with MCU that support more than 1 ports
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// APPLICATION API (Single Port)
+// Should be used with MCU supporting only 1 USB port for code simplicity
+//--------------------------------------------------------------------+
+
+
+//--------------------------------------------------------------------+
+// APPLICATION CALLBACK API (WEAK is optional)
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// USBD-CLASS DRIVER API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+void cusd_init(void);
+tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+tusb_error_t cusd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request);
+tusb_error_t cusd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes);
+void cusd_reset(uint8_t rhport);
+#endif
+
+
+#endif /* _TUSB_CUSTOM_DEVICE_H_ */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid.h b/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid.h new file mode 100755 index 0000000..d280317 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid.h @@ -0,0 +1,619 @@ +/**************************************************************************/
+/*!
+ @file hid.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_class
+ * \defgroup ClassDriver_HID Human Interface Device (HID)
+ * @{ */
+
+#ifndef _TUSB_HID_H_
+#define _TUSB_HID_H_
+
+#include "common/tusb_common.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Common Definitions
+//--------------------------------------------------------------------+
+/** \defgroup ClassDriver_HID_Common Common Definitions
+ * @{ */
+
+/// HID Subclass
+typedef enum
+{
+ HID_SUBCLASS_NONE = 0, ///< No Subclass
+ HID_SUBCLASS_BOOT = 1 ///< Boot Interface Subclass
+}hid_subclass_type_t;
+
+/// HID Protocol
+typedef enum
+{
+ HID_PROTOCOL_NONE = 0, ///< None
+ HID_PROTOCOL_KEYBOARD = 1, ///< Keyboard
+ HID_PROTOCOL_MOUSE = 2 ///< Mouse
+}hid_protocol_type_t;
+
+/// HID Descriptor Type
+typedef enum
+{
+ HID_DESC_TYPE_HID = 0x21, ///< HID Descriptor
+ HID_DESC_TYPE_REPORT = 0x22, ///< Report Descriptor
+ HID_DESC_TYPE_PHYSICAL = 0x23 ///< Physical Descriptor
+}hid_descriptor_type_t;
+
+/// HID Request Report Type
+typedef enum
+{
+ HID_REPORT_TYPE_INPUT = 1, ///< Input
+ HID_REPORT_TYPE_OUTPUT, ///< Output
+ HID_REPORT_TYPE_FEATURE ///< Feature
+}hid_report_type_t;
+
+/// HID Class Specific Control Request
+typedef enum
+{
+ HID_REQ_CONTROL_GET_REPORT = 0x01, ///< Get Report
+ HID_REQ_CONTROL_GET_IDLE = 0x02, ///< Get Idle
+ HID_REQ_CONTROL_GET_PROTOCOL = 0x03, ///< Get Protocol
+ HID_REQ_CONTROL_SET_REPORT = 0x09, ///< Set Report
+ HID_REQ_CONTROL_SET_IDLE = 0x0a, ///< Set Idle
+ HID_REQ_CONTROL_SET_PROTOCOL = 0x0b ///< Set Protocol
+}hid_request_type_t;
+
+/// USB HID Descriptor
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */
+ uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */
+
+ uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */
+ uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */
+ uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */
+
+ uint8_t bReportType; /**< Type of HID class report. */
+ uint16_t wReportLength; /**< the total size of the Report descriptor. */
+} tusb_hid_descriptor_hid_t;
+
+/// HID Country Code
+typedef enum
+{
+ HID_Local_NotSupported = 0 , ///< NotSupported
+ HID_Local_Arabic , ///< Arabic
+ HID_Local_Belgian , ///< Belgian
+ HID_Local_Canadian_Bilingual , ///< Canadian_Bilingual
+ HID_Local_Canadian_French , ///< Canadian_French
+ HID_Local_Czech_Republic , ///< Czech_Republic
+ HID_Local_Danish , ///< Danish
+ HID_Local_Finnish , ///< Finnish
+ HID_Local_French , ///< French
+ HID_Local_German , ///< German
+ HID_Local_Greek , ///< Greek
+ HID_Local_Hebrew , ///< Hebrew
+ HID_Local_Hungary , ///< Hungary
+ HID_Local_International , ///< International
+ HID_Local_Italian , ///< Italian
+ HID_Local_Japan_Katakana , ///< Japan_Katakana
+ HID_Local_Korean , ///< Korean
+ HID_Local_Latin_American , ///< Latin_American
+ HID_Local_Netherlands_Dutch , ///< Netherlands/Dutch
+ HID_Local_Norwegian , ///< Norwegian
+ HID_Local_Persian_Farsi , ///< Persian (Farsi)
+ HID_Local_Poland , ///< Poland
+ HID_Local_Portuguese , ///< Portuguese
+ HID_Local_Russia , ///< Russia
+ HID_Local_Slovakia , ///< Slovakia
+ HID_Local_Spanish , ///< Spanish
+ HID_Local_Swedish , ///< Swedish
+ HID_Local_Swiss_French , ///< Swiss/French
+ HID_Local_Swiss_German , ///< Swiss/German
+ HID_Local_Switzerland , ///< Switzerland
+ HID_Local_Taiwan , ///< Taiwan
+ HID_Local_Turkish_Q , ///< Turkish-Q
+ HID_Local_UK , ///< UK
+ HID_Local_US , ///< US
+ HID_Local_Yugoslavia , ///< Yugoslavia
+ HID_Local_Turkish_F ///< Turkish-F
+} hid_country_code_t;
+
+/** @} */
+
+//--------------------------------------------------------------------+
+// MOUSE
+//--------------------------------------------------------------------+
+/** \addtogroup ClassDriver_HID_Mouse Mouse
+ * @{ */
+
+/// Standard HID Boot Protocol Mouse Report.
+typedef struct ATTR_PACKED
+{
+ uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */
+ int8_t x; /**< Current delta x movement of the mouse. */
+ int8_t y; /**< Current delta y movement on the mouse. */
+ int8_t wheel; /**< Current delta wheel movement on the mouse. */
+// int8_t pan;
+} hid_mouse_report_t;
+
+/// Standard Mouse Buttons Bitmap
+typedef enum
+{
+ MOUSE_BUTTON_LEFT = BIT_(0), ///< Left button
+ MOUSE_BUTTON_RIGHT = BIT_(1), ///< Right button
+ MOUSE_BUTTON_MIDDLE = BIT_(2), ///< Middle button
+ MOUSE_BUTTON_BACKWARD = BIT_(3), ///< Backward button,
+ MOUSE_BUTTON_FORWARD = BIT_(4), ///< Forward button,
+}hid_mouse_button_bm_t;
+
+/// @}
+
+//--------------------------------------------------------------------+
+// Keyboard
+//--------------------------------------------------------------------+
+/** \addtogroup ClassDriver_HID_Keyboard Keyboard
+ * @{ */
+
+/// Standard HID Boot Protocol Keyboard Report.
+typedef struct ATTR_PACKED
+{
+ uint8_t modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of HID_KEYBOARD_MODIFER_* masks). */
+ uint8_t reserved; /**< Reserved for OEM use, always set to 0. */
+ uint8_t keycode[6]; /**< Key codes of the currently pressed keys. */
+} hid_keyboard_report_t;
+
+/// Keyboard modifier codes bitmap
+typedef enum
+{
+ KEYBOARD_MODIFIER_LEFTCTRL = BIT_(0), ///< Left Control
+ KEYBOARD_MODIFIER_LEFTSHIFT = BIT_(1), ///< Left Shift
+ KEYBOARD_MODIFIER_LEFTALT = BIT_(2), ///< Left Alt
+ KEYBOARD_MODIFIER_LEFTGUI = BIT_(3), ///< Left Window
+ KEYBOARD_MODIFIER_RIGHTCTRL = BIT_(4), ///< Right Control
+ KEYBOARD_MODIFIER_RIGHTSHIFT = BIT_(5), ///< Right Shift
+ KEYBOARD_MODIFIER_RIGHTALT = BIT_(6), ///< Right Alt
+ KEYBOARD_MODIFIER_RIGHTGUI = BIT_(7) ///< Right Window
+}hid_keyboard_modifier_bm_t;
+
+typedef enum
+{
+ KEYBOARD_LED_NUMLOCK = BIT_(0), ///< Num Lock LED
+ KEYBOARD_LED_CAPSLOCK = BIT_(1), ///< Caps Lock LED
+ KEYBOARD_LED_SCROLLLOCK = BIT_(2), ///< Scroll Lock LED
+ KEYBOARD_LED_COMPOSE = BIT_(3), ///< Composition Mode
+ KEYBOARD_LED_KANA = BIT_(4) ///< Kana mode
+}hid_keyboard_led_bm_t;
+
+/// @}
+
+//--------------------------------------------------------------------+
+// HID KEYCODE
+//--------------------------------------------------------------------+
+#define HID_KEY_NONE 0x00
+#define HID_KEY_A 0x04
+#define HID_KEY_B 0x05
+#define HID_KEY_C 0x06
+#define HID_KEY_D 0x07
+#define HID_KEY_E 0x08
+#define HID_KEY_F 0x09
+#define HID_KEY_G 0x0A
+#define HID_KEY_H 0x0B
+#define HID_KEY_I 0x0C
+#define HID_KEY_J 0x0D
+#define HID_KEY_K 0x0E
+#define HID_KEY_L 0x0F
+#define HID_KEY_M 0x10
+#define HID_KEY_N 0x11
+#define HID_KEY_O 0x12
+#define HID_KEY_P 0x13
+#define HID_KEY_Q 0x14
+#define HID_KEY_R 0x15
+#define HID_KEY_S 0x16
+#define HID_KEY_T 0x17
+#define HID_KEY_U 0x18
+#define HID_KEY_V 0x19
+#define HID_KEY_W 0x1A
+#define HID_KEY_X 0x1B
+#define HID_KEY_Y 0x1C
+#define HID_KEY_Z 0x1D
+#define HID_KEY_1 0x1E
+#define HID_KEY_2 0x1F
+#define HID_KEY_3 0x20
+#define HID_KEY_4 0x21
+#define HID_KEY_5 0x22
+#define HID_KEY_6 0x23
+#define HID_KEY_7 0x24
+#define HID_KEY_8 0x25
+#define HID_KEY_9 0x26
+#define HID_KEY_0 0x27
+#define HID_KEY_RETURN 0x28
+#define HID_KEY_ESCAPE 0x29
+#define HID_KEY_BACKSPACE 0x2A
+#define HID_KEY_TAB 0x2B
+#define HID_KEY_SPACE 0x2C
+#define HID_KEY_MINUS 0x2D
+#define HID_KEY_EQUAL 0x2E
+#define HID_KEY_BRACKET_LEFT 0x2F
+#define HID_KEY_BRACKET_RIGHT 0x30
+#define HID_KEY_BACKSLASH 0x31
+#define HID_KEY_EUROPE_1 0x32
+#define HID_KEY_SEMICOLON 0x33
+#define HID_KEY_APOSTROPHE 0x34
+#define HID_KEY_GRAVE 0x35
+#define HID_KEY_COMMA 0x36
+#define HID_KEY_PERIOD 0x37
+#define HID_KEY_SLASH 0x38
+#define HID_KEY_CAPS_LOCK 0x39
+#define HID_KEY_F1 0x3A
+#define HID_KEY_F2 0x3B
+#define HID_KEY_F3 0x3C
+#define HID_KEY_F4 0x3D
+#define HID_KEY_F5 0x3E
+#define HID_KEY_F6 0x3F
+#define HID_KEY_F7 0x40
+#define HID_KEY_F8 0x41
+#define HID_KEY_F9 0x42
+#define HID_KEY_F10 0x43
+#define HID_KEY_F11 0x44
+#define HID_KEY_F12 0x45
+#define HID_KEY_PRINT_SCREEN 0x46
+#define HID_KEY_SCROLL_LOCK 0x47
+#define HID_KEY_PAUSE 0x48
+#define HID_KEY_INSERT 0x49
+#define HID_KEY_HOME 0x4A
+#define HID_KEY_PAGE_UP 0x4B
+#define HID_KEY_DELETE 0x4C
+#define HID_KEY_END 0x4D
+#define HID_KEY_PAGE_DOWN 0x4E
+#define HID_KEY_ARROW_RIGHT 0x4F
+#define HID_KEY_ARROW_LEFT 0x50
+#define HID_KEY_ARROW_DOWN 0x51
+#define HID_KEY_ARROW_UP 0x52
+#define HID_KEY_NUM_LOCK 0x53
+#define HID_KEY_KEYPAD_DIVIDE 0x54
+#define HID_KEY_KEYPAD_MULTIPLY 0x55
+#define HID_KEY_KEYPAD_SUBTRACT 0x56
+#define HID_KEY_KEYPAD_ADD 0x57
+#define HID_KEY_KEYPAD_ENTER 0x58
+#define HID_KEY_KEYPAD_1 0x59
+#define HID_KEY_KEYPAD_2 0x5A
+#define HID_KEY_KEYPAD_3 0x5B
+#define HID_KEY_KEYPAD_4 0x5C
+#define HID_KEY_KEYPAD_5 0x5D
+#define HID_KEY_KEYPAD_6 0x5E
+#define HID_KEY_KEYPAD_7 0x5F
+#define HID_KEY_KEYPAD_8 0x60
+#define HID_KEY_KEYPAD_9 0x61
+#define HID_KEY_KEYPAD_0 0x62
+#define HID_KEY_KEYPAD_DECIMAL 0x63
+#define HID_KEY_EUROPE_2 0x64
+#define HID_KEY_APPLICATION 0x65
+#define HID_KEY_POWER 0x66
+#define HID_KEY_KEYPAD_EQUAL 0x67
+#define HID_KEY_F13 0x68
+#define HID_KEY_F14 0x69
+#define HID_KEY_F15 0x6A
+#define HID_KEY_CONTROL_LEFT 0xE0
+#define HID_KEY_SHIFT_LEFT 0xE1
+#define HID_KEY_ALT_LEFT 0xE2
+#define HID_KEY_GUI_LEFT 0xE3
+#define HID_KEY_CONTROL_RIGHT 0xE4
+#define HID_KEY_SHIFT_RIGHT 0xE5
+#define HID_KEY_ALT_RIGHT 0xE6
+#define HID_KEY_GUI_RIGHT 0xE7
+
+
+//--------------------------------------------------------------------+
+// REPORT DESCRIPTOR
+//--------------------------------------------------------------------+
+//------------- ITEM & TAG -------------//
+#define HID_REPORT_DATA_0(data)
+#define HID_REPORT_DATA_1(data) , data
+#define HID_REPORT_DATA_2(data) , U16_TO_U8S_LE(data)
+#define HID_REPORT_DATA_3(data) , U32_TO_U8S_LE(data)
+
+#define HID_REPORT_ITEM(data, tag, type, size) \
+ (((tag) << 4) | ((type) << 2) | (size)) HID_REPORT_DATA_##size(data)
+
+#define RI_TYPE_MAIN 0
+#define RI_TYPE_GLOBAL 1
+#define RI_TYPE_LOCAL 2
+
+//------------- MAIN ITEMS 6.2.2.4 -------------//
+#define HID_INPUT(x) HID_REPORT_ITEM(x, 8, RI_TYPE_MAIN, 1)
+#define HID_OUTPUT(x) HID_REPORT_ITEM(x, 9, RI_TYPE_MAIN, 1)
+#define HID_COLLECTION(x) HID_REPORT_ITEM(x, 10, RI_TYPE_MAIN, 1)
+#define HID_FEATURE(x) HID_REPORT_ITEM(x, 11, RI_TYPE_MAIN, 1)
+#define HID_COLLECTION_END HID_REPORT_ITEM(x, 12, RI_TYPE_MAIN, 0)
+
+//------------- INPUT, OUTPUT, FEATURE 6.2.2.5 -------------//
+#define HID_DATA (0<<0)
+#define HID_CONSTANT (1<<0)
+
+#define HID_ARRAY (0<<1)
+#define HID_VARIABLE (1<<1)
+
+#define HID_ABSOLUTE (0<<2)
+#define HID_RELATIVE (1<<2)
+
+#define HID_WRAP_NO (0<<3)
+#define HID_WRAP (1<<3)
+
+#define HID_LINEAR (0<<4)
+#define HID_NONLINEAR (1<<4)
+
+#define HID_PREFERRED_STATE (0<<5)
+#define HID_PREFERRED_NO (1<<5)
+
+#define HID_NO_NULL_POSITION (0<<6)
+#define HID_NULL_STATE (1<<6)
+
+#define HID_NON_VOLATILE (0<<7)
+#define HID_VOLATILE (1<<7)
+
+#define HID_BITFIELD (0<<8)
+#define HID_BUFFERED_BYTES (1<<8)
+
+//------------- COLLECTION ITEM 6.2.2.6 -------------//
+enum {
+ HID_COLLECTION_PHYSICAL = 0,
+ HID_COLLECTION_APPLICATION,
+ HID_COLLECTION_LOGICAL,
+ HID_COLLECTION_REPORT,
+ HID_COLLECTION_NAMED_ARRAY,
+ HID_COLLECTION_USAGE_SWITCH,
+ HID_COLLECTION_USAGE_MODIFIER
+};
+
+//------------- GLOBAL ITEMS 6.2.2.7 -------------//
+#define HID_USAGE_PAGE(x) HID_REPORT_ITEM(x, 0, RI_TYPE_GLOBAL, 1)
+#define HID_USAGE_PAGE_N(x, n) HID_REPORT_ITEM(x, 0, RI_TYPE_GLOBAL, n)
+
+#define HID_LOGICAL_MIN(x) HID_REPORT_ITEM(x, 1, RI_TYPE_GLOBAL, 1)
+#define HID_LOGICAL_MIN_N(x, n) HID_REPORT_ITEM(x, 1, RI_TYPE_GLOBAL, n)
+
+#define HID_LOGICAL_MAX(x) HID_REPORT_ITEM(x, 2, RI_TYPE_GLOBAL, 1)
+#define HID_LOGICAL_MAX_N(x, n) HID_REPORT_ITEM(x, 2, RI_TYPE_GLOBAL, n)
+
+#define HID_PHYSICAL_MIN(x) HID_REPORT_ITEM(x, 3, RI_TYPE_GLOBAL, 1)
+#define HID_PHYSICAL_MIN_N(x, n) HID_REPORT_ITEM(x, 3, RI_TYPE_GLOBAL, n)
+
+#define HID_PHYSICAL_MAX(x) HID_REPORT_ITEM(x, 4, RI_TYPE_GLOBAL, 1)
+#define HID_PHYSICAL_MAX_N(x, n) HID_REPORT_ITEM(x, 4, RI_TYPE_GLOBAL, n)
+
+#define HID_UNIT_EXPONENT(x) HID_REPORT_ITEM(x, 5, RI_TYPE_GLOBAL, 1)
+#define HID_UNIT_EXPONENT_N(x, n) HID_REPORT_ITEM(x, 5, RI_TYPE_GLOBAL, n)
+
+#define HID_UNIT(x) HID_REPORT_ITEM(x, 6, RI_TYPE_GLOBAL, 1)
+#define HID_UNIT_N(x, n) HID_REPORT_ITEM(x, 6, RI_TYPE_GLOBAL, n)
+
+#define HID_REPORT_SIZE(x) HID_REPORT_ITEM(x, 7, RI_TYPE_GLOBAL, 1)
+#define HID_REPORT_SIZE_N(x, n) HID_REPORT_ITEM(x, 7, RI_TYPE_GLOBAL, n)
+
+#define HID_REPORT_ID(x) HID_REPORT_ITEM(x, 8, RI_TYPE_GLOBAL, 1)
+#define HID_REPORT_ID_N(x) HID_REPORT_ITEM(x, 8, RI_TYPE_GLOBAL, n)
+
+#define HID_REPORT_COUNT(x) HID_REPORT_ITEM(x, 9, RI_TYPE_GLOBAL, 1)
+#define HID_REPORT_COUNT_N(x, n) HID_REPORT_ITEM(x, 9, RI_TYPE_GLOBAL, n)
+
+#define HID_PUSH HID_REPORT_ITEM(x, 10, RI_TYPE_GLOBAL, 0)
+#define HID_POP HID_REPORT_ITEM(x, 11, RI_TYPE_GLOBAL, 0)
+
+//------------- LOCAL ITEMS 6.2.2.8 -------------//
+#define HID_USAGE(x) HID_REPORT_ITEM(x, 0, RI_TYPE_LOCAL, 1)
+#define HID_USAGE_N(x, n) HID_REPORT_ITEM(x, 0, RI_TYPE_LOCAL, n)
+
+#define HID_USAGE_MIN(x) HID_REPORT_ITEM(x, 1, RI_TYPE_LOCAL, 1)
+#define HID_USAGE_MIN_N(x, n) HID_REPORT_ITEM(x, 1, RI_TYPE_LOCAL, n)
+
+#define HID_USAGE_MAX(x) HID_REPORT_ITEM(x, 2, RI_TYPE_LOCAL, 1)
+#define HID_USAGE_MAX_N(x, n) HID_REPORT_ITEM(x, 2, RI_TYPE_LOCAL, n)
+
+//--------------------------------------------------------------------+
+// Usage Table
+//--------------------------------------------------------------------+
+
+/// HID Usage Table - Table 1: Usage Page Summary
+enum {
+ HID_USAGE_PAGE_DESKTOP = 0x01,
+ HID_USAGE_PAGE_SIMULATE = 0x02,
+ HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03,
+ HID_USAGE_PAGE_SPORT = 0x04,
+ HID_USAGE_PAGE_GAME = 0x05,
+ HID_USAGE_PAGE_GENERIC_DEVICE = 0x06,
+ HID_USAGE_PAGE_KEYBOARD = 0x07,
+ HID_USAGE_PAGE_LED = 0x08,
+ HID_USAGE_PAGE_BUTTON = 0x09,
+ HID_USAGE_PAGE_ORDINAL = 0x0a,
+ HID_USAGE_PAGE_TELEPHONY = 0x0b,
+ HID_USAGE_PAGE_CONSUMER = 0x0c,
+ HID_USAGE_PAGE_DIGITIZER = 0x0d,
+ HID_USAGE_PAGE_PID = 0x0f,
+ HID_USAGE_PAGE_UNICODE = 0x10,
+ HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14,
+ HID_USAGE_PAGE_MEDICAL = 0x40,
+ HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83
+ HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87
+ HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c,
+ HID_USAGE_PAGE_SCALE = 0x8d,
+ HID_USAGE_PAGE_MSR = 0x8e,
+ HID_USAGE_PAGE_CAMERA = 0x90,
+ HID_USAGE_PAGE_ARCADE = 0x91,
+ HID_USAGE_PAGE_VENDOR = 0xFFFF // 0xFF00 - 0xFFFF
+};
+
+/// HID Usage Table - Table 6: Generic Desktop Page
+enum {
+ HID_USAGE_DESKTOP_POINTER = 0x01,
+ HID_USAGE_DESKTOP_MOUSE = 0x02,
+ HID_USAGE_DESKTOP_JOYSTICK = 0x04,
+ HID_USAGE_DESKTOP_GAMEPAD = 0x05,
+ HID_USAGE_DESKTOP_KEYBOARD = 0x06,
+ HID_USAGE_DESKTOP_KEYPAD = 0x07,
+ HID_USAGE_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08,
+ HID_USAGE_DESKTOP_TABLET_PC_SYSTEM = 0x09,
+ HID_USAGE_DESKTOP_X = 0x30,
+ HID_USAGE_DESKTOP_Y = 0x31,
+ HID_USAGE_DESKTOP_Z = 0x32,
+ HID_USAGE_DESKTOP_RX = 0x33,
+ HID_USAGE_DESKTOP_RY = 0x34,
+ HID_USAGE_DESKTOP_RZ = 0x35,
+ HID_USAGE_DESKTOP_SLIDER = 0x36,
+ HID_USAGE_DESKTOP_DIAL = 0x37,
+ HID_USAGE_DESKTOP_WHEEL = 0x38,
+ HID_USAGE_DESKTOP_HAT_SWITCH = 0x39,
+ HID_USAGE_DESKTOP_COUNTED_BUFFER = 0x3a,
+ HID_USAGE_DESKTOP_BYTE_COUNT = 0x3b,
+ HID_USAGE_DESKTOP_MOTION_WAKEUP = 0x3c,
+ HID_USAGE_DESKTOP_START = 0x3d,
+ HID_USAGE_DESKTOP_SELECT = 0x3e,
+ HID_USAGE_DESKTOP_VX = 0x40,
+ HID_USAGE_DESKTOP_VY = 0x41,
+ HID_USAGE_DESKTOP_VZ = 0x42,
+ HID_USAGE_DESKTOP_VBRX = 0x43,
+ HID_USAGE_DESKTOP_VBRY = 0x44,
+ HID_USAGE_DESKTOP_VBRZ = 0x45,
+ HID_USAGE_DESKTOP_VNO = 0x46,
+ HID_USAGE_DESKTOP_FEATURE_NOTIFICATION = 0x47,
+ HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER = 0x48,
+ HID_USAGE_DESKTOP_SYSTEM_CONTROL = 0x80,
+ HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN = 0x81,
+ HID_USAGE_DESKTOP_SYSTEM_SLEEP = 0x82,
+ HID_USAGE_DESKTOP_SYSTEM_WAKE_UP = 0x83,
+ HID_USAGE_DESKTOP_SYSTEM_CONTEXT_MENU = 0x84,
+ HID_USAGE_DESKTOP_SYSTEM_MAIN_MENU = 0x85,
+ HID_USAGE_DESKTOP_SYSTEM_APP_MENU = 0x86,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_HELP = 0x87,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_EXIT = 0x88,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_SELECT = 0x89,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_RIGHT = 0x8A,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_LEFT = 0x8B,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_UP = 0x8C,
+ HID_USAGE_DESKTOP_SYSTEM_MENU_DOWN = 0x8D,
+ HID_USAGE_DESKTOP_SYSTEM_COLD_RESTART = 0x8E,
+ HID_USAGE_DESKTOP_SYSTEM_WARM_RESTART = 0x8F,
+ HID_USAGE_DESKTOP_DPAD_UP = 0x90,
+ HID_USAGE_DESKTOP_DPAD_DOWN = 0x91,
+ HID_USAGE_DESKTOP_DPAD_RIGHT = 0x92,
+ HID_USAGE_DESKTOP_DPAD_LEFT = 0x93,
+ HID_USAGE_DESKTOP_SYSTEM_DOCK = 0xA0,
+ HID_USAGE_DESKTOP_SYSTEM_UNDOCK = 0xA1,
+ HID_USAGE_DESKTOP_SYSTEM_SETUP = 0xA2,
+ HID_USAGE_DESKTOP_SYSTEM_BREAK = 0xA3,
+ HID_USAGE_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4,
+ HID_USAGE_DESKTOP_APPLICATION_BREAK = 0xA5,
+ HID_USAGE_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6,
+ HID_USAGE_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7,
+ HID_USAGE_DESKTOP_SYSTEM_HIBERNATE = 0xA8,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6,
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7
+};
+
+
+/// HID Usage Table: Consumer Page (0x0C)
+/// Only contains controls that supported by Windows (whole list is too long)
+enum
+{
+ // Generic Control
+ HID_USAGE_CONSUMER_CONTROL = 0x0001,
+
+ // Power Control
+ HID_USAGE_CONSUMER_POWER = 0x0030,
+ HID_USAGE_CONSUMER_RESET = 0x0031,
+ HID_USAGE_CONSUMER_SLEEP = 0x0032,
+
+ // Screen Brightness
+ HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F,
+ HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070,
+
+ // These HID usages operate only on mobile systems (battery powered) and
+ // require Windows 8 (build 8302 or greater).
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C,
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6,
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_LED = 0x00C7,
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8,
+
+ // Media Control
+ HID_USAGE_CONSUMER_PLAY_PAUSE = 0x00CD,
+ HID_USAGE_CONSUMER_SCAN_NEXT = 0x00B5,
+ HID_USAGE_CONSUMER_SCAN_PREVIOUS = 0x00B6,
+ HID_USAGE_CONSUMER_STOP = 0x00B7,
+ HID_USAGE_CONSUMER_VOLUME = 0x00E0,
+ HID_USAGE_CONSUMER_MUTE = 0x00E2,
+ HID_USAGE_CONSUMER_BASS = 0x00E3,
+ HID_USAGE_CONSUMER_TREBLE = 0x00E4,
+ HID_USAGE_CONSUMER_BASS_BOOST = 0x00E5,
+ HID_USAGE_CONSUMER_VOLUME_INCREMENT = 0x00E9,
+ HID_USAGE_CONSUMER_VOLUME_DECREMENT = 0x00EA,
+ HID_USAGE_CONSUMER_BASS_INCREMENT = 0x0152,
+ HID_USAGE_CONSUMER_BASS_DECREMENT = 0x0153,
+ HID_USAGE_CONSUMER_TREBLE_INCREMENT = 0x0154,
+ HID_USAGE_CONSUMER_TREBLE_DECREMENT = 0x0155,
+
+ // Application Launcher
+ HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183,
+ HID_USAGE_CONSUMER_AL_EMAIL_READER = 0x018A,
+ HID_USAGE_CONSUMER_AL_CALCULATOR = 0x0192,
+ HID_USAGE_CONSUMER_AL_LOCAL_BROWSER = 0x0194,
+
+ // Browser/Explorer Specific
+ HID_USAGE_CONSUMER_AC_SEARCH = 0x0221,
+ HID_USAGE_CONSUMER_AC_HOME = 0x0223,
+ HID_USAGE_CONSUMER_AC_BACK = 0x0224,
+ HID_USAGE_CONSUMER_AC_FORWARD = 0x0225,
+ HID_USAGE_CONSUMER_AC_STOP = 0x0226,
+ HID_USAGE_CONSUMER_AC_REFRESH = 0x0227,
+ HID_USAGE_CONSUMER_AC_BOOKMARKS = 0x022A,
+
+ // Mouse Horizontal scroll
+ HID_USAGE_CONSUMER_AC_PAN = 0x0238,
+};
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_HID_H__ */
+
+/// @}
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid_device.c b/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid_device.c new file mode 100755 index 0000000..d8696f1 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid_device.c @@ -0,0 +1,648 @@ +/**************************************************************************/
+/*!
+ @file hid_device.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_HID)
+
+#define _TINY_USB_SOURCE_FILE_
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "common/tusb_common.h"
+#include "hid_device.h"
+#include "device/usbd_pvt.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+// Max report len is keyboard's one with 8 byte + 1 byte report id
+#define REPORT_BUFSIZE 12
+
+
+#define ITF_IDX_BOOT_KBD 0
+#define ITF_IDX_BOOT_MSE ( ITF_IDX_BOOT_KBD + (CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT) )
+#define ITF_IDX_GENERIC ( ITF_IDX_BOOT_MSE + (CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT) )
+#define ITF_COUNT ( ITF_IDX_GENERIC + 1 )
+
+typedef struct
+{
+ uint8_t itf_num;
+ uint8_t ep_in;
+
+ uint8_t idle_rate; // in unit of 4 ms TODO removed
+ bool boot_protocol;
+
+ uint16_t desc_len;
+ uint8_t const * desc_report;
+
+ CFG_TUSB_MEM_ALIGN uint8_t report_buf[REPORT_BUFSIZE];
+
+ // callbacks
+ uint16_t (*get_report_cb) (uint8_t report_id, hid_report_type_t type, uint8_t* buffer, uint16_t reqlen);
+ void (*set_report_cb) (uint8_t report_id, hid_report_type_t type, uint8_t const* buffer, uint16_t bufsize);
+
+}hidd_interface_t;
+
+typedef struct
+{
+ uint8_t usage; // HID_USAGE_*
+ uint8_t idle_rate; // in unit of 4 ms
+
+ uint8_t report_id;
+ uint8_t report_len;
+
+ hidd_interface_t* itf;
+} hidd_report_t ;
+
+CFG_TUSB_ATTR_USBRAM static hidd_interface_t _hidd_itf[ITF_COUNT];
+
+
+#if CFG_TUD_HID_KEYBOARD
+static hidd_report_t _kbd_rpt;
+#endif
+
+#if CFG_TUD_HID_MOUSE
+static hidd_report_t _mse_rpt;
+#endif
+
+/*------------- Helpers -------------*/
+
+static inline hidd_interface_t* get_interface_by_itfnum(uint8_t itf_num)
+{
+ for (uint8_t i=0; i < ITF_COUNT; i++ )
+ {
+ if ( itf_num == _hidd_itf[i].itf_num ) return &_hidd_itf[i];
+ }
+
+ return NULL;
+}
+
+
+//--------------------------------------------------------------------+
+// HID GENERIC API
+//--------------------------------------------------------------------+
+bool tud_hid_generic_ready(void)
+{
+ return (_hidd_itf[ITF_IDX_GENERIC].ep_in != 0) && !dcd_edpt_busy(TUD_OPT_RHPORT, _hidd_itf[ITF_IDX_GENERIC].ep_in);
+}
+
+bool tud_hid_generic_report(uint8_t report_id, void const* report, uint8_t len)
+{
+ TU_VERIFY( tud_hid_generic_ready() && (len < REPORT_BUFSIZE) );
+
+ hidd_interface_t * p_hid = &_hidd_itf[ITF_IDX_GENERIC];
+
+ // If report id = 0, skip ID field
+ if (report_id)
+ {
+ p_hid->report_buf[0] = report_id;
+ memcpy(p_hid->report_buf+1, report, len);
+ }else
+ {
+ memcpy(p_hid->report_buf, report, len);
+ }
+
+ // TODO idle rate
+ return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, len + ( report_id ? 1 : 0) );
+}
+
+//--------------------------------------------------------------------+
+// KEYBOARD APPLICATION API
+//--------------------------------------------------------------------+
+#if CFG_TUD_HID_KEYBOARD
+bool tud_hid_keyboard_ready(void)
+{
+ return (_kbd_rpt.itf != NULL) && !dcd_edpt_busy(TUD_OPT_RHPORT, _kbd_rpt.itf->ep_in);
+}
+
+bool tud_hid_keyboard_is_boot_protocol(void)
+{
+ return (_kbd_rpt.itf != NULL) && _kbd_rpt.itf->boot_protocol;
+}
+
+static bool hidd_kbd_report(hid_keyboard_report_t const *p_report)
+{
+ TU_VERIFY( tud_hid_keyboard_ready() );
+
+ hidd_interface_t * p_hid = _kbd_rpt.itf;
+
+ // Idle Rate = 0 : only send report if there is changes, i.e skip duplication
+ // Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
+ // If idle time is less than interrupt polling then use the polling.
+ static tu_timeout_t idle_tm = { 0, 0 };
+
+ if ( (_kbd_rpt.idle_rate == 0) || !tu_timeout_expired(&idle_tm) )
+ {
+ if ( 0 == memcmp(p_hid->report_buf, p_report, sizeof(hid_keyboard_report_t)) ) return true;
+ }
+
+ tu_timeout_set(&idle_tm, _kbd_rpt.idle_rate * 4);
+
+ memcpy(p_hid->report_buf, p_report, sizeof(hid_keyboard_report_t));
+ return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, sizeof(hid_keyboard_report_t));
+}
+
+bool tud_hid_keyboard_keycode(uint8_t modifier, uint8_t keycode[6])
+{
+ hid_keyboard_report_t report = { .modifier = modifier };
+
+ if ( keycode )
+ {
+ memcpy(report.keycode, keycode, 6);
+ }else
+ {
+ tu_memclr(report.keycode, 6);
+ }
+
+ return hidd_kbd_report(&report);
+}
+
+#if CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+
+bool tud_hid_keyboard_key_press(char ch)
+{
+ uint8_t keycode[6] = { 0 };
+ uint8_t modifier = 0;
+
+ if ( HID_ASCII_TO_KEYCODE[(uint8_t)ch].shift ) modifier = KEYBOARD_MODIFIER_LEFTSHIFT;
+ keycode[0] = HID_ASCII_TO_KEYCODE[(uint8_t)ch].keycode;
+
+ return tud_hid_keyboard_keycode(modifier, keycode);
+}
+
+bool tud_hid_keyboard_key_sequence(const char* str, uint32_t interval_ms)
+{
+ // Send each key in string
+ char ch;
+ while( (ch = *str++) != 0 )
+ {
+ char lookahead = *str;
+
+ tud_hid_keyboard_key_press(ch);
+
+ // Blocking delay
+ tu_timeout_wait(interval_ms);
+
+ /* Only need to empty report if the next character is NULL or the same with
+ * the current one, else no need to send */
+ if ( lookahead == ch || lookahead == 0 )
+ {
+ tud_hid_keyboard_key_release();
+ tu_timeout_wait(interval_ms);
+ }
+ }
+
+ return true;
+}
+
+#endif // CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+
+#endif // CFG_TUD_HID_KEYBOARD
+
+//--------------------------------------------------------------------+
+// MOUSE APPLICATION API
+//--------------------------------------------------------------------+
+#if CFG_TUD_HID_MOUSE
+
+bool tud_hid_mouse_ready(void)
+{
+ return (_mse_rpt.itf != NULL) && !dcd_edpt_busy(TUD_OPT_RHPORT, _mse_rpt.itf->ep_in);
+}
+
+bool tud_hid_mouse_is_boot_protocol(void)
+{
+ return (_mse_rpt.itf != NULL) && _mse_rpt.itf->boot_protocol;
+}
+
+static bool hidd_mouse_report(hid_mouse_report_t const *p_report)
+{
+ TU_VERIFY( tud_hid_mouse_ready() );
+
+ hidd_interface_t * p_hid = _mse_rpt.itf;
+ memcpy(p_hid->report_buf, p_report, sizeof(hid_mouse_report_t));
+
+ return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, sizeof(hid_mouse_report_t));
+}
+
+bool tud_hid_mouse_data(uint8_t buttons, int8_t x, int8_t y, int8_t scroll, int8_t pan)
+{
+ hid_mouse_report_t report =
+ {
+ .buttons = buttons,
+ .x = x,
+ .y = y,
+ .wheel = scroll,
+// .pan = pan
+ };
+
+ return hidd_mouse_report( &report );
+}
+
+bool tud_hid_mouse_move(int8_t x, int8_t y)
+{
+ TU_VERIFY( tud_hid_mouse_ready() );
+
+ hidd_interface_t * p_hid = _mse_rpt.itf;
+ uint8_t prev_buttons = p_hid->report_buf[0];
+
+ return tud_hid_mouse_data(prev_buttons, x, y, 0, 0);
+}
+
+bool tud_hid_mouse_scroll(int8_t vertical, int8_t horizontal)
+{
+ TU_VERIFY( tud_hid_mouse_ready() );
+
+ hidd_interface_t * p_hid = _mse_rpt.itf;
+ uint8_t prev_buttons = p_hid->report_buf[0];
+
+ return tud_hid_mouse_data(prev_buttons, 0, 0, vertical, horizontal);
+}
+
+#endif // CFG_TUD_HID_MOUSE
+
+//--------------------------------------------------------------------+
+// USBD-CLASS API
+//--------------------------------------------------------------------+
+void hidd_init(void)
+{
+ hidd_reset(TUD_OPT_RHPORT);
+}
+
+void hidd_reset(uint8_t rhport)
+{
+ tu_memclr(_hidd_itf, sizeof(_hidd_itf));
+
+ #if CFG_TUD_HID_KEYBOARD
+ tu_varclr(&_kbd_rpt);
+ #endif
+
+ #if CFG_TUD_HID_MOUSE
+ tu_varclr(&_mse_rpt);
+ #endif
+}
+
+tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len)
+{
+ uint8_t const *p_desc = (uint8_t const *) desc_itf;
+
+ // TODO not support HID OUT Endpoint
+ TU_ASSERT(desc_itf->bNumEndpoints == 1, ERR_TUD_INVALID_DESCRIPTOR);
+
+ //------------- HID descriptor -------------//
+ p_desc += p_desc[DESC_OFFSET_LEN];
+ tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
+ TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType, ERR_TUD_INVALID_DESCRIPTOR);
+
+ //------------- Endpoint Descriptor -------------//
+ p_desc += p_desc[DESC_OFFSET_LEN];
+ tusb_desc_endpoint_t const *desc_edpt = (tusb_desc_endpoint_t const *) p_desc;
+ TU_ASSERT(TUSB_DESC_ENDPOINT == desc_edpt->bDescriptorType, ERR_TUD_INVALID_DESCRIPTOR);
+
+ hidd_interface_t * p_hid = NULL;
+
+ /*------------- Boot protocol only keyboard & mouse -------------*/
+ if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT)
+ {
+ TU_ASSERT(desc_itf->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD || desc_itf->bInterfaceProtocol == HID_PROTOCOL_MOUSE, ERR_TUD_INVALID_DESCRIPTOR);
+
+ #if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+ if (desc_itf->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD)
+ {
+ p_hid = &_hidd_itf[ITF_IDX_BOOT_KBD];
+ p_hid->desc_report = usbd_desc_set->hid_report.boot_keyboard;
+ p_hid->get_report_cb = tud_hid_keyboard_get_report_cb;
+ p_hid->set_report_cb = tud_hid_keyboard_set_report_cb;
+
+ hidd_report_t* report = &_kbd_rpt;
+ report->usage = HID_USAGE_DESKTOP_KEYBOARD;
+ report->report_id = 0;
+ report->report_len = 8;
+ report->itf = p_hid;
+ }
+ #endif
+
+ #if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+ if (desc_itf->bInterfaceProtocol == HID_PROTOCOL_MOUSE)
+ {
+ p_hid = &_hidd_itf[ITF_IDX_BOOT_MSE];
+ p_hid->desc_report = usbd_desc_set->hid_report.boot_mouse;
+ p_hid->get_report_cb = tud_hid_mouse_get_report_cb;
+ p_hid->set_report_cb = tud_hid_mouse_set_report_cb;
+
+ hidd_report_t* report = &_mse_rpt;
+ report->usage = HID_USAGE_DESKTOP_MOUSE;
+ report->report_id = 0;
+ report->report_len = 4;
+ report->itf = p_hid;
+ }
+ #endif
+
+ TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR);
+ p_hid->boot_protocol = true; // default mode is BOOT
+ }
+ /*------------- Generic (multiple report) -------------*/
+ else
+ {
+ // TODO parse report ID for keyboard, mouse
+ p_hid = &_hidd_itf[ITF_IDX_GENERIC];
+
+ p_hid->desc_report = usbd_desc_set->hid_report.generic;
+ p_hid->get_report_cb = tud_hid_generic_get_report_cb;
+ p_hid->set_report_cb = tud_hid_generic_set_report_cb;
+
+ TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR);
+ }
+
+ TU_VERIFY(p_hid->desc_report, ERR_TUD_INVALID_DESCRIPTOR);
+ TU_ASSERT( dcd_edpt_open(rhport, desc_edpt), ERR_TUD_EDPT_OPEN_FAILED );
+
+ p_hid->itf_num = desc_itf->bInterfaceNumber;
+ p_hid->ep_in = desc_edpt->bEndpointAddress;
+ p_hid->desc_len = desc_hid->wReportLength;
+
+ *p_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
+
+ return TUSB_ERROR_NONE;
+}
+
+tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request)
+{
+ hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex );
+ TU_ASSERT(p_hid, TUSB_ERROR_FAILED);
+
+ OSAL_SUBTASK_BEGIN
+
+ //------------- STD Request -------------//
+ if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD)
+ {
+ uint8_t const desc_type = tu_u16_high(p_request->wValue);
+ uint8_t const desc_index = tu_u16_low (p_request->wValue);
+ (void) desc_index;
+
+ if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT)
+ {
+ // use device control buffer
+ STASK_ASSERT ( p_hid->desc_len <= CFG_TUD_CTRL_BUFSIZE );
+ memcpy(_usbd_ctrl_buf, p_hid->desc_report, p_hid->desc_len);
+
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, p_hid->desc_len);
+ }else
+ {
+ dcd_control_stall(rhport);
+ }
+ }
+ //------------- Class Specific Request -------------//
+ else if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS)
+ {
+ if( HID_REQ_CONTROL_GET_REPORT == p_request->bRequest )
+ {
+ // wValue = Report Type | Report ID
+ uint8_t const report_type = tu_u16_high(p_request->wValue);
+ uint8_t const report_id = tu_u16_low(p_request->wValue);
+
+ uint16_t xferlen;
+ if ( p_hid->get_report_cb )
+ {
+ xferlen = p_hid->get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->report_buf, p_request->wLength);
+ }else
+ {
+ // For boot Interface only: re-use report_buf -> report has no change
+ xferlen = p_request->wLength;
+ }
+
+ STASK_ASSERT( xferlen > 0 );
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, p_hid->report_buf, xferlen);
+ }
+ else if ( HID_REQ_CONTROL_SET_REPORT == p_request->bRequest )
+ {
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, p_request->wLength);
+
+ // wValue = Report Type | Report ID
+ uint8_t const report_type = tu_u16_high(p_request->wValue);
+ uint8_t const report_id = tu_u16_low(p_request->wValue);
+
+ if ( p_hid->set_report_cb )
+ {
+ p_hid->set_report_cb(report_id, (hid_report_type_t) report_type, _usbd_ctrl_buf, p_request->wLength);
+ }
+ }
+ else if (HID_REQ_CONTROL_SET_IDLE == p_request->bRequest)
+ {
+ // TODO idle rate of report
+ p_hid->idle_rate = tu_u16_high(p_request->wValue);
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ }
+ else if (HID_REQ_CONTROL_GET_IDLE == p_request->bRequest)
+ {
+ // TODO idle rate of report
+ _usbd_ctrl_buf[0] = p_hid->idle_rate;
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, 1);
+ }
+ else if (HID_REQ_CONTROL_GET_PROTOCOL == p_request->bRequest )
+ {
+ _usbd_ctrl_buf[0] = 1-p_hid->boot_protocol; // 0 is Boot, 1 is Report protocol
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, 1);
+ }
+ else if (HID_REQ_CONTROL_SET_PROTOCOL == p_request->bRequest )
+ {
+ p_hid->boot_protocol = 1 - p_request->wValue; // 0 is Boot, 1 is Report protocol
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ }else
+ {
+ dcd_control_stall(rhport);
+ }
+ }else
+ {
+ dcd_control_stall(rhport);
+ }
+
+ OSAL_SUBTASK_END
+}
+
+tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes)
+{
+ // nothing to do
+ return TUSB_ERROR_NONE;
+}
+
+
+/*------------------------------------------------------------------*/
+/* Ascii to Keycode
+ *------------------------------------------------------------------*/
+#if CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+
+const hid_ascii_to_keycode_entry_t HID_ASCII_TO_KEYCODE[128] =
+{
+ {0, 0 }, // 0x00 Null
+ {0, 0 }, // 0x01
+ {0, 0 }, // 0x02
+ {0, 0 }, // 0x03
+ {0, 0 }, // 0x04
+ {0, 0 }, // 0x05
+ {0, 0 }, // 0x06
+ {0, 0 }, // 0x07
+ {0, HID_KEY_BACKSPACE }, // 0x08 Backspace
+ {0, HID_KEY_TAB }, // 0x09 Horizontal Tab
+ {0, HID_KEY_RETURN }, // 0x0A Line Feed
+ {0, 0 }, // 0x0B
+ {0, 0 }, // 0x0C
+ {0, HID_KEY_RETURN }, // 0x0D Carriage return
+ {0, 0 }, // 0x0E
+ {0, 0 }, // 0x0F
+ {0, 0 }, // 0x10
+ {0, 0 }, // 0x11
+ {0, 0 }, // 0x12
+ {0, 0 }, // 0x13
+ {0, 0 }, // 0x14
+ {0, 0 }, // 0x15
+ {0, 0 }, // 0x16
+ {0, 0 }, // 0x17
+ {0, 0 }, // 0x18
+ {0, 0 }, // 0x19
+ {0, 0 }, // 0x1A
+ {0, HID_KEY_ESCAPE }, // 0x1B Escape
+ {0, 0 }, // 0x1C
+ {0, 0 }, // 0x1D
+ {0, 0 }, // 0x1E
+ {0, 0 }, // 0x1F
+
+ {0, HID_KEY_SPACE }, // 0x20
+ {1, HID_KEY_1 }, // 0x21 !
+ {1, HID_KEY_APOSTROPHE }, // 0x22 "
+ {1, HID_KEY_3 }, // 0x23 #
+ {1, HID_KEY_4 }, // 0x24 $
+ {1, HID_KEY_5 }, // 0x25 %
+ {1, HID_KEY_7 }, // 0x26 &
+ {0, HID_KEY_APOSTROPHE }, // 0x27 '
+ {1, HID_KEY_9 }, // 0x28 (
+ {1, HID_KEY_0 }, // 0x29 )
+ {1, HID_KEY_8 }, // 0x2A *
+ {1, HID_KEY_EQUAL }, // 0x2B +
+ {0, HID_KEY_COMMA }, // 0x2C ,
+ {0, HID_KEY_MINUS }, // 0x2D -
+ {0, HID_KEY_PERIOD }, // 0x2E .
+ {0, HID_KEY_SLASH }, // 0x2F /
+ {0, HID_KEY_0 }, // 0x30 0
+ {0, HID_KEY_1 }, // 0x31 1
+ {0, HID_KEY_2 }, // 0x32 2
+ {0, HID_KEY_3 }, // 0x33 3
+ {0, HID_KEY_4 }, // 0x34 4
+ {0, HID_KEY_5 }, // 0x35 5
+ {0, HID_KEY_6 }, // 0x36 6
+ {0, HID_KEY_7 }, // 0x37 7
+ {0, HID_KEY_8 }, // 0x38 8
+ {0, HID_KEY_9 }, // 0x39 9
+ {1, HID_KEY_SEMICOLON }, // 0x3A :
+ {0, HID_KEY_SEMICOLON }, // 0x3B ;
+ {1, HID_KEY_COMMA }, // 0x3C <
+ {0, HID_KEY_EQUAL }, // 0x3D =
+ {1, HID_KEY_PERIOD }, // 0x3E >
+ {1, HID_KEY_SLASH }, // 0x3F ?
+
+ {1, HID_KEY_2 }, // 0x40 @
+ {1, HID_KEY_A }, // 0x41 A
+ {1, HID_KEY_B }, // 0x42 B
+ {1, HID_KEY_C }, // 0x43 C
+ {1, HID_KEY_D }, // 0x44 D
+ {1, HID_KEY_E }, // 0x45 E
+ {1, HID_KEY_F }, // 0x46 F
+ {1, HID_KEY_G }, // 0x47 G
+ {1, HID_KEY_H }, // 0x48 H
+ {1, HID_KEY_I }, // 0x49 I
+ {1, HID_KEY_J }, // 0x4A J
+ {1, HID_KEY_K }, // 0x4B K
+ {1, HID_KEY_L }, // 0x4C L
+ {1, HID_KEY_M }, // 0x4D M
+ {1, HID_KEY_N }, // 0x4E N
+ {1, HID_KEY_O }, // 0x4F O
+ {1, HID_KEY_P }, // 0x50 P
+ {1, HID_KEY_Q }, // 0x51 Q
+ {1, HID_KEY_R }, // 0x52 R
+ {1, HID_KEY_S }, // 0x53 S
+ {1, HID_KEY_T }, // 0x55 T
+ {1, HID_KEY_U }, // 0x55 U
+ {1, HID_KEY_V }, // 0x56 V
+ {1, HID_KEY_W }, // 0x57 W
+ {1, HID_KEY_X }, // 0x58 X
+ {1, HID_KEY_Y }, // 0x59 Y
+ {1, HID_KEY_Z }, // 0x5A Z
+ {0, HID_KEY_BRACKET_LEFT }, // 0x5B [
+ {0, HID_KEY_BACKSLASH }, // 0x5C '\'
+ {0, HID_KEY_BRACKET_RIGHT }, // 0x5D ]
+ {1, HID_KEY_6 }, // 0x5E ^
+ {1, HID_KEY_MINUS }, // 0x5F _
+
+ {0, HID_KEY_GRAVE }, // 0x60 `
+ {0, HID_KEY_A }, // 0x61 a
+ {0, HID_KEY_B }, // 0x62 b
+ {0, HID_KEY_C }, // 0x63 c
+ {0, HID_KEY_D }, // 0x66 d
+ {0, HID_KEY_E }, // 0x65 e
+ {0, HID_KEY_F }, // 0x66 f
+ {0, HID_KEY_G }, // 0x67 g
+ {0, HID_KEY_H }, // 0x68 h
+ {0, HID_KEY_I }, // 0x69 i
+ {0, HID_KEY_J }, // 0x6A j
+ {0, HID_KEY_K }, // 0x6B k
+ {0, HID_KEY_L }, // 0x6C l
+ {0, HID_KEY_M }, // 0x6D m
+ {0, HID_KEY_N }, // 0x6E n
+ {0, HID_KEY_O }, // 0x6F o
+ {0, HID_KEY_P }, // 0x70 p
+ {0, HID_KEY_Q }, // 0x71 q
+ {0, HID_KEY_R }, // 0x72 r
+ {0, HID_KEY_S }, // 0x73 s
+ {0, HID_KEY_T }, // 0x75 t
+ {0, HID_KEY_U }, // 0x75 u
+ {0, HID_KEY_V }, // 0x76 v
+ {0, HID_KEY_W }, // 0x77 w
+ {0, HID_KEY_X }, // 0x78 x
+ {0, HID_KEY_Y }, // 0x79 y
+ {0, HID_KEY_Z }, // 0x7A z
+ {1, HID_KEY_BRACKET_LEFT }, // 0x7B {
+ {1, HID_KEY_BACKSLASH }, // 0x7C |
+ {1, HID_KEY_BRACKET_RIGHT }, // 0x7D }
+ {1, HID_KEY_GRAVE }, // 0x7E ~
+ {0, HID_KEY_DELETE } // 0x7F Delete
+};
+
+#endif
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid_device.h b/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid_device.h new file mode 100755 index 0000000..d5b9f38 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/hid/hid_device.h @@ -0,0 +1,393 @@ +/**************************************************************************/
+/*!
+ @file hid_device.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_HID_DEVICE_H_
+#define _TUSB_HID_DEVICE_H_
+
+#include "common/tusb_common.h"
+#include "device/usbd.h"
+#include "hid.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Class Driver Default Configure & Validation
+//--------------------------------------------------------------------+
+#ifndef CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+#define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 0
+#endif
+
+#if !CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+#error CFG_TUD_HID_KEYBOARD must be enabled
+#endif
+
+#if !CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+#error CFG_TUD_HID_MOUSE must be enabled
+#endif
+
+
+//--------------------------------------------------------------------+
+// HID GENERIC API
+//--------------------------------------------------------------------+
+bool tud_hid_generic_ready(void);
+bool tud_hid_generic_report(uint8_t report_id, void const* report, uint8_t len);
+
+/*------------- Callbacks (Weak is optional) -------------*/
+uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
+void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
+
+//--------------------------------------------------------------------+
+// KEYBOARD API
+//--------------------------------------------------------------------+
+#if CFG_TUD_HID_KEYBOARD
+/** \addtogroup ClassDriver_HID_Keyboard Keyboard
+ * @{ */
+/** \defgroup Keyboard_Device Device
+ * @{ */
+
+/** Check if the interface is ready to use
+ * \returns true if ready, otherwise interface may not be mounted or still busy transferring data
+ * \note Application must not perform any action if the interface is not ready
+ */
+bool tud_hid_keyboard_ready(void);
+bool tud_hid_keyboard_is_boot_protocol(void);
+
+bool tud_hid_keyboard_keycode(uint8_t modifier, uint8_t keycode[6]);
+
+static inline bool tud_hid_keyboard_key_release(void) { return tud_hid_keyboard_keycode(0, NULL); }
+
+#if CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+bool tud_hid_keyboard_key_press(char ch);
+bool tud_hid_keyboard_key_sequence(const char* str, uint32_t interval_ms);
+
+typedef struct{
+ uint8_t shift;
+ uint8_t keycode;
+}hid_ascii_to_keycode_entry_t;
+extern const hid_ascii_to_keycode_entry_t HID_ASCII_TO_KEYCODE[128];
+#endif
+
+#endif
+
+/*------------- Callbacks (Weak is optional) -------------*/
+
+/** Callback invoked when USB host request \ref HID_REQ_CONTROL_GET_REPORT.
+ * \param[in] report_type specify which report (INPUT, OUTPUT, FEATURE) that host requests
+ * \param[out] buffer data that application need to update, value must be accessible by USB controller (see \ref CFG_TUSB_ATTR_USBRAM)
+ * \param[in] reqlen number of bytes that host requested
+ * \retval non-zero Actual number of bytes in the response's buffer.
+ * \retval zero indicates the current request is not supported. Tinyusb device stack will reject the request by
+ * sending STALL in the data phase.
+ * \note After this callback, the request is silently executed by the tinyusb stack, thus
+ * the completion of this control request will not be reported to application.
+ * For Keyboard, USB host often uses this to turn on/off the LED for CAPLOCKS, NUMLOCK (\ref hid_keyboard_led_bm_t)
+ */
+ATTR_WEAK uint16_t tud_hid_keyboard_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
+
+/** Callback invoked when USB host request \ref HID_REQ_CONTROL_SET_REPORT.
+ * \param[in] report_type specify which report (INPUT, OUTPUT, FEATURE) that host requests
+ * \param[in] buffer containing the report's data
+ * \param[in] bufsize number of bytes in the \a buffer
+ * \note By the time this callback is invoked, the USB control transfer is already completed in the hardware side.
+ * Application are free to handle data at its own will.
+ */
+ATTR_WEAK void tud_hid_keyboard_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
+
+
+//ATTR_WEAK void tud_hid_keyboard_set_protocol_cb(bool boot_protocol);
+
+/** @} */
+/** @} */
+
+//--------------------------------------------------------------------+
+// MOUSE API
+//--------------------------------------------------------------------+
+#if CFG_TUD_HID_MOUSE
+/** \addtogroup ClassDriver_HID_Mouse Mouse
+ * @{ */
+/** \defgroup Mouse_Device Device
+ * @{ */
+
+/** \brief Check if the interface is currently busy or not
+ * \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to host
+ * \retval false if the interface is not busy meaning the stack successfully transferred data from/to host
+ * \note This function is primarily used for polling/waiting result after \ref tusbd_hid_mouse_send.
+ */
+bool tud_hid_mouse_ready(void);
+bool tud_hid_mouse_is_boot_protocol(void);
+
+bool tud_hid_mouse_data(uint8_t buttons, int8_t x, int8_t y, int8_t scroll, int8_t pan);
+
+bool tud_hid_mouse_move(int8_t x, int8_t y);
+bool tud_hid_mouse_scroll(int8_t vertical, int8_t horizontal);
+
+static inline bool tud_hid_mouse_button_press(uint8_t buttons)
+{
+ return tud_hid_mouse_data(buttons, 0, 0, 0, 0);
+}
+
+static inline bool tud_hid_mouse_button_release(void)
+{
+ return tud_hid_mouse_data(0, 0, 0, 0, 0);
+}
+
+/*------------- Callbacks (Weak is optional) -------------*/
+
+/**
+ * Callback function that is invoked when USB host request \ref HID_REQ_CONTROL_GET_REPORT.
+ * \param[in] report_type specify which report (INPUT, OUTPUT, FEATURE) that host requests
+ * \param[out] buffer buffer that application need to update, value must be accessible by USB controller (see \ref CFG_TUSB_ATTR_USBRAM)
+ * \param[in] reqlen number of bytes that host requested
+ * \retval non-zero Actual number of bytes in the response's buffer.
+ * \retval zero indicates the current request is not supported. Tinyusb device stack will reject the request by
+ * sending STALL in the data phase.
+ * \note After this callback, the request is silently executed by the tinyusb stack, thus
+ * the completion of this control request will not be reported to application
+ */
+ATTR_WEAK uint16_t tud_hid_mouse_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
+
+/**
+ * Callback function that is invoked when USB host request \ref HID_REQ_CONTROL_SET_REPORT.
+ * \param[in] report_type specify which report (INPUT, OUTPUT, FEATURE) that host requests
+ * \param[in] buffer buffer containing the report's data
+ * \param[in] bufsize number of bytes in the \a p_report_data
+ * \note By the time this callback is invoked, the USB control transfer is already completed in the hardware side.
+ * Application are free to handle data at its own will.
+ */
+ATTR_WEAK void tud_hid_mouse_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
+
+//ATTR_WEAK void tud_hid_mouse_set_protocol_cb(bool boot_protocol);
+
+#endif
+
+
+//--------------------------------------------------------------------+
+// HID Report Descriptor Template
+//--------------------------------------------------------------------+
+/* These template should be used as follow
+ * - Only 1 report : no parameter
+ * uint8_t report_desc[] = { ID_REPORT_DESC_KEYBOARD() };
+ *
+ * - Multiple Reports: "HID_REPORT_ID(ID)," must be passed to template
+ * uint8_t report_desc[] = {
+ * ID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) ,) ,
+ * HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2) ,)
+ * };
+ */
+
+/*------------- Keyboard Descriptor Template -------------*/
+#define HID_REPORT_DESC_KEYBOARD(...) \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\
+ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
+ /* 8 bits Modifier Keys (Shfit, Control, Alt) */ \
+ __VA_ARGS__ \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
+ HID_USAGE_MIN ( 224 ) ,\
+ HID_USAGE_MAX ( 231 ) ,\
+ HID_LOGICAL_MIN ( 0 ) ,\
+ HID_LOGICAL_MAX ( 1 ) ,\
+ HID_REPORT_COUNT ( 8 ) ,\
+ HID_REPORT_SIZE ( 1 ) ,\
+ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
+ /* 8 bit reserved */ \
+ HID_REPORT_COUNT ( 1 ) ,\
+ HID_REPORT_SIZE ( 8 ) ,\
+ HID_INPUT ( HID_CONSTANT ) ,\
+ /* 6-byte Keycodes */ \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
+ HID_USAGE_MIN ( 0 ) ,\
+ HID_USAGE_MAX ( 255 ) ,\
+ HID_LOGICAL_MIN ( 0 ) ,\
+ HID_LOGICAL_MAX ( 255 ) ,\
+ HID_REPORT_COUNT ( 6 ) ,\
+ HID_REPORT_SIZE ( 8 ) ,\
+ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
+ /* 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\
+ HID_USAGE_MIN ( 1 ) ,\
+ HID_USAGE_MAX ( 5 ) ,\
+ HID_REPORT_COUNT ( 5 ) ,\
+ HID_REPORT_SIZE ( 1 ) ,\
+ HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
+ /* led padding */ \
+ HID_REPORT_COUNT ( 1 ) ,\
+ HID_REPORT_SIZE ( 3 ) ,\
+ HID_OUTPUT ( HID_CONSTANT ) ,\
+ HID_COLLECTION_END \
+
+/*------------- Mouse Descriptor Template -------------*/
+#define HID_REPORT_DESC_MOUSE(...) \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
+ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
+ __VA_ARGS__ \
+ HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
+ HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
+ HID_USAGE_MIN ( 1 ) ,\
+ HID_USAGE_MAX ( 3 ) ,\
+ HID_LOGICAL_MIN ( 0 ) ,\
+ HID_LOGICAL_MAX ( 1 ) ,\
+ /* Left, Right, Middle, Backward, Forward mouse buttons */ \
+ HID_REPORT_COUNT ( 3 ) ,\
+ HID_REPORT_SIZE ( 1 ) ,\
+ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
+ /* 3 bit padding */ \
+ HID_REPORT_COUNT ( 1 ) ,\
+ HID_REPORT_SIZE ( 5 ) ,\
+ HID_INPUT ( HID_CONSTANT ) ,\
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
+ /* X, Y position [-127, 127] */ \
+ HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
+ HID_LOGICAL_MIN ( 0x81 ) ,\
+ HID_LOGICAL_MAX ( 0x7f ) ,\
+ HID_REPORT_COUNT ( 2 ) ,\
+ HID_REPORT_SIZE ( 8 ) ,\
+ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
+ /* Mouse scroll [-127, 127] */ \
+ HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
+ HID_LOGICAL_MIN ( 0x81 ) ,\
+ HID_LOGICAL_MAX ( 0x7f ) ,\
+ HID_REPORT_COUNT( 1 ) ,\
+ HID_REPORT_SIZE ( 8 ) ,\
+ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
+ HID_COLLECTION_END ,\
+ HID_COLLECTION_END \
+
+//------------- Consumer Control Report Template -------------//
+#define HID_REPORT_DESC_CONSUMER(...) \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\
+ HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\
+ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
+ __VA_ARGS__ \
+ HID_LOGICAL_MIN ( 0x00 ) ,\
+ HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\
+ HID_USAGE_MIN ( 0x00 ) ,\
+ HID_USAGE_MAX_N ( 0x03FF, 2 ) ,\
+ HID_REPORT_COUNT ( 1 ) ,\
+ HID_REPORT_SIZE ( 16 ) ,\
+ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
+ HID_COLLECTION_END \
+
+//------------- System Control Report Template -------------//
+/* 0x00 - do nothing
+ * 0x01 - Power Off
+ * 0x02 - Standby
+ * 0x04 - Wake Host
+ */
+#define HID_REPORT_DESC_SYSTEM_CONTROL(...) \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\
+ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
+ __VA_ARGS__ \
+ /* 2 bit system power control */ \
+ HID_LOGICAL_MIN ( 1 ) ,\
+ HID_LOGICAL_MAX ( 3 ) ,\
+ HID_REPORT_COUNT ( 1 ) ,\
+ HID_REPORT_SIZE ( 2 ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_SLEEP ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_WAKE_UP ) ,\
+ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
+ /* 6 bit padding */ \
+ HID_REPORT_COUNT ( 1 ) ,\
+ HID_REPORT_SIZE ( 6 ) ,\
+ HID_INPUT ( HID_CONSTANT ) ,\
+ HID_COLLECTION_END \
+
+//------------- Gamepad Report Template -------------//
+// Gamepad with 16 buttons and 2 joysticks
+// | Button Map (2 bytes) | X | Y | Z | Rz
+#define HID_REPORT_DESC_GAMEPAD(...) \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
+ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
+ __VA_ARGS__ \
+ /* 16 bit Button Map */ \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
+ HID_USAGE_MIN ( 1 ) ,\
+ HID_USAGE_MAX ( 16 ) ,\
+ HID_LOGICAL_MIN ( 0 ) ,\
+ HID_LOGICAL_MAX ( 1 ) ,\
+ HID_REPORT_COUNT ( 16 ) ,\
+ HID_REPORT_SIZE ( 1 ) ,\
+ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
+ /* X, Y, Z, Rz (min -127, max 127 ) */ \
+ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
+ HID_LOGICAL_MIN ( 0x81 ) ,\
+ HID_LOGICAL_MAX ( 0x7f ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
+ HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
+ HID_REPORT_COUNT ( 4 ) ,\
+ HID_REPORT_SIZE ( 8 ) ,\
+ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
+ HID_COLLECTION_END \
+
+
+
+/** @} */
+/** @} */
+
+
+
+//--------------------------------------------------------------------+
+// INTERNAL API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+void hidd_init(void);
+tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request);
+tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes);
+void hidd_reset(uint8_t rhport);
+
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_HID_DEVICE_H_ */
+
+
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc.h b/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc.h new file mode 100755 index 0000000..59df6be --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc.h @@ -0,0 +1,400 @@ +/**************************************************************************/
+/*!
+ @file msc.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_class
+ * \defgroup ClassDriver_MSC MassStorage (MSC)
+ * @{ */
+
+/** \defgroup ClassDriver_MSC_Common Common Definitions
+ * @{ */
+
+#ifndef _TUSB_MSC_H_
+#define _TUSB_MSC_H_
+
+#include <common/tusb_common.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Mass Storage Class Constant
+//--------------------------------------------------------------------+
+/// MassStorage Subclass
+typedef enum
+{
+ MSC_SUBCLASS_RBC = 1 , ///< Reduced Block Commands (RBC) T10 Project 1240-D
+ MSC_SUBCLASS_SFF_MMC , ///< SFF-8020i, MMC-2 (ATAPI). Typically used by a CD/DVD device
+ MSC_SUBCLASS_QIC , ///< QIC-157. Typically used by a tape device
+ MSC_SUBCLASS_UFI , ///< UFI. Typically used by Floppy Disk Drive (FDD) device
+ MSC_SUBCLASS_SFF , ///< SFF-8070i. Can be used by Floppy Disk Drive (FDD) device
+ MSC_SUBCLASS_SCSI ///< SCSI transparent command set
+}msc_subclass_type_t;
+
+enum {
+ MSC_CBW_SIGNATURE = 0x43425355, ///< Constant value of 43425355h (little endian)
+ MSC_CSW_SIGNATURE = 0x53425355 ///< Constant value of 53425355h (little endian)
+};
+
+/// \brief MassStorage Protocol.
+/// \details CBI only approved to use with full-speed floopy disk & should not used with highspeed or device other than floopy
+typedef enum
+{
+ MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt)
+ MSC_PROTOCOL_CBI_NO_INTERRUPT = 1 , ///< Control/Bulk/Interrupt protocol (without command completion interrupt)
+ MSC_PROTOCOL_BOT = 0x50 ///< Bulk-Only Transport
+}msc_protocol_type_t;
+
+/// MassStorage Class-Specific Control Request
+typedef enum
+{
+ MSC_REQ_GET_MAX_LUN = 254, ///< The Get Max LUN device request is used to determine the number of logical units supported by the device. Logical Unit Numbers on the device shall be numbered contiguously starting from LUN 0 to a maximum LUN of 15
+ MSC_REQ_RESET = 255 ///< This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host.
+}msc_request_type_t;
+
+/// \brief Command Block Status Values
+/// \details Indicates the success or failure of the command. The device shall set this byte to zero if the command completed
+/// successfully. A non-zero value shall indicate a failure during command execution according to the following
+typedef enum
+{
+ MSC_CSW_STATUS_PASSED = 0 , ///< MSC_CSW_STATUS_PASSED
+ MSC_CSW_STATUS_FAILED , ///< MSC_CSW_STATUS_FAILED
+ MSC_CSW_STATUS_PHASE_ERROR ///< MSC_CSW_STATUS_PHASE_ERROR
+}msc_csw_status_t;
+
+/// Command Block Wrapper
+typedef struct ATTR_PACKED
+{
+ uint32_t signature; ///< Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW.
+ uint32_t tag; ///< Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW.
+ uint32_t total_bytes; ///< The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags.
+ uint8_t dir; ///< Bit 7 of this field define transfer direction \n - 0 : Data-Out from host to the device. \n - 1 : Data-In from the device to the host.
+ uint8_t lun; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero.
+ uint8_t cmd_len; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16
+ uint8_t command[16]; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block
+}msc_cbw_t;
+
+TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct");
+
+/// Command Status Wrapper
+typedef struct ATTR_PACKED
+{
+ uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW.
+ uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW.
+ uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
+ uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t
+}msc_csw_t;
+
+TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct");
+
+//--------------------------------------------------------------------+
+// SCSI Constant
+//--------------------------------------------------------------------+
+
+/// SCSI Command Operation Code
+typedef enum
+{
+ SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation.
+ SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device.
+ SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters.
+ SCSI_CMD_MODE_SENSE_6 = 0x1A, ///< provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command.
+ SCSI_CMD_START_STOP_UNIT = 0x1B,
+ SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
+ SCSI_CMD_READ_CAPACITY_10 = 0x25, ///< The SCSI Read Capacity command is used to obtain data capacity information from a target device.
+ SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device.
+ SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed
+ SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer.
+ SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from the data-out buffer and write them.
+}scsi_cmd_type_t;
+
+/// SCSI Sense Key
+typedef enum
+{
+ SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command
+ SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< ndicates the last command completed successfully with some recovery action performed by the disc drive.
+ SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed.
+ SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition.
+ SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test.
+ SCSI_SENSE_ILLEGAL_REQUEST = 0x05, ///< Indicates an illegal parameter in the command descriptor block or in the additional parameters
+ SCSI_SENSE_UNIT_ATTENTION = 0x06, ///< Indicates the disc drive may have been reset.
+ SCSI_SENSE_DATA_PROTECT = 0x07, ///< Indicates that a command that reads or writes the medium was attempted on a block that is protected from this operation. The read or write operation is not performed.
+ SCSI_SENSE_FIRMWARE_ERROR = 0x08, ///< Vendor specific sense key.
+ SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command.
+ SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison.
+ SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium.
+ SCSI_SENSE_MISCOMPARE = 0x0e ///< ndicates that the source data did not match the data read from the medium.
+}scsi_sense_key_type_t;
+
+//--------------------------------------------------------------------+
+// SCSI Primary Command (SPC-4)
+//--------------------------------------------------------------------+
+
+/// SCSI Test Unit Ready Command
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY
+ uint8_t lun ; ///< Logical Unit
+ uint8_t reserved[3] ;
+ uint8_t control ;
+} scsi_test_unit_ready_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct");
+
+/// SCSI Inquiry Command
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY
+ uint8_t reserved1 ;
+ uint8_t page_code ;
+ uint8_t reserved2 ;
+ uint8_t alloc_length ; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred.
+ uint8_t control ;
+} scsi_inquiry_t, scsi_request_sense_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct");
+
+/// SCSI Inquiry Response Data
+typedef struct ATTR_PACKED
+{
+ uint8_t peripheral_device_type : 5;
+ uint8_t peripheral_qualifier : 3;
+
+ uint8_t : 7;
+ uint8_t is_removable : 1;
+
+ uint8_t version;
+
+ uint8_t response_data_format : 4;
+ uint8_t hierarchical_support : 1;
+ uint8_t normal_aca : 1;
+ uint8_t : 2;
+
+ uint8_t additional_length;
+
+ uint8_t protect : 1;
+ uint8_t : 2;
+ uint8_t third_party_copy : 1;
+ uint8_t target_port_group_support : 2;
+ uint8_t access_control_coordinator : 1;
+ uint8_t scc_support : 1;
+
+ uint8_t addr16 : 1;
+ uint8_t : 3;
+ uint8_t multi_port : 1;
+ uint8_t : 1; // vendor specific
+ uint8_t enclosure_service : 1;
+ uint8_t : 1;
+
+ uint8_t : 1; // vendor specific
+ uint8_t cmd_que : 1;
+ uint8_t : 2;
+ uint8_t sync : 1;
+ uint8_t wbus16 : 1;
+ uint8_t : 2;
+
+ uint8_t vendor_id[8] ; ///< 8 bytes of ASCII data identifying the vendor of the product.
+ uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor.
+ uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor.
+} scsi_inquiry_resp_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct");
+
+
+typedef struct ATTR_PACKED
+{
+ uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format
+ uint8_t valid : 1;
+
+ uint8_t reserved;
+
+ uint8_t sense_key : 4;
+ uint8_t : 1;
+ uint8_t ili : 1; ///< Incorrect length indicator
+ uint8_t end_of_medium : 1;
+ uint8_t filemark : 1;
+
+ uint32_t information;
+ uint8_t add_sense_len;
+ uint32_t command_specific_info;
+ uint8_t add_sense_code;
+ uint8_t add_sense_qualifier;
+ uint8_t field_replaceable_unit_code;
+
+ uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout
+
+} scsi_sense_fixed_resp_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct");
+
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6
+
+ uint8_t : 3;
+ uint8_t disable_block_descriptor : 1;
+ uint8_t : 0;
+
+ uint8_t page_code : 6;
+ uint8_t page_control : 2;
+
+ uint8_t subpage_code;
+ uint8_t alloc_length;
+ uint8_t control;
+} scsi_mode_sense6_t;
+
+TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct");
+
+typedef struct ATTR_PACKED
+{
+ uint8_t data_len;
+ uint8_t medium_type;
+ uint8_t device_specific_para;
+ uint8_t block_descriptor_len;
+} scsi_mode_sense6_resp_t;
+
+TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct");
+
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
+ uint8_t reserved[3];
+ uint8_t prohibit_removal;
+ uint8_t control;
+} scsi_prevent_allow_medium_removal_t;
+
+TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct");
+
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code;
+
+ uint8_t immded : 1;
+ uint8_t : 7;
+
+ uint8_t TU_RESERVED;
+
+ uint8_t power_condition_mod : 4;
+ uint8_t : 4;
+
+ uint8_t start : 1;
+ uint8_t load_eject : 1;
+ uint8_t no_flush : 1;
+ uint8_t : 1;
+ uint8_t power_condition : 4;
+
+ uint8_t control;
+} scsi_start_stop_unit_t;
+
+TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct");
+
+//--------------------------------------------------------------------+
+// SCSI MMC
+//--------------------------------------------------------------------+
+/// SCSI Read Format Capacity: Write Capacity
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code;
+ uint8_t reserved[6];
+ uint16_t alloc_length;
+ uint8_t control;
+} scsi_read_format_capacity_t;
+
+TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct");
+
+typedef struct ATTR_PACKED{
+ uint8_t reserved[3];
+ uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it.
+
+ uint32_t block_num; /// Number of Logical Blocks
+ uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present
+
+ uint8_t reserved2;
+ uint16_t block_size_u16;
+
+} scsi_read_format_capacity_data_t;
+
+TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct");
+
+//--------------------------------------------------------------------+
+// SCSI Block Command (SBC-3)
+// NOTE: All data in SCSI command are in Big Endian
+//--------------------------------------------------------------------+
+
+/// SCSI Read Capacity 10 Command: Read Capacity
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10
+ uint8_t reserved1 ;
+ uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
+ uint16_t reserved2 ;
+ uint8_t partial_medium_indicator ;
+ uint8_t control ;
+} scsi_read_capacity10_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct");
+
+/// SCSI Read Capacity 10 Response Data
+typedef struct {
+ uint32_t last_lba ; ///< The last Logical Block Address of the device
+ uint32_t block_size ; ///< Block size in bytes
+} scsi_read_capacity10_resp_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct");
+
+/// SCSI Read 10 Command
+typedef struct ATTR_PACKED
+{
+ uint8_t cmd_code ; ///< SCSI OpCode
+ uint8_t reserved ; // has LUN according to wiki
+ uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
+ uint8_t reserved2 ;
+ uint16_t block_count ; ///< Number of Blocks used by this command
+ uint8_t control ;
+} scsi_read10_t, scsi_write10_t;
+
+TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct");
+TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct");
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_MSC_H_ */
+
+/// @}
+/// @}
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc_device.c b/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc_device.c new file mode 100755 index 0000000..5a047b0 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc_device.c @@ -0,0 +1,567 @@ +/**************************************************************************/
+/*!
+ @file msc_device.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_MSC)
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#define _TINY_USB_SOURCE_FILE_
+
+#include "common/tusb_common.h"
+#include "msc_device.h"
+#include "device/usbd_pvt.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+enum
+{
+ MSC_STAGE_CMD = 0,
+ MSC_STAGE_DATA,
+ MSC_STAGE_STATUS
+};
+
+typedef struct {
+ CFG_TUSB_MEM_ALIGN msc_cbw_t cbw;
+
+//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13UXX)
+// uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member
+//#endif
+
+ CFG_TUSB_MEM_ALIGN msc_csw_t csw;
+
+ uint8_t itf_num;
+ uint8_t ep_in;
+ uint8_t ep_out;
+
+ // Bulk Only Transfer (BOT) Protocol
+ uint8_t stage;
+ uint32_t total_len;
+ uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage
+
+ // Sense Response Data
+ uint8_t sense_key;
+ uint8_t add_sense_code;
+ uint8_t add_sense_qualifier;
+}mscd_interface_t;
+
+CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf;
+CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN static uint8_t _mscd_buf[CFG_TUD_MSC_BUFSIZE];
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
+static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
+
+static inline uint32_t rdwr10_get_lba(uint8_t const command[])
+{
+ // read10 & write10 has the same format
+ scsi_write10_t* p_rdwr10 = (scsi_write10_t*) command;
+
+ // copy first to prevent mis-aligned access
+ uint32_t lba;
+ memcpy(&lba, &p_rdwr10->lba, 4);
+
+ return __be2n(lba);
+}
+
+static inline uint16_t rdwr10_get_blockcount(uint8_t const command[])
+{
+ // read10 & write10 has the same format
+ scsi_write10_t* p_rdwr10 = (scsi_write10_t*) command;
+
+ // copy first to prevent mis-aligned access
+ uint16_t block_count;
+ memcpy(&block_count, &p_rdwr10->block_count, 2);
+
+ return __be2n_16(block_count);
+}
+
+//--------------------------------------------------------------------+
+// APPLICATION API
+//--------------------------------------------------------------------+
+bool tud_msc_ready(void)
+{
+ return ( _mscd_itf.ep_in != 0 ) && ( _mscd_itf.ep_out != 0 ) ;
+}
+
+bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier)
+{
+ (void) lun;
+
+ _mscd_itf.sense_key = sense_key;
+ _mscd_itf.add_sense_code = add_sense_code;
+ _mscd_itf.add_sense_qualifier = add_sense_qualifier;
+
+ return true;
+}
+
+
+//--------------------------------------------------------------------+
+// USBD-CLASS API
+//--------------------------------------------------------------------+
+void mscd_init(void)
+{
+ tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
+}
+
+void mscd_reset(uint8_t rhport)
+{
+ tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
+}
+
+tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
+{
+ // only support SCSI's BOT protocol
+ TU_VERIFY( ( MSC_SUBCLASS_SCSI == p_desc_itf->bInterfaceSubClass &&
+ MSC_PROTOCOL_BOT == p_desc_itf->bInterfaceProtocol ), TUSB_ERROR_MSC_UNSUPPORTED_PROTOCOL );
+
+ mscd_interface_t * p_msc = &_mscd_itf;
+
+ // Open endpoint pair with usbd helper
+ tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_itf );
+ TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
+
+ p_msc->itf_num = p_desc_itf->bInterfaceNumber;
+ (*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
+
+ //------------- Queue Endpoint OUT for Command Block Wrapper -------------//
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_DCD_EDPT_XFER );
+
+ return TUSB_ERROR_NONE;
+}
+
+tusb_error_t mscd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request)
+{
+ OSAL_SUBTASK_BEGIN
+
+ TU_ASSERT(p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS, TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT);
+
+ if(MSC_REQ_RESET == p_request->bRequest)
+ {
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ }
+ else if (MSC_REQ_GET_MAX_LUN == p_request->bRequest)
+ {
+ // returned MAX LUN is minus 1 by specs
+ _usbd_ctrl_buf[0] = CFG_TUD_MSC_MAXLUN-1;
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, 1);
+ }else
+ {
+ dcd_control_stall(rhport); // stall unsupported request
+ }
+
+ OSAL_SUBTASK_END
+}
+
+// return length of response (copied to buffer), -1 if it is not an built-in commands
+int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize)
+{
+ int32_t ret;
+
+ switch ( p_cbw->command[0] )
+ {
+ case SCSI_CMD_READ_CAPACITY_10:
+ {
+ scsi_read_capacity10_resp_t read_capa10 =
+ {
+ .last_lba = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM-1), // read capacity
+ .block_size = ENDIAN_BE(CFG_TUD_MSC_BLOCK_SZ)
+ };
+
+ ret = sizeof(read_capa10);
+ memcpy(buffer, &read_capa10, ret);
+ }
+ break;
+
+ case SCSI_CMD_READ_FORMAT_CAPACITY:
+ {
+ scsi_read_format_capacity_data_t read_fmt_capa =
+ {
+ .list_length = 8,
+ .block_num = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM), // write capacity
+ .descriptor_type = 2, // formatted media
+ .block_size_u16 = ENDIAN_BE16(CFG_TUD_MSC_BLOCK_SZ)
+ };
+
+ ret = sizeof(read_fmt_capa);
+ memcpy(buffer, &read_fmt_capa, ret);
+ }
+ break;
+
+ case SCSI_CMD_INQUIRY:
+ {
+ scsi_inquiry_resp_t inquiry_rsp =
+ {
+ .is_removable = 1,
+ .version = 2,
+ .response_data_format = 2,
+ .vendor_id = "Adafruit",
+ .product_id = "Feather52840",
+ .product_rev = "1.0"
+ };
+
+ strncpy((char*) inquiry_rsp.vendor_id , CFG_TUD_MSC_VENDOR , sizeof(inquiry_rsp.vendor_id));
+ strncpy((char*) inquiry_rsp.product_id , CFG_TUD_MSC_PRODUCT , sizeof(inquiry_rsp.product_id));
+ strncpy((char*) inquiry_rsp.product_rev, CFG_TUD_MSC_PRODUCT_REV, sizeof(inquiry_rsp.product_rev));
+
+ ret = sizeof(inquiry_rsp);
+ memcpy(buffer, &inquiry_rsp, ret);
+ }
+ break;
+
+ case SCSI_CMD_MODE_SENSE_6:
+ {
+ scsi_mode_sense6_resp_t const mode_resp = {
+ .data_len = 3,
+ .medium_type = 0,
+ .device_specific_para = 0,
+ .block_descriptor_len = 0 // no block descriptor are included
+ };
+
+ ret = sizeof(mode_resp);
+ memcpy(buffer, &mode_resp, ret);
+ }
+ break;
+
+ case SCSI_CMD_REQUEST_SENSE:
+ {
+ scsi_sense_fixed_resp_t sense_rsp =
+ {
+ .response_code = 0x70,
+ .valid = 1
+ };
+
+ sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8;
+
+ sense_rsp.sense_key = _mscd_itf.sense_key;
+ sense_rsp.add_sense_code = _mscd_itf.add_sense_code;
+ sense_rsp.add_sense_qualifier = _mscd_itf.add_sense_qualifier;
+
+ ret = sizeof(sense_rsp);
+ memcpy(buffer, &sense_rsp, ret);
+
+ // Clear sense data after copy
+ tud_msc_set_sense(p_cbw->lun, 0, 0, 0);
+ }
+ break;
+
+ default: ret = -1; break;
+ }
+
+ return ret;
+}
+
+tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes)
+{
+ mscd_interface_t* p_msc = &_mscd_itf;
+ msc_cbw_t const * p_cbw = &p_msc->cbw;
+ msc_csw_t * p_csw = &p_msc->csw;
+
+ switch (p_msc->stage)
+ {
+ case MSC_STAGE_CMD:
+ //------------- new CBW received -------------//
+ // Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it
+ if(ep_addr != p_msc->ep_out) return TUSB_ERROR_NONE;
+
+ TU_ASSERT( event == DCD_XFER_SUCCESS &&
+ xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA );
+
+ p_csw->signature = MSC_CSW_SIGNATURE;
+ p_csw->tag = p_cbw->tag;
+ p_csw->data_residue = 0;
+
+ /*------------- Parse command and prepare DATA -------------*/
+ p_msc->stage = MSC_STAGE_DATA;
+ p_msc->total_len = p_cbw->total_bytes;
+ p_msc->xferred_len = 0;
+
+ if (SCSI_CMD_READ_10 == p_cbw->command[0])
+ {
+ proc_read10_cmd(rhport, p_msc);
+ }
+ else if (SCSI_CMD_WRITE_10 == p_cbw->command[0])
+ {
+ proc_write10_cmd(rhport, p_msc);
+ }
+ else
+ {
+ // For other SCSI commands
+ // 1. Zero : Invoke app callback, skip DATA and move to STATUS stage
+ // 2. OUT : queue transfer (invoke app callback after done)
+ // 3. IN : invoke app callback to get response
+ if ( p_cbw->total_bytes == 0)
+ {
+ int32_t const cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, NULL, 0);
+
+ p_msc->total_len = 0;
+ p_msc->stage = MSC_STAGE_STATUS;
+
+ if ( cb_result < 0 )
+ {
+ p_csw->status = MSC_CSW_STATUS_FAILED;
+ tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
+ }
+ else
+ {
+ p_csw->status = MSC_CSW_STATUS_PASSED;
+ }
+ }
+ else if ( !BIT_TEST_(p_cbw->dir, 7) )
+ {
+ // OUT transfer
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len), TUSB_ERROR_DCD_EDPT_XFER );
+ }
+ else
+ {
+ // IN Transfer
+ int32_t cb_result;
+
+ // first process if it is a built-in commands
+ cb_result = proc_builtin_scsi(p_cbw, _mscd_buf, sizeof(_mscd_buf));
+
+ // Not an built-in command, invoke user callback
+ if ( cb_result < 0 )
+ {
+ cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
+ }
+
+ if ( cb_result > 0 )
+ {
+ p_msc->total_len = (uint32_t) cb_result;
+ p_csw->status = MSC_CSW_STATUS_PASSED;
+
+ TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len, TUSB_ERROR_INVALID_PARA ); // cannot return more than host expect
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len), TUSB_ERROR_DCD_EDPT_XFER );
+ }else
+ {
+ p_msc->total_len = 0;
+ p_csw->status = MSC_CSW_STATUS_FAILED;
+ p_msc->stage = MSC_STAGE_STATUS;
+
+ tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
+ dcd_edpt_stall(rhport, p_msc->ep_in);
+ }
+ }
+ }
+ break;
+
+ case MSC_STAGE_DATA:
+ // OUT transfer, invoke callback if needed
+ if ( !BIT_TEST_(p_cbw->dir, 7) )
+ {
+ if ( SCSI_CMD_WRITE_10 != p_cbw->command[0] )
+ {
+ int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
+
+ if ( cb_result < 0 )
+ {
+ p_csw->status = MSC_CSW_STATUS_FAILED;
+ tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
+ }else
+ {
+ p_csw->status = MSC_CSW_STATUS_PASSED;
+ }
+ }
+ else
+ {
+ uint16_t const block_sz = p_cbw->total_bytes / rdwr10_get_blockcount(p_cbw->command);
+
+ // Adjust lba with transferred bytes
+ uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz);
+
+ // Application can consume smaller bytes
+ int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, p_msc->xferred_len % block_sz, _mscd_buf, xferred_bytes);
+
+ if ( nbytes < 0 )
+ {
+ // negative means error -> skip to status phase, status in CSW set to failed
+ p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len;
+ p_csw->status = MSC_CSW_STATUS_FAILED;
+ p_msc->stage = MSC_STAGE_STATUS;
+
+ tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
+ break;
+ }else
+ {
+ // Application consume less than what we got (including zero)
+ if ( nbytes < xferred_bytes )
+ {
+ if ( nbytes > 0 )
+ {
+ p_msc->xferred_len += nbytes;
+ memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes);
+ }
+
+ // simulate an transfer complete with adjusted parameters --> this driver callback will fired again
+ dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, DCD_XFER_SUCCESS, false);
+
+ return TUSB_ERROR_NONE; // skip the rest
+ }
+ else
+ {
+ // Application consume all bytes in our buffer. Nothing to do, process with normal flow
+ }
+ }
+ }
+ }
+
+ // Accumulate data so far
+ p_msc->xferred_len += xferred_bytes;
+
+ if ( p_msc->xferred_len >= p_msc->total_len )
+ {
+ // Data Stage is complete
+ p_msc->stage = MSC_STAGE_STATUS;
+ }
+ else
+ {
+ // READ10 & WRITE10 Can be executed with large bulk of data e.g write 8K bytes (several flash write)
+ // We break it into multiple smaller command whose data size is up to CFG_TUD_MSC_BUFSIZE
+ if (SCSI_CMD_READ_10 == p_cbw->command[0])
+ {
+ proc_read10_cmd(rhport, p_msc);
+ }
+ else if (SCSI_CMD_WRITE_10 == p_cbw->command[0])
+ {
+ proc_write10_cmd(rhport, p_msc);
+ }else
+ {
+ // No other command take more than one transfer yet -> unlikely error
+ TU_BREAKPOINT();
+ }
+ }
+ break;
+
+ case MSC_STAGE_STATUS: break; // processed immediately after this switch
+ default : break;
+ }
+
+ if ( p_msc->stage == MSC_STAGE_STATUS )
+ {
+ // Either endpoints is stalled, need to wait until it is cleared by host
+ if ( dcd_edpt_stalled(rhport, p_msc->ep_in) || dcd_edpt_stalled(rhport, p_msc->ep_out) )
+ {
+ // simulate an transfer complete with adjusted parameters --> this driver callback will fired again
+ dcd_event_xfer_complete(rhport, p_msc->ep_out, 0, DCD_XFER_SUCCESS, false);
+ }
+ else
+ {
+ // Invoke complete callback if defined
+ if ( SCSI_CMD_READ_10 == p_cbw->command[0])
+ {
+ if ( tud_msc_read10_complete_cb ) tud_msc_read10_complete_cb(p_cbw->lun);
+ }
+ else if ( SCSI_CMD_WRITE_10 == p_cbw->command[0] )
+ {
+ if ( tud_msc_write10_complete_cb ) tud_msc_write10_complete_cb(p_cbw->lun);
+ }
+ else
+ {
+ if ( tud_msc_scsi_complete_cb ) tud_msc_scsi_complete_cb(p_cbw->lun, p_cbw->command);
+ }
+
+ // Move to default CMD stage after sending status
+ p_msc->stage = MSC_STAGE_CMD;
+
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)) );
+
+ //------------- Queue the next CBW -------------//
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) );
+ }
+ }
+
+ return TUSB_ERROR_NONE;
+}
+
+/*------------------------------------------------------------------*/
+/* SCSI Command Process
+ *------------------------------------------------------------------*/
+static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
+{
+ msc_cbw_t const * p_cbw = &p_msc->cbw;
+ msc_csw_t * p_csw = &p_msc->csw;
+
+ uint16_t const block_sz = p_cbw->total_bytes / rdwr10_get_blockcount(p_cbw->command);
+
+ // Adjust lba with transferred bytes
+ uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz);
+
+ // remaining bytes capped at class buffer
+ int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
+
+ // Application can consume smaller bytes
+ nbytes = tud_msc_read10_cb(p_cbw->lun, lba, p_msc->xferred_len % block_sz, _mscd_buf, (uint32_t) nbytes);
+
+ if ( nbytes < 0 )
+ {
+ // negative means error -> pipe is stalled & status in CSW set to failed
+ p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len;
+ p_csw->status = MSC_CSW_STATUS_FAILED;
+
+ tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
+ dcd_edpt_stall(rhport, p_msc->ep_in);
+ }
+ else if ( nbytes == 0 )
+ {
+ // zero means not ready -> simulate an transfer complete so that this driver callback will fired again
+ dcd_event_xfer_complete(rhport, p_msc->ep_in, 0, DCD_XFER_SUCCESS, false);
+ }
+ else
+ {
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, nbytes), );
+ }
+}
+
+static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
+{
+ msc_cbw_t const * p_cbw = &p_msc->cbw;
+
+ // remaining bytes capped at class buffer
+ int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
+
+ // Write10 callback will be called later when usb transfer complete
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), );
+}
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc_device.h b/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc_device.h new file mode 100755 index 0000000..8403dfe --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/class/msc/msc_device.h @@ -0,0 +1,188 @@ +/**************************************************************************/
+/*!
+ @file msc_device.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_MSC_DEVICE_H_
+#define _TUSB_MSC_DEVICE_H_
+
+#include "common/tusb_common.h"
+#include "device/usbd.h"
+#include "msc.h"
+
+
+//--------------------------------------------------------------------+
+// Class Driver Configuration
+//--------------------------------------------------------------------+
+TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
+
+#ifndef CFG_TUD_MSC_MAXLUN
+ #define CFG_TUD_MSC_MAXLUN 1
+#elif CFG_TUD_MSC_MAXLUN == 0 || CFG_TUD_MSC_MAXLUN > 16
+ #error MSC Device: Incorrect setting of MAX LUN
+#endif
+
+#ifndef CFG_TUD_MSC_BLOCK_NUM
+ #error CFG_TUD_MSC_BLOCK_NUM must be defined
+#endif
+
+#ifndef CFG_TUD_MSC_BLOCK_SZ
+ #error CFG_TUD_MSC_BLOCK_SZ must be defined
+#endif
+
+#ifndef CFG_TUD_MSC_BUFSIZE
+ #error CFG_TUD_MSC_BUFSIZE must be defined, value of CFG_TUD_MSC_BLOCK_SZ should work well, the more the better
+#endif
+
+#ifndef CFG_TUD_MSC_VENDOR
+ #error CFG_TUD_MSC_VENDOR 8-byte name must be defined
+#endif
+
+#ifndef CFG_TUD_MSC_PRODUCT
+ #error CFG_TUD_MSC_PRODUCT 16-byte name must be defined
+#endif
+
+#ifndef CFG_TUD_MSC_PRODUCT_REV
+ #error CFG_TUD_MSC_PRODUCT_REV 4-byte string must be defined
+#endif
+
+// TODO highspeed device is 512
+#ifndef CFG_TUD_MSC_EPSIZE
+#define CFG_TUD_MSC_EPSIZE 64
+#endif
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \addtogroup ClassDriver_MSC
+ * @{
+ * \defgroup MSC_Device Device
+ * @{ */
+
+
+// Check if MSC interface is ready to use
+bool tud_msc_ready(void);
+bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
+
+//--------------------------------------------------------------------+
+// APPLICATION CALLBACK (WEAK is optional)
+//--------------------------------------------------------------------+
+/**
+ * Callback invoked when received \ref SCSI_CMD_READ_10 command
+ * \param[in] lun Logical unit number
+ * \param[in] lba Logical Block Address to be read
+ * \param[in] offset Byte offset from LBA
+ * \param[out] buffer Buffer which application need to update with the response data.
+ * \param[in] bufsize Requested bytes
+ *
+ * \return Number of byte read, if it is less than requested bytes by \a \b bufsize. Tinyusb will transfer
+ * this amount first and invoked this again for remaining data.
+ *
+ * \retval zero Indicate application is not ready yet to response e.g disk I/O is not complete.
+ * tinyusb will invoke this callback with the same parameters again some time later.
+ *
+ * \retval negative Indicate error e.g reading disk I/O. tinyusb will \b STALL the corresponding
+ * endpoint and return failed status in command status wrapper phase.
+ */
+int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
+
+/**
+ * Callback invoked when received \ref SCSI_CMD_WRITE_10 command
+ * \param[in] lun Logical unit number
+ * \param[in] lba Logical Block Address to be write
+ * \param[in] offset Byte offset from LBA
+ * \param[out] buffer Buffer which holds written data.
+ * \param[in] bufsize Requested bytes
+ *
+ * \return Number of byte written, if it is less than requested bytes by \a \b bufsize. Tinyusb will proceed with
+ * other work and invoked this again with adjusted parameters.
+ *
+ * \retval zero Indicate application is not ready yet e.g disk I/O is not complete.
+ * Tinyusb will invoke this callback with the same parameters again some time later.
+ *
+ * \retval negative Indicate error writing disk I/O. Tinyusb will \b STALL the corresponding
+ * endpoint and return failed status in command status wrapper phase.
+ */
+int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
+
+/**
+ * Callback invoked when received an SCSI command not in built-in list below.
+ * \param[in] lun Logical unit number
+ * \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
+ * \param[out] buffer Buffer for SCSI Data Stage.
+ * - For INPUT: application must fill this with response.
+ * - For OUTPUT it holds the Data from host
+ * \param[in] bufsize Buffer's length.
+ *
+ * \return Actual bytes processed, can be zero for no-data command.
+ * \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
+ * endpoint and return failed status in command status wrapper phase.
+ *
+ * \note Following command is automatically handled by tinyusb stack, callback should not be worried:
+ * - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
+ * - READ10 and WRITE10 has their own callbacks
+ */
+int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
+
+/*------------- Optional callbacks : Could be used by application to free up resources -------------*/
+ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
+ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun);
+ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]);
+
+/** @} */
+/** @} */
+
+//--------------------------------------------------------------------+
+// USBD-CLASS DRIVER API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+void mscd_init(void);
+tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+tusb_error_t mscd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request);
+tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes);
+void mscd_reset(uint8_t rhport);
+
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_MSC_DEVICE_H_ */
+
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/binary.h b/arduino/cores/nRF5/usb/tinyusb/src/common/binary.h new file mode 100755 index 0000000..3ab87e3 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/binary.h @@ -0,0 +1,132 @@ +/**************************************************************************/
+/*!
+ @file binary.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Common
+ * \defgroup Group_Binary Binary
+ * @{ */
+
+#ifndef _TUSB_BINARY_H_
+#define _TUSB_BINARY_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "tusb_compiler.h"
+
+//------------- Bit manipulation -------------//
+#define BIT_(n) (1U << (n)) ///< n-th Bit
+#define BIT_SET_(x, n) ( (x) | BIT_(n) ) ///< set n-th bit of x to 1
+#define BIT_CLR_(x, n) ( (x) & (~BIT_(n)) ) ///< clear n-th bit of x
+#define BIT_TEST_(x, n) ( ((x) & BIT_(n)) ? true : false ) ///< check if n-th bit of x is 1
+
+static inline uint32_t bit_set(uint32_t value, uint8_t n) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint32_t bit_set(uint32_t value, uint8_t n)
+{
+ return value | BIT_(n);
+}
+
+static inline uint32_t bit_clear(uint32_t value, uint8_t n) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint32_t bit_clear(uint32_t value, uint8_t n)
+{
+ return value & (~BIT_(n));
+}
+
+static inline bool bit_test(uint32_t value, uint8_t n) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline bool bit_test(uint32_t value, uint8_t n)
+{
+ return (value & BIT_(n)) ? true : false;
+}
+
+///< create a mask with n-bit lsb set to 1
+static inline uint32_t bit_mask(uint8_t n) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint32_t bit_mask(uint8_t n)
+{
+ return (n < 32) ? ( BIT_(n) - 1 ) : UINT32_MAX;
+}
+
+static inline uint32_t bit_mask_range(uint8_t start, uint32_t end) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint32_t bit_mask_range(uint8_t start, uint32_t end)
+{
+ return bit_mask(end+1) & ~ bit_mask(start);
+}
+
+static inline uint32_t bit_set_range(uint32_t value, uint8_t start, uint8_t end, uint32_t pattern) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint32_t bit_set_range(uint32_t value, uint8_t start, uint8_t end, uint32_t pattern)
+{
+ return ( value & ~bit_mask_range(start, end) ) | (pattern << start);
+}
+
+
+//------------- Binary Constant -------------//
+#if defined(__GNUC__) && !defined(__CC_ARM)
+
+#define BIN8(x) ((uint8_t) (0b##x))
+#define BIN16(b1, b2) ((uint16_t) (0b##b1##b2))
+#define BIN32(b1, b2, b3, b4) ((uint32_t) (0b##b1##b2##b3##b4))
+
+#else
+
+// internal macro of B8, B16, B32
+#define _B8__(x) (((x&0x0000000FUL)?1:0) \
+ +((x&0x000000F0UL)?2:0) \
+ +((x&0x00000F00UL)?4:0) \
+ +((x&0x0000F000UL)?8:0) \
+ +((x&0x000F0000UL)?16:0) \
+ +((x&0x00F00000UL)?32:0) \
+ +((x&0x0F000000UL)?64:0) \
+ +((x&0xF0000000UL)?128:0))
+
+#define BIN8(d) ((uint8_t) _B8__(0x##d##UL))
+#define BIN16(dmsb,dlsb) (((uint16_t)BIN8(dmsb)<<8) + BIN8(dlsb))
+#define BIN32(dmsb,db2,db3,dlsb) \
+ (((uint32_t)BIN8(dmsb)<<24) \
+ + ((uint32_t)BIN8(db2)<<16) \
+ + ((uint32_t)BIN8(db3)<<8) \
+ + BIN8(dlsb))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TUSB_BINARY_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/compiler/tusb_compiler_gcc.h b/arduino/cores/nRF5/usb/tinyusb/src/common/compiler/tusb_compiler_gcc.h new file mode 100755 index 0000000..3b6d977 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/compiler/tusb_compiler_gcc.h @@ -0,0 +1,137 @@ +/**************************************************************************/
+/*!
+ @file compiler_gcc.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Compiler
+ * \defgroup Group_GCC GNU GCC
+ * @{ */
+
+#ifndef _TUSB_COMPILER_GCC_H_
+#define _TUSB_COMPILER_GCC_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define ALIGN_OF(x) __alignof__(x)
+
+/// Normally, the compiler places the objects it generates in sections like data or bss & function in text. Sometimes, however, you need additional sections, or you need certain particular variables to appear in special sections, for example to map to special hardware. The section attribute specifies that a variable (or function) lives in a particular section
+#define ATTR_SECTION(sec_name) __attribute__ (( section(#sec_name) ))
+
+/// If this attribute is used on a function declaration and a call to such a function is not eliminated through dead code elimination or other optimizations, an error that includes message is diagnosed. This is useful for compile-time checking
+#define ATTR_ERROR(Message) __attribute__ ((error(Message)))
+
+/// If this attribute is used on a function declaration and a call to such a function is not eliminated through dead code elimination or other optimizations, a warning that includes message is diagnosed. This is useful for compile-time checking
+#define ATTR_WARNING(Message) __attribute__ ((warning(Message)))
+
+/** \defgroup Group_VariableAttr Variable Attributes
+ * @{ */
+
+/// This attribute specifies a minimum alignment for the variable or structure field, measured in bytes
+#define ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
+
+/// The packed attribute specifies that a variable or structure field should have the smallest possible alignment—one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute
+#define ATTR_PACKED __attribute__ ((packed))
+
+#define ATTR_PREPACKED
+
+#define ATTR_PACKED_STRUCT(x) x __attribute__ ((packed))
+/** @} */
+
+/** \defgroup Group_FuncAttr Function Attributes
+ * @{ */
+
+/// Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level is specified
+#define ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
+
+/// The nonnull attribute specifies that some function parameters should be non-null pointers. f the compiler determines that a null pointer is passed in an argument slot marked as non-null, and the -Wnonnull option is enabled, a warning is issued. All pointer arguments are marked as non-null
+#define ATTR_NON_NULL __attribute__ ((nonull))
+
+/// Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute pure
+#define ATTR_PURE __attribute__ ((pure))
+
+/// \brief Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the pure attribute below, since function is not allowed to read global memory.
+/// Note that a function that has pointer arguments and examines the data pointed to must not be declared const. Likewise, a function that calls a non-const function usually must not be const. It does not make sense for a const function to return void
+#define ATTR_CONST __attribute__ ((const))
+
+/// The deprecated attribute results in a warning if the function is used anywhere in the source file. This is useful when identifying functions that are expected to be removed in a future version of a program. The warning also includes the location of the declaration of the deprecated function, to enable users to easily find further information about why the function is deprecated, or what they should do instead. Note that the warnings only occurs for uses
+#define ATTR_DEPRECATED __attribute__ ((deprecated))
+
+/// Same as the deprecated attribute with optional message in the warning
+#define ATTR_DEPRECATED_MESS(mess) __attribute__ ((deprecated(mess)))
+
+/// The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code
+#define ATTR_WEAK __attribute__ ((weak))
+
+/// The alias attribute causes the declaration to be emitted as an alias for another symbol, which must be specified
+#define ATTR_ALIAS(func) __attribute__ ((alias(#func)))
+
+/// The weakref attribute marks a declaration as a weak reference. It is equivalent with weak + alias attribute, but require function is static
+#define ATTR_WEAKREF(func) __attribute__ ((weakref(#func)))
+
+/// The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug
+#define ATTR_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+
+/// This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly.
+#define ATTR_USED __attribute__ ((used))
+
+/// This attribute, attached to a function, means that the function is meant to be possibly unused. GCC does not produce a warning for this function.
+#define ATTR_UNUSED __attribute__ ((unused))
+
+/** @} */
+
+/** \defgroup Group_BuiltinFunc Built-in Functions
+* @{ */
+
+// TODO mcu specific
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define __n2be(x) __builtin_bswap32(x) ///< built-in function to convert 32-bit from native to Big Endian
+#define __be2n(x) __n2be(x) ///< built-in function to convert 32-bit from Big Endian to native
+
+#define __n2be_16(u16) __builtin_bswap16(u16)
+#define __be2n_16(u16) __n2be_16(u16)
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_COMPILER_GCC_H_ */
+
+/// @}
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/compiler/tusb_compiler_iar.h b/arduino/cores/nRF5/usb/tinyusb/src/common/compiler/tusb_compiler_iar.h new file mode 100755 index 0000000..1703ea4 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/compiler/tusb_compiler_iar.h @@ -0,0 +1,91 @@ +/**************************************************************************/
+/*!
+ @file compiler_iar.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \file
+ * \brief IAR Compiler
+ */
+
+/** \ingroup Group_Compiler
+ * \defgroup Group_IAR IAR ARM
+ * @{
+ */
+
+#ifndef _TUSB_COMPILER_IAR_H_
+#define _TUSB_COMPILER_IAR_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define ALIGN_OF(x) __ALIGNOF__(x)
+
+#define ATTR_PACKED_STRUCT(x) __packed x
+#define ATTR_PREPACKED __packed
+#define ATTR_PACKED
+//#define ATTR_SECTION(section) _Pragma((#section))
+
+#define ATTR_ALIGNED(bytes) _Pragma(XSTRING_(data_alignment=##bytes))
+
+#ifndef ATTR_ALWAYS_INLINE
+/// Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level is specified
+#define ATTR_ALWAYS_INLINE error
+#endif
+
+#define ATTR_PURE // TODO IAR pure function attribute
+#define ATTR_CONST // TODO IAR const function attribute
+#define ATTR_WEAK __weak
+
+#define ATTR_WARN_UNUSED_RESULT
+#define ATTR_USED
+#define ATTR_UNUSED
+
+// built-in function to convert 32-bit Big-Endian to Little-Endian
+//#if __LITTLE_ENDIAN__
+#define __be2n __REV
+#define __n2be __be2n
+
+#define __n2be_16(u16) ((uint16_t) __REV16(u16))
+#define __be2n_16(u16) __n2be_16(u16)
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_COMPILER_IAR_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_common.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_common.h new file mode 100755 index 0000000..3c5402e --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_common.h @@ -0,0 +1,249 @@ +/**************************************************************************/
+/*!
+ @file tusb_common.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Common
+ * \defgroup Group_CommonH common.h
+ * @{ */
+
+#ifndef _TUSB_COMMON_H_
+#define _TUSB_COMMON_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// INCLUDES
+//--------------------------------------------------------------------+
+
+//------------- Standard Header -------------//
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+//------------- TUSB Option Header -------------//
+#include "tusb_option.h"
+
+//------------- Common Header -------------//
+#include "tusb_compiler.h"
+#include "tusb_verify.h"
+#include "binary.h"
+#include "tusb_error.h"
+#include "tusb_timeout.h"
+#include "tusb_types.h"
+
+//--------------------------------------------------------------------+
+// MACROS
+//--------------------------------------------------------------------+
+#define TU_ARRAY_SZIE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
+
+#define U16_HIGH_U8(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
+#define U16_LOW_U8(u16) ((uint8_t) ((u16) & 0x00ff))
+#define U16_TO_U8S_BE(u16) U16_HIGH_U8(u16), U16_LOW_U8(u16)
+#define U16_TO_U8S_LE(u16) U16_LOW_U8(u16), U16_HIGH_U8(u16)
+
+#define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
+#define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
+#define U32_B3_U8(u32) ((uint8_t) (((u32) >> 8) & 0x000000ff))
+#define U32_B4_U8(u32) ((uint8_t) ((u32) & 0x000000ff)) // LSB
+
+#define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
+#define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
+
+//------------- Endian Conversion -------------//
+#define ENDIAN_BE(u32) \
+ (uint32_t) ( (((u32) & 0xFF) << 24) | (((u32) & 0xFF00) << 8) | (((u32) >> 8) & 0xFF00) | (((u32) >> 24) & 0xFF) )
+
+#define ENDIAN_BE16(le16) ((uint16_t) ((U16_LOW_U8(le16) << 8) | U16_HIGH_U8(le16)) )
+
+#ifndef __n2be_16
+#define __n2be_16(u16) ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) )
+#define __be2n_16(u16) __n2be_16(u16)
+#endif
+
+
+// for declaration of reserved field, make use of _TU_COUNTER_
+#define TU_RESERVED XSTRING_CONCAT_(reserved, _TU_COUNTER_)
+
+/*------------------------------------------------------------------*/
+/* Count number of arguments of __VA_ARGS__
+ * - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s
+ * - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
+ * - _RSEQ_N() is reverse sequential to N to add padding to have
+ * Nth position is the same as the number of arguments
+ * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
+ *------------------------------------------------------------------*/
+#ifndef VA_ARGS_NUM_
+
+#define VA_ARGS_NUM_(...) NARG_(_0, ##__VA_ARGS__,_RSEQ_N())
+#define NARG_(...) _GET_NTH_ARG(__VA_ARGS__)
+#define _GET_NTH_ARG( \
+ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
+ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
+ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
+ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
+ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
+ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
+ _61,_62,_63,N,...) N
+#define _RSEQ_N() \
+ 62,61,60, \
+ 59,58,57,56,55,54,53,52,51,50, \
+ 49,48,47,46,45,44,43,42,41,40, \
+ 39,38,37,36,35,34,33,32,31,30, \
+ 29,28,27,26,25,24,23,22,21,20, \
+ 19,18,17,16,15,14,13,12,11,10, \
+ 9,8,7,6,5,4,3,2,1,0
+#endif
+
+//--------------------------------------------------------------------+
+// INLINE FUNCTION
+//--------------------------------------------------------------------+
+#define tu_memclr(buffer, size) memset((buffer), 0, (size))
+#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
+
+static inline bool tu_mem_test_zero (void const* buffer, uint32_t size)
+{
+ uint8_t const* p_mem = (uint8_t const*) buffer;
+ for(uint32_t i=0; i<size; i++) if (p_mem[i] != 0) return false;
+ return true;
+}
+
+
+//------------- Conversion -------------//
+static inline uint32_t tu_u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
+{
+ return ( ((uint32_t) b1) << 24) + ( ((uint32_t) b2) << 16) + ( ((uint32_t) b3) << 8) + b4;
+}
+
+static inline uint8_t tu_u16_high(uint16_t u16)
+{
+ return (uint8_t) ( ((uint16_t) (u16 >> 8)) & 0x00ff);
+}
+
+static inline uint8_t tu_u16_low(uint16_t u16)
+{
+ return (uint8_t) (u16 & 0x00ff);
+}
+
+static inline uint16_t tu_u16_le2be(uint16_t u16)
+{
+ return ((uint16_t)(tu_u16_low(u16) << 8)) | tu_u16_high(u16);
+}
+
+//------------- Min -------------//
+static inline uint8_t tu_min8(uint8_t x, uint8_t y)
+{
+ return (x < y) ? x : y;
+}
+
+static inline uint16_t tu_min16(uint16_t x, uint16_t y)
+{
+ return (x < y) ? x : y;
+}
+
+static inline uint32_t tu_min32(uint32_t x, uint32_t y)
+{
+ return (x < y) ? x : y;
+}
+
+//------------- Max -------------//
+static inline uint32_t tu_max32(uint32_t x, uint32_t y)
+{
+ return (x > y) ? x : y;
+}
+
+//------------- Align -------------//
+static inline uint32_t tu_align32 (uint32_t value)
+{
+ return (value & 0xFFFFFFE0UL);
+}
+
+static inline uint32_t tu_align16 (uint32_t value)
+{
+ return (value & 0xFFFFFFF0UL);
+}
+
+static inline uint32_t tu_align_n (uint32_t alignment, uint32_t value)
+{
+ return value & ((uint32_t) ~(alignment-1));
+}
+
+static inline uint32_t tu_align4k (uint32_t value)
+{
+ return (value & 0xFFFFF000UL);
+}
+
+static inline uint32_t tu_offset4k(uint32_t value)
+{
+ return (value & 0xFFFUL);
+}
+
+//------------- Mathematics -------------//
+static inline uint32_t tu_abs(int32_t value)
+{
+ return (value < 0) ? (-value) : value;
+}
+
+
+/// inclusive range checking
+static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper)
+{
+ return (lower <= value) && (value <= upper);
+}
+
+// TODO use clz
+static inline uint8_t tu_log2(uint32_t value)
+{
+ uint8_t result = 0; // log2 of a value is its MSB's position
+
+ while (value >>= 1)
+ {
+ result++;
+ }
+ return result;
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_COMMON_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_compiler.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_compiler.h new file mode 100755 index 0000000..933d760 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_compiler.h @@ -0,0 +1,83 @@ +/**************************************************************************/
+/*!
+ @file compiler.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Common
+ * \defgroup Group_Compiler Compiler
+ * \brief Group_Compiler brief
+ * @{ */
+
+#ifndef _TUSB_COMPILER_H_
+#define _TUSB_COMPILER_H_
+
+#define STRING_(x) #x ///< stringify without expand
+#define XSTRING_(x) STRING_(x) ///< expand then stringify
+#define STRING_CONCAT_(a, b) a##b ///< concat without expand
+#define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) ///< expand then concat
+
+#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
+ #define _TU_COUNTER_ __COUNTER__
+#else
+ #define _TU_COUNTER_ __LINE__
+#endif
+
+//--------------------------------------------------------------------+
+// Compile-time Assert (use TU_VERIFY_STATIC to avoid name conflict)
+//--------------------------------------------------------------------+
+#if __STDC_VERSION__ >= 201112L
+ #define TU_VERIFY_STATIC _Static_assert
+#else
+ #define TU_VERIFY_STATIC(const_expr, _mess) enum { XSTRING_CONCAT_(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
+#endif
+
+// allow debugger to watch any module-wide variables anywhere
+#if CFG_TUSB_DEBUG
+#define STATIC_VAR
+#else
+#define STATIC_VAR static
+#endif
+
+
+#if defined(__GNUC__)
+ #include "compiler/tusb_compiler_gcc.h"
+#elif defined __ICCARM__
+ #include "compiler/tusb_compiler_iar.h"
+#endif
+
+#endif /* _TUSB_COMPILER_H_ */
+
+/// @}
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_error.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_error.h new file mode 100755 index 0000000..677fc44 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_error.h @@ -0,0 +1,117 @@ +/**************************************************************************/
+/*!
+ @file tusb_error.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Common
+ * \defgroup Group_Error Error Codes
+ * @{ */
+
+#ifndef _TUSB_ERRORS_H_
+#define _TUSB_ERRORS_H_
+
+#include "tusb_option.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define ERROR_ENUM(x) x,
+#define ERROR_STRING(x) #x,
+
+#define ERROR_TABLE(ENTRY) \
+ ENTRY(TUSB_ERROR_NONE )\
+ ENTRY(TUSB_ERROR_INVALID_PARA )\
+ ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\
+ ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\
+ ENTRY(TUSB_ERROR_HCD_FAILED )\
+ ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\
+ ENTRY(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND )\
+ ENTRY(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG )\
+ ENTRY(TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED )\
+ ENTRY(TUSB_ERROR_USBH_XFER_STALLED )\
+ ENTRY(TUSB_ERROR_USBH_XFER_FAILED )\
+ ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\
+ ENTRY(TUSB_ERROR_OSAL_WAITING ) /* only used by OSAL_NONE in the subtask */ \
+ ENTRY(TUSB_ERROR_OSAL_TASK_FAILED )\
+ ENTRY(TUSB_ERROR_OSAL_QUEUE_FAILED )\
+ ENTRY(TUSB_ERROR_OSAL_SEMAPHORE_FAILED )\
+ ENTRY(TUSB_ERROR_OSAL_MUTEX_FAILED )\
+ ENTRY(TUSB_ERROR_EHCI_NOT_ENOUGH_QTD )\
+ ENTRY(TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE )\
+ ENTRY(TUSB_ERROR_HIDH_NOT_SUPPORTED_PROTOCOL )\
+ ENTRY(TUSB_ERROR_HIDH_NOT_SUPPORTED_SUBCLASS )\
+ ENTRY(TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS )\
+ ENTRY(TUSB_ERROR_CDC_UNSUPPORTED_PROTOCOL )\
+ ENTRY(TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED )\
+ ENTRY(TUSB_ERROR_MSC_UNSUPPORTED_PROTOCOL )\
+ ENTRY(TUSB_ERROR_MSCH_UNKNOWN_SCSI_COMMAND )\
+ ENTRY(TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED )\
+ ENTRY(TUSB_ERROR_HUB_FEATURE_NOT_SUPPORTED )\
+ ENTRY(TUSB_ERROR_DESCRIPTOR_CORRUPTED )\
+ ENTRY(TUSB_ERROR_DCD_FAILED )\
+ ENTRY(TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT )\
+ ENTRY(TUSB_ERROR_DCD_NOT_ENOUGH_QTD )\
+ ENTRY(TUSB_ERROR_DCD_OPEN_PIPE_FAILED )\
+ ENTRY(TUSB_ERROR_DCD_EDPT_XFER )\
+ ENTRY(TUSB_ERROR_NOT_SUPPORTED_YET )\
+ ENTRY(TUSB_ERROR_USBD_DEVICE_NOT_CONFIGURED )\
+ ENTRY(TUSB_ERROR_NOT_ENOUGH_MEMORY )\
+ ENTRY(TUSB_ERROR_FAILED )\
+ \
+ ENTRY(ERR_TUD_INVALID_DESCRIPTOR) \
+ ENTRY(ERR_TUD_EDPT_OPEN_FAILED) \
+
+
+/// \brief Error Code returned
+typedef enum
+{
+ ERROR_TABLE(ERROR_ENUM)
+ TUSB_ERROR_COUNT
+}tusb_error_t;
+
+#if CFG_TUSB_DEBUG
+/// Enum to String for debugging purposes. Only available if \ref CFG_TUSB_DEBUG > 0
+extern char const* const tusb_strerr[TUSB_ERROR_COUNT];
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_ERRORS_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_fifo.c b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_fifo.c new file mode 100755 index 0000000..e0b3d0a --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_fifo.c @@ -0,0 +1,289 @@ +/**************************************************************************/
+/*!
+ @file tusb_fifo.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+ */
+/**************************************************************************/
+
+#include <string.h>
+
+#include "osal/osal.h"
+#include "tusb_fifo.h"
+
+// implement mutex lock and unlock
+// For OSAL_NONE: if mutex is locked by other, function return immediately (since there is no task context)
+// For Real RTOS: fifo lock is a blocking API
+#if CFG_FIFO_MUTEX
+
+static bool tu_fifo_lock(tu_fifo_t *f)
+{
+ if (f->mutex)
+ {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ // There is no subtask context for blocking mutex, we will check and return if cannot lock the mutex
+ if ( !osal_mutex_lock_notask(f->mutex) ) return false;
+#else
+ uint32_t err;
+ (void) err;
+ osal_mutex_lock(f->mutex, OSAL_TIMEOUT_WAIT_FOREVER, &err);
+#endif
+ }
+
+ return true;
+}
+
+static void tu_fifo_unlock(tu_fifo_t *f)
+{
+ if (f->mutex)
+ {
+ osal_mutex_unlock(f->mutex);
+ }
+}
+
+#else
+
+#define tu_fifo_lock(_ff) true
+#define tu_fifo_unlock(_ff)
+
+#endif
+
+bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable)
+{
+ if ( !tu_fifo_lock(f) ) return false;
+
+ f->buffer = (uint8_t*) buffer;
+ f->depth = depth;
+ f->item_size = item_size;
+ f->overwritable = overwritable;
+
+ f->rd_idx = f->wr_idx = f->count = 0;
+
+ tu_fifo_unlock(f);
+
+ return true;
+}
+
+
+/******************************************************************************/
+/*!
+ @brief Read one byte out of the RX buffer.
+
+ This function will return the byte located at the array index of the
+ read pointer, and then increment the read pointer index. If the read
+ pointer exceeds the maximum buffer size, it will roll over to zero.
+
+ @param[in] f
+ Pointer to the FIFO buffer to manipulate
+ @param[in] p_buffer
+ Pointer to the place holder for data read from the buffer
+
+ @returns TRUE if the queue is not empty
+*/
+/******************************************************************************/
+bool tu_fifo_read(tu_fifo_t* f, void * p_buffer)
+{
+ if( tu_fifo_empty(f) ) return false;
+
+ if ( !tu_fifo_lock(f) ) return false;
+
+ memcpy(p_buffer,
+ f->buffer + (f->rd_idx * f->item_size),
+ f->item_size);
+ f->rd_idx = (f->rd_idx + 1) % f->depth;
+ f->count--;
+
+ tu_fifo_unlock(f);
+
+ return true;
+}
+
+/******************************************************************************/
+/*!
+ @brief This function will read n elements into the array index specified by
+ the write pointer and increment the write index. If the write index
+ exceeds the max buffer size, then it will roll over to zero.
+
+ @param[in] f
+ Pointer to the FIFO buffer to manipulate
+ @param[in] p_data
+ The pointer to data location
+ @param[in] count
+ Number of element that buffer can afford
+
+ @returns number of items read from the FIFO
+*/
+/******************************************************************************/
+uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t count)
+{
+ if( tu_fifo_empty(f) ) return 0;
+
+ /* Limit up to fifo's count */
+ if ( count > f->count ) count = f->count;
+
+ /* Could copy up to 2 portions marked as 'x' if queue is wrapped around
+ * case 1: ....RxxxxW.......
+ * case 2: xxxxxW....Rxxxxxx
+ */
+// uint16_t index2upper = tu_min16(count, f->count-f->rd_idx);
+
+ uint8_t* p_buf = (uint8_t*) p_buffer;
+ uint16_t len = 0;
+ while( (len < count) && tu_fifo_read(f, p_buf) )
+ {
+ len++;
+ p_buf += f->item_size;
+ }
+
+ return len;
+}
+
+/******************************************************************************/
+/*!
+ @brief Reads one item without removing it from the FIFO
+
+ @param[in] f
+ Pointer to the FIFO buffer to manipulate
+ @param[in] pos
+ Position to read from in the FIFO buffer
+ @param[in] p_buffer
+ Pointer to the place holder for data read from the buffer
+
+ @returns TRUE if the queue is not empty
+*/
+/******************************************************************************/
+bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t pos, void * p_buffer)
+{
+ if ( pos >= f->count ) return false;
+
+ // rd_idx is pos=0
+ uint16_t index = (f->rd_idx + pos) % f->depth;
+ memcpy(p_buffer,
+ f->buffer + (index * f->item_size),
+ f->item_size);
+
+ return true;
+}
+
+/******************************************************************************/
+/*!
+ @brief Write one element into the RX buffer.
+
+ This function will write one element into the array index specified by
+ the write pointer and increment the write index. If the write index
+ exceeds the max buffer size, then it will roll over to zero.
+
+ @param[in] f
+ Pointer to the FIFO buffer to manipulate
+ @param[in] p_data
+ The byte to add to the FIFO
+
+ @returns TRUE if the data was written to the FIFO (overwrittable
+ FIFO will always return TRUE)
+*/
+/******************************************************************************/
+bool tu_fifo_write (tu_fifo_t* f, const void * p_data)
+{
+ if ( tu_fifo_full(f) && !f->overwritable ) return false;
+
+ if ( !tu_fifo_lock(f) ) return false;
+
+ memcpy( f->buffer + (f->wr_idx * f->item_size),
+ p_data,
+ f->item_size);
+
+ f->wr_idx = (f->wr_idx + 1) % f->depth;
+
+ if (tu_fifo_full(f))
+ {
+ f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size)
+ }
+ else
+ {
+ f->count++;
+ }
+
+ tu_fifo_unlock(f);
+
+ return true;
+}
+
+/******************************************************************************/
+/*!
+ @brief This function will write n elements into the array index specified by
+ the write pointer and increment the write index. If the write index
+ exceeds the max buffer size, then it will roll over to zero.
+
+ @param[in] f
+ Pointer to the FIFO buffer to manipulate
+ @param[in] p_data
+ The pointer to data to add to the FIFO
+ @param[in] count
+ Number of element
+ @return Number of written elements
+*/
+/******************************************************************************/
+uint16_t tu_fifo_write_n (tu_fifo_t* f, const void * p_data, uint16_t count)
+{
+ if ( count == 0 ) return 0;
+
+ uint8_t const* p_buf = (uint8_t const*) p_data;
+
+ uint16_t len = 0;
+ while( (len < count) && tu_fifo_write(f, p_buf) )
+ {
+ len++;
+ p_buf += f->item_size;
+ }
+
+ return len;
+}
+
+/******************************************************************************/
+/*!
+ @brief Clear the fifo read and write pointers and set length to zero
+
+ @param[in] f
+ Pointer to the FIFO buffer to manipulate
+*/
+/******************************************************************************/
+bool tu_fifo_clear(tu_fifo_t *f)
+{
+ if ( !tu_fifo_lock(f) ) return false;
+
+ f->rd_idx = f->wr_idx = f->count = 0;
+
+ tu_fifo_unlock(f);
+
+ return true;
+}
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_fifo.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_fifo.h new file mode 100755 index 0000000..70dc087 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_fifo.h @@ -0,0 +1,142 @@ +/**************************************************************************/
+/*!
+ @file tusb_fifo.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Common
+ * \defgroup group_fifo fifo
+ * @{ */
+
+#ifndef _TUSB_FIFO_H_
+#define _TUSB_FIFO_H_
+
+#define CFG_FIFO_MUTEX 1
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if CFG_FIFO_MUTEX
+#define tu_fifo_mutex_t osal_mutex_t
+#endif
+
+
+/** \struct tu_fifo_t
+ * \brief Simple Circular FIFO
+ */
+typedef struct
+{
+ uint8_t* buffer ; ///< buffer pointer
+ uint16_t depth ; ///< max items
+ uint16_t item_size ; ///< size of each item
+
+ volatile uint16_t count ; ///< number of items in queue
+ volatile uint16_t wr_idx ; ///< write pointer
+ volatile uint16_t rd_idx ; ///< read pointer
+
+ bool overwritable ;
+
+#if CFG_FIFO_MUTEX
+ tu_fifo_mutex_t mutex;
+#endif
+
+} tu_fifo_t;
+
+#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
+ uint8_t _name##_buf[_depth*sizeof(_type)]; \
+ tu_fifo_t _name = { \
+ .buffer = _name##_buf, \
+ .depth = _depth, \
+ .item_size = sizeof(_type), \
+ .overwritable = _overwritable, \
+ }
+
+bool tu_fifo_clear(tu_fifo_t *f);
+bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
+
+#if CFG_FIFO_MUTEX
+static inline void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t mutex_hdl)
+{
+ f->mutex = mutex_hdl;
+}
+#endif
+
+bool tu_fifo_write (tu_fifo_t* f, void const * p_data);
+uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t count);
+
+bool tu_fifo_read (tu_fifo_t* f, void * p_buffer);
+uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t count);
+
+bool tu_fifo_peek_at (tu_fifo_t* f, uint16_t pos, void * p_buffer);
+
+static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer)
+{
+ return tu_fifo_peek_at(f, 0, p_buffer);
+}
+
+static inline bool tu_fifo_empty(tu_fifo_t* f)
+{
+ return (f->count == 0);
+}
+
+static inline bool tu_fifo_full(tu_fifo_t* f)
+{
+ return (f->count == f->depth);
+}
+
+static inline uint16_t tu_fifo_count(tu_fifo_t* f)
+{
+ return f->count;
+}
+
+static inline uint16_t tu_fifo_remaining(tu_fifo_t* f)
+{
+ return f->depth - f->count;
+}
+
+static inline uint16_t tu_fifo_depth(tu_fifo_t* f)
+{
+ return f->depth;
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_FIFO_H_ */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_timeout.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_timeout.h new file mode 100755 index 0000000..9d80f5f --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_timeout.h @@ -0,0 +1,98 @@ +/**************************************************************************/
+/*!
+ @file tusb_timeout.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup Group_Common Common Files
+ * \defgroup Group_TimeoutTimer timeout timer
+ * @{ */
+
+
+#ifndef _TUSB_TIMEOUT_H_
+#define _TUSB_TIMEOUT_H_
+
+#include "tusb_compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t start;
+ uint32_t interval;
+}tu_timeout_t;
+
+extern uint32_t tusb_hal_millis(void);
+
+static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec)
+{
+ tt->interval = msec;
+ tt->start = tusb_hal_millis();
+}
+
+static inline bool tu_timeout_expired(tu_timeout_t* tt)
+{
+ return ( tusb_hal_millis() - tt->start ) >= tt->interval;
+}
+
+// For used with periodic event to prevent drift
+static inline void tu_timeout_reset(tu_timeout_t* tt)
+{
+ tt->start += tt->interval;
+}
+
+static inline void tu_timeout_restart(tu_timeout_t* tt)
+{
+ tt->start = tusb_hal_millis();
+}
+
+
+static inline void tu_timeout_wait(uint32_t msec)
+{
+ tu_timeout_t tt;
+ tu_timeout_set(&tt, msec);
+
+ // blocking delay
+ while ( !tu_timeout_expired(&tt) ) { }
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_TIMEOUT_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_types.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_types.h new file mode 100755 index 0000000..8ce334e --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_types.h @@ -0,0 +1,431 @@ +/**************************************************************************/
+/*!
+ @file tusb_types.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_usb_definitions
+ * \defgroup USBDef_Type USB Types
+ * @{ */
+
+#ifndef _TUSB_TYPES_H_
+#define _TUSB_TYPES_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "tusb_compiler.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*------------------------------------------------------------------*/
+/* CONSTANTS
+ *------------------------------------------------------------------*/
+
+/// defined base on EHCI specs value for Endpoint Speed
+typedef enum
+{
+ TUSB_SPEED_FULL = 0,
+ TUSB_SPEED_LOW ,
+ TUSB_SPEED_HIGH
+}tusb_speed_t;
+
+/// defined base on USB Specs Endpoint's bmAttributes
+typedef enum
+{
+ TUSB_XFER_CONTROL = 0 ,
+ TUSB_XFER_ISOCHRONOUS ,
+ TUSB_XFER_BULK ,
+ TUSB_XFER_INTERRUPT
+}tusb_xfer_type_t;
+
+typedef enum
+{
+ TUSB_DIR_OUT = 0,
+ TUSB_DIR_IN = 1,
+
+ TUSB_DIR_IN_MASK = 0x80
+}tusb_dir_t;
+
+
+/// USB Descriptor Types (section 9.4 table 9-5)
+typedef enum
+{
+ TUSB_DESC_DEVICE = 0x01 ,
+ TUSB_DESC_CONFIGURATION = 0x02 ,
+ TUSB_DESC_STRING = 0x03 ,
+ TUSB_DESC_INTERFACE = 0x04 ,
+ TUSB_DESC_ENDPOINT = 0x05 ,
+ TUSB_DESC_DEVICE_QUALIFIER = 0x06 ,
+ TUSB_DESC_OTHER_SPEED_CONFIG = 0x07 ,
+ TUSB_DESC_INTERFACE_POWER = 0x08 ,
+ TUSB_DESC_OTG = 0x09 ,
+ TUSB_DESC_DEBUG = 0x0A ,
+ TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B ,
+ TUSB_DESC_CLASS_SPECIFIC = 0x24
+}tusb_desc_type_t;
+
+typedef enum
+{
+ TUSB_REQ_GET_STATUS =0 , ///< 0
+ TUSB_REQ_CLEAR_FEATURE , ///< 1
+ TUSB_REQ_RESERVED , ///< 2
+ TUSB_REQ_SET_FEATURE , ///< 3
+ TUSB_REQ_RESERVED2 , ///< 4
+ TUSB_REQ_SET_ADDRESS , ///< 5
+ TUSB_REQ_GET_DESCRIPTOR , ///< 6
+ TUSB_REQ_SET_DESCRIPTOR , ///< 7
+ TUSB_REQ_GET_CONFIGURATION , ///< 8
+ TUSB_REQ_SET_CONFIGURATION , ///< 9
+ TUSB_REQ_GET_INTERFACE , ///< 10
+ TUSB_REQ_SET_INTERFACE , ///< 11
+ TUSB_REQ_SYNCH_FRAME ///< 12
+}tusb_request_code_t;
+
+typedef enum
+{
+ TUSB_REQ_TYPE_STANDARD = 0,
+ TUSB_REQ_TYPE_CLASS,
+ TUSB_REQ_TYPE_VENDOR
+} tusb_request_type_t;
+
+typedef enum
+{
+ TUSB_REQ_RCPT_DEVICE =0,
+ TUSB_REQ_RCPT_INTERFACE,
+ TUSB_REQ_RCPT_ENDPOINT,
+ TUSB_REQ_RCPT_OTHER
+} tusb_request_recipient_t;
+
+typedef enum
+{
+ TUSB_CLASS_UNSPECIFIED = 0 , ///< 0
+ TUSB_CLASS_AUDIO = 1 , ///< 1
+ TUSB_CLASS_CDC = 2 , ///< 2
+ TUSB_CLASS_HID = 3 , ///< 3
+ TUSB_CLASS_RESERVED_4 = 4 , ///< 4
+ TUSB_CLASS_PHYSICAL = 5 , ///< 5
+ TUSB_CLASS_IMAGE = 6 , ///< 6
+ TUSB_CLASS_PRINTER = 7 , ///< 7
+ TUSB_CLASS_MSC = 8 , ///< 8
+ TUSB_CLASS_HUB = 9 , ///< 9
+ TUSB_CLASS_CDC_DATA = 10 , ///< 10
+ TUSB_CLASS_SMART_CARD = 11 , ///< 11
+ TUSB_CLASS_RESERVED_12 = 12 , ///< 12
+ TUSB_CLASS_CONTENT_SECURITY = 13 , ///< 13
+ TUSB_CLASS_VIDEO = 14 , ///< 14
+ TUSB_CLASS_PERSONAL_HEALTHCARE = 15 , ///< 15
+ TUSB_CLASS_AUDIO_VIDEO = 16 , ///< 16
+
+ TUSB_CLASS_MAPPED_INDEX_START = 17 , // TODO Map DIAGNOSTIC, WIRELESS_CONTROLLER, MISC, VENDOR_SPECIFIC to this to minimize the array
+
+ TUSB_CLASS_DIAGNOSTIC = 0xDC ,
+ TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0 ,
+ TUSB_CLASS_MISC = 0xEF ,
+ TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE ,
+ TUSB_CLASS_VENDOR_SPECIFIC = 0xFF
+}tusb_class_code_t;
+
+typedef enum
+{
+ MISC_SUBCLASS_COMMON = 2
+}misc_subclass_type_t;
+
+typedef enum
+{
+ MISC_PROTOCOL_IAD = 1
+}misc_protocol_type_t;
+
+enum {
+ TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = BIT_(5),
+ TUSB_DESC_CONFIG_ATT_SELF_POWER = BIT_(6),
+ TUSB_DESC_CONFIG_ATT_BUS_POWER = BIT_(7)
+};
+
+#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2)
+
+/// Device State
+typedef enum
+{
+ TUSB_DEVICE_STATE_UNPLUG = 0 ,
+ TUSB_DEVICE_STATE_ADDRESSED ,
+ TUSB_DEVICE_STATE_CONFIGURED ,
+ TUSB_DEVICE_STATE_SUSPENDED ,
+
+ TUSB_DEVICE_STATE_REMOVING ,
+ TUSB_DEVICE_STATE_SAFE_REMOVE ,
+
+ TUSB_DEVICE_STATE_INVALID_PARAMETER
+}tusb_device_state_t;
+
+typedef enum
+{
+ TUSB_EVENT_NONE = 0,
+ TUSB_EVENT_XFER_COMPLETE,
+ TUSB_EVENT_XFER_ERROR,
+ TUSB_EVENT_XFER_STALLED,
+}tusb_event_t;
+
+enum {
+ DESC_OFFSET_LEN = 0,
+ DESC_OFFSET_TYPE = 1
+};
+
+enum {
+ INTERFACE_INVALID_NUMBER = 0xff
+};
+
+//--------------------------------------------------------------------+
+// STANDARD DESCRIPTORS
+//--------------------------------------------------------------------+
+
+/// USB Standard Device Descriptor (section 9.6.1, table 9-8)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< DEVICE Descriptor Type.
+ uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant.
+
+ uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific.
+ uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
+ uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis.
+ uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64.
+
+ uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF).
+ uint16_t idProduct ; ///< Product ID (assigned by the manufacturer).
+ uint16_t bcdDevice ; ///< Device release number in binary-coded decimal.
+ uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer.
+ uint8_t iProduct ; ///< Index of string descriptor describing product.
+ uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number.
+
+ uint8_t bNumConfigurations ; ///< Number of possible configurations.
+} tusb_desc_device_t;
+
+/// USB Standard Configuration Descriptor (section 9.6.1 table 9-10) */
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes
+ uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
+ uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration.
+
+ uint8_t bNumInterfaces ; ///< Number of interfaces supported by this configuration
+ uint8_t bConfigurationValue ; ///< Value to use as an argument to the SetConfiguration() request to select this configuration.
+ uint8_t iConfiguration ; ///< Index of string descriptor describing this configuration
+ uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one.
+ uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA).
+} tusb_desc_configuration_t;
+
+/// USB Standard Interface Descriptor (section 9.6.1 table 9-12)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes
+ uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type
+
+ uint8_t bInterfaceNumber ; ///< Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration.
+ uint8_t bAlternateSetting ; ///< Value used to select this alternate setting for the interface identified in the prior field
+ uint8_t bNumEndpoints ; ///< Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe.
+ uint8_t bInterfaceClass ; ///< Class code (assigned by the USB-IF). \li A value of zero is reserved for future standardization. \li If this field is set to FFH, the interface class is vendor-specific. \li All other values are reserved for assignment by the USB-IF.
+ uint8_t bInterfaceSubClass ; ///< Subclass code (assigned by the USB-IF). \n These codes are qualified by the value of the bInterfaceClass field. \li If the bInterfaceClass field is reset to zero, this field must also be reset to zero. \li If the bInterfaceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
+ uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface.
+ uint8_t iInterface ; ///< Index of string descriptor describing this interface
+} tusb_desc_interface_t;
+
+/// USB Standard Endpoint Descriptor (section 9.6.1 table 9-13)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes
+ uint8_t bDescriptorType ; ///< ENDPOINT Descriptor Type
+
+ uint8_t bEndpointAddress ; ///< The address of the endpoint on the USB device described by this descriptor. The address is encoded as follows: \n Bit 3...0: The endpoint number \n Bit 6...4: Reserved, reset to zero \n Bit 7: Direction, ignored for control endpoints 0 = OUT endpoint 1 = IN endpoint.
+
+ struct ATTR_PACKED {
+ uint8_t xfer : 2;
+ uint8_t sync : 2;
+ uint8_t usage : 2;
+ uint8_t : 2;
+ } bmAttributes ; ///< This field describes the endpoint's attributes when it is configured using the bConfigurationValue. \n Bits 1..0: Transfer Type \n- 00 = Control \n- 01 = Isochronous \n- 10 = Bulk \n- 11 = Interrupt \n If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: \n Bits 3..2: Synchronization Type \n- 00 = No Synchronization \n- 01 = Asynchronous \n- 10 = Adaptive \n- 11 = Synchronous \n Bits 5..4: Usage Type \n- 00 = Data endpoint \n- 01 = Feedback endpoint \n- 10 = Implicit feedback Data endpoint \n- 11 = Reserved \n Refer to Chapter 5 of USB 2.0 specification for more information. \n All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host.
+
+ struct ATTR_PACKED {
+ uint16_t size : 11; ///< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. \n For isochronous endpoints, this value is used to reserve the bus time in the schedule, required for the per-(micro)frame data payloads. The pipe may, on an ongoing basis, actually use less bandwidth than that reserved. The device reports, if necessary, the actual bandwidth used via its normal, non-USB defined mechanisms. \n For all endpoints, bits 10..0 specify the maximum packet size (in bytes). \n For high-speed isochronous and interrupt endpoints: \n Bits 12..11 specify the number of additional transaction opportunities per microframe: \n- 00 = None (1 transaction per microframe) \n- 01 = 1 additional (2 per microframe) \n- 10 = 2 additional (3 per microframe) \n- 11 = Reserved \n Bits 15..13 are reserved and must be set to zero.
+ uint16_t hs_period_mult : 2;
+ uint16_t : 0;
+ }wMaxPacketSize;
+
+ uint8_t bInterval ; ///< Interval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 us units). \n- For full-/high-speed isochronous endpoints, this value must be in the range from 1 to 16. The bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). \n- For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255. \n- For high-speed interrupt endpoints, the bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value must be from 1 to 16. \n- For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255. \n Refer to Chapter 5 of USB 2.0 specification for more information.
+} tusb_desc_endpoint_t;
+
+/// USB Other Speed Configuration Descriptor (section 9.6.1 table 9-11)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of descriptor
+ uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
+ uint16_t wTotalLength ; ///< Total length of data returned
+
+ uint8_t bNumInterfaces ; ///< Number of interfaces supported by this speed configuration
+ uint8_t bConfigurationValue ; ///< Value to use to select configuration
+ uint8_t IConfiguration ; ///< Index of string descriptor
+ uint8_t bmAttributes ; ///< Same as Configuration descriptor
+ uint8_t bMaxPower ; ///< Same as Configuration descriptor
+} tusb_desc_other_speed_t;
+
+/// USB Device Qualifier Descriptor (section 9.6.1 table 9-9)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of descriptor
+ uint8_t bDescriptorType ; ///< Device Qualifier Type
+ uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00)
+
+ uint8_t bDeviceClass ; ///< Class Code
+ uint8_t bDeviceSubClass ; ///< SubClass Code
+ uint8_t bDeviceProtocol ; ///< Protocol Code
+ uint8_t bMaxPacketSize0 ; ///< Maximum packet size for other speed
+ uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations
+ uint8_t bReserved ; ///< Reserved for future use, must be zero
+} tusb_desc_device_qualifier_t;
+
+/// USB Interface Association Descriptor (IAD ECN)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of descriptor
+ uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
+
+ uint8_t bFirstInterface ; ///< Index of the first associated interface.
+ uint8_t bInterfaceCount ; ///< Total number of associated interfaces.
+
+ uint8_t bFunctionClass ; ///< Interface class ID.
+ uint8_t bFunctionSubClass ; ///< Interface subclass ID.
+ uint8_t bFunctionProtocol ; ///< Interface protocol ID.
+
+ uint8_t iFunction ; ///< Index of the string descriptor describing the interface association.
+} tusb_desc_interface_assoc_t;
+
+/// USB Header Descriptor
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes
+ uint8_t bDescriptorType ; ///< Descriptor Type
+} tusb_desc_header_t;
+
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes
+ uint8_t bDescriptorType ; ///< Descriptor Type
+ uint16_t unicode_string[];
+} tusb_desc_string_t;
+
+
+/*------------------------------------------------------------------*/
+/* Types
+ *------------------------------------------------------------------*/
+typedef struct ATTR_PACKED{
+ union {
+ struct ATTR_PACKED {
+ uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
+ uint8_t type : 2; ///< Request type tusb_request_type_t.
+ uint8_t direction : 1; ///< Direction type. tusb_dir_t
+ } bmRequestType_bit;
+ uint8_t bmRequestType;
+ };
+
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} tusb_control_request_t;
+
+TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "mostly compiler option issue");
+
+// TODO move to somewhere suitable
+static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t recipient)
+{
+ return ((uint8_t) (direction << 7)) | ((uint8_t) (type << 5)) | (recipient);
+}
+
+//--------------------------------------------------------------------+
+// Endpoint helper
+//--------------------------------------------------------------------+
+
+// Get direction from Endpoint address
+static inline tusb_dir_t edpt_dir(uint8_t addr)
+{
+ return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+}
+
+// Get Endpoint number from address
+static inline uint8_t edpt_number(uint8_t addr)
+{
+ return addr & (~TUSB_DIR_IN_MASK);
+}
+
+static inline uint8_t edpt_addr(uint8_t num, tusb_dir_t dir)
+{
+ return num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0);
+}
+
+//--------------------------------------------------------------------+
+// Descriptor helper
+//--------------------------------------------------------------------+
+static inline uint8_t const * descriptor_next(uint8_t const p_desc[])
+{
+ return p_desc + p_desc[DESC_OFFSET_LEN];
+}
+
+static inline uint8_t descriptor_type(uint8_t const p_desc[])
+{
+ return p_desc[DESC_OFFSET_TYPE];
+}
+
+static inline uint8_t descriptor_len(uint8_t const p_desc[])
+{
+ return p_desc[DESC_OFFSET_LEN];
+}
+
+// Length of the string descriptors in bytes with slen characters
+#define TUD_DESC_STRLEN(_slen) (2*(_slen) + 2)
+
+// Header of string descriptors with len + string type
+#define TUD_DESC_STR_HEADER(_slen) ( (uint16_t) ( (TUSB_DESC_STRING << 8 ) | TUD_DESC_STRLEN(_slen)) )
+
+// Convert comma-separated string to descriptor unicode format
+#define TUD_DESC_STRCONV( ... ) (const uint16_t[]) { TUD_DESC_STR_HEADER(VA_ARGS_NUM_(__VA_ARGS__)), __VA_ARGS__ }
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_TYPES_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_verify.h b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_verify.h new file mode 100755 index 0000000..c22c53d --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/common/tusb_verify.h @@ -0,0 +1,186 @@ +/**************************************************************************/
+/*!
+ @file verify.h
+ @author hathach
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+#ifndef TUSB_VERIFY_H_
+#define TUSB_VERIFY_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "tusb_option.h"
+#include "tusb_compiler.h"
+
+/*------------------------------------------------------------------*/
+/* This file use an advanced macro technique to mimic the default parameter
+ * as C++ for the sake of code simplicity. Beware of a headache macro
+ * manipulation that you are told to stay away.
+ *
+ * e.g
+ *
+ * - TU_VERIFY( cond ) will return false if cond is false
+ * - TU_VERIFY( cond, err) will return err instead if cond is false
+ *------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+//--------------------------------------------------------------------+
+// TU_VERIFY Helper
+//--------------------------------------------------------------------+
+#if CFG_TUSB_DEBUG >= 1
+ #include <stdio.h>
+ #define _MESS_ERR(_err) printf("%s: %d: failed, error = %s\n", __func__, __LINE__, tusb_strerr[_err])
+ #define _MESS_FAILED() printf("%s: %d: failed\n", __func__, __LINE__)
+#else
+ #define _MESS_ERR(_err)
+ #define _MESS_FAILED()
+#endif
+
+// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
+#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
+
+#define TU_BREAKPOINT() \
+ do {\
+ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
+ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */\
+ } while(0)
+
+#else
+#define TU_BREAKPOINT()
+#endif
+
+/*------------------------------------------------------------------*/
+/* Macro Generator
+ *------------------------------------------------------------------*/
+
+// Helper to implement optional parameter for TU_VERIFY Macro family
+#define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
+#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
+
+/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/
+#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do { if ( !(_cond) ) { _handler; return _ret; } } while(0)
+
+/*------------- Generator for TU_VERIFY_ERR and TU_VERIFY_ERR_HDLR -------------*/
+#define TU_VERIFY_ERR_DEF2(_error, _handler) \
+ do { \
+ uint32_t _err = (uint32_t)(_error); \
+ if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _err; }\
+ } while(0)
+
+#define TU_VERIFY_ERR_DEF3(_error, _handler, _ret) \
+ do { \
+ uint32_t _err = (uint32_t)(_error); \
+ if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _ret; }\
+ } while(0)
+
+
+
+
+/*------------------------------------------------------------------*/
+/* TU_VERIFY
+ * - TU_VERIFY_1ARGS : return false if failed
+ * - TU_VERIFY_2ARGS : return provided value if failed
+ *------------------------------------------------------------------*/
+#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false)
+#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret)
+
+#define TU_VERIFY(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS)(__VA_ARGS__)
+
+
+/*------------------------------------------------------------------*/
+/* TU_VERIFY WITH HANDLER
+ * - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed
+ * - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed
+ *------------------------------------------------------------------*/
+#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false)
+#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret)
+
+#define TU_VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS)(__VA_ARGS__)
+
+
+/*------------------------------------------------------------------*/
+/* TU_VERIFY STATUS
+ * - TU_VERIFY_ERR_1ARGS : return status of condition if failed
+ * - TU_VERIFY_ERR_2ARGS : return provided status code if failed
+ *------------------------------------------------------------------*/
+#define TU_VERIFY_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, )
+#define TU_VERIFY_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, ,_ret)
+
+#define TU_VERIFY_ERR(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_ERR_2ARGS, TU_VERIFY_ERR_1ARGS)(__VA_ARGS__)
+
+/*------------------------------------------------------------------*/
+/* TU_VERIFY STATUS WITH HANDLER
+ * - TU_VERIFY_ERR_HDLR_2ARGS : execute handler, return status if failed
+ * - TU_VERIFY_ERR_HDLR_3ARGS : execute handler, return provided error if failed
+ *------------------------------------------------------------------*/
+#define TU_VERIFY_ERR_HDLR_2ARGS(_error, _handler) TU_VERIFY_ERR_DEF2(_error, _handler)
+#define TU_VERIFY_ERR_HDLR_3ARGS(_error, _handler, _ret) TU_VERIFY_ERR_DEF3(_error, _handler, _ret)
+
+#define TU_VERIFY_ERR_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_ERR_HDLR_3ARGS, TU_VERIFY_ERR_HDLR_2ARGS)(__VA_ARGS__)
+
+
+
+/*------------------------------------------------------------------*/
+/* ASSERT
+ * basically TU_VERIFY with TU_BREAKPOINT() as handler
+ * - 1 arg : return false if failed
+ * - 2 arg : return error if failed
+ *------------------------------------------------------------------*/
+#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false)
+#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret)
+
+#define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS)(__VA_ARGS__)
+
+/*------------------------------------------------------------------*/
+/* ASSERT Error
+ * basically TU_VERIFY Error with TU_BREAKPOINT() as handler
+ *------------------------------------------------------------------*/
+#define ASERT_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, TU_BREAKPOINT())
+#define ASERT_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, TU_BREAKPOINT(), _ret)
+
+#define TU_ASSERT_ERR(...) GET_3RD_ARG(__VA_ARGS__, ASERT_ERR_2ARGS, ASERT_ERR_1ARGS)(__VA_ARGS__)
+
+/*------------------------------------------------------------------*/
+/* ASSERT HDLR
+ *------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* TUSB_VERIFY_H_ */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/device/dcd.h b/arduino/cores/nRF5/usb/tinyusb/src/device/dcd.h new file mode 100755 index 0000000..87837df --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/device/dcd.h @@ -0,0 +1,179 @@ +/**************************************************************************/
+/*!
+ @file dcd.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_usbd
+ * \defgroup group_dcd Device Controller Driver (DCD)
+ * @{ */
+
+#ifndef _TUSB_DCD_H_
+#define _TUSB_DCD_H_
+
+#include "common/tusb_common.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+enum
+{
+ DCD_XFER_SUCCESS = 0,
+ DCD_XFER_FAILED,
+ DCD_XFER_STALLED
+};
+
+typedef enum
+{
+ DCD_EVENT_BUS_RESET = 1,
+ DCD_EVENT_UNPLUGGED,
+ DCD_EVENT_SOF,
+ DCD_EVENT_SUSPENDED,
+ DCD_EVENT_RESUME,
+
+ DCD_EVENT_SETUP_RECEIVED,
+ DCD_EVENT_XFER_COMPLETE,
+
+ USBD_EVT_FUNC_CALL
+} dcd_eventid_t;
+
+typedef struct ATTR_ALIGNED(4)
+{
+ uint8_t rhport;
+ uint8_t event_id;
+
+ union {
+ // USBD_EVT_SETUP_RECEIVED
+ tusb_control_request_t setup_received;
+
+ // USBD_EVT_XFER_COMPLETE
+ struct {
+ uint8_t ep_addr;
+ uint8_t result;
+ uint32_t len;
+ }xfer_complete;
+
+ // USBD_EVT_FUNC_CALL
+ struct {
+ void (*func) (void*);
+ void* param;
+ }func_call;
+ };
+} dcd_event_t;
+
+TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct");
+
+/*------------------------------------------------------------------*/
+/* Device API (Weak is optional)
+ *------------------------------------------------------------------*/
+bool dcd_init (uint8_t rhport);
+void dcd_set_address (uint8_t rhport, uint8_t dev_addr);
+void dcd_set_config (uint8_t rhport, uint8_t config_num);
+
+void dcd_connect (uint8_t rhport) ATTR_WEAK;
+void dcd_disconnect (uint8_t rhport) ATTR_WEAK;
+
+/*------------------------------------------------------------------*/
+/* Event Function
+ * Called by DCD to notify USBD
+ *------------------------------------------------------------------*/
+void dcd_event_handler(dcd_event_t const * event, bool in_isr);
+
+// helper to send bus signal event
+static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
+{
+ dcd_event_t event = { .rhport = 0, .event_id = eid, };
+ dcd_event_handler(&event, in_isr);
+}
+
+// helper to send setup received
+static inline void dcd_event_setup_recieved(uint8_t rhport, uint8_t const * setup, bool in_isr)
+{
+ dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_SETUP_RECEIVED };
+ memcpy(&event.setup_received, setup, 8);
+
+ dcd_event_handler(&event, true);
+}
+
+// helper to send transfer complete event
+static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
+{
+ dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_XFER_COMPLETE };
+
+ event.xfer_complete.ep_addr = ep_addr;
+ event.xfer_complete.len = xferred_bytes;
+ event.xfer_complete.result = result;
+
+ dcd_event_handler(&event, in_isr);
+}
+
+
+/*------------------------------------------------------------------*/
+/* Endpoint API
+ *------------------------------------------------------------------*/
+
+//------------- Non-control Endpoints -------------//
+bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
+bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr);
+
+void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
+void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
+bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr);
+
+//------------- Control Endpoint -------------//
+bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length);
+
+// Helper to send STATUS (zero length) packet
+// Note dir is value of direction bit in setup packet (i.e DATA stage direction)
+static inline bool dcd_control_status(uint8_t rhport, uint8_t dir)
+{
+ // status direction is reversed to one in the setup packet
+ return dcd_control_xfer(rhport, 1-dir, NULL, 0);
+}
+
+static inline void dcd_control_stall(uint8_t rhport)
+{
+ dcd_edpt_stall(rhport, 0);
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_DCD_H_ */
+
+/// @}
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/device/usbd.c b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd.c new file mode 100755 index 0000000..1c2fa5d --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd.c @@ -0,0 +1,633 @@ +/**************************************************************************/
+/*!
+ @file usbd.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED
+
+#define _TINY_USB_SOURCE_FILE_
+
+#include "tusb.h"
+#include "usbd.h"
+#include "device/usbd_pvt.h"
+
+#ifndef CFG_TUD_TASK_QUEUE_SZ
+#define CFG_TUD_TASK_QUEUE_SZ 16
+#endif
+
+#ifndef CFG_TUD_TASK_STACK_SZ
+#define CFG_TUD_TASK_STACK_SZ 150
+#endif
+
+#ifndef CFG_TUD_TASK_PRIO
+#define CFG_TUD_TASK_PRIO 0
+#endif
+
+
+//--------------------------------------------------------------------+
+// Device Data
+//--------------------------------------------------------------------+
+typedef struct {
+ uint8_t config_num;
+
+ // map interface number to driver (0xff is invalid)
+ uint8_t itf2drv[16];
+
+ // map endpoint to driver ( 0xff is invalid )
+ uint8_t ep2drv[2][8];
+}usbd_device_t;
+
+CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_CTRL_BUFSIZE];
+static usbd_device_t _usbd_dev;
+
+
+// Auto descriptor is enabled, descriptor set point to auto generated one
+#if CFG_TUD_DESC_AUTO
+extern tud_desc_set_t const _usbd_auto_desc_set;
+tud_desc_set_t const* usbd_desc_set = &_usbd_auto_desc_set;
+#else
+tud_desc_set_t const* usbd_desc_set = &tud_desc_set;
+#endif
+
+//--------------------------------------------------------------------+
+// Class Driver
+//--------------------------------------------------------------------+
+typedef struct {
+ uint8_t class_code;
+
+ void (* init ) (void);
+ tusb_error_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length);
+ tusb_error_t (* control_req_st ) (uint8_t rhport, tusb_control_request_t const *);
+ tusb_error_t (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, tusb_event_t, uint32_t);
+ void (* sof ) (uint8_t rhport);
+ void (* reset ) (uint8_t);
+} usbd_class_driver_t;
+
+static usbd_class_driver_t const usbd_class_drivers[] =
+{
+ #if CFG_TUD_CDC
+ {
+ .class_code = TUSB_CLASS_CDC,
+ .init = cdcd_init,
+ .open = cdcd_open,
+ .control_req_st = cdcd_control_request_st,
+ .xfer_cb = cdcd_xfer_cb,
+ .sof = NULL,
+ .reset = cdcd_reset
+ },
+ #endif
+
+ #if CFG_TUD_MSC
+ {
+ .class_code = TUSB_CLASS_MSC,
+ .init = mscd_init,
+ .open = mscd_open,
+ .control_req_st = mscd_control_request_st,
+ .xfer_cb = mscd_xfer_cb,
+ .sof = NULL,
+ .reset = mscd_reset
+ },
+ #endif
+
+
+ #if CFG_TUD_HID
+ {
+ .class_code = TUSB_CLASS_HID,
+ .init = hidd_init,
+ .open = hidd_open,
+ .control_req_st = hidd_control_request_st,
+ .xfer_cb = hidd_xfer_cb,
+ .sof = NULL,
+ .reset = hidd_reset
+ },
+ #endif
+
+ #if CFG_TUD_CUSTOM_CLASS
+ {
+ .class_code = TUSB_CLASS_VENDOR_SPECIFIC,
+ .init = cusd_init,
+ .open = cusd_open,
+ .control_req_st = cusd_control_request_st,
+ .xfer_cb = cusd_xfer_cb,
+ .sof = NULL,
+ .reset = cusd_reset
+ },
+ #endif
+};
+
+enum { USBD_CLASS_DRIVER_COUNT = sizeof(usbd_class_drivers) / sizeof(usbd_class_driver_t) };
+
+
+//--------------------------------------------------------------------+
+// DCD Event
+//--------------------------------------------------------------------+
+OSAL_TASK_DEF(_usbd_task_def, "usbd", usbd_task, CFG_TUD_TASK_PRIO, CFG_TUD_TASK_STACK_SZ);
+
+/*------------- event queue -------------*/
+OSAL_QUEUE_DEF(_usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t);
+static osal_queue_t _usbd_q;
+
+/*------------- control transfer semaphore -------------*/
+static osal_semaphore_def_t _usbd_sem_def;
+osal_semaphore_t _usbd_ctrl_sem;
+
+//--------------------------------------------------------------------+
+// INTERNAL FUNCTION
+//--------------------------------------------------------------------+
+static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id);
+static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number);
+static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * const p_request, uint8_t const ** pp_buffer);
+
+//--------------------------------------------------------------------+
+// APPLICATION API
+//--------------------------------------------------------------------+
+bool tud_mounted(void)
+{
+ return _usbd_dev.config_num > 0;
+}
+
+//--------------------------------------------------------------------+
+// IMPLEMENTATION
+//--------------------------------------------------------------------+
+static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request_t const * const p_request);
+static tusb_error_t usbd_main_st(void);
+
+tusb_error_t usbd_init (void)
+{
+ #if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE)
+ dcd_init(0);
+ #endif
+
+ #if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
+ dcd_init(1);
+ #endif
+
+ //------------- Task init -------------//
+ _usbd_q = osal_queue_create(&_usbd_qdef);
+ TU_VERIFY(_usbd_q, TUSB_ERROR_OSAL_QUEUE_FAILED);
+
+ _usbd_ctrl_sem = osal_semaphore_create(&_usbd_sem_def);
+ TU_VERIFY(_usbd_q, TUSB_ERROR_OSAL_SEMAPHORE_FAILED);
+
+ osal_task_create(&_usbd_task_def);
+
+ //------------- class init -------------//
+ for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) usbd_class_drivers[i].init();
+
+ return TUSB_ERROR_NONE;
+}
+
+static void usbd_reset(uint8_t rhport)
+{
+ tu_varclr(&_usbd_dev);
+ memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping
+ memset(_usbd_dev.ep2drv , 0xff, sizeof(_usbd_dev.ep2drv )); // invalid mapping
+
+ for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++)
+ {
+ if ( usbd_class_drivers[i].reset ) usbd_class_drivers[i].reset( rhport );
+ }
+}
+
+// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper
+// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with
+// forever loop cannot have any return at all.
+
+// Within tinyusb stack, all task's code must be placed in subtask to be able to support multiple RTOS
+// including none.
+void usbd_task( void* param)
+{
+ (void) param;
+
+ OSAL_TASK_BEGIN
+ usbd_main_st();
+ OSAL_TASK_END
+}
+
+static tusb_error_t usbd_main_st(void)
+{
+ static dcd_event_t event;
+
+ OSAL_SUBTASK_BEGIN
+
+ // Loop until there is no more events in the queue
+ while (1)
+ {
+ uint32_t err;
+
+ err = TUSB_ERROR_NONE;
+ tu_memclr(&event, sizeof(dcd_event_t));
+
+ osal_queue_receive(_usbd_q, &event, OSAL_TIMEOUT_WAIT_FOREVER, &err);
+
+ if ( DCD_EVENT_SETUP_RECEIVED == event.event_id )
+ {
+ STASK_INVOKE( proc_control_request_st(event.rhport, &event.setup_received), err );
+ }
+ else if (DCD_EVENT_XFER_COMPLETE == event.event_id)
+ {
+ // Invoke the class callback associated with the endpoint address
+ uint8_t const ep_addr = event.xfer_complete.ep_addr;
+ uint8_t const drv_id = _usbd_dev.ep2drv[ edpt_dir(ep_addr) ][ edpt_number(ep_addr) ];
+
+ if (drv_id < USBD_CLASS_DRIVER_COUNT)
+ {
+ usbd_class_drivers[drv_id].xfer_cb( event.rhport, ep_addr, (tusb_event_t) event.xfer_complete.result, event.xfer_complete.len);
+ }
+ }
+ else if (DCD_EVENT_BUS_RESET == event.event_id)
+ {
+ usbd_reset(event.rhport);
+ osal_queue_reset(_usbd_q);
+ osal_semaphore_reset(_usbd_ctrl_sem);
+ }
+ else if (DCD_EVENT_UNPLUGGED == event.event_id)
+ {
+ usbd_reset(event.rhport);
+ osal_queue_reset(_usbd_q);
+ osal_semaphore_reset(_usbd_ctrl_sem);
+
+ tud_umount_cb(); // invoke callback
+ }
+ else if (DCD_EVENT_SOF == event.event_id)
+ {
+ for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++)
+ {
+ if ( usbd_class_drivers[i].sof )
+ {
+ usbd_class_drivers[i].sof( event.rhport );
+ }
+ }
+ }
+ else if ( USBD_EVT_FUNC_CALL == event.event_id )
+ {
+ if ( event.func_call.func ) event.func_call.func(event.func_call.param);
+ }
+ else
+ {
+ TU_BREAKPOINT();
+ }
+ }
+
+ OSAL_SUBTASK_END
+}
+
+//--------------------------------------------------------------------+
+// CONTROL REQUEST
+//--------------------------------------------------------------------+
+static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request_t const * const p_request)
+{
+ OSAL_SUBTASK_BEGIN
+
+ ATTR_UNUSED tusb_error_t error;
+ error = TUSB_ERROR_NONE;
+
+ //------------- Standard Request e.g in enumeration -------------//
+ if( TUSB_REQ_RCPT_DEVICE == p_request->bmRequestType_bit.recipient &&
+ TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type )
+ {
+ if ( TUSB_REQ_GET_DESCRIPTOR == p_request->bRequest )
+ {
+ uint8_t const * buffer = NULL;
+ uint16_t const len = get_descriptor(rhport, p_request, &buffer);
+
+ if ( len )
+ {
+ STASK_ASSERT( len <= CFG_TUD_CTRL_BUFSIZE );
+ memcpy(_usbd_ctrl_buf, buffer, len);
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, len);
+ }else
+ {
+ dcd_control_stall(rhport); // stall unsupported descriptor
+ }
+ }
+ else if (TUSB_REQ_GET_CONFIGURATION == p_request->bRequest )
+ {
+ memcpy(_usbd_ctrl_buf, &_usbd_dev.config_num, 1);
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, 1);
+ }
+ else if ( TUSB_REQ_SET_ADDRESS == p_request->bRequest )
+ {
+ dcd_set_address(rhport, (uint8_t) p_request->wValue);
+
+ #if CFG_TUSB_MCU != OPT_MCU_NRF5X // nrf5x auto handle set address, we must not return status
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ #endif
+ }
+ else if ( TUSB_REQ_SET_CONFIGURATION == p_request->bRequest )
+ {
+ proc_set_config_req(rhport, (uint8_t) p_request->wValue);
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ }
+ else
+ {
+ dcd_control_stall(rhport); // Stall unsupported request
+ }
+ }
+
+ //------------- Class/Interface Specific Request -------------//
+ else if ( TUSB_REQ_RCPT_INTERFACE == p_request->bmRequestType_bit.recipient )
+ {
+ if (_usbd_dev.itf2drv[ tu_u16_low(p_request->wIndex) ] < USBD_CLASS_DRIVER_COUNT)
+ {
+ STASK_INVOKE( usbd_class_drivers[ _usbd_dev.itf2drv[ tu_u16_low(p_request->wIndex) ] ].control_req_st(rhport, p_request), error );
+ }else
+ {
+ dcd_control_stall(rhport); // Stall unsupported request
+ }
+ }
+
+ //------------- Endpoint Request -------------//
+ else if ( TUSB_REQ_RCPT_ENDPOINT == p_request->bmRequestType_bit.recipient &&
+ TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type)
+ {
+ if (TUSB_REQ_GET_STATUS == p_request->bRequest )
+ {
+ uint16_t status = dcd_edpt_stalled(rhport, tu_u16_low(p_request->wIndex)) ? 0x0001 : 0x0000;
+ memcpy(_usbd_ctrl_buf, &status, 2);
+
+ usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, 2);
+ }
+ else if (TUSB_REQ_CLEAR_FEATURE == p_request->bRequest )
+ {
+ // only endpoint feature is halted/stalled
+ dcd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ }
+ else if (TUSB_REQ_SET_FEATURE == p_request->bRequest )
+ {
+ // only endpoint feature is halted/stalled
+ dcd_edpt_stall(rhport, tu_u16_low(p_request->wIndex));
+ dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+ }
+ else
+ {
+ dcd_control_stall(rhport); // Stall unsupported request
+ }
+ }
+
+ //------------- Unsupported Request -------------//
+ else
+ {
+ dcd_control_stall(rhport); // Stall unsupported request
+ }
+
+ OSAL_SUBTASK_END
+}
+
+// Process Set Configure Request
+// TODO Host (windows) can get HID report descriptor before set configured
+// may need to open interface before set configured
+static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number)
+{
+ dcd_set_config(rhport, config_number);
+
+ _usbd_dev.config_num = config_number;
+
+ //------------- parse configuration & open drivers -------------//
+ uint8_t const * desc_cfg = (uint8_t const *) usbd_desc_set->config;
+ TU_ASSERT(desc_cfg != NULL, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
+ uint8_t const * p_desc = desc_cfg + sizeof(tusb_desc_configuration_t);
+ uint16_t const cfg_len = ((tusb_desc_configuration_t*)desc_cfg)->wTotalLength;
+
+ while( p_desc < desc_cfg + cfg_len )
+ {
+ if ( TUSB_DESC_INTERFACE_ASSOCIATION == descriptor_type(p_desc) )
+ {
+ p_desc = descriptor_next(p_desc); // ignore Interface Association
+ }else
+ {
+ TU_ASSERT( TUSB_DESC_INTERFACE == descriptor_type(p_desc), TUSB_ERROR_NOT_SUPPORTED_YET );
+
+ tusb_desc_interface_t* p_desc_itf = (tusb_desc_interface_t*) p_desc;
+ uint8_t const class_code = p_desc_itf->bInterfaceClass;
+
+ // Check if class is supported
+ uint8_t drv_id;
+ for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
+ {
+ if ( usbd_class_drivers[drv_id].class_code == class_code ) break;
+ }
+ TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT, TUSB_ERROR_NOT_SUPPORTED_YET );
+
+ // Interface number must not be used
+ TU_ASSERT( 0xff == _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber], TUSB_ERROR_FAILED);
+ _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber] = drv_id;
+
+ uint16_t len=0;
+ TU_ASSERT_ERR( usbd_class_drivers[drv_id].open( rhport, p_desc_itf, &len ) );
+ TU_ASSERT( len >= sizeof(tusb_desc_interface_t), TUSB_ERROR_FAILED );
+
+ mark_interface_endpoint(p_desc, len, drv_id);
+
+ p_desc += len; // next interface
+ }
+ }
+
+ // invoke callback
+ tud_mount_cb();
+
+ return TUSB_ERROR_NONE;
+}
+
+// return len of descriptor and change pointer to descriptor's buffer
+static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * const p_request, uint8_t const ** pp_buffer)
+{
+ (void) rhport;
+
+ tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue);
+ uint8_t const desc_index = tu_u16_low( p_request->wValue );
+
+ uint8_t const * desc_data = NULL ;
+ uint16_t len = 0;
+
+ switch(desc_type)
+ {
+ case TUSB_DESC_DEVICE:
+ desc_data = (uint8_t const *) usbd_desc_set->device;
+ len = sizeof(tusb_desc_device_t);
+ break;
+
+ case TUSB_DESC_CONFIGURATION:
+ desc_data = (uint8_t const *) usbd_desc_set->config;
+ len = ((tusb_desc_configuration_t const*) desc_data)->wTotalLength;
+ break;
+
+ case TUSB_DESC_STRING:
+ // String Descriptor always uses the desc set from user
+ if ( desc_index < tud_desc_set.string_count )
+ {
+ desc_data = tud_desc_set.string_arr[desc_index];
+ TU_VERIFY( desc_data != NULL, 0 );
+
+ len = desc_data[0]; // first byte of descriptor is its size
+ }else
+ {
+ // out of range
+ /* The 0xee string is indeed a Microsoft USB extension.
+ * It can be used to tell Windows what driver it should use for the device !!!
+ */
+ return 0;
+ }
+ break;
+
+ case TUSB_DESC_DEVICE_QUALIFIER:
+ // TODO If not highspeed capable stall this request otherwise
+ // return the descriptor that could work in highspeed
+ return 0;
+ break;
+
+ default: return 0;
+ }
+
+ TU_ASSERT( desc_data != NULL, 0);
+
+ // up to Host's length
+ len = tu_min16(p_request->wLength, len );
+ (*pp_buffer) = desc_data;
+
+ return len;
+}
+
+// Helper marking endpoint of interface belongs to class driver
+static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id)
+{
+ uint16_t len = 0;
+
+ while( len < desc_len )
+ {
+ if ( TUSB_DESC_ENDPOINT == descriptor_type(p_desc) )
+ {
+ uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
+
+ _usbd_dev.ep2drv[ edpt_dir(ep_addr) ][ edpt_number(ep_addr) ] = driver_id;
+ }
+
+ len += descriptor_len(p_desc);
+ p_desc = descriptor_next(p_desc);
+ }
+}
+
+//--------------------------------------------------------------------+
+// USBD-DCD Callback API
+//--------------------------------------------------------------------+
+void dcd_event_handler(dcd_event_t const * event, bool in_isr)
+{
+ uint8_t const rhport = event->rhport;
+
+ switch (event->event_id)
+ {
+ case DCD_EVENT_BUS_RESET:
+ case DCD_EVENT_UNPLUGGED:
+ case DCD_EVENT_SOF:
+ osal_queue_send(_usbd_q, event, in_isr);
+ break;
+
+ case DCD_EVENT_SUSPENDED:
+ // TODO support suspended
+ break;
+
+ case DCD_EVENT_RESUME:
+ // TODO support resume
+ break;
+
+ case DCD_EVENT_SETUP_RECEIVED:
+ osal_queue_send(_usbd_q, event, in_isr);
+ break;
+
+ case DCD_EVENT_XFER_COMPLETE:
+ if (event->xfer_complete.ep_addr == 0)
+ {
+ // only signal data stage, skip status (zero byte)
+ if (event->xfer_complete.len)
+ {
+ (void) event->xfer_complete.result; // TODO handle control error/stalled
+ osal_semaphore_post( _usbd_ctrl_sem, in_isr);
+ }
+ }else
+ {
+ osal_queue_send(_usbd_q, event, in_isr);
+ }
+ TU_ASSERT(event->xfer_complete.result == DCD_XFER_SUCCESS,);
+ break;
+
+ default: break;
+ }
+}
+
+//--------------------------------------------------------------------+
+// Helper
+//--------------------------------------------------------------------+
+tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
+{
+ for(int i=0; i<2; i++)
+ {
+ TU_ASSERT(TUSB_DESC_ENDPOINT == p_desc_ep->bDescriptorType &&
+ xfer_type == p_desc_ep->bmAttributes.xfer, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
+
+ TU_ASSERT( dcd_edpt_open(rhport, p_desc_ep), TUSB_ERROR_DCD_OPEN_PIPE_FAILED );
+
+ if ( edpt_dir(p_desc_ep->bEndpointAddress) == TUSB_DIR_IN )
+ {
+ (*ep_in) = p_desc_ep->bEndpointAddress;
+ }else
+ {
+ (*ep_out) = p_desc_ep->bEndpointAddress;
+ }
+
+ p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_ep );
+ }
+
+ return TUSB_ERROR_NONE;
+}
+
+void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr )
+{
+ dcd_event_t event =
+ {
+ .rhport = 0,
+ .event_id = USBD_EVT_FUNC_CALL,
+ };
+
+ event.func_call.func = func;
+ event.func_call.param = param;
+
+ osal_queue_send(_usbd_q, &event, in_isr);
+}
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/device/usbd.h b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd.h new file mode 100755 index 0000000..f9e0d8f --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd.h @@ -0,0 +1,103 @@ +/**************************************************************************/
+/*!
+ @file usbd.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_usbd
+ * @{ */
+
+#ifndef _TUSB_USBD_H_
+#define _TUSB_USBD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include <common/tusb_common.h>
+#include "osal/osal.h"
+#include "device/dcd.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+/// \brief Descriptor pointer collector to all the needed.
+typedef struct {
+ void const * device; ///< pointer to device descriptor \ref tusb_desc_device_t
+ void const * config; ///< pointer to the whole configuration descriptor, starting by \ref tusb_desc_configuration_t
+
+ uint8_t const** string_arr; ///< a array of pointers to string descriptors
+ uint16_t string_count;
+
+ struct {
+ uint8_t const* generic;
+ uint8_t const* boot_keyboard;
+ uint8_t const* boot_mouse;
+ } hid_report;
+
+}tud_desc_set_t;
+
+
+// Must be defined by application
+extern tud_desc_set_t tud_desc_set;
+
+//--------------------------------------------------------------------+
+// APPLICATION API
+//--------------------------------------------------------------------+
+bool tud_mounted(void);
+
+//--------------------------------------------------------------------+
+// APPLICATION CALLBACK (WEAK is optional)
+//--------------------------------------------------------------------+
+
+/** Callback invoked when device is mounted (configured) */
+ATTR_WEAK void tud_mount_cb(void);
+
+/** Callback invoked when device is unmounted (bus reset/unplugged) */
+ATTR_WEAK void tud_umount_cb(void);
+
+//void tud_device_suspended_cb(void);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_USBD_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/device/usbd_auto_desc.c b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd_auto_desc.c new file mode 100755 index 0000000..c6523f2 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd_auto_desc.c @@ -0,0 +1,633 @@ +/**************************************************************************/
+/*!
+ @file usbd_auto_desc.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DESC_AUTO
+
+#include "tusb.h"
+
+//--------------------------------------------------------------------+
+// Auto Description Default Configure & Validation
+//--------------------------------------------------------------------+
+
+// If HID Generic interface is generated
+#define AUTO_DESC_HID_GENERIC (CFG_TUD_HID && ((CFG_TUD_HID_KEYBOARD && !CFG_TUD_HID_KEYBOARD_BOOT) || \
+ (CFG_TUD_HID_MOUSE && !CFG_TUD_HID_MOUSE_BOOT)) )
+/*------------- VID/PID -------------*/
+#ifndef CFG_TUD_DESC_VID
+#define CFG_TUD_DESC_VID 0xCAFE
+#endif
+
+#ifndef CFG_TUD_DESC_PID
+
+/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
+ * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
+ *
+ * Auto ProductID layout's Bitmap:
+ * [MSB] HID Generic | Boot Mouse | Boot Keyboard | MSC | CDC [LSB]
+ */
+#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
+#define CFG_TUD_DESC_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
+ _PID_MAP(HID_KEYBOARD, 2) | _PID_MAP(HID_MOUSE, 3) | (AUTO_DESC_HID_GENERIC << 4) )
+#endif
+
+//--------------------------------------------------------------------+
+// Interface & Endpoint mapping
+//--------------------------------------------------------------------+
+
+/*------------- Interface Numbering -------------*/
+/* The order as follows: CDC, MSC, Boot Keyboard, Boot Mouse, HID Generic
+ * If an interface is not enabled, the later will take its place */
+
+enum
+{
+#if CFG_TUD_CDC
+ ITF_NUM_CDC,
+ ITF_NUM_CDC_DATA,
+#endif
+
+#if CFG_TUD_MSC
+ ITF_NUM_MSC,
+#endif
+
+#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+ ITF_NUM_HID_BOOT_KBD,
+#endif
+
+#if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+ ITF_NUM_HID_BOOT_MSE,
+#endif
+
+#if AUTO_DESC_HID_GENERIC
+ ITF_NUM_HID_GEN,
+#endif
+
+ ITF_NUM_TOTAL
+};
+
+enum {
+ ITF_STR_LANGUAGE = 0 ,
+ ITF_STR_MANUFACTURER ,
+ ITF_STR_PRODUCT ,
+ ITF_STR_SERIAL ,
+
+#if CFG_TUD_CDC
+ ITF_STR_CDC ,
+#endif
+
+#if CFG_TUD_MSC
+ ITF_STR_MSC ,
+#endif
+
+#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+ ITF_STR_HID_BOOT_KBD,
+#endif
+
+#if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+ ITF_STR_HID_BOOT_MSE,
+#endif
+
+#if AUTO_DESC_HID_GENERIC
+ ITF_STR_HID_GEN,
+#endif
+};
+
+/*------------- Endpoint Numbering & Size -------------*/
+#define _EP_IN(x) (0x80 | (x))
+#define _EP_OUT(x) (x)
+
+// CDC
+#define EP_CDC_NOTIF _EP_IN ( ITF_NUM_CDC+1 )
+#define EP_CDC_NOTIF_SIZE 8
+
+#define EP_CDC_OUT _EP_OUT( ITF_NUM_CDC+2 )
+#define EP_CDC_IN _EP_IN ( ITF_NUM_CDC+2 )
+
+// Mass Storage
+#define EP_MSC_OUT _EP_OUT( ITF_NUM_MSC+1 )
+#define EP_MSC_IN _EP_IN ( ITF_NUM_MSC+1 )
+
+
+// HID Keyboard with boot protocol
+#define EP_HID_KBD_BOOT _EP_IN ( ITF_NUM_HID_BOOT_KBD+1 )
+#define EP_HID_KBD_BOOT_SZ 8
+
+// HID Mouse with boot protocol
+#define EP_HID_MSE_BOOT _EP_IN ( ITF_NUM_HID_BOOT_MSE+1 )
+#define EP_HID_MSE_BOOT_SZ 8
+
+// HID composite = keyboard + mouse + gamepad + etc ...
+#define EP_HID_GEN _EP_IN ( ITF_NUM_HID_GEN+1 )
+#define EP_HID_GEN_SIZE 16
+
+
+//--------------------------------------------------------------------+
+// Auto generated HID Report Descriptors
+//--------------------------------------------------------------------+
+
+
+/*------------- Boot Protocol Report Descriptor -------------*/
+#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+uint8_t const _desc_auto_hid_boot_kbd_report[] = { HID_REPORT_DESC_KEYBOARD() };
+#endif
+
+#if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+uint8_t const _desc_auto_hid_boot_mse_report[] = { HID_REPORT_DESC_MOUSE() };
+#endif
+
+
+/*------------- Generic (composite) Descriptor -------------*/
+#if AUTO_DESC_HID_GENERIC
+
+// Report ID: 0 if there is only 1 report
+// starting from 1 if there is multiple reports
+#define _REPORT_ID_KBD
+
+// TODO report ID
+uint8_t const _desc_auto_hid_generic_report[] =
+{
+#if CFG_TUD_HID_KEYBOARD && !CFG_TUD_HID_KEYBOARD_BOOT
+ HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1), ),
+#endif
+
+#if CFG_TUD_HID_MOUSE && !CFG_TUD_HID_MOUSE_BOOT
+ HID_REPORT_DESC_MOUSE( HID_REPORT_ID(2), )
+#endif
+
+};
+
+#endif // hid generic
+
+
+/*------------------------------------------------------------------*/
+/* Auto generated Device & Configuration descriptor
+ *------------------------------------------------------------------*/
+
+// For highspeed device but currently in full speed mode
+//tusb_desc_device_qualifier_t _device_qual =
+//{
+// .bLength = sizeof(tusb_desc_device_qualifier_t),
+// .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
+// .bcdUSB = 0x0200,
+// .bDeviceClass =
+//};
+
+/*------------- Device Descriptor -------------*/
+tusb_desc_device_t const _desc_auto_device =
+{
+ .bLength = sizeof(tusb_desc_device_t),
+ .bDescriptorType = TUSB_DESC_DEVICE,
+ .bcdUSB = 0x0200,
+
+ #if CFG_TUD_CDC
+ // Use Interface Association Descriptor (IAD) for CDC
+ // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
+ .bDeviceClass = TUSB_CLASS_MISC,
+ .bDeviceSubClass = MISC_SUBCLASS_COMMON,
+ .bDeviceProtocol = MISC_PROTOCOL_IAD,
+ #else
+ .bDeviceClass = 0x00,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ #endif
+
+ .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE,
+
+ .idVendor = CFG_TUD_DESC_VID,
+ .idProduct = CFG_TUD_DESC_PID,
+ .bcdDevice = 0x0100,
+
+ .iManufacturer = 0x01,
+ .iProduct = 0x02,
+ .iSerialNumber = 0x03,
+
+ .bNumConfigurations = 0x01 // TODO multiple configurations
+};
+
+
+/*------------- Configuration Descriptor -------------*/
+typedef struct ATTR_PACKED
+{
+ tusb_desc_configuration_t config;
+
+ //------------- CDC -------------//
+#if CFG_TUD_CDC
+ struct ATTR_PACKED
+ {
+ tusb_desc_interface_assoc_t iad;
+
+ //CDC Control Interface
+ tusb_desc_interface_t comm_itf;
+ cdc_desc_func_header_t header;
+ cdc_desc_func_call_management_t call;
+ cdc_desc_func_acm_t acm;
+ cdc_desc_func_union_t union_func;
+ tusb_desc_endpoint_t ep_notif;
+
+ //CDC Data Interface
+ tusb_desc_interface_t data_itf;
+ tusb_desc_endpoint_t ep_out;
+ tusb_desc_endpoint_t ep_in;
+ }cdc;
+#endif
+
+ //------------- Mass Storage -------------//
+#if CFG_TUD_MSC
+ struct ATTR_PACKED
+ {
+ tusb_desc_interface_t itf;
+ tusb_desc_endpoint_t ep_out;
+ tusb_desc_endpoint_t ep_in;
+ } msc;
+#endif
+
+ //------------- HID -------------//
+#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+ struct ATTR_PACKED
+ {
+ tusb_desc_interface_t itf;
+ tusb_hid_descriptor_hid_t hid_desc;
+ tusb_desc_endpoint_t ep_in;
+ } hid_kbd_boot;
+#endif
+
+#if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+ struct ATTR_PACKED
+ {
+ tusb_desc_interface_t itf;
+ tusb_hid_descriptor_hid_t hid_desc;
+ tusb_desc_endpoint_t ep_in;
+ } hid_mse_boot;
+#endif
+
+#if AUTO_DESC_HID_GENERIC
+
+ struct ATTR_PACKED
+ {
+ tusb_desc_interface_t itf;
+ tusb_hid_descriptor_hid_t hid_desc;
+ tusb_desc_endpoint_t ep_in;
+
+ #if 0 // CFG_TUD_HID_KEYBOARD
+ tusb_desc_endpoint_t ep_out;
+ #endif
+ } hid_generic;
+
+#endif
+
+} desc_auto_cfg_t;
+
+desc_auto_cfg_t const _desc_auto_config_struct =
+{
+ .config =
+ {
+ .bLength = sizeof(tusb_desc_configuration_t),
+ .bDescriptorType = TUSB_DESC_CONFIGURATION,
+
+ .wTotalLength = sizeof(desc_auto_cfg_t),
+ .bNumInterfaces = ITF_NUM_TOTAL,
+
+ .bConfigurationValue = 1,
+ .iConfiguration = 0x00,
+ .bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
+ .bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
+ },
+
+#if CFG_TUD_CDC
+ // IAD points to CDC Interfaces
+ .cdc =
+ {
+ .iad =
+ {
+ .bLength = sizeof(tusb_desc_interface_assoc_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION,
+
+ .bFirstInterface = ITF_NUM_CDC,
+ .bInterfaceCount = 2,
+
+ .bFunctionClass = TUSB_CLASS_CDC,
+ .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
+ .bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
+ .iFunction = 0
+ },
+
+ //------------- CDC Communication Interface -------------//
+ .comm_itf =
+ {
+ .bLength = sizeof(tusb_desc_interface_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE,
+ .bInterfaceNumber = ITF_NUM_CDC,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = TUSB_CLASS_CDC,
+ .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
+ .bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
+ .iInterface = 4
+ },
+
+ .header =
+ {
+ .bLength = sizeof(cdc_desc_func_header_t),
+ .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_HEADER,
+ .bcdCDC = 0x0120
+ },
+
+ .call =
+ {
+ .bLength = sizeof(cdc_desc_func_call_management_t),
+ .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_CALL_MANAGEMENT,
+ .bmCapabilities = { 0 },
+ .bDataInterface = ITF_NUM_CDC+1,
+ },
+
+ .acm =
+ {
+ .bLength = sizeof(cdc_desc_func_acm_t),
+ .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
+ .bmCapabilities = { // 0x02
+ .support_line_request = 1,
+ }
+ },
+
+ .union_func =
+ {
+ .bLength = sizeof(cdc_desc_func_union_t), // plus number of
+ .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_UNION,
+ .bControlInterface = ITF_NUM_CDC,
+ .bSubordinateInterface = ITF_NUM_CDC+1,
+ },
+
+ .ep_notif =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_CDC_NOTIF,
+ .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
+ .wMaxPacketSize = { .size = EP_CDC_NOTIF_SIZE },
+ .bInterval = 0x10
+ },
+
+ //------------- CDC Data Interface -------------//
+ .data_itf =
+ {
+ .bLength = sizeof(tusb_desc_interface_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE,
+ .bInterfaceNumber = ITF_NUM_CDC+1,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = TUSB_CLASS_CDC_DATA,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0x00
+ },
+
+ .ep_out =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_CDC_OUT,
+ .bmAttributes = { .xfer = TUSB_XFER_BULK },
+ .wMaxPacketSize = { .size = CFG_TUD_CDC_EPSIZE },
+ .bInterval = 0
+ },
+
+ .ep_in =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_CDC_IN,
+ .bmAttributes = { .xfer = TUSB_XFER_BULK },
+ .wMaxPacketSize = { .size = CFG_TUD_CDC_EPSIZE },
+ .bInterval = 0
+ },
+ },
+#endif // cdc
+
+#if CFG_TUD_MSC
+ //------------- Mass Storage-------------//
+ .msc =
+ {
+ .itf =
+ {
+ .bLength = sizeof(tusb_desc_interface_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE,
+ .bInterfaceNumber = ITF_NUM_MSC,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = TUSB_CLASS_MSC,
+ .bInterfaceSubClass = MSC_SUBCLASS_SCSI,
+ .bInterfaceProtocol = MSC_PROTOCOL_BOT,
+ .iInterface = 4 + CFG_TUD_CDC
+ },
+
+ .ep_out =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_MSC_OUT,
+ .bmAttributes = { .xfer = TUSB_XFER_BULK },
+ .wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE},
+ .bInterval = 1
+ },
+
+ .ep_in =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_MSC_IN,
+ .bmAttributes = { .xfer = TUSB_XFER_BULK },
+ .wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE},
+ .bInterval = 1
+ }
+ },
+#endif // msc
+
+#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+ .hid_kbd_boot =
+ {
+ .itf =
+ {
+ .bLength = sizeof(tusb_desc_interface_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE,
+ .bInterfaceNumber = ITF_NUM_HID_BOOT_KBD,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = TUSB_CLASS_HID,
+ .bInterfaceSubClass = HID_SUBCLASS_BOOT,
+ .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,
+ .iInterface = 0 //4 + CFG_TUD_CDC + CFG_TUD_MSC
+ },
+
+ .hid_desc =
+ {
+ .bLength = sizeof(tusb_hid_descriptor_hid_t),
+ .bDescriptorType = HID_DESC_TYPE_HID,
+ .bcdHID = 0x0111,
+ .bCountryCode = HID_Local_NotSupported,
+ .bNumDescriptors = 1,
+ .bReportType = HID_DESC_TYPE_REPORT,
+ .wReportLength = sizeof(_desc_auto_hid_boot_kbd_report)
+ },
+
+ .ep_in =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_HID_KBD_BOOT,
+ .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
+ .wMaxPacketSize = { .size = EP_HID_KBD_BOOT_SZ },
+ .bInterval = 0x0A
+ }
+ },
+#endif // boot keyboard
+
+ //------------- HID Mouse -------------//
+#if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+ .hid_mse_boot =
+ {
+ .itf =
+ {
+ .bLength = sizeof(tusb_desc_interface_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE,
+ .bInterfaceNumber = ITF_NUM_HID_BOOT_MSE,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = TUSB_CLASS_HID,
+ .bInterfaceSubClass = HID_SUBCLASS_BOOT,
+ .bInterfaceProtocol = HID_PROTOCOL_MOUSE,
+ .iInterface = 0 // 4 + CFG_TUD_CDC + CFG_TUD_MSC + CFG_TUD_HID_KEYBOARD
+ },
+
+ .hid_desc =
+ {
+ .bLength = sizeof(tusb_hid_descriptor_hid_t),
+ .bDescriptorType = HID_DESC_TYPE_HID,
+ .bcdHID = 0x0111,
+ .bCountryCode = HID_Local_NotSupported,
+ .bNumDescriptors = 1,
+ .bReportType = HID_DESC_TYPE_REPORT,
+ .wReportLength = sizeof(_desc_auto_hid_boot_mse_report)
+ },
+
+ .ep_in =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_HID_MSE_BOOT,
+ .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
+ .wMaxPacketSize = { .size = EP_HID_MSE_BOOT_SZ },
+ .bInterval = 0x0A
+ },
+ },
+
+#endif // boot mouse
+
+#if AUTO_DESC_HID_GENERIC
+
+ //------------- HID Generic Multiple report -------------//
+ .hid_generic =
+ {
+ .itf =
+ {
+ .bLength = sizeof(tusb_desc_interface_t),
+ .bDescriptorType = TUSB_DESC_INTERFACE,
+ .bInterfaceNumber = ITF_NUM_HID_GEN,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = TUSB_CLASS_HID,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0, // 4 + CFG_TUD_CDC + CFG_TUD_MSC,
+ },
+
+ .hid_desc =
+ {
+ .bLength = sizeof(tusb_hid_descriptor_hid_t),
+ .bDescriptorType = HID_DESC_TYPE_HID,
+ .bcdHID = 0x0111,
+ .bCountryCode = HID_Local_NotSupported,
+ .bNumDescriptors = 1,
+ .bReportType = HID_DESC_TYPE_REPORT,
+ .wReportLength = sizeof(_desc_auto_hid_generic_report)
+ },
+
+ .ep_in =
+ {
+ .bLength = sizeof(tusb_desc_endpoint_t),
+ .bDescriptorType = TUSB_DESC_ENDPOINT,
+ .bEndpointAddress = EP_HID_GEN,
+ .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
+ .wMaxPacketSize = { .size = EP_HID_GEN_SIZE },
+ .bInterval = 0x0A
+ }
+ }
+
+#endif // hid generic
+};
+
+uint8_t const * const _desc_auto_config = (uint8_t const*) &_desc_auto_config_struct;
+
+tud_desc_set_t const _usbd_auto_desc_set =
+{
+ .device = &_desc_auto_device,
+ .config = &_desc_auto_config_struct,
+
+ .hid_report =
+ {
+#if AUTO_DESC_HID_GENERIC
+ .generic = _desc_auto_hid_generic_report,
+#else
+ .generic = NULL,
+#endif
+
+#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
+ .boot_keyboard = _desc_auto_hid_boot_kbd_report,
+#endif
+
+#if CFG_TUD_HID_MOUSE && CFG_TUD_HID_MOUSE_BOOT
+ .boot_mouse = _desc_auto_hid_boot_mse_report
+#endif
+ }
+};
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/device/usbd_pvt.h b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd_pvt.h new file mode 100755 index 0000000..dea0f3b --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/device/usbd_pvt.h @@ -0,0 +1,92 @@ +/**************************************************************************/
+/*!
+ @file usbd_pvt.h
+ @author hathach
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+#ifndef USBD_PVT_H_
+#define USBD_PVT_H_
+
+#include "osal/osal.h"
+#include "common/tusb_fifo.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// for used by usbd_control_xfer_st() only, must not be used directly
+extern osal_semaphore_t _usbd_ctrl_sem;
+extern uint8_t _usbd_ctrl_buf[CFG_TUD_CTRL_BUFSIZE];
+
+// Either point to tud_desc_set or usbd_auto_desc_set depending on CFG_TUD_DESC_AUTO
+extern tud_desc_set_t const* usbd_desc_set;
+
+//--------------------------------------------------------------------+
+// INTERNAL API for stack management
+//--------------------------------------------------------------------+
+tusb_error_t usbd_init (void);
+void usbd_task (void* param);
+
+/*------------------------------------------------------------------*/
+/* Endpoint helper
+ *------------------------------------------------------------------*/
+// helper to parse an pair of In and Out endpoint descriptors. They must be consecutive
+tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
+
+// Carry out Data and Status stage of control transfer
+// Must be call in a subtask (_st) function
+#define usbd_control_xfer_st(_rhport, _dir, _buffer, _len) \
+ do { \
+ if (_len) { \
+ uint32_t err; \
+ dcd_control_xfer(_rhport, _dir, (uint8_t*) _buffer, _len); \
+ osal_semaphore_wait( _usbd_ctrl_sem, OSAL_TIMEOUT_CONTROL_XFER, &err ); \
+ STASK_ASSERT_ERR( err ); \
+ } \
+ dcd_control_status(_rhport, _dir); \
+ /* No need to wait for status phase to complete */ \
+ }while(0)
+
+
+/*------------------------------------------------------------------*/
+/* Other Helpers
+ *------------------------------------------------------------------*/
+void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* USBD_PVT_H_ */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/license.md b/arduino/cores/nRF5/usb/tinyusb/src/license.md new file mode 100755 index 0000000..3329982 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/license.md @@ -0,0 +1,27 @@ +# License
+
+<pre>Software License Agreement (BSD License)
+Copyright (c) 2013, hathach (tinyusb.org)
+All rights reserved.
+
+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 the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE AUTHOR 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.</pre>
\ No newline at end of file diff --git a/arduino/cores/nRF5/usb/tinyusb/src/osal/osal.c b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal.c new file mode 100755 index 0000000..1c31279 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal.c @@ -0,0 +1,60 @@ +/**************************************************************************/
+/*!
+ @file osal.c
+ @author hathach
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+#include "osal.h"
+
+//--------------------------------------------------------------------+
+// TICK API
+//--------------------------------------------------------------------+
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+
+uint32_t tusb_hal_millis(void)
+{
+ return ( ( ((uint64_t) xTaskGetTickCount()) * 1000) / configTICK_RATE_HZ );
+}
+
+#elif CFG_TUSB_OS == OPT_OS_MYNEWT
+
+uint32_t tusb_hal_millis(void)
+{
+ return os_time_ticks_to_ms32( os_time_get() );
+}
+
+#endif
+
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/osal/osal.h b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal.h new file mode 100755 index 0000000..2ca06f6 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal.h @@ -0,0 +1,132 @@ +/**************************************************************************/
+/*!
+ @file osal.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_OSAL_H_
+#define _TUSB_OSAL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \addtogroup group_osal
+ * @{ */
+
+#include "tusb_option.h"
+#include "common/tusb_common.h"
+
+enum
+{
+ OSAL_TIMEOUT_NOTIMEOUT = 0, // return immediately
+ OSAL_TIMEOUT_NORMAL = 10, // default timeout
+ OSAL_TIMEOUT_WAIT_FOREVER = 0xFFFFFFFFUL
+};
+
+#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER
+
+typedef void (*osal_task_func_t)( void * );
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+ #include "osal_none.h"
+
+ #define OSAL_TASK_BEGIN
+ #define OSAL_TASK_END
+
+#else
+ /* RTOS Porting API
+ *
+ * uint32_t tusb_hal_millis(void)
+ *
+ * Task
+ * osal_task_def_t
+ * bool osal_task_create(osal_task_def_t* taskdef)
+ * void osal_task_delay(uint32_t msec)
+ *
+ * Queue
+ * osal_queue_def_t, osal_queue_t
+ * osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+ * osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *p_error)
+ * bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr)
+ * osal_queue_reset()
+ *
+ * Semaphore
+ * osal_semaphore_def_t, osal_semaphore_t
+ * osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+ * bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+ * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, uint32_t *p_error)
+ * void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
+ *
+ * Mutex
+ * osal_mutex_t
+ * osal_mutex_create(osal_mutex_def_t* mdef)
+ * bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+ * void osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec, uint32_t *p_error)
+ */
+
+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
+ #include "osal_freertos.h"
+ #elif CFG_TUSB_OS == OPT_OS_MYNEWT
+ #include "osal_mynewt.h"
+ #else
+ #error CFG_TUSB_OS is not defined or OS is not supported yet
+ #endif
+
+ #define OSAL_TASK_BEGIN while(1) {
+ #define OSAL_TASK_END }
+
+ //------------- Sub Task -------------//
+ #define OSAL_SUBTASK_BEGIN
+ #define OSAL_SUBTASK_END return TUSB_ERROR_NONE;
+
+ #define STASK_RETURN(_error) return _error;
+ #define STASK_INVOKE(_subtask, _status) (_status) = _subtask
+
+ //------------- Sub Task Assert -------------//
+ #define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR(_err)
+ #define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, _func)
+
+ #define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED)
+ #define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, _func)
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+/** @} */
+
+#endif /* _TUSB_OSAL_H_ */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/osal/osal_freertos.h b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal_freertos.h new file mode 100755 index 0000000..c990e56 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal_freertos.h @@ -0,0 +1,186 @@ +/**************************************************************************/
+/*!
+ @file osal_freeRTOS.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_osal
+ * @{
+ * \defgroup Group_FreeRTOS FreeRTOS
+ * @{ */
+
+#ifndef _TUSB_OSAL_FREERTOS_H_
+#define _TUSB_OSAL_FREERTOS_H_
+
+//------------- FreeRTOS Headers -------------//
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "queue.h"
+#include "task.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 0
+// Helper to determine if we are in ISR to use ISR API (only cover ARM Cortex)
+static inline bool in_isr(void)
+{
+ return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
+}
+#endif
+
+//--------------------------------------------------------------------+
+// TASK API
+//--------------------------------------------------------------------+
+#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) \
+ static uint8_t _name##_##buf[_stack_sz*sizeof(StackType_t)]; \
+ osal_task_def_t _name = { .func = _func, .prio = _prio, .stack_sz = _stack_sz, .buf = _name##_##buf, .strname = _str };
+
+typedef struct
+{
+ osal_task_func_t func;
+
+ uint16_t prio;
+ uint16_t stack_sz;
+ void* buf;
+ const char* strname;
+
+ StaticTask_t stask;
+}osal_task_def_t;
+
+static inline bool osal_task_create(osal_task_def_t* taskdef)
+{
+ return NULL != xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, (StackType_t*) taskdef->buf, &taskdef->stask);
+}
+
+static inline void osal_task_delay(uint32_t msec)
+{
+ vTaskDelay( pdMS_TO_TICKS(msec) );
+}
+
+//--------------------------------------------------------------------+
+// Semaphore API
+//--------------------------------------------------------------------+
+typedef StaticSemaphore_t osal_semaphore_def_t;
+typedef SemaphoreHandle_t osal_semaphore_t;
+
+static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+{
+ return xSemaphoreCreateBinaryStatic(semdef);
+}
+
+static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+{
+ return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl);
+}
+
+static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, uint32_t *err)
+{
+ uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec);
+ (*err) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT);
+}
+
+static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
+{
+ xQueueReset(sem_hdl);
+}
+
+//--------------------------------------------------------------------+
+// MUTEX API (priority inheritance)
+//--------------------------------------------------------------------+
+typedef StaticSemaphore_t osal_mutex_def_t;
+typedef SemaphoreHandle_t osal_mutex_t;
+
+static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+{
+ return xSemaphoreCreateMutexStatic(mdef);
+}
+
+#define osal_mutex_lock osal_semaphore_wait
+
+static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+{
+ return xSemaphoreGive(mutex_hdl);
+}
+
+//--------------------------------------------------------------------+
+// QUEUE API
+//--------------------------------------------------------------------+
+#define OSAL_QUEUE_DEF(_name, _depth, _type) \
+ static _type _name##_##buf[_depth];\
+ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf };
+
+typedef struct
+{
+ uint16_t depth;
+ uint16_t item_sz;
+ void* buf;
+
+ StaticQueue_t sq;
+}osal_queue_def_t;
+
+typedef QueueHandle_t osal_queue_t;
+
+static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+{
+ return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq);
+}
+
+static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *err)
+{
+ uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec);
+ (*err) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT);
+}
+
+static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr)
+{
+ return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER);
+}
+
+static inline void osal_queue_reset(osal_queue_t const queue_hdl)
+{
+ xQueueReset(queue_hdl);
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_OSAL_FREERTOS_H_ */
+
+/** @} */
+/** @} */
+
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/osal/osal_none.h b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal_none.h new file mode 100755 index 0000000..796ddc1 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/osal/osal_none.h @@ -0,0 +1,244 @@ +/**************************************************************************/
+/*!
+ @file osal_none.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_osal
+ * \defgroup Group_OSNone None OS
+ * @{ */
+
+#ifndef _TUSB_OSAL_NONE_H_
+#define _TUSB_OSAL_NONE_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// TASK API
+// NOTES: Each blocking OSAL_NONE services such as semaphore wait,
+// queue receive embedded return statement, therefore local variable
+// retain value before/after such services needed to declare as static
+// OSAL_TASK_LOOP
+// {
+// OSAL_TASK_BEGIN
+//
+// task body statements
+//
+// OSAL_TASK_LOOP_ENG
+// }
+//
+// NOTE: no switch statement is allowed in Task and subtask
+//--------------------------------------------------------------------+
+#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) osal_task_def_t _name;
+
+typedef uint8_t osal_task_def_t;
+
+static inline bool osal_task_create(osal_task_def_t* taskdef)
+{
+ (void) taskdef;
+ return true;
+}
+
+#define TASK_RESTART \
+ _state = 0
+
+#define osal_task_delay(_msec) \
+ do { \
+ _timeout = tusb_hal_millis(); \
+ _state = __LINE__; case __LINE__: \
+ if ( _timeout + (_msec) > tusb_hal_millis() ) \
+ return TUSB_ERROR_OSAL_WAITING; \
+ }while(0)
+
+//--------------------------------------------------------------------+
+// SUBTASK (a sub function that uses OS blocking services & called by a task
+//--------------------------------------------------------------------+
+#define OSAL_SUBTASK_BEGIN \
+ static uint16_t _state = 0; \
+ ATTR_UNUSED static uint32_t _timeout = 0; \
+ (void) _timeout; \
+ switch(_state) { \
+ case 0: {
+
+#define OSAL_SUBTASK_END \
+ default: TASK_RESTART; break; \
+ }} \
+ return TUSB_ERROR_NONE;
+
+#define STASK_INVOKE(_subtask, _status) \
+ do { \
+ _state = __LINE__; case __LINE__: \
+ { \
+ (_status) = _subtask; /* invoke sub task */ \
+ if (TUSB_ERROR_OSAL_WAITING == (_status)) return TUSB_ERROR_OSAL_WAITING; \
+ } \
+ }while(0)
+
+//------------- Sub Task Assert -------------//
+#define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0)
+
+#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR_HDLR(_err, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED)
+#define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED )
+
+#define STASK_ASSERT(_cond) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED)
+#define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED)
+
+//--------------------------------------------------------------------+
+// Semaphore API
+//--------------------------------------------------------------------+
+typedef struct
+{
+ volatile uint16_t count;
+}osal_semaphore_def_t;
+
+typedef osal_semaphore_def_t* osal_semaphore_t;
+
+static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+{
+ semdef->count = 0;
+ return semdef;
+}
+
+static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+{
+ (void) in_isr;
+ sem_hdl->count++;
+ return true;
+}
+
+static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
+{
+ sem_hdl->count = 0;
+}
+
+#define osal_semaphore_wait(_sem_hdl, _msec, _err) \
+ do { \
+ _timeout = tusb_hal_millis(); \
+ _state = __LINE__; case __LINE__: \
+ if( (_sem_hdl)->count == 0 ) { \
+ if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && (_timeout + (_msec) <= tusb_hal_millis()) ) \
+ *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \
+ else \
+ return TUSB_ERROR_OSAL_WAITING; \
+ } else{ \
+ /* Enter critical ? */ \
+ (_sem_hdl)->count--; \
+ /* Exit critical ? */ \
+ *(_err) = TUSB_ERROR_NONE; \
+ } \
+ }while(0)
+
+//--------------------------------------------------------------------+
+// MUTEX API
+// Within tinyusb, mutex is never used in ISR context
+//--------------------------------------------------------------------+
+typedef osal_semaphore_def_t osal_mutex_def_t;
+typedef osal_semaphore_t osal_mutex_t;
+
+static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+{
+ mdef->count = 1;
+ return mdef;
+}
+
+#define osal_mutex_unlock(_mutex_hdl) osal_semaphore_post(_mutex_hdl, false)
+#define osal_mutex_lock osal_semaphore_wait
+
+// check if mutex is available for non-thread/substask usage in some cases
+static inline bool osal_mutex_lock_notask(osal_mutex_t mutex_hdl)
+{
+ if (mutex_hdl->count)
+ {
+ mutex_hdl->count--;
+ return true;
+ }else
+ {
+ return false;
+ }
+}
+
+//--------------------------------------------------------------------+
+// QUEUE API
+//--------------------------------------------------------------------+
+#include "common/tusb_fifo.h"
+
+#define OSAL_QUEUE_DEF(_name, _depth, _type) TU_FIFO_DEF(_name, _depth, _type, false)
+
+typedef tu_fifo_t osal_queue_def_t;
+typedef tu_fifo_t* osal_queue_t;
+
+static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+{
+ tu_fifo_clear(qdef);
+ return (osal_queue_t) qdef;
+}
+
+static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr)
+{
+ (void) in_isr;
+ return tu_fifo_write( (tu_fifo_t*) queue_hdl, data);
+}
+
+static inline void osal_queue_reset(osal_queue_t const queue_hdl)
+{
+ queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0;
+}
+
+#define osal_queue_receive(_q_hdl, p_data, _msec, _err) \
+ do { \
+ _timeout = tusb_hal_millis(); \
+ _state = __LINE__; case __LINE__: \
+ if( (_q_hdl)->count == 0 ) { \
+ if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + (_msec) <= tusb_hal_millis()) ) \
+ *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \
+ else \
+ return TUSB_ERROR_OSAL_WAITING; \
+ } else{ \
+ /* Enter critical ? */ \
+ tu_fifo_read(_q_hdl, p_data); \
+ /* Exit critical ? */ \
+ *(_err) = TUSB_ERROR_NONE; \
+ } \
+ }while(0)
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_OSAL_NONE_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c b/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c new file mode 100755 index 0000000..d561ba4 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -0,0 +1,562 @@ +/**************************************************************************/
+/*!
+ @file dcd_nrf5x.c
+ @author hathach
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X
+
+#include "nrf.h"
+#include "nrf_power.h"
+#include "nrf_usbd.h"
+#include "nrf_clock.h"
+
+#include "device/dcd.h"
+
+// TODO remove later
+#include "device/usbd.h"
+#include "device/usbd_pvt.h" // to use defer function helper
+
+/*------------------------------------------------------------------*/
+/* MACRO TYPEDEF CONSTANT ENUM
+ *------------------------------------------------------------------*/
+enum
+{
+ // Max allowed by USB specs
+ MAX_PACKET_SIZE = 64,
+
+ // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT
+ EDPT_END_ALL_MASK = (0xff << USBD_INTEN_ENDEPIN0_Pos) | (0xff << USBD_INTEN_ENDEPOUT0_Pos) |
+ USBD_INTENCLR_ENDISOIN_Msk | USBD_INTEN_ENDISOOUT_Msk
+};
+
+/*------------------------------------------------------------------*/
+/* VARIABLE DECLARATION
+ *------------------------------------------------------------------*/
+typedef struct
+{
+ uint8_t* buffer;
+ uint16_t total_len;
+ volatile uint16_t actual_len;
+ uint8_t mps; // max packet size
+
+ // nrf52840 will auto ACK OUT packet after DMA is done
+ // indicate packet is already ACK
+ volatile bool data_received;
+
+} nom_xfer_t;
+
+/*static*/ struct
+{
+ struct
+ {
+ uint8_t* buffer;
+ uint16_t total_len;
+ volatile uint16_t actual_len;
+
+ uint8_t dir;
+ }control;
+
+ // Non control: 7 endpoints IN & OUT (offset 1)
+ nom_xfer_t xfer[7][2];
+
+ volatile bool dma_running;
+}_dcd;
+
+void bus_reset(void)
+{
+ for(int i=0; i<8; i++)
+ {
+ NRF_USBD->TASKS_STARTEPIN[i] = 0;
+ NRF_USBD->TASKS_STARTEPOUT[i] = 0;
+ }
+
+ NRF_USBD->TASKS_STARTISOIN = 0;
+ NRF_USBD->TASKS_STARTISOOUT = 0;
+
+ tu_varclr(&_dcd);
+}
+
+/*------------------------------------------------------------------*/
+/* Controller API
+ *------------------------------------------------------------------*/
+bool dcd_init (uint8_t rhport)
+{
+ (void) rhport;
+ return true;
+}
+
+void dcd_connect (uint8_t rhport)
+{
+
+}
+void dcd_disconnect (uint8_t rhport)
+{
+
+}
+
+void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
+{
+ (void) rhport;
+ // Set Address is automatically update by hw controller
+}
+
+void dcd_set_config (uint8_t rhport, uint8_t config_num)
+{
+ (void) rhport;
+ (void) config_num;
+ // Nothing to do
+}
+
+/*------------------------------------------------------------------*/
+/* Control
+ *------------------------------------------------------------------*/
+static void edpt_dma_start(volatile uint32_t* reg_startep)
+{
+ // Only one dma can be active
+ if ( _dcd.dma_running )
+ {
+ if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)
+ {
+ // If called within ISR, use usbd task to defer later
+ usbd_defer_func( (osal_task_func_t) edpt_dma_start, (void*) reg_startep, true );
+ return;
+ }
+ else
+ {
+ // Otherwise simply block wait
+ while ( _dcd.dma_running ) { }
+ }
+ }
+
+ _dcd.dma_running = true;
+
+ (*reg_startep) = 1;
+ __ISB(); __DSB();
+}
+
+static void edpt_dma_end(void)
+{
+ TU_ASSERT(_dcd.dma_running, );
+
+ _dcd.dma_running = false;
+}
+
+static void xact_control_start(void)
+{
+ // Each transaction is up to 64 bytes
+ uint8_t const xact_len = tu_min16(_dcd.control.total_len-_dcd.control.actual_len, MAX_PACKET_SIZE);
+
+ if ( _dcd.control.dir == TUSB_DIR_OUT )
+ {
+ // TODO control out
+ NRF_USBD->EPOUT[0].PTR = (uint32_t) _dcd.control.buffer;
+ NRF_USBD->EPOUT[0].MAXCNT = xact_len;
+
+ NRF_USBD->TASKS_EP0RCVOUT = 1;
+ __ISB(); __DSB();
+ }else
+ {
+ NRF_USBD->EPIN[0].PTR = (uint32_t) _dcd.control.buffer;
+ NRF_USBD->EPIN[0].MAXCNT = xact_len;
+
+ edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[0]);
+ }
+
+ _dcd.control.buffer += xact_len;
+ _dcd.control.actual_len += xact_len;
+}
+
+bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length)
+{
+ (void) rhport;
+
+ if ( length )
+ {
+ // Data Phase
+ _dcd.control.total_len = length;
+ _dcd.control.actual_len = 0;
+ _dcd.control.buffer = buffer;
+ _dcd.control.dir = dir;
+
+ xact_control_start();
+ }else
+ {
+ // Status Phase also require Easy DMA has to be free as well !!!!
+ edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS);
+ edpt_dma_end();
+ }
+
+ return true;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ *------------------------------------------------------------------*/
+
+static inline nom_xfer_t* get_td(uint8_t epnum, uint8_t dir)
+{
+ return &_dcd.xfer[epnum-1][dir];
+}
+
+/*------------- Bulk/Int OUT transfer -------------*/
+
+/**
+ * Prepare Bulk/Int out transaction, Endpoint start to accept/ACK Data
+ * @param epnum
+ */
+static void xact_out_prepare(uint8_t epnum)
+{
+ // Write zero value to SIZE register will allow hw to ACK (accept data)
+ // If it is not already done by DMA
+ NRF_USBD->SIZE.EPOUT[epnum] = 0;
+ __ISB(); __DSB();
+}
+
+static void xact_out_dma(uint8_t epnum)
+{
+ nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
+
+ uint8_t const xact_len = NRF_USBD->SIZE.EPOUT[epnum];
+
+ // Trigger DMA move data from Endpoint -> SRAM
+ NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer;
+ NRF_USBD->EPOUT[epnum].MAXCNT = xact_len;
+
+ edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]);
+
+ xfer->buffer += xact_len;
+ xfer->actual_len += xact_len;
+}
+
+
+/*------------- Bulk/Int IN transfer -------------*/
+
+/**
+ * Prepare Bulk/Int in transaction, use DMA to transfer data from Memory -> Endpoint
+ * @param epnum
+ */
+static void xact_in_prepare(uint8_t epnum)
+{
+ nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_IN);
+
+ // Each transaction is up to Max Packet Size
+ uint8_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps);
+
+ NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer;
+ NRF_USBD->EPIN[epnum].MAXCNT = xact_len;
+
+ xfer->buffer += xact_len;
+
+ edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]);
+}
+
+bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
+{
+ (void) rhport;
+
+ uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress);
+ uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress);
+
+ _dcd.xfer[epnum-1][dir].mps = desc_edpt->wMaxPacketSize.size;
+
+ if ( dir == TUSB_DIR_OUT )
+ {
+ NRF_USBD->INTENSET = BIT_(USBD_INTEN_ENDEPOUT0_Pos + epnum);
+ NRF_USBD->EPOUTEN |= BIT_(epnum);
+ }else
+ {
+ NRF_USBD->INTENSET = BIT_(USBD_INTEN_ENDEPIN0_Pos + epnum);
+ NRF_USBD->EPINEN |= BIT_(epnum);
+ }
+ __ISB(); __DSB();
+
+ return true;
+}
+
+bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ uint8_t const epnum = edpt_number(ep_addr);
+ uint8_t const dir = edpt_dir(ep_addr);
+
+ nom_xfer_t* xfer = get_td(epnum, dir);
+
+ xfer->buffer = buffer;
+ xfer->total_len = total_bytes;
+ xfer->actual_len = 0;
+
+ if ( dir == TUSB_DIR_OUT )
+ {
+ if ( xfer->data_received )
+ {
+ // nrf52840 auto ACK OUT packet after DMA is done
+ // Data already received previously --> trigger DMA to copy to SRAM
+ xact_out_dma(epnum);
+ }else
+ {
+ xact_out_prepare(epnum);
+ }
+ }else
+ {
+ xact_in_prepare(epnum);
+ }
+
+ return true;
+}
+
+bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+
+ // control is never got halted
+ if ( ep_addr == 0 ) return false;
+
+ uint8_t const epnum = edpt_number(ep_addr);
+ return (edpt_dir(ep_addr) == TUSB_DIR_IN ) ? NRF_USBD->HALTED.EPIN[epnum] : NRF_USBD->HALTED.EPOUT[epnum];
+}
+
+void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+
+ if ( ep_addr == 0)
+ {
+ NRF_USBD->TASKS_EP0STALL = 1;
+ }else
+ {
+ NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep_addr;
+ }
+
+ __ISB(); __DSB();
+}
+
+void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+
+ if ( ep_addr )
+ {
+ NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr;
+ __ISB(); __DSB();
+ }
+}
+
+bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+
+ // USBD shouldn't check control endpoint state
+ if ( 0 == ep_addr ) return false;
+
+ uint8_t const epnum = edpt_number(ep_addr);
+ uint8_t const dir = edpt_dir(ep_addr);
+
+ nom_xfer_t* xfer = get_td(epnum, dir);
+
+ return xfer->actual_len < xfer->total_len;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ *------------------------------------------------------------------*/
+void USBD_IRQHandler(void)
+{
+ uint32_t const inten = NRF_USBD->INTEN;
+ uint32_t int_status = 0;
+
+ volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET;
+
+ for(int i=0; i<USBD_INTEN_EPDATA_Pos+1; i++)
+ {
+ if ( BIT_TEST_(inten, i) && regevt[i] )
+ {
+ int_status |= BIT_(i);
+
+ // event clear
+ regevt[i] = 0;
+ __ISB(); __DSB();
+ }
+ }
+
+ /*------------- Interrupt Processing -------------*/
+ if ( int_status & USBD_INTEN_USBRESET_Msk )
+ {
+ bus_reset();
+ dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true);
+ }
+
+ if ( int_status & EDPT_END_ALL_MASK )
+ {
+ // DMA complete move data from SRAM -> Endpoint
+ edpt_dma_end();
+ }
+
+ /*------------- Control Transfer -------------*/
+ if ( int_status & USBD_INTEN_EP0SETUP_Msk )
+ {
+ uint8_t setup[8] = {
+ NRF_USBD->BMREQUESTTYPE , NRF_USBD->BREQUEST, NRF_USBD->WVALUEL , NRF_USBD->WVALUEH,
+ NRF_USBD->WINDEXL , NRF_USBD->WINDEXH , NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH
+ };
+ dcd_event_setup_recieved(0, setup, true);
+ }
+
+ if ( int_status & USBD_INTEN_EP0DATADONE_Msk )
+ {
+ if ( _dcd.control.dir == TUSB_DIR_OUT )
+ {
+ // Control OUT: data from Host -> Endpoint
+ // Trigger DMA to move Endpoint -> SRAM
+ edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[0]);
+ }else
+ {
+ // Control IN: data transferred from Endpoint -> Host
+ if ( _dcd.control.actual_len < _dcd.control.total_len )
+ {
+ xact_control_start();
+ }else
+ {
+ // Control IN complete
+ dcd_event_xfer_complete(0, 0, _dcd.control.actual_len, DCD_XFER_SUCCESS, true);
+ }
+ }
+ }
+
+ // Control OUT: data from Endpoint -> SRAM
+ if ( int_status & USBD_INTEN_ENDEPOUT0_Msk)
+ {
+ if ( _dcd.control.actual_len < _dcd.control.total_len )
+ {
+ xact_control_start();
+ }else
+ {
+ // Control OUT complete
+ dcd_event_xfer_complete(0, 0, _dcd.control.actual_len, DCD_XFER_SUCCESS, true);
+ }
+ }
+
+ /*------------- Bulk/Interrupt Transfer -------------*/
+
+ /* Bulk/Int OUT: data from DMA -> SRAM
+ * Note: Since nrf controller auto ACK next packet without SW awareness
+ * We must handle this stage before Host -> Endpoint just in case
+ * 2 event happens at once
+ */
+ for(uint8_t epnum=1; epnum<8; epnum++)
+ {
+ if ( BIT_TEST_(int_status, USBD_INTEN_ENDEPOUT0_Pos+epnum) )
+ {
+ nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
+
+ uint8_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT;
+
+ xfer->data_received = false;
+
+ // Transfer complete if transaction len < Max Packet Size or total len is transferred
+ if ( (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len) )
+ {
+ // Prepare for next transaction
+ xact_out_prepare(epnum);
+ }else
+ {
+ xfer->total_len = xfer->actual_len;
+
+ // BULK/INT OUT complete
+ dcd_event_xfer_complete(0, epnum, xfer->actual_len, DCD_XFER_SUCCESS, true);
+ }
+ }
+
+ // Ended event for Bulk/Int : nothing to do
+ }
+
+ if ( int_status & USBD_INTEN_EPDATA_Msk)
+ {
+ uint32_t data_status = NRF_USBD->EPDATASTATUS;
+
+ nrf_usbd_epdatastatus_clear(data_status);
+
+ // Bulk/Int In: data from Endpoint -> Host
+ for(uint8_t epnum=1; epnum<8; epnum++)
+ {
+ if ( BIT_TEST_(data_status, epnum ) )
+ {
+ nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_IN);
+
+ xfer->actual_len += NRF_USBD->EPIN[epnum].MAXCNT;
+
+ if ( xfer->actual_len < xfer->total_len )
+ {
+ // prepare next transaction
+ xact_in_prepare(epnum);
+ } else
+ {
+ // Bulk/Int IN complete
+ dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, DCD_XFER_SUCCESS, true);
+ }
+ }
+ }
+
+ // Bulk/Int OUT: data from Host -> Endpoint
+ for(uint8_t epnum=1; epnum<8; epnum++)
+ {
+ if ( BIT_TEST_(data_status, 16+epnum ) )
+ {
+ nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
+
+ if (xfer->actual_len < xfer->total_len)
+ {
+ xact_out_dma(epnum);
+ }else
+ {
+ // Data overflow !!! Nah, nrf52840 will auto ACK OUT packet after DMA is done
+ // Mark this endpoint with data received
+ xfer->data_received = true;
+ }
+ }
+ }
+ }
+
+ // SOF interrupt
+ if ( int_status & USBD_INTEN_SOF_Msk )
+ {
+ dcd_event_bus_signal(0, DCD_EVENT_SOF, true);
+ }
+}
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c b/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c new file mode 100755 index 0000000..a371590 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c @@ -0,0 +1,303 @@ +/**************************************************************************/
+/*!
+ @file hal_nrf5x.c
+ @author hathach
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2018, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X
+
+#include "nrf.h"
+#include "nrf_gpio.h"
+#include "nrf_clock.h"
+#include "nrf_usbd.h"
+#include "nrf_drv_usbd_errata.h"
+
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_sdm.h"
+#include "nrf_soc.h"
+
+// TODO fully move to nrfx
+enum {
+ NRFX_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
+ NRFX_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */
+ NRFX_POWER_USB_EVT_READY /**< USB power regulator ready. */
+};
+#else
+#include "nrfx_power.h"
+#endif
+
+#include "tusb_hal.h"
+
+/*------------------------------------------------------------------*/
+/* MACRO TYPEDEF CONSTANT ENUM
+ *------------------------------------------------------------------*/
+// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
+// 2 is highest for application
+#define USB_NVIC_PRIO 2
+
+void tusb_hal_nrf_power_event(uint32_t event);
+
+/*------------------------------------------------------------------*/
+/* HFCLK helper
+ *------------------------------------------------------------------*/
+
+#ifdef SOFTDEVICE_PRESENT
+// check if SD is present and enabled
+static bool is_sd_enabled(void)
+{
+ uint8_t sd_en = false;
+ (void) sd_softdevice_is_enabled(&sd_en);
+ return sd_en;
+}
+#endif
+
+static bool hfclk_running(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ if ( is_sd_enabled() )
+ {
+ uint32_t is_running;
+ (void) sd_clock_hfclk_is_running(&is_running);
+ return (is_running ? true : false);
+ }
+#endif
+
+ return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
+}
+
+static void hfclk_enable(void)
+{
+ // already running, nothing to do
+ if ( hfclk_running() ) return;
+
+#ifdef SOFTDEVICE_PRESENT
+ if ( is_sd_enabled() )
+ {
+ (void)sd_clock_hfclk_request();
+ return;
+ }
+#endif
+
+ nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
+ nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);
+}
+
+static void hfclk_disable(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ if ( is_sd_enabled() )
+ {
+ (void)sd_clock_hfclk_release();
+ return;
+ }
+#endif
+
+ nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);
+}
+
+
+/*------------------------------------------------------------------*/
+/* TUSB HAL
+ *------------------------------------------------------------------*/
+bool tusb_hal_init(void)
+{
+ return true;
+}
+
+void tusb_hal_int_enable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_EnableIRQ(USBD_IRQn);
+}
+
+void tusb_hal_int_disable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_DisableIRQ(USBD_IRQn);
+}
+
+/*------------------------------------------------------------------*/
+/* Controller Start up Sequence (USBD 51.4 specs)
+ *------------------------------------------------------------------*/
+// tusb_hal_nrf_power_event must be called by SOC event handler
+void tusb_hal_nrf_power_event (uint32_t event)
+{
+ switch ( event )
+ {
+ case NRFX_POWER_USB_EVT_DETECTED:
+ if ( !NRF_USBD->ENABLE )
+ {
+ /* Prepare for READY event receiving */
+ nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
+
+ /* Enable the peripheral */
+ // ERRATA 171, 187, 166
+
+ // Somehow Errata 187 check failed for pca10056 1.0.0 (2018.19)
+ if ( nrf_drv_usbd_errata_187() )
+ {
+ // CRITICAL_REGION_ENTER();
+ if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 )
+ {
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *) (0x4006ED14)) = 0x00000003;
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *) (0x4006ED14)) = 0x00000003;
+ }
+ // CRITICAL_REGION_EXIT();
+ }
+
+ if ( nrf_drv_usbd_errata_171() )
+ {
+ // CRITICAL_REGION_ENTER();
+ if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 )
+ {
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0;
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0;
+ }
+ // CRITICAL_REGION_EXIT();
+ }
+
+ nrf_usbd_enable();
+
+ // Enable HFCLK
+ hfclk_enable();
+ }
+ break;
+
+ case NRFX_POWER_USB_EVT_READY:
+ /* Waiting for USBD peripheral enabled */
+ while ( !(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE) ) { }
+
+ nrf_usbd_eventcause_clear(USBD_EVENTCAUSE_READY_Msk);
+ nrf_usbd_event_clear(USBD_EVENTCAUSE_READY_Msk);
+
+ if ( nrf_drv_usbd_errata_171() )
+ {
+ // CRITICAL_REGION_ENTER();
+ if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 )
+ {
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *) (0x4006EC14)) = 0x00000000;
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *) (0x4006EC14)) = 0x00000000;
+ }
+
+ // CRITICAL_REGION_EXIT();
+ }
+
+ // Somehow Errata 187 check failed for pca10056 1.0.0 (2018.19)
+ if ( nrf_drv_usbd_errata_187() )
+ {
+ // CRITICAL_REGION_ENTER();
+ if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 )
+ {
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *) (0x4006ED14)) = 0x00000000;
+ *((volatile uint32_t *) (0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *) (0x4006ED14)) = 0x00000000;
+ }
+ // CRITICAL_REGION_EXIT();
+ }
+
+ if ( nrf_drv_usbd_errata_166() )
+ {
+ *((volatile uint32_t *) (NRF_USBD_BASE + 0x800)) = 0x7E3;
+ *((volatile uint32_t *) (NRF_USBD_BASE + 0x804)) = 0x40;
+
+ __ISB();
+ __DSB();
+ }
+
+ nrf_usbd_isosplit_set(USBD_ISOSPLIT_SPLIT_HalfIN);
+
+ // Enable interrupt. SOF is used as CDC auto flush
+ NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk |
+ USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk;
+
+ // Enable interrupt
+ NVIC_SetPriority(USBD_IRQn, USB_NVIC_PRIO);
+ NVIC_ClearPendingIRQ(USBD_IRQn);
+ NVIC_EnableIRQ(USBD_IRQn);
+
+ // Wait for HFCLK
+ while ( !hfclk_running() )
+ {
+ }
+
+ // Enable pull up
+ nrf_usbd_pullup_enable();
+ break;
+
+ case NRFX_POWER_USB_EVT_REMOVED:
+ if ( NRF_USBD->ENABLE )
+ {
+ // Abort all transfers
+
+ // Disable pull up
+ nrf_usbd_pullup_disable();
+
+ // Disable Interrupt
+ NVIC_DisableIRQ(USBD_IRQn);
+
+ // disable all interrupt
+ NRF_USBD->INTENCLR = NRF_USBD->INTEN;
+
+ nrf_usbd_disable();
+ hfclk_disable();
+ }
+ break;
+
+ default: break;
+ }
+}
+
+#endif
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/nrf_drv_usbd_errata.h b/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/nrf_drv_usbd_errata.h new file mode 100755 index 0000000..01cc4c9 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/portable/nordic/nrf5x/nrf_drv_usbd_errata.h @@ -0,0 +1,193 @@ +/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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.
+ *
+ */
+
+#ifndef NRF_DRV_USBD_ERRATA_H__
+#define NRF_DRV_USBD_ERRATA_H__
+
+#include <stdbool.h>
+/**
+ * @defgroup nrf_drv_usbd_errata Functions to check if selected PAN is present in current chip
+ * @{
+ * @ingroup nrf_drv_usbd
+ *
+ * Functions here are checking the presence of an error in current chip.
+ * The checking is done at runtime based on the microcontroller version.
+ * This file is subject to removal when nRF51840 prototype support is removed.
+ */
+
+#ifndef NRF_DRV_USBD_ERRATA_ENABLE
+/**
+ * @brief The constant that informs if errata should be enabled at all
+ *
+ * If this constant is set to 0, all the Errata bug fixes will be automatically disabled.
+ */
+#define NRF_DRV_USBD_ERRATA_ENABLE 1
+#endif
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on NRF52840 chip
+ * @retval true It is NRF52480 chip
+ * @retval false It is other chip
+ */
+static inline bool nrf_drv_usbd_errata_type_52840(void)
+{
+ return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
+ (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on first sample of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is first sample version
+ * @retval false It is other chip
+ */
+static inline bool nrf_drv_usbd_errata_type_52840_proto1(void)
+{
+ return ( nrf_drv_usbd_errata_type_52840() &&
+ ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on first final product of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is first final product
+ * @retval false It is other chip
+ */
+static inline bool nrf_drv_usbd_errata_type_52840_fp1(void)
+{
+ return ( nrf_drv_usbd_errata_type_52840() &&
+ ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x20 ) &&
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
+}
+
+/**
+ * @brief Function to check if chip requires errata 104
+ *
+ * Errata: USBD: EPDATA event is not always generated.
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_104(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
+}
+
+/**
+ * @brief Function to check if chip requires errata 154
+ *
+ * Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task.
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_154(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
+}
+
+/**
+ * @brief Function to check if chip requires errata 166
+ *
+ * Errata: ISO double buffering not functional
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_166(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && true;
+}
+
+/**
+ * @brief Function to check if chip requires errata 171
+ *
+ * Errata: USBD might not reach its active state.
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_171(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && true;
+}
+
+/**
+ * @brief Function to check if chip requires errata 187
+ *
+ * Errata: USB cannot be enabled
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_187(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_fp1();
+}
+
+/**
+ * @brief Function to check if chip requires errata ???
+ *
+ * Errata: SIZE.EPOUT not writable
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_sizeepout_rw(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
+}
+
+/**
+ * @brief Function to check if chip requires errata 199
+ *
+ * Errata: USBD cannot receive tasks during DMA
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usb_errata_199(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && true;
+}
+
+/** @} */
+#endif /* NRF_DRV_USBD_ERRATA_H__ */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/portable/readme.md b/arduino/cores/nRF5/usb/tinyusb/src/portable/readme.md new file mode 100755 index 0000000..70dd7f0 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/portable/readme.md @@ -0,0 +1,4 @@ +To port tinyusb to support new MCU you need to implement all API in the
+- tusb_hal.h (mandatory for both device and host stack)
+- device/dcd.h for device stack
+- host/hcd.h for host stack
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/tusb.c b/arduino/cores/nRF5/usb/tinyusb/src/tusb.c new file mode 100755 index 0000000..e9db184 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/tusb.c @@ -0,0 +1,92 @@ +/**************************************************************************/
+/*!
+ @file tusb.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_HOST_ENABLED || TUSB_OPT_DEVICE_ENABLED
+
+#define _TINY_USB_SOURCE_FILE_
+
+#include "tusb.h"
+#include "device/usbd_pvt.h"
+
+static bool _initialized = false;
+
+
+tusb_error_t tusb_init(void)
+{
+ // skip if already initialized
+ if (_initialized) return TUSB_ERROR_NONE;
+
+ TU_VERIFY( tusb_hal_init(), TUSB_ERROR_FAILED ) ; // hardware init
+
+#if MODE_HOST_SUPPORTED
+ TU_ASSERT_ERR( usbh_init() ); // host stack init
+#endif
+
+#if TUSB_OPT_DEVICE_ENABLED
+ TU_ASSERT_ERR ( usbd_init() ); // device stack init
+#endif
+
+ _initialized = true;
+
+ return TUSB_ERROR_NONE;
+}
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+void tusb_task(void)
+{
+ #if MODE_HOST_SUPPORTED
+ usbh_enumeration_task(NULL);
+ #endif
+
+ #if TUSB_OPT_DEVICE_ENABLED
+ usbd_task(NULL);
+ #endif
+}
+#endif
+
+
+/*------------------------------------------------------------------*/
+/* Debug
+ *------------------------------------------------------------------*/
+#if CFG_TUSB_DEBUG
+char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) };
+#endif
+
+#endif // host or device enabled
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/tusb.h b/arduino/cores/nRF5/usb/tinyusb/src/tusb.h new file mode 100755 index 0000000..c0246cc --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/tusb.h @@ -0,0 +1,143 @@ +/**************************************************************************/
+/*!
+ @file tusb.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_H_
+#define _TUSB_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "common/tusb_common.h"
+#include "tusb_hal.h"
+#include "osal/osal.h"
+#include "common/tusb_fifo.h"
+
+//------------- HOST -------------//
+#if MODE_HOST_SUPPORTED
+ #include "host/usbh.h"
+
+ #if HOST_CLASS_HID
+ #include "class/hid/hid_host.h"
+ #endif
+
+ #if CFG_TUSB_HOST_MSC
+ #include "class/msc/msc_host.h"
+ #endif
+
+ #if CFG_TUSB_HOST_CDC
+ #include "class/cdc/cdc_host.h"
+ #endif
+
+ #if CFG_TUSB_HOST_CUSTOM_CLASS
+ #include "class/custom_host.h"
+ #endif
+
+#endif
+
+//------------- DEVICE -------------//
+#if TUSB_OPT_DEVICE_ENABLED
+ #include "device/usbd.h"
+
+ #if CFG_TUD_HID
+ #include "class/hid/hid_device.h"
+ #endif
+
+ #if CFG_TUD_CDC
+ #include "class/cdc/cdc_device.h"
+ #endif
+
+ #if CFG_TUD_MSC
+ #include "class/msc/msc_device.h"
+ #endif
+
+ #if CFG_TUD_CUSTOM_CLASS
+ #include "class/custom/custom_device.h"
+ #endif
+#endif
+
+
+//--------------------------------------------------------------------+
+// APPLICATION API
+//--------------------------------------------------------------------+
+/** \ingroup group_application_api
+ * @{ */
+
+/** \brief Initialize the usb stack
+ * \return Error Code of the \ref TUSB_ERROR enum
+ * \note Function will initialize the stack according to configuration in the configure file (tusb_config.h)
+ */
+tusb_error_t tusb_init(void);
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+/** \brief Run all tinyusb's internal tasks (e.g host task, device task).
+ * \note This function is only required when using no RTOS (\ref CFG_TUSB_OS == OPT_OS_NONE). All the stack functions
+ * & callback are invoked within this function, so it should be called periodically within the mainloop
+ *
+ @code
+ int main(void)
+ {
+ your_init_code();
+ tusb_init();
+
+ // other config code
+
+ while(1) // the mainloop
+ {
+ your_application_code();
+
+ tusb_task(); // handle tinyusb event, task etc ...
+ }
+ }
+ @endcode
+ *
+ */
+void tusb_task(void);
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_H_ */
+
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/tusb_hal.h b/arduino/cores/nRF5/usb/tinyusb/src/tusb_hal.h new file mode 100755 index 0000000..85a2a87 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/tusb_hal.h @@ -0,0 +1,114 @@ +/**************************************************************************/
+/*!
+ @file hal.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_HAL_H_
+#define _TUSB_HAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// INCLUDES
+//--------------------------------------------------------------------+
+#include "common/tusb_common.h"
+
+//--------------------------------------------------------------------+
+// HAL API
+//--------------------------------------------------------------------+
+/** \ingroup group_mcu
+ * \defgroup group_hal Hardware Abtract Layer (HAL)
+ * Hardware Abstraction Layer (HAL) is an abstraction layer, between the physical hardware and the tinyusb stack.
+ * Its function is to hide differences in hardware from most of MCUs, so that most of the stack code does not need to be changed to
+ * run on systems with a different MCU.
+ * HAL are sets of routines that emulate some platform-specific details, giving programs direct access to the hardware resources.
+ * @{ */
+
+/** \brief Initialize USB controller hardware
+ * \returns true if succeeded
+ * \note This function is invoked by \ref tusb_init as part of the initialization.
+ */
+bool tusb_hal_init(void);
+
+/** \brief Enable USB Interrupt on a specific USB Controller
+ * \param[in] rhport is a zero-based index to identify USB controller's ID
+ */
+void tusb_hal_int_enable(uint8_t rhport);
+
+/** \brief Disable USB Interrupt on a specific USB Controller
+ * \param[in] rhport is a zero-based index to identify USB controller's ID
+ */
+void tusb_hal_int_disable(uint8_t rhport);
+
+// Only required to implement if using No RTOS (osal_none)
+uint32_t tusb_hal_millis(void);
+
+
+// Enable all ports' interrupt
+static inline void tusb_hal_int_enable_all(void)
+{
+#ifdef CFG_TUSB_RHPORT0_MODE
+ tusb_hal_int_enable(0);
+#endif
+
+#ifdef CFG_TUSB_RHPORT0_MODE
+ tusb_hal_int_enable(1);
+#endif
+}
+
+// Disable all ports' interrupt
+static inline void tusb_hal_int_disable_all(void)
+{
+#ifdef CFG_TUSB_RHPORT0_MODE
+ tusb_hal_int_disable(0);
+#endif
+
+#ifdef CFG_TUSB_RHPORT0_MODE
+ tusb_hal_int_disable(1);
+#endif
+}
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_HAL_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tinyusb/src/tusb_option.h b/arduino/cores/nRF5/usb/tinyusb/src/tusb_option.h new file mode 100755 index 0000000..8463671 --- /dev/null +++ b/arduino/cores/nRF5/usb/tinyusb/src/tusb_option.h @@ -0,0 +1,224 @@ +/**************************************************************************/
+/*!
+ @file tusb_option.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_OPTION_H_
+#define _TUSB_OPTION_H_
+
+#define TUSB_VERSION_YEAR 00
+#define TUSB_VERSION_MONTH 00
+#define TUSB_VERSION_WEEK 0
+#define TUSB_VERSION_NAME "alpha"
+#define TUSB_VERSION XSTRING_(TUSB_VERSION_YEAR) "." XSTRING_(TUSB_VERSION_MONTH)
+
+/** \defgroup group_mcu Supported MCU
+ * \ref CFG_TUSB_MCU must be defined to one of these
+ * @{ */
+#define OPT_MCU_LPC11UXX 1 ///< NXP LPC11Uxx series
+#define OPT_MCU_LPC13XX 2 ///< NXP LPC13xx (not supported yet)
+#define OPT_MCU_LPC13UXX 3 ///< NXP LPC13xx 12 bit ADC series
+#define OPT_MCU_LPC175X_6X 4 ///< NXP LPC175x, LPC176x series
+#define OPT_MCU_LPC177X_8X 5 ///< NXP LPC177x, LPC178x series (not supported yet)
+#define OPT_MCU_LPC18XX 6 ///< NXP LPC18xx series (not supported yet)
+#define OPT_MCU_LPC43XX 7 ///< NXP LPC43xx series
+
+#define OPT_MCU_NRF5X 100 ///< Nordic nRF5x series
+/** @} */
+
+/** \defgroup group_supported_os Supported RTOS
+ * \ref CFG_TUSB_OS must be defined to one of these
+ * @{ */
+#define OPT_OS_NONE 1 ///< No RTOS
+#define OPT_OS_FREERTOS 2 ///< FreeRTOS
+#define OPT_OS_MYNEWT 3 ///< Mynewt OS
+/** @} */
+
+
+// Allow to use command line to change the config name/location
+#ifndef CFG_TUSB_CONFIG_FILE
+ #define CFG_TUSB_CONFIG_FILE "tusb_config.h"
+#endif
+
+#include CFG_TUSB_CONFIG_FILE
+
+/** \addtogroup group_configuration
+ * @{ */
+
+//--------------------------------------------------------------------
+// CONTROLLER
+//--------------------------------------------------------------------
+/** \defgroup group_mode Controller Mode Selection
+ * \brief CFG_TUSB_CONTROLLER_N_MODE must be defined with these
+ * @{ */
+#define OPT_MODE_HOST 0x02 ///< Host Mode
+#define OPT_MODE_DEVICE 0x01 ///< Device Mode
+#define OPT_MODE_NONE 0x00 ///< Disabled
+/** @} */
+
+#ifndef CFG_TUSB_RHPORT0_MODE
+ #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
+#endif
+
+#ifndef CFG_TUSB_RHPORT1_MODE
+ #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE
+#endif
+
+#define CONTROLLER_HOST_NUMBER (\
+ ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 1 : 0) + \
+ ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : 0))
+
+#define MODE_HOST_SUPPORTED (CONTROLLER_HOST_NUMBER > 0)
+
+#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) )
+#define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 )
+
+#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) )
+#define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 )
+
+#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST)) || ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE))
+ #error "tinyusb does not support same modes on more than 1 roothub port"
+#endif
+
+//--------------------------------------------------------------------+
+// COMMON OPTIONS
+//--------------------------------------------------------------------+
+/**
+ determines the debug level for the stack
+ - Level 3: TBD
+ - Level 2: TBD
+ - Level 1: Print out if Assert failed. STATIC_VAR is NULL --> accessible when debugging
+ - Level 0: no debug information is generated
+*/
+#ifndef CFG_TUSB_DEBUG
+ #define CFG_TUSB_DEBUG 0
+ #warning CFG_TUSB_DEBUG is not defined, default value is 0
+#endif
+
+#ifndef CFG_TUSB_ATTR_USBRAM
+ #error CFG_TUSB_ATTR_USBRAM is not defined, please help me know how to place data in accessible RAM for usb controller
+#endif
+
+#ifndef CFG_TUSB_OS
+#define CFG_TUSB_OS OPT_OS_NONE
+#endif
+
+//--------------------------------------------------------------------
+// DEVICE OPTIONS
+//--------------------------------------------------------------------
+#if TUSB_OPT_DEVICE_ENABLED
+
+ #ifndef CFG_TUD_ENDOINT0_SIZE
+ #define CFG_TUD_ENDOINT0_SIZE 64
+ #endif
+
+ #ifndef CFG_TUD_ENUM_BUFFER_SIZE
+ #define CFG_TUD_CTRL_BUFSIZE 256
+ #endif
+
+ #ifndef CFG_TUD_DESC_AUTO
+ #define CFG_TUD_DESC_AUTO 0
+ #endif
+
+ #ifndef CFG_TUD_CDC
+ #define CFG_TUD_CDC 0
+ #endif
+
+ #ifndef CFG_TUD_MSC
+ #define CFG_TUD_MSC 0
+ #endif
+
+ #ifndef CFG_TUD_HID_KEYBOARD
+ #define CFG_TUD_HID_KEYBOARD 0
+ #endif
+
+ #ifndef CFG_TUD_HID_MOUSE
+ #define CFG_TUD_HID_MOUSE 0
+ #endif
+
+ #ifndef CFG_TUD_HID_KEYBOARD_BOOT
+ #define CFG_TUD_HID_KEYBOARD_BOOT 0
+ #endif
+
+ #ifndef CFG_TUD_HID_MOUSE_BOOT
+ #define CFG_TUD_HID_MOUSE_BOOT 0
+ #endif
+
+#endif // TUSB_OPT_DEVICE_ENABLED
+
+//--------------------------------------------------------------------
+// HOST OPTIONS
+//--------------------------------------------------------------------
+#if MODE_HOST_SUPPORTED
+ #ifndef CFG_TUSB_HOST_DEVICE_MAX
+ #define CFG_TUSB_HOST_DEVICE_MAX 1
+ #warning CFG_TUSB_HOST_DEVICE_MAX is not defined, default value is 1
+ #endif
+
+ //------------- HUB CLASS -------------//
+ #if CFG_TUSB_HOST_HUB && (CFG_TUSB_HOST_DEVICE_MAX == 1)
+ #error there is no benefit enable hub with max device is 1. Please disable hub or increase CFG_TUSB_HOST_DEVICE_MAX
+ #endif
+
+ //------------- HID CLASS -------------//
+ #define HOST_CLASS_HID ( CFG_TUSB_HOST_HID_KEYBOARD + CFG_TUSB_HOST_HID_MOUSE + CFG_TUSB_HOST_HID_GENERIC )
+// #if HOST_CLASS_HID
+// #define HOST_HCD_XFER_INTERRUPT
+// #endif
+
+ #ifndef CFG_TUSB_HOST_ENUM_BUFFER_SIZE
+ #define CFG_TUSB_HOST_ENUM_BUFFER_SIZE 256
+ #endif
+
+ //------------- CLASS -------------//
+#endif // MODE_HOST_SUPPORTED
+
+
+//------------------------------------------------------------------
+// Configuration Validation
+//------------------------------------------------------------------
+
+#if (CFG_TUSB_OS != OPT_OS_NONE) && !defined (CFG_TUD_TASK_PRIO)
+ #error CFG_TUD_TASK_PRIO need to be defined (hint: use the highest if possible)
+#endif
+
+#if CFG_TUD_ENDOINT0_SIZE > 64
+ #error Control Endpoint Max Package Size cannot larger than 64
+#endif
+
+#endif /* _TUSB_OPTION_H_ */
+
+/** @} */
diff --git a/arduino/cores/nRF5/usb/tusb_config.h b/arduino/cores/nRF5/usb/tusb_config.h new file mode 100755 index 0000000..5c1ffd0 --- /dev/null +++ b/arduino/cores/nRF5/usb/tusb_config.h @@ -0,0 +1,165 @@ +/**************************************************************************/
+/*!
+ @file tusb_config.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_CONFIG_H_
+#define _TUSB_CONFIG_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------
+// COMMON CONFIGURATION
+//--------------------------------------------------------------------
+#define CFG_TUSB_MCU OPT_MCU_NRF5X
+
+#ifdef NRF52840_XXAA
+#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
+#else
+#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
+#endif
+
+#define CFG_TUSB_DEBUG 0
+
+/*------------- RTOS -------------*/
+#define CFG_TUSB_OS OPT_OS_FREERTOS
+#define CFG_TUD_TASK_PRIO (configMAX_PRIORITIES-2) // TASK_PRIO_HIGH = Bluefruit Task
+//#define CFG_TUD_TASK_QUEUE_SZ 16
+//#define CFG_TUD_TASK_STACK_SZ 150
+
+//--------------------------------------------------------------------
+// DEVICE CONFIGURATION
+//--------------------------------------------------------------------
+
+#define CFG_TUD_ENDOINT0_SIZE 64
+
+/*------------- Descriptors -------------*/
+
+/* Enable auto generated descriptor, tinyusb will try its best to create
+ * descriptor ( device, configuration, hid ) that matches enabled CFG_* in this file
+ *
+ * Note: All CFG_TUD_DESC_* are relevant only if CFG_TUD_DESC_AUTO is enabled
+ */
+#define CFG_TUD_DESC_AUTO 1
+
+/* USB VID/PID if not defined, tinyusb to use default value
+ * Note: different class combination e.g CDC and (CDC + MSC) should have different
+ * PID since Host OS will "remembered" device driver after the first plug */
+#define CFG_TUD_DESC_VID 0x239A
+#define CFG_TUD_DESC_PID 0x8029
+
+//------------- CLASS -------------//
+#define CFG_TUD_CDC 1
+
+// disable msc for feather nrf52840 for now until have a more stable QSPI driver
+#ifdef ARDUINO_NRF52840_FEATHER
+#define CFG_TUD_MSC 0
+#else
+#define CFG_TUD_MSC 1
+#endif
+
+
+#define CFG_TUD_HID 0
+#define CFG_TUD_HID_KEYBOARD 0
+#define CFG_TUD_HID_MOUSE 0
+
+/* Use Boot Protocol for Keyboard, Mouse. Enable this will create separated HID interface
+ * require more IN endpoints. If disabled, they they are all packed into a single
+ * multiple report interface called "Generic". */
+#define CFG_TUD_HID_KEYBOARD_BOOT 0
+#define CFG_TUD_HID_MOUSE_BOOT 0
+
+
+//--------------------------------------------------------------------
+// CDC
+//--------------------------------------------------------------------
+
+// FIFO size of CDC TX and RX
+#define CFG_TUD_CDC_RX_BUFSIZE 256
+#define CFG_TUD_CDC_TX_BUFSIZE 256
+
+//--------------------------------------------------------------------
+// MSC
+//--------------------------------------------------------------------
+
+// Number of supported Logical Unit Number (At least 1)
+#define CFG_TUD_MSC_MAXLUN 1
+
+// Buffer size of Device Mass storage
+#define CFG_TUD_MSC_BUFSIZE 512
+
+// Number of Blocks
+#include <stdint.h>
+extern uint32_t flash_qspi_size (void);
+#define CFG_TUD_MSC_BLOCK_NUM (flash_qspi_size() / CFG_TUD_MSC_BLOCK_SZ)
+
+// Block size
+#define CFG_TUD_MSC_BLOCK_SZ 512
+
+// Vendor name included in Inquiry response, max 8 bytes
+#define CFG_TUD_MSC_VENDOR "Adafruit"
+
+// Product name included in Inquiry response, max 16 bytes
+#define CFG_TUD_MSC_PRODUCT "Bluefruit nRF52"
+
+// Product revision string included in Inquiry response, max 4 bytes
+#define CFG_TUD_MSC_PRODUCT_REV "1.0"
+
+//--------------------------------------------------------------------
+// HID
+//--------------------------------------------------------------------
+
+/* Use the HID_ASCII_TO_KEYCODE lookup if CFG_TUD_HID_KEYBOARD is enabled.
+ * This will occupies 256 bytes of ROM. It will also enable the use of 2 extra APIs
+ * - tud_hid_keyboard_send_char()
+ * - tud_hid_keyboard_send_string()
+ */
+#define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 1
+
+//--------------------------------------------------------------------
+// USB RAM PLACEMENT
+//--------------------------------------------------------------------
+#define CFG_TUSB_ATTR_USBRAM
+#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4)
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CONFIG_H_ */
diff --git a/arduino/cores/nRF5/usb/usb.c b/arduino/cores/nRF5/usb/usb.c new file mode 100755 index 0000000..e6ea31e --- /dev/null +++ b/arduino/cores/nRF5/usb/usb.c @@ -0,0 +1,123 @@ +/**************************************************************************/ +/*! + @file usb.c + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Adafruit Industries (adafruit.com) + All rights reserved. + + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. +*/ +/**************************************************************************/ + +#ifdef NRF52840_XXAA + +#include "nrfx.h" +#include "nrfx_power.h" +#include "nrf_sdm.h" +#include "nrf_soc.h" + +#include "nrf_usbd.h" +#include "tusb.h" +#include "usb.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +extern uint16_t usb_desc_str_serial[1+16]; + +// Init usb when starting up. Softdevice is not enabled yet +void usb_init(void) +{ + // Power module init + const nrfx_power_config_t pwr_cfg = { 0 }; + nrfx_power_init(&pwr_cfg); + + // Register tusb function as USB power handler + const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; + nrfx_power_usbevt_init(&config); + + nrfx_power_usbevt_enable(); + + // USB power may already be ready at this time -> no event generated + // We need to invoke the handler based on the status initially + uint32_t usb_reg = NRF_POWER->USBREGSTATUS; + + if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); + if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); + + // Create Serial string descriptor + char tmp_serial[17]; + sprintf(tmp_serial, "%08lX%08lX", NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0]); + + for(uint8_t i=0; i<16; i++) + { + usb_desc_str_serial[1+i] = tmp_serial[i]; + } + + // Init tinyusb stack + tusb_init(); +} + +// Must be called before sd_softdevice_enable() +// NRF_POWER is restricted prph used by Softdevice, must be release before enable SD +void usb_softdevice_pre_enable(void) +{ + nrfx_power_usbevt_disable(); + nrfx_power_usbevt_uninit(); + nrfx_power_uninit(); +} + +// Must be called after sd_softdevice_enable() +// To re-enable USB +void usb_softdevice_post_enable(void) +{ + sd_power_usbdetected_enable(true); + sd_power_usbpwrrdy_enable(true); + sd_power_usbremoved_enable(true); +} + + +// Invoked when cdc when line state changed e.g connected/disconnected +// Use to reset to DFU when disconnect with 1200 bps +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) +{ + (void) itf; // interface ID, not used + + // DTR = false is counted as disconnected + if ( !dtr ) + { + cdc_line_coding_t coding; + tud_cdc_get_line_coding(&coding); + + if ( coding.bit_rate == 1200 ) enterSerialDfu(); + } +} + + + +#endif diff --git a/arduino/cores/nRF5/usb/usb.h b/arduino/cores/nRF5/usb/usb.h new file mode 100755 index 0000000..853f6b5 --- /dev/null +++ b/arduino/cores/nRF5/usb/usb.h @@ -0,0 +1,56 @@ +/**************************************************************************/ +/*! + @file usb.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Adafruit Industries (adafruit.com) + All rights reserved. + + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. +*/ +/**************************************************************************/ + +#ifndef USB_H_ +#define USB_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +void usb_init(void); +void usb_softdevice_pre_enable(void); +void usb_softdevice_post_enable(void); + +/* tinyusb function that handles power event (detected, ready, removed) + * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. */ +void tusb_hal_nrf_power_event(uint32_t event); + +#ifdef __cplusplus + } +#endif + +#endif /* USB_H_ */ diff --git a/arduino/cores/nRF5/usb/usb_desc.c b/arduino/cores/nRF5/usb/usb_desc.c new file mode 100755 index 0000000..097821d --- /dev/null +++ b/arduino/cores/nRF5/usb/usb_desc.c @@ -0,0 +1,103 @@ +/**************************************************************************/
+/*!
+ @file usb_desc.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ Copyright (c) 2018, Adafruit Industries (adafruit.com)
+
+ All rights reserved.
+
+ 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. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifdef NRF52840_XXAA
+
+#include "tusb.h"
+
+
+/*------------- Interface Numbering -------------*/
+enum {
+ ITF_STR_LANGUAGE = 0 ,
+ ITF_STR_MANUFACTURER ,
+ ITF_STR_PRODUCT ,
+ ITF_STR_SERIAL ,
+ ITF_STR_CDC ,
+ ITF_STR_MSC
+};
+
+//--------------------------------------------------------------------+
+// STRING DESCRIPTORS
+//--------------------------------------------------------------------+
+
+// Serial is 64-bit DeviceID -> 16 chars len
+uint16_t usb_desc_str_serial[1+16] = { TUD_DESC_STR_HEADER(16) };
+
+// array of pointer to string descriptors
+uint16_t const * const string_desc_arr [] =
+{
+ // 0: is supported language = English
+ TUD_DESC_STRCONV(0x0409),
+
+ // 1: Manufacturer
+ TUD_DESC_STRCONV('A','d','a','f','r','u','i','t',' ','I','n','d','u','s','t','r','i','e','s'),
+
+ // 2: Product
+ TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','n','R','F','5','2','8','4','0'),
+
+ // 3: Serials TODO use chip ID
+ usb_desc_str_serial,
+
+ // 4: CDC Interface
+ TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','S','e','r','i','a','l'),
+
+ // 5: MSC Interface
+ TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','U','F','2'),
+};
+
+
+// tud_desc_set is required by tinyusb stack
+// since CFG_TUD_DESC_AUTO is enabled, we only need to set string_arr
+tud_desc_set_t tud_desc_set =
+{
+ .device = NULL,
+ .config = NULL,
+ .string_arr = (uint8_t const **) string_desc_arr,
+ .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]),
+
+ .hid_report =
+ {
+ .generic = NULL,
+ .boot_keyboard = NULL,
+ .boot_mouse = NULL
+ }
+};
+
+#endif
diff --git a/arduino/cores/nRF5/usb/usb_msc_flash.c b/arduino/cores/nRF5/usb/usb_msc_flash.c new file mode 100755 index 0000000..0d7ee88 --- /dev/null +++ b/arduino/cores/nRF5/usb/usb_msc_flash.c @@ -0,0 +1,135 @@ +/**************************************************************************/ +/*! + @file usb_msc_flash.c + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Adafruit Industries (adafruit.com) + All rights reserved. + + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. +*/ +/**************************************************************************/ +#if NRF52840_XXAA + +#include "tusb.h" + +#if CFG_TUD_MSC + +#include "nrf_gpio.h" +#include "flash/flash_qspi.h" + +// Callback invoked when received an SCSI command not in built-in list below +// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE +// - READ10 and WRITE10 has their own callbacks +int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) +{ + const void* response = NULL; + uint16_t resplen = 0; + + switch ( scsi_cmd[0] ) + { + case SCSI_CMD_TEST_UNIT_READY: + // Command that host uses to check our readiness before sending other commands + resplen = 0; + break; + + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // Host is about to read/write etc ... better not to disconnect disk + resplen = 0; + break; + + case SCSI_CMD_START_STOP_UNIT: + // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power + /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd; + // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well + // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage + start_stop->start; + start_stop->load_eject; + */ + resplen = 0; + break; + + default: + // Set Sense = Invalid Command Operation + tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // negative means error -> tinyusb could stall and/or response with failed status + resplen = -1; + break; + } + + // return len must not larger than bufsize + if ( resplen > bufsize ) + { + resplen = bufsize; + } + + // copy response to stack's buffer if any + if ( response && resplen ) + { + memcpy(buffer, response, resplen); + } + + return resplen; +} + +// Callback invoked when received READ10 command. +// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. +int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) +{ + (void) lun; + + return flash_qspi_read(buffer, lba * CFG_TUD_MSC_BLOCK_SZ + offset, bufsize); +} + +// Callback invoked when received WRITE10 command. +// Process data in buffer to disk's storage and return number of written bytes +int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) +{ + (void) lun; + + uint32_t wrcount = flash_qspi_write(lba * CFG_TUD_MSC_BLOCK_SZ + offset, buffer, bufsize); + + // update fatfs's cache if address matches + extern ExternalFS_usbmsc_write (uint32_t lba, void const* buffer, uint32_t bufsize) ATTR_WEAK; + if ( ExternalFS_usbmsc_write ) ExternalFS_usbmsc_write(lba, buffer, bufsize); + + return wrcount; +} + +// Callback invoked when WRITE10 command is completed (status received and accepted by host). +// used to flush any pending cache. +void tud_msc_write10_complete_cb (uint8_t lun) +{ + (void) lun; + + // flush pending cache when write10 is complete + flash_qspi_flush(); +} + +#endif // CFG_TUD_MSC +#endif // nrf52840 |