Added setup files to customize Arduino

This commit is contained in:
LuiCat 2019-03-07 14:53:24 +01:00
parent 951b5a2c9a
commit a1c1ba2276
3 changed files with 327 additions and 0 deletions

162
setup/HID.cpp Normal file
View File

@ -0,0 +1,162 @@
/*
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 "HID.h"
#if defined(USBCON)
HID_& HID()
{
static HID_ obj;
return obj;
}
int HID_::getInterface(uint8_t* interfaceCount)
{
*interfaceCount += 1; // uses 1
HIDDescriptor hidInterface = {
D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE),
D_HIDREPORT(descriptorSize),
D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
};
return USB_SendControl(0, &hidInterface, sizeof(hidInterface));
}
int HID_::getDescriptor(USBSetup& setup)
{
// Check if this is a HID Class Descriptor request
if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }
// In a HID Class Descriptor wIndex cointains the interface number
if (setup.wIndex != pluggedInterface) { return 0; }
int total = 0;
HIDSubDescriptor* 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;
}
// Reset the protocol on reenumeration. Normally the host should not assume the state of the protocol
// due to the USB specs, but Windows and Linux just assumes its in report mode.
protocol = HID_REPORT_PROTOCOL;
return total;
}
uint8_t HID_::getShortName(char *name)
{
name[0] = 'H';
name[1] = 'I';
name[2] = 'D';
name[3] = 'A' + (descriptorSize & 0x0F);
name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
return 5;
}
void HID_::AppendDescriptor(HIDSubDescriptor *node)
{
if (!rootNode) {
rootNode = node;
} else {
HIDSubDescriptor *current = rootNode;
while (current->next) {
current = current->next;
}
current->next = node;
}
descriptorSize += node->length;
}
int HID_::SendReport(uint8_t id, const void* data, int len)
{
auto ret = USB_Send(pluggedEndpoint, &id, 1);
if (ret < 0) return ret;
auto ret2 = USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, len);
if (ret2 < 0) return ret2;
return ret + ret2;
}
bool HID_::setup(USBSetup& setup)
{
if (pluggedInterface != setup.wIndex) {
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 (request == HID_GET_IDLE) {
// TODO: Send8(idle);
}
}
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
{
if (request == HID_SET_PROTOCOL) {
// The USB Host tells us if we are in boot or report mode.
// This only works with a real boot compatible device.
protocol = setup.wValueL;
return true;
}
if (request == HID_SET_IDLE) {
idle = setup.wValueL;
return true;
}
if (request == HID_SET_REPORT)
{
//uint8_t reportID = setup.wValueL;
//uint16_t length = setup.wLength;
//uint8_t data[length];
// Make sure to not read more data than USB_EP_SIZE.
// You can read multiple times through a loop.
// The first byte (may!) contain the reportID on a multreport.
//USB_RecvControl(data, length);
}
}
return false;
}
HID_::HID_(void) : PluggableUSBModule(1, 1, epType),
rootNode(NULL), descriptorSize(0),
protocol(HID_REPORT_PROTOCOL), idle(1)
{
epType[0] = EP_TYPE_INTERRUPT_IN;
PluggableUSB().plug(this);
}
int HID_::begin(void)
{
return 0;
}
#endif /* if defined(USBCON) */

127
setup/HID.h Normal file
View File

@ -0,0 +1,127 @@
/*
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.
*/
#ifndef HID_h
#define HID_h
#include <stdint.h>
#include <Arduino.h>
#include "PluggableUSB.h"
#if defined(USBCON)
#define _USING_HID
// HID 'Driver'
// ------------
#define HID_GET_REPORT 0x01
#define HID_GET_IDLE 0x02
#define HID_GET_PROTOCOL 0x03
#define HID_SET_REPORT 0x09
#define HID_SET_IDLE 0x0A
#define HID_SET_PROTOCOL 0x0B
#define HID_HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESCRIPTOR_TYPE 0x22
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
// HID subclass HID1.11 Page 8 4.2 Subclass
#define HID_SUBCLASS_NONE 0
#define HID_SUBCLASS_BOOT_INTERFACE 1
// HID Keyboard/Mouse bios compatible protocols HID1.11 Page 9 4.3 Protocols
#define HID_PROTOCOL_NONE 0
#define HID_PROTOCOL_KEYBOARD 1
#define HID_PROTOCOL_MOUSE 2
// Normal or bios protocol (Keyboard/Mouse) HID1.11 Page 54 7.2.5 Get_Protocol Request
// "protocol" variable is used for this purpose.
#define HID_BOOT_PROTOCOL 0
#define HID_REPORT_PROTOCOL 1
// HID Request Type HID1.11 Page 51 7.2.1 Get_Report Request
#define HID_REPORT_TYPE_INPUT 1
#define HID_REPORT_TYPE_OUTPUT 2
#define HID_REPORT_TYPE_FEATURE 3
typedef struct
{
uint8_t len; // 9
uint8_t dtype; // 0x21
uint8_t addr;
uint8_t versionL; // 0x101
uint8_t versionH; // 0x101
uint8_t country;
uint8_t desctype; // 0x22 report
uint8_t descLenL;
uint8_t descLenH;
} HIDDescDescriptor;
typedef struct
{
InterfaceDescriptor hid;
HIDDescDescriptor desc;
EndpointDescriptor in;
} HIDDescriptor;
class HIDSubDescriptor {
public:
HIDSubDescriptor *next = NULL;
HIDSubDescriptor(const void *d, const uint16_t l) : data(d), length(l) { }
const void* data;
const uint16_t length;
};
class HID_ : public PluggableUSBModule
{
public:
HID_(void);
int begin(void);
int SendReport(uint8_t id, const void* data, int len);
int SendRaw(const void* data, int len);
void AppendDescriptor(HIDSubDescriptor* node);
void PrependDescriptor(HIDSubDescriptor* node);
protected:
// Implementation of the PluggableUSBModule
int getInterface(uint8_t* interfaceCount);
int getDescriptor(USBSetup& setup);
bool setup(USBSetup& setup);
uint8_t getShortName(char* name);
private:
uint8_t epType[1];
HIDSubDescriptor* 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

38
setup/boards.txt Normal file
View File

@ -0,0 +1,38 @@
##############################################################
# Nintendo Switch Controller for Micro/Leonardo #
##############################################################
ns_con.name=Nintendo Switch Controller (Micro)
ns_con.vid.1=0x0F0D
ns_con.pid.1=0x0092
ns_con.upload.tool=avrdude
ns_con.upload.protocol=avr109
ns_con.upload.maximum_size=28672
ns_con.upload.maximum_data_size=2560
ns_con.upload.speed=57600
ns_con.upload.disable_flushing=true
ns_con.upload.use_1200bps_touch=true
ns_con.upload.wait_for_upload_port=true
ns_con.bootloader.tool=avrdude
ns_con.bootloader.low_fuses=0xff
ns_con.bootloader.high_fuses=0xd8
ns_con.bootloader.extended_fuses=0xcb
ns_con.bootloader.file=caterina/Caterina-Micro.hex
ns_con.bootloader.unlock_bits=0x3F
ns_con.bootloader.lock_bits=0x2F
ns_con.build.mcu=atmega32u4
ns_con.build.f_cpu=16000000L
ns_con.build.board=AVR_MICRO
ns_con.build.core=arduino
ns_con.build.variant=micro
ns_con.build.vid=0x0F0D
ns_con.build.pid=0x0092
ns_con.build.usb_manufacturer="HORI CO.,LTD."
ns_con.build.usb_product="POKKEN CONTROLLER"
ns_con.build.extra_flags={build.usb_flags}