#include "Platform.h"
#include "USBAPI.h"
#include "USBDesc.h"
#if defined(USBCON)
#ifdef HID_ENABLED
Mouse_ Mouse;
Keyboard_ Keyboard;
#define LSB(_x) ((_x) & 0xFF)
#define MSB(_x) ((_x) >> 8)
#define RAWHID_USAGE_PAGE 0xFFC0
#define RAWHID_USAGE 0x0C00
#define RAWHID_TX_SIZE 64
#define RAWHID_RX_SIZE 64
extern const u8 _hidReportDescriptor[] PROGMEM;
const u8 _hidReportDescriptor[] = {
0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x03, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06, 0xc0, 0xc0,
0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x85, 0x02, 0x05, 0x07,
0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x03,
0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07,
0x19, 0x00, 0x29, 0x65, 0x81, 0x00, 0xc0,
#if RAWHID_ENABLED
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
0xA1, 0x01, 0x85, 0x03, 0x75, 0x08, 0x15, 0x00, 0x26, 0xFF, 0x00,
0x95, 64, 0x09, 0x01, 0x81, 0x02,
0x95, 64, 0x09, 0x02, 0x91, 0x02, 0xC0 #endif
};
extern const HIDDescriptor _hidInterface PROGMEM;
const HIDDescriptor _hidInterface =
{
D_INTERFACE(HID_INTERFACE,1,3,0,0),
D_HIDREPORT(sizeof(_hidReportDescriptor)),
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
};
u8 _hid_protocol = 1;
u8 _hid_idle = 1;
#define WEAK __attribute__ ((weak))
int WEAK HID_GetInterface(u8* interfaceNum)
{
interfaceNum[0] += 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)
{
return true;
}
if (HID_GET_PROTOCOL == r)
{
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;
}
}
return false;
}
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;
}
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x33|SHIFT, 0x33, 0x36|SHIFT, 0x2e, 0x37|SHIFT, 0x38|SHIFT, 0x1f|SHIFT, 0x04|SHIFT, 0x05|SHIFT, 0x06|SHIFT, 0x07|SHIFT, 0x08|SHIFT, 0x09|SHIFT, 0x0a|SHIFT, 0x0b|SHIFT, 0x0c|SHIFT, 0x0d|SHIFT, 0x0e|SHIFT, 0x0f|SHIFT, 0x10|SHIFT, 0x11|SHIFT, 0x12|SHIFT, 0x13|SHIFT, 0x14|SHIFT, 0x15|SHIFT, 0x16|SHIFT, 0x17|SHIFT, 0x18|SHIFT, 0x19|SHIFT, 0x1a|SHIFT, 0x1b|SHIFT, 0x1c|SHIFT, 0x1d|SHIFT, 0x2f, 0x31, 0x30, 0x23|SHIFT, 0x2d|SHIFT, 0x35, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x2f|SHIFT, 0x31|SHIFT, 0x30|SHIFT, 0x35|SHIFT, 0 };
uint8_t USBPutChar(uint8_t c);
size_t Keyboard_::press(uint8_t k)
{
uint8_t i;
if (k >= 136) { k = k - 136;
} else if (k >= 128) { _keyReport.modifiers |= (1<<(k-128));
k = 0;
} else { k = pgm_read_byte(_asciimap + k);
if (!k) {
setWriteError();
return 0;
}
if (k & 0x80) { _keyReport.modifiers |= 0x02; k &= 0x7F;
}
}
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;
}
size_t Keyboard_::release(uint8_t k)
{
uint8_t i;
if (k >= 136) { k = k - 136;
} else if (k >= 128) { _keyReport.modifiers &= ~(1<<(k-128));
k = 0;
} else { k = pgm_read_byte(_asciimap + k);
if (!k) {
return 0;
}
if (k & 0x80) { _keyReport.modifiers &= ~(0x02); k &= 0x7F;
}
}
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); uint8_t r = release(c); return (p); }
#endif
#endif