I was working on some other USBHost extensions and found I needed debug information that was
being generated by a Teensy plugged into the USB host port that was output using Serial Emulation
to be available. Likewise I wanted the ability to feed data back to that other Teensy.
So I decided to create USBHost_t36 implementation to handle the USB types that include Serial Emulation
USBSerialEmu class.
The USBSerialEmu code was based on the USBSerial code as well as RAWHID. I found that there was a bug
in the Receiving of data that was sent by the remote SEREMU output, I would miss the first character
Fixed.
USBSerial fixed same bug in reading first character
@PaulStoffregen - This stuff was extracted from my MTP Device USB Host code, which is currently only in a test state.
I do have a simple sketch I ran, that echoes anything it receives from either Serial or Serial EMU on the board plugged into the host and echoes it on SerialUSB1.
// USBSerialEMU - Simple USBSerial or USBSerialEmu echo to SerialUSB1...
//
// This example is in the public domain
#include <USBHost_t36.h>
USBHost myusb;
USBHub hub1(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBSerial_BigBuffer userial(myusb, 1); // USB Serial big or little...
USBSerialEmu seremu(myusb);
#if !defined(USB_TRIPLE_SERIAL) && !defined(USB_DUAL_SERIAL)
#error Program uses SerialUSB1 so needs Dual or Tripple Serial
#endif
USBDriver *drivers[] = {&hub1, &hid1, &hid2, &userial};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "HID1", "HID2", "USerial"};
bool driver_active[CNT_DEVICES] = {false, false};
// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&seremu};
#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_DEVICES] = {"seremu"};
bool hid_driver_active[CNT_DEVICES] = {false, false};
Stream *debug_stream = nullptr;
elapsedMillis emBlink = 0;
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(2000000);
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Serial Emulation Device Test Program");
myusb.begin();
}
char buffer[512];
void loop()
{
if (emBlink > 500) {
emBlink = 0;
digitalToggleFast(13);
}
myusb.Task();
CheckHostDevicesChanged();
processDebugStreams();
}
void CheckHostDevicesChanged()
{
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);
}
}
}
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);
}
}
}
}
void processDebugStreams()
{
//==============================================
// Debug stream stuff
if (seremu) debug_stream = &seremu;
else if (userial) debug_stream = &userial;
else debug_stream = nullptr;
uint16_t avail;
uint16_t avail_for_write;
if (debug_stream) {
if ((avail = debug_stream->available())) {
avail_for_write = SerialUSB1.availableForWrite();
if (avail > avail_for_write) avail = avail_for_write;
if (avail > sizeof(buffer)) avail = sizeof(buffer);
debug_stream->readBytes(buffer, avail);
SerialUSB1.write(buffer, avail);
}
if ((avail = SerialUSB1.available())) {
avail_for_write = debug_stream->availableForWrite();
if (avail > avail_for_write) avail = avail_for_write;
if (avail > sizeof(buffer)) avail = sizeof(buffer);
SerialUSB1.readBytes(buffer, avail);
debug_stream->write(buffer, avail);
Serial.printf("USB1->");
Serial.write(buffer, avail);
}
}
}
I was working on some other USBHost extensions and found I needed debug information that was being generated by a Teensy plugged into the USB host port that was output using Serial Emulation to be available. Likewise I wanted the ability to feed data back to that other Teensy.
So I decided to create USBHost_t36 implementation to handle the USB types that include Serial Emulation USBSerialEmu class.
The USBSerialEmu code was based on the USBSerial code as well as RAWHID. I found that there was a bug in the Receiving of data that was sent by the remote SEREMU output, I would miss the first character Fixed.
USBSerial fixed same bug in reading first character
@PaulStoffregen - This stuff was extracted from my MTP Device USB Host code, which is currently only in a test state.
I do have a simple sketch I ran, that echoes anything it receives from either Serial or Serial EMU on the board plugged into the host and echoes it on SerialUSB1.