Separated CDC, HID and its APIs.
Also added Absolute Mouse and changed the structure. Added a better readme for changelog and todo list.
This commit is contained in:
parent
e120b47a49
commit
f7fe5f32aa
13 changed files with 1280 additions and 666 deletions
252
Arduino.h
Normal file
252
Arduino.h
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
Arduino.h - Main include file for the Arduino SDK
|
||||
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
void yield(void);
|
||||
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
|
||||
#define INPUT 0x0
|
||||
#define OUTPUT 0x1
|
||||
#define INPUT_PULLUP 0x2
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define HALF_PI 1.5707963267948966192313216916398
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105
|
||||
#define EULER 2.718281828459045235360287471352
|
||||
|
||||
#define SERIAL 0x0
|
||||
#define DISPLAY 0x1
|
||||
|
||||
#define LSBFIRST 0
|
||||
#define MSBFIRST 1
|
||||
|
||||
#define CHANGE 1
|
||||
#define FALLING 2
|
||||
#define RISING 3
|
||||
|
||||
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
#define DEFAULT 0
|
||||
#define EXTERNAL 1
|
||||
#define INTERNAL 2
|
||||
#else
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
|
||||
#define INTERNAL1V1 2
|
||||
#define INTERNAL2V56 3
|
||||
#else
|
||||
#define INTERNAL 3
|
||||
#endif
|
||||
#define DEFAULT 1
|
||||
#define EXTERNAL 0
|
||||
#endif
|
||||
|
||||
// undefine stdlib's abs if encountered
|
||||
#ifdef abs
|
||||
#undef abs
|
||||
#endif
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define abs(x) ((x)>0?(x):-(x))
|
||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||
#define sq(x) ((x)*(x))
|
||||
|
||||
#define interrupts() sei()
|
||||
#define noInterrupts() cli()
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
||||
|
||||
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
||||
#define highByte(w) ((uint8_t) ((w) >> 8))
|
||||
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||
|
||||
// avr-libc defines _NOP() since 1.6.2
|
||||
#ifndef _NOP
|
||||
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
|
||||
#endif
|
||||
|
||||
typedef unsigned int word;
|
||||
|
||||
#define bit(b) (1UL << (b))
|
||||
|
||||
typedef uint8_t boolean;
|
||||
typedef uint8_t byte;
|
||||
|
||||
void init(void);
|
||||
void initVariant(void);
|
||||
|
||||
int atexit(void (*func)()) __attribute__((weak));
|
||||
|
||||
void pinMode(uint8_t, uint8_t);
|
||||
void digitalWrite(uint8_t, uint8_t);
|
||||
int digitalRead(uint8_t);
|
||||
int analogRead(uint8_t);
|
||||
void analogReference(uint8_t mode);
|
||||
void analogWrite(uint8_t, int);
|
||||
|
||||
unsigned long millis(void);
|
||||
unsigned long micros(void);
|
||||
void delay(unsigned long);
|
||||
void delayMicroseconds(unsigned int us);
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||
|
||||
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
||||
|
||||
void attachInterrupt(uint8_t, void (*)(void), int mode);
|
||||
void detachInterrupt(uint8_t);
|
||||
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
|
||||
// Get the bit location within the hardware port of the given virtual pin.
|
||||
// This comes from the pins_*.c file for the active board configuration.
|
||||
|
||||
#define analogInPinToBit(P) (P)
|
||||
|
||||
// On the ATmega1280, the addresses of some of the port registers are
|
||||
// greater than 255, so we can't store them in uint8_t's.
|
||||
extern const uint16_t PROGMEM port_to_mode_PGM[];
|
||||
extern const uint16_t PROGMEM port_to_input_PGM[];
|
||||
extern const uint16_t PROGMEM port_to_output_PGM[];
|
||||
|
||||
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
|
||||
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
|
||||
|
||||
// Get the bit location within the hardware port of the given virtual pin.
|
||||
// This comes from the pins_*.c file for the active board configuration.
|
||||
//
|
||||
// These perform slightly better as macros compared to inline functions
|
||||
//
|
||||
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
||||
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
||||
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
||||
#define analogInPinToBit(P) (P)
|
||||
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
|
||||
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
|
||||
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
|
||||
|
||||
#define NOT_A_PIN 0
|
||||
#define NOT_A_PORT 0
|
||||
|
||||
#define NOT_AN_INTERRUPT -1
|
||||
|
||||
#ifdef ARDUINO_MAIN
|
||||
#define PA 1
|
||||
#define PB 2
|
||||
#define PC 3
|
||||
#define PD 4
|
||||
#define PE 5
|
||||
#define PF 6
|
||||
#define PG 7
|
||||
#define PH 8
|
||||
#define PJ 10
|
||||
#define PK 11
|
||||
#define PL 12
|
||||
#endif
|
||||
|
||||
#define NOT_ON_TIMER 0
|
||||
#define TIMER0A 1
|
||||
#define TIMER0B 2
|
||||
#define TIMER1A 3
|
||||
#define TIMER1B 4
|
||||
#define TIMER1C 5
|
||||
#define TIMER2 6
|
||||
#define TIMER2A 7
|
||||
#define TIMER2B 8
|
||||
|
||||
#define TIMER3A 9
|
||||
#define TIMER3B 10
|
||||
#define TIMER3C 11
|
||||
#define TIMER4A 12
|
||||
#define TIMER4B 13
|
||||
#define TIMER4C 14
|
||||
#define TIMER4D 15
|
||||
#define TIMER5A 16
|
||||
#define TIMER5B 17
|
||||
#define TIMER5C 18
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "USBAPI.h"
|
||||
#include "CDC.h"
|
||||
#include "HID.h"
|
||||
|
||||
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
|
||||
#error "Targets with both UART0 and CDC serial not supported"
|
||||
#endif
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
uint16_t makeWord(byte h, byte l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
|
||||
void noTone(uint8_t _pin);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
long random(long, long);
|
||||
void randomSeed(unsigned int);
|
||||
long map(long, long, long, long, long);
|
||||
|
||||
#endif
|
||||
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif
|
||||
2
CDC.cpp
2
CDC.cpp
|
|
@ -16,7 +16,7 @@
|
|||
** SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "USBAPI.h"
|
||||
#include "CDC.h"
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#if defined(USBCON)
|
||||
|
|
|
|||
77
CDC.h
Normal file
77
CDC.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
CDC.h
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __CDC__
|
||||
#define __CDC__
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#if defined(USBCON)
|
||||
|
||||
#include "USBDesc.h"
|
||||
#include "USBCore.h"
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Serial over CDC (Serial1 is the physical port)
|
||||
|
||||
struct ring_buffer;
|
||||
|
||||
#if (RAMEND < 1000)
|
||||
#define SERIAL_BUFFER_SIZE 16
|
||||
#else
|
||||
#define SERIAL_BUFFER_SIZE 64
|
||||
#endif
|
||||
|
||||
class Serial_ : public Stream
|
||||
{
|
||||
private:
|
||||
int peek_buffer;
|
||||
public:
|
||||
Serial_() { peek_buffer = -1; };
|
||||
void begin(unsigned long);
|
||||
void begin(unsigned long, uint8_t);
|
||||
void end(void);
|
||||
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t*, size_t);
|
||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
uint32_t baud(void);
|
||||
uint8_t stopbits(void);
|
||||
uint8_t paritytype(void);
|
||||
uint8_t numbits(void);
|
||||
bool dtr(void);
|
||||
bool rts(void);
|
||||
operator bool();
|
||||
|
||||
volatile uint8_t _rx_buffer_head;
|
||||
volatile uint8_t _rx_buffer_tail;
|
||||
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
|
||||
};
|
||||
extern Serial_ Serial;
|
||||
|
||||
#define HAVE_CDCSERIAL
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
|
||||
#endif
|
||||
483
HID.cpp
483
HID.cpp
|
|
@ -16,138 +16,32 @@
|
|||
** SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "USBAPI.h"
|
||||
#include "HID.h"
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
#if defined(USBCON)
|
||||
#ifdef HID_ENABLED
|
||||
|
||||
//#define RAWHID_ENABLED
|
||||
|
||||
// Singletons for mouse and keyboard
|
||||
|
||||
Mouse_ Mouse;
|
||||
Keyboard_ Keyboard;
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
|
||||
// HID report descriptor
|
||||
|
||||
#define LSB(_x) ((_x) & 0xFF)
|
||||
#define MSB(_x) ((_x) >> 8)
|
||||
|
||||
#define RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF
|
||||
#define RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF
|
||||
#define RAWHID_TX_SIZE (USB_EP_SIZE-1)
|
||||
#define RAWHID_RX_SIZE (USB_EP_SIZE-1)
|
||||
|
||||
#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)
|
||||
// by default use the standard HID APIs
|
||||
#ifndef EXTERN_HID_REPORT
|
||||
#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) */
|
||||
HID_REPORT_KEYBOARD_LEDS(HID_REPORTID_KEYBOARD),
|
||||
#else
|
||||
HID_REPORT_KEYBOARD_KEYS(HID_REPORTID_KEYBOARD),
|
||||
#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
|
||||
HID_REPORT_MOUSE(HID_REPORTID_MOUSE),
|
||||
HID_REPORT_MOUSE_ABSOLUTE(HID_REPORTID_MOUSE_ABSOLUTE),
|
||||
//HID_REPORT_RAWHID(HID_REPORTID_RAWHID),
|
||||
HID_REPORT_CONSUMERCONTROL(HID_REPORTID_CONSUMERCONTROL),
|
||||
HID_REPORT_SYSTEMCONTROL(HID_REPORTID_SYSTEMCONTROL),
|
||||
#else
|
||||
EXTERN_HID_REPORT
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -167,8 +61,6 @@ const HIDDescriptor _hidInterface =
|
|||
u8 _hid_protocol = 1;
|
||||
u8 _hid_idle = 1;
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
int WEAK HID_GetInterface(u8* interfaceNum)
|
||||
{
|
||||
interfaceNum[0] += 1; // uses 1
|
||||
|
|
@ -217,354 +109,39 @@ bool WEAK HID_Setup(Setup& setup)
|
|||
_hid_idle = setup.wValueL;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
#if defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
if (HID_SET_REPORT == r)
|
||||
{
|
||||
//TODO check correct report ID (not needed for now, no other device has an out report)
|
||||
// maybe make this a general weak implementation to use it for RAW HID later?
|
||||
if (setup.wLength == 2)
|
||||
{
|
||||
// write led out report data
|
||||
uint8_t data[2];
|
||||
if (2 == USB_RecvControl(data, 2))
|
||||
hid_keyboard_leds = data[1];
|
||||
HID_SetKeyboardLedReport(data[1]);
|
||||
}
|
||||
// else TODO check for other devices like RAW HID, not needed for now
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Mouse
|
||||
|
||||
#ifdef HID_MOUSE_ENABLED
|
||||
|
||||
Mouse_::Mouse_(void) : _buttons(0)
|
||||
{
|
||||
#if defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
void WEAK HID_SetKeyboardLedReport(uint8_t leds){
|
||||
// weak function implemented by the Keyboard API
|
||||
// to not always create the Keyboard object, if it isn't used
|
||||
}
|
||||
|
||||
void Mouse_::begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::click(uint8_t b)
|
||||
{
|
||||
_buttons = b;
|
||||
move(0, 0, 0);
|
||||
_buttons = 0;
|
||||
move(0, 0, 0);
|
||||
}
|
||||
|
||||
void Mouse_::move(signed char x, signed char y, signed char wheel)
|
||||
{
|
||||
u8 m[4];
|
||||
m[0] = _buttons;
|
||||
m[1] = x;
|
||||
m[2] = y;
|
||||
m[3] = wheel;
|
||||
HID_SendReport(1, m, 4);
|
||||
}
|
||||
|
||||
void Mouse_::buttons(uint8_t b)
|
||||
{
|
||||
if (b != _buttons)
|
||||
{
|
||||
_buttons = b;
|
||||
move(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse_::press(uint8_t b)
|
||||
{
|
||||
buttons(_buttons | b);
|
||||
}
|
||||
|
||||
void Mouse_::release(uint8_t b)
|
||||
{
|
||||
buttons(_buttons & ~b);
|
||||
}
|
||||
|
||||
bool Mouse_::isPressed(uint8_t b)
|
||||
{
|
||||
if ((b & _buttons) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
|
||||
#ifdef HID_KEYBOARD_ENABLED
|
||||
|
||||
Keyboard_::Keyboard_(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::sendReport(KeyReport* keys)
|
||||
{
|
||||
HID_SendReport(2, keys, sizeof(KeyReport));
|
||||
}
|
||||
|
||||
extern
|
||||
const uint8_t _asciimap[128] PROGMEM;
|
||||
|
||||
#define SHIFT 0x80
|
||||
const uint8_t _asciimap[128] =
|
||||
{
|
||||
0x00, // NUL
|
||||
0x00, // SOH
|
||||
0x00, // STX
|
||||
0x00, // ETX
|
||||
0x00, // EOT
|
||||
0x00, // ENQ
|
||||
0x00, // ACK
|
||||
0x00, // BEL
|
||||
0x2a, // BS Backspace
|
||||
0x2b, // TAB Tab
|
||||
0x28, // LF Enter
|
||||
0x00, // VT
|
||||
0x00, // FF
|
||||
0x00, // CR
|
||||
0x00, // SO
|
||||
0x00, // SI
|
||||
0x00, // DEL
|
||||
0x00, // DC1
|
||||
0x00, // DC2
|
||||
0x00, // DC3
|
||||
0x00, // DC4
|
||||
0x00, // NAK
|
||||
0x00, // SYN
|
||||
0x00, // ETB
|
||||
0x00, // CAN
|
||||
0x00, // EM
|
||||
0x00, // SUB
|
||||
0x00, // ESC
|
||||
0x00, // FS
|
||||
0x00, // GS
|
||||
0x00, // RS
|
||||
0x00, // US
|
||||
|
||||
0x2c, // ' '
|
||||
0x1e | SHIFT, // !
|
||||
0x34 | SHIFT, // "
|
||||
0x20 | SHIFT, // #
|
||||
0x21 | SHIFT, // $
|
||||
0x22 | SHIFT, // %
|
||||
0x24 | SHIFT, // &
|
||||
0x34, // '
|
||||
0x26 | SHIFT, // (
|
||||
0x27 | SHIFT, // )
|
||||
0x25 | SHIFT, // *
|
||||
0x2e | SHIFT, // +
|
||||
0x36, // ,
|
||||
0x2d, // -
|
||||
0x37, // .
|
||||
0x38, // /
|
||||
0x27, // 0
|
||||
0x1e, // 1
|
||||
0x1f, // 2
|
||||
0x20, // 3
|
||||
0x21, // 4
|
||||
0x22, // 5
|
||||
0x23, // 6
|
||||
0x24, // 7
|
||||
0x25, // 8
|
||||
0x26, // 9
|
||||
0x33 | SHIFT, // :
|
||||
0x33, // ;
|
||||
0x36 | SHIFT, // <
|
||||
0x2e, // =
|
||||
0x37 | SHIFT, // >
|
||||
0x38 | SHIFT, // ?
|
||||
0x1f | SHIFT, // @
|
||||
0x04 | SHIFT, // A
|
||||
0x05 | SHIFT, // B
|
||||
0x06 | SHIFT, // C
|
||||
0x07 | SHIFT, // D
|
||||
0x08 | SHIFT, // E
|
||||
0x09 | SHIFT, // F
|
||||
0x0a | SHIFT, // G
|
||||
0x0b | SHIFT, // H
|
||||
0x0c | SHIFT, // I
|
||||
0x0d | SHIFT, // J
|
||||
0x0e | SHIFT, // K
|
||||
0x0f | SHIFT, // L
|
||||
0x10 | SHIFT, // M
|
||||
0x11 | SHIFT, // N
|
||||
0x12 | SHIFT, // O
|
||||
0x13 | SHIFT, // P
|
||||
0x14 | SHIFT, // Q
|
||||
0x15 | SHIFT, // R
|
||||
0x16 | SHIFT, // S
|
||||
0x17 | SHIFT, // T
|
||||
0x18 | SHIFT, // U
|
||||
0x19 | SHIFT, // V
|
||||
0x1a | SHIFT, // W
|
||||
0x1b | SHIFT, // X
|
||||
0x1c | SHIFT, // Y
|
||||
0x1d | SHIFT, // Z
|
||||
0x2f, // [
|
||||
0x31, // bslash
|
||||
0x30, // ]
|
||||
0x23 | SHIFT, // ^
|
||||
0x2d | SHIFT, // _
|
||||
0x35, // `
|
||||
0x04, // a
|
||||
0x05, // b
|
||||
0x06, // c
|
||||
0x07, // d
|
||||
0x08, // e
|
||||
0x09, // f
|
||||
0x0a, // g
|
||||
0x0b, // h
|
||||
0x0c, // i
|
||||
0x0d, // j
|
||||
0x0e, // k
|
||||
0x0f, // l
|
||||
0x10, // m
|
||||
0x11, // n
|
||||
0x12, // o
|
||||
0x13, // p
|
||||
0x14, // q
|
||||
0x15, // r
|
||||
0x16, // s
|
||||
0x17, // t
|
||||
0x18, // u
|
||||
0x19, // v
|
||||
0x1a, // w
|
||||
0x1b, // x
|
||||
0x1c, // y
|
||||
0x1d, // z
|
||||
0x2f | SHIFT, //
|
||||
0x31 | SHIFT, // |
|
||||
0x30 | SHIFT, // }
|
||||
0x35 | SHIFT, // ~
|
||||
0 // DEL
|
||||
};
|
||||
|
||||
uint8_t USBPutChar(uint8_t c);
|
||||
|
||||
// press() adds the specified key (printing, non-printing, or modifier)
|
||||
// to the persistent key report and sends the report. Because of the way
|
||||
// USB HID works, the host acts like the key remains pressed until we
|
||||
// call release(), releaseAll(), or otherwise clear the report and resend.
|
||||
size_t Keyboard_::press(uint8_t k)
|
||||
{
|
||||
uint8_t i;
|
||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
||||
k = k - 136;
|
||||
}
|
||||
else if (k >= 128) { // it's a modifier key
|
||||
_keyReport.modifiers |= (1 << (k - 128));
|
||||
k = 0;
|
||||
}
|
||||
else { // it's a printing key
|
||||
k = pgm_read_byte(_asciimap + k);
|
||||
if (!k) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
||||
_keyReport.modifiers |= 0x02; // the left shift modifier
|
||||
k &= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
// Add k to the key report only if it's not already present
|
||||
// and if there is an empty slot.
|
||||
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
||||
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
||||
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (_keyReport.keys[i] == 0x00) {
|
||||
_keyReport.keys[i] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 6) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sendReport(&_keyReport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// release() takes the specified key out of the persistent key report and
|
||||
// sends the report. This tells the OS the key is no longer pressed and that
|
||||
// it shouldn't be repeated any more.
|
||||
size_t Keyboard_::release(uint8_t k)
|
||||
{
|
||||
uint8_t i;
|
||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
||||
k = k - 136;
|
||||
}
|
||||
else if (k >= 128) { // it's a modifier key
|
||||
_keyReport.modifiers &= ~(1 << (k - 128));
|
||||
k = 0;
|
||||
}
|
||||
else { // it's a printing key
|
||||
k = pgm_read_byte(_asciimap + k);
|
||||
if (!k) {
|
||||
return 0;
|
||||
}
|
||||
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
||||
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
||||
k &= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
// Test the key report to see if k is present. Clear it if it exists.
|
||||
// Check all positions in case the key is present more than once (which it shouldn't be)
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (0 != k && _keyReport.keys[i] == k) {
|
||||
_keyReport.keys[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
sendReport(&_keyReport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Keyboard_::releaseAll(void)
|
||||
{
|
||||
_keyReport.keys[0] = 0;
|
||||
_keyReport.keys[1] = 0;
|
||||
_keyReport.keys[2] = 0;
|
||||
_keyReport.keys[3] = 0;
|
||||
_keyReport.keys[4] = 0;
|
||||
_keyReport.keys[5] = 0;
|
||||
_keyReport.modifiers = 0;
|
||||
sendReport(&_keyReport);
|
||||
}
|
||||
|
||||
size_t Keyboard_::write(uint8_t c)
|
||||
{
|
||||
uint8_t p = press(c); // Keydown
|
||||
release(c); // Keyup
|
||||
return p; // just return the result of press() since release() almost always returns 1
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#else /* if defined(USBCON) */
|
||||
|
||||
void WEAK HID_SendReport(u8 id, const void* data, int len)
|
||||
{
|
||||
// empty to let the user use the HIDAPI for different use
|
||||
}
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
|
|
|
|||
287
HID.h
Normal file
287
HID.h
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
HID.h
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __HID__
|
||||
#define __HID__
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
// enable Led out report by default
|
||||
#ifndef EXTERN_HID_REPORT
|
||||
#define HID_KEYBOARD_LEDS_ENABLED
|
||||
#endif
|
||||
|
||||
// HID report IDs
|
||||
// note by NicoHood: I would not change the current IDs, since it can confuse the OS
|
||||
// I had several problems if i change the report id and its use.
|
||||
// It doesnt matter if a device is not presented and there is a lack of IDs (at least number 1 must be represented)
|
||||
// Report IDs and the report itself can be overwritten by the pins_arduino.h
|
||||
#ifndef HID_REPORTID_MOUSE
|
||||
#define HID_REPORTID_MOUSE 1
|
||||
#endif
|
||||
#ifndef HID_REPORTID_KEYBOARD
|
||||
#define HID_REPORTID_KEYBOARD 2
|
||||
#endif
|
||||
#ifndef HID_REPORTID_RAWHID
|
||||
#define HID_REPORTID_RAWHID 3
|
||||
#endif
|
||||
#ifndef HID_REPORTID_CONSUMERCONTROL
|
||||
#define HID_REPORTID_CONSUMERCONTROL 4
|
||||
#endif
|
||||
#ifndef HID_REPORTID_SYSTEMCONTROL
|
||||
#define HID_REPORTID_SYSTEMCONTROL 5
|
||||
#endif
|
||||
#ifndef HID_REPORTID_GAMEPAD
|
||||
#define HID_REPORTID_GAMEPAD 5
|
||||
#endif
|
||||
#ifndef HID_REPORTID_MOUSE_ABSOLUTE
|
||||
#define HID_REPORTID_MOUSE_ABSOLUTE 6
|
||||
#endif
|
||||
|
||||
// HID reports
|
||||
// Report IDs and the report itself can be overwritten by the pins_arduino.h
|
||||
|
||||
|
||||
#ifndef HID_REPORT_MOUSE
|
||||
#define HID_REPORT_MOUSE(report_id) /* Mouse relative */ \
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) 54 */ \
|
||||
0x09, 0x02, /* USAGE (Mouse) */ \
|
||||
0xa1, 0x01, /* COLLECTION (Application) */ \
|
||||
0x85, report_id, /* REPORT_ID */ \
|
||||
\
|
||||
/* 8 Buttons */ \
|
||||
0x05, 0x09, /* USAGE_PAGE (Button) */ \
|
||||
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ \
|
||||
0x29, 0x08, /* USAGE_MAXIMUM (Button 8) */ \
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ \
|
||||
0x95, 0x08, /* REPORT_COUNT (8) */ \
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */ \
|
||||
0x81, 0x02, /* INPUT (Data,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 */
|
||||
#endif
|
||||
|
||||
#ifndef HID_REPORT_MOUSE_ABSOLUTE
|
||||
#define HID_REPORT_MOUSE_ABSOLUTE(report_id) /* Mouse absolute */ \
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */ \
|
||||
0x09, 0x02, /* Usage (Mouse) */ \
|
||||
0xA1, 0x01, /* Collection (Application) */ \
|
||||
0x85, report_id, /* REPORT_ID */ \
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */ \
|
||||
0x09, 0x30, /* Usage (X) */ \
|
||||
0x09, 0x31, /* Usage (Y) */ \
|
||||
0x15, 0x00, /* Logical Minimum (0) */ \
|
||||
0x26, 0xFF, 0x7F, /* Logical Maximum (32767) */ \
|
||||
0x75, 0x10, /* Report Size (16), */ \
|
||||
0x95, 0x02, /* Report Count (2), */ \
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */ \
|
||||
0xC0 /* End Collection */
|
||||
#endif
|
||||
|
||||
#ifndef HID_REPORT_KEYBOARD_LEDS
|
||||
#define HID_REPORT_KEYBOARD_LEDS(report_id) /* Keyboard */ \
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) 47 */ \
|
||||
0x09, 0x06, /* USAGE (Keyboard) */ \
|
||||
0xa1, 0x01, /* COLLECTION (Application) */ \
|
||||
0x85, report_id, /* REPORT_ID */ \
|
||||
0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \
|
||||
\
|
||||
/* Keyboard Modifiers (shift, alt, ...) */ \
|
||||
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) */ \
|
||||
\
|
||||
/* 5 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) */ \
|
||||
\
|
||||
/* 6 Keyboard keys */ \
|
||||
0x95, 0x06, /* REPORT_COUNT (6) */ \
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */ \
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \
|
||||
0x26, 0xE7, 0x00, /* LOGICAL_MAXIMUM (231) */ \
|
||||
0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \
|
||||
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */ \
|
||||
0x29, 0xE7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ \
|
||||
0x81, 0x00, /* INPUT (Data,Ary,Abs) */ \
|
||||
\
|
||||
/* End */ \
|
||||
0xc0 /* END_COLLECTION */
|
||||
#endif
|
||||
|
||||
#ifndef HID_REPORT_KEYBOARD_KEYS
|
||||
#define HID_REPORT_KEYBOARD_KEYS(report_id) /* Keyboard */ \
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) 47 */ \
|
||||
0x09, 0x06, /* USAGE (Keyboard) */ \
|
||||
0xa1, 0x01, /* COLLECTION (Application) */ \
|
||||
0x85, report_id, /* REPORT_ID */ \
|
||||
0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \
|
||||
\
|
||||
/* Keyboard Modifiers (shift, alt, ...) */ \
|
||||
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) */ \
|
||||
\
|
||||
HID_REPORT_KEYBOARD_LEDS \
|
||||
/* 6 Keyboard keys */ \
|
||||
0x95, 0x06, /* REPORT_COUNT (6) */ \
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */ \
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */ \
|
||||
0x26, 0xE7, 0x00, /* LOGICAL_MAXIMUM (231) */ \
|
||||
0x05, 0x07, /* USAGE_PAGE (Keyboard) */ \
|
||||
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */ \
|
||||
0x29, 0xE7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ \
|
||||
0x81, 0x00, /* INPUT (Data,Ary,Abs) */ \
|
||||
\
|
||||
/* End */ \
|
||||
0xc0 /* END_COLLECTION */
|
||||
#endif
|
||||
|
||||
//TODO limit to system keys only?
|
||||
#ifndef HID_REPORT_SYSTEMCONTROL
|
||||
#define HID_REPORT_SYSTEMCONTROL(report_id) /* System Control (Power Down, Sleep, Wakeup, ...) */ \
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ \
|
||||
0x09, 0x80, /* USAGE (System Control) */ \
|
||||
0xa1, 0x01, /* COLLECTION (Application) */ \
|
||||
0x85, report_id, /* 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
|
||||
|
||||
#ifndef HID_REPORT_CONSUMERCONTROL
|
||||
#define HID_REPORT_CONSUMERCONTROL(report_id) /* Consumer Control (Sound/Media keys) */ \
|
||||
0x05, 0x0C, /* usage page (consumer device) */ \
|
||||
0x09, 0x01, /* usage -- consumer control */ \
|
||||
0xA1, 0x01, /* collection (application) */ \
|
||||
0x85, report_id, /* report id */ \
|
||||
/* 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
|
||||
|
||||
// note by NicoHood: RawHID might never work with multireports, because of OS problems
|
||||
// therefore we have to make it a single report with no idea. No other HID device will be supported then.
|
||||
#define RAWHID_USAGE_PAGE 0xFFC0 // recommended: 0xFF00 to 0xFFFF
|
||||
#define RAWHID_USAGE 0x0C00 // recommended: 0x0100 to 0xFFFF
|
||||
#define RAWHID_TX_SIZE (USB_EP_SIZE-1)
|
||||
#define RAWHID_RX_SIZE (USB_EP_SIZE-1)
|
||||
|
||||
#define LSB(_x) ((_x) & 0xFF)
|
||||
#define MSB(_x) ((_x) >> 8)
|
||||
|
||||
#ifndef HID_REPORT_RAWHID
|
||||
#define HID_REPORT_RAWHID(report_id) /* RAW HID */ \
|
||||
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), /* 30 */ \
|
||||
0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), \
|
||||
\
|
||||
0xA1, 0x01, /* Collection 0x01 */ \
|
||||
0x85, report_id, /* 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
|
||||
|
||||
#if defined(USBCON)
|
||||
|
||||
#include "USBDesc.h"
|
||||
#include "USBCore.h"
|
||||
#include "HIDAPI.h"
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// HID 'Driver'
|
||||
|
||||
int HID_GetInterface(uint8_t* interfaceNum);
|
||||
int HID_GetDescriptor(int i);
|
||||
bool HID_Setup(Setup& setup);
|
||||
void HID_SendReport(uint8_t id, const void* data, int len);
|
||||
#if defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
void HID_SetKeyboardLedReport(uint8_t leds);
|
||||
#endif
|
||||
|
||||
#else /* if defined(USBCON) */
|
||||
|
||||
// (weak) function prototype to let the user use the HIDAPI for different use
|
||||
// if he include the api himself
|
||||
void HID_SendReport(uint8_t id, const void* data, int len);
|
||||
|
||||
#endif /* if defined(USBCON) */
|
||||
|
||||
#endif
|
||||
28
HIDAPI.h
Normal file
28
HIDAPI.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
HIDAPI.h
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __HIDAPI__
|
||||
#define __HIDAPI__
|
||||
|
||||
// include all HID APIs
|
||||
#include "Keyboard.h"
|
||||
#include "Mouse.h"
|
||||
//TODO
|
||||
|
||||
#endif
|
||||
284
Keyboard.cpp
Normal file
284
Keyboard.cpp
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
Keyboard.cpp
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "Keyboard.h"
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
|
||||
#if defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
uint8_t hid_keyboard_leds = 0;
|
||||
void HID_SetKeyboardLedReport(uint8_t leds){
|
||||
hid_keyboard_leds = leds;
|
||||
}
|
||||
#endif
|
||||
|
||||
Keyboard_ Keyboard;
|
||||
|
||||
Keyboard_::Keyboard_(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Keyboard_::sendReport(KeyReport* keys)
|
||||
{
|
||||
HID_SendReport(HID_REPORTID_KEYBOARD, keys, sizeof(KeyReport));
|
||||
}
|
||||
|
||||
extern
|
||||
const uint8_t _asciimap[128] PROGMEM;
|
||||
|
||||
#define SHIFT 0x80
|
||||
const uint8_t _asciimap[128] =
|
||||
{
|
||||
0x00, // NUL
|
||||
0x00, // SOH
|
||||
0x00, // STX
|
||||
0x00, // ETX
|
||||
0x00, // EOT
|
||||
0x00, // ENQ
|
||||
0x00, // ACK
|
||||
0x00, // BEL
|
||||
0x2a, // BS Backspace
|
||||
0x2b, // TAB Tab
|
||||
0x28, // LF Enter
|
||||
0x00, // VT
|
||||
0x00, // FF
|
||||
0x00, // CR
|
||||
0x00, // SO
|
||||
0x00, // SI
|
||||
0x00, // DEL
|
||||
0x00, // DC1
|
||||
0x00, // DC2
|
||||
0x00, // DC3
|
||||
0x00, // DC4
|
||||
0x00, // NAK
|
||||
0x00, // SYN
|
||||
0x00, // ETB
|
||||
0x00, // CAN
|
||||
0x00, // EM
|
||||
0x00, // SUB
|
||||
0x00, // ESC
|
||||
0x00, // FS
|
||||
0x00, // GS
|
||||
0x00, // RS
|
||||
0x00, // US
|
||||
|
||||
0x2c, // ' '
|
||||
0x1e | SHIFT, // !
|
||||
0x34 | SHIFT, // "
|
||||
0x20 | SHIFT, // #
|
||||
0x21 | SHIFT, // $
|
||||
0x22 | SHIFT, // %
|
||||
0x24 | SHIFT, // &
|
||||
0x34, // '
|
||||
0x26 | SHIFT, // (
|
||||
0x27 | SHIFT, // )
|
||||
0x25 | SHIFT, // *
|
||||
0x2e | SHIFT, // +
|
||||
0x36, // ,
|
||||
0x2d, // -
|
||||
0x37, // .
|
||||
0x38, // /
|
||||
0x27, // 0
|
||||
0x1e, // 1
|
||||
0x1f, // 2
|
||||
0x20, // 3
|
||||
0x21, // 4
|
||||
0x22, // 5
|
||||
0x23, // 6
|
||||
0x24, // 7
|
||||
0x25, // 8
|
||||
0x26, // 9
|
||||
0x33 | SHIFT, // :
|
||||
0x33, // ;
|
||||
0x36 | SHIFT, // <
|
||||
0x2e, // =
|
||||
0x37 | SHIFT, // >
|
||||
0x38 | SHIFT, // ?
|
||||
0x1f | SHIFT, // @
|
||||
0x04 | SHIFT, // A
|
||||
0x05 | SHIFT, // B
|
||||
0x06 | SHIFT, // C
|
||||
0x07 | SHIFT, // D
|
||||
0x08 | SHIFT, // E
|
||||
0x09 | SHIFT, // F
|
||||
0x0a | SHIFT, // G
|
||||
0x0b | SHIFT, // H
|
||||
0x0c | SHIFT, // I
|
||||
0x0d | SHIFT, // J
|
||||
0x0e | SHIFT, // K
|
||||
0x0f | SHIFT, // L
|
||||
0x10 | SHIFT, // M
|
||||
0x11 | SHIFT, // N
|
||||
0x12 | SHIFT, // O
|
||||
0x13 | SHIFT, // P
|
||||
0x14 | SHIFT, // Q
|
||||
0x15 | SHIFT, // R
|
||||
0x16 | SHIFT, // S
|
||||
0x17 | SHIFT, // T
|
||||
0x18 | SHIFT, // U
|
||||
0x19 | SHIFT, // V
|
||||
0x1a | SHIFT, // W
|
||||
0x1b | SHIFT, // X
|
||||
0x1c | SHIFT, // Y
|
||||
0x1d | SHIFT, // Z
|
||||
0x2f, // [
|
||||
0x31, // bslash
|
||||
0x30, // ]
|
||||
0x23 | SHIFT, // ^
|
||||
0x2d | SHIFT, // _
|
||||
0x35, // `
|
||||
0x04, // a
|
||||
0x05, // b
|
||||
0x06, // c
|
||||
0x07, // d
|
||||
0x08, // e
|
||||
0x09, // f
|
||||
0x0a, // g
|
||||
0x0b, // h
|
||||
0x0c, // i
|
||||
0x0d, // j
|
||||
0x0e, // k
|
||||
0x0f, // l
|
||||
0x10, // m
|
||||
0x11, // n
|
||||
0x12, // o
|
||||
0x13, // p
|
||||
0x14, // q
|
||||
0x15, // r
|
||||
0x16, // s
|
||||
0x17, // t
|
||||
0x18, // u
|
||||
0x19, // v
|
||||
0x1a, // w
|
||||
0x1b, // x
|
||||
0x1c, // y
|
||||
0x1d, // z
|
||||
0x2f | SHIFT, //
|
||||
0x31 | SHIFT, // |
|
||||
0x30 | SHIFT, // }
|
||||
0x35 | SHIFT, // ~
|
||||
0 // DEL
|
||||
};
|
||||
|
||||
// press() adds the specified key (printing, non-printing, or modifier)
|
||||
// to the persistent key report and sends the report. Because of the way
|
||||
// USB HID works, the host acts like the key remains pressed until we
|
||||
// call release(), releaseAll(), or otherwise clear the report and resend.
|
||||
size_t Keyboard_::press(uint8_t k)
|
||||
{
|
||||
uint8_t i;
|
||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
||||
k = k - 136;
|
||||
}
|
||||
else if (k >= 128) { // it's a modifier key
|
||||
_keyReport.modifiers |= (1 << (k - 128));
|
||||
k = 0;
|
||||
}
|
||||
else { // it's a printing key
|
||||
k = pgm_read_byte(_asciimap + k);
|
||||
if (!k) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
||||
_keyReport.modifiers |= 0x02; // the left shift modifier
|
||||
k &= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
// Add k to the key report only if it's not already present
|
||||
// and if there is an empty slot.
|
||||
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
||||
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
||||
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (_keyReport.keys[i] == 0x00) {
|
||||
_keyReport.keys[i] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 6) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sendReport(&_keyReport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// release() takes the specified key out of the persistent key report and
|
||||
// sends the report. This tells the OS the key is no longer pressed and that
|
||||
// it shouldn't be repeated any more.
|
||||
size_t Keyboard_::release(uint8_t k)
|
||||
{
|
||||
uint8_t i;
|
||||
if (k >= 136) { // it's a non-printing key (not a modifier)
|
||||
k = k - 136;
|
||||
}
|
||||
else if (k >= 128) { // it's a modifier key
|
||||
_keyReport.modifiers &= ~(1 << (k - 128));
|
||||
k = 0;
|
||||
}
|
||||
else { // it's a printing key
|
||||
k = pgm_read_byte(_asciimap + k);
|
||||
if (!k) {
|
||||
return 0;
|
||||
}
|
||||
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
||||
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
||||
k &= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
// Test the key report to see if k is present. Clear it if it exists.
|
||||
// Check all positions in case the key is present more than once (which it shouldn't be)
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (0 != k && _keyReport.keys[i] == k) {
|
||||
_keyReport.keys[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
sendReport(&_keyReport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Keyboard_::releaseAll(void)
|
||||
{
|
||||
// release all keys
|
||||
memset(&_keyReport, 0x00, sizeof(_keyReport));
|
||||
sendReport(&_keyReport);
|
||||
}
|
||||
|
||||
size_t Keyboard_::write(uint8_t c)
|
||||
{
|
||||
uint8_t p = press(c); // Keydown
|
||||
release(c); // Keyup
|
||||
return p; // just return the result of press() since release() almost always returns 1
|
||||
}
|
||||
110
Keyboard.h
Normal file
110
Keyboard.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Keyboard.h
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __KEYBOARDAPI__
|
||||
#define __KEYBOARDAPI__
|
||||
|
||||
// to access the HID_SendReport via USBAPI.h, report number and the Print class
|
||||
#include "Arduino.h"
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
|
||||
#define KEY_PRINT 0xCE
|
||||
#define KEY_NUM_LOCK 0xDB
|
||||
#define KEY_SCROLL_LOCK 0xCF
|
||||
#define KEY_PAUSE 0xD0
|
||||
|
||||
#define KEY_LEFT_CTRL 0x80
|
||||
#define KEY_LEFT_SHIFT 0x81
|
||||
#define KEY_LEFT_ALT 0x82
|
||||
#define KEY_LEFT_GUI 0x83
|
||||
#define KEY_LEFT_WINDOWS KEY_LEFT_GUI
|
||||
#define KEY_RIGHT_CTRL 0x84
|
||||
#define KEY_RIGHT_SHIFT 0x85
|
||||
#define KEY_RIGHT_ALT 0x86
|
||||
#define KEY_RIGHT_GUI 0x87
|
||||
#define KEY_RIGHT_WINDOWS KEY_RIGHT_GUI
|
||||
|
||||
#define KEY_UP_ARROW 0xDA
|
||||
#define KEY_DOWN_ARROW 0xD9
|
||||
#define KEY_LEFT_ARROW 0xD8
|
||||
#define KEY_RIGHT_ARROW 0xD7
|
||||
#define KEY_BACKSPACE 0xB2
|
||||
#define KEY_TAB 0xB3
|
||||
#define KEY_RETURN 0xB0
|
||||
#define KEY_ESC 0xB1
|
||||
#define KEY_INSERT 0xD1
|
||||
#define KEY_DELETE 0xD4
|
||||
#define KEY_PAGE_UP 0xD3
|
||||
#define KEY_PAGE_DOWN 0xD6
|
||||
#define KEY_HOME 0xD2
|
||||
#define KEY_END 0xD5
|
||||
#define KEY_CAPS_LOCK 0xC1
|
||||
#define KEY_F1 0xC2
|
||||
#define KEY_F2 0xC3
|
||||
#define KEY_F3 0xC4
|
||||
#define KEY_F4 0xC5
|
||||
#define KEY_F5 0xC6
|
||||
#define KEY_F6 0xC7
|
||||
#define KEY_F7 0xC8
|
||||
#define KEY_F8 0xC9
|
||||
#define KEY_F9 0xCA
|
||||
#define KEY_F10 0xCB
|
||||
#define KEY_F11 0xCC
|
||||
#define KEY_F12 0xCD
|
||||
|
||||
#define LED_NUM_LOCK 0x01
|
||||
#define LED_CAPS_LOCK 0x02
|
||||
#define LED_SCROLL_LOCK 0x04
|
||||
|
||||
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
||||
typedef struct
|
||||
{
|
||||
uint8_t modifiers;
|
||||
uint8_t reserved;
|
||||
uint8_t keys[6];
|
||||
} KeyReport;
|
||||
|
||||
// extern accessible led out report
|
||||
extern uint8_t hid_keyboard_leds;
|
||||
|
||||
class Keyboard_ : public Print
|
||||
{
|
||||
protected:
|
||||
KeyReport _keyReport;
|
||||
void sendReport(KeyReport* keys);
|
||||
public:
|
||||
Keyboard_(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
size_t write(uint8_t k);
|
||||
size_t press(uint8_t k);
|
||||
size_t release(uint8_t k);
|
||||
void releaseAll(void);
|
||||
|
||||
//TODO
|
||||
#if defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
inline uint8_t getLEDs(void){ return hid_keyboard_leds; }
|
||||
#endif
|
||||
};
|
||||
extern Keyboard_ Keyboard;
|
||||
|
||||
#endif
|
||||
88
Mouse.cpp
Normal file
88
Mouse.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Mouse.cpp
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "Mouse.h"
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Mouse
|
||||
|
||||
Mouse_ Mouse;
|
||||
|
||||
Mouse_::Mouse_(void) : _buttons(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::end(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Mouse_::click(uint8_t b)
|
||||
{
|
||||
_buttons = b;
|
||||
move(0, 0, 0);
|
||||
_buttons = 0;
|
||||
move(0, 0, 0);
|
||||
}
|
||||
|
||||
void Mouse_::move(signed char x, signed char y, signed char wheel)
|
||||
{
|
||||
u8 m[4];
|
||||
m[0] = _buttons;
|
||||
m[1] = x;
|
||||
m[2] = y;
|
||||
m[3] = wheel;
|
||||
HID_SendReport(1, m, 4);
|
||||
}
|
||||
|
||||
void Mouse_::buttons(uint8_t b)
|
||||
{
|
||||
if (b != _buttons)
|
||||
{
|
||||
_buttons = b;
|
||||
move(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse_::press(uint8_t b)
|
||||
{
|
||||
buttons(_buttons | b);
|
||||
}
|
||||
|
||||
void Mouse_::release(uint8_t b)
|
||||
{
|
||||
buttons(_buttons & ~b);
|
||||
}
|
||||
|
||||
bool Mouse_::isPressed(uint8_t b)
|
||||
{
|
||||
if ((b & _buttons) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mouse_::moveTo(uint16_t x, uint16_t y)
|
||||
{
|
||||
uint32_t pos = ((uint32_t)y << 16) | x;
|
||||
HID_SendReport(HID_REPORTID_MOUSE_ABSOLUTE, &pos, sizeof(pos));
|
||||
}
|
||||
56
Mouse.h
Normal file
56
Mouse.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Mouse.h
|
||||
Copyright (c) 2005-2014 Arduino. All right reserved.
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __MOUSEAPI__
|
||||
#define __MOUSEAPI__
|
||||
|
||||
// to access the HID_SendReport via USBAPI.h and report number
|
||||
#include "Arduino.h"
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Mouse
|
||||
|
||||
#define MOUSE_LEFT 0x01
|
||||
#define MOUSE_RIGHT 0x02
|
||||
#define MOUSE_MIDDLE 0x04
|
||||
#define MOUSE_PREV 0x08
|
||||
#define MOUSE_NEXT 0x10
|
||||
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE | MOUSE_PREV | MOUSE_NEXT)
|
||||
|
||||
class Mouse_
|
||||
{
|
||||
private:
|
||||
uint8_t _buttons;
|
||||
void buttons(uint8_t b);
|
||||
public:
|
||||
Mouse_(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
void click(uint8_t b = MOUSE_LEFT);
|
||||
void move(signed char x, signed char y, signed char wheel = 0);
|
||||
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
||||
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
||||
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
||||
|
||||
void moveTo(uint16_t x, uint16_t y);
|
||||
};
|
||||
extern Mouse_ Mouse;
|
||||
|
||||
#endif
|
||||
54
Readme.md
Normal file
54
Readme.md
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
TODO
|
||||
====
|
||||
|
||||
Under Construction. This is a todo list for myself and a feature list so far.
|
||||
|
||||
```
|
||||
Keyboard Layout english only?
|
||||
more usb definitions instead of fixed values, noone understands
|
||||
someone has to add the keywords.txt definitions as well
|
||||
keyboard music vol (change descriptor)
|
||||
keyboard led move to usb function not to keyboard and from keyboard call this function?
|
||||
weak hidsendreport implement somewhere the prototype?
|
||||
move HID-Core to a seperate folder?
|
||||
usb wakeup
|
||||
keycode/raw for keyboard
|
||||
magic key fix?
|
||||
add examples
|
||||
void Recv(volatile u8* data, u8 count) static inline??
|
||||
|
||||
Bugs
|
||||
Mouse Abs only works with system report under special circumstances.
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
(flash numbers might be irrelevant due to a lot of improvements)
|
||||
* Uses less flash if HID or Serial is not used
|
||||
* Extended and compacter(flash) HID Report Descriptors
|
||||
* Fixed USB Device Descriptor
|
||||
* Added u2 compatibility with smaller USB_EP_SIZE (16u2 etc)
|
||||
* Added Serial Event for LineEncoding and LineState (+12b flash)
|
||||
* Added Serial Function to get dtr state, line encoding etc
|
||||
* Added Keyboard Led Out report to get Led states (for numlock etc, +52b flash, 1b ram)
|
||||
* Made CDC-Core independent from USB-Core
|
||||
* Made HID-Core independent from USB-Core
|
||||
* Made HID-API independent from HID-Core
|
||||
* Removed not needed virtual functions in Keyboard
|
||||
* Made HID Reports and its IDs replaceable via pins_Arduino.h
|
||||
* Added Absolute Mouse
|
||||
```
|
||||
|
||||
```
|
||||
Include schematic
|
||||
- Arduino.h
|
||||
- USBAPI.h -> Arduino.h, USBDESC.h, USBCore.h
|
||||
- CDC.h -> Arduino.h, USBDESC.h, USBCore.h
|
||||
- HID.h -> Arduino.h, USBDESC.h, USBCore.h, HID-API
|
||||
- HID-API -> Keyboard.h, Mouse.h
|
||||
- Keyboard.h -> Arduino.h
|
||||
- Mouse.h -> Arduino.h
|
||||
|
||||
HID.h contains all HID configuration.
|
||||
Each HID-API (like Mouse) includes Arduino.h and gets these settings as well.
|
||||
```
|
||||
212
USBAPI.h
212
USBAPI.h
|
|
@ -34,29 +34,6 @@ typedef unsigned long u32;
|
|||
|
||||
#if defined(USBCON)
|
||||
|
||||
// include needed HID devices
|
||||
// the more you activate, the more flash it will take
|
||||
// by default only Mouse + Keyboard (without LEDs) are activated
|
||||
#define HID_MOUSE_ENABLED
|
||||
#define HID_KEYBOARD_ENABLED
|
||||
//#define HID_KEYBOARD_LEDS_ENABLED
|
||||
|
||||
//#define HID_RAWHID_ENABLED (currently broken for USB-Core)
|
||||
//#define HID_MEDIA_ENABLED
|
||||
//#define HID_SYSTEM_ENABLED
|
||||
//#define HID_GAMEPAD_ENABLED
|
||||
|
||||
/** Enum for the HID report IDs used in the device. */
|
||||
typedef enum{
|
||||
HID_REPORTID_NotAReport = 0x00, /**< first entry is always zero for multireports */
|
||||
HID_REPORTID_MouseReport = 0x01, /**< Report ID for the Mouse report within the device. */
|
||||
HID_REPORTID_KeyboardReport = 0x02, /**< Report ID for the Keyboard report within the device. */
|
||||
HID_REPORTID_RawHidReport = 0x03, /**< Report ID for the Raw Hid report within the device. */
|
||||
HID_REPORTID_MediaReport = 0x04, /**< Report ID for the Media report within the device. */
|
||||
HID_REPORTID_SystemReport = 0x05, /**< Report ID for the Power report within the device. */
|
||||
HID_REPORTID_GamepadReport = 0x06, /**< Report ID for the Gamepad report within the device. */
|
||||
} HID_Report_IDs;
|
||||
|
||||
#include "USBDesc.h"
|
||||
#include "USBCore.h"
|
||||
|
||||
|
|
@ -76,195 +53,6 @@ public:
|
|||
};
|
||||
extern USBDevice_ USBDevice;
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Serial over CDC (Serial1 is the physical port)
|
||||
|
||||
struct ring_buffer;
|
||||
|
||||
#if (RAMEND < 1000)
|
||||
#define SERIAL_BUFFER_SIZE 16
|
||||
#else
|
||||
#define SERIAL_BUFFER_SIZE 64
|
||||
#endif
|
||||
|
||||
class Serial_ : public Stream
|
||||
{
|
||||
private:
|
||||
int peek_buffer;
|
||||
public:
|
||||
Serial_() { peek_buffer = -1; };
|
||||
void begin(unsigned long);
|
||||
void begin(unsigned long, uint8_t);
|
||||
void end(void);
|
||||
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t*, size_t);
|
||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
uint32_t baud(void);
|
||||
uint8_t stopbits(void);
|
||||
uint8_t paritytype(void);
|
||||
uint8_t numbits(void);
|
||||
bool dtr(void);
|
||||
bool rts(void);
|
||||
operator bool();
|
||||
|
||||
volatile uint8_t _rx_buffer_head;
|
||||
volatile uint8_t _rx_buffer_tail;
|
||||
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
|
||||
};
|
||||
extern Serial_ Serial;
|
||||
|
||||
#define HAVE_CDCSERIAL
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Mouse
|
||||
|
||||
#ifdef HID_MOUSE_ENABLED
|
||||
|
||||
#define MOUSE_LEFT 0x01
|
||||
#define MOUSE_RIGHT 0x02
|
||||
#define MOUSE_MIDDLE 0x04
|
||||
#define MOUSE_PREV 0x08
|
||||
#define MOUSE_NEXT 0x10
|
||||
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE | MOUSE_PREV | MOUSE_NEXT)
|
||||
|
||||
class Mouse_
|
||||
{
|
||||
private:
|
||||
uint8_t _buttons;
|
||||
void buttons(uint8_t b);
|
||||
public:
|
||||
Mouse_(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
void click(uint8_t b = MOUSE_LEFT);
|
||||
void move(signed char x, signed char y, signed char wheel = 0);
|
||||
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
|
||||
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
|
||||
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
|
||||
};
|
||||
extern Mouse_ Mouse;
|
||||
|
||||
#endif
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Keyboard
|
||||
|
||||
#ifdef HID_KEYBOARD_ENABLED
|
||||
|
||||
#define KEY_PRINT 0xCE
|
||||
#define KEY_NUM_LOCK 0xDB
|
||||
#define KEY_SCROLL_LOCK 0xCF
|
||||
#define KEY_PAUSE 0xD0
|
||||
|
||||
#define KEY_LEFT_CTRL 0x80
|
||||
#define KEY_LEFT_SHIFT 0x81
|
||||
#define KEY_LEFT_ALT 0x82
|
||||
#define KEY_LEFT_GUI 0x83
|
||||
#define KEY_LEFT_WINDOWS KEY_LEFT_GUI
|
||||
#define KEY_RIGHT_CTRL 0x84
|
||||
#define KEY_RIGHT_SHIFT 0x85
|
||||
#define KEY_RIGHT_ALT 0x86
|
||||
#define KEY_RIGHT_GUI 0x87
|
||||
#define KEY_RIGHT_WINDOWS KEY_RIGHT_GUI
|
||||
|
||||
#define KEY_UP_ARROW 0xDA
|
||||
#define KEY_DOWN_ARROW 0xD9
|
||||
#define KEY_LEFT_ARROW 0xD8
|
||||
#define KEY_RIGHT_ARROW 0xD7
|
||||
#define KEY_BACKSPACE 0xB2
|
||||
#define KEY_TAB 0xB3
|
||||
#define KEY_RETURN 0xB0
|
||||
#define KEY_ESC 0xB1
|
||||
#define KEY_INSERT 0xD1
|
||||
#define KEY_DELETE 0xD4
|
||||
#define KEY_PAGE_UP 0xD3
|
||||
#define KEY_PAGE_DOWN 0xD6
|
||||
#define KEY_HOME 0xD2
|
||||
#define KEY_END 0xD5
|
||||
#define KEY_CAPS_LOCK 0xC1
|
||||
#define KEY_F1 0xC2
|
||||
#define KEY_F2 0xC3
|
||||
#define KEY_F3 0xC4
|
||||
#define KEY_F4 0xC5
|
||||
#define KEY_F5 0xC6
|
||||
#define KEY_F6 0xC7
|
||||
#define KEY_F7 0xC8
|
||||
#define KEY_F8 0xC9
|
||||
#define KEY_F9 0xCA
|
||||
#define KEY_F10 0xCB
|
||||
#define KEY_F11 0xCC
|
||||
#define KEY_F12 0xCD
|
||||
|
||||
#define LED_NUM_LOCK 0x01
|
||||
#define LED_CAPS_LOCK 0x02
|
||||
#define LED_SCROLL_LOCK 0x04
|
||||
|
||||
#if defined USBCON && defined(HID_KEYBOARD_ENABLED) && defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
// extern accessible led out report
|
||||
extern uint8_t hid_keyboard_leds;
|
||||
#endif
|
||||
|
||||
// Low level key report: up to 6 keys and shift, ctrl etc at once
|
||||
typedef struct
|
||||
{
|
||||
uint8_t modifiers;
|
||||
uint8_t reserved;
|
||||
uint8_t keys[6];
|
||||
} KeyReport;
|
||||
|
||||
class Keyboard_ : public Print
|
||||
{
|
||||
private:
|
||||
KeyReport _keyReport;
|
||||
void sendReport(KeyReport* keys);
|
||||
public:
|
||||
Keyboard_(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
virtual size_t write(uint8_t k);
|
||||
virtual size_t press(uint8_t k);
|
||||
virtual size_t release(uint8_t k);
|
||||
virtual void releaseAll(void);
|
||||
|
||||
#if defined(HID_KEYBOARD_LEDS_ENABLED)
|
||||
inline uint8_t getLEDs(void){ return hid_keyboard_leds; }
|
||||
#endif
|
||||
};
|
||||
extern Keyboard_ Keyboard;
|
||||
|
||||
#endif
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Low level API
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint8_t wValueL;
|
||||
uint8_t wValueH;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} Setup;
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// HID 'Driver'
|
||||
|
||||
int HID_GetInterface(uint8_t* interfaceNum);
|
||||
int HID_GetDescriptor(int i);
|
||||
bool HID_Setup(Setup& setup);
|
||||
void HID_SendReport(uint8_t id, const void* data, int len);
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// MSC 'Driver'
|
||||
|
|
|
|||
13
USBCore.h
13
USBCore.h
|
|
@ -317,5 +317,18 @@ typedef struct
|
|||
#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
|
||||
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Low level API
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint8_t wValueL;
|
||||
uint8_t wValueH;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} Setup;
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue