Using a teensy board to act as host for a USB device (not common devices!)

Status
Not open for further replies.

monamomeni

New member
Hi all,

I am coming to this forum because I am already stuck with a USBhost project. I have a board from Texas Instrument which interfaces to PC with a USB cable. There is a Windows application and a driver that must be installed on PC so that data from TI board is seen on the application. I want to have transmitted data on a microcontroller for further processing, but there is no such function implemented on this board.

This is how I got involved in the work of communicating with TI board over USB. I have tried USBhost library of MKR1000 (with Samd21 core Cortex M0 and native USB port) and connected MKR to TI with OTG cable and external power. The library couldn't read the descriptors of TI board. It however read correctly the descriptors of a generic thumb drive.. So, I figured MKR library is not yet fully functional to work with my board.

How generalized and mature a teensy USBhost library is?

A general USB Analyzer shows that TI board is of class 2 (CDC) which basically should work like a virtual serial COM port. My question is, which teensy board should I use and if anyone understand this problem and have any recommendation for me. I am not an advanced programmer to go into details of drivers yet. But if it is possible and you know about it, please help me find a way to speak to this board!

Thanks and cheers! :D::cool:
 
Teensy 3.6 is currently the only Teensy model with USB host capability. To connect USB devices, you'd need this cable.

https://www.pjrc.com/store/cable_usb_host_t36.html

The library for USB host mode is USBHost_t36. It comes with Teensyduino, and you can also get the code on github.

https://github.com/PaulStoffregen/USBHost_t36

Whether it would work with this device is a good question. We do have a driver for CDC serial, but it's only been tested with a few boards. Here's the driver code.

https://github.com/PaulStoffregen/USBHost_t36/blob/master/serial.cpp

The claim() function is the code which looks at the descriptors and decides if this driver can service the whole device or an interface. If you read through the code, it has many places which return false. If this TI device really is a CDC serial with something a bit strange in its descriptors, maybe you could get it working by just replacing the claim() function. Maybe even just hard-code the stuff like rx_ep, rx_size, tx_ep, tx_size and so on, then return true. While that function is long, because it supports 4 different types of USB serial, hopefully you can see the basic idea that is tries to discover the info it needs and writes to the key variables that control how it will access the device.

If that TI device is something substantially different than CDC serial (2 bulk endpoints for the data flow in each direction) then you'd need to write a driver for whatever it really does with its endpoints.
 
I know you can probably get the same information with Windows... But what I have done while trying to support more devices with the usbhost library, is to try plugging the board into some linux board. Could be a PC running Linux, have also done with other boards like Odroid, UP, and maybe RPI...

Is to have the Linux board running and plug in the new adapter or the like, and then try to get as much information about the chip as I can...

Things like get the USB information for it... By using the command lsusb.

I first use the command to get a list of devices, and then get the verbose information for it. I believe the command would look something like:
lsusb -v -d <vid:pid>

Where you find the vid/pid as part of the generic lsusb command.

I would see if Linux gives me any hints about drivers or the like, probably using a command like: dmesg | tail -25
May have to adjust the count depending on what is going on.

If the device is a HID device which it does not sound like it is, than I would try to get that information as well. (more details in other threads).

I would then try it on Teensy 3.6, probably running the Mouse.ino example program. But before building the sketch I would enable debug output in the library.
Edit: usbhost_t36.h and uncomment the line: //#define USBHOST_PRINT_DEBUG
which is around line 59

I believe that should enable the claim code for serial to print out a lot more information.

We might be able to give some additional hints if you post some of the above information.

Good luck

Kurt
 
Thank you very much Paul and Kurt for this helpful information. I am way behind getting test with teensy but i will try my best to follow instructions and provide feedback :)
The device is really like a COM port on windows, but the strange thing is that before I start the application and tell it to capture data (using buttons in Graphical user interface), it doesn't send any information.

Once the data capture is started, I can see it uses two endpoints 0x82 and 0x02 for UP and DOWN direction and the transmission type is Bulk or Interrupt Transfer. Do you think the triggers in application layer is a barrier for the USBhost library to connect to the board?

Here's device descriptors on Windows:

Connection Information
Port: 3
Speed: Full Speed
Device address: 1
Open pipes: 3
Connection status: Device connected

Device Descriptor
USB version: 2.0
Device class: 0x2 - Communications
Device subclass: 0x0 - Unknown
Device protocol: 0x0 - Unknown
Control pipe max size: 8 bytes
Vendor ID: 0x2047 (Texas Instruments)
Product ID: 0x300 (Unknown)
Product version: 2.0
Manufacturer: Texas Instruments
Product: MSP430-USB Example
Serial Number: 9283806E1C001000
Configurations: 1


descriptors[0] = "Configuration Descriptor"
bLength = 9
bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE (2)
wTotalLength = 67
bNumInterfaces = 2
bConfigurationValue = 1
iConfiguration = 4
Reserved = 0
SupportsRemoteWakeup = 0
SelfPowered = 0
PoweredByBus = 1
MaxPower = 0x32 -> 100 mA

descriptors[1] = "Interface Descriptor"
bLength = 9
bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE (4)
bInterfaceNumber = 0
bAlternateSetting = 0
bNumEndpoints = 1
bInterfaceClass = UsbCommunication (2)
bInterfaceSubClass = 2
bInterfaceProtocol = 1
iInterface = 5

descriptors[2] = "Class-Specific Interface Descriptor"
bLength = 5
bDescriptorType = CS_INTERFACE (36)
bDescriptorSubtype = 0
comm_interface =
bcdCDC = 272

descriptors[3] = "Class-Specific Interface Descriptor"
bLength = 5
bDescriptorType = CS_INTERFACE (36)
bDescriptorSubtype = 1
comm_interface =
call_capatibilities =
controls =
UseClassInterface = 0
SelfControl = 0
Reserved = 0
bmCapatibilities = 0
bDataInterface = 00000001

descriptors[4] = "Class-Specific Interface Descriptor"
bLength = 4
bDescriptorType = CS_INTERFACE (36)
bDescriptorSubtype = 2
comm_interface =
abstract_control_capatibilities =
controls =
FeatureSupport = 0
LineStateSupport = 1
Send_Break_Support = 0
NotificationSupport = 0
Reserved = 0
bmCapatibilities = 00000010

descriptors[5] = "Class-Specific Interface Descriptor"
bLength = 5
bDescriptorType = CS_INTERFACE (36)
bDescriptorSubtype = 6
comm_interface =
bMasterInterface = 0
bSlaveInterface = 1

descriptors[6] = "Endpoint Descriptor"
bLength = 7
bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE (5)
bEndpointAddress = 1
Reserved = 0
Direction = Input
type = Interrupt (3)
reserved = 0
wMaxPacketSize = 64
bInterval = 255

descriptors[7] = "Interface Descriptor"
bLength = 9
bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE (4)
bInterfaceNumber = 1
bAlternateSetting = 0
bNumEndpoints = 2
bInterfaceClass = UsbCommData (10)
bInterfaceSubClass = 0
bInterfaceProtocol = 0
iInterface = 0

descriptors[8] = "Endpoint Descriptor"
bLength = 7
bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE (5)
bEndpointAddress = 2
Reserved = 0
Direction = Output
type = Bulk (2)
reserved = 0
wMaxPacketSize = 64
bInterval = 255

descriptors[9] = "Endpoint Descriptor"
bLength = 7
bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE (5)
bEndpointAddress = 2
Reserved = 0
Direction = Input
type = Bulk (2)
reserved = 0
wMaxPacketSize = 64
bInterval = 255
 
The descriptor info looks like pretty standard CDC-ACM (USB serial) protocol. According to the descriptors, it really should work.

Do you think the triggers in application layer is a barrier for the USBhost library to connect to the board?

This is merely guesswork, but if (a pretty big if) the proprietary Windows application is sending some special command or message to get that device to start sending data, and you don't know what that command is or how to send it, then obviously that's going to be a stumbling block in any effort to get it working on other platforms. You might need to somehow capture the data that application sends, so you can learn the special command. There are 2 ways to capture USB data. I have personally never used the software-only way, but I've been told there are free or inexpensive Windows programs which can do this. The hardware way is expensive, but works extremely well and can even use a different computer to do the capture.
 
Is it possible to detect *ANY* device being plugged in and get it's VID/PID?
I plan to use USBSerial, and have it working (example worked 1st time out of the box!), but I also want to know when *ANY* device is plugged in, even something that USBHost_t36 doesn't support, and print a simple diagnostic message with that PID/VID.
 
The answer is probably...

You could develop a simple class that inherits from one or more of the USBHost base classes and implement a few of the methods..

But part of it may depend on what type of object you wish to detect.

Example simple USB generic object...

You could implement a subclass of USBDriver. And when you are called with the claim method, it has a handle to the Device_t object, where you can extract the dev->idVendor, dev->idProduct
for VID/PID

There are two levels of this claim code. You can claim at the device level or you can claim at the interface level...

Now if this device is a HID type device and a USBHIDParser claims the object (probably at the interface level), The Hid Parser code will loop through the HID Collections and call off to any classes that implement the USBHIDInput class and call their claim_collection with a pointer to the HIDParser as well as the device structure where you can get the PID/VID.

Then there is Bluetooth (although not yet into main branch)...

Wondering if we maybe should also provide some method/object/callback that can be called at some different events, so the UI can provide additional information.
 
Status
Not open for further replies.
Back
Top