You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
7.4 KiB

//=============================================================================
// Simple test to forward RAWHID and Seremu USB Host device
// It also forwards any Serial Emulation data it receives as well to Serial
// This sketch is very much like the main teensy example: USBtoSerial.ino
//
// This sketch needs to be built with USB Type of RawHID
//
// The main testing for this is to have a Teensy programmed with the example
// sketch: Examples -> _Teensy -> USBRawHID -> Basic
// plugged into the USBHost port.
//
// Which talks to the host test software you can download from:
// https://www.pjrc.com/teensy/rawhid.html
//
//
// This example is in the public domain
//=============================================================================
#include "USBHost_t36.h"
//=============================================================================
// Options
//=============================================================================
// uncomment the line below to output debug information
//#define DEBUG_OUTPUT
// Uncomment the line below to print out information about the USB devices that attach.
#define PRINT_DEVICE_INFO
//=============================================================================
// USB Objects
//=============================================================================
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
RawHIDController rawhid1(myusb);
USBSerialEmu seremu(myusb);
uint8_t buffer[512]; // most of the time will be 64 bytes, but if we support 512...
//=============================================================================
// optional debug stuff
//=============================================================================
#ifdef DEBUG_OUTPUT
#define DBGPrintf Serial.printf
#else
// not debug have it do nothing
inline void DBGPrintf(...) {
}
#endif
#ifdef PRINT_DEVICE_INFO
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 };
#endif
//=============================================================================
// Setup
//=============================================================================
void setup() {
while (!Serial && millis() < 5000) ; //wait up to 5 seconds
#ifdef __IMXRT1062__
if (CrashReport) {
Serial.print(CrashReport);
}
#endif
DBGPrintf("\n\nUSB Host RawHid and Seremu forwarding\n");
myusb.begin();
rawhid1.attachReceive(OnReceiveHidData);
}
//=============================================================================
// loop
//=============================================================================
void loop() {
uint16_t rd, wr, n;
myusb.Task();
// See if any RawHID USB packets are waiting for us.
n = RawHID.recv(buffer, 0); // 0 timeout = do not wait
if (n > 0) {
DBGPrintf("RawHID.recv(%u)", n);
rawhid1.sendPacket(buffer);
}
// check if any data has arrived on the USB virtual serial port
rd = Serial.available();
if (rd > 0) {
// check if the USB Host serial port is ready to transmit
wr = seremu.availableForWrite();
if (wr > 0) {
// compute how much data to move, the smallest
// of rd, wr and the buffer size
if (rd > wr) rd = wr;
if (rd > sizeof(buffer)) rd = sizeof(buffer);
// read data from the USB port
n = Serial.readBytes((char *)buffer, rd);
// write it to the USB Host serial port
DBGPrintf("S-U(%u %u)\n", rd, n);
seremu.write(buffer, n);
}
}
// check if any data has arrived on the USBHost serial port
rd = seremu.available();
if (rd > 0) {
// check if the USB virtual serial port is ready to transmit
wr = Serial.availableForWrite();
if (wr > 0) {
// compute how much data to move, the smallest
// of rd, wr and the buffer size
if (rd > wr) rd = wr;
if (rd > 80) rd = 80;
// read data from the USB host serial port
n = seremu.readBytes((char *)buffer, rd);
// write it to the USB port
DBGPrintf("U-S(%u %u):", rd, n);
Serial.write(buffer, n);
}
}
// Sort of the main Copy of the USBSerial code
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);
Serial.write(emu_buffer, rd);
}
#ifdef PRINT_DEVICE_INFO
// Optional.
UpdateActiveDeviceInfo();
#endif
}
bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
DBGPrintf("OnReceiveHidDta(%x %p %u)\n", usage, data, len);
RawHID.send(data, len);
return true;
}
#ifdef PRINT_DEVICE_INFO
// 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());
// }
}
}
}
}
#endif