Hi, I have been trying many things, I can have a HID and USB Host Serial working at the same time, but currently not two HID, With this code it is clear why as it has only one HID, lets see that a bit later, but now working detecting USB HOST serial disconnect.
I think it gets now correctly set up (and works) but disconnection is not detected. How should I detect that serial USB Host device is disconnected.
The current code, but it could be only distracting at this time. goal is to get multiple HID and USB Host serial connected using a HUB at same time, and correctly detect when the know devices are connected or disconnected. the USB_HostCheck() is constantly called from the main loop.
This detects correctly when HID device is disconnected, but not Serial?
The complete relevant code (on setup() there is USB_H.begin()
I think it gets now correctly set up (and works) but disconnection is not detected. How should I detect that serial USB Host device is disconnected.
The current code, but it could be only distracting at this time. goal is to get multiple HID and USB Host serial connected using a HUB at same time, and correctly detect when the know devices are connected or disconnected. the USB_HostCheck() is constantly called from the main loop.
This detects correctly when HID device is disconnected, but not Serial?
Code:
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
driver_active[i] = false; Serial.println("USB DEVICE DISCONNECTED");
Serial.printf("*** Device % s - disconnected ***\n", driver_names[i]);
if(LD_port == i) { LoupeDeckInitialised = false; LoupeDeckConnected = false; }
}
The complete relevant code (on setup() there is USB_H.begin()
Code:
#ifndef USBHOST_T4_H
#define USBHOST_T4_H
#include <stdint.h>
#include <USBHost_t36.h>
//these variables are currently under work
bool LoupeDeckConnected = false;
bool LoupeDeckInitialised = false;
int8_t USB_H_port = -1;
int8_t LD_port = -1;
bool HostSerialConnected = false;
bool HID_updateAvailable = false;
uint8_t StreamDeckButtons[100] = {0};
uint32_t LD_vid, LD_pid;
void USB_HostCheck();
class HID_Input : public USBHIDInput {
public:
HID_Input(USBHost &host, uint32_t Usage = 0) : fixed_Usage_(Usage) { INIT(); }
uint32_t Usage(void) {return Usage_;}
protected:
virtual hidclaim_t claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topUsage);
virtual bool hid_process_in_data(const Transfer_t *Transfer);
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:
void INIT();
USBHIDParser *driver_;
uint8_t collections_claimed = 0;
volatile int hid_input_begin_level_ = 0;
uint32_t fixed_Usage_;
uint32_t Usage_ = 0;
Transfer_t mytransfers[2] __attribute__ ((aligned(32)));
};
USBHost USB_H;
USBHub hub(USB_H);
USBHIDParser hidDev1(USB_H);
HID_Input hidin1(USB_H);
USBSerial_BigBuffer USB_serial[3] = { USBSerial_BigBuffer(USB_H), USBSerial_BigBuffer(USB_H), USBSerial_BigBuffer(USB_H) };
USBDriver *drivers[] = { &USB_serial[0], &USB_serial[1], &USB_serial[2], &hub, &hidDev1};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"USB_serial0", "USB_serial1", "USB_serial2", "Hub", "hidDev1" };
bool driver_active[CNT_DEVICES] = { false, false, false, false, false };
USBHIDInput *hiddrivers[] = {&hidin1 };
const int CNT_HIDDEVICES = sizeof(hiddrivers)/sizeof(hiddrivers[0]);
const char * hid_driver_names[CNT_HIDDEVICES] = {"hidin1" };
bool hid_driver_active[CNT_HIDDEVICES] = {false};
void HID_Input::INIT()
{
USBHost::contribute_Transfers(mytransfers, sizeof(mytransfers) / sizeof(Transfer_t));
USBHIDParser::driver_ready_for_hid_collection(this);
}
hidclaim_t HID_Input::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topUsage)
{
Serial.printf("HID_Input Claim: %x:%x Usage: %x", dev->idVendor, dev->idProduct, topUsage);
if (mydevice != NULL && dev != mydevice) {
Serial.println("- NO (Device)");
return CLAIM_NO;
}
if (Usage_ && (Usage_ != topUsage)) {
Serial.printf(" - NO (Usage: %x)\n");
return CLAIM_NO; // Only claim one?? we need multible HID + serial supported
}
mydevice = dev;
collections_claimed++;
Usage_ = topUsage;
driver_ = driver;
// Set Large Driver
uint8_t hid_tx_buffer1[8192], hid_tx_buffer2[8192];
driver_->setTXBuffers(hid_tx_buffer1, hid_tx_buffer2, 0);
Serial.println(" - Yes");
return CLAIM_INTERFACE; // We want
}
void HID_Input::disconnect_collection(Device_t *dev) {if (--collections_claimed == 0) { mydevice = NULL; Usage_ = 0; }}
bool HID_Input::hid_process_in_data(const Transfer_t *Transfer) { hid_input_begin_level_ = 0; return false;}
void indent_level(int level) { if ((level > 5) || (level < 0)) return; while (level--){ } }
void HID_Input::hid_input_begin(uint32_t topUsage, uint32_t type, int lgmin, int lgmax)
{
indent_level(hid_input_begin_level_);
Serial.printf("Begin topUsage:%x type:%x min:%d max:%d\n", topUsage, type, lgmin, lgmax);
if (hid_input_begin_level_ < 2)
hid_input_begin_level_++;
}
void HID_Input::hid_input_data(uint32_t Usage, int32_t value)
{
//handle HID incoming data from here currently just detects Stramdeck button presses (and also mouse)
indent_level(hid_input_begin_level_);
Serial.print(" Usage "); Serial.print(Usage); Serial.print(" value "); Serial.println(value);
uint16_t Usage_page = Usage >> 16;
Usage = Usage & 0x00ff;
switch (Usage_page) {
case 9: {if(Usage>99) Usage = 99; StreamDeckButtons[Usage] = value & 0x000000ff;} break;
default: Serial.println(" UNKNOWN"); break;
}
}
void HID_Input::hid_input_end() { hid_input_begin_level_--; indent_level(hid_input_begin_level_); HID_updateAvailable = true;}
//this is called frequently from the main loop
void USB_HostCheck(){
USB_H.Task();
for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
driver_active[i] = false; Serial.println("USB DEVICE DISCONNECTED");
Serial.printf("*** Device % s - disconnected ***\n", driver_names[i]);
if(LD_port == i) { LoupeDeckInitialised = false; LoupeDeckConnected = false; }
} else {
driver_active[i] = true; Serial.println("USB DEVICE CONNECTED");
Serial.printf("*** Device % s % x: % x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
const uint8_t *psz = drivers[i]->manufacturer(); if (psz && *psz) Serial.printf(" manufacturer: % s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) {Serial.printf(" product: % s\n", psz);
if(strstr((const char*)psz, "Stream Deck" ) != NULL ) { Serial.println(" PINGO2 Stream Deck CNT_DEVICES"); }
if(strstr((const char*)psz, "Loupedeck Live" ) != NULL )
{ Serial.println(" PINGO1 Loupedeck Live CNT_DEVICES");
HostSerialConnected = true; LD_port = i; USB_H_port = LD_port;
LD_vid = drivers[i]->idVendor();
LD_pid = drivers[i]->idProduct();
}
if(strstr((const char*)psz, "USB Receiver" ) != NULL ) { Serial.println(" PINGO3 Logitech USB Receiver CNT_DEVICES"); }
}
psz = drivers[i]->serialNumber(); if (psz && *psz) Serial.printf(" Serial: % s\n", psz);
// If this is a new Serial device.
if(i<3){ if (drivers[i] == &USB_serial[i])
{
USB_H_port=i; USB_serial[USB_H_port].begin(2096000, USBHOST_SERIAL_8N1 );
Serial.print("USB_serial["); Serial.print(USB_H_port); Serial.println("] started");
LoupeDeckConnected = true;
LoupeDeckInitialised = false;
} }
} } }
for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.println("HID DISCONNECTED");
Serial.printf("*** HID Device % s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
Serial.println("HID CONNECTED");
Serial.printf("*** HID Device % s % x: % x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;
const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: % s\n", psz);
psz = hiddrivers[i]->product(); if (psz && *psz) {Serial.printf(" product: % s\n", psz);
if(strstr((const char*)psz, "Stream Deck" ) != NULL ) Serial.println(" PINGO2 Stream Deck CNT_HIDDEVICES");
if(strstr((const char*)psz, "USB Receiver" ) != NULL ) Serial.println(" PINGO3 Logitech USB Receiver CNT_HIDDEVICES"); }
psz = hiddrivers[i]->serialNumber(); if (psz && *psz) Serial.printf(" Serial: % s\n", psz);
}}}
}
#endif
// maybe print out some information about some of the Usage numbers that we know about
// The information comes from the USB document, HID Usage Tables
// https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
Last edited: