harbaum / I2C-Tiny-USB

Cheap and simple I²C to USB interface
http://www.harbaum.org/till/i2c_tiny_usb
375 stars 79 forks source link

Tiny-USB hangs on host reboot #13

Open BeetleX99 opened 4 years ago

BeetleX99 commented 4 years ago

Hi, i2c-tiny-usb (main.hex on digispark) is fine with debian host.

But if the host is rebooting, the tiny doesn´t respond to the usb registering process. After a system reboot just pulling and replugging the hardware module re-enables the module again.

Any advice for fixing? I am not familiar with the USB state machines...

PizzaProgram commented 4 years ago

I have just realized: This is TRUE!

After reboot > device is not recognized. Only manual unplugging / re-plugging helps.

So basically this makes the whole thing useless, unless there's a trick we don't know about?

BeetleX99 commented 4 years ago

I tried something on Linux level, but didn´t succeed. I am not the expert so far. As the original project was transferred to Digi/Ada, maybe the hangup is caused by this? Anyone out there, being able to check this? Till?

BeetleX99 commented 4 years ago

Sorry, closed by mistake!

PizzaProgram commented 4 years ago

Since the author isn't answering, I'm forced to ask:

zgyarmati commented 4 years ago

I've looked into this briefly. It seems that this only happen with the digispark port of the i2c-tiny-usb fimware. Digispark uses an USB bootloader micronucleus, and I suppose (but I didn't really debug this), that the USB bootloader causes the issue. I think if you flash the original (not Digispark/micronucleus based) fw on the Digispark module's attiny85, than the issue will disappear, without getting/building new hardware.

harbaum commented 4 years ago

What exactly do you think is the problem? Are other digispark based projects also affected by this?

zgyarmati commented 4 years ago

Oddly it turned out that with my Digispark (likely a clone, i don't even remember where i bought it) i can't reproduce the issue, neither with reboot nor with switching off and back on my computer, by using the main.hex available in the digispark dir. One variable could be the micronucleus bootloader version. @BeetleX99 , @PizzaProgram, could you please check what bootloader version do you have? It's written when the .hex is flashed with micronucleus as:

Device has firmware version 1.11 Available space for user applications: 6330 bytes Suggested sleep time between sending pages: 8ms Whole page count: 99 page size: 64 Erase function sleep duration: 792ms

PizzaProgram commented 4 years ago

I have used a special fork of micronucleus, that is compatible with WinUSB driver, because it was impossible to flash the device with the "normal one". (Unknown device keeps popping up only for 2 sec in device manager, so no chance to install a driver. Zadig.exe is refreshing every 3 sec too.)


> Please plug in the device...
> Press CTRL+C to terminate the program.
> Device found!
> Device has firmware version 1.6
> Available space for user application: 6012 bytes
> Suggested sleep time between sending pages: 8ms
> Whole page count: 94, page size: 64
> Erase function sleep duration: 752ms
> Erasing flash memory...
..........
> Writing flash memory...
.....................................................................
> Starting the user application...
> Micronucleus done. Thank you!````
PizzaProgram commented 4 years ago
libwdi:debug [wdi_create_list] Hardware ID: USB\VID_0403&PID_C631&REV_0201
libwdi:debug [wdi_create_list] Compatible ID: USB\Class_00&SubClass_00&Prot_00
libwdi:debug [wdi_create_list] Driverless USB device (2): USB\VID_0403&PID_C631\0070
libwdi:debug [wdi_create_list] Device description: 'i2c-tiny-usb'
zgyarmati commented 4 years ago

I flashed the 1.6 version of the Micronucleus bootloader FW from here: https://github.com/mariusgreuel/micronucleus/tree/v1.06/firmware/releases (the file "micronucleus-1.06.hex") and on the top of that I flashed the i2c-tiny-usb main.hex from this repo. I can't reproduce the issue with rebooting on my Linux box... I see that your OS is Windows, but unfortunately i don't have the means to debug this under Windows.

PizzaProgram commented 4 years ago

hmmm.... now I don't understand:

  1. Is there 2 different .hex file I need to flash? (1 for the boot loader + 1 for the I2C>USB?)
  2. How is 1.6 version = 1.06 ?
  3. How do I flash a boot loader anyway? Is it possible with Arduino IDE?
  4. Isn't it possible to do everything from Arduino IDE software anyway?
PizzaProgram commented 4 years ago

I can't reproduce the issue with rebooting on my Linux box...

What kind of "box" is that? A Raspberry Pi? Is that box unpowering for a moment the USB port while rebooting? (Because the RPi 4 does NOT >> and that's causing the problem)

BeetleX99 commented 4 years ago

Great News! I did some testing at CubieTruck and Raspi in parallel, and now I just found the culprit! If the Tiny runs behind an usb-hub, it will fail in rebooting, connected directly to the CubieTruck the Tiny is activated after each reboot!!!

zgyarmati commented 4 years ago

@BeetleX99, thx for sharing this observation! The hub has an external power supply, or host-powered?

PizzaProgram commented 4 years ago

@BeetleX99 I guess you have an external power at your USB hub. Or maybe a bigger capacitor (condenser) built-in that "holds" the power for a moment while your mainboard is rebooting. Which gives a great idea:

The developers could use an external powered USB HUB to simulate and debug the problem too!

PizzaProgram commented 4 years ago

I've just quickly looked at the kerner code but I don't find any "keepalive timer", that triggers a re-inic sequence of the device if that signal is lost. So this is maybe an architectural problem of the whole code design?

IMHO it's much more difficult to detect a signal loss, if not BOTH parties of the communication are keeping track of each other from time to time. (Maybe once every 1 sec? )

BeetleX99 commented 4 years ago

My hub doesn´t have an externel power supply.

Gemba commented 3 years ago

FWIW, you may try this patch.

PizzaProgram commented 3 years ago

Sounds great! :+1:

Sadly this is a bit too complicated for me how enable this patch on my RPi4. I guess a new linux Buster kernel release / upgrade will come out soon, and the driver will be auto-upgraded?

... about these lines starting from 14:

+    i = 0;
+    while (--i) { /* fake USB disconnect for > 250 ms */
+        _delay_ms(30);
     }

How can this run for 250ms if i=0 ?

Gemba commented 3 years ago

Maybe it can/will be fixed in a future kernel/firmware (if it can be attributed to be a kernel/firmware issue). I did not update to the latest development there.

The -- is the trick here together with the type of i. -- is an decrement operator which decreases the value of i before it gets evaluated in the while condition. As i is a uchar/byte it will be 255 at the first evalutaion of while().

PizzaProgram commented 3 years ago

Maybe I have too low programming knowledge after 35+ years of learning, but this while cycle does not seem to be right. If you say this should run for 250ms, than "--i overflow" start at 255 x 30ms delay = 7650ms.

How about a simple, clear code, that everyone can understand and nobody thinks it's a bug?

i = 0;
while (i < 12) { /* fake USB disconnect for > 250 ms */
  ++i;  _delay_ms(25);
}

That will run for 250ms, not 7650, or cause any byte-overflow ... (i <> 12) or (i != 12) is fine too, I just don't know the exact syntax.

PizzaProgram commented 3 years ago

I did not update to the latest development there...

Why not ?

o2bshane commented 3 years ago

I too have experience a digispark freezing after a reboot of the host computer. This happens with every micronucleus firmware except the default. It seems we need the digispark to enter bootloader mode to re-initalize the USB connection after the host reboots otherwise it freezes. I've tried using a WDT to reset the digispark and the USB connection but again with a modified micronucleus ( like one that only enters the bootloader on external reset) it freezes without the bootloader resting the USB connection.