PaulStoffregen / teensy_loader_cli

Command line Teensy Loader
http://www.pjrc.com/teensy/loader_cli.html
331 stars 152 forks source link

rebootor on TEENSY2PP does not appear on the USB bus #38

Open stapelberg opened 6 years ago

stapelberg commented 6 years ago

Here’s what I did:

% wget https://raw.githubusercontent.com/PaulStoffregen/teensy_loader_cli/f5b6d7aafda9a8b014b4bb08660833ca45c136d2/rebootor/rebootor.hex
% teensy_loader_cli -w -v --mcu=TEENSY2PP rebootor.hex
Teensy Loader, Command Line, Version 2.1
Read "rebootor.hex": 1312 bytes, 1.0% usage
Found HalfKay Bootloader
Programming......
Booting

Afterwards:

I can enter programming mode and re-program the teensy, but the symptom remains unchanged. I also tried recompiling rebootor.c, but my compilation shows the same symptoms.

Is the rebootor.hex file supposed to work on a TEENSY2PP? Am I doing something wrong? I can reproduce this behavior on an ASUS Z370-A mainboard and on a ThinkPad X1 Carbon 2015, so I think my USB ports/cable shouldn’t be the problem.

Thanks!

stapelberg commented 6 years ago

I spent some time getting this to work, posting this here in the hope that it’s useful to you while fixing this properly, or anyone else in the meantime.

First, I modified the usb rawhid implementation within the hardware/teensy directory of my arduino installation like so:

diff -ur cores/usb_rawhid/usb.c arduino-1.8.5/hardware/teensy/avr/cores/usb_rawhid/usb.c
--- cores/usb_rawhid/usb.c  2017-11-23 22:30:31.286067066 +0100
+++ arduino-1.8.5/hardware/teensy/avr/cores/usb_rawhid/usb.c    2017-12-17 16:23:04.301840825 +0100
@@ -21,7 +21,9 @@
  * THE SOFTWARE.
  */

+#include <util/delay.h>

+#include "core_pins.h"
 #include "usb_common.h"
 #include "usb_private.h"

@@ -402,7 +404,7 @@
    UEINTX = ~(1<<RXOUTI);
 }

-
+volatile uint16_t reset_cnt = 0;

 // USB Endpoint Interrupt - endpoint 0 is handled here.  The
 // other endpoints are manipulated by the user-callable
@@ -532,30 +534,27 @@
            }
        }
                 if (wIndex == RAWHID_INTERFACE) {
-                        if (bmRequestType == 0xA1 && bRequest == HID_GET_REPORT) {
-                                len = RAWHID_TX_SIZE;
-                                do {
-                                        // wait for host ready for IN packet
-                                        do {
-                                                i = UEINTX;
-                                        } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
-                                        if (i & (1<<RXOUTI)) return;    // abort
-                                        // send IN packet
-                                        n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
-                                        for (i = n; i; i--) {
-                                                // just send zeros
-                                                UEDATX = 0;
-                                        }
-                                        len -= n;
-                                        usb_send_in();
-                                } while (len || n == ENDPOINT0_SIZE);
-                                return;
-                        }
                         if (bmRequestType == 0x21 && bRequest == HID_SET_REPORT) {
+                                uint8_t buf[6];
                                 len = RAWHID_RX_SIZE;
                                 do {
                                         n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
                                         usb_wait_receive_out();
+                                        buf[0] = UEDATX;
+                                        buf[1] = UEDATX;
+                                        buf[2] = UEDATX;
+                                        buf[3] = UEDATX;
+                                        buf[4] = UEDATX;
+                                        buf[5] = UEDATX;
+                                        if (buf[0] == 'r' && buf[1] == 'e' && buf[2] == 'b'
+                                         && buf[3] == 'o' && buf[4] == 'o' && buf[5] == 't') {
+                                                // When we get the "reboot" message,
+                                                // pulse all port B, C, & D pins low
+                                                PORTB = 0, PORTC = 0, PORTD = 0;
+                                                DDRB = 0xFF, DDRC = 0xFF, DDRD = 0xFF;
+                                                reset_cnt = 1;
+                       digitalWriteFast(6, 1);
+                                        }
                                         // ignore incoming bytes
                                         usb_ack_out();
                                         len -= n;
@@ -563,7 +562,7 @@
                                 usb_wait_in_ready();
                                 usb_send_in();
                                 return;
-                        }
+                        }        
                 }
                 if (wIndex == DEBUG_INTERFACE) {
                         if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
diff -ur cores/usb_rawhid/usb_private.h arduino-1.8.5/hardware/teensy/avr/cores/usb_rawhid/usb_private.h
--- cores/usb_rawhid/usb_private.h  2017-11-23 22:30:31.286067066 +0100
+++ arduino-1.8.5/hardware/teensy/avr/cores/usb_rawhid/usb_private.h    2017-12-17 14:28:17.972039550 +0100
@@ -14,9 +14,9 @@
  **************************************************************************/

 #define VENDOR_ID               0x16C0
-#define PRODUCT_ID              0x0486
-#define RAWHID_USAGE_PAGE  0xFFAB  // recommended: 0xFF00 to 0xFFFF
-#define RAWHID_USAGE       0x0200  // recommended: 0x0100 to 0xFFFF
+#define PRODUCT_ID              0x0477
+#define RAWHID_USAGE_PAGE  0xFF00  // recommended: 0xFF00 to 0xFFFF
+#define RAWHID_USAGE       0x0100  // recommended: 0x0100 to 0xFFFF

 // These determine how much USB bandwidth is allocated (1=fastest)
 #define RAWHID_TX_INTERVAL 1
@@ -34,9 +34,9 @@
  *
  **************************************************************************/

-#define STR_PRODUCT             L"Teensyduino RawHID Device"
-#define STR_RAWHID     L"Teensyduino RawHID"
-#define STR_DEBUG      L"Emulated Arduino Serial"
+#define STR_PRODUCT             L"Rebootor"
+#define STR_RAWHID     L"Rebootor"
+#define STR_DEBUG      L"Rebootor"
 #define ENDPOINT0_SIZE          64

 // Some operating systems, especially Windows, may cache USB device

Then, I compiled the following Arduino sketch for the TEENSY2PP in rawhid USB mode:

volatile extern uint16_t reset_cnt;

void setup() {
  Serial.begin(9600);
  Serial.println(F("RawHID Example"));
  pinMode(27, INPUT_PULLUP);
}

void loop() {
     delay(100); // millis
        if (reset_cnt > 0) {
      reset_cnt--;
      if (reset_cnt == 0) {
        DDRB = 0, DDRC = 0, DDRD = 0;
        PORTB = 0xFF, PORTC = 0xFF, PORTD = 0xFF;
        digitalWriteFast(6, 0);
      }
    }

}

I then connected GND and port 27 (next to each other) of the TEENSY2PP with the PROGRAM/GND pins of my TEENSY36, and can successfully reboot and program the Teensy 3.6 using teensy_loader_cli -w -r -v --mcu=TEENSY36 out.hex

Find the .hex file for TEENSY2PP in rebootor.zip