Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 19 of 19

Thread: Setup USB Host to talk with hub with two FTDI serial devices

  1. #1
    Junior Member
    Join Date
    Oct 2020
    Posts
    10

    Setup USB Host to talk with hub with two FTDI serial devices

    Hey. Have a device with an usb port that, when connected to windows, shows up as two COM devices that are running on the FTDI driver. How would I setup a application to be able to talk to these serial devices though the USB Host on the Teensy 4.1?
    Where do I start?

    Best Regards
    Martin
    Last edited by myhrmans; 10-05-2020 at 11:52 AM.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,976
    You would use the USBHost_t36 library. In Arduino, click File > Examples > USBHost_t36 > Test > SerialTest to get started.

    At the beginning of your program, you create a list of the USB devices your program will be able to support. You would need to create at least 1 USBHub and at least 2 USBSerial instances.

    Most USB hubs with more than 4 ports are internally made from multiple 4 port hubs, so plan on using more than 1 USBHub instance if you want to support larger hubs.

  3. #3
    Junior Member
    Join Date
    Oct 2020
    Posts
    10
    Quote Originally Posted by PaulStoffregen View Post
    You would use the USBHost_t36 library. In Arduino, click File > Examples > USBHost_t36 > Test > SerialTest to get started.

    At the beginning of your program, you create a list of the USB devices your program will be able to support. You would need to create at least 1 USBHub and at least 2 USBSerial instances.

    Most USB hubs with more than 4 ports are internally made from multiple 4 port hubs, so plan on using more than 1 USBHub instance if you want to support larger hubs.
    Cool. Yeah tried that but I believe our FTDI chip is not supported currently by the USBSerial class:
    Vid=403 pid=6010
    I believe it's the same as the current supported one. Where do I start when implementing this protocol?
    Thanks.

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    If it does not work without it, you might simply try adding a line to serial.cpp in the usb host library:
    Code:
    USBSerial::product_vendor_mapping_t USBSerial::pid_vid_mapping[] = {
    	// FTDI mappings. 
    	{0x0403, 0x6001, USBSerial::FTDI},
    	{0x0403, 0x6010, USBSerial::FTDI},
    
    	// PL2303
    ...

  5. #5
    Junior Member
    Join Date
    Oct 2020
    Posts
    10
    Yeah tried that. Also changed the rx and tx endpoints to match the maximum data from 64 to 512 bytes. It does connect now but the sending never flushes. I checked the code and for a composite device it looks like the implementation is very specific.

  6. #6
    Junior Member
    Join Date
    Oct 2020
    Posts
    10
    The FTDI is the FTDI 2232h

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,976
    We'll probably need to add a "big buffer" version of serial to someday support this, like we do for MIDI.

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    You might be able to uncomment the line: //#define USBHOST_PRINT_DEBUG

    in the usbhost_t36.h file to get additional debug output.

    May have to debug... Probably someone who has one will need to debug... Which device do you have?

  9. #9
    Junior Member
    Join Date
    Oct 2020
    Posts
    10
    Teensy 4.1, or are we talking about the other device?

  10. #10
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    The other device. Your post #1 mentioned that it was a T4.1.
    Something like: https://smile.amazon.com/FTDI-Breako...dp/B06XGGGMB7/ ?

  11. #11
    Junior Member
    Join Date
    Oct 2020
    Posts
    10
    Quote Originally Posted by KurtE View Post
    The other device. Your post #1 mentioned that it was a T4.1.
    Something like: https://smile.amazon.com/FTDI-Breako...dp/B06XGGGMB7/ ?
    Ah yes. Something like that, correct.

  12. #12
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    Quick update,

    I received one of the devices I mentioned, and first quick information from linux system about the device.
    Code:
    kurt@kurt-XPS-8300:~/Desktop/arduino-1.8.13$ lsusb
    Bus 002 Device 003: ID 18e3:9106 Fitipower Integrated Technology Inc 
    Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 010: ID 413c:2006 Dell Computer Corp. 
    Bus 001 Device 009: ID 413c:1004 Dell Computer Corp. 
    Bus 001 Device 011: ID 0403:8088 Future Technology Devices International, Ltd 
    Bus 001 Device 006: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
    Bus 001 Device 003: ID 045e:07a5 Microsoft Corp. Wireless Receiver 1461C
    Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    kurt@kurt-XPS-8300:~/Desktop/arduino-1.8.13$ lsusb -v -d 0403:8088
    
    Bus 001 Device 011: ID 0403:8088 Future Technology Devices International, Ltd 
    Couldn't open device, some information will be missing
    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               2.00
      bDeviceClass            0 
      bDeviceSubClass         0 
      bDeviceProtocol         0 
      bMaxPacketSize0        64
      idVendor           0x0403 Future Technology Devices International, Ltd
      idProduct          0x8088 
      bcdDevice            7.00
      iManufacturer           1 
      iProduct                2 
      iSerial                 3 
      bNumConfigurations      1
      Configuration Descriptor:
        bLength                 9
        bDescriptorType         2
        wTotalLength       0x0037
        bNumInterfaces          2
        bConfigurationValue     1
        iConfiguration          0 
        bmAttributes         0xa0
          (Bus Powered)
          Remote Wakeup
        MaxPower              500mA
        Interface Descriptor:
          bLength                 9
          bDescriptorType         4
          bInterfaceNumber        0
          bAlternateSetting       0
          bNumEndpoints           2
          bInterfaceClass       255 Vendor Specific Class
          bInterfaceSubClass    255 Vendor Specific Subclass
          bInterfaceProtocol    255 Vendor Specific Protocol
          iInterface              2 
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x81  EP 1 IN
            bmAttributes            2
              Transfer Type            Bulk
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0200  1x 512 bytes
            bInterval               0
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x02  EP 2 OUT
            bmAttributes            2
              Transfer Type            Bulk
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0200  1x 512 bytes
            bInterval               0
        Interface Descriptor:
          bLength                 9
          bDescriptorType         4
          bInterfaceNumber        1
          bAlternateSetting       0
          bNumEndpoints           2
          bInterfaceClass       255 Vendor Specific Class
          bInterfaceSubClass    255 Vendor Specific Subclass
          bInterfaceProtocol    255 Vendor Specific Protocol
          iInterface              2 
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x83  EP 3 IN
            bmAttributes            2
              Transfer Type            Bulk
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0200  1x 512 bytes
            bInterval               0
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x04  EP 4 OUT
            bmAttributes            2
              Transfer Type            Bulk
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0200  1x 512 bytes
            bInterval               0
    And details from dmesg
    Code:
    [  921.793325] usb 1-1.4.2: new high-speed USB device number 11 using ehci-pci
    [  921.907610] usb 1-1.4.2: New USB device found, idVendor=0403, idProduct=8088, bcdDevice= 7.00
    [  921.907614] usb 1-1.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [  921.907616] usb 1-1.4.2: Product: EPT USB <-> Serial&JTAG Cable
    [  921.907618] usb 1-1.4.2: Manufacturer: EPT
    [  921.907619] usb 1-1.4.2: SerialNumber: EPT53HOOF

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    Quote Originally Posted by PaulStoffregen View Post
    We'll probably need to add a "big buffer" version of serial to someday support this, like we do for MIDI.
    Yes probably as a minimum as it shows:
    Code:
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x81  EP 1 IN
            bmAttributes            2
              Transfer Type            Bulk
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0200  1x 512 bytes
            bInterval               0
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x02  EP 2 OUT
            bmAttributes            2
              Transfer Type            Bulk
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0200  1x 512 bytes
            bInterval               0
    Current code bails if sizes > 64

  14. #14
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    @myhrmans - I am not sure if you are still interested or waching.

    I have stated a branch: https://github.com/KurtE/USBHost_t36...rial_BigBuffer

    Where I have the beginnings of a bigbuffer class. I am at least now able to echo stuff out on the first channel of it (J1 pin 7 to 10) and test sketch is getting the data back...

    I still have debug turned on... Will now try to see if I have two of these objects if it gets both...

    Test sketch so far... Nothing special.
    Code:
    // Simple test of USB Host Mouse/Keyboard
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    #define USBBAUD 115200
    uint32_t baud = USBBAUD;
    uint32_t format = USBHOST_SERIAL_8N1;
    USBHost myusb;
    USBHub hub1(myusb);
    USBHub hub2(myusb);
    USBHIDParser hid1(myusb);
    USBHIDParser hid2(myusb);
    USBHIDParser hid3(myusb);
    USBSerial userial(myusb);
    USBSerial_BigBuffer userialb(myusb);
    
    USBDriver *drivers[] = {&hub1, &hub2, &hid1, &hid2, &hid3, &userial, &userialb};
    #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
    const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2",  "HID1", "HID2", "HID3", "USERIAL1", "USERIALB" };
    bool driver_active[CNT_DEVICES] = {false, false, false, false};
    
    void setup()
    {
      pinMode(13, OUTPUT);
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      for (int i = 0; i < 5; i++) {
        digitalWrite(2, HIGH);
        delayMicroseconds(50);
        digitalWrite(2, LOW);
        delayMicroseconds(50);
      }
      while (!Serial && (millis() < 5000)) ; // wait for Arduino Serial Monitor
      Serial.println("\n\nUSB Host Testing - Serial");
      myusb.begin();
      Serial1.begin(115200);  // We will echo stuff Through Serial1...
    
    }
    
    
    void loop()
    {
      digitalWrite(13, !digitalRead(13));
      myusb.Task();
    
      updateDeviceList();
    
      if (Serial.available()) {
        Serial.println("Serial Available");
        while (Serial.available()) {
          int ch = Serial.read();
          if (ch == '#') {
            // Lets see if we have a baud rate specified here...
            uint32_t new_baud = 0;
            for (;;) {
              ch = Serial.read();
              if ((ch < '0') || (ch > '9'))
                break;
              new_baud = new_baud * 10 + ch - '0';
            }
            // See if the user is specifying a format: 8n1, 7e1, 7e2, 8n2
            // Note this is Quick and very dirty code...
            //
            if (ch == ',') {
              char command_line[10];
              ch = Serial.read();
              while (ch == ' ') Serial.read();  // ignore any spaces.
              uint8_t cb = 0;
              while ((ch > ' ') && (cb < sizeof(command_line))) {
                command_line[cb++] = ch;
                ch = Serial.read();
              }
              command_line[cb] = '\0';
              if (CompareStrings(command_line, "8N1")) format = USBHOST_SERIAL_8N1;
              else if (CompareStrings(command_line, "8N2")) format = USBHOST_SERIAL_8N2;
              else if (CompareStrings(command_line, "7E1")) format = USBHOST_SERIAL_7E1;
              else if (CompareStrings(command_line, "7O1")) format = USBHOST_SERIAL_7O1;
            }
            Serial.println("\n*** Set new Baud command ***\n  do userial.end()");
            digitalWriteFast(2, HIGH);
            userial.end();  // Do the end statement;
            digitalWriteFast(2, LOW);
            if (new_baud) {
              baud = new_baud;
              Serial.print("  New Baud: ");
              Serial.println(baud);
              Serial.print("  Format: ");
              Serial.println(format, HEX);
              digitalWriteFast(3, HIGH);
              userial.begin(baud, format);
              digitalWriteFast(3, LOW);
              Serial.println("  Completed ");
    
              Serial1.end();
              Serial1.begin(baud, format);
    
            } else {
              Serial.println("  New Baud 0 - leave disabled");
            }
    
            while (Serial.read() != -1);
          } else {
            if (userial)userial.write(ch);
            if (userialb)userialb.write(ch);
          }
        }
      }
    
      while (Serial1.available()) {
        //    Serial.println("Serial1 Available");
        Serial1.write(Serial1.read());
      }
    
      while (userial.available()) {
        //    Serial.println("USerial Available");
    
        Serial.write(userial.read());
      }
      while (userialb.available()) {
        //    Serial.println("USerialb Available");
    
        Serial.write(userialb.read());
      }
    }
    
    void updateDeviceList() {
      // Print out information about different devices.
      for (uint8_t i = 0; i < CNT_DEVICES; i++) {
        if (*drivers[i] != driver_active[i]) {
          if (driver_active[i]) {
            Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
            driver_active[i] = false;
          } else {
            Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
            driver_active[i] = true;
    
            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);
            psz = drivers[i]->serialNumber();
            if (psz && *psz) Serial.printf("  Serial: %s\n", psz);
    
            // If this is a new Serial device.
            if (drivers[i] == &userial) {
              // Lets try first outputting something to our USerial to see if it will go out...
              userial.begin(baud);
            }
          }
        }
      }
    
    }
    
    
    bool CompareStrings(const char *sz1, const char *sz2) {
      while (*sz2 != 0) {
        if (toupper(*sz1) != toupper(*sz2))
          return false;
        sz1++;
        sz2++;
      }
      return true; // end of string so show as match
    
    
    }

  15. #15
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    @All - To properly support this or similar devices, is a little more complicated.

    That is the current branch as I have pushed up for the previous post is a somewhat minimal change. It simply allows for the larger buffer. By moving the "BigBuffer" into the sub classes, where the TX and RX buffers than grab their space from. So the subclass constructor passes in pointer, plus size and also constraints on how big or small the RX or TX can be... My test case appeared to be able to talk to the first Serial object of the device.

    BUT - A couple of issues.

    a) I am not an FTDI expert and know if there are any differences in the messages and the like needed to properly internally configure the device and how different it is or isn't to our run of the mill FTDI device, especially since for example Window 10 will complain that it has no driver for it... Have not tried yet to see if Linux knows much about it.

    b) Something that I have started to address and if anyone wishes to help test... - In most cases, the USB Host Serial code currently claims the device at the device level. So once it sees the VID:PID of the device, it then verifies that it understands the first interface and then it claims it.... So it never looks at the 2nd interface and as such we don't do anything with that 2nd interface.

    There was an earlier case where we had composite device with Serial, that is code to handle. I believe an example was Teensy that did lets say Serial and Midi....

    So: I now have a version of the code which I push up that rearranges a lot of the code in the USBSerialBase::claim code where I now updated the VID:PID mapping table to have an additional field, to say when to try to claim (0=Device, 1=interface), it still has some hard coded testing device class 2 SubClass 0 at the start and only process on type==0...

    But in addition, I tried to fold in the code that if we were on the Interface level, there was another duplication of code to see if we have that composite device and the Interface was of the proper format.... Then bind at the interface into the main part of the code, that when it does not find the device in the table and we are at interface level than check interface for proper CDCACM stuff...

    With these current updates, My hacked up test case did appear to bind to both Interfaces. I had 2 BigBuffer Serial objects and they claimed both.
    So far I can talk to first. The 2nd one went through the initialization phase, but not sure if any data is going through...
    But then not sure what to expect as this device is named a Serial/JTAG device. So not sure if there is some internal configuration of device...
    Code:
    USB Host Testing - Serial
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20008000
    periodictable = 20008000
    port change: 10001803
        connect
      begin reset
    port change: 18001205
      port enabled
      end recovery
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 00 02 00 00 00 40 03 04 88 80 00 07 01 02 03 01 
        VendorID = 0403, ProductID = 8088, Version = 0700
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer: EPT
    enumeration:
    Product: EPT USB <-> Serial&JTAG Cable
    enumeration:
    Serial Number: EPT53HOOF
    enumeration:
    Config data length = 55
    enumeration:
    Configuration Descriptor:
      09 02 37 00 02 01 00 A0 FA 
        NumInterfaces = 2
        ConfigurationValue = 1
      09 04 00 00 02 FF FF FF 02 
        Interface = 0
        Number of endpoints = 2
        Class/Subclass/Protocol = 255 / 255 / 255
      07 05 81 02 00 02 00 
        Endpoint = 1 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      07 05 02 02 00 02 00 
        Endpoint = 2 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      09 04 01 00 02 FF FF FF 02 
        Interface = 1
        Number of endpoints = 2
        Class/Subclass/Protocol = 255 / 255 / 255
      07 05 83 02 00 02 00 
        Endpoint = 3 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      07 05 04 02 00 02 00 
        Endpoint = 4 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
    enumeration:
    USBHub memory usage = 960
    USBHub claim_device this=20005960
    USBHub memory usage = 960
    USBHub claim_device this=20005D20
    HIDParser claim this=20004700
    HIDParser claim this=20004D20
    HIDParser claim this=20005340
    USBSerial(64)claim this=200040A0
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 02 FF FF FF 02 07 05 81 02 00 02 00 07 05 02 02 00 02 00 09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    Serial device wants to map at interface level
    USBSerial(512)claim this=20002CE0
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 02 FF FF FF 02 07 05 81 02 00 02 00 07 05 02 02 00 02 00 09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    Serial device wants to map at interface level
    USBSerial(512)claim this=20006100
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 02 FF FF FF 02 07 05 81 02 00 02 00 07 05 02 02 00 02 00 09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    Serial device wants to map at interface level
    Descriptor 4 = INTERFACE
    HIDParser claim this=20004700
    HIDParser claim this=20004D20
    HIDParser claim this=20005340
    USBSerial(64)claim this=200040A0
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 02 FF FF FF 02 07 05 81 02 00 02 00 07 05 02 02 00 02 00 09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    len = 46
    USBSerial(512)claim this=20002CE0
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 02 FF FF FF 02 07 05 81 02 00 02 00 07 05 02 02 00 02 00 09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    len = 46
    USBSerial, rxep=1(512), txep=2(512)
      rx buffer size:1024
      tx buffer size:1024
    new_Pipe
    new_Pipe
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    Descriptor 4 = INTERFACE
    HIDParser claim this=20004700
    HIDParser claim this=20004D20
    HIDParser claim this=20005340
    USBSerial(64)claim this=200040A0
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    len = 23
    USBSerial(512)claim this=20006100
    vid=403, pid=8088, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 01 00 02 FF FF FF 02 07 05 83 02 00 02 00 07 05 04 02 00 02 00 
    len = 23
    USBSerial, rxep=3(512), txep=4(512)
      rx buffer size:1024
      tx buffer size:1024
    new_Pipe
    new_Pipe
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    control callback (serial) F
    *** Device USERIALB 403:8088 - connected ***
      manufacturer: EPT
      product: EPT USB <-> Serial&JTAG Cable
      Serial: EPT53HOOF
    control callback (serial) F
    control callback (serial) E
    control callback (serial) E
    control callback (serial) C
    control callback (serial) C
    control callback (serial) 8
    *** Device USERIALB2 403:8088 - connected ***
      manufacturer: EPT
      product: EPT USB <-> Serial&JTAG Cable
      Serial: EPT53HOOF
    control callback (serial) E
    control callback (serial) 0
    control callback (serial) C
    control callback (serial) 8
    control callback (serial) 0
    Hacked up Test case:
    Code:
    // Simple test of USB Host Mouse/Keyboard
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    #define USBBAUD 115200
    uint32_t baud = USBBAUD;
    uint32_t format = USBHOST_SERIAL_8N1;
    USBHost myusb;
    USBHub hub1(myusb);
    USBHub hub2(myusb);
    USBHIDParser hid1(myusb);
    USBHIDParser hid2(myusb);
    USBHIDParser hid3(myusb);
    USBSerial userial(myusb);
    USBSerial_BigBuffer userialb(myusb);
    USBSerial_BigBuffer userialb2(myusb);
    
    USBDriver *drivers[] = {&hub1, &hub2, &hid1, &hid2, &hid3, &userial, &userialb, &userialb2};
    #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
    const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2",  "HID1", "HID2", "HID3", "USERIAL1", "USERIALB", "USERIALB2" };
    bool driver_active[CNT_DEVICES] = {false, false, false, false};
    
    void setup()
    {
      pinMode(13, OUTPUT);
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      for (int i = 0; i < 5; i++) {
        digitalWrite(2, HIGH);
        delayMicroseconds(50);
        digitalWrite(2, LOW);
        delayMicroseconds(50);
      }
      while (!Serial && (millis() < 5000)) ; // wait for Arduino Serial Monitor
      Serial.println("\n\nUSB Host Testing - Serial");
      myusb.begin();
      Serial1.begin(115200);  // We will echo stuff Through Serial1...
    
    }
    
    
    void loop()
    {
      digitalWrite(13, !digitalRead(13));
      myusb.Task();
    
      updateDeviceList();
    
      if (Serial.available()) {
        Serial.println("Serial Available");
        while (Serial.available()) {
          int ch = Serial.read();
          if (ch == '#') {
            // Lets see if we have a baud rate specified here...
            uint32_t new_baud = 0;
            for (;;) {
              ch = Serial.read();
              if ((ch < '0') || (ch > '9'))
                break;
              new_baud = new_baud * 10 + ch - '0';
            }
            // See if the user is specifying a format: 8n1, 7e1, 7e2, 8n2
            // Note this is Quick and very dirty code...
            //
            if (ch == ',') {
              char command_line[10];
              ch = Serial.read();
              while (ch == ' ') Serial.read();  // ignore any spaces.
              uint8_t cb = 0;
              while ((ch > ' ') && (cb < sizeof(command_line))) {
                command_line[cb++] = ch;
                ch = Serial.read();
              }
              command_line[cb] = '\0';
              if (CompareStrings(command_line, "8N1")) format = USBHOST_SERIAL_8N1;
              else if (CompareStrings(command_line, "8N2")) format = USBHOST_SERIAL_8N2;
              else if (CompareStrings(command_line, "7E1")) format = USBHOST_SERIAL_7E1;
              else if (CompareStrings(command_line, "7O1")) format = USBHOST_SERIAL_7O1;
            }
            Serial.println("\n*** Set new Baud command ***\n  do userial.end()");
            digitalWriteFast(2, HIGH);
            userial.end();  // Do the end statement;
            digitalWriteFast(2, LOW);
            if (new_baud) {
              baud = new_baud;
              Serial.print("  New Baud: ");
              Serial.println(baud);
              Serial.print("  Format: ");
              Serial.println(format, HEX);
              digitalWriteFast(3, HIGH);
              userial.begin(baud, format);
              digitalWriteFast(3, LOW);
              Serial.println("  Completed ");
    
              Serial1.end();
              Serial1.begin(baud, format);
            } else if (ch == '$') {
              while (Serial.read() != -1) ;
              while (Serial.read() == -1) {
                if (userial)userial.write("USerial");
                if (userialb)userialb.write("USerialB");
                if (userialb2)userialb2.write("UserialB2");
                delay(100);
              }
              
            } else {
              Serial.println("  New Baud 0 - leave disabled");
            }
    
            while (Serial.read() != -1);
          } else {
            if (userial)userial.write(ch);
            if (userialb)userialb.write(ch);
            if (userialb2)userialb2.write(ch);
          }
        }
      }
    
      while (Serial1.available()) {
        //    Serial.println("Serial1 Available");
        Serial1.write(Serial1.read());
      }
    
      while (userial.available()) {
        //    Serial.println("USerial Available");
        Serial.write(userial.read());
      }
      if (userialb.available()) {
        Serial.print("SB:");
        while (userialb.available()) {
          //    Serial.println("USerialb Available");
          Serial.write(userialb.read());
        }
      }
      if (userialb2.available()) {
        Serial.print("SB2:");
        while (userialb2.available()) {
          //    Serial.println("USerialb Available");
          Serial.write(userialb2.read());
        }
      }
    }
    
    void updateDeviceList() {
      // Print out information about different devices.
      for (uint8_t i = 0; i < CNT_DEVICES; i++) {
        if (*drivers[i] != driver_active[i]) {
          if (driver_active[i]) {
            Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
            driver_active[i] = false;
          } else {
            Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
            driver_active[i] = true;
    
            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);
            psz = drivers[i]->serialNumber();
            if (psz && *psz) Serial.printf("  Serial: %s\n", psz);
    
            // If this is a new Serial device.
            if (drivers[i] == &userial) {
              // Lets try first outputting something to our USerial to see if it will go out...
              userial.begin(baud);
            }
            if (drivers[i] == &userialb) {
              // Lets try first outputting something to our USerial to see if it will go out...
              userialb.begin(baud);
            }
            if (drivers[i] == &userialb2) {
              // Lets try first outputting something to our USerial to see if it will go out...
              userialb2.begin(baud);
            }
          }
        }
      }
    
    }
    
    
    bool CompareStrings(const char *sz1, const char *sz2) {
      while (*sz2 != 0) {
        if (toupper(*sz1) != toupper(*sz2))
          return false;
        sz1++;
        sz2++;
      }
      return true; // end of string so show as match
    
    
    }
    Not very special but just seeing if the basics are working... But again Not sure about how to test this 2nd port and not sure if can test if this case works.


    But wondering about some other usage cases, that I/(WE?) should probably test before I fully cleanup and see about doing Pull Request. Note: This code is based off Master branch... Did not pull in any of the updated BlueTooth...

    a) Need to pull out at least a few of the different USB to Serial devices like standard FTDI, PL2303, CH341... Probably don't need to test many as other than a little code ordering, the rest of code should not have changed.

    b) Any device that shows up as a CDCACM device - Not sure any more which devices used for this. I am not sure if Simple Teensy did this, or some AVR 8 bit boards with built in USB like Leonardo...

    c) Teensy - Could be interesting with different versions now.
    1) Like T3.x - Simple Serial
    2) T4.x - Probably did not work on released version as:
    Code:
    id=16C0, pid=483, bDeviceClass = 2, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 01 02 02 01 00 05 24 00 10 01 05 24 01 01 01 04 24 02 06 05 24 06 00 01 07 05 82 03 10 00 05 09 04 01 00 02 0A 00 00 00 07 05 03 02 00 02 00 07 05 84 02 00 02 00 
      Interface is Serial
        CS_INTERFACE - subtype: 0 10 1 - Header Functional Descriptor
        CS_INTERFACE - subtype: 1 1 1 - Call Management Functional
        CS_INTERFACE - subtype: 2 6 - Abstract Control Management
        CS_INTERFACE - subtype: 6 0 1  - union Functional
        Interface: 1
         Endpoint: 3
          tx_size = 512
         Endpoint: 84
          rx_size = 512
      exited loop rx:4, tx:3
      rx buffer size:1024
      tx buffer size:1024
    new_Pipe
    The released code does not support >64 bytes...

    3) Composite Teensy -

    4) Multi-Serial - Again maybe different for T4 vs T3...
    ...


    Now to see how badly things are broken.. I did push up the WIP ...

  16. #16
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    I may be mainly talking to myself

    For the heck of it to test with T4 with MultSerial, I created a version of the example sketch USBToSerial that allows you to build for
    USBType of Serial, Dual Serial, Triple Serial
    and for each of these setup to go to different HardwareSerial ports.

    I have tried it with simple loop back on T4, using TyCommander.

    Now to try it with connecting it to T4.1 through USB...
    Attached Files Attached Files

  17. #17
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,864
    Did some more testing... And I hope I did not break anything, but cleaned it up and issued PR:
    https://github.com/PaulStoffregen/USBHost_t36/pull/40

    At a minimum it also helps to support Two T4.x's talking to each other over USB with 512 byte transfers.

    Probably all for this now unless I hear or find something.

  18. #18
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,647
    Quote Originally Posted by KurtE View Post
    ...

    At a minimum it also helps to support Two T4.x's talking to each other over USB with 512 byte transfers.
    ...
    Nice work KurtE,
    ... wondering how fast lines per second test runs across the USBHost Serial ... will see if I can try it before you

  19. #19
    Junior Member
    Join Date
    Oct 2020
    Posts
    10
    Quote Originally Posted by KurtE View Post
    Did some more testing... And I hope I did not break anything, but cleaned it up and issued PR:
    https://github.com/PaulStoffregen/USBHost_t36/pull/40

    At a minimum it also helps to support Two T4.x's talking to each other over USB with 512 byte transfers.

    Probably all for this now unless I hear or find something.
    Cool. Will test this out and report 😁👍

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •