USBHost_t36.h multiple serial and HID, connect, disconnect?

Garug

Well-known member
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?
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:
Some documentation or help would be very Wellcome. the detection of serial stop is still a mystery, and I did not yet set multiple HID devices up, but looking what the
Code:
void HID_Input::hid_input_data(uint32_t Usage, int32_t value)
{

    Serial.print(" Usage "); Serial.print(Usage, HEX); 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;    
    }
}
provides

Code:
Begin topUsage:10000 type:6 min:-2047 max:2047
 Usage 10030 value -1
 UNKNOWN
 Usage 10031 value 1
 UNKNOWN
Begin topUsage:10000 type:6 min:-127 max:127
 Usage 10038 value 0
 UNKNOWN
Begin topUsage:10000 type:6 min:-127 max:127
 Usage C0238 value 0
 UNKNOWN
 READY Begin topUsage:10000 type:2 min:0 max:1
 Usage 90001 value 0
 Usage 90002 value 0
 Usage 90003 value 0
 Usage 90004 value 0
 Usage 90005 value 0
 Usage 90006 value 0
 Usage 90007 value 0
 Usage 90008 value 0
 Usage 90009 value 0
 Usage 9000A value 0
 Usage 9000B value 0
 Usage 9000C value 0
 Usage 9000D value 0
 Usage 9000E value 0
 Usage 9000F value 0
 Usage 90010 value 0
Begin topUsage:10000 type:6 min:-2047 max:2047
 Usage 10030 value -1
 UNKNOWN
 Usage 10031 value 0
 UNKNOWN
Begin topUsage:10000 type:6 min:-127 max:127
 Usage 10038 value 0
 UNKNOWN
Begin topUsage:10000 type:6 min:-127 max:127
 Usage C0238 value 0
 UNKNOWN
 READY

there is no problem decoding the mouse from this, and Stream deck is as easy, but I see no way to know what device is providing that data? Both Stream deck and mouse provide buttons(9000x), only mouse provides x, y, (10030, and 10031)and scroll (10038) so I could use that to define from witch it come form and mouse also seem to have (C0238) that I do not know what it is, but I do not think that is the way. An also before setting it up the current code does not support multiple HID devices at same time.... Is there any documentation?

I would rather not use any mouse or keyboard library, those I can decode and rather do that on my code, just would need some assistance setting multiple HID and Serial up at the same time, getting connection and disconnection handled correctly and how to detect what HID device is providing the data (and also to what hid device send)
 
This is the current version, Loupe deck + mouse works and provides printout (for mouse)

Code:
*******************HID UPDATE*********************** 
 x -2 y 0 s 0 b1 0 b2 0 b3 0
Begin topUsage:10000 type:2 min:0 max:1
 Usage 90001 value 0
 Usage 90002 value 0
 Usage 90003 value 0
 Usage 90004 value 0
 Usage 90005 value 0
 Usage 90006 value 0
 Usage 90007 value 0
 Usage 90008 value 0
 Usage 90009 value 0
 Usage 9000A value 0
 Usage 9000B value 0
 Usage 9000C value 0
 Usage 9000D value 0
 Usage 9000E value 0
 Usage 9000F value 0
 Usage 90010 value 0
Begin topUsage:10000 type:6 min:-2047 max:2047
 Usage 10030 value -2
 Usage 10031 value 0
Begin topUsage:10000 type:6 min:-127 max:127
 Usage 10038 value 0
Begin topUsage:10000 type:6 min:-127 max:127
 Usage C0238 value 0

Stream deck works a alone, I guess it could work also with Loupe deck if using powered USB HUB it provides printout of the buttons

Code:
 *******************HID UPDATE*********************** 
Begin topUsage:c0000 type:2 min:0 max:255
 Usage 90001 value 0
 Usage 90002 value 0
 Usage 90003 value 0
 Usage 90004 value 0
 Usage 90005 value 0
 Usage 90006 value 0
 Usage 90007 value 0
 Usage 90008 value 0
 Usage 90009 value 0
 Usage 9000A value 0
 Usage 9000B value 0
 Usage 9000C value 0
 Usage 9000D value 0
 Usage 9000E value 0
 Usage 9000F value 0
 Usage 90010 value 0

So the topUsage could be used to detect if mouse or Stream deck, is that the idea?

The current code

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;
uint8_t  USB_H_port = 0;
bool     HostSerialConnected = false;
bool     HID_updateAvailable = false;
uint8_t  StreamDeckButtons[100] = {0};


         typedef struct {
            int16_t   x[8]    = {0};
            int16_t   y[8]    = {0};
            int16_t   s[8]    = {0};
            bool      b[20]   = {0};
            bool      updated = false;
       
            } mouse_t;
            
            mouse_t mouse1; 


             


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, 1), USBSerial_BigBuffer(USB_H, 2), USBSerial_BigBuffer(USB_H, 3) };

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 HID_Input::hid_input_begin(uint32_t topUsage, uint32_t type, int lgmin, int lgmax)
{

  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)
{
    Serial.print(" Usage "); Serial.print(Usage, HEX);Serial.print(" value "); Serial.println(value);
    uint16_t Usage_page = Usage >> 16;
    Usage = Usage & 0x00ff;
    switch (Usage_page) 
       {
      
      case 0x09: { if(Usage>19) Usage = 19; 
                    StreamDeckButtons[Usage] = value & 0x00000001;
                    } break;

      case 0x01: { if(Usage == 0x30){ mouse1.x[0] = value; mouse1.updated = true;}  
                   if(Usage == 0x31){ mouse1.y[0] = value; }
                   if(Usage == 0x38){ mouse1.s[0] = value; }
                   } break;

      case 0x0C: { mouse1.updated = true;} break;

      default:   {  Serial.println(" UNKNOWN"); 
                    Serial.print(" Usage "); Serial.print(Usage, HEX); 
                    Serial.print(" value "); Serial.println(value);}   break;    
        }
}

void HID_Input::hid_input_end() 
     { 
      hid_input_begin_level_--;  
      HID_updateAvailable = true;       
      Serial.println(" *******************HID UPDATE*********************** ");
      if(mouse1.updated){ for (uint8_t i = 0; i < 20; i++) { mouse1.b[i] = StreamDeckButtons[i]; }
                          for (uint8_t i = 0; i < 7 ; i++) { mouse1.x[7-i] = mouse1.x[6-i];
                                                             mouse1.y[7-i] = mouse1.y[6-i]; 
                                                             mouse1.s[7-i] = mouse1.s[6-i];      }
                           mouse1.updated = false;
                           Serial.print(" x "); Serial.print(mouse1.x[0]);
                           Serial.print(" y "); Serial.print(mouse1.y[0]);
                           Serial.print(" s "); Serial.print(mouse1.s[0]);
                           Serial.print(" b1 "); Serial.print(mouse1.b[1]);
                           Serial.print(" b2 "); Serial.print(mouse1.b[2]);
                           Serial.print(" b3 "); Serial.print(mouse1.b[3]);
                           Serial.println();
                         }
  
      

      
      }

//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("SERIAL DISCONNECTED");
        Serial.printf("*** Device % s - disconnected ***\n", driver_names[i]);
        LoupeDeckInitialised = false;
        LoupeDeckConnected = false;
        
      } else {

        driver_active[i] = true; Serial.println("SERIAL 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; }
           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
 
I got both Stream deck and Logitech ERGO M575 working, the mouse just needed a lot of ports, I guess because it uses the Logitech wireless USB module. The connections/disconnection still needs work.

Actually connecting/disconnecting currently seems to work pretty ok, if disconnecting the USB Hub when making changes.

Word of warning, the ChatGPT can be convincing advising about USBHost_t36.h but it does not have access to it and gives totally misleading guidance.

Code:
USBHost USB_H;
USBHub hub1(USB_H);
USBHub hub2(USB_H);
USBHub hub3(USB_H);
USBHub hub4(USB_H);

HID_Input           hidin[10]     = { HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H) };
USBHIDParser        hidDev[10]    = { USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(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], &hub1, &hub2, &hub3, &hub4, &hidDev[0], &hidDev[1], &hidDev[2], &hidDev[3], &hidDev[4], &hidDev[5], &hidDev[6], &hidDev[7], &hidDev[8], &hidDev[9]};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"USB_serial0", "USB_serial1", "USB_serial2", "hub1", "hub2","hub3", "hub4", "hidDev0", "hidDev1", "hidDev2", "hidDev3", "hidDev4", "hidDev5", "hidDev6", "hidDev7", "hidDev8", "hidDev9" };
bool driver_active[CNT_DEVICES] = { false, false, false, false, false, false, false, false, false, false, false };

USBHIDInput *hiddrivers[] = {&hidin[0], &hidin[1], &hidin[2], &hidin[3], &hidin[4], &hidin[5], &hidin[6], &hidin[7], &hidin[8], &hidin[9]};
const int CNT_HIDDEVICES = sizeof(hiddrivers)/sizeof(hiddrivers[0]);
const char * hid_driver_names[CNT_HIDDEVICES] = {"hidin0", "hidin1", "hidin2", "hidin3", "hidin4", "hidin5", "hidin6", "hidin7", "hidin8", "hidin9" };
bool hid_driver_active[CNT_HIDDEVICES] = {false, false, false, false, false, false, false, false, false, false};


The connection of the Stream deck and mouse

Code:
***DRIVER CONNECTED: *** Device hub1 2109: 2813 - connected ***
  manufacturer: VIA Labs, Inc.
  product: USB2.0 Hub
***DRIVER CONNECTED: *** Device hidDev0 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver DRIVER
***DRIVER CONNECTED: *** Device hidDev1 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver DRIVER
HID_Input Claim: 46d:c52b Usage: 10002 - Yes
HID_Input Claim: 46d:c52b Usage: c0001 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: c0001 - Yes
HID_Input Claim: 46d:c52b Usage: 10080 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: 10080 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: 10080 - Yes
HID_Input Claim: 46d:c52b Usage: ffbc0088 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ffbc0088 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ffbc0088 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ffbc0088 - Yes
***HID DEVICE CONNECTED: *** HID Device hidin0 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
***HID DEVICE CONNECTED: *** HID Device hidin1 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
***HID DEVICE CONNECTED: *** HID Device hidin2 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
***HID DEVICE CONNECTED: *** HID Device hidin3 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
HID_Input Claim: 46d:c52b Usage: ff000001 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000001 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000001 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000001 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000001 - Yes
HID_Input Claim: 46d:c52b Usage: ff000002 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000002 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000002 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000002 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000002 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000002 - Yes
HID_Input Claim: 46d:c52b Usage: ff000004 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000004 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000004 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000004 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000004 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000004 - NO (Usage: 402e0000)
HID_Input Claim: 46d:c52b Usage: ff000004 - Yes
***HID DEVICE CONNECTED: *** HID Device hidin4 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
***HID DEVICE CONNECTED: *** HID Device hidin5 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
***HID DEVICE CONNECTED: *** HID Device hidin6 46d: c52b - connected ***
  manufacturer: Logitech
  product: USB Receiver
 Logitech USB Receiver HID DEVICES
***DRIVER CONNECTED: *** Device hidDev2 fd9: 60 - connected ***
  manufacturer: Elgato Systems
  product: Stream Deck
 Stream Deck DRIVER
 USB_HID_SD_port 2
  Serial: AL01H1A08927
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001- NO (Device)
HID_Input Claim: fd9:60 Usage: c0001 - Yes
***HID DEVICE CONNECTED: *** HID Device hidin7 fd9: 60 - connected ***
  manufacturer: Elgato Systems
  product: Stream Deck
 Stream Deck HID DEVICES
  Serial: AL01H1A08927
 
Last edited:
Sorry, I was not doing much monitoring up here yesterday... Sort of off doing different things.

I have found with some of the Wireless Mice or keyboards, that yes, they can consume several objects.

For example, I know we made some changes for some Logitech Mouse, whose dongle I believe used maybe 3 HID Parser objects.
Plus a Mouse and Keyboard object. That it, I believe they may use the same dongle for a mouse or keyboard or combination products.

And in the case before the Keyboard object was sending some unexpected messages...
 
About receiving the HID messages, I get them now using hid_input_begin, hid_input_data and hid_input_end() That works and using the TopUsage and Usage the parsing will be fine, but is that the way to do it. I mean is there not a way to see from what device that message was?

On this mouse decoded to x 0 y 0 s -1 b1 0 b2 0 b3 0 and second message Stream deck button 8 pressed.

Code:
Begin topUsage:10000 type:2 min:0 max:1
 Usage 90001 value 0
 Usage 90002 value 0
 Usage 90003 value 0
 Usage 90004 value 0
 Usage 90005 value 0
 Usage 90006 value 0
 Usage 90007 value 0
 Usage 90008 value 0
 Usage 90009 value 0
 Usage 9000A value 0
 Usage 9000B value 0
 Usage 9000C value 0
 Usage 9000D value 0
 Usage 9000E value 0
 Usage 9000F value 0
 Usage 90010 value 0
Begin topUsage:10000 type:6 min:-2047 max:2047
 Usage 10030 value 0
 Usage 10031 value 0
Begin topUsage:10000 type:6 min:-127 max:127
 Usage 10038 value -1
Begin topUsage:10000 type:6 min:-127 max:127
 Usage C0238 value 0
 *******************HID UPDATE*********************** 
 x 0 y 0 s -1 b1 0 b2 0 b3 0
 *******************HID UPDATE*********************** 
 *******************HID UPDATE*********************** 
 *******************HID UPDATE*********************** 
Begin topUsage:c0000 type:2 min:0 max:255
 Usage 90001 value 0
 Usage 90002 value 0
 Usage 90003 value 0
 Usage 90004 value 0
 Usage 90005 value 0
 Usage 90006 value 0
 Usage 90007 value 0
 Usage 90008 value 1
 Usage 90009 value 0
 Usage 9000A value 0
 Usage 9000B value 0
 Usage 9000C value 0
 Usage 9000D value 0
 Usage 9000E value 0
 Usage 9000F value 0
 Usage 90010 value 0
 
Last edited:
That is the normal way the HID parser code works.

However there is a hook that some of the client code, like the RAWHID and for example some cases the Keyboard and maybe some others use.

That is, when the message comes in: the hid code will call off to the callback function: hid_process_in_data and if your code processes it and returnes TRUE,
the parsing code will not happen. For example with the Keyboard:
Code:
bool KeyboardController::hid_process_in_data(const Transfer_t *transfer)
{
	const uint8_t *buffer = (const uint8_t *)transfer->buffer;
	/*
	uint16_t len = transfer->length;
	const uint8_t *p = buffer;
	USBHDBGSerial.printf("HPID(%p, %u):", transfer->driver, len);
	  if (len > 32) len = 32;
	while (len--) USBHDBGSerial.printf(" %02X", *p++); */
	// Probably need to do some more checking of the data, but
	// first pass if length == 8 assume boot format:
	// Hoped driver would be something I could check but...
	if ((transfer->driver == driver_[0]) &&  (transfer->length == 8)) {
		/*USBHDBGSerial.printf(" (boot)\n"); */
		process_boot_keyboard_format(buffer, true);
		keyboard_uses_boot_format_  = true;
		return true;
	}
	//USBHDBGSerial.printf("\n");

	return false;
}
If we decide that it is in the standard 8 byte boot format, we process that directly. otherwise we let it go through and let the HID code parse the data.
This helped when we were adding N key rollover support. As there are a few different ways that different keyboards do that and it made sense in that case to let the HID parsing code figure it out.
 
This is more hypothetical question, but if two mice would be connected, how to tell from witch the data came from. When they are connected they could be given individual name but when HID messages come is there any way to catch that name (from the level I am doing the coding now)

I mean for sending it is kind of done like that now, when the device is connected I do catch the port and use that later when sending to that device hidDev[USB_HID_SD_port].sendPacket...

The USB Host serial connection works both directions like that.

I mean why is the hid_input_data(uint32_t Usage, int32_t value) not having Device_t *dev , would there be easy way to have that?
 
I connected also wireless 3D connexion and needed to at some more devices :)

But with this there is some problems, it randomly succeeds to connect often hangs or crashes and despite more ports added does not work together with the mouse.

Code:
***DRIVER CONNECTED: *** Device hub1 2109: 2813 - connected ***
  manufacturer: VIA Labs, Inc.
  product: USB2.0 Hub
***DRIVER CONNECTED: *** Device hidDev0 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
***DRIVER CONNECTED: *** Device hidDev1 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
***DRIVER CONNECTED: *** Device hidDev2 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
***DRIVER CONNECTED: *** Device hidDev3 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
***DRIVER CONNECTED: *** Device hidDev4 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
HID_Input Claim: 256f:c652 Usage: ff00ff00 - Yes
HID_Input Claim: 256f:c652 Usage: 10008 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: 10008 - Yes
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - Yes
***HID DEVICE CONNECTED: *** HID Device hidin0 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
***HID DEVICE CONNECTED: *** HID Device hidin1 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
***HID DEVICE CONNECTED: *** HID Device hidin2 256f: c652 - connected ***
  manufacturer: 3Dconnexion
  product: 3Dconnexion Universal Receiver
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - Yes
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - Yes
 *******************HID UPDATE*********************** 
Begin topUsage:10000 type:2 min:-350 max:350
 Usage 10030 value 0
 Usage 10031 value 20
 Usage 10032 value 61
 Usage 10033 value 0
 Usage 10034 value 0
 Usage 10035 value 20
 *******************HID UPDATE*********************** 
 x 0 y 20 s 0 b1 0 b2 0 b3 0
 *******************HID UPDATE*********************** 
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - Yes
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - NO (Usage: 402e0000)
HID_Input Claim: 256f:c652 Usage: ff0a0001 - Yes
 *******************HID UPDATE*********************** 
Begin topUsage:10000 type:2 min:-350 max:350
 Usage 10030 value 0
 Usage 10031 value 0
 Usage 10032 value 0
 Usage 10033 value 0
 Usage 10034 value 0
 Usage 10035 value 0
 *******************HID UPDATE*********************** 
 x 0 y 0 s 0 b1 0 b2 0 b3 0
 *******************HID UPDATE*********************** 
 *******************HID UPDATE*********************** 
Begin topUsage:10000 type:2 min:-350 max:350
 Usage 10030 value 0
 Usage 10031 value 0
 Usage 10032 value 0
 Usage 10033 value 0
 Usage 10034 value 0
 Usage 10035 value 0

I got also an random message with it in middle of use

Code:
*******************HID UPDATE*********************** 
 *******************HID UPDATE*********************** 
Begin topUsage:10000 type:2 min:0 max:100
 Usage 60020 value 100
 UNKNOWN
 Usage 20 value 100
Begin topUsage:10000 type:2 min:0 max:1
 Usage FF000027 value 0
 UNKNOWN
 Usage 27 value 0
 *******************HID UPDATE***********************

But also this one has the same topUsage:10000 and same Usage 10030 value 0
Usage 10031 value 0 and buttons also so how to separate it from mouse if not detecting from what device the message is coming?

EDIT: Seems the 3D connexion connection problems where on my code, had not added enough driver_active , but still will not work with mouse everything hangs.

EDIT2: after adding enough devices mouse and 3D connexion and Steam deck work at the same time, there is some problems with Loupe Deck and 3Dconnexion and mouse at the same time, will see.

the 3dconnexion has Begin topUsage:10000 type:2 min:-350 max:350
and the mouse Begin topUsage:10000 type:2 min:0 max:1

So I could use min and max to detect witch one it is, but still wonder, is there no way to see the message was from 3dConnexion or mouse?
 
Last edited:
The Transfer_t mytransfers[2] __attribute__ ((aligned(32)));

What would be good size to have? In theory there might be joystick, mouse, keyboard, 3d mouse, midi device Loupedeck and/or stream deck connected at the same time?

I have now CNT_HIDDEVICES = 18; is there any harm to have it 18 other than the about 20k memory it seems to consume?
 
Last edited:
Sorry, I am distracted as I am trying to debug some of my own not related code.

Count of devices really only impacts as you mentioned amount of memory. And maybe in few cases where it walk the list of objects.
 
Ok, good thanks.

The question still, when using

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();


Is there some way to see the VID and PID of the device that send the data?

It would be so much easier knowing the device and in case multiple same type device (then should use also the serial number)

Note, I do now quite get it above when you mention the hid_process_in_data(const Transfer_t *transfer) but maybe should look in to that, maybe it provides the missing handles?


EDIT: CHatGPT keeps suggesting stuff like

Code:
void HID_Input::hid_input_data(uint32_t Usage, int32_t value)
{   
  // Get the device that provided the data
  Device_t *dev = driver_->getConnectedDevice();

  // Get the PID and VID of the device
  uint16_t pid = dev->idProduct();
  uint16_t vid = dev->idVendor();

But non of it works 'class USBHIDParser' has no member named 'getConnectedDevice'. How do I get the connected device??

Where is the Device_t defined?

And also I do not quite understand, I know the connected devices, and there is many, I need to get the PID and VID (and Serial number) of the device that sends the data.
 
Last edited:
Well some success ChatGPT can actually get the USBHost_t36.h from GitHub when told so, and provide much better responses This works, but still some problems

Code:
void HID_Input::hid_input_data(uint32_t Usage, int32_t value)
{   
  // Get the device that provided the data
  Device_t *dev = mydevice;

  // Get the PID and VID of the device
  uint16_t pid = dev->idProduct;
  uint16_t vid = dev->idVendor;
  const uint8_t *serial = USBHIDInput::serialNumber();
 
Many/Most of the HID drivers keep a back pointer to the USBHIDParser object.
This is passed to you in the claim_collection method.

Many use it to restrict their object to only dealing with one HID parser.

And for example, there is code within some classes like joystick.cpp, if you look at it,
does grab the VID/PID of this and has a table to try to map these to what type of joystick it might be.

Device_t, like most of these objects are defined in the file usbhost_t36.h
Line 92:
typedef struct Device_struct Device_t;
 
The solution was finally, well short, but took me long time to arrive there. Getting the serial number for every message was not practical due how the USBHost_t36.h is but with this I get the deviceID that is the same ID the device got when it was connected, so with that it can be identified, and actually the PID and VID are not needed here. all moved it to the hid_input_begin, no need to get it many times per message.

Code:
void HID_Input::hid_input_begin(uint32_t topUsage, uint32_t type, int lgmin, int lgmax)
{
// Get the device that provided the data
  Device_t *dev = mydevice;

  uint16_t pid = dev->idProduct;
  uint16_t vid = dev->idVendor;
  uint8_t deviceID = dev->address;

EDIT just now noticed the above form KurtE, I guess kind of the same solution, thanks.
 
There is still the problem that Loupe Deck USB disconnection goes unnoticed

This prints nothing when it is disconnected
Code:
 void HID_Input::disconnect_collection(Device_t *dev) 
     {
      if (--collections_claimed == 0) { mydevice = NULL;  Usage_ = 0; 
      Serial.println("Device disconnected!"); 
      }
     
     }

and it does not connect correctly after. It is the same if it is connected via a hub or directly.

If connected via hub and the hub is disconnected, then everything seems to go correctly and also reconnection is ok.

The Loupe Deck is a serial device.

Any ideas how to fix this?
 
EDIT, the below is maybe not relevant, just noticed that there is now the problem also with older code. I switched this morning to Arduino 2.x... oh s*** one should never do two changes at same time, it works ok with Arduino 1.8.19... After some more looking into it, the below works on the old environment, kind of, I think there is now though some different connection and disconnection problems, so will leave the below there.

****************************************

There seems to be problem with USBDriver *drivers and USBHIDInput *hiddrivers

Streamdeck uses hidDev[SD1.port].sendPacket to send data to display and hidin ( hid_input_data) to receive button presses

It all works fine if the USBDriver and USBHIDInput arrays are organised so that they do not get same index number when Stream deck is connected, but when I changed it so that they get the same index number (same number 0 , not same index) I get som glitches on display and constant printout >>>USBHIDParser:: out_data

What is going on?

I can change it back as it was, but would like to understand why organising it like this causes problems i.e &hidin[0] and &hidDev[0] have index 0 on the array. when I had first "USB_serial0", "USB_serial1", "USB_serial2", "hub1", "hub2","hub3", "hub4" and then "hidDev0" i.e "hidDev0" had index 7 it worked fine.

Code:
USBHost USB_H;
USBHub  hub1(USB_H);
USBHub  hub2(USB_H);
USBHub  hub3(USB_H);
USBHub  hub4(USB_H);

USBSerial_BigBuffer     USB_serial[3] = { USBSerial_BigBuffer(USB_H), USBSerial_BigBuffer(USB_H), USBSerial_BigBuffer(USB_H) };



HID_Input          hidin[18]          = { HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), 
                                          HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), 
                                          HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H), HID_Input(USB_H) };
                                          
USBHIDParser      hidDev[18]          = { USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H),
                                          USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H),
                                          USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H), USBHIDParser(USB_H) };

const int CNT_DEVICES = 25;
                                      
USBDriver       *drivers[CNT_DEVICES] = { &hidDev[0], &hidDev[1], &hidDev[2], &hidDev[3], &hidDev[4], &hidDev[5], 
                                          &hidDev[6], &hidDev[7], &hidDev[8], &hidDev[9], &hidDev[10], &hidDev[11],
                                          &hidDev[12], &hidDev[13], &hidDev[14], &hidDev[15], &hidDev[16], &hidDev[17],
                                          &USB_serial[0], &USB_serial[1], &USB_serial[2], &hub1, &hub2, &hub3, &hub4 };

const char* driver_names[CNT_DEVICES] = {"hidDev0", "hidDev1", "hidDev2", "hidDev3", "hidDev4", "hidDev5", 
                                         "hidDev6", "hidDev7", "hidDev8", "hidDev9", "hidDev10", "hidDev11",
                                         "hidDev12", "hidDev13", "hidDev14", "hidDev15", "hidDev16", "hidDev17",
                                         "USB_serial0", "USB_serial1", "USB_serial2", "hub1", "hub2","hub3", "hub4"
                                         };
                                          
bool       driver_active[CNT_DEVICES] = { false, false, false, false, false, false, false, 
                                          false, false, false, false, false, false, 
                                          false, false, false, false, false, false,
                                          false, false, false, false, false, false };

const int CNT_HIDDEVICES = 18;

USBHIDInput       *hiddrivers[CNT_HIDDEVICES] = {&hidin[0], &hidin[1], &hidin[2], &hidin[3], &hidin[4], &hidin[5], 
                                                 &hidin[6], &hidin[7], &hidin[8], &hidin[9], &hidin[10], &hidin[11],
                                                 &hidin[12], &hidin[13], &hidin[14], &hidin[15], &hidin[16], &hidin[17]};

const char * hid_driver_names[CNT_HIDDEVICES] = {"hidin0", "hidin1", "hidin2", "hidin3", "hidin4", "hidin5", 
                                                 "hidin6", "hidin7", "hidin8", "hidin9", "hidin10", "hidin11",
                                                 "hidin12", "hidin13", "hidin14", "hidin15", "hidin16", "hidin17" };
                                                 
bool        hid_driver_active[CNT_HIDDEVICES] = {false, false, false, false, false, false, 
                                                 false, false, false, false, false, false,
                                                 false, false, false, false, false, false};
 
Last edited:
Back
Top