mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-12-21 23:08:55 -05:00
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
|
||||
// HID input data fully decoded by the USBHIDParser driver
|
||||
class USBHIDInput {
|
||||
public:
|
||||
USBHIDInput();
|
||||
private:
|
||||
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_end();
|
||||
virtual void disconnect_collection(Device_t *dev);
|
||||
void add_to_list();
|
||||
USBHIDInput *next;
|
||||
static USBHIDInput *list;
|
||||
friend class USBHIDParser;
|
||||
};
|
||||
|
||||
@ -498,7 +496,7 @@ private:
|
||||
class USBHIDParser : public USBDriver {
|
||||
public:
|
||||
USBHIDParser(USBHost &host) { init(); }
|
||||
void driver_ready_for_hid_collection(USBHIDInput *driver);
|
||||
static void driver_ready_for_hid_collection(USBHIDInput *driver);
|
||||
protected:
|
||||
enum { TOPUSAGE_LIST_LEN = 4 };
|
||||
enum { USAGE_LIST_LEN = 12 };
|
||||
@ -517,6 +515,7 @@ protected:
|
||||
private:
|
||||
Pipe_t *in_pipe;
|
||||
Pipe_t *out_pipe;
|
||||
static USBHIDInput *available_hid_drivers_list;
|
||||
//uint32_t topusage_list[TOPUSAGE_LIST_LEN];
|
||||
USBHIDInput *topusage_drivers[TOPUSAGE_LIST_LEN];
|
||||
uint16_t in_size;
|
||||
@ -711,6 +710,35 @@ private:
|
||||
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 {
|
||||
public:
|
||||
MouseController(USBHost &host) { init(); }
|
||||
@ -743,5 +771,7 @@ private:
|
||||
Pipe_t mypipes[2] __attribute__ ((aligned(32)));
|
||||
Transfer_t mytransfers[4] __attribute__ ((aligned(32)));
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -10,33 +10,40 @@ USBHub hub2(myusb);
|
||||
USBHub hub3(myusb);
|
||||
KeyboardController keyboard1(myusb);
|
||||
KeyboardController keyboard2(myusb);
|
||||
USBHIDParser hid1(myusb);
|
||||
USBHIDParser hid2(myusb);
|
||||
USBHIDParser hid3(myusb);
|
||||
USBHIDParser hid4(myusb);
|
||||
USBHIDParser hid5(myusb);
|
||||
MouseController mouse1(myusb);
|
||||
|
||||
void setup()
|
||||
{
|
||||
while (!Serial) ; // wait for Arduino Serial Monitor
|
||||
Serial.println("USB Host Testing");
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard2.attachPress(OnPress);
|
||||
while (!Serial) ; // wait for Arduino Serial Monitor
|
||||
Serial.println("USB Host Testing");
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard2.attachPress(OnPress);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
myusb.Task();
|
||||
myusb.Task();
|
||||
if(mouse1.available()) {
|
||||
Serial.print("buttons = ");
|
||||
Serial.print(mouse1.getButtons(),DEC);
|
||||
Serial.print(", wheel = ");
|
||||
Serial.print(mouse1.getWheel(),DEC);
|
||||
Serial.print(mouse1.getButtons());
|
||||
Serial.print(", mouseX = ");
|
||||
Serial.print(mouse1.getMouseX(),DEC);
|
||||
Serial.print(mouse1.getMouseX());
|
||||
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();
|
||||
}
|
||||
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.
|
||||
// Unlike the list of USBDriver (managed in enumeration.cpp), drivers stay
|
||||
// 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;
|
||||
if (list == NULL) {
|
||||
list = this;
|
||||
driver->next = NULL;
|
||||
if (available_hid_drivers_list == NULL) {
|
||||
available_hid_drivers_list = driver;
|
||||
} else {
|
||||
USBHIDInput *last = list;
|
||||
USBHIDInput *last = available_hid_drivers_list;
|
||||
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.
|
||||
USBHIDInput * USBHIDParser::find_driver(uint32_t topusage)
|
||||
{
|
||||
USBHIDInput *driver = USBHIDInput::list;
|
||||
println("find_driver");
|
||||
USBHIDInput *driver = available_hid_drivers_list;
|
||||
while (driver) {
|
||||
println(" driver ", (uint32_t)driver, HEX);
|
||||
if (driver->claim_collection(device, topusage)) {
|
||||
return driver;
|
||||
}
|
||||
@ -367,7 +369,7 @@ void USBHIDParser::parse(uint16_t type_and_report_id, const uint8_t *data, uint3
|
||||
uint32_t topusage = 0;
|
||||
uint8_t topusage_index = 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 report_id = 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;
|
||||
break;
|
||||
case 2: val = p[1] | (p[2] << 8);
|
||||
println("val16 = ", val, HEX);
|
||||
p += 3;
|
||||
break;
|
||||
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 "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()
|
||||
{
|
||||
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("packet size(mouse) = ", size);
|
||||
// packey size seems to be 20 for (wireless type 2) or 6 bytes for wired
|
||||
packetSize = size;
|
||||
if ((size != 20) && (size != 6)) return false;
|
||||
packetSize = size;
|
||||
if ((size != 20) && (size != 6)) return false;
|
||||
if(packetSize == 6) packetSize = 8; // Minimum packet size needed is 8
|
||||
uint32_t interval = descriptors[24];
|
||||
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.
|
||||
// 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.
|
||||
|
||||
if(packetSize == 20) {
|
||||
@ -155,4 +230,5 @@ void MouseController::mouseDataClear() {
|
||||
mouseY = 0;
|
||||
wheel = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user