Mouse using HID parser
This commit is contained in:
parent
1259027ebc
commit
f58ed079a6
|
@ -402,16 +402,14 @@ private:
|
||||||
// Device drivers may inherit from this base class, if they wish to receive
|
// Device drivers may inherit from this base class, if they wish to receive
|
||||||
// HID input data fully decoded by the USBHIDParser driver
|
// HID input data fully decoded by the USBHIDParser driver
|
||||||
class USBHIDInput {
|
class USBHIDInput {
|
||||||
public:
|
|
||||||
USBHIDInput();
|
|
||||||
private:
|
private:
|
||||||
virtual bool claim_collection(Device_t *dev, uint32_t topusage);
|
virtual bool claim_collection(Device_t *dev, uint32_t topusage);
|
||||||
virtual void hid_input_begin(uint32_t topusage, uint32_t type, int min, int max);
|
virtual void hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax);
|
||||||
virtual void hid_input_data(uint32_t usage, int32_t value);
|
virtual void hid_input_data(uint32_t usage, int32_t value);
|
||||||
virtual void hid_input_end();
|
virtual void hid_input_end();
|
||||||
virtual void disconnect_collection(Device_t *dev);
|
virtual void disconnect_collection(Device_t *dev);
|
||||||
|
void add_to_list();
|
||||||
USBHIDInput *next;
|
USBHIDInput *next;
|
||||||
static USBHIDInput *list;
|
|
||||||
friend class USBHIDParser;
|
friend class USBHIDParser;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -498,7 +496,7 @@ private:
|
||||||
class USBHIDParser : public USBDriver {
|
class USBHIDParser : public USBDriver {
|
||||||
public:
|
public:
|
||||||
USBHIDParser(USBHost &host) { init(); }
|
USBHIDParser(USBHost &host) { init(); }
|
||||||
void driver_ready_for_hid_collection(USBHIDInput *driver);
|
static void driver_ready_for_hid_collection(USBHIDInput *driver);
|
||||||
protected:
|
protected:
|
||||||
enum { TOPUSAGE_LIST_LEN = 4 };
|
enum { TOPUSAGE_LIST_LEN = 4 };
|
||||||
enum { USAGE_LIST_LEN = 12 };
|
enum { USAGE_LIST_LEN = 12 };
|
||||||
|
@ -517,6 +515,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
Pipe_t *in_pipe;
|
Pipe_t *in_pipe;
|
||||||
Pipe_t *out_pipe;
|
Pipe_t *out_pipe;
|
||||||
|
static USBHIDInput *available_hid_drivers_list;
|
||||||
//uint32_t topusage_list[TOPUSAGE_LIST_LEN];
|
//uint32_t topusage_list[TOPUSAGE_LIST_LEN];
|
||||||
USBHIDInput *topusage_drivers[TOPUSAGE_LIST_LEN];
|
USBHIDInput *topusage_drivers[TOPUSAGE_LIST_LEN];
|
||||||
uint16_t in_size;
|
uint16_t in_size;
|
||||||
|
@ -711,6 +710,35 @@ private:
|
||||||
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
|
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
class MouseController : public USBHIDInput {
|
||||||
|
public:
|
||||||
|
MouseController(USBHost &host) { USBHIDParser::driver_ready_for_hid_collection(this); }
|
||||||
|
bool available() { return mouseEvent; }
|
||||||
|
void mouseDataClear();
|
||||||
|
uint8_t getButtons() { return buttons; }
|
||||||
|
int getMouseX() { return mouseX; }
|
||||||
|
int getMouseY() { return mouseY; }
|
||||||
|
int getWheel() { return wheel; }
|
||||||
|
int getWheelH() { return wheelH; }
|
||||||
|
protected:
|
||||||
|
virtual bool claim_collection(Device_t *dev, uint32_t topusage);
|
||||||
|
virtual void hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax);
|
||||||
|
virtual void hid_input_data(uint32_t usage, int32_t value);
|
||||||
|
virtual void hid_input_end();
|
||||||
|
virtual void disconnect_collection(Device_t *dev);
|
||||||
|
private:
|
||||||
|
Device_t *mydevice = NULL;
|
||||||
|
uint8_t collections_claimed = 0;
|
||||||
|
volatile bool mouseEvent = false;
|
||||||
|
uint8_t buttons = 0;
|
||||||
|
int mouseX = 0;
|
||||||
|
int mouseY = 0;
|
||||||
|
int wheel = 0;
|
||||||
|
int wheelH = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
class MouseController : public USBDriver {
|
class MouseController : public USBDriver {
|
||||||
public:
|
public:
|
||||||
MouseController(USBHost &host) { init(); }
|
MouseController(USBHost &host) { init(); }
|
||||||
|
@ -743,5 +771,7 @@ private:
|
||||||
Pipe_t mypipes[2] __attribute__ ((aligned(32)));
|
Pipe_t mypipes[2] __attribute__ ((aligned(32)));
|
||||||
Transfer_t mytransfers[4] __attribute__ ((aligned(32)));
|
Transfer_t mytransfers[4] __attribute__ ((aligned(32)));
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,33 +10,40 @@ USBHub hub2(myusb);
|
||||||
USBHub hub3(myusb);
|
USBHub hub3(myusb);
|
||||||
KeyboardController keyboard1(myusb);
|
KeyboardController keyboard1(myusb);
|
||||||
KeyboardController keyboard2(myusb);
|
KeyboardController keyboard2(myusb);
|
||||||
|
USBHIDParser hid1(myusb);
|
||||||
|
USBHIDParser hid2(myusb);
|
||||||
|
USBHIDParser hid3(myusb);
|
||||||
|
USBHIDParser hid4(myusb);
|
||||||
|
USBHIDParser hid5(myusb);
|
||||||
MouseController mouse1(myusb);
|
MouseController mouse1(myusb);
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
while (!Serial) ; // wait for Arduino Serial Monitor
|
while (!Serial) ; // wait for Arduino Serial Monitor
|
||||||
Serial.println("USB Host Testing");
|
Serial.println("USB Host Testing");
|
||||||
myusb.begin();
|
myusb.begin();
|
||||||
keyboard1.attachPress(OnPress);
|
keyboard1.attachPress(OnPress);
|
||||||
keyboard2.attachPress(OnPress);
|
keyboard2.attachPress(OnPress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
myusb.Task();
|
myusb.Task();
|
||||||
if(mouse1.available()) {
|
if(mouse1.available()) {
|
||||||
Serial.print("buttons = ");
|
Serial.print("buttons = ");
|
||||||
Serial.print(mouse1.getButtons(),DEC);
|
Serial.print(mouse1.getButtons());
|
||||||
Serial.print(", wheel = ");
|
|
||||||
Serial.print(mouse1.getWheel(),DEC);
|
|
||||||
Serial.print(", mouseX = ");
|
Serial.print(", mouseX = ");
|
||||||
Serial.print(mouse1.getMouseX(),DEC);
|
Serial.print(mouse1.getMouseX());
|
||||||
Serial.print(", mouseY = ");
|
Serial.print(", mouseY = ");
|
||||||
Serial.println(mouse1.getMouseY(),DEC);
|
Serial.print(mouse1.getMouseY());
|
||||||
|
Serial.print(", wheel = ");
|
||||||
|
Serial.print(mouse1.getWheel());
|
||||||
|
Serial.print(", wheelH = ");
|
||||||
|
Serial.print(mouse1.getWheelH());
|
||||||
|
Serial.println();
|
||||||
mouse1.mouseDataClear();
|
mouse1.mouseDataClear();
|
||||||
}
|
}
|
||||||
delay(50);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
21
hid.cpp
21
hid.cpp
|
@ -288,17 +288,17 @@ void USBHIDParser::parse()
|
||||||
// This is a list of all the drivers inherited from the USBHIDInput class.
|
// This is a list of all the drivers inherited from the USBHIDInput class.
|
||||||
// Unlike the list of USBDriver (managed in enumeration.cpp), drivers stay
|
// Unlike the list of USBDriver (managed in enumeration.cpp), drivers stay
|
||||||
// on this list even when they have claimed a top level collection.
|
// on this list even when they have claimed a top level collection.
|
||||||
USBHIDInput * USBHIDInput::list = NULL;
|
USBHIDInput * USBHIDParser::available_hid_drivers_list = NULL;
|
||||||
|
|
||||||
USBHIDInput::USBHIDInput()
|
void USBHIDParser::driver_ready_for_hid_collection(USBHIDInput *driver)
|
||||||
{
|
{
|
||||||
next = NULL;
|
driver->next = NULL;
|
||||||
if (list == NULL) {
|
if (available_hid_drivers_list == NULL) {
|
||||||
list = this;
|
available_hid_drivers_list = driver;
|
||||||
} else {
|
} else {
|
||||||
USBHIDInput *last = list;
|
USBHIDInput *last = available_hid_drivers_list;
|
||||||
while (last->next) last = last->next;
|
while (last->next) last = last->next;
|
||||||
last->next = this;
|
last->next = driver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,8 +307,10 @@ USBHIDInput::USBHIDInput()
|
||||||
// collection is returned, or NULL if no driver wants it.
|
// collection is returned, or NULL if no driver wants it.
|
||||||
USBHIDInput * USBHIDParser::find_driver(uint32_t topusage)
|
USBHIDInput * USBHIDParser::find_driver(uint32_t topusage)
|
||||||
{
|
{
|
||||||
USBHIDInput *driver = USBHIDInput::list;
|
println("find_driver");
|
||||||
|
USBHIDInput *driver = available_hid_drivers_list;
|
||||||
while (driver) {
|
while (driver) {
|
||||||
|
println(" driver ", (uint32_t)driver, HEX);
|
||||||
if (driver->claim_collection(device, topusage)) {
|
if (driver->claim_collection(device, topusage)) {
|
||||||
return driver;
|
return driver;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +369,7 @@ void USBHIDParser::parse(uint16_t type_and_report_id, const uint8_t *data, uint3
|
||||||
uint32_t topusage = 0;
|
uint32_t topusage = 0;
|
||||||
uint8_t topusage_index = 0;
|
uint8_t topusage_index = 0;
|
||||||
uint8_t collection_level = 0;
|
uint8_t collection_level = 0;
|
||||||
uint8_t usage[USAGE_LIST_LEN] = {0, 0};
|
uint16_t usage[USAGE_LIST_LEN] = {0, 0};
|
||||||
uint8_t usage_count = 0;
|
uint8_t usage_count = 0;
|
||||||
uint8_t report_id = 0;
|
uint8_t report_id = 0;
|
||||||
uint16_t report_size = 0;
|
uint16_t report_size = 0;
|
||||||
|
@ -392,6 +394,7 @@ void USBHIDParser::parse(uint16_t type_and_report_id, const uint8_t *data, uint3
|
||||||
p += 2;
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case 2: val = p[1] | (p[2] << 8);
|
case 2: val = p[1] | (p[2] << 8);
|
||||||
|
println("val16 = ", val, HEX);
|
||||||
p += 3;
|
p += 3;
|
||||||
break;
|
break;
|
||||||
case 3: val = p[1] | (p[2] << 8) | (p[3] << 16) | (p[4] << 24);
|
case 3: val = p[1] | (p[2] << 8) | (p[3] << 16) | (p[4] << 24);
|
||||||
|
|
84
mouse.cpp
84
mouse.cpp
|
@ -24,6 +24,81 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "USBHost_t36.h" // Read this header first for key info
|
#include "USBHost_t36.h" // Read this header first for key info
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
|
||||||
|
bool MouseController::claim_collection(Device_t *dev, uint32_t topusage)
|
||||||
|
{
|
||||||
|
// only claim Desktop/Mouse
|
||||||
|
if (topusage != 0x10002) return false;
|
||||||
|
// only claim from one physical device
|
||||||
|
if (mydevice != NULL && dev != mydevice) return false;
|
||||||
|
mydevice = dev;
|
||||||
|
collections_claimed++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseController::disconnect_collection(Device_t *dev)
|
||||||
|
{
|
||||||
|
if (--collections_claimed == 0) {
|
||||||
|
mydevice = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseController::hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax)
|
||||||
|
{
|
||||||
|
// TODO: check if absolute coordinates
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseController::hid_input_data(uint32_t usage, int32_t value)
|
||||||
|
{
|
||||||
|
//Serial.printf("Mouse: usage=%X, value=%d\n", usage, value);
|
||||||
|
uint32_t usage_page = usage >> 16;
|
||||||
|
usage &= 0xFFFF;
|
||||||
|
if (usage_page == 9 && usage >= 1 && usage <= 8) {
|
||||||
|
if (value == 0) {
|
||||||
|
buttons &= ~(1 << (usage -1));
|
||||||
|
} else {
|
||||||
|
buttons |= (1 << (usage -1));
|
||||||
|
}
|
||||||
|
} else if (usage_page == 1) {
|
||||||
|
switch (usage) {
|
||||||
|
case 0x30:
|
||||||
|
mouseX = value;
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
mouseY = value;
|
||||||
|
break;
|
||||||
|
case 0x32: // Apple uses this for horizontal scroll
|
||||||
|
wheelH = value;
|
||||||
|
break;
|
||||||
|
case 0x38:
|
||||||
|
wheel = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (usage_page == 12) {
|
||||||
|
if (usage == 0x238) { // Microsoft uses this for horizontal scroll
|
||||||
|
wheelH = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseController::hid_input_end()
|
||||||
|
{
|
||||||
|
mouseEvent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseController::mouseDataClear() {
|
||||||
|
mouseEvent = false;
|
||||||
|
buttons = 0;
|
||||||
|
mouseX = 0;
|
||||||
|
mouseY = 0;
|
||||||
|
wheel = 0;
|
||||||
|
wheelH = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
void MouseController::init()
|
void MouseController::init()
|
||||||
{
|
{
|
||||||
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
|
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
|
||||||
|
@ -59,8 +134,8 @@ bool MouseController::claim(Device_t *dev, int type, const uint8_t *descriptors,
|
||||||
println("descriptors[23] = ",descriptors[23]);
|
println("descriptors[23] = ",descriptors[23]);
|
||||||
println("packet size(mouse) = ", size);
|
println("packet size(mouse) = ", size);
|
||||||
// packey size seems to be 20 for (wireless type 2) or 6 bytes for wired
|
// packey size seems to be 20 for (wireless type 2) or 6 bytes for wired
|
||||||
packetSize = size;
|
packetSize = size;
|
||||||
if ((size != 20) && (size != 6)) return false;
|
if ((size != 20) && (size != 6)) return false;
|
||||||
if(packetSize == 6) packetSize = 8; // Minimum packet size needed is 8
|
if(packetSize == 6) packetSize = 8; // Minimum packet size needed is 8
|
||||||
uint32_t interval = descriptors[24];
|
uint32_t interval = descriptors[24];
|
||||||
println("polling interval = ", interval);
|
println("polling interval = ", interval);
|
||||||
|
@ -129,7 +204,7 @@ void MouseController::new_data(const Transfer_t *transfer)
|
||||||
//
|
//
|
||||||
// Wireless Logitech mouse reports have byte 0 set to 0x02 indicating a type 2 report.
|
// Wireless Logitech mouse reports have byte 0 set to 0x02 indicating a type 2 report.
|
||||||
// Not sure what this really means yet but all bytes of the report packet are shifted
|
// Not sure what this really means yet but all bytes of the report packet are shifted
|
||||||
// ahead by one byte and there is a single byte that is always zero after the button
|
// ahead by one byte and there is a single byte that is always zero after the button
|
||||||
// report byte.
|
// report byte.
|
||||||
|
|
||||||
if(packetSize == 20) {
|
if(packetSize == 20) {
|
||||||
|
@ -155,4 +230,5 @@ void MouseController::mouseDataClear() {
|
||||||
mouseY = 0;
|
mouseY = 0;
|
||||||
wheel = 0;
|
wheel = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue