Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 22 of 22

Thread: T4.x support for Raw HID 512? wonder if it makes sense to add to system?

  1. #1
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007

    T4.x support for Raw HID 512? wonder if it makes sense to add to system?

    While pulling out the last few my hairs trying to figure out why in the FS Integration thread: https://forum.pjrc.com/threads/68139...ng-MTP-and-MSC
    why at times when we transfer a file to one of the storage areas on Teensy, sometimes we get incomplete transfers, other times maybe reboots... I thought I would play with Raw HID.

    This is not completely random as a lot of the MTP USB code is very similar to the raw hid support. Also sounded like a fun distraction while waiting for inspiration or answers to some of the pending issues in the integration.

    So I started playing with it and have some stuff working I believe. I have this up in a Fork/Branch of cores:
    https://github.com/KurtE/cores/tree/rawhid_512

    I also have it setup, on the T4.x to be able to build for either 64 or 512 by choosing different USB option... My boards.local.txt have:
    Code:
    teensy41.menu.usb.rawhid512=Raw HID 512
    teensy41.menu.usb.rawhid512.build.usbtype=USB_RAWHID512
    teensy41.menu.usb.rawhid512.fake_serial=teensy_gateway
    
    teensyMM.menu.usb.rawhid512=Raw HID 512
    teensyMM.menu.usb.rawhid512.build.usbtype=USB_RAWHID512
    teensyMM.menu.usb.rawhid512.fake_serial=teensy_gateway
    
    teensy40.menu.usb.rawhid512=Raw HID 512
    teensy40.menu.usb.rawhid512.build.usbtype=USB_RAWHID512
    teensy40.menu.usb.rawhid512.fake_serial=teensy_gateway
    Note: I added a couple of methods to RawHid to allow the sketch to see what is the size of transfers. As there are chances even if you build for 512 it will run at 64 if the host does not support High speed.

    I updated the Host side code, so far only Linux as don't know how to build for windows... Have not tried yet, my guess is, it will require installing additional stuff...

    With the Linux side, again there are methods to query the size of transfers.

    I have not played yet with the writes on Teensy to host, as I am mainly interested in emulating the SendObject functionality. Still more testing there, like introducing delays.

    Example sketch:
    Code:
    /* RawHID receive big 
      This example code is in the public domain.
    */
    
    // RawHID packets are always 64 bytes
    byte buffer[512];
    
    int rx_size;
    
    unsigned int packetCount = 0;
    uint32_t last_packet_number = (uint32_t) - 1;
    uint32_t packet_count = 0;
    elapsedMillis em;
    elapsedMillis emTotal;
    bool run_active = false;
    
    void setup() {
      while (!Serial);
      pinMode(13, OUTPUT);
      Serial.begin(9600);
      Serial.println(F("RawHID lots of input test"));
      rx_size = RawHID.rxSize();
    //  rx_size = 64;
      Serial.printf("RawHid RX Size: %d\n", rx_size);
      em = 0;
      Serial.println(F("Waiting for packets"));
    }
    
    
    void loop() {
      int n;
      n = RawHID.recv(buffer, 0); // 0 timeout = do not wait
      if (n > 0) {
        packet_count++;
        digitalToggleFast(13);
        // check Serial numbers
        uint32_t packet_number = 0;
        for (int i = 0; buffer[i] >= '0' && buffer[i] <= '9'; i++) {
          packet_number = packet_number * 10 + buffer[i] - '0';
        }
        if (packet_number == 0) {
          Serial.println("Looks like new run started");
          last_packet_number = 0;
          packet_count = 1;
          emTotal = 0;
        } else if (packet_number != (last_packet_number + 1)) {
          Serial.printf("Missing? cnt: %u, Last: %u cur:%u\n", packet_count, packet_number, last_packet_number);
        } else if ((buffer[8] != buffer[rx_size-2]) || (buffer[rx_size-1] != '\n')) {
          Serial.printf("msg format error: %u\n", packet_count);
        }
        if (buffer[7] == '$') {
          Serial.printf("Received end marker: %u %u Time:%u\n", packet_count, packet_number,
            (uint32_t)emTotal);
        }
        last_packet_number = packet_number;
        run_active = true;
        em = 0;
        if ((packet_count & 0x3ff) == 0) Serial.print(".");
        if ((packet_count & 0xffff) == 0) Serial.println();
      } else if (run_active && (em > 1000)) {
        Serial.printf("\nTimeout: %u %u\n", packet_count, last_packet_number);
        run_active = false;
        
      }
    }
    Linux code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <stdint.h>
    #include <string.h>
    
    #if defined(OS_LINUX) || defined(OS_MACOSX)
    #include <sys/ioctl.h>
    #include <termios.h>
    #elif defined(OS_WINDOWS)
    #include <conio.h>
    #endif
    
    #include "hid.h"
    
    #define MAX_PACKET_SIZE 512
    
    #define FILE_SIZE 22400000ul
    int packet_size;
    uint32_t count_packets;
    
    int main()
    {
    	int r;
    	char buf[MAX_PACKET_SIZE];
    
    	// C-based example is 16C0:0480:FFAB:0200
    	r = rawhid_open(1, 0x16C0, 0x0480, 0xFFAB, 0x0200);
    	if (r <= 0) {
    		// Arduino-based example is 16C0:0486:FFAB:0200
    		r = rawhid_open(1, 0x16C0, 0x0486, 0xFFAB, 0x0200);
    		if (r <= 0) {
    			printf("no rawhid device found\n");
    			return -1;
    		}
    	}
    	printf("found rawhid device\n");
    
    	printf("Starting output(%u)\n", count_packets);
    	printf("Rx Size:%d Tx Size:%d\n", rawhid_rxSize(0), rawhid_txSize(0));
    	packet_size = rawhid_txSize(0);
    	if (packet_size <= 0) {
    		printf("invalid size field");
    		return -1;
    	}
    	count_packets = FILE_SIZE / packet_size;
    
    	for (uint32_t packet_num = 0; packet_num < count_packets; packet_num++){
    		memset(buf, 'A' + (packet_num & 0xf), packet_size) ;
    		sprintf(buf, "%07u", packet_num);
    		buf[7] = (packet_num == (count_packets-1))? '$' : ' ';
    		buf[packet_size-1] = '\n';
    		rawhid_send(0, buf, packet_size, 100);
    		if ((packet_num & 0x1ff) == 0) printf(".");
    		if ((packet_num & 0xffff) == 0) printf("\n");
    	}
    	printf("\nDone...\n");
    	return 0;
    }
    I have included here update Rawhid host download, which is my WIP including above program. Note Makefile updated to build this one instead of main example.

    Does this make a difference?
    Well the example sketch tries to upload logically a 22mb file. With normal Rawhid this takes about 88 seconds, converting to 512 this now takes < 11 seconds. As expected 8 times faster.

    Again not sure if there is any interest in this... If not probably won't take it much farther.

    There is a minor issue in the HID descriptor where I say the size is still 64 as the count field is one byte... Probably a way to update, but not sure if anyone actually looks.

    Also might update USBHost_t35 hid support to handle it being plugged in, which would give a very fast transfer rate between two T4.xs...

    Now back to playing
    Attached Files Attached Files

  2. #2
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,867
    @KurtE
    Nice work - doubt I can be much help here - don't really use linux, only windows.

  3. #3
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Quote Originally Posted by mjs513 View Post
    @KurtE
    Nice work - doubt I can be much help here - don't really use linux, only windows.
    I hear you... I want to make it work on Windows as well.

    As a curiosity I tried on my windows machine open up the Ubuntu sub-system... I edited makefile to say windows.
    Installed make and it built... the .exe file... But trying to run it says it is for wrong architecture...
    I think it built for 32 bits and I am running 64 bits...

    Not sure how hard it is to get it to build 64 bits... Will try building in Visual studio... Have it feeling it will want lots of things installed to allow it to build.

    Would be interesting to know if anyone else has built the Rawhid stuff for windows using native windows tools?

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Quick update: Mostly talking to myself I was able to get the Windows version to build now

    I have it building two different ways:

    By the Makefile in an Ubuntu on Windows which looks like it is running 18.04...
    Note: I had to edit both sources and makefiles. The i586...ming32 stuff needed to be replaced by the ming64 stuff:
    I think I need to: sudo apt-get install mingw-w64 mingw-w64-tools

    Windows part of makefile changed to:
    Code:
    else ifeq ($(OS), WINDOWS)
    TARGET = $(PROG).exe
    CC = i686-w64-mingw32-gcc
    STRIP = i686-w64-mingw32-strip
    CFLAGS = -Wall -O2 -DOS_$(OS)
    LIBS = -lhid -lsetupapi
    endif
    Then hid_windows.c - was in header file hell for awhile... The set of includes that built yesterday:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <windows.h>
    #include <setupapi.h>
    #include <hidsdi.h>
    //#include <ddk/wdm.h>
    //#include <ddk/miniport.h>
    //#include <ddk/hidclass.h>
    //#include <hidsdi.h>
    //#include <hidclass.h>
    
    #include "hid.h"
    I was this morning also able to build it now using VS 2019 after installing SDK and WDK. I don't have a very clean project file, but it worked... It does run, I have not tried plugging in board yet to see if the new windows one will see the hid device.

    The next thing I would like to figure out here is how to detect when I connect, what the max packet length for that endpoint... Have that working in Linux...

    Wondering now if I should post the stuff here and/or create a github project? Did not see one...

    Now back to playing

  5. #5
    Junior Member
    Join Date
    Jun 2020
    Posts
    2
    If you are looking for people with an interest in this to continue.. I'm interested as having battled with the Rawhid stuff myself

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,509
    Just updated the VS2019 here - not sure I completed SDK and WDK install the other week ... with a github I could maybe build along.
    > SDK : Yes ( Win 11 )
    > WDK : installing

    DONE:
    Code:
    'Installing Windows Driver Kit...'
    - The following target products have been selected...
    - 	Visual Studio Enterprise 2019
    Quote Originally Posted by Inventor View Post
    If you are looking for people with an interest in this to continue.. I'm interested as having battled with the Rawhid stuff myself
    Having others play along is fun and helpful ... it's my main help here ...
    Last edited by defragster; 11-06-2021 at 12:53 AM.

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    I pushed up my WIP stuff up into a github project rawhid...

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,509
    Quote Originally Posted by KurtE View Post
    I pushed up my WIP stuff up into a github project rawhid...
    Got it - build fail:
    Code:
    Severity	Code	Description	Project	File	Line	Suppression State
    Warning	C26451	Arithmetic overflow: Using operator '+' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '+' to avoid overflow (io.2).	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\hid_WINDOWS.c	135	
    Error (active)	E1696	cannot open source file "hid.h"	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\SendALot.cpp	14	
    Error (active)	E0020	identifier "rawhid_open" is undefined	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\SendALot.cpp	28	
    Error (active)	E0020	identifier "rawhid_rxSize" is undefined	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\SendALot.cpp	40	
    Error (active)	E0020	identifier "rawhid_txSize" is undefined	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\SendALot.cpp	40	
    Error (active)	E0020	identifier "rawhid_send" is undefined	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\SendALot.cpp	53	
    Warning	C26451	Arithmetic overflow: Using operator '+' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '+' to avoid overflow (io.2).	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\hid_WINDOWS.c	89	
    Error	LNK2019	unresolved external symbol __imp_SetupDiEnumDeviceInterfaces referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol __imp_SetupDiGetDeviceInterfaceDetailW referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol __imp_SetupDiGetClassDevsW referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol HidP_GetCaps referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol HidD_GetAttributes referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol HidD_GetHidGuid referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol HidD_GetPreparsedData referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK2019	unresolved external symbol HidD_FreePreparsedData referenced in function rawhid_open	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\RawHid\hid_WINDOWS.obj	1	
    Error	LNK1120	8 unresolved externals	RawHid	C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\x64\Debug\RawHid.exe	1
    Moved the hid.h into src folder ... not sure what else ...

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Will look again tomorrow… today I am sort of out of it…

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,509
    Quote Originally Posted by KurtE View Post
    Will look again tomorrow… today I am sort of out of it…
    makes two of us

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Quote Originally Posted by defragster View Post
    makes two of us
    Feeling more with it today...

    I think one issue with the stuff I uploaded was I had a hard coded path in the include directory list... Trying to make sure it is now resolved. I pushed up a change
    to convert it to ..\..\.. Will see if that resolved it.

    Note: the Ubuntu window works for me as well.

  12. #12
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Pushed up a few more changes today, both in cores and now the rawhid library.

    Cores: updated the HID report, such that it says the report data is now 512 bytes long (when appropriate). Could not do this directly as the count is mainly by a repeat count which is only one byte... But instead change the underlying data size to be 64 bits instead of 8 bit...

    in the rawhid project:
    I now include both of the test sketches I have, including building a large file... Actually not needed here.
    And the send a logically large file code which is main test...

    Tested on windows, that it could run with the hid test program here. in either 64 or 512 byte packet sizes...

  13. #13
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,867
    Finally got done with my chores and updated cores, sketch and VS project. Did have to update Linker Input to add hib.lib and setupapi.lib as well as changing the hid.h path in SendALot.cpp. But it worked at 512:
    Click image for larger version. 

Name:	Capture.jpg 
Views:	16 
Size:	52.8 KB 
ID:	26424

    Would be interesting it would work USB1 to USB1

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,509
    Cool.
    Got copy of KurtE/cores/tree/rawhid_512

    And have an EXE building version of: KurtE/RawHid

    ... but chores now ...

  15. #15
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    USB1 to USB1... Is this asking saying SerUSB1? Or USB Host...

    As for USBHost having a rawhid plugged in... Playing with it now... so far extracted some RAWHID test code out of several of the examples and creating it's own sample...

    So far I have:
    Code:
    // Simple test of USB Host Mouse/Keyboard
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    
    
    USBHost myusb;
    USBHub hub1(myusb);
    USBHub hub2(myusb);
    USBHIDParser hid1(myusb);
    USBHIDParser hid2(myusb);
    
    RawHIDController rawhid1(myusb);
    RawHIDController rawSEMU(myusb, 0xffc90004);
    
    USBDriver *drivers[] = {&hub1, &hub2, &hid1, &hid2};
    #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
    const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "HID1" , "HID2"};
    bool driver_active[CNT_DEVICES] = {false, false, false, false};
    
    // Lets also look at HID Input devices
    USBHIDInput *hiddrivers[] = {&rawhid1, &rawSEMU};
    #define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
    const char * hid_driver_names[CNT_DEVICES] = {"RawHid1", "rawSEMU"};
    bool hid_driver_active[CNT_DEVICES] = {false, false};
    void setup()
    {
      while (!Serial) ; // wait for Arduino Serial Monitor
    
      if (CrashReport) {
        Serial.print(CrashReport);
      }
    
      Serial.println("\n\nUSB Host Testing");
      Serial.println(sizeof(USBHub), DEC);
      myusb.begin();
    
      rawhid1.attachReceive(OnReceiveHidData);
      rawSEMU.attachReceive(OnReceiveSEMU);
    }
    
    
    void loop()
    {
      myusb.Task();
      UpdateActiveDeviceInfo();
      if (Serial.available()) {
        int ch = Serial.read(); // get the first char.
        while (Serial.read() != -1) ;
      }
    
    
      // See if we have some RAW data
      if (rawhid1) {
        int ch;
        uint8_t buffer[64];
        uint8_t count_chars = 0;
        memset(buffer, 0, sizeof(buffer));
        if (Serial.available()) {
          while (((ch = Serial.read()) != -1) && (count_chars < sizeof(buffer))) {
            buffer[count_chars++] = ch;
          }
          rawhid1.sendPacket(buffer);
        }
      }
    }
    
    // check to see if the device list has changed:
    void UpdateActiveDeviceInfo() {
      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);
    
            // Note: with some keyboards there is an issue that they don't output in boot protocol mode
            // and may not work.  The above code can try to force the keyboard into boot mode, but there
            // are issues with doing this blindly with combo devices like wireless keyboard/mouse, which
            // may cause the mouse to not work.  Note: the above id is in the builtin list of
            // vendor IDs that are already forced
          }
        }
      }
    
      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);
          }
        }
      }
    
    }
    bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
      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;
    }
    
    bool OnReceiveSEMU(uint32_t usage, const uint8_t *data, uint32_t len) {
      // Lets trim off trailing null characters.
      while ((len > 0) && (data[len - 1] == 0)) {
        len--;
      }
      if (len) {
        Serial.print("RawHid Serial: ");
        Serial.write(data, len);
      }
    }
    And it detects that it is plugged in...
    Code:
    USB Host Testing
    960
    *** Device HID1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
    *** Device HID2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
    *** HID Device RawHid1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
    *** HID Device rawSEMU 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560

    So if the sketch plugged in should send something on its Seremu, I will forward it... But right now not getting anything as the sketch on other side has;
    while (!Serial) ;

    And my Seremu code is not doing what SEREMU needs to tell other side, I am connected... Could avoid this by using timeout on this... But taking a quick look

  16. #16
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,867
    USB1 to USB1... Is this asking saying SerUSB1? Or USB Host...
    Meant USB_Host

    Wanted can I tell you great minds think a like but need to stop now - wrist. Its a fun problem isn't it

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,509
    Seems to be building ... not as far as knowing what is going on yet:
    Code:
    C:\T_Drive\tCode\pjrc_latency_test\RawHid\VS\RawHid\x64\Debug>RawHid.exe
    $$$ Hid report sizes In:513 Out: 513
    found rawhid device
    Starting output(0)
    Rx Size:512 Tx Size:512
    .
    .....................................................................................
    Done...
    Edit to TSET for 'r' rawhid512: TSet.cmd
    Code:
    ...
    Echo 	o :: mtpserial
    Echo 	r :: rawhid512
    Echo.
    Choice /C 123456789abcdefghijklmnor /M "What USB"
    If Errorlevel 25 Goto U25
    If Errorlevel 24 Goto U24
    ...
    REM >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   USB
    
    :U25
    set usb=rawhid512
    goto BeDone
    
    :U24
    ...
    Update: TyComm doesn't get the 'Serial.print' from the sketch - but T_sermon does:
    Code:
    RawHID lots of input test
    RawHid RX Size: 512
    Waiting for packets
    Looks like new run started
    Missing? cnt: 5, Last: 9165 cur:3
    .........................
    TyComm 'connects' - but that output was buffered and showed up when T_sermon was opened.

    Output is after it completed the 'Done' pass - then after a wait ( maybe the 5 missing? ) I restarted the EXE.
    Last edited by defragster; 11-07-2021 at 06:47 AM.

  18. #18
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    I am playing again this morning... Trying to make it work with USBHost...

    Just having some fun... Will pull in you tset changes soon!

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Making progress on supporting rawhid512 in usb host... can still improve it...

    Pushed up more changes in my fork/branch of usbhost_t36 fs_integration...

    Here is wip sketch:
    Code:
    // Simple test of USB Host Mouse/Keyboard
    //
    // This example is in the public domain
    
    #include "USBHost_t36.h"
    
    
    USBHost myusb;
    USBHub hub1(myusb);
    USBHub hub2(myusb);
    USBHIDParser hid1(myusb);
    USBHIDParser hid2(myusb);
    
    DMAMEM uint8_t rawhid_big_buffer[2048] __attribute__ ((aligned(32)));
    RawHIDController rawhid1(myusb, 0, rawhid_big_buffer, sizeof(rawhid_big_buffer));
    USBSerialEmu seremu(myusb);
    
    USBDriver *drivers[] = {&hub1, &hub2, &hid1, &hid2};
    #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
    const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "HID1" , "HID2"};
    bool driver_active[CNT_DEVICES] = {false, false, false, false};
    
    // Lets also look at HID Input devices
    USBHIDInput *hiddrivers[] = {&rawhid1, &seremu};
    #define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
    const char * hid_driver_names[CNT_DEVICES] = {"RawHid1", "SerEmu"};
    bool hid_driver_active[CNT_DEVICES] = {false, false};
    
    #define FILE_SIZE 22400000ul
    int packet_size;
    int count_packets;
    
    int packet_num = -1; // say we are not active
    
    Stream* SerialEmuEcho;
    
    void setup()
    {
      while (!Serial) ; // wait for Arduino Serial Monitor
    
      if (CrashReport) {
        Serial.print(CrashReport);
      }
      Serial.println("\n\nUSB Host Testing");
      Serial.println(sizeof(USBHub), DEC);
    #if defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL)
      SerialUSB1.begin(115200);
      SerialEmuEcho = &SerialUSB1;  
    #else
      SerialEmuEcho = &Serial;  
    #endif  
    
    
      myusb.begin();
    
      rawhid1.attachReceive(OnReceiveHidData);
    }
    
    uint8_t buf[512];
    
    void loop()
    {
      myusb.Task();
      UpdateActiveDeviceInfo();
      if (Serial.available()) {
        while (Serial.read() != -1) ;
        if (rawhid1 && (packet_num == -1)) {
          packet_num = 0;
          packet_size = rawhid1.txSize();
          count_packets = FILE_SIZE / packet_size;
    
          Serial.println("Start sending rawhid data");
        } else {
          Serial.println("End sending Rawhid data");
        }
      }
    
      if (seremu) {
        uint8_t emu_buffer[64];
        uint16_t cb;
        if ((cb = seremu.available())) {
          if (cb > sizeof(emu_buffer)) cb = sizeof(emu_buffer);
          int rd = seremu.readBytes(emu_buffer, cb);
          SerialEmuEcho->write(emu_buffer, rd);
        }
      }
    
      // See if we have some RAW data
      if (rawhid1 && (packet_num >= 0) ) {
        memset(buf, 'A' + (packet_num & 0xf), packet_size) ;
        snprintf((char *)buf, sizeof(buf), "%07u", packet_num);
        buf[7] = (packet_num == (count_packets - 1)) ? '$' : ' ';
        buf[packet_size - 1] = '\n';
        if (rawhid1.sendPacket(buf, packet_size)) {
          if ((packet_num & 0x1ff) == 0) Serial.print("+");
          if ((packet_num & 0xffff) == 0) Serial.println();
          packet_num++;
          if (packet_num == count_packets) {
            Serial.println("\nDone...");
            packet_num = -1;
          }
        }
      }
    }
    
    // check to see if the device list has changed:
    void UpdateActiveDeviceInfo() {
      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);
    
            // Note: with some keyboards there is an issue that they don't output in boot protocol mode
            // and may not work.  The above code can try to force the keyboard into boot mode, but there
            // are issues with doing this blindly with combo devices like wireless keyboard/mouse, which
            // may cause the mouse to not work.  Note: the above id is in the builtin list of
            // vendor IDs that are already forced
          }
        }
      }
    
      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);
            if (hiddrivers[i] == &seremu) {
              Serial.printf("   RX Size:%u TX Size:%u\n", seremu.rxSize(), seremu.txSize());
            }
            if (hiddrivers[i] == &rawhid1) {
              Serial.printf("   RX Size:%u TX Size:%u\n", rawhid1.rxSize(), rawhid1.txSize());
            }
          }
        }
      }
    
    }
    bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
      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;
    }
    So talks to same sketch on the rawhid disk that was testing host stuff with...

    Edit: addded above sketch to my rawhid project.
    Last edited by KurtE; 11-07-2021 at 08:34 PM.

  20. #20
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,509
    Quote Originally Posted by KurtE View Post
    I am playing again this morning... Trying to make it work with USBHost...

    Just having some fun... Will pull in you tset changes soon!
    Good work Kurt. I updated Defragster/Tset - just that change to TSet.cmd for WIP with manual Boards.txt edit to work.

    Interesting that RawHid on T_sermon works to support Serial.print and TyComm loses it? Wonder if @koromix might have a way to enable that ...
    > is PJRC T_sermon rawhid512 aware ? to make that work or is there something else going on that breaks TyComm ?


    BTW: When I moved TSET.cmd into github folder for upload --- did a file copy with Win 11 File Explorer and NO 15 SECOND WAIT !!!!!! Did a purge and rebuild of the 'Index' file - also deleted two random REG keys that may have been part of it.

  21. #21
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Quick update:

    I now have it working reasonably well with USBHost talking to the Rawhid or Rawhid 512. Updated the HID class to detect the size of the rx and tx pipes...

    enhanced the HID calls to allow the hid object that claims it to provide external larger buffers, now up to 4 of them for rx and tx...

    Sketch also talks using the seremu code in USBHost... Fixed a seremu bug... Sketch detects if SerialUSB1 exists.. if so forwards to it...

    Right now does the send a large index file like data to the other test sketch...

    Sample run:
    Serial:
    Code:
    USB Host RawHid and Seremu Testing
    960
    *** Device HID1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
    *** Device HID2 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
    Rawhid Claim: 16c0:486 usage: ffab0200
        >> setTXBuffers: 20200000 20200200 20200400 20200600
        >> setRXBuffers: 20200800 20200a00 20200c00 20200e00
    Rawhid Claim: 16c0:486 usage: ffc90004
    *** HID Device RawHid1 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
       RX Size:512 TX Size:512
    *** HID Device SerEmu 16c0:486 - connected ***
      manufacturer: Teensyduino
      product: Teensyduino RawHID
      Serial: 10883560
       RX Size:64 TX Size:32
    
    *** press any keyboard keys to start sending data ***
    Start sending rawhid data
    +
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Done...
    
    *** press any keyboard keys to start sending data ***
    SerialUSB1:
    Code:
    RawHID lots of input test
    RawHid RX Size: 512
    Waiting for packets
    Looks like new run started
    ..........................................Received end marker: 43750 43749 Time:32888
    
    Timeout: 43750 43749
    Not as fast as talking to PC, may check to see the timing settings...

    back to other diversions.

  22. #22
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,007
    Now back to something complete random.... Sort of...

    Today I played a little more with the Rawhid stuff to see if I can make it work closer to the MTP transfer code to see if I could replicate maybe losing messages.

    One main difference is RAWHID uses interrupt transfers and MTP uses bulk transfers... So hacked up another variant of the RAWHID that uses bulk transfers...

    So hacked it pushed up a cores branch rawhid_512_bulk that had another USB type...

    boards.local.txt
    Code:
    teensy41.menu.usb.rawhid512=Raw HID 512
    teensy41.menu.usb.rawhid512.build.usbtype=USB_RAWHID512
    teensy41.menu.usb.rawhid512.fake_serial=teensy_gateway
    
    teensyMM.menu.usb.rawhid512=Raw HID 512
    teensyMM.menu.usb.rawhid512.build.usbtype=USB_RAWHID512
    teensyMM.menu.usb.rawhid512.fake_serial=teensy_gateway
    
    teensy40.menu.usb.rawhid512=Raw HID 512
    teensy40.menu.usb.rawhid512.build.usbtype=USB_RAWHID512
    teensy40.menu.usb.rawhid512.fake_serial=teensy_gateway
    
    teensy41.menu.usb.rawhid512B=Raw HID 512 Bulk
    teensy41.menu.usb.rawhid512B.build.usbtype=USB_RAWHID512B
    teensy41.menu.usb.rawhid512B.fake_serial=teensy_gateway
    
    teensyMM.menu.usb.rawhid512B=Raw HID 512 Bulk
    teensyMM.menu.usb.rawhid512B.build.usbtype=USB_RAWHID512B
    teensyMM.menu.usb.rawhid512B.fake_serial=teensy_gateway
    
    teensy40.menu.usb.rawhid512B=Raw HID 512 Bulk
    teensy40.menu.usb.rawhid512B.build.usbtype=USB_RAWHID512B
    teensy40.menu.usb.rawhid512B.fake_serial=teensy_gateway

    I then also hacked up my rawhid project, hid code so far on linux to detect it is BULK and use the bulk api instead of the interrupt api...
    So far only on write.

    Plus updated the test sketch to detect it and then try to send 32 packets at a time...
    Appears to be working... Not seeing any lost packets yet.

    Click image for larger version. 

Name:	Screenshot from 2021-11-29 15-58-43.png 
Views:	12 
Size:	156.2 KB 
ID:	26724
    Last edited by KurtE; 11-30-2021 at 12:16 AM.

Posting Permissions

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