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

prnthp

Member
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!
 
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).
 
@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.
 
@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.
 
@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/TeensyFanController/blob/master/teensy_fan_controller/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.
 
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
  }
}
 
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
 
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.
 
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()
  }
}
 
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();
  }
}
 
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.
 
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).
 
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.
 
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);
    }
  }
[B][COLOR="#FF0000"] time = 0;[/COLOR][/B] // 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 a moderator:
^ 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:
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?
 
^ 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.
 
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...
 
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...
 
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:
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
 
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
 
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...
 
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:
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...
 
Back
Top