mirror of
https://github.com/arduino/Arduino.git
synced 2024-12-01 12:24:14 +01:00
Merge branch 'phid-class'
This commit is contained in:
commit
aa921659f6
@ -23,78 +23,84 @@
|
||||
#if defined(USBCON)
|
||||
#ifdef PLUGGABLE_USB_ENABLED
|
||||
|
||||
#define MAX_MODULES 6
|
||||
extern uint8_t _initEndpoints[];
|
||||
|
||||
static u8 lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT;
|
||||
static u8 lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT;
|
||||
|
||||
extern u8 _initEndpoints[];
|
||||
|
||||
//PUSBCallbacks cbs[MAX_MODULES];
|
||||
static u8 modules_count = 0;
|
||||
|
||||
static PUSBListNode* rootNode = NULL;
|
||||
|
||||
int PUSB_GetInterface(u8* interfaceNum)
|
||||
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
|
||||
{
|
||||
int ret = 0;
|
||||
PUSBListNode* node = rootNode;
|
||||
for (u8 i=0; i<modules_count; i++) {
|
||||
ret = node->cb->getInterface(interfaceNum);
|
||||
node = node->next;
|
||||
int sent = 0;
|
||||
PUSBListNode* node;
|
||||
for (node = rootNode; node; node = node->next) {
|
||||
int res = node->getInterface(interfaceCount);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
sent += res;
|
||||
}
|
||||
return ret;
|
||||
return sent;
|
||||
}
|
||||
|
||||
int PUSB_GetDescriptor(int8_t t)
|
||||
int PluggableUSB_::getDescriptor(int8_t type)
|
||||
{
|
||||
int ret = 0;
|
||||
PUSBListNode* node = rootNode;
|
||||
for (u8 i=0; i<modules_count && ret == 0; i++) {
|
||||
ret = node->cb->getDescriptor(t);
|
||||
node = node->next;
|
||||
PUSBListNode* node;
|
||||
for (node = rootNode; node; node = node->next) {
|
||||
int ret = node->getDescriptor(type);
|
||||
// ret!=0 -> request has been processed
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PUSB_Setup(USBSetup& setup, u8 j)
|
||||
bool PluggableUSB_::setup(USBSetup& setup, uint8_t interfaceNum)
|
||||
{
|
||||
bool ret = false;
|
||||
PUSBListNode* node = rootNode;
|
||||
for (u8 i=0; i<modules_count && ret == false; i++) {
|
||||
ret = node->cb->setup(setup, j);
|
||||
node = node->next;
|
||||
PUSBListNode* node;
|
||||
for (node = rootNode; node; node = node->next) {
|
||||
if (node->setup(setup, interfaceNum)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface)
|
||||
bool PluggableUSB_::plug(PUSBListNode *node)
|
||||
{
|
||||
if (modules_count >= MAX_MODULES) {
|
||||
return 0;
|
||||
if ((lastEp + node->numEndpoints) > USB_ENDPOINTS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (modules_count == 0) {
|
||||
if (!rootNode) {
|
||||
rootNode = node;
|
||||
} else {
|
||||
PUSBListNode *current = rootNode;
|
||||
while(current->next != NULL) {
|
||||
while (current->next) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = node;
|
||||
}
|
||||
|
||||
*interface = lastIf;
|
||||
lastIf += node->cb->numInterfaces;
|
||||
for ( u8 i = 0; i< node->cb->numEndpoints; i++) {
|
||||
_initEndpoints[lastEp] = node->cb->endpointType[i];
|
||||
node->pluggedInterface = lastIf;
|
||||
node->pluggedEndpoint = lastEp;
|
||||
lastIf += node->numInterfaces;
|
||||
for (uint8_t i = 0; i < node->numEndpoints; i++) {
|
||||
_initEndpoints[lastEp] = node->endpointType[i];
|
||||
lastEp++;
|
||||
}
|
||||
modules_count++;
|
||||
return lastEp - node->cb->numEndpoints;
|
||||
return true;
|
||||
// restart USB layer???
|
||||
}
|
||||
|
||||
PluggableUSB_& PluggableUSB()
|
||||
{
|
||||
static PluggableUSB_ obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT),
|
||||
lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT),
|
||||
rootNode(NULL)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
#endif /* if defined(USBCON) */
|
||||
|
@ -25,30 +25,50 @@
|
||||
|
||||
#if defined(USBCON)
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
bool (*setup)(USBSetup& setup, u8 i);
|
||||
int (*getInterface)(u8* interfaceNum);
|
||||
int (*getDescriptor)(int8_t t);
|
||||
int8_t numEndpoints;
|
||||
int8_t numInterfaces;
|
||||
uint8_t *endpointType;
|
||||
} PUSBCallbacks;
|
||||
|
||||
class PUSBListNode {
|
||||
public:
|
||||
PUSBListNode(int8_t numEps, int8_t numIfs, uint8_t *epType) :
|
||||
numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
|
||||
{ }
|
||||
|
||||
inline uint8_t interface() const { return pluggedInterface; }
|
||||
inline int8_t endpoint() const { return pluggedEndpoint; }
|
||||
|
||||
protected:
|
||||
virtual bool setup(USBSetup& setup, uint8_t interfaceNum) = 0;
|
||||
virtual int getInterface(uint8_t* interfaceCount) = 0;
|
||||
virtual int getDescriptor(int8_t t) = 0;
|
||||
|
||||
uint8_t pluggedInterface;
|
||||
int8_t pluggedEndpoint;
|
||||
|
||||
const int8_t numEndpoints;
|
||||
const int8_t numInterfaces;
|
||||
const uint8_t *endpointType;
|
||||
|
||||
PUSBListNode *next = NULL;
|
||||
PUSBCallbacks *cb;
|
||||
PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;}
|
||||
|
||||
friend class PluggableUSB_;
|
||||
};
|
||||
|
||||
int8_t PUSB_AddFunction(PUSBListNode *node, u8 *interface);
|
||||
class PluggableUSB_ {
|
||||
public:
|
||||
PluggableUSB_();
|
||||
bool plug(PUSBListNode *node);
|
||||
int getInterface(uint8_t* interfaceCount);
|
||||
int getDescriptor(int8_t type);
|
||||
bool setup(USBSetup& setup, uint8_t interfaceNum);
|
||||
|
||||
int PUSB_GetInterface(u8* interfaceNum);
|
||||
private:
|
||||
uint8_t lastIf;
|
||||
uint8_t lastEp;
|
||||
PUSBListNode* rootNode;
|
||||
};
|
||||
|
||||
int PUSB_GetDescriptor(int8_t t);
|
||||
|
||||
bool PUSB_Setup(USBSetup& setup, u8 i);
|
||||
// Replacement for global singleton.
|
||||
// This function prevents static-initialization-order-fiasco
|
||||
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
|
||||
PluggableUSB_& PluggableUSB();
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -308,20 +308,15 @@ int USB_Send(u8 ep, const void* d, int len)
|
||||
return r;
|
||||
}
|
||||
|
||||
u8 _initEndpoints[] =
|
||||
u8 _initEndpoints[USB_ENDPOINTS] =
|
||||
{
|
||||
0,
|
||||
0, // Control Endpoint
|
||||
|
||||
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
|
||||
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
|
||||
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
|
||||
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
|
||||
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
|
||||
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
|
||||
|
||||
#ifdef PLUGGABLE_USB_ENABLED
|
||||
//allocate 3 endpoints and remove const so they can be changed by the user
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
// Following endpoints are automatically initialized to 0
|
||||
};
|
||||
|
||||
#define EP_SINGLE_64 0x32 // EP0
|
||||
@ -367,7 +362,7 @@ bool ClassInterfaceRequest(USBSetup& setup)
|
||||
return CDC_Setup(setup);
|
||||
|
||||
#ifdef PLUGGABLE_USB_ENABLED
|
||||
return PUSB_Setup(setup, i);
|
||||
return PluggableUSB().setup(setup, i);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -445,7 +440,7 @@ static u8 SendInterfaces()
|
||||
CDC_GetInterface(&interfaces);
|
||||
|
||||
#ifdef PLUGGABLE_USB_ENABLED
|
||||
PUSB_GetInterface(&interfaces);
|
||||
PluggableUSB().getInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
return interfaces;
|
||||
@ -481,7 +476,7 @@ bool SendDescriptor(USBSetup& setup)
|
||||
|
||||
InitControl(setup.wLength);
|
||||
#ifdef PLUGGABLE_USB_ENABLED
|
||||
ret = PUSB_GetDescriptor(t);
|
||||
ret = PluggableUSB().getDescriptor(t);
|
||||
if (ret != 0) {
|
||||
return (ret > 0 ? true : false);
|
||||
}
|
||||
|
@ -99,8 +99,8 @@
|
||||
|
||||
// bEndpointAddress in Endpoint Descriptor
|
||||
#define USB_ENDPOINT_DIRECTION_MASK 0x80
|
||||
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
|
||||
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
|
||||
#define USB_ENDPOINT_OUT(addr) (lowByte((addr) | 0x00))
|
||||
#define USB_ENDPOINT_IN(addr) (lowByte((addr) | 0x80))
|
||||
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
||||
@ -277,4 +277,4 @@ typedef struct
|
||||
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,23 +1,28 @@
|
||||
/*
|
||||
Copyright (c) 2011, Peter Barrett
|
||||
Copyright (c) 2015, Arduino LLC
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
/* Copyright (c) 2011, Peter Barrett
|
||||
**
|
||||
** Permission to use, copy, modify, and/or distribute this software for
|
||||
** any purpose with or without fee is hereby granted, provided that the
|
||||
** above copyright notice and this permission notice appear in all copies.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
** SOFTWARE.
|
||||
*/
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#define PLUGGABLE_USB_ENABLED
|
||||
|
||||
#if defined(EPRST6)
|
||||
#define USB_ENDPOINTS 7 // AtMegaxxU4
|
||||
#else
|
||||
#define USB_ENDPOINTS 5 // AtMegaxxU2
|
||||
#endif
|
||||
|
||||
#define CDC_INTERFACE_COUNT 2
|
||||
#define CDC_ENPOINT_COUNT 3
|
||||
|
@ -1,153 +1,123 @@
|
||||
/* Copyright (c) 2015, Arduino LLC
|
||||
**
|
||||
** Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||
**
|
||||
** Permission to use, copy, modify, and/or distribute this software for
|
||||
** any purpose with or without fee is hereby granted, provided that the
|
||||
** above copyright notice and this permission notice appear in all copies.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
** SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
Copyright (c) 2015, Arduino LLC
|
||||
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "PluggableUSB.h"
|
||||
#include "HID.h"
|
||||
|
||||
#if defined(USBCON)
|
||||
|
||||
HID_ HID;
|
||||
|
||||
static uint8_t HID_ENDPOINT_INT;
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// HID Interface
|
||||
|
||||
static uint8_t HID_INTERFACE;
|
||||
|
||||
HIDDescriptor _hidInterface;
|
||||
|
||||
static HIDDescriptorListNode* rootNode = NULL;
|
||||
static uint16_t sizeof_hidReportDescriptor = 0;
|
||||
static uint8_t modules_count = 0;
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Driver
|
||||
|
||||
uint8_t _hid_protocol = 1;
|
||||
uint8_t _hid_idle = 1;
|
||||
|
||||
int HID_GetInterface(uint8_t* interfaceNum)
|
||||
HID_& HID()
|
||||
{
|
||||
interfaceNum[0] += 1; // uses 1
|
||||
_hidInterface =
|
||||
{
|
||||
D_INTERFACE(HID_INTERFACE,1,3,0,0),
|
||||
D_HIDREPORT(sizeof_hidReportDescriptor),
|
||||
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,USB_EP_SIZE,0x01)
|
||||
};
|
||||
return USB_SendControl(0,&_hidInterface,sizeof(_hidInterface));
|
||||
static HID_ obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
int HID_GetDescriptor(int8_t t)
|
||||
int HID_::getInterface(uint8_t* interfaceCount)
|
||||
{
|
||||
if (HID_REPORT_DESCRIPTOR_TYPE == t) {
|
||||
HIDDescriptorListNode* current = rootNode;
|
||||
*interfaceCount += 1; // uses 1
|
||||
HIDDescriptor hidInterface = {
|
||||
D_INTERFACE(interface(), 1, 3, 0, 0),
|
||||
D_HIDREPORT(descriptorSize),
|
||||
D_ENDPOINT(USB_ENDPOINT_IN(endpoint()), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
|
||||
};
|
||||
return USB_SendControl(0, &hidInterface, sizeof(hidInterface));
|
||||
}
|
||||
|
||||
int HID_::getDescriptor(int8_t type)
|
||||
{
|
||||
if (HID_REPORT_DESCRIPTOR_TYPE == type) {
|
||||
int total = 0;
|
||||
while(current != NULL) {
|
||||
total += USB_SendControl(TRANSFER_PGM,current->data,current->length);
|
||||
current = current->next;
|
||||
HIDDescriptorListNode* node;
|
||||
for (node = rootNode; node; node = node->next) {
|
||||
int res = USB_SendControl(TRANSFER_PGM, node->data, node->length);
|
||||
if (res == -1)
|
||||
return -1;
|
||||
total += res;
|
||||
}
|
||||
return total;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ignored
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HID_::AppendDescriptor(HIDDescriptorListNode *node)
|
||||
{
|
||||
if (modules_count == 0) {
|
||||
if (!rootNode) {
|
||||
rootNode = node;
|
||||
} else {
|
||||
HIDDescriptorListNode *current = rootNode;
|
||||
while(current->next != NULL) {
|
||||
while (current->next) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = node;
|
||||
}
|
||||
modules_count++;
|
||||
sizeof_hidReportDescriptor += (uint16_t)node->length;
|
||||
descriptorSize += node->length;
|
||||
}
|
||||
|
||||
void HID_::SendReport(u8 id, const void* data, int len)
|
||||
void HID_::SendReport(uint8_t id, const void* data, int len)
|
||||
{
|
||||
USB_Send(HID_TX, &id, 1);
|
||||
USB_Send(HID_TX | TRANSFER_RELEASE,data,len);
|
||||
USB_Send(endpoint(), &id, 1);
|
||||
USB_Send(endpoint() | TRANSFER_RELEASE, data, len);
|
||||
}
|
||||
|
||||
bool HID_Setup(USBSetup& setup, uint8_t i)
|
||||
bool HID_::setup(USBSetup& setup, uint8_t interfaceNum)
|
||||
{
|
||||
if (HID_INTERFACE != i) {
|
||||
return false;
|
||||
} else {
|
||||
uint8_t r = setup.bRequest;
|
||||
uint8_t requestType = setup.bmRequestType;
|
||||
if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
|
||||
{
|
||||
if (HID_GET_REPORT == r)
|
||||
{
|
||||
//HID_GetReport();
|
||||
return true;
|
||||
}
|
||||
if (HID_GET_PROTOCOL == r)
|
||||
{
|
||||
//Send8(_hid_protocol); // TODO
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
|
||||
{
|
||||
if (HID_SET_PROTOCOL == r)
|
||||
{
|
||||
_hid_protocol = setup.wValueL;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HID_SET_IDLE == r)
|
||||
{
|
||||
_hid_idle = setup.wValueL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (interface() != interfaceNum) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t request = setup.bRequest;
|
||||
uint8_t requestType = setup.bmRequestType;
|
||||
|
||||
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
|
||||
{
|
||||
if (request == HID_GET_REPORT) {
|
||||
// TODO: HID_GetReport();
|
||||
return true;
|
||||
}
|
||||
if (request == HID_GET_PROTOCOL) {
|
||||
// TODO: Send8(protocol);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
|
||||
{
|
||||
if (request == HID_SET_PROTOCOL) {
|
||||
protocol = setup.wValueL;
|
||||
return true;
|
||||
}
|
||||
if (request == HID_SET_IDLE) {
|
||||
idle = setup.wValueL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
HID_::HID_(void)
|
||||
HID_::HID_(void) : PUSBListNode(1, 1, epType),
|
||||
rootNode(NULL), descriptorSize(0),
|
||||
protocol(1), idle(1)
|
||||
{
|
||||
static uint8_t endpointType[1];
|
||||
|
||||
endpointType[0] = EP_TYPE_INTERRUPT_IN;
|
||||
|
||||
static PUSBCallbacks cb = {
|
||||
.setup = &HID_Setup,
|
||||
.getInterface = &HID_GetInterface,
|
||||
.getDescriptor = &HID_GetDescriptor,
|
||||
.numEndpoints = 1,
|
||||
.numInterfaces = 1,
|
||||
.endpointType = endpointType,
|
||||
};
|
||||
|
||||
static PUSBListNode node(&cb);
|
||||
|
||||
HID_ENDPOINT_INT = PUSB_AddFunction(&node, &HID_INTERFACE);
|
||||
epType[0] = EP_TYPE_INTERRUPT_IN;
|
||||
PluggableUSB().plug(this);
|
||||
}
|
||||
|
||||
int HID_::begin(void)
|
||||
|
@ -1,38 +1,34 @@
|
||||
/*
|
||||
HID.h
|
||||
|
||||
Copyright (c) 2015, Arduino LLC
|
||||
Original code (pre-library): Copyright (c) 2011, Peter Barrett
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HID_h
|
||||
#define HID_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include "PluggableUSB.h"
|
||||
|
||||
#if defined(USBCON)
|
||||
|
||||
#define _USING_HID
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// HID 'Driver'
|
||||
|
||||
// HID 'Driver'
|
||||
// ------------
|
||||
#define HID_GET_REPORT 0x01
|
||||
#define HID_GET_IDLE 0x02
|
||||
#define HID_GET_PROTOCOL 0x03
|
||||
@ -44,24 +40,6 @@
|
||||
#define HID_REPORT_DESCRIPTOR_TYPE 0x22
|
||||
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
|
||||
|
||||
class HIDDescriptorListNode {
|
||||
public:
|
||||
HIDDescriptorListNode *next = NULL;
|
||||
HIDDescriptorListNode(const void *d, const uint16_t l) : data(d), length(l) { }
|
||||
|
||||
const void* data;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
class HID_
|
||||
{
|
||||
public:
|
||||
HID_(void);
|
||||
int begin(void);
|
||||
void SendReport(uint8_t id, const void* data, int len);
|
||||
void AppendDescriptor(HIDDescriptorListNode* node);
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len; // 9
|
||||
@ -82,13 +60,46 @@ typedef struct
|
||||
EndpointDescriptor in;
|
||||
} HIDDescriptor;
|
||||
|
||||
#define HID_TX HID_ENDPOINT_INT
|
||||
class HIDDescriptorListNode {
|
||||
public:
|
||||
HIDDescriptorListNode *next = NULL;
|
||||
HIDDescriptorListNode(const void *d, const uint16_t l) : data(d), length(l) { }
|
||||
|
||||
#define D_HIDREPORT(_descriptorLength) \
|
||||
{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength & 0xFF, _descriptorLength >> 8 }
|
||||
const void* data;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
class HID_ : public PUSBListNode
|
||||
{
|
||||
public:
|
||||
HID_(void);
|
||||
int begin(void);
|
||||
void SendReport(uint8_t id, const void* data, int len);
|
||||
void AppendDescriptor(HIDDescriptorListNode* node);
|
||||
|
||||
#endif
|
||||
protected:
|
||||
// Implementation of the PUSBListNode
|
||||
int getInterface(uint8_t* interfaceCount);
|
||||
int getDescriptor(int8_t type);
|
||||
bool setup(USBSetup& setup, uint8_t interfaceNum);
|
||||
|
||||
#endif
|
||||
private:
|
||||
uint8_t epType[1];
|
||||
|
||||
HIDDescriptorListNode* rootNode;
|
||||
uint16_t descriptorSize;
|
||||
|
||||
uint8_t protocol;
|
||||
uint8_t idle;
|
||||
};
|
||||
|
||||
// Replacement for global singleton.
|
||||
// This function prevents static-initialization-order-fiasco
|
||||
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
|
||||
HID_& HID();
|
||||
|
||||
#define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
|
||||
|
||||
#endif // USBCON
|
||||
|
||||
#endif // HID_h
|
||||
|
@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
|
||||
Keyboard_::Keyboard_(void)
|
||||
{
|
||||
static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
||||
HID.AppendDescriptor(&node);
|
||||
HID().AppendDescriptor(&node);
|
||||
}
|
||||
|
||||
void Keyboard_::begin(void)
|
||||
@ -76,7 +76,7 @@ void Keyboard_::end(void)
|
||||
|
||||
void Keyboard_::sendReport(KeyReport* keys)
|
||||
{
|
||||
HID.SendReport(2,keys,sizeof(KeyReport));
|
||||
HID().SendReport(2,keys,sizeof(KeyReport));
|
||||
}
|
||||
|
||||
extern
|
||||
|
@ -94,7 +94,6 @@ public:
|
||||
void releaseAll(void);
|
||||
};
|
||||
extern Keyboard_ Keyboard;
|
||||
extern HID_ HID;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -63,7 +63,7 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
|
||||
Mouse_::Mouse_(void) : _buttons(0)
|
||||
{
|
||||
static HIDDescriptorListNode node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
||||
HID.AppendDescriptor(&node);
|
||||
HID().AppendDescriptor(&node);
|
||||
}
|
||||
|
||||
void Mouse_::begin(void)
|
||||
@ -89,7 +89,7 @@ void Mouse_::move(signed char x, signed char y, signed char wheel)
|
||||
m[1] = x;
|
||||
m[2] = y;
|
||||
m[3] = wheel;
|
||||
HID.SendReport(1,m,4);
|
||||
HID().SendReport(1,m,4);
|
||||
}
|
||||
|
||||
void Mouse_::buttons(uint8_t b)
|
||||
|
@ -55,7 +55,6 @@ public:
|
||||
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
||||
};
|
||||
extern Mouse_ Mouse;
|
||||
extern HID_ HID;
|
||||
|
||||
#endif
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user