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

Thread: Teensy 3.6 USB host hangs on userial.begin() if device already plugged in

  1. #1
    Junior Member
    Join Date
    Oct 2019
    Location
    Tucson
    Posts
    12

    Teensy 3.6 USB host hangs on userial.begin() if device already plugged in

    Hi, I'm using a Teensy 3.6 for my Scope Clock. I provide USB host support for a GlobalSat BU-353S4 GPS puck, using the TinyGPS and USBHost_t36 libraries. This puck uses an FTDI serial to USB chip.
    The source code is on my GitHub page https://github.com/nixiebunny/SCTVcode
    My problem is that when I have the GPS puck plugged in and then power up the board, the userial.begin() call in myusb.Task() in loop() in z_main.ino hangs when the USB enumeration occurs.
    Unplugging and plugging in the GPS puck will get it unhung.

    How can I find out why this call to userial.begin() is hanging?
    I see that USBHost_t36 uses a state variable pending_control to deal with the necessary startup tasks in USBSerialBase::begin().
    How does one debug this state machine?

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    26,212
    Any idea which FTDI chip is used? Can you plug it into a PC and get the vid & pid numbers? Or edit USBHost_t36 to turn on USBHOST_PRINT_DEBUG and capture the huge amount of info it prints to the serial monitor?

  3. #3
    Junior Member
    Join Date
    Oct 2019
    Location
    Tucson
    Posts
    12
    Paul,
    Thanks for the quick reply.

    It's vid 067B pid 2303 rev 0400

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Quote Originally Posted by Nixiebunny View Post
    Paul,
    Thanks for the quick reply.

    It's vid 067B pid 2303 rev 0400
    I believe that is a PL2303 adapter and not an FTDI

    The Pid/vid is in our table, but I think I only had one variety of them ...

    Is this built into your gps puck or is it a different piece?

    Edit - ordered one from Amazon... maybe have by end of weekend...

  5. #5
    Junior Member
    Join Date
    Oct 2019
    Location
    Tucson
    Posts
    12
    Kurt,
    Thanks for looking into this. I have a pile of Teensys waiting for a solution.
    This USB chip is inside the puck. I've never seen it.

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Mine arrived...

    I did a quick and dirty updated serial test program for usb serial, below, which is printing out GPS (NMEA data)...

    At least on my TMMOD I tried it with.

    Code:
    // Simple test for receiving data from Serial 
    // like BU-353S4
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    #define USBBAUD 4800
    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);
    
    // There is now two versions of the USBSerial class, that are both derived from a common Base class
    // The difference is on how large of transfers that it can handle.  This is controlled by
    // the device descriptor, where up to now we handled those up to 64 byte USB transfers.
    // But there are now new devices that support larger transfer like 512 bytes.  This for example
    // includes the Teensy 4.x boards.  For these we need the big buffer version. 
    // uncomment one of the following defines for userial
    USBSerial userial(myusb);  // works only for those Serial devices who transfer <=64 bytes (like T3.x, FTDI...)
    //USBSerial_BigBuffer userial(myusb, 1); // Handles anything up to 512 bytes
    //USBSerial_BigBuffer userial(myusb); // Handles up to 512 but by default only for those > 64 bytes
    
    
    USBDriver *drivers[] = {&hub1, &hub2, &hid1, &hid2, &hid3, &userial};
    #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
    const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2",  "HID1", "HID2", "HID3", "USERIAL1" };
    bool driver_active[CNT_DEVICES] = {false, false, false, false};
    
    bool dump_data = false;
    uint8_t dump_col = 0;
    
    void setup()
    {
      pinMode(13, OUTPUT);
      while (!Serial && (millis() < 5000)) ; // wait for Arduino Serial Monitor
      Serial.println("\n\nUSB Host Testing - Serial");
      myusb.begin();
    }
    
    
    void loop()
    {
      digitalWrite(13, !digitalRead(13));
      myusb.Task();
      // 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 (Serial.available()) {
        int ch = Serial.read();
        if (ch == 'd') {
          dump_data = !dump_data;
          dump_col = 0;
          Serial.println();
        }
        while (Serial.read() != -1);
        Serial.printf("Paused (%u)\n", dump_data);
        while (Serial.read() == -1);
        while (Serial.read() != -1);
      }
    
      while (userial.available()) {
        int ch = userial.read();
        if (dump_data) {
          Serial.printf("%02x ", ch);
          dump_col++; 
          if (dump_col >= 32) {
            dump_col = 0;
            Serial.println();
          }
        } else {
          Serial.write(ch);
        }
      }
    }

  7. #7
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,122
    I couldn't resist the temptation to play along so I picked up a BU-353S4 from Amazon to see how it works when hooked into TinyGPS. So @KurtE and I played a bit and with a minor adjustment of the test_with_gps_device sketch we got it working:
    Code:
    USB Host Testing - Serial
    Testing TinyGPS library v. 13
    by Mikal Hart
    
    Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
              (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
    -------------------------------------------------------------------------------------------------------------------------------------
    *** Device USERIAL1 67b:2303 - connected ***
      manufacturer: Prolific Technology Inc. 
      product: USB-Serial Controller D
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0        
    5    210  xxxxxxxxxxx xxxxxxxxxx 275  02/03/2022 21:11:12 302  20.40  152.11 1.87  SSE   5554     51.30  NE    65890 380       0
    and heres the modified sketch for anyone who wants to try it:
    Code:
    // Simple test for receiving data from Serial
    // like BU-353S4
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    #define USBBAUD 4800
    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);
    
    // There is now two versions of the USBSerial class, that are both derived from a common Base class
    // The difference is on how large of transfers that it can handle.  This is controlled by
    // the device descriptor, where up to now we handled those up to 64 byte USB transfers.
    // But there are now new devices that support larger transfer like 512 bytes.  This for example
    // includes the Teensy 4.x boards.  For these we need the big buffer version.
    // uncomment one of the following defines for userial
    //USBSerial userial(myusb);  // works only for those Serial devices who transfer <=64 bytes (like T3.x, FTDI...)
    USBSerial_BigBuffer userial(myusb, 1);  // Handles anything up to 512 bytes
    //USBSerial_BigBuffer userial(myusb); // Handles up to 512 but by default only for those > 64 bytes
    
    
    USBDriver *drivers[] = { &hub1, &hub2, &hid1, &hid2, &hid3, &userial };
    #define CNT_DEVICES (sizeof(drivers) / sizeof(drivers[0]))
    const char *driver_names[CNT_DEVICES] = { "Hub1", "Hub2", "HID1", "HID2", "HID3", "USERIAL1" };
    bool driver_active[CNT_DEVICES] = { false, false, false, false };
    
    #include <TinyGPS.h>
    
    /* This sample code demonstrates the normal use of a TinyGPS object.
       It assumes that you have a 4800-baud serial GPS device hooked up
       to a serial port, or SoftwareSerial on pins 4(rx) and 3(tx).
    */
    
    TinyGPS gps;
    
    
    static void smartdelay(unsigned long ms);
    static void print_float(float val, float invalid, int len, int prec);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);
    
    void setup() {
      pinMode(13, OUTPUT);
      while (!Serial && (millis() < 5000))
        ;  // wait for Arduino Serial Monitor
      Serial.println("\n\nUSB Host Testing - Serial");
      myusb.begin();
    
      Serial.print("Testing TinyGPS library v. ");
      Serial.println(TinyGPS::library_version());
      Serial.println("by Mikal Hart");
      Serial.println();
      Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
      Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
      Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");
    }
    
    void loop() {
      float flat, flon;
      unsigned long age, chars = 0;
      unsigned short sentences = 0, failed = 0;
      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
    
      myusb.Task();
      // 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);
            }
          }
        }
      }
    
      digitalWrite(13, !digitalRead(13));
      if (userial) {
        print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
        print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
        gps.f_get_position(&flat, &flon, &age);
        print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
        print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
        print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
        print_date(gps);
        print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
        print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
        print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
        print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
        print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
        print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
        print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);
    
        gps.stats(&chars, &sentences, &failed);
        print_int(chars, 0xFFFFFFFF, 6);
        print_int(sentences, 0xFFFFFFFF, 10);
        print_int(failed, 0xFFFFFFFF, 9);
        Serial.println();
    
        smartdelay(1000);
      }
    }
    
    static void smartdelay(unsigned long ms) {
      unsigned long start = millis();
      do {
        while (userial.available())
          gps.encode(userial.read());
          myusb.Task();
      } while (millis() - start < ms);
    }
    
    static void print_float(float val, float invalid, int len, int prec) {
      if (val == invalid) {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      } else {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1);  // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3
                               : vi >= 10  ? 2
                                           : 1;
        for (int i = flen; i < len; ++i)
          Serial.print(' ');
      }
      smartdelay(0);
    }
    
    static void print_int(unsigned long val, unsigned long invalid, int len) {
      char sz[32];
      if (val == invalid) {
        strcpy(sz, "*******");
      } else {
        sprintf(sz, "%ld", val);
      }
      sz[len] = 0;
      for (int i = strlen(sz); i < len; ++i) {
        sz[i] = ' ';
      }
      if (len > 0) {
        sz[len - 1] = ' ';
      }
      Serial.print(sz);
      smartdelay(0);
    }
    
    static void print_date(TinyGPS &gps) {
      int year;
      byte month, day, hour, minute, second, hundredths;
      unsigned long age;
      gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
      if (age == TinyGPS::GPS_INVALID_AGE) {
        Serial.print("********** ******** ");
      } else {
        char sz[32];
        sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
                month, day, year, hour, minute, second);
        Serial.print(sz);
      }
      print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
      smartdelay(0);
    }
    
    static void print_str(const char *str, int len) {
      int slen = strlen(str);
      for (int i = 0; i < len; ++i) {
        Serial.print(i < slen ? str[i] : ' ');
      }
      smartdelay(0);
    }

  8. #8
    Junior Member
    Join Date
    Oct 2019
    Location
    Tucson
    Posts
    12
    Kurt,
    Hi. I apologize for the long response time, I've been dealing with various supply chain issues.
    I am glad to see that you were able to get the GPS puck and talk to it.
    My next question is if you have found a way to reproduce the problem that I am having, which is that userial.begin(baud) hangs if the GPS puck is installed on power-up.
    Last edited by Nixiebunny; 02-11-2022 at 04:20 PM.

  9. #9
    Junior Member
    Join Date
    Oct 2019
    Location
    Tucson
    Posts
    12
    I have done more testing and determined that the problem is a timing issue. I found that removing part of the splash screen text causes the clock to not hang in the userial.begin(baud) call.
    So, this leads to another question: What sort of timing issues does the Teensy USB host library have with regard to background processing?
    Can I insert some task swapping function into my display code to allow the USB code to work more reliably?
    If so, where is this documented?

  10. #10
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,122
    @Nixiebunny

    I tried the sketch in post #7 on a T3.6, cycled power several times and did very that it does hang on userial.begin but seems only to happen with me if I cycle the power on and off too quickly but that may be an issue with the gps as well not just usb

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Sorry I obviously don't have your setup with scope... So can not test your larger program.

    I did a quick look and probably the first things I would try include:

    In your main ino...

    readGPStime - I would probably have the function check if userial is valid.

    Code:
    static void readGPStime(TinyGPS &gps)
    {
      byte mon, days, hr, mins, sec, hund;
      int yrs;
    
      // bail if we don't have valid serial...
      if (!userial) {
         GPSage =TinyGPS::GPS_INVALID_AGE;
        return;
      }
          
    
      gps.crack_datetime(&yrs, &mon, &days, &hr, &mins, &sec, &hund, &GPSage);
      
      GPSHun  = hund; 
      GPSSec  = sec; 
      GPSMin  = mins;
      GPSHrs  = hr;
      GPSDay  = days;
      GPSMon  = mon;
      GPSYrs  = yrs % 100;   // remove century
      GPSCen  = yrs/100;
    }
    also in z_main.ino.
    Code:
      // Read the USB serial port if anything's there
      if (userial) {
        while (userial.available())
          myGps.encode(userial.read());
      }
    And see if that helps.

  12. #12
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,122
    deleted _ didnt work _ never got a fix
    Last edited by mjs513; 02-13-2022 at 02:10 PM.

  13. #13
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,122
    Quote Originally Posted by PaulStoffregen View Post
    Any idea which FTDI chip is used? Can you plug it into a PC and get the vid & pid numbers? Or edit USBHost_t36 to turn on USBHOST_PRINT_DEBUG and capture the huge amount of info it prints to the serial monitor?
    Just as a FYI its a Prolific PL2303 chip. The hang in userial.begin seems to be in the while loop for pending control and at least for my test sketch it is not consist when it hangs have to just power it off and on several times then you see the hang. Once I turned USB Debug on I can't seem to make it fail.
    Code:
    USB Host Testing - Serial
    sizeof Device = 36
    sizeof Pipe = 96
    sizeof Transfer = 64
    power up USBHS PHY
     reset waited 5
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 1FFF6000
    periodictable = 1FFF6000
    port change: 10001803
        connect
    Testing TinyGPS library v. 13
    by Mikal Hart
    
    Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
              (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
    -------------------------------------------------------------------------------------------------------------------------------------
      begin reset
    port change: 10001005
      port enabled
      end recovery
    new_Device: 12 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 10 01 00 00 00 40 7B 06 03 23 00 04 01 02 00 01 
        VendorID = 067B, ProductID = 2303, Version = 0400
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer: Prolific Technology Inc. 
    enumeration:
    Product: USB-Serial Controller D
    enumeration:
    Config data length = 39
    enumeration:
    Configuration Descriptor:
      09 02 27 00 01 01 00 80 32 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 03 FF 00 00 00 
        Interface = 0
        Number of endpoints = 3
        Class/Subclass/Protocol = 255 / 0 / 0
      07 05 81 03 0A 00 01 
        Endpoint = 1 IN
        Type = Interrupt
        Max Size = 10
        Polling Interval = 1
      07 05 02 02 40 00 00 
        Endpoint = 2 OUT
        Type = Bulk
        Max Size = 64
        Polling Interval = 0
      07 05 83 02 40 00 00 
        Endpoint = 3 IN
        Type = Bulk
        Max Size = 64
        Polling Interval = 0
    enumeration:
    USBHub memory usage = 960
    USBHub claim_device this=1FFF2040
    USBHub memory usage = 960
    USBHub claim_device this=1FFF2BE0
    HIDParser claim this=1FFF4380
    HIDParser claim this=1FFF2400
    HIDParser claim this=1FFF4A60
    USBSerial(512)claim this=1FFF2FA0
    vid=67B, pid=2303, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
    09 04 00 00 03 FF 00 00 00 07 05 81 03 0A 00 01 07 05 02 02 40 00 00 07 05 83 02 40 00 00 
    len = 30
    USBSerial, rxep=3(64), txep=2(64)
      rx buffer size:1920
      tx buffer size:1920
    new_Pipe
    new_Pipe
    PL2303: readRegister(0x04)
    *** Device USERIAL1 67b:2303 - connected ***
      manufacturer: Prolific Technology Inc. 
      product: USB-Serial Controller D
    control callback (serial) 3F
    PL2303: writeRegister(0x04, 0x00)
    control callback (serial) 3F
    PL2303: readRegister(0x04)
    control callback (serial) 3F
    PL2303: v1 = readRegister(0x03)
    control callback (serial) 3F
    PL2303: readRegister(0x04)
    control callback (serial) 3F
    PL2303: writeRegister(0x04, 0x01)
    control callback (serial) 3F
    PL2303: readRegister(0x04)
    control callback (serial) 3F
    PL2303: v2 = readRegister(0x03)
    control callback (serial) 3F
     PL2303 Version FF:FF
    PL2303: writeRegister(0, 1)
    control callback (serial) 3F
    PL2303: writeRegister(1, 0)
    control callback (serial) 3F
    PL2303: writeRegister(2, 44)
    control callback (serial) 3F
    PL2303: writeRegister(8, 0)
    control callback (serial) 3F
    PL2303: writeRegister(9, 0)
    control callback (serial) 3F
    PL2303: Read current Baud/control
    control callback (serial) 3E
    PL2303: Returned configuration data: 80 25 00 00 00 00 00 
    PL2303: Set baud/control: 12C0 = C0 12 00 00 00 00 08 
    control callback (serial) 3C
    PL2303: writeRegister(0, 0)
    control callback (serial) 38
    PL2303: Read current Baud/control
    PL2303: Returned configuration data: 00 00 00 00 00 00 00 
    PL2303: 0x21, 0x22, 0x3
    control callback (serial) 20
    PL2303: 0x21, 0x22, 0x3
    control callback (serial) 0
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0        
    control callback (serial) 0
    rx token: 803F8100 transfer length: 64 len:1 - 24 0
    rx: 24
    UPDATE: As soon as I turned debug off I got the failure again.
    Last edited by mjs513; 02-13-2022 at 03:31 PM. Reason: UPDATED INFO

  14. #14
    Junior Member
    Join Date
    Oct 2019
    Location
    Tucson
    Posts
    12
    Yes, those changes are good practice, and I have implemented them just now.
    However, they don't fix the userial.begin() hang problem.

    I suspect that the scope display drawing code is the source of the trouble, as it's a big chunk of code that is all run during one iteration of loop().
    I may need to restructure the drawing code so that one loop iteration does one bit of drawing rather than the whole screen.

    Does that sound like it would be worth the trouble?

  15. #15
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    We should probably put timeout in that function. Will be interesting to see which message not being handled.
    So may put simple code in loop to print out the pending_control and see which one it is stuck at.

    But got side tracked, building with IDE2, and noticed a difference in output of build:
    Code:
    "C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\teensy\\tools\\teensy-tools\\1.56.1/stdout_redirect" "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino-sketch-D4C72D10D92A5530CD4556280F104BC3/test_with_gps_device_usb.ino.sym" "C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\teensy\\tools\\teensy-compile\\1.56.1/arm/bin/arm-none-eabi-objdump" -t -C "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino-sketch-D4C72D10D92A5530CD4556280F104BC3/test_with_gps_device_usb.ino.elf"
    "C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\teensy\\tools\\teensy-tools\\1.56.1/teensy_size" "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino-sketch-D4C72D10D92A5530CD4556280F104BC3/test_with_gps_device_usb.ino.elf"
    Multiple libraries were found for "USBHost_t36.h"
      Used: D:\GitHub\USBHost_t36
      Not used: C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.56.1\libraries\USBHost_t36
    Multiple libraries were found for "TinyGPS.h"
      Used: D:\GitHub\TinyGPS
      Not used: C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.56.1\libraries\TinyGPS
    Multiple libraries were found for "SdFat.h"
      Used: D:\GitHub\SdFat
      Not used: C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.56.1\libraries\SdFat
    Using library USBHost_t36 at version 0.1 in folder: D:\GitHub\USBHost_t36 
    Using library TinyGPS in folder: D:\GitHub\TinyGPS (legacy)
    Using library SdFat at version 2.1.0 in folder: D:\GitHub\SdFat
    It is showing through the symbolic links I have in the <sketches>/libraries folder
    where for example TinyGPS would have ssaid something like:
    Using library TinyGPS in folder: C:\Users\kurte\Documents\Arduino\libraries\TinyGPS (legacy)

    So thought I should mention it up on the ide issues ... Not sure if is bad or not, would make my Sublimetext projects easier... as by default adding directory to project will also go through the link,
    unless you say in project file don't follow the link...

  16. #16
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Good morning Paul and all:

    Been debugging some and it happens if the complete initiization completes before the userial.begin() is called.

    I have hacked up the begin method:
    Code:
    void USBSerialBase::begin(uint32_t baud, uint32_t format)
    {
           // Appears the pl2303 hangs if we call and pending control is 0... try hack
           if ((pending_control == 0) && (sertype == PL2303)) {
                  Serial.printf("SBSerialBase::begin try end hack %u %u %x %x\n", sertype, setup_state, pending_control, control_queued);
                  end();
           }
           NVIC_DISABLE_IRQ(IRQ_USBHS);
           uint32_t pending_in = pending_control;
           bool cq_in = control_queued;
    
           baudrate = baud;
           bool format_changed = format != format_;
           format_ = format; 
           switch (sertype) {
                  default:
                  case CDCACM: pending_control |= 0x6; break;
                  case FTDI: pending_control |= (format_changed? 0xf : 0xe); break;  // Set BAUD, FLOW, DTR
                  case PL2303: pending_control |= 0x1e; break;  // set more stuff...
                  case CH341: pending_control |= 0x1e; break;
                  case CP210X: pending_control |= 0xf; break;
           }
           if (!control_queued) control(NULL);
           NVIC_ENABLE_IRQ(IRQ_USBHS);
           // Wait until all packets have been queued before we return to caller. 
           elapsedMillis em; 
           bool forced_yet = false;
           uint32_t pending_control_prev = 0;
           Serial.printf("USer in %u %u %x %x\n", sertype, setup_state, pending_in, cq_in);
           while (pending_control && (em < 5000)) {
                  if (pending_control != pending_control_prev) {
                         pending_control_prev = pending_control;
                         Serial.printf("USer %u %x\n", (uint32_t)em, pending_control);
                  }
                  if ((em > 250) && !forced_yet) {
                         forced_yet = true;
                         Serial.printf("USer force call to control\n");
                         control(NULL);
                  }
                  yield();      // not sure if we want to yield or what? 
           }
           if (pending_control) {
                  Serial.printf("USBSerialBase::begin timeout %u %x %u\n", (uint32_t)em, pending_control, control_queued);
           }
    
    }
    I put in code to not not hang… Also put time out in end as well… So no hang, but does not work.
    If you look at that first if… that is the case it does not work… tried to call end, still does not work… Tried forcing it to maybe send.. Finally added print outs in the
    Control as well:
    Code:
    void USBSerialBase::control(const Transfer_t *transfer)
    {
           println("control callback (serial) ", pending_control, HEX);
           Serial.printf("USerial control:callback %x %u\n", pending_control, transfer->length);
    When it does not work, I see something like:
    Code:
    USB Host Testing - Serial
    Testing TinyGPS library v. 13
    by Mikal Hart
    
    Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
              (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
    -------------------------------------------------------------------------------------------------------------------------------------
    *** Device USERIAL1 67b:2303 - connected ***
      manufacturer: Prolific Technology Inc. 
      product: USB-Serial Controller D
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3e 7
    USerial control:callback 3c 7
    USerial control:callback 38 0
    USerial control:callback 20 7
    *** Device USERIAL1 67b:2303 - connected ***
    manufacturer: Prolific Technology Inc. 
    product: USB-Serial Controller D
    SBSerialBase::begin try end hack 3 99 0 1
    USBSerialBase::end timeoutUSer in 3 99 80 1
    USer 0 9e
    USer force call to control
    USerial control:callback 9e 24265
    USer 251 9c
    USBSerialBase::begin timeout 5000 9c 1
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** *** ******* ****** *** 2162 0 0
    Note: we do not get any more callbacks after this, nor any data...

    When it does work:
    Code:
    USB Host Testing - Serial
    Testing TinyGPS library v. 13
    by Mikal Hart
    
    Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
              (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
    -------------------------------------------------------------------------------------------------------------------------------------
    *** Device USERIAL1 67b:2303 - connected ***
      manufacturer: Prolific Technology Inc. 
      product: USB-Serial Controller D
    USer in 3 1 3f 1
    USer 0 3f
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USer 13 3e
    USerial control:callback 3e 7
    USer 14 3c
    USerial control:callback 3c 7
    USer 15 38
    USerial control:callback 38 0
    USer 16 20
    USerial control:callback 20 7
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0        
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   15    0         0        
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   111   0         0        
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   251   0         0        
    9    100  48.427532 -122.622505418  02/14/2022 17:32:25 445  113.30 0.00   0.54  N     7638     34.30  NE    487   2         0        
    9    100  48.427536 -122.622505475  02/14/2022 17:32:26 498  106.80 0.00   0.41  N     7638     34.30  NE    924   5         0        
    9    100  48.427547 -122.622490224  02/14/2022 17:32:27 251  109.90 0.00   0.81  N     7638     34.30  NE    1360  8         0
    Our init code follows the same messages as the Linux driver:
    Code:
                 pl2303_vendor_read(serial, 0x8484, buf);
                  pl2303_vendor_write(serial, 0x0404, 0);
                  pl2303_vendor_read(serial, 0x8484, buf);
                  pl2303_vendor_read(serial, 0x8383, buf);
                  pl2303_vendor_read(serial, 0x8484, buf);
                  pl2303_vendor_write(serial, 0x0404, 1);
                  pl2303_vendor_read(serial, 0x8484, buf);
                  pl2303_vendor_read(serial, 0x8383, buf);
                  pl2303_vendor_write(serial, 0, 1);
                  pl2303_vendor_write(serial, 1, 0);
                  if (spriv->quirks & PL2303_QUIRK_LEGACY)
                         pl2303_vendor_write(serial, 2, 0x24);
                  else
                         pl2303_vendor_write(serial, 2, 0x44);
    And I believe we are the type 1 which is PL2303_QUIRK_LEGACY I tried changing from 44 to 24 no difference…

    B
    Code:
    ut wondering another legacy thing is: on the open we see:
                    if (spriv->quirks & PL2303_QUIRK_LEGACY) {
                                    usb_clear_halt(serial->dev, port->write_urb->pipe);
                                    usb_clear_halt(serial->dev, port->read_urb->pipe);
    So now needing to see what that might do and how to translate back to our world…

    Edit: found
    Code:
     int libusb_clear_halt(libusb_device_handle *devh, unsigned char endpoint) Clear an halt/stall for a endpoint. Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and a LIBUSB_ERROR code on failure.
    
    int libusb_reset_device(libusb_device_handle *devh) Perform an USB port reset for an usb device. Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if re-enumeration is required or if the device has been disconnected and a LIBUSB_ERROR code on failure.


    Thoughts?
    Last edited by KurtE; 02-14-2022 at 04:57 PM.

  17. #17
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Update:

    In the ISR I change to output some more state:
    Code:
    	uint32_t stat = USBHS_USBSTS;
    	USBHS_USBSTS = stat; // clear pending interrupts
    	//stat &= USBHS_USBINTR; // mask away unwanted interrupts
    #if 1
    	println();
    	println("ISR: ", stat, HEX);
    	//if (stat & USBHS_USBSTS_UI)  println(" USB Interrupt");
    	if (stat & USBHS_USBSTS_UEI) Serial.printf(" USB Error\n");
    	if (stat & USBHS_USBSTS_PCI) Serial.printf(" Port Change\n");
    	//if (stat & USBHS_USBSTS_FRI) println(" Frame List Rollover");
    	if (stat & USBHS_USBSTS_SEI) Serial.printf(" System Error\n");
    	//if (stat & USBHS_USBSTS_AAI) println(" Async Advance (doorbell)");
    	if (stat & USBHS_USBSTS_URI) Serial.printf(" Reset Recv\n");
    	//if (stat & USBHS_USBSTS_SRI) println(" SOF");
    	if (stat & USBHS_USBSTS_SLI) Serial.printf(" Suspend\n");
    	if (stat & USBHS_USBSTS_HCH) Serial.printf(" Host Halted\n");
    	//if (stat & USBHS_USBSTS_RCL) println(" Reclamation");
    	//if (stat & USBHS_USBSTS_PS)  println(" Periodic Sched En");
    	//if (stat & USBHS_USBSTS_AS)  println(" Async Sched En");
    	//if (stat & USBHS_USBSTS_NAKI) println(" NAK");
    	//if (stat & USBHS_USBSTS_UAI) println(" USB Async");
    	//if (stat & USBHS_USBSTS_UPI) println(" USB Periodic");
    	//if (stat & USBHS_USBSTS_TI0) println(" Timer0");
    	//if (stat & USBHS_USBSTS_TI1) println(" Timer1");
    #endif
    Code:
    -------------------------------------------------------------------------------------------------------------------------------------
     Port Change
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0        
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3e 7
    USerial control:callback 3c 7
    USerial control:callback 38 0
     USB Error
    USerial control:callback 20 7
    *** Device USERIAL1 67b:2303 - connected ***
      manufacturer: Prolific Technology Inc. 
      product: USB-Serial Controller D
    SBSerialBase::begin try end hack 3 99 0 1
    USBSerialBase::end timeoutUSer in 3 99 80 1
    USer 0 9e
    USer force call to control
    USerial control:callback 9e 24417
    USer 251 9c
    USBSerialBase::begin timeout 5000 9c 1
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   2162  0         0
    Notice I am getting the USB Error
    message.


    Well not sure that means anything yet as get it in the working case as well.
    Code:
     Port Change
    *** Device USERIAL1 67b:2303 - connected ***
      manufacturer: Prolific Technology Inc. 
      product: USB-Serial Controller D
    USer in 3 1 3f 1
    USer 0 3f
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 1
    USerial control:callback 3f 1
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USerial control:callback 3f 0
    USer 13 3e
    USerial control:callback 3e 7
    USer 14 3c
    USerial control:callback 3c 7
    USer 15 38
    USerial control:callback 38 0
    USer 16 20
     USB Error
    USerial control:callback 20 7
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0        
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   15    0         0        
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   94    0         0        
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   234   0         0        
    8    130  48.427509 -122.622414293  02/14/2022 18:06:05 316  115.70 ****** ***** ***   7638     34.30  NE    435   1         0        
    8    130  48.427498 -122.622406518  02/14/2022 18:06:05 546  112.90 0.00   0.93  N     7638     34.30  NE    754   4         0        
    8    130  48.427505 -122.622414348  02/14/2022 18:06:06 376  110.20 0.00   0.50  N     7638     34.30  NE    1148  6         0        
    8    130  48.427513 -122.622437786  02/14/2022 18:06:07 813  110.50 0.00   0.44  N     7638     34.30  NE    1351  8         0
    Again maybe timing..

  18. #18
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Found the problem :fingers crossed:

    Will post a fix soon...

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,327
    Pushed the changes up to my FS Integration branch: https://github.com/kurte/USBHost_t36...ntegration_MSC

    Then went back to master branch and changes over and put up new branch: https://github.com/kurte/USBHost_t36...303_begin_hang

    Created PR for that one: https://github.com/PaulStoffregen/USBHost_t36/pull/81

    Although sort of wish the pr associated with the FS Integration (#78) instead but that is different story.

  20. #20
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,122
    Quote Originally Posted by KurtE View Post
    Pushed the changes up to my FS Integration branch: https://github.com/kurte/USBHost_t36...ntegration_MSC

    Then went back to master branch and changes over and put up new branch: https://github.com/kurte/USBHost_t36...303_begin_hang

    Created PR for that one: https://github.com/PaulStoffregen/USBHost_t36/pull/81

    Although sort of wish the pr associated with the FS Integration (#78) instead but that is different story.
    Can confirm not seeing any hangs on the T3.6 with the fix.

    And yes would be nice if he pr associated with the FS Integration (#78) gets incorporated

Posting Permissions

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