Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 3 1 2 3 LastLast
Results 1 to 25 of 60

Thread: RawHID.recv() hangs after updating to Teensyduino 1.4.9 or higher for Teensy 4.0

Hybrid View

  1. #1
    Junior Member prnthp's Avatar
    Join Date
    Oct 2019
    Posts
    15

    RawHID.recv() hangs after updating to Teensyduino 1.4.9 or higher for Teensy 4.0

    Hello

    I've been having trouble receiving raw HID packets after upgrading to Teensyduino 1.4.9 or higher. I've boiled my code down to its simplest form and by simply switching from 1.4.8 to 1.4.9 or higher it hangs. It also does not respond to the magic reboot/programming packet (have to press the button to program).

    It's a simple test program that blinks the LED twice if the received packet's first byte is 0xAB. On 1.4.8 it's fine.

    My setup:
    • Teensy 4.0 (tested on two separate boards, same issue)
    • Good USB cable (tried more than one)
    • macOS 10.15.3
    • PlatformIO w/ platform=teensy@4.7.0 and higher for Teensyduino 1.4.9 +
    • PlotformIO w/ platform=teensy@4.6.0 for Teensyduino 1.4.8
    • Host side is using libusb's HIDAPI


    Code:
    #include <Arduino.h>
    
    void blink(int num);
    
    void setup() 
    {
      delay(500); // Simulate initialization
      pinMode(13, OUTPUT);
      blink(1);
    }
    
    char rx_buffer[64];
    
    void loop() 
    {
      noInterrupts();
      int n = RawHID.recv(rx_buffer, 1); 
      if (n > 0) 
      {
        if (rx_buffer[0] == 0xAB) // Signature
        {
          blink(2);
        }
      }
      interrupts();
    }
    
    void blink(int num)
    {
      for (int i = 0; i < num; i++)
      {
        digitalWrite(13, HIGH);
        delay(50);
        digitalWrite(13, LOW);
        delay(50);
      }
    }
    Thank you!

  2. #2
    I've also experienced issues with Teensy 4.0. Especially when using noInterrupts() and interrupts().

    As it stands currently, my opinion is that the Teensy 4.0 is not yet stable (maybe HID or interrupts related; note that IntervalTimer seems to be reliable as of Teensyduino 1.50).

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    @prnthp - are the issues seen with latest IDE 1.8.12 and TD 1.51? If only using PIO - there was a post in last days that it has been updated.

    @mstrthalias - Teensy 4.0 has been generally quite stable for the last year while still in Beta … of course support has been expanding across and into all areas. If there is a sketch showing something 'not yet stable' - with the latest IDE 1.8.12 and TD 1.51 please post so it can be addressed. Particularly when "noInterrupts() and interrupts()" in code odd things can happen when not properly integrated.

  4. #4
    Junior Member prnthp's Avatar
    Join Date
    Oct 2019
    Posts
    15
    Quote Originally Posted by defragster View Post
    @prnthp - are the issues seen with latest IDE 1.8.12 and TD 1.51? If only using PIO - there was a post in last days that it has been updated.
    Yes. Still hangs on both TD 1.51 and PIO teensy@4.8.0. I just double-checked right now to make sure.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Quote Originally Posted by prnthp View Post
    Yes. Still hangs on both TD 1.51 and PIO teensy@4.8.0. I just double-checked right now to make sure.
    Assuming the same would occur when built in the Arduino IDE … that code is a bit wild.

    A Teensy 4.0 can run through loop() 5+ Million times per second with minimal loading.

    How often can a RawHID message present itself - not sure if that is in excess of 1,000 per second with faster USB on T_4.0 or not?

    Not sure why noInterrupts() is needed to run that code snippet as written? Perhaps so, but it would be better to limit the noInterrupts() usage to a more reasonable number it seems - perhaps using an elapsedMillis or elapsedMicros variable to do that a mere 1,000 or 10,000 times per second as cycling the interrupts that fast will not be good for general system function.

    Code:
    elapsedMicros foo;
    loop() {
      if ( foo >= 100 )
      {
        foo=0;
        // do code here ONLY 10,000 times per second
      }
    }

  6. #6
    Junior Member prnthp's Avatar
    Join Date
    Oct 2019
    Posts
    15
    Quote Originally Posted by defragster View Post
    Assuming the same would occur when built in the Arduino IDE that code is a bit wild.

    A Teensy 4.0 can run through loop() 5+ Million times per second with minimal loading.

    How often can a RawHID message present itself - not sure if that is in excess of 1,000 per second with faster USB on T_4.0 or not?

    Not sure why noInterrupts() is needed to run that code snippet as written? Perhaps so, but it would be better to limit the noInterrupts() usage to a more reasonable number it seems - perhaps using an elapsedMillis or elapsedMicros variable to do that a mere 1,000 or 10,000 times per second as cycling the interrupts that fast will not be good for general system function.

    Code:
    elapsedMicros foo;
    loop() {
      if ( foo >= 100 )
      {
        foo=0;
        // do code here ONLY 10,000 times per second
      }
    }
    Thanks for all the help!

    I haphazardly assumed that
    Code:
    RawHID.recv(rx_buffer, 1);
    would be blocking and the 1 ms timeout would handle that issue for me, looks like it is not.

    I tried something similar to what you suggested on the toy code in the OP and it worked. However, when I implemented it on the actual project, it still hangs.

    The reason for the noInterrupts(); calls is I have an interrupt-driven (IntervalTimer) 1000 Hz PID loop that reads data structures that are updated using the HID receive calls. Since the data coming in could be over several hundred packets, I need to halt the loop momentarily.

  7. #7
    @defragster Thanks for responding. I just updated Arduino and Teensyduino and still seeing the same behavior with the Teensy 4.0.

    Unfortunately I do not have a small example to reproduce this, but the entire project can be flashed: https://github.com/mstrthealias/TeensyFanController/

    The reason I think it might relate to this thread, is because the following diff causes the project to be non-functional on the Teensy 4.0 (and I have to use hard reset to get it back):

    Code:
    diff --git a/teensy_fan_controller/src/core.h b/teensy_fan_controller/src/core.h
    index 22f151b..8509406 100644
    --- a/teensy_fan_controller/src/core.h
    +++ b/teensy_fan_controller/src/core.h
    @@ -44,7 +44,7 @@ struct FanData {
    
       uint16_t rpm = 0;
       Moving_Average<uint16_t, uint16_t, 5> rpmAvg;
    -  uint16_t pulse_counter = 0;
    +  volatile uint16_t pulse_counter = 0;
       uint8_t pct = 0;
    
       uint8_t isrPin = 0;
    diff --git a/teensy_fan_controller/src/src.ino b/teensy_fan_controller/src/src.ino
    index fc5e23e..d0bb05c 100644
    --- a/teensy_fan_controller/src/src.ino
    +++ b/teensy_fan_controller/src/src.ino
    @@ -318,6 +318,7 @@ void do_hid_send()
    
     void loop(void)
     {
    +  noInterrupts();
       if (doADC) {
         doADC = false;
         do_adc();
    @@ -351,4 +352,5 @@ void loop(void)
         doLog = false;
         do_log();
       }
    +  interrupts();
     }
    https://github.com/mstrthealias/Teen...er/src/src.ino

    Note that, the Teensy 4.0 does not immediately hard crash if `do_hid_recv();` is commented out (along with the patch above).


    The reason I've questioned Teensy 4.0 stability:

    If I open and close the fan controller's Management UI 10 times, the Teensy 4.0 will usually freeze and require reboot (without the `noInterrupts()`/`interrupts()` calls). This does not occur on the Teensy 3.2 and 3.5.

    If I comment out the `do_adc()` AND `do_pid()` calls, the freeze does not seem to occur (but does occur if just one of those calls are commented out). If I only comment out the analogRead and analogWrite calls (which are invoked by the do_adc/do_pid) calls, the freeze still occurs.

    There are also issues with the RPM/pulse counting logic (Teensy 4.0 only), which I haven't pinpointed, nor identified whether or not noise/schematic is to the blame. If I comment out the analogWrite calls (PWM), the pulse counter interrupt does not unexpectedly fire.

  8. #8
    I believe I found a solution to the Teensy 4.0 Teensy Fan Controller instability:

    * Update HID receive/read to occur once every 10ms
    * Wrap RPM calculation with noInterrupts() and interrupts() calls
    * Wrap ADC averaging with noInterrupts() and interrupts() calls
    * Wrap fan % calculation with noInterrupts() and interrupts() calls
    * Wrap log logic with noInterrupts() and interrupts() calls
    * Wrap HID send logic with noInterrupts() and interrupts() calls

    Note that a hard crash occurred with the following:

    * Wrapping HID receive logic with noInterrupts() and interrupts() calls
    * Wrapping ADC read logic (which calls delay(1) 10 times) with noInterrupts() and interrupts() calls
    * Most combinations of noInterrupts() and interrupts() calls when HID receive ran every loop() call

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Prior posts didn't show any interrupt code ...

    To see if it clears things up stop the IntervalTimer and manually call it from loop leaving the interrupts running.

    Code:
    elapsedMicros foo;
    elapsedMicros bar;
    loop() {
      if ( foo >= 100 )
      {
        foo=0;
        // do code here ONLY 10,000 times per second
      }
      if ( bar >= 1000 )
      {
        bar-=1000;
        // call the IntervalTimer's _isr()
      }
    }

  10. #10
    I'm still seeing instability on the Teensy 4.0, and the time at which it crashes is random.

    I'm launching the client with a loop that requests a config download (over RawHID) every ~5 seconds. I haven't seen the Teensy 3.x crash after such a request, and the client loop reached 190 attempts on a 3.2 before I canceled it.

    On the Teensy 4.0, it crashes at random times: the last crash made it to the 18th attempt, the previous crash to the 56th attempt, and about the 8th attempt before that.

    It seems to happen sooner if RawHID.recv is called more frequently (fe. every 5ms instead of every 10ms), or if I set the CPU to 150MHz instead of 600MHz.

    I confident that it always crashes if noInterrupts() is called before RawHID.recv(), and am wondering if the cause is from __disable_irq() being called when the interrupts are already disabled. The following code also always crashes the device:

    Code:
    void setup() {
      Serial.begin(9600);
    }
    
    elapsedMillis cntMillis;
    
    void loop() {
      if (cntMillis >= 500) {
        cntMillis = 0;
        
        noInterrupts();
        delay(500);
        noInterrupts();
        delay(1000);
        Serial.println("GOT HERE");
        interrupts();
      }
    }

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Quote Originally Posted by mstrthealias View Post
    I'm still seeing instability on the Teensy 4.0, and the time at which it crashes is random.

    I'm launching the client with a loop that requests a config download (over RawHID) every ~5 seconds. I haven't seen the Teensy 3.x crash after such a request, and the client loop reached 190 attempts on a 3.2 before I canceled it.

    On the Teensy 4.0, it crashes at random times: the last crash made it to the 18th attempt, the previous crash to the 56th attempt, and about the 8th attempt before that.

    It seems to happen sooner if RawHID.recv is called more frequently (fe. every 5ms instead of every 10ms), or if I set the CPU to 150MHz instead of 600MHz.

    I confident that it always crashes if noInterrupts() is called before RawHID.recv(), and am wondering if the cause is from __disable_irq() being called when the interrupts are already disabled. The following code also always crashes the device:

    ...
    You may have come across something unique to Teensy 4.0 RawHID implementation.

    If you can present a MAC and Teensy program set the reproduces the problem it may be something Paul can investigate and resolve.

    As noted in post #9 - one more test would be not enabling the intervaltimer call to the _isr() code - instead don't disable interrupts and see what happens when that is run in loop(). That will simplify the situation considerably, while still running " 1000 Hz PID loop " - if it works then it shows it isn't related to the other running code.

  12. #12
    I just tested with no pin IRQs and no timer IRQs initialized, and had a crash on the 5th and 9th attempt of sending an HID packet to the device.

    I'll build a simple example that represents the problem late tomorrow. The device logic looks like:

    Code:
    uint16_t yar = 0;
    void loop(void)
    {
      if (cntMillis >= 10) {
        cntMillis = 0;
        do_hid_recv();
        yar++;
      }
      if (yar >= 10) {
        yar = 0;
        do_hid_send();
      }
    }
    The crash occurs when the client sends a payload to the device, and I think only when the device receives the packet when it's already in the RawHID->recv() logic (which takes 0.9-1ms per call, with parameter timeout=0).

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Quote Originally Posted by mstrthealias View Post
    I just tested with no pin IRQs and no timer IRQs initialized, and had a crash on the 5th and 9th attempt of sending an HID packet to the device.

    I'll build a simple example that represents the problem late tomorrow. The device logic looks like:

    Code:
    uint16_t yar = 0;
    void loop(void)
    {
      if (cntMillis >= 10) {
        cntMillis = 0;
        do_hid_recv();
        yar++;
      }
      if (yar >= 10) {
        yar = 0;
        do_hid_send();
      }
    }
    The crash occurs when the client sends a payload to the device, and I think only when the device receives the packet when it's already in the RawHID->recv() logic (which takes 0.9-1ms per call, with parameter timeout=0).
    Good work - That should go farther to finding an issue without contention over _isr()'s and not toggling interrupts on and off!

    Posting the complete sketch with full setup() and defines of all things like cntMillis - and client Code for running the HID SENDER portion to the exact messages and timing- should let Paul get to the root of any Teensy 4.0 trouble.

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Quote Originally Posted by mstrthealias View Post
    I just tested with no pin IRQs and no timer IRQs initialized, and had a crash on the 5th and 9th attempt of sending an HID packet to the device.

    I'll build a simple example that represents the problem late tomorrow. The device logic looks like:
    ...
    @mstrthealias: was there a set of code to reproduce this that can be posted in case it helps lead to a resolution?

  15. #15
    Junior Member prnthp's Avatar
    Join Date
    Oct 2019
    Posts
    15
    Thanks @mstrthalias, @defragster.

    Here's the updated code w/o all the interrupt stuff. Like what @mstrthalias has found, it works fine for single HID packets but randomly crashes once consecutive reads are done. I can confirm that it does not hang for TD 1.48 and hangs for TD 1.51.

    Code:
    #include <Arduino.h>
    
    void blink(int num);
    
    void setup() 
    {
      delay(500); // Simulate initialization
      pinMode(13, OUTPUT);
      blink(1);
    }
    
    char rx_buffer[64];
    
    elapsedMicros time;
    
    void loop() 
    {
      if (time < 100)
      {
        return;
      }
      int n = RawHID.recv(rx_buffer, 1); 
      if (n > 0) 
      {
        if (rx_buffer[0] == 0xAB) // Signature
        {
          blink(2);
        }
      }
     time = 0; // p#15::  code is missing time = 0; at the end of the main loop(). I've tested it again and the issue is still there for TD1.49 - TD1.51.
    
    }
    
    void blink(int num)
    {
      for (int i = 0; i < num; i++)
      {
        digitalWrite(13, HIGH);
        delay(10);
        digitalWrite(13, LOW);
        delay(10);
      }
    }
    And here's the host-side code, which is actually a plugin for Unity/C# on macOS. It uses https://github.com/libusb/hidapi. sendHID() is usually called in rapid succession for ~100 times. I've timed the calls and they are at least 1 ms apart from each other. (Note that I forced a 1 ms delay, it works for TD 1.48 even when I did not force a delay and the calls were 0.5 ms apart, i.e. as fast as the OS let me and I've used this kind of stuff extensively without fail on a Teensy 3.5 on TD 1.46 - TD 1.48 before.)
    Code:
    #include "hidapi.h"
    #include <stdio.h>
    #include <string.h>
    
    int r;
    hid_device *teensy_handle;
    
    int EXPORT_API connectHID(int VID, int PID) {
        // USAGE_PAGE = 0xFF00
        // USAGE = 0x0100
        if (teensy_handle != NULL)
        {
            hid_close(teensy_handle);
        }
        
        int r;
        r = hid_init();
        if (r < 0)
        {
            return r;
        }
        
        teensy_handle = hid_open(VID, PID, NULL);
        if (teensy_handle == NULL)
        {
            return -2;
        }
        else
        {
            return 1;
        }
    }
    
    int EXPORT_API sendHID(char* buf)
    {
        int r;
        unsigned char write_buf[65];
        memset(write_buf, 0, 65);
        memcpy(write_buf+1, buf, 64);
        
        r = hid_write(teensy_handle, write_buf, 65);
        
        return r;
    }
    And to make sure that the delay(10); in the blink() function didn't affect this issue, this threaded version also works on TD 1.48 but hangs on TD1.51.

    Code:
    #include <TeensyThreads.h>
    
    void blink(int num)
    {
      threads.addThread(blinkThread, num);
    }
    
    void blinkThread(int num)
    {
      for (int i = 0; i < num; i++)
      {
        digitalWrite(13, HIGH);
        threads.delay(50);
        digitalWrite(13, LOW);
        threads.delay(50);
      }
    }
    Last edited by defragster; 03-13-2020 at 09:43 PM.

  16. #16
    Junior Member prnthp's Avatar
    Join Date
    Oct 2019
    Posts
    15
    ^ The above code is missing time = 0; at the end of the main loop(). I've tested it again and the issue is still there for TD1.49 - TD1.51.

    Just wanted to add that it still hangs on TD 1.52 Beta 1.
    Last edited by prnthp; 03-11-2020 at 08:47 PM.

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Quote Originally Posted by prnthp View Post
    ^ The above code is missing time = 0; at the end of the main loop(). I've tested it again and the issue is still there for TD1.49 - TD1.51.

    Just wanted to add that it still hangs on TD 1.52 Beta 1.
    Post #14 updated to include "time=0;" at end of loop.

  18. #18
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,306
    I thought I would take a look and see what was going and if I could reproduce it. I started to try to setup MSC to allow the RAWHID stuff to compile and then decided on a different approach. That is why not use a T3.6 or T4 to drive the other T4 and see if that can reproduce the issue. It does!

    Again your sketch that I am running:
    Code:
    #include <Arduino.h>
    
    void blink(int num);
    
    void setup() 
    {
      delay(500); // Simulate initialization
      pinMode(13, OUTPUT);
      blink(1);
    }
    
    char rx_buffer[64];
    
    elapsedMicros time;
    
    void loop() 
    {
      if (time < 100)
      {
        return;
      }
      int n = RawHID.recv(rx_buffer, 1); 
      if (n > 0) 
      {
        if (rx_buffer[0] == 0xAB) // Signature
        {
          blink(2);
        }
      }
     time = 0; // p#15::  code is missing time = 0; at the end of the main loop(). I've tested it again and the issue is still there for TD1.49 - TD1.51.
    
    }
    
    void blink(int num)
    {
      for (int i = 0; i < num; i++)
      {
        digitalWrite(13, HIGH);
        delay(10);
        digitalWrite(13, LOW);
        delay(10);
      }
    }
    My semi stripped down and modified version of the USBHost mouse example:
    Code:
    // Simple test of USB Host Mouse/Keyboard
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    
    USBHost myusb;
    USBHub hub1(myusb);
    USBHIDParser hid1(myusb);
    USBHIDParser hid2(myusb);
    USBHIDParser hid3(myusb);
    RawHIDController rawhid1(myusb);
    RawHIDController rawhid2(myusb, 0xffc90004);
    
    USBDriver *drivers[] = {&hub1, &hid1, &hid2, &hid3};
    #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
    const char * driver_names[CNT_DEVICES] = {"Hub1", "HID1" , "HID2", "HID3"};
    bool driver_active[CNT_DEVICES] = {false, false, false, false};
    
    // Lets also look at HID Input devices
    USBHIDInput *hiddrivers[] = {&rawhid1, &rawhid2};
    #define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
    const char * hid_driver_names[CNT_DEVICES] = {"RawHid1", "RawHid2"};
    bool hid_driver_active[CNT_DEVICES] = {false, false};
    bool show_changed_only = false;
    
    
    void setup()
    {
      while (!Serial) ; // wait for Arduino Serial Monitor
      Serial.println("\n\nUSB Host Testing");
      Serial.println(sizeof(USBHub), DEC);
      myusb.begin();
      rawhid1.attachReceive(OnReceiveHidData);
      rawhid2.attachReceive(OnReceiveHidData);
      pinMode(13, OUTPUT);
    }
    
    
    void loop()
    {
      myusb.Task();
    
      if (Serial.available()) {
        int ch = Serial.read(); // get the first char.
        while (Serial.read() != -1) ;
        if (show_changed_only) {
          show_changed_only = false;
          Serial.println("\n*** Show All fields mode ***");
        } else {
          show_changed_only = true;
          Serial.println("\n*** Show only changed fields mode ***");
        }
      }
    
      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);
          }
        }
      }
    
      for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
        if (*hiddrivers[i] != hid_driver_active[i]) {
          if (hid_driver_active[i]) {
            Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
            hid_driver_active[i] = false;
          } else {
            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);
            psz = hiddrivers[i]->serialNumber();
            if (psz && *psz) Serial.printf("  Serial: %s\n", psz);
          }
        }
      }
      // See if we have some RAW data
      if (rawhid1) {
        uint8_t buffer[64];
        digitalWriteFast(13, !digitalReadFast(13));
        memset(buffer, 0, sizeof(buffer));
        buffer[0] = 0xab;
        rawhid1.sendPacket(buffer);
        delay(250);
      }
    
    }
    bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
      // Called for maybe both HIDS for rawhid basic test.  One is for the Teensy
      // to output to Serial. while still having Raw Hid...
      if (usage == 0xffc90004) {
        // Lets trim off trailing null characters.
        while ((len > 0) && (data[len - 1] == 0)) {
          len--;
        }
        if (len) {
          Serial.print("RawHid Serial: ");
          Serial.write(data, len);
        }
      } else {
        Serial.print("RawHID data: ");
        Serial.println(usage, HEX);
        while (len) {
          uint8_t cb = (len > 16) ? 16 : len;
          const uint8_t *p = data;
          uint8_t i;
          for (i = 0; i < cb; i++) {
            Serial.printf("%02x ", *p++);
          }
          Serial.print(": ");
          for (i = 0; i < cb; i++) {
            Serial.write(((*data >= ' ') && (*data <= '~')) ? *data : '.');
            data++;
          }
          len -= cb;
          Serial.println();
        }
      }
    
      return true;
    }
    You start it up and plug in your T4 and it shows the
    Debug stuff:
    Code:
    USB Host Testing
    
    960
    
    *** Device HID1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    *** Device HID2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    *** HID Device RawHid2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    *** HID Device RawHid1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    With both of them blinking showing they are communicating. After awhile your program stops...

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,306
    Quick update: Updated the hanging program to see if it hangs or does not get valid data... Setup to output to Serial (other raw hid)...

    Code:
    #include <Arduino.h>
    
    void blink(int num);
    void setup()
    {
      while (!Serial && millis() < 3000) ;
      Serial.begin(115200);
      delay(500); // Simulate initialization
      pinMode(13, OUTPUT);
      blink(1);
    }
    
    char rx_buffer[64];
    
    elapsedMicros time;
    uint32_t loop_count = 0;
    uint32_t receive_count = 0;
    uint32_t valid_count = 0;
    
    
    void loop()
    {
      if (time < 100)
      {
        return;
      }
      loop_count++;
      int n = RawHID.recv(rx_buffer, 1);
      if (n > 0)
      {
        receive_count++;
        if (rx_buffer[0] == 0xAB) // Signature
        {
          valid_count++;
          blink(2);
        }
      }
      time = 0;
      if ((loop_count & 0x7f) == 0) Serial.printf("L:%u R:%u: V:%d\n", loop_count, receive_count, valid_count);
    }
    
    void blink(int num)
    {
      for (int i = 0; i < num; i++)
      {
        digitalWrite(13, HIGH);
        delay(10);
        digitalWrite(13, LOW);
        delay(10);
      }
    }
    It does hang now last several lines out output:
    Code:
    RawHid Serial: L:10112 R:100: V:100
    RawHid Serial: L:10240 R:101: V:101
    RawHid Serial: L:10368 R:102: V:102
    RawHid Serial: L:10496 R:103: V:103
    RawHid Serial: L:10624 R:105: V:105
    RawHid Serial: L:10752 R:106: V:106
    RawHid Serial: L:10880 R:107: V:107
    RawHid Serial: L:11008 R:108: V:108
    RawHid Serial: L:11136 R:109: V:109
    (Those lines are echoed back from the USB Host code.

    Now to instrument more on inside the call...

  20. #20
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,306
    Quick update: Not hanging in usb_rawhid_recv:
    Code:
    int usb_rawhid_recv(void *buffer, uint32_t timeout)
    {
    	uint32_t wait_begin_at = systick_millis_count;
    	digitalWriteFast(0, HIGH);
    	while (1) {
    		if (!usb_configuration) return -1; // usb not enumerated by host
    		uint32_t status = usb_transfer_status(rx_transfer);
    		if (!(status & 0x80)) break; // transfer descriptor ready
    		if (systick_millis_count - wait_begin_at > timeout)  {
    			digitalWriteFast(0, LOW);
    			return 0;
    		}
    		yield();
    	}
    	digitalWriteFast(0, LOW);
    	memcpy(buffer, rx_buffer, RAWHID_RX_SIZE);
    	memset(rx_transfer, 0, sizeof(rx_transfer));
    	digitalWriteFast(1, HIGH);
    	usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0);
    	usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0);
    	digitalWriteFast(1, LOW);
    	return RAWHID_RX_SIZE;
    }
    Logic analyzer stopped with both signal 0 or 1 being low...

    EDIT: - Note: I am not sure yet if timing and/or other stuff, but I appear to always hang with Receive count printed of something like 109 or 108... Note: same when I change delay in my transmit code to 100 instead of 250.

    So next up checking either memory something and/or timing?

    EDIT2: I print out _sbrk(0); Which is not changing so no one is calling malloc or neeeeew
    Last edited by KurtE; 03-14-2020 at 06:15 PM.

  21. #21
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Set up here with two T4.0's. Stop at same point:
    Code:
    T:\tCode\Serial\RawHidMouse\RawHidMouse.ino Mar 14 2020 10:47:22
    
    USB Host Testing
    960
    *** Device HID1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    *** Device HID2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    *** HID Device RawHid1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    *** HID Device RawHid2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    RawHid Serial: 
    T:\tCode\Serial\RawHidHang\RawHidHang.ino Mar 14 2020 10:57:08RawHid Serial: 
    RawHid Serial: L:128 R:5: V:5
    RawHid Serial: L:256 R:6: V:6
    RawHid Serial: L:384 R:7: V:7// …
    RawHid Serial: L:11008 R:108: V:108
    RawHid Serial: L:11136 R:109: V:109
    So it seems I have it set up the same?

    I added debug_tt to the one "RawHidHang" that was hanging and now it keeps running? I uploaded to the RawHidHang with added debug_tt then had to repower the "RawHidMouse". The startup message transfers the startup "T:\tCode\Serial\RawHidHang\RawHidHang.ino Mar 14 2020 11:01:39" then just prints 0's for Rcv and Valid #'s - until the Host repowered.

    and it just keeps running - with both blinking - except as I was typing that the RawHidHang stopped:
    Code:
    // …
    RawHid Serial: L:156416 R:1481: V:1481
    RawHid Serial: L:156544 R:1482: V:1482
    RawHid Serial: L:156672 R:1483: V:1483
    Not sure that adds anything???

    Adding the "debBegin_tt( (HardwareSerial*)&Serial, LED_BUILTIN, 12);" to the Hanging sketch and printing "where_tt( );" shows "loop34() stack var: 20077FDC" … line 34 in loop(), the rest is the addr of a stack var.

    So with that added it is now running even longer? Is this a change showing something changed 'with added code'?

    Code:
    //…
    RawHid Serial: L:317824 R:3005: V:3005
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:317952 R:3006: V:3006
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318080 R:3008: V:3008
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318208 R:3009: V:3009
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318336 R:3010: V:3010
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318464 R:3011: V:3011
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318592 R:3012: V:3012
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318720 R:3014: V:3014
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318848 R:3015: V:3015
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:318976 R:3016: V:3016
    RawHid Serial: loop34() stack var: 20077FDC
    The ODD thing is the where_tt() is printing TWICE as above with some periodic regularity? And there are missing prints of the "R: & V:" values as showing in TyComm.

    It is still running now at : RawHid Serial: L:357760 R:3383: V:3383 … and counting

  22. #22
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    BTW: P#21 suggests it is not FAULTING - just going to sleep somewhere? If it were faulting the debug_tt code would trigger the FAULT_BLINK and should eject some USB output and that is not showing.

    I just hooked up pin12 for debug_tt interrupt break - it triggers text to host when running - will try again when it next 'stops'.

    I left it a bit and it did 'stop' again with these last lines on the USBHost code connected to TyComm - so it ran for some time working up to #4110:
    Code:
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:434432 R:4106: V:4106
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:434560 R:4108: V:4108
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:434688 R:4109: V:4109
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:434816 R:4110: V:4110
    NOTE: I repowered the USBHost ( also powering the sketch device T4 ) and it started fresh like this - not sure why the "R: V:" messages are missing? :
    Code:
    T:\tCode\Serial\RawHidMouse\RawHidMouse.ino Mar 14 2020 10:47:22
    
    
    USB Host Testing
    960
    *** Device HID1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    *** Device HID2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    *** HID Device RawHid2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    RawHid Serial: 
    T:\tCode\Serial\RawHidHang\RawHidHang.ino Mar 14 2020 11:16:02
    RawHid Serial: 
    *** HID Device RawHid1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6683800
    RawHid Serial: F_CPU==600000000   F_BUS==150000000
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:128 R:4: V:4
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:256 R:5: V:5
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:384 R:7: V:7
    RawHid Serial: loop34() stack var: 20077FDC
    RawHid Serial: L:512 R:8: V:8

  23. #23
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,306
    I am probably going to do some other stuff for awhile, but I tried turning on the debug prints in USB and build the hanging app. The code tries to output to Serial4, so I hooked it up to Serial1 of my other teensy... And it prints a few lines and hangs without ever blinking that one...

    Code:
    USB Host Testing
    
    960
    
    ***********IMXRT Startup**********
    
    test 1 -1234567 3
    
    CCM_ANALOG_PLL_USB1=80003000
    
      enable USB clocks
    
    CCM_ANALOG_PLL_USB1=80003040
    
    Increasing voltage to 1250 mV
    
    need to switch to alternate clock during reconfigure of ARM PLL
    
    USB PLL is running, so we can use 120 MHz
    
    Freq: 12 MHz * 100 / 2 / 1
    
    ARM PLL=80002042
    
    ARM PLL needs reconfigure
    
    ARM PLL=80002064
    
    New Frequency: ARM=600000000, IPG=150000000
    
    BURSTSIZE=00000808
    
    BURSTSIZE=00000808
    
    USB1_TXFILLTUNING=00000000
    
    USB reset took 6 loops
    
    analogInit
    
    *suspend
    
    *reset
    
    *data
    
    setup 01000680 00080000
    
    port at 480 Mbit
    
    *data
    
    setup 00010500 00000000
    
    *data
    
    setup 01000680 00120000
    
    *data
    
    setup 03000680 01FC0000
    
    *data
    
    setup 03010680 01FC0409
    
    *data
    
    setup 03020680 01FC0409
    
    *data
    
    setup 03030680 01FC0409
    
    *data
    
    setup 02000680 00090000
    
    *data
    
    setup 02000680 00490000
    
    *data
    
    setup 00010900 00000000
    
    usb_seremu_configure
    
    usb_rawhid_configure
    
    *** Device HID1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    *** Device HID2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    *data
    
    setup 22000681 001C0000
    
    **** HID Device RawHid1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    RawHid Serial: 
    
    USB Host Testing
    
    960
    
    data
    
    setup 22000681 00210001
    
    USB1_ENDPTCOMPLETE=00000010
    
    *da*** HID Device RawHid2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 6243450
    Sort of scrambled together, probably should go find other TTL to serial converter, or use 2 USB Serial outputs...

  24. #24
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,907
    Teensy makes a GREAT TTL to Serial converter ... KurtE: isn't that one over there ... and there ...

    Started again and the _isr() does a BLINK toggle - and the BLINK is showing - but no feedthrough of the USB output text.

    Found the code stopping my _isr() from retriggering. So it is working to toggle blink on each press, even when the loop() code it halting.

    Need to get the "debBegin_tt( &Serial1, LED_BUILTIN, 12);" hooked up and tested.
    Last edited by defragster; 03-14-2020 at 09:05 PM. Reason: &Serial1

  25. #25
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,306
    Sounds good. Again I may have one or two Teensy chips around here

    I am doing some old fashion debugging.

    I put a digitalWriteFast High at start of USB _isr and a LOW at the end, and when it hangs it shows the level as high. So hang is in the ISR.

    Now to add a few more and see where in ISR.

    And it appears to be in the top area:
    Code:
    	if (status & USB_USBSTS_UI) {
    		digitalWriteFast(1, HIGH);
    		//printf("data\n");
    		uint32_t setupstatus = USB1_ENDPTSETUPSTAT;
    		//printf("USB1_ENDPTSETUPSTAT=%X\n", setupstatus);
    ...
    Now to zero more into this area. Note: Even adding these digitalWriteFast are changing the timing enough that it may take longer to get the duplicate...

Posting Permissions

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