#include "USBHost_t36.h"
// 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
//=============================================================================
// optional debug stuff
//=============================================================================
#ifdef DEBUG_OUTPUT
#define DBGPrintf Serial.printf
#else
// not debug have it do nothing
inline void DBGPrintf(...) {
}
#endif
//=============================================================================
// USB Objects
//=============================================================================
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
DMAMEM uint8_t rawhid_big_buffer[8 * 512] __attribute__((aligned(32)));
RawHIDController rawhid1(myusb, 0, rawhid_big_buffer, sizeof(rawhid_big_buffer));
USBSerialEmu seremu(myusb);
#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
//=============================================================================
// forward references
//=============================================================================
extern bool OnReceiveHIDData(uint32_t usage, const uint8_t *data, uint32_t len);
struct RX_DATA_STRUCTURE {
//put your variable definitions here for the data you want to send
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
long timestamp;
uint8_t id;
int16_t distance; // packet data.
float roll;
float pitch;
float yaw;
float altitude;
float pressure;
float temperature;
};
byte buffer[512];
byte rxBuffer[512];
//give a name to the group of data
RX_DATA_STRUCTURE mydata;
void setup() {
while (!Serial && millis() < 5000) ; //wait up to 5 seconds
#ifdef __IMXRT1062__
if (CrashReport) {
Serial.print(CrashReport);
}
#endif
Serial.printf("\n\nUSB Host RawHid File Transfers Host(master) side\n");
myusb.begin();
rawhid1.attachReceive(OnReceiveHIDData);
// check if any data has arrived on the USBHost serial port
forward_remote_serial();
// Optional.
UpdateActiveDeviceInfo();
pinMode(LED_BUILTIN, OUTPUT);
digitalWriteFast(LED_BUILTIN, LOW);
}
void loop() {
}
//=============================================================================
// OnReceiveHIDData - called when we receive RawHID packet from the USBHost object
//=============================================================================
bool OnReceiveHIDData(uint32_t usage, const uint8_t *data, uint32_t len) {
DBGPrintf("OnReceiveHidDta(%x %p %u)\n", usage, data, len);
memcpy(&mydata, data, sizeof(mydata));
Serial.printf("%d, %d, %d, %f, %f, %f, %f, %f, %f\n", mydata.id, mydata.timestamp,
mydata.distance, mydata.roll, mydata.pitch,
mydata.yaw, mydata.altitude, mydata.pressure, mydata.temperature);
return true;
}
//=============================================================================
//=============================================================================
void forward_remote_serial() {
uint16_t rd, wr, n;
uint8_t emu_buffer[512];
// 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 > sizeof(emu_buffer)) rd = sizeof(emu_buffer);
// read data from the USB host serial port
n = seremu.readBytes((char *)emu_buffer, rd);
// write it to the USB port
//DBGPrintf("U-S(%u %u):", rd, n);
Serial.write(emu_buffer, n);
}
}
}
//=============================================================================
// updateActiveDeviceInfo
//=============================================================================
// check to see if the device list has changed:
void UpdateActiveDeviceInfo() {
#ifdef PRINT_DEVICE_INFO
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) {
// rx_size = rawhid1.rxSize();
// Serial.printf(" RX Size:%u TX Size:%u\n", rx_size, rawhid1.txSize());
//}
}
}
}
#else
// we still want to find out if rawhid1 connected and if so what size is it.
static bool last_rawhid1 = false;
if (rawhid1 && !last_rawhid1) {
rx_size = rawhid1.rxSize();
DBGPrintf("rawhid1 connected rx:%u tx:%u\n", rx_size, rawhid1.txSize());
}
last_rawhid1 = rawhid1;
#endif
}