_restart_Teensyduino() for T3.x

jbliesener

Well-known member
Hi, Paul!

I was trying to do a software reset on my T3. Back in the old Teensy 2 times, I used to call _restart_Teensyduino_() for that and it worked (as far as I remember). There was _reboot_Teensyduino_() to start the bootloader and _restart_Teensyduino() to reboot the current sketch.

For the T3 library, it seems that both functions are declared in hardware\teensy\cores\teensy3\core_pins.h, but only _reboot_Teensyduino_() seems to be implemented in usb_dev.c, issuing a "bkpt" instruction. _restart_Teensydiono_() gives me a linker error.

I just downloaded 1.20rc4, the problem persists.

What would be a safe way to reboot the processor? I believe that disabling interrupts and issuing something like "(*(void(*)())0)();" may not be sufficient, as this would not reset the internal hardware components. The other option would be to issue SYSRESETREQ through SCB_AIRCR, which requires some fiddling with the VECTKEY bits to make it work.

It would be nice if the function was either (implemented) or (not declared).

Thanks, Jorg

__EDIT__: This seems to work:

Code:
#define AIRCR_VECTKEY     0x05FA0000
#define AIRCR_SYSRESETREQ 0x00000004

void _restart_Teensyduino_() {
  SCB_AIRCR = (AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
  while(1);
}

One of the posts here suggests that it might be a good idea to retain the remaining bits in SCB_AIRCR, but from what I see in the ARMv7 reference manual, it seems that there is only one additional bit group (PRIGROUP) that might be affected - and it is set to 000 on a reset. All others are either Write Only or Read Only, so I see no need to preserve them.
 
Last edited:
This has been on my TO-DO list for 2 years.

The need has lessened, since Arduino Leonardo & Yun have caused many of the Arduino sketches to use "while (!Serial)" at startup, which explains whe this has sank to a lower priority. Still, there are a LOT of sketches and examples that depend on Arduino Uno's restart-on-serial-monitor-open behavior.

The intention behind _restart_Teensyduino_() is emulating the Arduino Uno restart, where the CPU reboots and all on-chip peripheral reset, but the USB on Arduino Uno is implemented by another chip which does not reset. On Teensy 2.0, this is done by code which clears all (or most) peripheral registers, but not the USB, and then jumps to location zero. The USB stack on Teensy 2.0 checks if the USB is already active and skips initialization.

On Teensy 3.x, the ARM processor is more complex, with more modes to consider, more on-chip peripherals, and maybe other subtle issues I haven't anticipated yet.

When you write to SCB_AIRCR's system reset, does the USB disconnect? I haven't personally tested this, but my understanding is the USB should disconnect in this situation.
 
This has been on my TO-DO list for 2 years.
When you write to SCB_AIRCR's system reset, does the USB disconnect? I haven't personally tested this, but my understanding is the USB should disconnect in this situation.

Yes, it does and reconnects when the Teensy comes up again.

But then there's this 10 second timeout on Windows if you disconnect a Teensy in Serial Emulation mode (through teensy_gateway). So, actually, it reconnects only 10 seconds AFTER the reboot. So, I disabled interrupts and waited 10 seconds before rebooting. Didn't help either. What actually gives a solid, clean reboot is this - quite ugly:

Code:
		cout << "Rebooting in 10 seconds (USB delay)" << endl;
		delay(100);
		// disable USB
		USB0_CONTROL = 0;
		NVIC_DISABLE_IRQ(IRQ_USBOTG);
		USB0_INTEN = USB_INTEN_USBRSTEN;
		USB0_CTL = 0;
		USB0_INTEN = 0;
		SIM_SCGC4 &= ~SIM_SCGC4_USBOTG;

		// give Windows some time to disconnect
		// how can this be done faster? Is there something like a USB disconnect message?
		// the serial usb port (CDC) disconnects immediately, when you unplug the cable,
		// seremu needs these 10 seconds.
		delay(10000);
		_restart_Teensyduino_();

Yes, it would be very nice to run a reset that leaves the USB port alive.

Jorg
 
Which version of Windows are you using?

I saw that delay on Windows XP and 7 (in other reboot testing). On Windows 8.1, it appeared to be fixed.
 
I'm using Windows 7/64bit. Any idea what causes this behavior?

Well, I guess I'll have to upgrade... I wanted to avoid the tiles as long as possible, but it looks as if the time has come.... :( :( :(
 
I'm using Windows 7/64bit. Any idea what causes this behavior?

No, sadly, I have no idea why Windows does this.

Believe me, it's not for lack of trying. I've spent many long sessions trying to dig into this problem.

I've watched the communication with a USB protocol analyzer (with another computer displaying the data). It's clearly a case of Windows pausing late in the enumeration process. Teensy is replying to every request very quickly.

I tried fiddling with the descriptors on Teensy. The number of HID interfaces makes quite a difference. More = slower, but why, I don't know. There's no logical reason.

I tried different combinations of software, with and without Teensy Loader and teensy_gateway running. None seem to matter.

I've spent many long hours searching MSDN and other sources. Lots of leads, but many hours spent trying stuff has always been fruitless.

Well, I guess I'll have to upgrade... I wanted to avoid the tiles as long as possible, but it looks as if the time has come.... :( :( :(

I can't say for certain the problem is totally fixed on Windows 8.1, but it definitely didn't happen in the few tests I tried. But to be honest, I haven't spent a lot of time using 8.1.

About a year ago, Phil Torrone of Adafruit made contact with someone in Microsoft's driver quality team. I submitted a detailed bug report (with a 7 minute video demo), not about this delay, but about the surprise removal bug in USBSER.SYS. In a followup email a few months ago, they suggested a fix might be coming. Apparently their testing and release process is very slow.

Still, I'm hopeful for Windows 9 to finally be the first version of Windows where USB stuff really works as well as Linux and Macintosh.
 
Thanks a lot, Paul. The 10 second delay issue isn't a show stopper for me. I'm able to reboot, that is what matters.

I just was a bit confused about function that is declared but not implemented. Maybe you can fix it somehow (after resolving C_DEBUGEN - that IS important to me).

And, as always, thanks for your great work!
 
Back
Top