USBHOST_t36 direct write

The short answer is no, or at least not to the extent your question makes any sense in the context of USB protocol.

You really need to read at least chapter 4 and maybe part of chapter 5, 8 and 9 from the USB 2.0 spec. Here's just the PDF, to save you a little time & trouble finding it on the USB website.

https://www.pjrc.com/teensy/beta/usb20.pdf

Aside from lacking any context or explanation, your question makes little sense because "data" is a rather generic word. USB has tokens, transfers, endpoints/pipes, etc.

But to try for a longer but still quick answer, what you can do is add a driver file to USBHost_t36 which inherits the USBDriver class and implements the required virtual functions. In your constructor, create some pipe and transfer structs and give them to the library to use. Your claim() function should look at the descriptor data and return true if the VID and PID are the device you wish to use. Before returning, you would create pipes to communicate with specific endpoints in the device. See the comments in USBHost_t36 and the drivers already in the library for details. After creating the pipe, you probably also want to assign a callback function to it. Again, see the existing drivers for examples.

Once you have created a pipe, then you can call queue_Data_Transfer(). You'll pass it the pipe, your buffer to send or receive data, the number of bytes, and a pointer to your instance (almost always "this"). One of those transfer structs you created will be used to instruct the USB hardware to execute your transfer at the next opportunity. The USB host controller automatically manages USB bandwidth, so when it will actually execute your transfer depends on which transfer type and other info you used when creating the pipe, which hopefully was done to match the specs the device gave you in its descriptor data. Obviously your buffer needs to be a class member or static/global, since any local variable may go out of scope before the transfer actually executes. When the transfer is complete, the library will call your callback function to notify you.

There isn't any way to just arbitrarily send data to a specific PID/VID. USB doesn't even use that info for actual communication. Devices are dynamically assigned a 7 bit address as they're detected. The hardware uses a complex group of lists of devices (which have the 7 bit address) and pipes (which have the 4 bit endpoint number) and automatically manages bandwidth among all of them, executing pending transfers that have been assigned to the pipes. To send or receive actual transfers, you need to get to the point where pipes are created, so you can queue transfers.

One nice thing is the USB host controller automatically takes care of all the lower-level token (packet) stuff, so you can queue transfers of any length. The hardware will automatically divvy it into as many tokens as needed. You don't need to worry about actual packet sizes, other than when you create the pipe object, which is how the hardware knows what max packet size to use for that endpoint.

This stuff will probably make more sense after you've read some of the USB spec.
 
Last edited:
Thank Paul,


I have 1 X-Keys keyboard with 16 buttons and LEDs and a normal keyboard.
These are connected to a USB hub.

These are linked with "USBHIDParser hid1 (myusb);" and "USBHIDParser hid2 (myusb);"

When I only connect the X-Keys it works fine. But when I add the normal keyboard, it no longer works. What am I doing wrong and how can I improve it.

Always thanks.
 
If you look at the Joystick example in the Serial examples directory think you may find your answer. You would just be substituting keyboard for joystick.

If you post your a simple version of your code that illustrates the what you are doing maybe we can help you with what you are doing wrong or give you some advice.
 
Hai,

Here is a simple version of the sketch, when I only connect the "X-Keys" keyboard, the leds work fine. When I connect a normal and the "X-Keys" keyboard, it no longer works.

Thanks in advance.

Code:
#include "USBHost_t36.h"

USBHost myusb;
USBHub hub1(myusb);

KeyboardController keyboard1(myusb);
KeyboardController keyboard2(myusb);

USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);

void setup() {
  while (!Serial) ; // wait for Arduino Serial Monitor
  myusb.begin();
  keyboard1.attachPress(OnPress);
  keyboard2.attachPress(OnPress);
    
  delay (1000);
  Serial.println("==================================================================================");
  uint8_t rpt[33];
  rpt[0] = 180; //  Set Frequency of Flash
  rpt[1] = 100;
  hid1.sendPacket(rpt,-1);
  
  delay(100);

  rpt[0] = 187; //  Set brightest.
  rpt[1] = 200; 
  hid1.sendPacket(rpt);

  delay(100);

  rpt[0] = 179; //  Set LED red.
  rpt[1] = 7;
  rpt[2] = 1; 
  hid1.sendPacket(rpt);

  delay(2000);

  rpt[0] = 179; //  Set LED green.
  rpt[1] = 6;
  rpt[2] = 0; 
  hid1.sendPacket(rpt);
 
  delay(2000);

  rpt[0] = 179; //  Set LED red blink.
  
  rpt[1] = 7;
  rpt[2] = 2; 
  hid1.sendPacket(rpt);

  delay(2000);
  
  Serial.println("==================================================================================");
}


uint8_t i, m = 1;
unsigned long mmillis = 0;

void loop(){
  myusb.Task();

  if (millis() > mmillis) {
    mmillis = millis() + 500;
    uint8_t rpt[33];

    uint8_t keyId = i;
    uint8_t mode = m;

    rpt[0] = 181;
    rpt[1] = keyId + (2 * (keyId / 6));
    rpt[2] = mode;
    hid1.sendPacket(rpt);
    
    i++;
    if (i == 16) {
      i = 0;
      m++;
      if (m == 3) m = 0;
     }
   }
 }

void OnPress(int key)
{
  Serial.print("key '");
  Serial.print((char)key);
  Serial.print("'  ");
  Serial.println(key);
}
 
Back
Top