Starting from Zero
This commit is contained in:
parent
402efb58c1
commit
c4c2f47f61
26 changed files with 0 additions and 4582 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
|||
dev/*
|
||||
*.pdn
|
||||
275
CDC.cpp
275
CDC.cpp
|
|
@ -1,275 +0,0 @@
|
|||
|
||||
|
||||
/* 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) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "USBAPI.h"
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#if defined(USBCON)
|
||||
#ifdef CDC_ENABLED
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 dwDTERate;
|
||||
u8 bCharFormat;
|
||||
u8 bParityType;
|
||||
u8 bDataBits;
|
||||
u8 lineState;
|
||||
} LineInfo;
|
||||
|
||||
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
extern const CDCDescriptor _cdcInterface PROGMEM;
|
||||
const CDCDescriptor _cdcInterface =
|
||||
{
|
||||
D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 1),
|
||||
|
||||
// CDC communication interface
|
||||
D_INTERFACE(CDC_ACM_INTERFACE, 1, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0),
|
||||
D_CDCCS(CDC_HEADER, 0x10, 0x01), // Header (1.10 bcd)
|
||||
D_CDCCS(CDC_CALL_MANAGEMENT, 1, 1), // Device handles call management (not)
|
||||
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT, 6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
|
||||
D_CDCCS(CDC_UNION, CDC_ACM_INTERFACE, CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
|
||||
D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_ACM), USB_ENDPOINT_TYPE_INTERRUPT, 0x10, 0x40),
|
||||
|
||||
// CDC data interface
|
||||
D_INTERFACE(CDC_DATA_INTERFACE, 2, CDC_DATA_INTERFACE_CLASS, 0, 0),
|
||||
// edit by NicoHood
|
||||
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0),
|
||||
D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_IN), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0)
|
||||
};
|
||||
|
||||
int WEAK CDC_GetInterface(u8* interfaceNum)
|
||||
{
|
||||
interfaceNum[0] += 2; // uses 2
|
||||
return USB_SendControl(TRANSFER_PGM, &_cdcInterface, sizeof(_cdcInterface));
|
||||
}
|
||||
// edit by NicoHood
|
||||
// ensure the address isnt used anywhere else by adding a compiler flag in the makefile lf flag
|
||||
// -Wl,--section-start=.blkey=0x280
|
||||
//TODO where to put that flag? use different position: 0x100 maybe?
|
||||
// someone has to add the compiler flag to fix this bug: https://github.com/arduino/Arduino/issues/2474
|
||||
//volatile uint8_t MagicBootKey __attribute__((section(".blkey")));
|
||||
|
||||
bool WEAK CDC_Setup(Setup& setup)
|
||||
{
|
||||
u8 r = setup.bRequest;
|
||||
u8 requestType = setup.bmRequestType;
|
||||
|
||||
if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
|
||||
{
|
||||
if (CDC_GET_LINE_CODING == r)
|
||||
{
|
||||
USB_SendControl(0, (void*)&_usbLineInfo, 7);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
|
||||
{
|
||||
if (CDC_SET_LINE_CODING == r)
|
||||
{
|
||||
USB_RecvControl((void*)&_usbLineInfo, 7);
|
||||
}
|
||||
|
||||
if (CDC_SET_CONTROL_LINE_STATE == r)
|
||||
{
|
||||
_usbLineInfo.lineState = setup.wValueL;
|
||||
}
|
||||
|
||||
if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
|
||||
{
|
||||
// auto-reset into the bootloader is triggered when the port, already
|
||||
// open at 1200 bps, is closed. this is the signal to start the watchdog
|
||||
// with a relatively long period so it can finish housekeeping tasks
|
||||
// like servicing endpoints before the sketch ends
|
||||
|
||||
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
||||
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
|
||||
{
|
||||
// edit by NicoHood
|
||||
// change ram pointer to fit the 16u2's ram size and only use a 8bit value
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
*(uint16_t *)0x0800 = 0x7777;
|
||||
wdt_enable(WDTO_120MS);
|
||||
#else
|
||||
// workaround for this issue:
|
||||
// https://github.com/arduino/Arduino/issues/2474
|
||||
// I didnt change this for the 32u4 to simply not touch their code
|
||||
cli();
|
||||
|
||||
//MagicBootKey = 0x77;
|
||||
*(uint8_t *)0x0280 = 0x77;
|
||||
|
||||
wdt_enable(WDTO_120MS);
|
||||
|
||||
// wait for reset
|
||||
for (;;);
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Most OSs do some intermediate steps when configuring ports and DTR can
|
||||
// twiggle more than once before stabilizing.
|
||||
// To avoid spurious resets we set the watchdog to 250ms and eventually
|
||||
// cancel if DTR goes back high.
|
||||
|
||||
// edit by NicoHood
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
wdt_disable();
|
||||
wdt_reset();
|
||||
*(uint16_t *)0x0800 = 0x0;
|
||||
#else
|
||||
// not used because of the workaround above
|
||||
//wdt_disable();
|
||||
//wdt_reset();
|
||||
//MagicBootKey = 0x0;
|
||||
//*(uint8_t *)0x0280 = 0x00;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Serial_::begin(unsigned long /* baud_count */)
|
||||
{
|
||||
peek_buffer = -1;
|
||||
}
|
||||
|
||||
void Serial_::begin(unsigned long /* baud_count */, byte /* config */)
|
||||
{
|
||||
peek_buffer = -1;
|
||||
}
|
||||
|
||||
void Serial_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
// edit by NicoHood
|
||||
uint8_t Serial_::lineState(void)
|
||||
{
|
||||
return _usbLineInfo.lineState;
|
||||
}
|
||||
|
||||
int Serial_::available(void)
|
||||
{
|
||||
if (peek_buffer >= 0) {
|
||||
return 1 + USB_Available(CDC_RX);
|
||||
}
|
||||
return USB_Available(CDC_RX);
|
||||
}
|
||||
|
||||
int Serial_::peek(void)
|
||||
{
|
||||
if (peek_buffer < 0)
|
||||
peek_buffer = USB_Recv(CDC_RX);
|
||||
return peek_buffer;
|
||||
}
|
||||
|
||||
int Serial_::read(void)
|
||||
{
|
||||
if (peek_buffer >= 0) {
|
||||
int c = peek_buffer;
|
||||
peek_buffer = -1;
|
||||
return c;
|
||||
}
|
||||
return USB_Recv(CDC_RX);
|
||||
}
|
||||
|
||||
void Serial_::flush(void)
|
||||
{
|
||||
USB_Flush(CDC_TX);
|
||||
}
|
||||
|
||||
size_t Serial_::write(uint8_t c)
|
||||
{
|
||||
return write(&c, 1);
|
||||
}
|
||||
|
||||
size_t Serial_::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
/* only try to send bytes if the high-level CDC connection itself
|
||||
is open (not just the pipe) - the OS should set lineState when the port
|
||||
is opened and clear lineState when the port is closed.
|
||||
bytes sent before the user opens the connection or after
|
||||
the connection is closed are lost - just like with a UART. */
|
||||
|
||||
// TODO - ZE - check behavior on different OSes and test what happens if an
|
||||
// open connection isn't broken cleanly (cable is yanked out, host dies
|
||||
// or locks up, or host virtual serial port hangs)
|
||||
if (_usbLineInfo.lineState > 0) {
|
||||
int r = USB_Send(CDC_TX, buffer, size);
|
||||
if (r > 0) {
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This operator is a convenient way for a sketch to check whether the
|
||||
// port has actually been configured and opened by the host (as opposed
|
||||
// to just being connected to the host). It can be used, for example, in
|
||||
// setup() before printing to ensure that an application on the host is
|
||||
// actually ready to receive and display the data.
|
||||
// We add a short delay before returning to fix a bug observed by Federico
|
||||
// where the port is configured (lineState != 0) but not quite opened.
|
||||
Serial_::operator bool() {
|
||||
bool result = false;
|
||||
if (_usbLineInfo.lineState > 0)
|
||||
result = true;
|
||||
delay(10);
|
||||
return result;
|
||||
}
|
||||
|
||||
Serial_ Serial;
|
||||
|
||||
#endif
|
||||
#endif /* if defined(USBCON) */
|
||||
405
HID.cpp
405
HID.cpp
|
|
@ -1,405 +0,0 @@
|
|||
|
||||
|
||||
/* 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) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "USBAPI.h"
|
||||
|
||||
#if defined(USBCON)
|
||||
#ifdef HID_ENABLED
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// HID report descriptor
|
||||
|
||||
#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
// extern accessible led out report
|
||||
uint8_t hid_keyboard_leds = 0;
|
||||
#endif
|
||||
|
||||
extern const u8 _hidReportDescriptor[] PROGMEM;
|
||||
const u8 _hidReportDescriptor[] = {
|
||||
#ifdef HID_MOUSE_ENABLED
|
||||
// Mouse
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x85, HID_REPORTID_MouseReport,// REPORT_ID
|
||||
// 5 buttons
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Button 5)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
// reserved
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
// x, y, wheel
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x09, 0x38, // USAGE (Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
// end
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
#endif
|
||||
|
||||
#ifdef HID_KEYBOARD_ENABLED
|
||||
// Keyboard
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, HID_REPORTID_KeyboardReport, // REPORT_ID
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
// modifiers
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
// reserved byte
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
// Key[6] Array
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
#ifdef HID_KEYBOARD_LEDS_ENABLED
|
||||
// LEDs for num lock etc
|
||||
0x05, 0x08, /* USAGE_PAGE (LEDs) */
|
||||
0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
|
||||
0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
|
||||
0x95, 0x05, /* REPORT_COUNT (5) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
|
||||
// Reserved 3 bits
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x75, 0x03, /* REPORT_SIZE (3) */
|
||||
0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
|
||||
#endif
|
||||
// end
|
||||
0xc0, // END_COLLECTION
|
||||
#endif
|
||||
|
||||
#ifdef HID_RAWHID_ENABLED
|
||||
// RAW HID
|
||||
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
|
||||
0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
|
||||
|
||||
0xA1, 0x01, // Collection 0x01
|
||||
0x85, HID_REPORTID_RawKeyboardReport, // REPORT_ID
|
||||
0x75, 0x08, // report size = 8 bits
|
||||
0x15, 0x00, // logical minimum = 0
|
||||
0x26, 0xFF, 0x00, // logical maximum = 255
|
||||
|
||||
0x95, RAWHID_TX_SIZE, // report count TX
|
||||
0x09, 0x01, // usage
|
||||
0x81, 0x02, // Input (array)
|
||||
|
||||
0x95, RAWHID_RX_SIZE, // report count RX
|
||||
0x09, 0x02, // usage
|
||||
0x91, 0x02, // Output (array)
|
||||
0xC0, // end collection
|
||||
#endif
|
||||
|
||||
#ifdef HID_MEDIA_ENABLED
|
||||
// Media
|
||||
0x05, 0x0C, // usage page (consumer device)
|
||||
0x09, 0x01, // usage -- consumer control
|
||||
0xA1, 0x01, // collection (application)
|
||||
0x85, HID_REPORTID_MediaReport, // report id
|
||||
//0x05, 0x0C, // usage page (consumer)
|
||||
|
||||
// 4 media Keys
|
||||
0x15, 0x00, //logical minimum
|
||||
0x26, 0xFF, 0x03, //logical maximum (3ff)
|
||||
0x19, 0x00, // usage minimum (0)
|
||||
0x2A, 0xFF, 0x03, //usage maximum (3ff)
|
||||
0x95, 0x04, //report count (4)
|
||||
0x75, 0x10, //report size (16)
|
||||
|
||||
0x81, 0x00, //input
|
||||
0xC0, //end collection
|
||||
#endif
|
||||
|
||||
#ifdef HID_SYSTEM_ENABLED
|
||||
// System
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x80, // USAGE (System Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, HID_REPORTID_SystemReport, // REPORT_ID
|
||||
// 1 system key
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Undefined)
|
||||
0x29, 0xff, // USAGE_MAXIMUM (System Menu Down)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
#endif
|
||||
|
||||
#ifdef HID_GAMEPAD_ENABLED
|
||||
// Gamepad
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x04, // USAGE (Joystick)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, HID_REPORTID_GamepadReport, // REPORT_ID
|
||||
// 32 Buttons
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x20, // USAGE_MAXIMUM (Button 32)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x20, // REPORT_COUNT (32)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
// 4 16bit Axis
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x09, 0x33, // USAGE (Rx)
|
||||
0x09, 0x34, // USAGE (Ry)
|
||||
0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768)
|
||||
0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x95, 0x04, // REPORT_COUNT (4)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
// 2 8bit Axis
|
||||
0x09, 0x32, // USAGE (Z)
|
||||
0x09, 0x35, // USAGE (Rz)
|
||||
0x15, 0x80, // LOGICAL_MINIMUM (-128)
|
||||
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
// 2 Hat Switches
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x39, // USAGE (Hat switch)
|
||||
0x09, 0x39, // USAGE (Hat switch)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x08, // LOGICAL_MAXIMUM (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
#endif
|
||||
};
|
||||
|
||||
extern const HIDDescriptor _hidInterface PROGMEM;
|
||||
const HIDDescriptor _hidInterface =
|
||||
{
|
||||
D_INTERFACE(HID_INTERFACE, 1, 3, 0, 0),
|
||||
D_HIDREPORT(sizeof(_hidReportDescriptor)),
|
||||
// edit by NicoHood
|
||||
D_ENDPOINT(USB_ENDPOINT_IN(HID_ENDPOINT_INT), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
|
||||
};
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Driver
|
||||
|
||||
u8 _hid_protocol = 1;
|
||||
u8 _hid_idle = 1;
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
int WEAK HID_GetInterface(u8* interfaceNum)
|
||||
{
|
||||
interfaceNum[0] += 1; // uses 1
|
||||
return USB_SendControl(TRANSFER_PGM, &_hidInterface, sizeof(_hidInterface));
|
||||
}
|
||||
|
||||
int WEAK HID_GetDescriptor(int /* i */)
|
||||
{
|
||||
return USB_SendControl(TRANSFER_PGM, _hidReportDescriptor, sizeof(_hidReportDescriptor));
|
||||
}
|
||||
|
||||
void WEAK HID_SendReport(u8 id, const void* data, int len)
|
||||
{
|
||||
USB_Send(HID_TX, &id, 1);
|
||||
USB_Send(HID_TX | TRANSFER_RELEASE, data, len);
|
||||
}
|
||||
|
||||
bool WEAK HID_Setup(Setup& setup)
|
||||
{
|
||||
u8 r = setup.bRequest;
|
||||
u8 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;
|
||||
}
|
||||
|
||||
// edit by NicoHood
|
||||
#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
if (HID_SET_REPORT == r)
|
||||
{
|
||||
if (setup.wLength == 2)
|
||||
{
|
||||
uint8_t data[2];
|
||||
if (2 == USB_RecvControl(data, 2))
|
||||
{
|
||||
// write led out report data
|
||||
hid_keyboard_leds=data[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else if defined(USE_USB_API)
|
||||
|
||||
// still provide the weak HID_SendReport function to be able to overwrite it externaly
|
||||
void __attribute__((weak)) HID_SendReport(uint8_t id, const void* data, int len)
|
||||
{
|
||||
// the user has to overwrite this if no USB Core is used
|
||||
}
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
|
||||
// HID API libs are only included if the device has USB functionality or if the USE_USB_API is needed
|
||||
#if defined(USBCON) || defined(USE_USB_API)
|
||||
|
||||
//================================================================================
|
||||
// Mouse
|
||||
//================================================================================
|
||||
|
||||
#ifdef HID_MOUSE_ENABLED
|
||||
|
||||
// object instance
|
||||
Mouse_ Mouse;
|
||||
|
||||
#endif
|
||||
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
//================================================================================
|
||||
|
||||
#ifdef HID_KEYBOARD_ENABLED
|
||||
|
||||
// object instance
|
||||
Keyboard_ Keyboard;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//================================================================================
|
||||
// Media
|
||||
//================================================================================
|
||||
|
||||
#ifdef HID_MEDIA_ENABLED
|
||||
|
||||
// object instance
|
||||
Media_ Media;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//================================================================================
|
||||
// System
|
||||
//================================================================================
|
||||
|
||||
#ifdef HID_SYSTEAM_ENABLED
|
||||
|
||||
// object instance
|
||||
System_ System;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//================================================================================
|
||||
// Gamepad
|
||||
//================================================================================
|
||||
|
||||
#ifdef HID_GAMEPAD_ENABLED
|
||||
|
||||
// object instance
|
||||
Gamepad_ Gamepad;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // if defined(USBCON) || defined(USE_USB_API)
|
||||
330
Readme.md
330
Readme.md
|
|
@ -1,330 +0,0 @@
|
|||
Arduino HID Project 2.0
|
||||
=======================
|
||||

|
||||
|
||||
This project went through a lot of phases and has now reached an HID library with 3 software solutions.
|
||||
The idea is to enable enhanced USB functions to almost all 'standard' Arduino boards.
|
||||
This is done with slightly different methods for different boards.
|
||||
|
||||
**Arduino IDE 1.5.8 is required for the HID Project.**
|
||||
|
||||
**Supported HID devices:**
|
||||
|
||||
* Keyboard with Leds out (modifiers + 6 keys pressed at the same time)
|
||||
* Mouse (5 buttons, move, wheel)
|
||||
* Media Keys (4 keys for music player, webbrowser and more)
|
||||
* System Key (for PC standby/shutdown)
|
||||
* 1 Gamepad (32 buttons, 4 16bit axis, 2 8bit axis, 2 D-Pads)
|
||||
|
||||
**Supported Arduinos:**
|
||||
* Uno
|
||||
* Mega
|
||||
* Leonardo
|
||||
* (Pro)Micro
|
||||
* Any other 8u2/16u/at90usb162/32u2/32u4 compatible board
|
||||
|
||||
| Leonardo/Micro | Uno/Mega HoodLoader2 | Uno/Mega HoodLoader1 |
|
||||
|:---------------------------|:----------------------------|---------------------------------------|
|
||||
| Extended Arduino USB-Core | Same Core as Leonardo/Micro | Coded with Lufa |
|
||||
| More HID devices | Fully reprogrammable 16u2 | No reprogrammable 16u2 |
|
||||
| Keyboard Led Out report | Serial0 fully usable | Main MCU sends HID reports on Serial0 |
|
||||
| System Wakeup fix (soon) | | Serial Protocol filters HID reports |
|
||||
| Serial Control Line access | | Built-in ISP function |
|
||||
|
||||
The HID project contains HID APIs to generate HID reports and functions to send them to the USB Host.
|
||||
The API (syntax/usage) of the HID Project is always the same for each solution, **you can port code from one device to another very easy**.
|
||||
|
||||
* On a Leonardo this function is extended and improved to get more HID devices + some improvements.
|
||||
* [HoodLoader2](https://github.com/NicoHood/HoodLoader2) is a BootLoader for the 16u2 that let's you use it as standalone MCU with the same USB-Core.
|
||||
* [HoodLoader1](https://github.com/NicoHood/HoodLoader) is a 16u2 firmware that filters special HW Serial signals from the main MCU and sends HID signals to the USB Host.
|
||||
|
||||
|
||||
To make things more clear the HID Software is in a separate repository than the HoodLoader (1 & 2) sources and installing instructions.
|
||||
**HoodLoader 1&2 is only used for an Uno/Mega to actually enable USB functions.** The 16u2 is normally used for USB-Serial programming of the main MCU but can do way more than that.
|
||||
To use HoodLoader1&2 you also need the HID Project. For more information and installation instructions see the specific repository.
|
||||
|
||||
HoodLoader1 was the first solution to enable HID functions to the Uno/Mega but HoodLoader2 opens way more options because you can reprogram the whole MCU standalone.
|
||||
See the repository for more infos about this great new opportunity. HoodLoader1 API is still usable in a specific example. HoodLoader1&2 are not needed/compatible with a Leonardo/Micro.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
**Please remove any older HID Project files from your sketchbook and your Arduino core to not run into any problems.**
|
||||
|
||||
Download the library and [install it](http://arduino.cc/en/pmwiki.php?n=Guide/Libraries) like you are used to (access the examples, keywords.txt with IDE).
|
||||
Then **move and replace** all .h and .cpp files to the path below. **I strongly recommend to install the library like this. Otherwise it wont work.**
|
||||
|
||||
```
|
||||
C:\Arduino\arduino-1.5.8\hardware\arduino\avr\cores\arduino
|
||||
```
|
||||
The installation path may differ to yours. **Please use Arduino IDE 1.5.8** and file an issue if a newer version isn't working.
|
||||
Restart the IDE. Ensure all drivers are installed. See [this](https://learn.sparkfun.com/tutorials/disabling-driver-signature-on-windows-8/disabling-signed-driver-enforcement-on-windows-8)
|
||||
on how to install the unsigned HoodLoader2 drivers.
|
||||
|
||||
**If you are using an Arduino Uno/Mega follow the installation instructions of the HoodLoader1 or 2** (no extra hardware needed, just a few cables).
|
||||
You can grab the latest version + installing instructions of each HoodLoader in its own repository linked above.
|
||||
|
||||
Of course the new version [HoodLoader2](https://github.com/NicoHood/HoodLoader2) is recommend and HoodLoader1 API is only for compatibility reasons online.
|
||||
The old, full HoodLoader1 HID (software)solution (before update 2.0) can be found here: [Outdated HID Project for 1.5.7](https://github.com/NicoHood/HID/tree/3d8a9b40752a143141b8be4b8f744e203c80b000)
|
||||
|
||||
|
||||
How to use
|
||||
==========
|
||||
|
||||
### Micro/Leonardo + HoodLoader2
|
||||
|
||||
**Edit the USBAPI.h you installed to de/activate usb functions.** By default only Mouse and Keyboard is activated.
|
||||
The more you activate the more flash is used. For the Uno/Mega you have a limited ram/flash size, so please try not to exceed this limit and only use the needed HID devices.
|
||||
RawHID is currently not working properly.
|
||||
|
||||
**Try the Basic examples for each HID device. They are pretty much self explaining.**
|
||||
|
||||
**The HoodLoader2 examples are to show some special cases for the 16u2.** It shows how to remove the USB functions if needed,
|
||||
how to optimally use ram since its limited and some ported sketches to reprogram the main MCU or for the missing ISP function. Please check them out.
|
||||
|
||||
|
||||
### HoodLoader1
|
||||
|
||||
**Try the HoodLoader1 example. It provides the basic Serial protocol API to send HID reports. You have to copy this to every sketch again.**
|
||||
|
||||
With HoodLoader1 you can **only use baud 115200 for HID** due to speed/programming reasons.
|
||||
Use Serial.begin(115200) in every HoodLoader1 sketch.
|
||||
Its not bad anyway because its the fastest baud and you want fast HID recognition.
|
||||
You still can **fully use any other baud** for normal sketches but HID wont work.
|
||||
If you try nevertheless it will output Serial crap to the monitor.
|
||||
|
||||
Keep in mind that HoodLoader1 has **no flush function**. If the PC is reading HID too slow it can miss data, like on a Raspberry Pi.
|
||||
Add a delay to the sending function or just use the newer HoodLoader2.
|
||||
|
||||
Always release buttons to not cause any erros. Replug USB cable to reset the values if anything went wrong.
|
||||
Keep in mind that **with HoodLoader1 the 16u2 is always on**. The 16u2 and its HID reports are not reset if the main MCU is reset.
|
||||
So you need to reset the HID reports on every startup with a begin() of each used API.
|
||||
On Windows every USB report will reset when you open the lock screen.
|
||||
See [deactivate HID function (Hoodloader only)](https://github.com/NicoHood/Hoodloader) how to temporary disable HID again.
|
||||
|
||||
For **16u2 as ISP usage** (optional, Hoodloader only, has nothing to do with HID function)
|
||||
see [Hoodloader repository](https://github.com/NicoHood/Hoodloader).
|
||||
|
||||
The sending API is no longer integrated directly in the HID Project since it is now more an extended USB-Core and this has nothing to do with it.
|
||||
Its more a legacy version to still use HoodLoader1 or to reimplement something similar with HoodLoader2 if you still want full report access for the main MCU.
|
||||
|
||||
**The older, full integrated HID Core can be found here.** Keep in mind to remove all newer stuff since it may conflict (a clean arduino core would do it).
|
||||
It is not better than this solution, maybe easier to use since its just more integrated.
|
||||
[Outdated HID Project for 1.5.7](https://github.com/NicoHood/HID/tree/3d8a9b40752a143141b8be4b8f744e203c80b000)
|
||||
|
||||
|
||||
How it works
|
||||
============
|
||||
For the Leonardo/Micro + HoodLoader2 its a modified version of the HID descriptors and USB-Core.
|
||||
This changes were made to improve the functions, add more devices and add u2 series compatibility.
|
||||
|
||||
HoodLoader1 only:
|
||||
For the Uno/Mega you need a special Bootloader. Why? See [Hoodloader repository](https://github.com/NicoHood/Hoodloader).
|
||||
To sum it up: Serial information is grabbed by the "man in the middle, 16u2" and you dont have to worry to get any wrong Serial stuff via USB.
|
||||
Thatswhy you need a special baud (115200) that both sides can communicate with each other.
|
||||
Every USB command is send via a special [NicoHood Protocol](https://github.com/NicoHood/NicoHoodProtocol)
|
||||
that's filtered out by the 16u2. If you use Serial0 for extern devices it cannot filter the signal of course.
|
||||
You can still use the NHP, just dont use the reserved Address 1.
|
||||
|
||||
This project wouldnt be possible without
|
||||
========================================
|
||||
|
||||
* [Lufa 140302 from Dean Camera](http://www.fourwalledcubicle.com/LUFA.php)
|
||||
* [Darran's HID Projects] (https://github.com/harlequin-tech/arduino-usb)
|
||||
* [Connor's Joystick for the Leonardo](http://www.imaginaryindustries.com/blog/?p=80)
|
||||
* [Stefan Jones Multimedia Keys Example](http://stefanjones.ca/blog/arduino-leonardo-remote-multimedia-keys/)
|
||||
* [Athanasios Douitsis Multimedia Keys Example](https://github.com/aduitsis/ardumultimedia)
|
||||
* [The Original Arduino Sources](https://github.com/arduino/Arduino/tree/master/hardware/arduino/firmwares/atmegaxxu2/arduino-usbserial)
|
||||
* [USBlyzer](http://www.usblyzer.com/)
|
||||
* [Mattairtechs 16u2 Lufa USB Core](https://www.mattairtech.com/index.php/development-boards/mt-db-u1.html)
|
||||
* [Paul Brook's Minimus 32u2 Arduino USB Core](https://github.com/pbrook/minimus-arduino)
|
||||
* [Paul Stoffregen's Teensy Core](https://github.com/PaulStoffregen/cores)
|
||||
* [Keyboard Led Out report by hartmut_holgraefe](http://forum.arduino.cc/index.php?topic=173583.0)
|
||||
* A lot of searching through the web
|
||||
* The awesome official Arduino IRC chat!
|
||||
* [The NicoHood Protocol ^.^](https://github.com/NicoHood/NicoHoodProtocol)
|
||||
* See HoodLoader1&2 repository for more credits/links
|
||||
|
||||
**Projects can be found here:**
|
||||
* [Gamecube to PC adapter](https://github.com/NicoHood/Nintendo)
|
||||
* [Other projects](http://nicohood.wordpress.com/)
|
||||
* For donations please contact me on my blog :)
|
||||
|
||||
Ideas for the future
|
||||
====================
|
||||
* Add more devices (even more?, voice device, flight control?)
|
||||
* Add Midi (no more free Endpoints, possible on 32u4)
|
||||
* Add HID rumble support (very hard)
|
||||
|
||||
Known Bugs
|
||||
==========
|
||||
See [Hoodloader repository](https://github.com/NicoHood/Hoodloader) for Hoodloader related Bugs/Issues.
|
||||
|
||||
System Wakeup is currently not working on all versions! Will be fixed soon!
|
||||
System Shutdown is only working on Windows systems.
|
||||
|
||||
RawHID is not working properly, test it at your own risk.
|
||||
|
||||
Feel free to open an Issue on Github if you find a bug. Or message me via my [blog](http://nicohood.wordpress.com/)!
|
||||
|
||||
Known Issues
|
||||
============
|
||||
|
||||
**If You have weird Problems especially with controllers, let me know.**
|
||||
Sometimes the problem is just that Windows messes up the PID so you might want to compile the hoodloader with a different PID
|
||||
or reinstall the drivers. With HoodLoader1 we had a lot of problems especially with linux.
|
||||
|
||||
XBMC 13.1 (a Media Center) uses Gamepad input. Its seems to not work and may cause weird errors.
|
||||
Even with a standard Gamepad I have these errors. Just want to mention it here.
|
||||
|
||||
The USB implementation of the Leonardo/Micro is not that good it can cause errors or disconnects with massiv Serial input.
|
||||
This has nothing to do with this library! For example Adalight dosnt work well for me,
|
||||
so you better use an Arduino Uno with Hoodloader1 (yes the older one!) for Mediacenter control and Ambilight.
|
||||
|
||||
Do not use HID in interrupts because it uses Serial (Hoodloader1 only). Your Arduino can crash!
|
||||
|
||||
HoodLoader1 only: If you get a checksum error after uploading please message me and send me the whole project.
|
||||
Same if your Arduino crashes and dont want to upload sketches anymore (Replug usb fixes this).
|
||||
These bugs occurred while developing the bootloader and should be fixed. Just in case it happens again I noted it here.
|
||||
USB can behave weird, so please check your code for errors first. If you cannot find a mistake open a Github issue.
|
||||
|
||||
Version History
|
||||
===============
|
||||
```
|
||||
2.0 Release (29.11.2014)
|
||||
* Added HoodLoader2
|
||||
* Separated HoodLoader1&2 more
|
||||
* Added u2 series for USB-Core
|
||||
* Extended USB core and fixed minor things for the u2 series
|
||||
* Added Led Out report.
|
||||
* Added CDC Line state
|
||||
* Reworked the whole library structure again
|
||||
|
||||
1.8 Beta Release (26.08.2014)
|
||||
* Changes in the Hoodloader:
|
||||
* **Huge improvements**, see [Hoodloader repository](https://github.com/NicoHood/Hoodloader)
|
||||
* Reworked the whole library, easy installation now
|
||||
* HID fixes for Media Keys/Ubuntu
|
||||
* Removed Joystick, added 4 Gamepads
|
||||
|
||||
1.7.3 Beta Release (10.08.2014)
|
||||
* Changes in the Hoodloader:
|
||||
* Fixed HID flush bug (1.6 - 1.7.2)
|
||||
|
||||
1.7.2 Beta Release (10.08.2014)
|
||||
* Changes in the Hoodloader:
|
||||
* Added Lite version for 8u2
|
||||
* Added Versions that show up as Uno/Mega (not recommended)
|
||||
* Makefile and structure changes
|
||||
|
||||
1.7.1 Beta Release (10.08.2014)
|
||||
* Changes in the Hoodloader:
|
||||
* Fixed HID deactivation bug
|
||||
|
||||
1.7 Beta Release (10.08.2014)
|
||||
* Changes in the Hoodloader:
|
||||
* Works as ISP now. See the [Hoodloader Repository](https://github.com/NicoHood/Hoodloader) for more information.
|
||||
* Exceeded 8kb limit. For flashing a 8u2 use v1.6 please!
|
||||
* Changed Readme text
|
||||
|
||||
1.6 Beta Release (09.08.2014)
|
||||
* Bugfixes in the Hoodloader:
|
||||
* Changed HID management (not blocking that much, faster)
|
||||
* added RawHID in/out (HID to Serial)
|
||||
* Added RawHID Class and example
|
||||
|
||||
1.5 Beta Release (21.07.2014)
|
||||
* Moved Hoodloader source to a [separate Github page](https://github.com/NicoHood/Hoodloader)
|
||||
* Bugfixes in the Hoodloader:
|
||||
* Firmware is still available here
|
||||
* Overall a lot of ram improvements, now with a big global union of ram
|
||||
* Removed USBtoUSART buffer (not needed, saved 128/500 bytes)
|
||||
* Removed Lite version because of better ram usage not needed
|
||||
* Separated different modes better to not cause any errors in default mode
|
||||
* Improved the deactivate option
|
||||
* Integrated NHP directly
|
||||
* Replaced LightweightRingbuffer with native Lufa Ringbuffer
|
||||
* Improved writing to CDC Host
|
||||
* Fixed a bug in checkNHPProtocol: & needs to be a ==
|
||||
* General structure changes
|
||||
* Improved stability
|
||||
* Fixed Arduino as ISP bug
|
||||
|
||||
1.4.1 Beta Release (10.07.2014)
|
||||
* #define Bugfix in USBAPI.h
|
||||
|
||||
1.4 Beta Release (10.07.2014)
|
||||
* Bugfixes in the Hoodloader:
|
||||
* Added Lite Version with less ram usage
|
||||
* Changed PIDs, edited driver file
|
||||
* merged v1.0.x and v1.5.x together (both are compatible!)
|
||||
* added IDE v1.5.7 support
|
||||
* added Tutorials
|
||||
|
||||
1.3 Beta Release (01.07.2014)
|
||||
* Bugfixes in the Hoodloader:
|
||||
* Improved ram usage (you can get even better but that messes up code and increases flash)
|
||||
* **Important NHP fix inside the HID Class for Uno/Mega**
|
||||
|
||||
1.2 Beta Release (22.06.2014)
|
||||
* Added 1.0.x/1.5.x support
|
||||
* Bugfixes in the Hoodloader:
|
||||
* Sometimes HID Devices weren't updating when using more than 1 Device (set forcewrite to true)
|
||||
* Fast updates crashed the bootloader (too much ram usage, set CDC buffer from 128b to 100b each)
|
||||
* Minor file structure changes
|
||||
|
||||
1.1 Beta Release (05.06.2014)
|
||||
* Added Leonardo/Micro support
|
||||
* Included NicoHoodProtocol
|
||||
* Minor fixes
|
||||
|
||||
1.0 Beta Release (03.06.2014)
|
||||
```
|
||||
|
||||
Licence and Copyright
|
||||
=====================
|
||||
If you use this library for any cool project let me know!
|
||||
|
||||
```
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
```
|
||||
|
||||
For Developers
|
||||
==============
|
||||
If you deactivate some reports it can occur that windows will cause problems and recognize it as different device.
|
||||
While developing I had that much trouble that I had to change the PID. No way to repair the broken windows driver settings.
|
||||
So be careful if you change the source on your own with important PIDs. (Therefore I made a 2nd Lite Version with a different PID and more ram)
|
||||
Therefore reinstall the divers for any device or just dont touch the HID reports in the Bootloader.
|
||||
The Leonardo/Micro version worked fine till now.
|
||||
|
||||
See this how to uninstall the drivers:
|
||||
https://support.microsoft.com/kb/315539
|
||||
|
||||
The Hootloader was coded with Windows7 and Visual Studio and compiled with a Raspberry Pi.
|
||||
Lufa version 140302 is included!
|
||||
**To recompile see instructions in [Hoodloader Repository](https://github.com/NicoHood/Hoodloader).**
|
||||
|
||||
The difference between the Leonardo/Micro and Uno/Mega is that the HID Class is different. All other classes are the same.
|
||||
The Leonardo/Micro Version uses USBAPI.h and no Serial while the Uno/Mega Version uses Serial.
|
||||
You can also modify the library to send HID reports to other devices/other serials.
|
||||
Just modify the HID Class (#define HID_SERIAL Serial).
|
||||
|
||||
785
USBCore.cpp
785
USBCore.cpp
|
|
@ -1,785 +0,0 @@
|
|||
|
||||
|
||||
/* Copyright (c) 2010, 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) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "USBAPI.h"
|
||||
|
||||
#if defined(USBCON)
|
||||
|
||||
#define EP_TYPE_CONTROL 0x00
|
||||
#define EP_TYPE_BULK_IN 0x81
|
||||
#define EP_TYPE_BULK_OUT 0x80
|
||||
#define EP_TYPE_INTERRUPT_IN 0xC1
|
||||
#define EP_TYPE_INTERRUPT_OUT 0xC0
|
||||
#define EP_TYPE_ISOCHRONOUS_IN 0x41
|
||||
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
|
||||
|
||||
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
|
||||
#define TX_RX_LED_PULSE_MS 100
|
||||
volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
|
||||
volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
extern const u16 STRING_LANGUAGE[] PROGMEM;
|
||||
extern const u8 STRING_PRODUCT[] PROGMEM;
|
||||
extern const u8 STRING_MANUFACTURER[] PROGMEM;
|
||||
extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM;
|
||||
extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM;
|
||||
|
||||
const u16 STRING_LANGUAGE[2] = {
|
||||
(3 << 8) | (2 + 2),
|
||||
0x0409 // English
|
||||
};
|
||||
|
||||
#ifndef USB_PRODUCT
|
||||
// If no product is provided, use USB IO Board
|
||||
#define USB_PRODUCT "USB IO Board"
|
||||
#endif
|
||||
|
||||
const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
|
||||
|
||||
#if USB_VID == 0x2341
|
||||
# if defined(USB_MANUFACTURER)
|
||||
# undef USB_MANUFACTURER
|
||||
# endif
|
||||
# define USB_MANUFACTURER "Arduino LLC"
|
||||
#elif USB_VID == 0x1b4f
|
||||
# if defined(USB_MANUFACTURER)
|
||||
# undef USB_MANUFACTURER
|
||||
# endif
|
||||
# define USB_MANUFACTURER "SparkFun"
|
||||
#elif !defined(USB_MANUFACTURER)
|
||||
// Fall through to unknown if no manufacturer name was provided in a macro
|
||||
# define USB_MANUFACTURER "Unknown"
|
||||
#endif
|
||||
|
||||
const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER;
|
||||
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
#define DEVICE_CLASS 0x02
|
||||
#else
|
||||
#define DEVICE_CLASS 0x00
|
||||
#endif
|
||||
|
||||
// edit by NicoHood
|
||||
// warning from USBlyzer: IAD is used. Should be EFh (Miscellaneous Device Class).
|
||||
// Lufa also use these values, so i will use them at least for the u2 boards. Someone should fix this for the u4 series if needed.
|
||||
// You have to use this descriptor if you have CDC AND HID at the same time. Otherwise they are quite different.
|
||||
#if defined(HID_ENABLED) && (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__))
|
||||
|
||||
// DEVICE DESCRIPTOR
|
||||
const DeviceDescriptor USB_DeviceDescriptor =
|
||||
D_DEVICE(0xEF, 0x02, 0x01, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1);
|
||||
|
||||
#else
|
||||
|
||||
// DEVICE DESCRIPTOR
|
||||
const DeviceDescriptor USB_DeviceDescriptor =
|
||||
D_DEVICE(0x00, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1);
|
||||
|
||||
#endif
|
||||
|
||||
const DeviceDescriptor USB_DeviceDescriptorA =
|
||||
D_DEVICE(DEVICE_CLASS, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1);
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
volatile u8 _usbConfiguration = 0;
|
||||
|
||||
static inline void WaitIN(void)
|
||||
{
|
||||
while (!(UEINTX & (1 << TXINI)))
|
||||
;
|
||||
}
|
||||
|
||||
static inline void ClearIN(void)
|
||||
{
|
||||
UEINTX = ~(1 << TXINI);
|
||||
}
|
||||
|
||||
static inline void WaitOUT(void)
|
||||
{
|
||||
while (!(UEINTX & (1 << RXOUTI)))
|
||||
;
|
||||
}
|
||||
|
||||
static inline u8 WaitForINOrOUT()
|
||||
{
|
||||
while (!(UEINTX & ((1 << TXINI) | (1 << RXOUTI))))
|
||||
;
|
||||
return (UEINTX & (1 << RXOUTI)) == 0;
|
||||
}
|
||||
|
||||
static inline void ClearOUT(void)
|
||||
{
|
||||
UEINTX = ~(1 << RXOUTI);
|
||||
}
|
||||
|
||||
void Recv(volatile u8* data, u8 count)
|
||||
{
|
||||
while (count--)
|
||||
*data++ = UEDATX;
|
||||
|
||||
RXLED1; // light the RX LED
|
||||
RxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||
}
|
||||
|
||||
static inline u8 Recv8()
|
||||
{
|
||||
RXLED1; // light the RX LED
|
||||
RxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||
|
||||
return UEDATX;
|
||||
}
|
||||
|
||||
static inline void Send8(u8 d)
|
||||
{
|
||||
UEDATX = d;
|
||||
}
|
||||
|
||||
static inline void SetEP(u8 ep)
|
||||
{
|
||||
UENUM = ep;
|
||||
}
|
||||
|
||||
static inline u8 FifoByteCount()
|
||||
{
|
||||
return UEBCLX;
|
||||
}
|
||||
|
||||
static inline u8 ReceivedSetupInt()
|
||||
{
|
||||
return UEINTX & (1 << RXSTPI);
|
||||
}
|
||||
|
||||
static inline void ClearSetupInt()
|
||||
{
|
||||
UEINTX = ~((1 << RXSTPI) | (1 << RXOUTI) | (1 << TXINI));
|
||||
}
|
||||
|
||||
static inline void Stall()
|
||||
{
|
||||
UECONX = (1 << STALLRQ) | (1 << EPEN);
|
||||
}
|
||||
|
||||
static inline u8 ReadWriteAllowed()
|
||||
{
|
||||
return UEINTX & (1 << RWAL);
|
||||
}
|
||||
|
||||
static inline u8 Stalled()
|
||||
{
|
||||
return UEINTX & (1 << STALLEDI);
|
||||
}
|
||||
|
||||
static inline u8 FifoFree()
|
||||
{
|
||||
return UEINTX & (1 << FIFOCON);
|
||||
}
|
||||
|
||||
static inline void ReleaseRX()
|
||||
{
|
||||
UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1
|
||||
}
|
||||
|
||||
static inline void ReleaseTX()
|
||||
{
|
||||
UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0
|
||||
}
|
||||
|
||||
static inline u8 FrameNumber()
|
||||
{
|
||||
return UDFNUML;
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
u8 USBGetConfiguration(void)
|
||||
{
|
||||
return _usbConfiguration;
|
||||
}
|
||||
|
||||
#define USB_RECV_TIMEOUT
|
||||
class LockEP
|
||||
{
|
||||
u8 _sreg;
|
||||
public:
|
||||
LockEP(u8 ep) : _sreg(SREG)
|
||||
{
|
||||
cli();
|
||||
SetEP(ep & 7);
|
||||
}
|
||||
~LockEP()
|
||||
{
|
||||
SREG = _sreg;
|
||||
}
|
||||
};
|
||||
|
||||
// Number of bytes, assumes a rx endpoint
|
||||
u8 USB_Available(u8 ep)
|
||||
{
|
||||
LockEP lock(ep);
|
||||
return FifoByteCount();
|
||||
}
|
||||
|
||||
// Non Blocking receive
|
||||
// Return number of bytes read
|
||||
int USB_Recv(u8 ep, void* d, int len)
|
||||
{
|
||||
if (!_usbConfiguration || len < 0)
|
||||
return -1;
|
||||
|
||||
LockEP lock(ep);
|
||||
u8 n = FifoByteCount();
|
||||
len = min(n, len);
|
||||
n = len;
|
||||
u8* dst = (u8*)d;
|
||||
while (n--)
|
||||
*dst++ = Recv8();
|
||||
if (len && !FifoByteCount()) // release empty buffer
|
||||
ReleaseRX();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Recv 1 byte if ready
|
||||
int USB_Recv(u8 ep)
|
||||
{
|
||||
u8 c;
|
||||
if (USB_Recv(ep, &c, 1) != 1)
|
||||
return -1;
|
||||
return c;
|
||||
}
|
||||
|
||||
// Space in send EP
|
||||
u8 USB_SendSpace(u8 ep)
|
||||
{
|
||||
LockEP lock(ep);
|
||||
if (!ReadWriteAllowed())
|
||||
return 0;
|
||||
// edit by NicoHood
|
||||
return USB_EP_SIZE - FifoByteCount();
|
||||
}
|
||||
|
||||
// Blocking Send of data to an endpoint
|
||||
int USB_Send(u8 ep, const void* d, int len)
|
||||
{
|
||||
if (!_usbConfiguration)
|
||||
return -1;
|
||||
|
||||
int r = len;
|
||||
const u8* data = (const u8*)d;
|
||||
u8 timeout = 250; // 250ms timeout on send? TODO
|
||||
while (len)
|
||||
{
|
||||
u8 n = USB_SendSpace(ep);
|
||||
if (n == 0)
|
||||
{
|
||||
if (!(--timeout))
|
||||
return -1;
|
||||
delay(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n > len)
|
||||
n = len;
|
||||
{
|
||||
LockEP lock(ep);
|
||||
// Frame may have been released by the SOF interrupt handler
|
||||
if (!ReadWriteAllowed())
|
||||
continue;
|
||||
len -= n;
|
||||
if (ep & TRANSFER_ZERO)
|
||||
{
|
||||
while (n--)
|
||||
Send8(0);
|
||||
}
|
||||
else if (ep & TRANSFER_PGM)
|
||||
{
|
||||
while (n--)
|
||||
Send8(pgm_read_byte(data++));
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
Send8(*data++);
|
||||
}
|
||||
if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer
|
||||
ReleaseTX();
|
||||
}
|
||||
}
|
||||
TXLED1; // light the TX LED
|
||||
TxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||
return r;
|
||||
}
|
||||
|
||||
extern const u8 _initEndpoints[] PROGMEM;
|
||||
const u8 _initEndpoints[] =
|
||||
{
|
||||
0,
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
|
||||
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
|
||||
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT
|
||||
#endif
|
||||
};
|
||||
|
||||
#define EP_SINGLE_64 0x32 // EP0
|
||||
#define EP_DOUBLE_64 0x36 // Other endpoints
|
||||
// edit by NicoHood
|
||||
#define EP_SINGLE_16 0x12
|
||||
|
||||
static
|
||||
void InitEP(u8 index, u8 type, u8 size)
|
||||
{
|
||||
UENUM = index;
|
||||
UECONX = 1;
|
||||
UECFG0X = type;
|
||||
UECFG1X = size;
|
||||
}
|
||||
|
||||
static
|
||||
void InitEndpoints()
|
||||
{
|
||||
for (u8 i = 1; i < sizeof(_initEndpoints); i++)
|
||||
{
|
||||
UENUM = i;
|
||||
UECONX = 1;
|
||||
UECFG0X = pgm_read_byte(_initEndpoints + i);
|
||||
// edit by NicoHood
|
||||
#if USB_EP_SIZE == 16
|
||||
UECFG1X = EP_SINGLE_16;
|
||||
#elif USB_EP_SIZE == 64
|
||||
UECFG1X = EP_DOUBLE_64;
|
||||
#else
|
||||
#error Unsupported value for USB_EP_SIZE
|
||||
#endif
|
||||
}
|
||||
UERST = 0x7E; // And reset them
|
||||
UERST = 0;
|
||||
}
|
||||
|
||||
// Handle CLASS_INTERFACE requests
|
||||
static
|
||||
bool ClassInterfaceRequest(Setup& setup)
|
||||
{
|
||||
u8 i = setup.wIndex;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
if (CDC_ACM_INTERFACE == i)
|
||||
return CDC_Setup(setup);
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
if (HID_INTERFACE == i)
|
||||
return HID_Setup(setup);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int _cmark;
|
||||
int _cend;
|
||||
void InitControl(int end)
|
||||
{
|
||||
SetEP(0);
|
||||
_cmark = 0;
|
||||
_cend = end;
|
||||
}
|
||||
|
||||
static
|
||||
bool SendControl(u8 d)
|
||||
{
|
||||
if (_cmark < _cend)
|
||||
{
|
||||
if (!WaitForINOrOUT())
|
||||
return false;
|
||||
Send8(d);
|
||||
if (!((_cmark + 1) & 0x3F))
|
||||
ClearIN(); // Fifo is full, release this packet
|
||||
}
|
||||
_cmark++;
|
||||
return true;
|
||||
};
|
||||
|
||||
// Clipped by _cmark/_cend
|
||||
int USB_SendControl(u8 flags, const void* d, int len)
|
||||
{
|
||||
int sent = len;
|
||||
const u8* data = (const u8*)d;
|
||||
bool pgm = flags & TRANSFER_PGM;
|
||||
while (len--)
|
||||
{
|
||||
u8 c = pgm ? pgm_read_byte(data++) : *data++;
|
||||
if (!SendControl(c))
|
||||
return -1;
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
// Send a USB descriptor string. The string is stored in PROGMEM as a
|
||||
// plain ASCII string but is sent out as UTF-16 with the correct 2-byte
|
||||
// prefix
|
||||
static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) {
|
||||
SendControl(2 + string_len * 2);
|
||||
SendControl(3);
|
||||
for (u8 i = 0; i < string_len; i++) {
|
||||
bool r = SendControl(pgm_read_byte(&string_P[i]));
|
||||
r &= SendControl(0); // high byte
|
||||
if (!r) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Does not timeout or cross fifo boundaries
|
||||
// Will only work for transfers <= 64 bytes
|
||||
// TODO
|
||||
int USB_RecvControl(void* d, int len)
|
||||
{
|
||||
WaitOUT();
|
||||
Recv((u8*)d, len);
|
||||
ClearOUT();
|
||||
return len;
|
||||
}
|
||||
|
||||
int SendInterfaces()
|
||||
{
|
||||
int total = 0;
|
||||
u8 interfaces = 0;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
total = CDC_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
total += HID_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
// Construct a dynamic configuration descriptor
|
||||
// This really needs dynamic endpoint allocation etc
|
||||
// TODO
|
||||
static
|
||||
bool SendConfiguration(int maxlen)
|
||||
{
|
||||
// Count and measure interfaces
|
||||
InitControl(0);
|
||||
int interfaces = SendInterfaces();
|
||||
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor), interfaces);
|
||||
|
||||
// Now send them
|
||||
InitControl(maxlen);
|
||||
USB_SendControl(0, &config, sizeof(ConfigDescriptor));
|
||||
SendInterfaces();
|
||||
return true;
|
||||
}
|
||||
|
||||
u8 _cdcComposite = 0;
|
||||
|
||||
static
|
||||
bool SendDescriptor(Setup& setup)
|
||||
{
|
||||
u8 t = setup.wValueH;
|
||||
if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
|
||||
return SendConfiguration(setup.wLength);
|
||||
|
||||
InitControl(setup.wLength);
|
||||
#ifdef HID_ENABLED
|
||||
if (HID_REPORT_DESCRIPTOR_TYPE == t)
|
||||
return HID_GetDescriptor(t);
|
||||
#endif
|
||||
|
||||
const u8* desc_addr = 0;
|
||||
if (USB_DEVICE_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
if (setup.wLength == 8)
|
||||
_cdcComposite = 1;
|
||||
desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor;
|
||||
}
|
||||
else if (USB_STRING_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
if (setup.wValueL == 0) {
|
||||
desc_addr = (const u8*)&STRING_LANGUAGE;
|
||||
}
|
||||
else if (setup.wValueL == IPRODUCT) {
|
||||
return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT));
|
||||
}
|
||||
else if (setup.wValueL == IMANUFACTURER) {
|
||||
return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc_addr == 0)
|
||||
return false;
|
||||
u8 desc_length = pgm_read_byte(desc_addr);
|
||||
|
||||
USB_SendControl(TRANSFER_PGM, desc_addr, desc_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Endpoint 0 interrupt
|
||||
ISR(USB_COM_vect)
|
||||
{
|
||||
SetEP(0);
|
||||
if (!ReceivedSetupInt())
|
||||
return;
|
||||
|
||||
Setup setup;
|
||||
Recv((u8*)&setup, 8);
|
||||
ClearSetupInt();
|
||||
|
||||
u8 requestType = setup.bmRequestType;
|
||||
if (requestType & REQUEST_DEVICETOHOST)
|
||||
WaitIN();
|
||||
else
|
||||
ClearIN();
|
||||
|
||||
bool ok = true;
|
||||
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
|
||||
{
|
||||
// Standard Requests
|
||||
u8 r = setup.bRequest;
|
||||
if (GET_STATUS == r)
|
||||
{
|
||||
Send8(0); // TODO
|
||||
Send8(0);
|
||||
}
|
||||
else if (CLEAR_FEATURE == r)
|
||||
{
|
||||
}
|
||||
else if (SET_FEATURE == r)
|
||||
{
|
||||
}
|
||||
else if (SET_ADDRESS == r)
|
||||
{
|
||||
WaitIN();
|
||||
UDADDR = setup.wValueL | (1 << ADDEN);
|
||||
}
|
||||
else if (GET_DESCRIPTOR == r)
|
||||
{
|
||||
ok = SendDescriptor(setup);
|
||||
}
|
||||
else if (SET_DESCRIPTOR == r)
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
else if (GET_CONFIGURATION == r)
|
||||
{
|
||||
Send8(1);
|
||||
}
|
||||
else if (SET_CONFIGURATION == r)
|
||||
{
|
||||
if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
|
||||
{
|
||||
InitEndpoints();
|
||||
_usbConfiguration = setup.wValueL;
|
||||
}
|
||||
else
|
||||
ok = false;
|
||||
}
|
||||
else if (GET_INTERFACE == r)
|
||||
{
|
||||
}
|
||||
else if (SET_INTERFACE == r)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InitControl(setup.wLength); // Max length of transfer
|
||||
ok = ClassInterfaceRequest(setup);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
ClearIN();
|
||||
else
|
||||
{
|
||||
Stall();
|
||||
}
|
||||
}
|
||||
|
||||
void USB_Flush(u8 ep)
|
||||
{
|
||||
SetEP(ep);
|
||||
if (FifoByteCount())
|
||||
ReleaseTX();
|
||||
}
|
||||
|
||||
// General interrupt
|
||||
ISR(USB_GEN_vect)
|
||||
{
|
||||
u8 udint = UDINT;
|
||||
UDINT = 0;
|
||||
|
||||
// End of Reset
|
||||
if (udint & (1 << EORSTI))
|
||||
{
|
||||
InitEP(0, EP_TYPE_CONTROL, EP_SINGLE_64); // init ep0
|
||||
_usbConfiguration = 0; // not configured yet
|
||||
UEIENX = 1 << RXSTPE; // Enable interrupts for ep0
|
||||
}
|
||||
|
||||
// Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
|
||||
if (udint & (1 << SOFI))
|
||||
{
|
||||
#ifdef CDC_ENABLED
|
||||
USB_Flush(CDC_TX); // Send a tx frame if found
|
||||
#endif
|
||||
|
||||
// check whether the one-shot period has elapsed. if so, turn off the LED
|
||||
if (TxLEDPulse && !(--TxLEDPulse))
|
||||
TXLED0;
|
||||
if (RxLEDPulse && !(--RxLEDPulse))
|
||||
RXLED0;
|
||||
}
|
||||
}
|
||||
|
||||
// VBUS or counting frames
|
||||
// Any frame counting?
|
||||
u8 USBConnected()
|
||||
{
|
||||
u8 f = UDFNUML;
|
||||
delay(3);
|
||||
return f != UDFNUML;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
USBDevice_ USBDevice;
|
||||
|
||||
USBDevice_::USBDevice_()
|
||||
{
|
||||
}
|
||||
|
||||
// edit by NicoHood
|
||||
// added from teensy definition by paul stoffregen
|
||||
#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)
|
||||
#define HW_CONFIG()
|
||||
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
|
||||
#define USB_CONFIG() (USBCON = (1<<USBE))
|
||||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define HW_CONFIG() (UHWCON = 0x01)
|
||||
#define PLL_CONFIG() (PLLCSR = 0x12)
|
||||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
|
||||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define HW_CONFIG() (UHWCON = 0x81)
|
||||
#define PLL_CONFIG() (PLLCSR = 0x1A)
|
||||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
|
||||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define HW_CONFIG() (UHWCON = 0x81)
|
||||
#define PLL_CONFIG() (PLLCSR = 0x16)
|
||||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
|
||||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
|
||||
#endif
|
||||
|
||||
void USBDevice_::attach()
|
||||
{
|
||||
// edit by NicoHood
|
||||
_usbConfiguration = 0;
|
||||
HW_CONFIG(); // power internal reg
|
||||
|
||||
// from Paul, TODO needed?
|
||||
//USBCON = 0; // Reset controller
|
||||
USB_FREEZE(); // clock frozen, usb enabled
|
||||
|
||||
#if F_CPU == 16000000UL
|
||||
// Need 16 MHz xtal
|
||||
#ifdef PINDIV
|
||||
PLLCSR = (1 << PINDIV) | (1 << PLLE);
|
||||
#else
|
||||
// added from paul brook, no idea for what board this is used for
|
||||
PLLCSR = (1 << PLLP0) | (1 << PLLE);
|
||||
#endif
|
||||
|
||||
#elif F_CPU == 8000000UL
|
||||
// Need 8 MHz xtal
|
||||
PLLCSR = (1 << PLLE);
|
||||
#endif
|
||||
|
||||
while (!(PLLCSR & (1 << PLOCK))) // wait for lock pll
|
||||
;
|
||||
|
||||
// Some tests on specific versions of macosx (10.7.3), reported some
|
||||
// strange behaviuors when the board is reset using the serial
|
||||
// port touch at 1200 bps. This delay fixes this behaviour.
|
||||
delay(1);
|
||||
|
||||
USB_CONFIG(); // start USB clock
|
||||
UDIEN = (1 << EORSTE) | (1 << SOFE); // Enable interrupts for EOR (End of Reset) and SOF (start of frame)
|
||||
UDCON = 0; // enable attach resistor
|
||||
|
||||
TX_RX_LED_INIT;
|
||||
}
|
||||
|
||||
void USBDevice_::detach()
|
||||
{
|
||||
}
|
||||
|
||||
// Check for interrupts
|
||||
// TODO: VBUS detection
|
||||
bool USBDevice_::configured()
|
||||
{
|
||||
return _usbConfiguration;
|
||||
}
|
||||
|
||||
void USBDevice_::poll()
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
307
USBCore.h
307
USBCore.h
|
|
@ -1,307 +0,0 @@
|
|||
|
||||
// Copyright (c) 2010, 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 __USBCORE_H__
|
||||
#define __USBCORE_H__
|
||||
|
||||
// Standard requests
|
||||
#define GET_STATUS 0
|
||||
#define CLEAR_FEATURE 1
|
||||
#define SET_FEATURE 3
|
||||
#define SET_ADDRESS 5
|
||||
#define GET_DESCRIPTOR 6
|
||||
#define SET_DESCRIPTOR 7
|
||||
#define GET_CONFIGURATION 8
|
||||
#define SET_CONFIGURATION 9
|
||||
#define GET_INTERFACE 10
|
||||
#define SET_INTERFACE 11
|
||||
|
||||
|
||||
// bmRequestType
|
||||
#define REQUEST_HOSTTODEVICE 0x00
|
||||
#define REQUEST_DEVICETOHOST 0x80
|
||||
#define REQUEST_DIRECTION 0x80
|
||||
|
||||
#define REQUEST_STANDARD 0x00
|
||||
#define REQUEST_CLASS 0x20
|
||||
#define REQUEST_VENDOR 0x40
|
||||
#define REQUEST_TYPE 0x60
|
||||
|
||||
#define REQUEST_DEVICE 0x00
|
||||
#define REQUEST_INTERFACE 0x01
|
||||
#define REQUEST_ENDPOINT 0x02
|
||||
#define REQUEST_OTHER 0x03
|
||||
#define REQUEST_RECIPIENT 0x03
|
||||
|
||||
#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE)
|
||||
#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE)
|
||||
|
||||
// Class requests
|
||||
|
||||
#define CDC_SET_LINE_CODING 0x20
|
||||
#define CDC_GET_LINE_CODING 0x21
|
||||
#define CDC_SET_CONTROL_LINE_STATE 0x22
|
||||
|
||||
// edit by NicoHood
|
||||
#define CDC_CONTROL_LINE_OUT_DTR (1 << 0)
|
||||
#define CDC_CONTROL_LINE_OUT_RTS (1 << 1)
|
||||
|
||||
#define MSC_RESET 0xFF
|
||||
#define MSC_GET_MAX_LUN 0xFE
|
||||
|
||||
#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
|
||||
|
||||
// Descriptors
|
||||
|
||||
#define USB_DEVICE_DESC_SIZE 18
|
||||
#define USB_CONFIGUARTION_DESC_SIZE 9
|
||||
#define USB_INTERFACE_DESC_SIZE 9
|
||||
#define USB_ENDPOINT_DESC_SIZE 7
|
||||
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 1
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 3
|
||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
|
||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
|
||||
|
||||
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
|
||||
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
|
||||
#define USB_DEVICE_CLASS_STORAGE 0x08
|
||||
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
|
||||
|
||||
#define USB_CONFIG_POWERED_MASK 0x40
|
||||
#define USB_CONFIG_BUS_POWERED 0x80
|
||||
#define USB_CONFIG_SELF_POWERED 0xC0
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 0x20
|
||||
|
||||
// bMaxPower in Configuration Descriptor
|
||||
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
|
||||
|
||||
// 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_TYPE_MASK 0x03
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
|
||||
#define USB_ENDPOINT_TYPE_BULK 0x02
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
|
||||
|
||||
#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
|
||||
|
||||
#define CDC_V1_10 0x0110
|
||||
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
|
||||
|
||||
#define CDC_CALL_MANAGEMENT 0x01
|
||||
#define CDC_ABSTRACT_CONTROL_MODEL 0x02
|
||||
#define CDC_HEADER 0x00
|
||||
#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
|
||||
#define CDC_UNION 0x06
|
||||
#define CDC_CS_INTERFACE 0x24
|
||||
#define CDC_CS_ENDPOINT 0x25
|
||||
#define CDC_DATA_INTERFACE_CLASS 0x0A
|
||||
|
||||
#define MSC_SUBCLASS_SCSI 0x06
|
||||
#define MSC_PROTOCOL_BULK_ONLY 0x50
|
||||
|
||||
#define HID_HID_DESCRIPTOR_TYPE 0x21
|
||||
#define HID_REPORT_DESCRIPTOR_TYPE 0x22
|
||||
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
|
||||
|
||||
|
||||
// Device
|
||||
typedef struct {
|
||||
u8 len; // 18
|
||||
u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
|
||||
u16 usbVersion; // 0x200
|
||||
u8 deviceClass;
|
||||
u8 deviceSubClass;
|
||||
u8 deviceProtocol;
|
||||
u8 packetSize0; // Packet 0
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
u16 deviceVersion; // 0x100
|
||||
u8 iManufacturer;
|
||||
u8 iProduct;
|
||||
u8 iSerialNumber;
|
||||
u8 bNumConfigurations;
|
||||
} DeviceDescriptor;
|
||||
|
||||
// Config
|
||||
typedef struct {
|
||||
u8 len; // 9
|
||||
u8 dtype; // 2
|
||||
u16 clen; // total length
|
||||
u8 numInterfaces;
|
||||
u8 config;
|
||||
u8 iconfig;
|
||||
u8 attributes;
|
||||
u8 maxPower;
|
||||
} ConfigDescriptor;
|
||||
|
||||
// String
|
||||
|
||||
// Interface
|
||||
typedef struct
|
||||
{
|
||||
u8 len; // 9
|
||||
u8 dtype; // 4
|
||||
u8 number;
|
||||
u8 alternate;
|
||||
u8 numEndpoints;
|
||||
u8 interfaceClass;
|
||||
u8 interfaceSubClass;
|
||||
u8 protocol;
|
||||
u8 iInterface;
|
||||
} InterfaceDescriptor;
|
||||
|
||||
// Endpoint
|
||||
typedef struct
|
||||
{
|
||||
u8 len; // 7
|
||||
u8 dtype; // 5
|
||||
u8 addr;
|
||||
u8 attr;
|
||||
u16 packetSize;
|
||||
u8 interval;
|
||||
} EndpointDescriptor;
|
||||
|
||||
// Interface Association Descriptor
|
||||
// Used to bind 2 interfaces together in CDC compostite device
|
||||
typedef struct
|
||||
{
|
||||
u8 len; // 8
|
||||
u8 dtype; // 11
|
||||
u8 firstInterface;
|
||||
u8 interfaceCount;
|
||||
u8 functionClass;
|
||||
u8 funtionSubClass;
|
||||
u8 functionProtocol;
|
||||
u8 iInterface;
|
||||
} IADDescriptor;
|
||||
|
||||
// CDC CS interface descriptor
|
||||
typedef struct
|
||||
{
|
||||
u8 len; // 5
|
||||
u8 dtype; // 0x24
|
||||
u8 subtype;
|
||||
u8 d0;
|
||||
u8 d1;
|
||||
} CDCCSInterfaceDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 len; // 4
|
||||
u8 dtype; // 0x24
|
||||
u8 subtype;
|
||||
u8 d0;
|
||||
} CDCCSInterfaceDescriptor4;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 len;
|
||||
u8 dtype; // 0x24
|
||||
u8 subtype; // 1
|
||||
u8 bmCapabilities;
|
||||
u8 bDataInterface;
|
||||
} CMFunctionalDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 len;
|
||||
u8 dtype; // 0x24
|
||||
u8 subtype; // 1
|
||||
u8 bmCapabilities;
|
||||
} ACMFunctionalDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// IAD
|
||||
IADDescriptor iad; // Only needed on compound device
|
||||
|
||||
// Control
|
||||
InterfaceDescriptor cif; //
|
||||
CDCCSInterfaceDescriptor header;
|
||||
CMFunctionalDescriptor callManagement; // Call Management
|
||||
ACMFunctionalDescriptor controlManagement; // ACM
|
||||
CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION
|
||||
EndpointDescriptor cifin;
|
||||
|
||||
// Data
|
||||
InterfaceDescriptor dif;
|
||||
EndpointDescriptor in;
|
||||
EndpointDescriptor out;
|
||||
} CDCDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
InterfaceDescriptor msc;
|
||||
EndpointDescriptor in;
|
||||
EndpointDescriptor out;
|
||||
} MSCDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 len; // 9
|
||||
u8 dtype; // 0x21
|
||||
u8 addr;
|
||||
u8 versionL; // 0x101
|
||||
u8 versionH; // 0x101
|
||||
u8 country;
|
||||
u8 desctype; // 0x22 report
|
||||
u8 descLenL;
|
||||
u8 descLenH;
|
||||
} HIDDescDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
InterfaceDescriptor hid;
|
||||
HIDDescDescriptor desc;
|
||||
EndpointDescriptor in;
|
||||
} HIDDescriptor;
|
||||
|
||||
|
||||
#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
|
||||
{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
|
||||
|
||||
#define D_CONFIG(_totalLength,_interfaces) \
|
||||
{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) }
|
||||
|
||||
#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
|
||||
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
|
||||
|
||||
#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
|
||||
{ 7, 5, _addr,_attr,_packetSize, _interval }
|
||||
|
||||
#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
|
||||
{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
|
||||
|
||||
#define D_HIDREPORT(_descriptorLength) \
|
||||
{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 }
|
||||
|
||||
#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
|
||||
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
|
||||
|
||||
|
||||
#endif
|
||||
90
USBDesc.h
90
USBDesc.h
|
|
@ -1,90 +0,0 @@
|
|||
|
||||
|
||||
/* 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) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define CDC_ENABLED
|
||||
#define HID_ENABLED
|
||||
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
#define CDC_INTERFACE_COUNT 2
|
||||
#define CDC_ENPOINT_COUNT 3
|
||||
#else
|
||||
#define CDC_INTERFACE_COUNT 0
|
||||
#define CDC_ENPOINT_COUNT 0
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
#define HID_INTERFACE_COUNT 1
|
||||
#define HID_ENPOINT_COUNT 1
|
||||
#else
|
||||
#define HID_INTERFACE_COUNT 0
|
||||
#define HID_ENPOINT_COUNT 0
|
||||
#endif
|
||||
|
||||
#define CDC_ACM_INTERFACE 0 // CDC ACM
|
||||
#define CDC_DATA_INTERFACE 1 // CDC Data
|
||||
#define CDC_FIRST_ENDPOINT 1
|
||||
#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First
|
||||
#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1)
|
||||
#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2)
|
||||
|
||||
#define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface
|
||||
#define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT)
|
||||
#define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT)
|
||||
|
||||
#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT)
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
#define CDC_RX CDC_ENDPOINT_OUT
|
||||
#define CDC_TX CDC_ENDPOINT_IN
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
#define HID_TX HID_ENDPOINT_INT
|
||||
#endif
|
||||
|
||||
// edit by NicoHood
|
||||
#ifndef USB_EP_SIZE
|
||||
#define USB_EP_SIZE 64
|
||||
#endif
|
||||
#define IMANUFACTURER 1
|
||||
#define IPRODUCT 2
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Advanced Gamepad example
|
||||
*/
|
||||
|
||||
// include HID library
|
||||
#include <HID.h>
|
||||
|
||||
// see HID_Reports.h for all data structures
|
||||
HID_GamepadReport_Data_t Gamepadreport;
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
// see HID_Reports.h for all data structures
|
||||
HID_GamepadReport_Data_t Gamepadreport;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
memset(&Gamepadreport, 0, sizeof(Gamepadreport));
|
||||
HID_SendReport(HID_REPORTID_Gamepad1Report, &Gamepadreport, sizeof(Gamepadreport));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// This demo is actually made for advanced users to show them how they can write an own report.
|
||||
// This might be useful for a Gamepad if you want to edit the values direct on your own.
|
||||
|
||||
// count with buttons binary
|
||||
static uint32_t count = 0;
|
||||
Gamepadreport.whole32[0] = count++;
|
||||
|
||||
// move x/y Axis to a new position (16bit)
|
||||
Gamepadreport.whole16[2] = (random(0xFFFF));
|
||||
|
||||
// functions before only set the values
|
||||
// this writes the report to the host
|
||||
HID_SendReport(HID_REPORTID_Gamepad1Report, &Gamepadreport, sizeof(Gamepadreport));
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Advanced Keyboard example
|
||||
|
||||
This demo is actually made for advanced users to show them how they can write an own report.
|
||||
This might be useful for a Keyboard if you only use one key,
|
||||
because the library has a lot of code for simple use
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
pressRawKeyboard(0, 0);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// press normal keys (a-z, A-Z, 0-9)
|
||||
pressRawKeyboard(0, RAW_KEYBOARD_KEY('a')); //modifiers + a
|
||||
pressRawKeyboard(0, RAW_KEYBOARD_KEY('Z')); //modifiers + Z
|
||||
|
||||
// press STRG + ALT + DEL on keyboard (see usb documentation for more)
|
||||
//pressRawKeyboard(RAW_KEYBOARD_LEFT_CTRL | RAW_KEYBOARD_LEFT_ALT , RAW_KEYBOARD_DELETE); //modifiers + key
|
||||
|
||||
// release! Important
|
||||
pressRawKeyboard(0, 0);
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void pressRawKeyboard(uint8_t modifiers, uint8_t key) {
|
||||
uint8_t keys[8] = {
|
||||
modifiers, 0, key, 0, 0, 0, 0, 0
|
||||
}; //modifiers, reserved, key[0]
|
||||
HID_SendReport(HID_REPORTID_KeyboardReport, keys, sizeof(keys));
|
||||
}
|
||||
|
||||
/*
|
||||
See Hut1_12v2.pdf Chapter 10 (Page 53) for more Keys
|
||||
(especially a-z, a=0x04 z=29)
|
||||
Definitions:
|
||||
|
||||
RAW_KEYBOARD_LEFT_CTRL
|
||||
RAW_KEYBOARD_LEFT_SHIFT
|
||||
RAW_KEYBOARD_LEFT_ALT
|
||||
RAW_KEYBOARD_LEFT_GUI
|
||||
RAW_KEYBOARD_RIGHT_CTRL
|
||||
RAW_KEYBOARD_RIGHT_SHIFT
|
||||
RAW_KEYBOARD_RIGHT_ALT
|
||||
RAW_KEYBOARD_RIGHT_GUI
|
||||
|
||||
RAW_KEYBOARD_KEY(key)
|
||||
|
||||
RAW_KEYBOARD_UP_ARROW
|
||||
RAW_KEYBOARD_DOWN_ARROW
|
||||
RAW_KEYBOARD_LEFT_ARROW
|
||||
RAW_KEYBOARD_RIGHT_ARROW
|
||||
RAW_KEYBOARD_SPACEBAR
|
||||
RAW_KEYBOARD_BACKSPACE
|
||||
RAW_KEYBOARD_TAB
|
||||
RAW_KEYBOARD_RETURN
|
||||
RAW_KEYBOARD_ESC
|
||||
RAW_KEYBOARD_INSERT
|
||||
RAW_KEYBOARD_DELETE
|
||||
RAW_KEYBOARD_PAGE_UP
|
||||
RAW_KEYBOARD_PAGE_DOWN
|
||||
RAW_KEYBOARD_HOME
|
||||
RAW_KEYBOARD_END
|
||||
RAW_KEYBOARD_CAPS_LOCK
|
||||
RAW_KEYBOARD_F1
|
||||
RAW_KEYBOARD_F2
|
||||
RAW_KEYBOARD_F3
|
||||
RAW_KEYBOARD_F4
|
||||
RAW_KEYBOARD_F5
|
||||
RAW_KEYBOARD_F6
|
||||
RAW_KEYBOARD_F7
|
||||
RAW_KEYBOARD_F8
|
||||
RAW_KEYBOARD_F9
|
||||
RAW_KEYBOARD_F10
|
||||
RAW_KEYBOARD_F11
|
||||
RAW_KEYBOARD_F12
|
||||
RAW_KEYBOARD_PRINT
|
||||
RAW_KEYBOARD_SCROLL_LOCK
|
||||
RAW_KEYBOARD_PAUSE
|
||||
*/
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Advanced RawHID example
|
||||
|
||||
Shows how to send bytes via raw HID
|
||||
Press a button to send some example values.
|
||||
Keep in mind that you can only send full data packets, the rest is filled with zero!
|
||||
|
||||
Definitions from HID_Reports.h:
|
||||
RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF
|
||||
RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF
|
||||
RAWHID_TX_SIZE 15 // 1 byte for report ID
|
||||
RAWHID_RX_SIZE 15 // 1 byte for report ID
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// no begin function needed for RawHID
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// direct without library. Always send RAWHID_RX_SIZE bytes!
|
||||
uint8_t buff[RAWHID_RX_SIZE]; // unitialized, has random values
|
||||
HID_SendReport(HID_REPORTID_RawKeyboardReport, buff, sizeof(buff));
|
||||
|
||||
// with library
|
||||
memset(&buff, 42, sizeof(buff));
|
||||
RawHID.write(buff, sizeof(buff));
|
||||
|
||||
// write a single byte, will fill the rest with zeros
|
||||
RawHID.write(0xCD);
|
||||
|
||||
// huge buffer with library, will fill the rest with zeros
|
||||
uint8_t megabuff[64];
|
||||
for (int i = 0; i < sizeof(megabuff); i++)
|
||||
megabuff[i] = i;
|
||||
RawHID.write(megabuff, sizeof(megabuff));
|
||||
|
||||
// You can use print too, but better dont use a linefeed
|
||||
RawHID.println("Hello World");
|
||||
|
||||
// And compare it to write:
|
||||
RawHID.write("Hello World\r\n");
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Expected output:
|
||||
|
||||
// manual with unintialized buff
|
||||
recv 15 bytes:
|
||||
01 55 C1 FF 01 01 01 00 00 01 00 00 01 00 20
|
||||
|
||||
// filled buff
|
||||
recv 15 bytes:
|
||||
2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
|
||||
|
||||
// single byte filled with zero
|
||||
recv 15 bytes:
|
||||
CD 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
// huge buffer filled with zero at the end
|
||||
recv 15 bytes:
|
||||
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E
|
||||
|
||||
recv 15 bytes:
|
||||
0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D
|
||||
|
||||
recv 15 bytes:
|
||||
1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C
|
||||
|
||||
recv 15 bytes:
|
||||
2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B
|
||||
|
||||
recv 15 bytes:
|
||||
3C 3D 3E 3F 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
// print
|
||||
recv 15 bytes:
|
||||
48 65 6C 6C 6F 20 57 6F 72 6C 64 00 00 00 00
|
||||
|
||||
//\r
|
||||
recv 15 bytes:
|
||||
0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
//\n
|
||||
recv 15 bytes:
|
||||
0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
//write
|
||||
recv 15 bytes:
|
||||
48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A 00 00
|
||||
|
||||
*/
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Gamepad example
|
||||
|
||||
Press a button and demonstrate Gamepad actions
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
Gamepad.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// press button 1-32 and reset (34 becaue its written later)
|
||||
static uint8_t count = 1;
|
||||
Gamepad.press(count++);
|
||||
if (count == 34) {
|
||||
Gamepad.releaseAll();
|
||||
count = 1;
|
||||
}
|
||||
|
||||
// move x/y Axis to a new position (16bit)
|
||||
Gamepad.xAxis(random(0xFFFF));
|
||||
Gamepad.yAxis(random(0xFFFF));
|
||||
|
||||
// go through all dPad positions
|
||||
// values: 0-8 (0==centred)
|
||||
static uint8_t dpad1 = GAMEPAD_DPAD_CENTERED;
|
||||
Gamepad.dPad1(dpad1++);
|
||||
if(dpad1>GAMEPAD_DPAD_UP_LEFT) dpad1 = GAMEPAD_DPAD_CENTERED;
|
||||
static int8_t dpad2 = GAMEPAD_DPAD_CENTERED;
|
||||
Gamepad.dPad2(dpad2--);
|
||||
if(dpad2<GAMEPAD_DPAD_CENTERED) dpad2 = GAMEPAD_DPAD_UP_LEFT;
|
||||
|
||||
|
||||
// functions before only set the values
|
||||
// this writes the report to the host
|
||||
Gamepad.write();
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Prototypes:
|
||||
|
||||
void begin(void);
|
||||
void end(void);
|
||||
void write(void);
|
||||
void press(uint8_t b);
|
||||
void release(uint8_t b);
|
||||
void releaseAll(void);
|
||||
void buttons(uint32_t b);
|
||||
void xAxis(int16_t a);
|
||||
void yAxis(int16_t a);
|
||||
void rxAxis(int16_t a);
|
||||
void ryAxis(int16_t a);
|
||||
void zAxis(int8_t a);
|
||||
void rzAxis(int8_t a);
|
||||
void dPad1(int8_t d);
|
||||
void dPad2(int8_t d);
|
||||
|
||||
Definitions:
|
||||
GAMEPAD_DPAD_CENTERED 0
|
||||
GAMEPAD_DPAD_UP 1
|
||||
GAMEPAD_DPAD_UP_RIGHT 2
|
||||
GAMEPAD_DPAD_RIGHT 3
|
||||
GAMEPAD_DPAD_DOWN_RIGHT 4
|
||||
GAMEPAD_DPAD_DOWN 5
|
||||
GAMEPAD_DPAD_DOWN_LEFT 6
|
||||
GAMEPAD_DPAD_LEFT 7
|
||||
GAMEPAD_DPAD_UP_LEFT 8
|
||||
*/
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Keyboard example
|
||||
|
||||
Press a button to write some text to your pc.
|
||||
See official documentation for more infos
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Starts Serial debug output
|
||||
Serial.begin(115200);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
Keyboard.begin();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// Same use as the official library, pretty much self explaining
|
||||
Keyboard.println("This message was sent with my Arduino.");
|
||||
Serial.println("Serial port is still working and not glitching out");
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Definitions:
|
||||
|
||||
KEY_LEFT_CTRL
|
||||
KEY_LEFT_SHIFT
|
||||
KEY_LEFT_ALT
|
||||
KEY_LEFT_GUI
|
||||
KEY_RIGHT_CTRL
|
||||
KEY_RIGHT_SHIFT
|
||||
KEY_RIGHT_ALT
|
||||
KEY_RIGHT_GUI
|
||||
|
||||
KEY_UP_ARROW
|
||||
KEY_DOWN_ARROW
|
||||
KEY_LEFT_ARROW
|
||||
KEY_RIGHT_ARROW
|
||||
KEY_BACKSPACE
|
||||
KEY_TAB
|
||||
KEY_RETURN
|
||||
KEY_ESC
|
||||
KEY_INSERT
|
||||
KEY_DELETE
|
||||
KEY_PAGE_UP
|
||||
KEY_PAGE_DOWN
|
||||
KEY_HOME
|
||||
KEY_END
|
||||
KEY_CAPS_LOCK
|
||||
KEY_F1
|
||||
KEY_F2
|
||||
KEY_F3
|
||||
KEY_F4
|
||||
KEY_F5
|
||||
KEY_F6
|
||||
KEY_F7
|
||||
KEY_F8
|
||||
KEY_F9
|
||||
KEY_F10
|
||||
KEY_F11
|
||||
KEY_F12
|
||||
|
||||
KEY_PRINT
|
||||
KEY_SCROLL_LOCK
|
||||
KEY_PAUSE
|
||||
*/
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Media example
|
||||
|
||||
Press a button to play/pause music player
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
Media.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// See list below for more definitions or the official usb documentation
|
||||
Media.write(MEDIA_PLAY_PAUSE);
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Definitions:
|
||||
|
||||
MEDIA_FAST_FORWARD
|
||||
MEDIA_REWIND
|
||||
MEDIA_NEXT
|
||||
MEDIA_PREVIOUS
|
||||
MEDIA_STOP
|
||||
MEDIA_PLAY_PAUSE
|
||||
|
||||
MEDIA_VOLUME_MUTE
|
||||
MEDIA_VOLUME_UP
|
||||
MEDIA_VOLUME_DOWN
|
||||
|
||||
MEDIA_EMAIL_READER
|
||||
MEDIA_CALCULATOR
|
||||
MEDIA_EXPLORER
|
||||
|
||||
MEDIA_BROWSER_HOME
|
||||
MEDIA_BROWSER_BACK
|
||||
MEDIA_BROWSER_FORWARD
|
||||
MEDIA_BROWSER_REFRESH
|
||||
MEDIA_BROWSER_BOOKMARKS
|
||||
*/
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Mouse example
|
||||
|
||||
Press a button to click with mouse. See official documentation for more infos
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Starts Serial debug output
|
||||
Serial.begin(115200);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
Mouse.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// Same use as the official library, pretty much self explaining
|
||||
Mouse.click();
|
||||
Serial.println("Serial port is still working and not glitching out");
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Definitions:
|
||||
|
||||
MOUSE_LEFT
|
||||
MOUSE_RIGHT
|
||||
MOUSE_MIDDLE
|
||||
MOUSE_PREV
|
||||
MOUSE_NEXT
|
||||
*/
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
System example
|
||||
|
||||
Press a button to put pc into standby mode
|
||||
*/
|
||||
|
||||
const int pinLed = LED_BUILTIN;
|
||||
const int pinButton = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
System.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// See list below for more definitions or the official usb documentation
|
||||
System.write(SYSTEM_SLEEP);
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Definitions:
|
||||
|
||||
SYSTEM_POWER_DOWN
|
||||
SYSTEM_SLEEP
|
||||
SYSTEM_WAKE_UP
|
||||
*/
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Keyboard HoodLoader1 API Legacy example
|
||||
|
||||
Legacy Example on how to access the Serial HID API of HoodLoader1.
|
||||
This methode is outdated, because you can now control the whole
|
||||
16u2 with HoodLoader2. It might be still usefull if you want the 328/2560
|
||||
keep control of the USB functions. Keep in mind that there is no such thing
|
||||
as flushing HID reports. If the USB Host is too slow HID reports might be missed.
|
||||
|
||||
You can also adapt the sending method below to send Mouse/Keyboard/Media/System reports.
|
||||
Gamepads/RawHID have a general problem with the original HoodLoader1 firmware, so please avoid this.
|
||||
It might be compatible with the new HoodLoader2 port of the protocol later on.
|
||||
|
||||
HID reports are converted into a special Serial Protocol with NHP.
|
||||
This sketch should only be used with a 328/2560, not a 16u2.
|
||||
The 16u2 has a HoodLoader1 compatible sketch/firmware loaded and will
|
||||
listen to the Serial Port for these Protocol packets on baud 115200.
|
||||
|
||||
The HID_SendReport function is implemented weak, so we can overwrite it
|
||||
in this sketch below. A simple NHP implementation encapsulated the HID reports
|
||||
into NHP packets with correct addresses and checksums.
|
||||
|
||||
Press a button to write some text to your pc.
|
||||
See official documentation for more infos
|
||||
*/
|
||||
|
||||
// Serial to write Protocol data to. Default: Serial
|
||||
#define HID_SERIAL Serial
|
||||
#define SERIAL_HID_BAUD 115200
|
||||
|
||||
// extra delay for raspberry. Only needed for Hoodloader and slow devices
|
||||
//#define HID_EXTRADELAY 20
|
||||
|
||||
const int pinLed = 13;
|
||||
const int pinButton = 8;
|
||||
|
||||
void setup() {
|
||||
pinMode(pinLed, OUTPUT);
|
||||
pinMode(pinButton, INPUT_PULLUP);
|
||||
|
||||
// Starts Serial at baud 115200 otherwise HID wont work with HoodLoader1.
|
||||
// This is not needed for Leonado/(Pro)Micro/16u2(HoodLoader2)
|
||||
Serial.begin(SERIAL_HID_BAUD);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
Keyboard.begin();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (!digitalRead(pinButton)) {
|
||||
digitalWrite(pinLed, HIGH);
|
||||
|
||||
// Same use as the official library, pretty much self explaining
|
||||
Keyboard.println("This message was sent with my Arduino.");
|
||||
Serial.println("Serial port is still working and not glitching out");
|
||||
|
||||
// simple debounce
|
||||
delay(300);
|
||||
digitalWrite(pinLed, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// HoodLoader1 compatible NHP sending API
|
||||
//================================================================================
|
||||
|
||||
// Start Mask
|
||||
#define NHP_MASK_START 0xC0 //B11|000000 the two MSB bits
|
||||
#define NHP_MASK_LEAD 0xC0 //B11|000000
|
||||
#define NHP_MASK_DATA 0x00 //B0|0000000 only the first MSB is important
|
||||
#define NHP_MASK_END 0x80 //B10|000000
|
||||
|
||||
// Content Mask
|
||||
#define NHP_MASK_LENGTH 0x38 //B00|111|000
|
||||
#define NHP_MASK_COMMAND 0x0F //B0000|1111
|
||||
#define NHP_MASK_DATA_7BIT 0x7F //B0|1111111
|
||||
#define NHP_MASK_DATA_4BIT 0x0F //B0000|1111
|
||||
#define NHP_MASK_DATA_3BIT 0x07 //B00000|111
|
||||
#define NHP_MASK_ADDRESS 0x3F //B00|111111
|
||||
|
||||
// Reserved Addresses
|
||||
#define NHP_ADDRESS_CONTROL 0x01
|
||||
|
||||
// Reserved Usages
|
||||
#define NHP_USAGE_ARDUINOHID 0x01
|
||||
|
||||
// overwrites the HID_SendReport function which is empty/not used on a 328/2560
|
||||
void HID_SendReport(uint8_t id, const void* data, int len)
|
||||
{
|
||||
// write the Report via Protocol and checksum. 16bit for each sending
|
||||
// send control address
|
||||
NHPwriteChecksum(NHP_ADDRESS_CONTROL, (NHP_USAGE_ARDUINOHID << 8) | id);
|
||||
const uint8_t* report = (const uint8_t*)data;
|
||||
for (int i = 0; i < len; i++) {
|
||||
uint8_t data0 = report[i++];
|
||||
uint8_t data1 = 0;
|
||||
if (i != len)
|
||||
data1 = report[i];
|
||||
// valid HID reports start at Address 2
|
||||
NHPwriteChecksum(2 + i / 2, (data1 << 8) | data0);
|
||||
}
|
||||
#ifdef HID_EXTRADELAY
|
||||
delay(HID_EXTRADELAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
// simple copy/modification of the NicoHoodProtocol writechecksum function
|
||||
void NHPwriteChecksum(uint8_t address, uint16_t indata) {
|
||||
// writes two bytes with its inverse
|
||||
uint32_t temp = ~indata;
|
||||
uint32_t data = (temp << 16) | indata;
|
||||
|
||||
// buffer for write operation
|
||||
uint8_t writebuffer[6];
|
||||
|
||||
// start with the maximum size of blocks
|
||||
uint8_t blocks = 7;
|
||||
|
||||
// check for the first 7 bit block that doesnt fit into the first 3 bits
|
||||
while (blocks > 2) {
|
||||
uint8_t nextvalue = (data >> (7 * (blocks - 3)));
|
||||
|
||||
if (nextvalue > NHP_MASK_DATA_3BIT) {
|
||||
// special case for the MSB
|
||||
if (blocks == 7) {
|
||||
writebuffer[0] = nextvalue;
|
||||
blocks--;
|
||||
}
|
||||
// this block is too big, write this into the next data block
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// write the possible first 3 bits and check again after if zero
|
||||
writebuffer[0] = nextvalue;
|
||||
blocks--;
|
||||
// we have our first bits, stop (nonzero)
|
||||
if (nextvalue)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write the rest of the data bits
|
||||
uint8_t datablocks = blocks - 2;
|
||||
while (datablocks > 0) {
|
||||
writebuffer[datablocks] = data & NHP_MASK_DATA_7BIT;
|
||||
data >>= 7;
|
||||
datablocks--;
|
||||
}
|
||||
|
||||
// write lead + length mask
|
||||
writebuffer[0] |= NHP_MASK_LEAD | (blocks << 3);
|
||||
|
||||
// write end mask
|
||||
writebuffer[blocks - 1] = NHP_MASK_END | ((address - 1) & NHP_MASK_ADDRESS);
|
||||
|
||||
// write the buffer
|
||||
HID_SERIAL.write(writebuffer, blocks);
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
HoodLoader2 NoUSB Blink example
|
||||
|
||||
This sketch demonstrates how to use HoodLoader2 without USB Core.
|
||||
This might be useful to keep ram/flash usage at a very low level.
|
||||
Select Tools->USB Core->No USB functions to get rid of the USB Core.
|
||||
|
||||
Blinks Leds and shows what workaround is needed to get the timing correct.
|
||||
You can still use the normal digitalWrite(LED_BUILTIN_TX, LOW); for updating Leds.
|
||||
Keep in mind that the logic is inverted then! LOW=HIGH and vice versa.
|
||||
*/
|
||||
|
||||
#ifndef USBCON
|
||||
// workaround for undefined USBCON has to be placed in every sketch
|
||||
// otherwise the timings wont work correctly
|
||||
ISR(USB_GEN_vect)
|
||||
{
|
||||
UDINT = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
TX_RX_LED_INIT;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
TXLED0;
|
||||
delay(100);
|
||||
TXLED1;
|
||||
delay(100);
|
||||
RXLED0;
|
||||
delay(100);
|
||||
RXLED1;
|
||||
delay(100);
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
PWM Fade
|
||||
|
||||
This example shows how to fade an LED on pin 7
|
||||
using the analogWrite() function.
|
||||
|
||||
Basically it is a demonstartion that PWM on pin 7 works fine.
|
||||
You can also deactivate the USB Core for this example, but then you'd
|
||||
need the workaround. See the other example for this.
|
||||
*/
|
||||
|
||||
int led = 7; // the pin that the LED is attached to
|
||||
int brightness = 0; // how bright the LED is
|
||||
int fadeAmount = 5; // how many points to fade the LED by
|
||||
|
||||
// the setup routine runs once when you press reset:
|
||||
void setup() {
|
||||
// declare pin 9 to be an output:
|
||||
pinMode(led, OUTPUT);
|
||||
}
|
||||
|
||||
// the loop routine runs over and over again forever:
|
||||
void loop() {
|
||||
// set the brightness of pin 9:
|
||||
analogWrite(led, brightness);
|
||||
|
||||
// change the brightness for next time through the loop:
|
||||
brightness = brightness + fadeAmount;
|
||||
|
||||
// reverse the direction of the fading at the ends of the fade:
|
||||
if (brightness == 0 || brightness == 255) {
|
||||
fadeAmount = -fadeAmount ;
|
||||
}
|
||||
// wait for 30 milliseconds to see the dimming effect
|
||||
delay(30);
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
HoodLoader2 SerialKeyboard example
|
||||
|
||||
This sketch should demonstrate how to program a basic sketch with HoodLoader2.
|
||||
It was used to demonstrate that Serial and HID is working properly.
|
||||
The the other examples on how to use the other APIs, it works the same.
|
||||
|
||||
Use the F() macro to save strings in PROGMEM to keep ram usage low.
|
||||
The 16u2 has very low RAM, so don't try to use that much ram.
|
||||
|
||||
Open the Serial port, type in anything and see that Serial and Keyboard is working.
|
||||
See official documentation for more infos.
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
// start + wait for serial debug in/output
|
||||
while (!Serial);
|
||||
Serial.begin(115200);
|
||||
Serial.println(F("Startup"));
|
||||
|
||||
// Sends a clean report to the host. This is important because
|
||||
// the 16u2 of the Uno/Mega is not turned off while programming
|
||||
// so you want to start with a clean report to avoid strange bugs after reset.
|
||||
Keyboard.begin();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (Serial.available()) {
|
||||
// discard all Serial bytes to avoid multiple sendings
|
||||
unsigned long currentMillis = millis();
|
||||
while (millis() - currentMillis < 100) {
|
||||
if (Serial.available())
|
||||
Serial.write(Serial.read());
|
||||
}
|
||||
|
||||
// print an information back to the serial port
|
||||
Serial.println();
|
||||
Serial.println(F("Serial port working. Printing Text in 3 seconds."));
|
||||
|
||||
// wait 3 seconds and discard all new in bytes to not crash the Arduino
|
||||
currentMillis = millis();
|
||||
while (millis() - currentMillis < 3000) {
|
||||
if (Serial.available())
|
||||
Serial.write(Serial.read());
|
||||
}
|
||||
|
||||
// same use as the official library, pretty much self explaining
|
||||
Keyboard.print(F("This message was sent with my Arduino."));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
HoodLoader2 USB-Serial
|
||||
|
||||
Transferes from USB to HW Serial and vice versa.
|
||||
It also resets the main MCU on a DTR rise.
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
// set main MCU by default active
|
||||
pinMode(MAIN_MCU_RESET_PIN, OUTPUT);
|
||||
digitalWrite(MAIN_MCU_RESET_PIN, HIGH);
|
||||
|
||||
// Start USB and HW Serial
|
||||
Serial.begin(115200);
|
||||
Serial1.begin(115200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// USB -> Serial
|
||||
for (int i = 0; i < USB_EP_SIZE; i++) {
|
||||
// read maximum one EP_SIZE to not block
|
||||
if (Serial.available())
|
||||
Serial1.write(Serial.read());
|
||||
else break;
|
||||
}
|
||||
|
||||
// Serial -> USB
|
||||
if (Serial1.available()) {
|
||||
Serial.flush();
|
||||
// send maximum one EP_SIZE to give the usb some time to flush the buffer
|
||||
uint8_t buff[USB_EP_SIZE-1];
|
||||
int i = 0;
|
||||
for (i = 0; i < USB_EP_SIZE-1; i++) {
|
||||
if (Serial1.available())
|
||||
buff[i] = Serial1.read();
|
||||
else break;
|
||||
}
|
||||
Serial.write(buff, i);
|
||||
}
|
||||
|
||||
// reset the main mcu if DTR goes HIGH
|
||||
static bool lastDTR = 0;
|
||||
bool newDTR = (Serial.lineState()&CDC_CONTROL_LINE_OUT_DTR) ? 1 : 0;
|
||||
if (lastDTR ^ newDTR)
|
||||
digitalWrite(MAIN_MCU_RESET_PIN, lastDTR);
|
||||
lastDTR = newDTR;
|
||||
}
|
||||
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014 NicoHood
|
||||
See the readme for credit to other people.
|
||||
|
||||
Gamepad example project
|
||||
|
||||
Press physical buttons to press USB Gamepad buttons.
|
||||
This can be used for a simple SNES Controller.
|
||||
*/
|
||||
|
||||
// pin mappings
|
||||
const int pinButton1 = 2;
|
||||
const int pinButton2 = 3;
|
||||
const int pinButton3 = 4;
|
||||
const int pinButton4 = 5;
|
||||
const int pinButton5 = 6;
|
||||
const int pinButton6 = 7;
|
||||
const int pinButton7 = 8;
|
||||
const int pinButton8 = 9;
|
||||
const int pinButton9 = 10;
|
||||
const int pinButton10 = 18;
|
||||
const int pinButton11 = 19;
|
||||
const int pinButton12 = 20;
|
||||
|
||||
void setup() {
|
||||
// pinsetup
|
||||
pinMode(pinButton1, INPUT_PULLUP);
|
||||
pinMode(pinButton2, INPUT_PULLUP);
|
||||
pinMode(pinButton3, INPUT_PULLUP);
|
||||
pinMode(pinButton4, INPUT_PULLUP);
|
||||
pinMode(pinButton5, INPUT_PULLUP);
|
||||
pinMode(pinButton6, INPUT_PULLUP);
|
||||
pinMode(pinButton7, INPUT_PULLUP);
|
||||
pinMode(pinButton8, INPUT_PULLUP);
|
||||
pinMode(pinButton9, INPUT_PULLUP);
|
||||
pinMode(pinButton10, INPUT_PULLUP);
|
||||
pinMode(pinButton11, INPUT_PULLUP);
|
||||
pinMode(pinButton12, INPUT_PULLUP);
|
||||
|
||||
// Sends a clean report to the host. This is important on any Arduino type.
|
||||
// Make sure all desired USB functions are activated in USBAPI.h!
|
||||
Gamepad.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check each button and press Gamepad if needed
|
||||
if (!digitalRead(pinButton1))
|
||||
Gamepad.press(1);
|
||||
else
|
||||
Gamepad.release(1);
|
||||
|
||||
if (!digitalRead(pinButton2))
|
||||
Gamepad.press(2);
|
||||
else
|
||||
Gamepad.release(2);
|
||||
|
||||
if (!digitalRead(pinButton3))
|
||||
Gamepad.press(3);
|
||||
else
|
||||
Gamepad.release(3);
|
||||
|
||||
if (!digitalRead(pinButton4))
|
||||
Gamepad.press(4);
|
||||
else
|
||||
Gamepad.release(4);
|
||||
|
||||
if (!digitalRead(pinButton5))
|
||||
Gamepad.press(5);
|
||||
else
|
||||
Gamepad.release(5);
|
||||
|
||||
if (!digitalRead(pinButton6))
|
||||
Gamepad.press(6);
|
||||
else
|
||||
Gamepad.release(6);
|
||||
|
||||
if (!digitalRead(pinButton7))
|
||||
Gamepad.press(7);
|
||||
else
|
||||
Gamepad.release(7);
|
||||
|
||||
if (!digitalRead(pinButton8))
|
||||
Gamepad.press(8);
|
||||
else
|
||||
Gamepad.release(8);
|
||||
|
||||
if (!digitalRead(pinButton9))
|
||||
Gamepad.press(9);
|
||||
else
|
||||
Gamepad.release(9);
|
||||
|
||||
if (!digitalRead(pinButton10))
|
||||
Gamepad.press(10);
|
||||
else
|
||||
Gamepad.release(10);
|
||||
|
||||
if (!digitalRead(pinButton11))
|
||||
Gamepad.press(11);
|
||||
else
|
||||
Gamepad.release(11);
|
||||
|
||||
if (!digitalRead(pinButton12))
|
||||
Gamepad.press(12);
|
||||
else
|
||||
Gamepad.release(12);
|
||||
|
||||
// write the information to the host now!
|
||||
Gamepad.write();
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Examples
|
||||
========
|
||||
|
||||
Just try these examples once the HID Source is installed. Its pretty much self explaining.
|
||||
BIN
header.jpg
BIN
header.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 147 KiB |
201
keywords.txt
201
keywords.txt
|
|
@ -1,201 +0,0 @@
|
|||
#######################################
|
||||
# Syntax Coloring Map For HID
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
end KEYWORD2
|
||||
click KEYWORD2
|
||||
move KEYWORD2
|
||||
write KEYWORD2
|
||||
press KEYWORD2
|
||||
isPressed KEYWORD2
|
||||
releaseAll KEYWORD2
|
||||
buttons KEYWORD2
|
||||
xAxis KEYWORD2
|
||||
yAxis KEYWORD2
|
||||
zAxis KEYWORD2
|
||||
rxAxis KEYWORD2
|
||||
ryAxis KEYWORD2
|
||||
rzAxis KEYWORD2
|
||||
dPad1 KEYWORD2
|
||||
dPad2 KEYWORD2
|
||||
HID_SendReport KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Classes (KEYWORD3)
|
||||
#######################################
|
||||
|
||||
Mouse KEYWORD3
|
||||
Keyboard KEYWORD3
|
||||
RawHID KEYWORD3
|
||||
Media KEYWORD3
|
||||
System KEYWORD3
|
||||
Gamepad KEYWORD3
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
#CDC
|
||||
CDC_CONTROL_LINE_OUT_DTR LITERAL1
|
||||
CDC_CONTROL_LINE_OUT_TRS LITERAL1
|
||||
|
||||
#Mouse
|
||||
|
||||
MOUSE_LEFT LITERAL1
|
||||
MOUSE_RIGHT LITERAL1
|
||||
MOUSE_MIDDLE LITERAL1
|
||||
MOUSE_PREV LITERAL1
|
||||
MOUSE_NEXT LITERAL1
|
||||
|
||||
#Keyboard
|
||||
|
||||
LED_NUM_LOCK LITERAL1
|
||||
LED_CAPS_LOCK LITERAL1
|
||||
LED_SCROLL_LOCK LITERAL1
|
||||
|
||||
KEY_LEFT_CTRL LITERAL1
|
||||
KEY_LEFT_SHIFT LITERAL1
|
||||
KEY_LEFT_ALT LITERAL1
|
||||
KEY_LEFT_GUI LITERAL1
|
||||
KEY_LEFT_WINDOWS LITERAL1
|
||||
KEY_RIGHT_CTRL LITERAL1
|
||||
KEY_RIGHT_SHIFT LITERAL1
|
||||
KEY_RIGHT_ALT LITERAL1
|
||||
KEY_RIGHT_GUI LITERAL1
|
||||
KEY_RIGHT_WINDOWS LITERAL1
|
||||
|
||||
KEY_UP_ARROW LITERAL1
|
||||
KEY_DOWN_ARROW LITERAL1
|
||||
KEY_LEFT_ARROW LITERAL1
|
||||
KEY_RIGHT_ARROW LITERAL1
|
||||
KEY_BACKSPACE LITERAL1
|
||||
KEY_TAB LITERAL1
|
||||
KEY_RETURN LITERAL1
|
||||
KEY_ENTER LITERAL1
|
||||
KEY_ESC LITERAL1
|
||||
KEY_INSERT LITERAL1
|
||||
KEY_DELETE LITERAL1
|
||||
KEY_PAGE_UP LITERAL1
|
||||
KEY_PAGE_DOWN LITERAL1
|
||||
KEY_HOME LITERAL1
|
||||
KEY_END LITERAL1
|
||||
KEY_CAPS_LOCK LITERAL1
|
||||
KEY_F1 LITERAL1
|
||||
KEY_F2 LITERAL1
|
||||
KEY_F3 LITERAL1
|
||||
KEY_F4 LITERAL1
|
||||
KEY_F5 LITERAL1
|
||||
KEY_F6 LITERAL1
|
||||
KEY_F7 LITERAL1
|
||||
KEY_F8 LITERAL1
|
||||
KEY_F9 LITERAL1
|
||||
KEY_F10 LITERAL1
|
||||
KEY_F11 LITERAL1
|
||||
KEY_F12 LITERAL1
|
||||
|
||||
KEY_PRINT LITERAL1
|
||||
KEY_NUM_LOCK LITERAL1
|
||||
KEY_SCROLL_LOCK LITERAL1
|
||||
KEY_PAUSE LITERAL1
|
||||
|
||||
#Raw Keyboard definitions
|
||||
|
||||
RAW_KEYBOARD_LEFT_CTRL LITERAL1
|
||||
RAW_KEYBOARD_LEFT_SHIFT LITERAL1
|
||||
RAW_KEYBOARD_LEFT_ALT LITERAL1
|
||||
RAW_KEYBOARD_LEFT_GUI LITERAL1
|
||||
RAW_KEYBOARD_RIGHT_CTRL LITERAL1
|
||||
RAW_KEYBOARD_RIGHT_SHIFT LITERAL1
|
||||
RAW_KEYBOARD_RIGHT_ALT LITERAL1
|
||||
RAW_KEYBOARD_RIGHT_GUI LITERAL1
|
||||
|
||||
RAW_KEYBOARD_KEY LITERAL1
|
||||
|
||||
RAW_KEYBOARD_UP_ARROW LITERAL1
|
||||
RAW_KEYBOARD_DOWN_ARROW LITERAL1
|
||||
RAW_KEYBOARD_LEFT_ARROW LITERAL1
|
||||
RAW_KEYBOARD_RIGHT_ARROW LITERAL1
|
||||
RAW_KEYBOARD_SPACEBAR LITERAL1
|
||||
RAW_KEYBOARD_BACKSPACE LITERAL1
|
||||
RAW_KEYBOARD_TAB LITERAL1
|
||||
RAW_KEYBOARD_RETURN LITERAL1
|
||||
RAW_KEYBOARD_ESC LITERAL1
|
||||
RAW_KEYBOARD_INSERT LITERAL1
|
||||
RAW_KEYBOARD_DELETE LITERAL1
|
||||
RAW_KEYBOARD_PAGE_UP LITERAL1
|
||||
RAW_KEYBOARD_PAGE_DOWN LITERAL1
|
||||
RAW_KEYBOARD_HOME LITERAL1
|
||||
RAW_KEYBOARD_END LITERAL1
|
||||
RAW_KEYBOARD_CAPS_LOCK LITERAL1
|
||||
RAW_KEYBOARD_F1 LITERAL1
|
||||
RAW_KEYBOARD_F2 LITERAL1
|
||||
RAW_KEYBOARD_F3 LITERAL1
|
||||
RAW_KEYBOARD_F4 LITERAL1
|
||||
RAW_KEYBOARD_F5 LITERAL1
|
||||
RAW_KEYBOARD_F6 LITERAL1
|
||||
RAW_KEYBOARD_F7 LITERAL1
|
||||
RAW_KEYBOARD_F8 LITERAL1
|
||||
RAW_KEYBOARD_F9 LITERAL1
|
||||
RAW_KEYBOARD_F10 LITERAL1
|
||||
RAW_KEYBOARD_F11 LITERAL1
|
||||
RAW_KEYBOARD_F12 LITERAL1
|
||||
RAW_KEYBOARD_PRINT LITERAL1
|
||||
RAW_KEYBOARD_SCROLL_LOCK LITERAL1
|
||||
RAW_KEYBOARD_PAUSE LITERAL1
|
||||
|
||||
#RawHID
|
||||
RAWHID_RX_SIZE LITERAL1
|
||||
RAWHID_TX_SIZE LITERAL1
|
||||
|
||||
#Media
|
||||
|
||||
MEDIA_FAST_FORWARD LITERAL1
|
||||
MEDIA_REWIND LITERAL1
|
||||
MEDIA_NEXT LITERAL1
|
||||
MEDIA_PREVIOUS LITERAL1
|
||||
MEDIA_STOP LITERAL1
|
||||
MEDIA_PLAY_PAUSE LITERAL1
|
||||
|
||||
MEDIA_VOLUME_MUTE LITERAL1
|
||||
MEDIA_VOLUME_UP LITERAL1
|
||||
MEDIA_VOLUME_DOWN LITERAL1
|
||||
|
||||
MEDIA_EMAIL_READER LITERAL1
|
||||
MEDIA_CALCULATOR LITERAL1
|
||||
MEDIA_EXPLORER LITERAL1
|
||||
|
||||
MEDIA_BROWSER_HOME LITERAL1
|
||||
MEDIA_BROWSER_BACK LITERAL1
|
||||
MEDIA_BROWSER_FORWARD LITERAL1
|
||||
MEDIA_BROWSER_REFRESH LITERAL1
|
||||
MEDIA_BROWSER_BOOKMARKS LITERAL1
|
||||
|
||||
#System
|
||||
|
||||
SYSTEM_POWER_DOWN LITERAL1
|
||||
SYSTEM_SLEEP LITERAL1
|
||||
SYSTEM_WAKE_UP LITERAL1
|
||||
|
||||
#Gamepad
|
||||
GAMEPAD_DPAD_CENTERED LITERAL1
|
||||
GAMEPAD_DPAD_UP LITERAL1
|
||||
GAMEPAD_DPAD_UP_RIGHT LITERAL1
|
||||
GAMEPAD_DPAD_RIGHT LITERAL1
|
||||
GAMEPAD_DPAD_DOWN_RIGHT LITERAL1
|
||||
GAMEPAD_DPAD_DOWN LITERAL1
|
||||
GAMEPAD_DPAD_DOWN_LEFT LITERAL1
|
||||
GAMEPAD_DPAD_LEFT LITERAL1
|
||||
GAMEPAD_DPAD_UP_LEFT LITERAL1
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
wiring_private.h - Internal header file.
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
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.
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.h 239 2007-01-12 17:58:39Z mellis $
|
||||
*/
|
||||
|
||||
#ifndef WiringPrivate_h
|
||||
#define WiringPrivate_h
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
#define EXTERNAL_INT_0 0
|
||||
#define EXTERNAL_INT_1 1
|
||||
#define EXTERNAL_INT_2 2
|
||||
#define EXTERNAL_INT_3 3
|
||||
#define EXTERNAL_INT_4 4
|
||||
#define EXTERNAL_INT_5 5
|
||||
#define EXTERNAL_INT_6 6
|
||||
#define EXTERNAL_INT_7 7
|
||||
|
||||
// edit by NicoHood
|
||||
#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) \
|
||||
|| defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__)
|
||||
#define EXTERNAL_NUM_INTERRUPTS 8
|
||||
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
|
||||
#define EXTERNAL_NUM_INTERRUPTS 3
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define EXTERNAL_NUM_INTERRUPTS 5
|
||||
#else
|
||||
#define EXTERNAL_NUM_INTERRUPTS 2
|
||||
#endif
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue