USB-Host - How to begin?

Status
Not open for further replies.
Hi Frank,

Not sure the second one has HID or not...

But again maybe try plugging it into T3.6 or T4.x with one of the USBHost_t36 examples like I mentioned.
And at about line 62 in USBHost_t36.h uncomment the line: //#define USBHOST_PRINT_DEBUG
Build and see what all we print out about it.

Hi Kurt,
it prints this:
Code:
USB HID Device Info Program

This Sketch shows information about plugged in HID devices

*** You can control the output by simple character input to Serial ***
R - Turns on or off showing the raw data
C - Toggles showing changed data only on or off
<anything else> - toggles showing the Hid formatted breakdown of the data

USB2 PLL running
 reset waited 6
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 2000C000
periodictable = 2000C000
port change: 10001803
    connect
  begin reset
port change: 18001205
  port enabled
  end recovery
new_Device: 480 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 40 DA 0B 38 28 00 01 01 02 03 01 
    VendorID = 0BDA, ProductID = 2838, Version = 0100
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Manufacturer: Realtek
enumeration:
Product: RTL2838UHIDIR
enumeration:
Serial Number: 00000001
enumeration:
Config data length = 34
enumeration:
Configuration Descriptor:
  09 02 22 00 02 01 04 80 FA 
    NumInterfaces = 2
    ConfigurationValue = 1
  09 04 00 00 01 FF FF FF 05 
    Interface = 0
    Number of endpoints = 1
    Class/Subclass/Protocol = 255 / 255 / 255
  07 05 81 02 00 02 00 
    Endpoint = 1 IN
    Type = Bulk
    Max Size = 512
    Polling Interval = 0
  09 04 01 00 00 FF FF FF 05 
    Interface = 1
    Number of endpoints = 0
    Class/Subclass/Protocol = 255 / 255 / 255
enumeration:
USBHub memory usage = 960
USBHub claim_device this=20007340
USBHub memory usage = 960
USBHub claim_device this=20007700

USBDeviceInfo claim this=20006CE8

****************************************
** Device Level **
  vid=BDA
  pid=2838
  bDeviceClass = 0
  bDeviceSubClass = 0
  bDeviceProtocol = 0
09 04 00 00 01 FF FF FF 05 07 05 81 02 00 02 00 09 04 01 00 00 FF FF FF 05 
HIDParser claim this=20006060
HIDParser claim this=200066A0
HIDParser claim this=2000AD20
HIDParser claim this=20004960
HIDParser claim this=20006D00
Descriptor 4 = INTERFACE

USBDeviceInfo claim this=20006CE8

****************************************
** Interface Level **
09 04 00 00 01 FF FF FF 05 07 05 81 02 00 02 00 09 04 01 00 00 FF FF FF 05 
 bInterfaceNumber = 0
 number end points = 1
 bInterfaceClass =    255
 bInterfaceSubClass = 255
 bInterfaceProtocol = 255
HIDParser claim this=20006060
HIDParser claim this=200066A0
HIDParser claim this=2000AD20
HIDParser claim this=20004960
HIDParser claim this=20006D00
Descriptor 5 = ENDPOINT
Descriptor 4 = INTERFACE

USBDeviceInfo claim this=20006CE8

****************************************
** Interface Level **
09 04 01 00 00 FF FF FF 05 
HIDParser claim this=20006060
HIDParser claim this=200066A0
HIDParser claim this=2000AD20
HIDParser claim this=20004960
HIDParser claim this=20006D00

too late here...zzzzz
 
So far this one looks like it does not want to give up it's secrets!

That is it is not giving any clue by device class, subclass nor protocol. 0s for the device and 0xff for interface.
So probably vendor specific.

So the code would need to claim it by VID:pID combination and then go from there.
 
@Frank B - @KurtE
Playing a bit more found that I can use Wireshark as a USB sniffer using PCAB2_interface that is part of Wireshark. Interesting, seems to use URB control as Bulkin - bulkout. Did see 16k data packets being sent from the dongle to windows. Could not find anything on the web about the USB interface though - did find a few libraries though.

Also Frank in terms of the IR Receiver I found this:
RTL-SDR dongles like the NooElec NESDR Mini 2+ often come with an infrared remote control, intended to control TV player software when the device is used in DVB-T mode. But when used as an SDR, what can you do with it? Besides removing the sensor to potentially reduce noise?
came from this site: https://medium.com/@rxseger/receiving-ir-signals-with-rtl-sdr-dongles-5a8658a44b90#.58v415dgp
 
I hope we don't need wireshark..! But it is a nice find. Thanks!
The sourcode of librtlsdr is available (see Post #12) - I hope that it is enough.. at a first glance it looks ok, and seems to have all info.
It handles the different tuner chips too (on "our" stick this is the R820t)
 
I hope we don't need wireshark..! But it is a nice find. Thanks!
The sourcode of librtlsdr is available (see Post #12) - I hope that it is enough.. at a first glance it looks ok, and seems to have all info.
It handles the different tuner chips too (on "our" stick this is the R820t)

Morning Frank (well at least for me, probably afternoon for you)

Was just curious on what was being sent and received over USB thats why I used Wireshark. I came across Librtlsdr as well in my search and was looking at it on and off between playing with other stuff. Noticed it handled different tuners as well.
 
Morning Frank (well at least for me, probably afternoon for you)

Was just curious on what was being sent and received over USB thats why I used Wireshark. I came across Librtlsdr as well in my search and was looking at it on and off between playing with other stuff. Noticed it handled different tuners as well.

I installed Wireshark. Thanks again. Did not know that it can monitor USB traffic, too.
Oh my... that allows to look at other devices, too...
 
@Frank B - @KurtE
Yea - wireshark is pretty neat. A lot of stuff I don't know how to use but it does help.

Anyway found I had USBview on my Win10 machine and decided to give it a try on the SDR dongle. Here is the dump. Pretty much consistent with what we already saw:
Code:
[Port7]  :  USB Composite Device
https://www.engineersgarage.com/article_page/usb-descriptors-and-their-types-part-3-6/

Is Port User Connectable:         yes
Is Port Debug Capable:            no
Companion Port Number:            0
Companion Hub Symbolic Link Name: 
Protocols Supported:
 USB 1.1:                         yes
 USB 2.0:                         yes
 USB 3.0:                         no

Device Power State:               PowerDeviceD0

       ---===>Device Information<===---
English product name: "RTL2838UHIDIR"

ConnectionStatus:                  
Current Config Value:              0x01  -> Device Bus Speed: High (is not SuperSpeed or higher capable)
Device Address:                    0x15
Open Pipes:                           1

          ===>Device Descriptor<===
bLength:                           0x12
bDescriptorType:                   0x01
bcdUSB:                          0x0200
bDeviceClass:                      0x00  -> This is an Interface Class Defined Device
bDeviceSubClass:                   0x00
bDeviceProtocol:                   0x00
bMaxPacketSize0:                   0x40 = (64) Bytes
idVendor:                        0x0BDA = Realtek Semiconductor Corp.
idProduct:                       0x2838
bcdDevice:                       0x0100
iManufacturer:                     0x01
     English (United States)  "Realtek"
iProduct:                          0x02
     English (United States)  "RTL2838UHIDIR"
iSerialNumber:                     0x03
     English (United States)  "00000001"
bNumConfigurations:                0x01

          ---===>Open Pipes<===---

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x02  -> Bulk Transfer Type
wMaxPacketSize:                  0x0200 = 0x200 max bytes
bInterval:                         0x00

       ---===>Full Configuration Descriptor<===---

          ===>Configuration Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x02
wTotalLength:                    0x0022  -> Validated
bNumInterfaces:                    0x02
bConfigurationValue:               0x01
iConfiguration:                    0x04
     English (United States)  "USB2.0-Bulk&Iso"
bmAttributes:                      0x80  -> Bus Powered
MaxPower:                          0xFA = 500 mA

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x00
bAlternateSetting:                 0x00
bNumEndpoints:                     0x01
bInterfaceClass:                   0xFF  -> Interface Class Unknown to USBView
bInterfaceSubClass:                0xFF
bInterfaceProtocol:                0xFF
iInterface:                        0x05
     English (United States)  "Bulk-In, Interface"

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x02  -> Bulk Transfer Type
wMaxPacketSize:                  0x0200 = 0x200 max bytes
bInterval:                         0x00

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x01
bAlternateSetting:                 0x00
bNumEndpoints:                     0x00
bInterfaceClass:                   0xFF  -> Interface Class Unknown to USBView
bInterfaceSubClass:                0xFF
bInterfaceProtocol:                0xFF
iInterface:                        0x05
     English (United States)  "Bulk-In, Interface"
 
Yup.
Ok, I think I will start tomorrow and see how far it goes.
If I get stuck I will ask :)

Luckyly, I have to take a longer break in between to fix my Motor Scooter.
 
Ok, seems that the Teensy library is async.
for this project, it would be more convienient to have it synchronous.

the other way, a state machine is too much work here and not easy to read the code later...

So: how can I wait for a control transfer?
I've seen that there is a callback "control()" - it's called some time after the transfer
But how do I wait for the callback?

In more detail:
I added a volatile bool flag, that gets set in the callback "control()".
Then I tried to wait for the flag:
while (!flag) {yield(); Task(); }
Seems that neither "yield()" nor "Task()" help. flag is never not set to true in this case. What do I need to call to wait for the control transfer?
(this all happens at the end of "claim()" - i'm trying to initialze the rtl stick with a bunch of control transfers)
 
I may have a misunderstanding here.. is it allowed to configure the device in claim()? If not, how do it do it?
 
maybe Paul can answer this?

How would i translate:
Code:
uint16_t rtlsdr_demod_read_reg(rtlsdr_dev_t *dev, uint8_t page, uint16_t addr, uint8_t len)
{
    int r;
    unsigned char data[2];

    uint16_t index = page;
    uint16_t reg;
    addr = (addr << 8) | 0x20;

   [COLOR=#0000ff] r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, data, len, CTRL_TIMEOUT);[/COLOR]

    if (r < 0)
        fprintf(stderr, "%s failed with %d\n", __FUNCTION__, r);

    reg = (data[1] << 8) | data[0];

    return reg;
}

int rtlsdr_demod_write_reg(rtlsdr_dev_t *dev, uint8_t page, uint16_t addr, uint16_t val, uint8_t len)
{
    int r;
    unsigned char data[2];
    uint16_t index = 0x10 | page;
    addr = (addr << 8) | 0x20;

    if (len == 1)
        data[0] = val & 0xff;
    else
        data[0] = val >> 8;

    data[1] = val & 0xff;

   [COLOR=#0000ff] r = libusb_control_transfer(dev->devh, CTRL_OUT, 0, addr, index, data, len, CTRL_TIMEOUT);[/COLOR]

    if (r < 0)
        fprintf(stderr, "%s failed with %d\n", __FUNCTION__, r);

    rtlsdr_demod_read_reg(dev, 0x0a, 0x01, 1);

    return (r == len) ? 0 : -1;
}
to the teensy usb host libary?
 
As you can see most of the time we do it asynch. Note the MSC stuff does a lot of this stuff Sync...

Note: on doing new stuff I am a bit rusty: I will show some of the stuff from USBSerialBase as it does some of this stuff:

But I believe for control messages you will get a call:
Code:
void USBSerialBase::control(const Transfer_t *transfer)
{
	println("control callback (serial) ", pending_control, HEX);
	control_queued = false;

	// We will split this up by Serial type, maybe different functions? 

	//-------------------------------------------------------------------------
	// First FTDI
	if (sertype == FTDI) {
		if (pending_control & 1) {
			pending_control &= ~1;
			// set data format
			uint16_t ftdi_format = format_ & 0xf;	// This should give us the number of bits.

			// now lets extract the parity from our encoding
			ftdi_format |= (format_ & 0xe0) << 3;	// they encode bits 9-11

			// See if two stop bits
			if (format_ & 0x100) ftdi_format |= (0x2 << 11);

			mk_setup(setup, 0x40, 4, ftdi_format, 0, 0); // data format 8N1
			queue_Control_Transfer(device, &setup, NULL, this);
			control_queued = true;
			return;
		}
		// set baud rate
		if (pending_control & 2) {
			pending_control &= ~2;
...
And likewise if you have input or output pipes created, you setup your own callbacks...
 
I was afraid of something like this....
So to read a register from RTL2832 you need about 10 times as many lines as in sdrlib.
That would not be such a problem, but there are many register accesses there.
I think this is not possible. I can't write 1000 lines of code without knowing if it works afterwards. (That is very likely)
I have to think of something better.
Maybe my idea to write a synchronous wrapper first was not so bad.
However, I would have to do that "blind", because I actually only see if it works when it's done.
I'm not sure if I can motivate myself to do that...
Probably this is quite simple if you are well acquainted with the host library. I'm not.
 
@Frank B - @KurtE

Been looking at librtlsdr.c as well as USBHost_t36 and libusb on and off most of the morning.

Think what going to have to happen is that you are going to have to write a new class for USBHost_t36 that calls those functions that are being called off to libusb - libusb_control_transfer and libusb_control_transfer. I keep gravitating to the way its done in ADK even though I don't how that works.

I did get the MSC class to claim the dongle but it only showing 2 interfaces - BULKIN and INTERFACE so maybe a kludge between the 2.

Never did try and create a new device in USBHost - just a bunch of modifications.
 
Again you might take a look at the MSC stuff (MassStorageDriver.cpp) as it runs more or less in lock step...

Again it may not do as much with control but for sending and receiving messages:
look at the function msDoCommand, which is setup to send a message and then if appropriate wait for a response message.

Again in it's call back methods it just sets a flag saying message received or message Sent... And loops...

You could probably do something very similar.
 
Ok, it uses a flaglike I mentioned before - so this works after claim(), obviously.
So, it means I can call a initialize() after claim is ready - perhaps in Task(). Thank you.
I'll try that :)
 
Success :)

Finally, I wrote this:
Code:
//This is a callback that gets called after control transfers:
void RTL2832::control(const Transfer_t *transfer)
{
  memcpy((void*)&controlTransferResult, (void*)transfer, sizeof(controlTransferResult));
  control_transfer_completed = true;
}

int RTL2832::control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout)
{
  memset((void*)&controlTransferResult, 0, sizeof(controlTransferResult)); //<-needed?
  control_transfer_completed = false;

  mk_setup(rtlsetup, bmRequestType, bRequest, wValue, wIndex, wLength);
  bool b = queue_Control_Transfer(dev, &rtlsetup, (void*)data, this);

  if (b) {
    unsigned long  m = millis();
    while ( control_transfer_completed == false ) {
      if (millis() - m > timeout) return _RTL_USB_ERROR_TIMEOUT;
      yield();
    }
    memcpy((void*)data, (void*)controlTransferResult.buffer, controlTransferResult.length);
    print_hexbytes(controlTransferResult.buffer, controlTransferResult.length);
    return controlTransferResult.length;
  }

  return _RTL_USB_ERROR;
}

..and after porting some 100 lines more, I got this:
Code:
USB2 PLL running
 reset waited 6
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 20003000
periodictable = 20003000
port change: 10001803
    connect
  begin reset
port change: 18001205
  port enabled
  end recovery
new_Device: 480 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 40 DA 0B 38 28 00 01 01 02 03 01 
    VendorID = 0BDA, ProductID = 2838, Version = 0100
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Manufacturer: Realtek
enumeration:
Product: RTL2838UHIDIR
enumeration:
Serial Number: 00000001
enumeration:
Config data length = 34
enumeration:
Configuration Descriptor:
  09 02 22 00 02 01 04 80 FA 
    NumInterfaces = 2
    ConfigurationValue = 1
  09 04 00 00 01 FF FF FF 05 
    Interface = 0
    Number of endpoints = 1
    Class/Subclass/Protocol = 255 / 255 / 255
  07 05 81 02 00 02 00 
    Endpoint = 1 IN
    Type = Bulk
    Max Size = 512
    Polling Interval = 0
  09 04 01 00 00 FF FF FF 05 
    Interface = 1
    Number of endpoints = 0
    Class/Subclass/Protocol = 255 / 255 / 255
enumeration:
USBHub memory usage = 960
USBHub claim_device this=20002040
USBHub memory usage = 960
USBHub claim_device this=20002400
-------------------------------
Generic RTL2832U OEM claim this=200027C0, type=0 , bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
09 04 00 00 01 FF FF FF 05 07 05 81 02 00 02 00 09 04 01 00 00 FF FF FF 05 
len = 25
Endpoints = 1
-------------------------------
Initializing
[....]
[COLOR=#ff0000]Found Rafael Micro R820T tuner[/COLOR]
Initialized.
(scroll down)
So, it can initialize the RTL2832 i2c device and talk via I2C to the R820T tuner .
 
Nice job @Frank B !. Just got back on line and saw your post. Feels good to see that its alive finally. When dreams become a reality. You know if you make this work on a Teensy I think it will be the first time that anyone got it working on a microprocessor. All implementations have been on Windows or Linux :)
 
Nice job @Frank B !. Just got back on line and saw your post. Feels good to see that its alive finally. When dreams become a reality. You know if you make this work on a Teensy I think it will be the first time that anyone got it working on a microprocessor. All implementations have been on Windows or Linux :)

Thanks :)
There are still ~60% to do, for the library/USB communication only.
I'm not that sure that it will work. The samplerate is incredible high. I think default is 2.4Msps?
SDR# offers lower (and even higher) samplerates. Have to look if we can use them..
 
Thanks :)
There are still ~60% to do, for the library/USB communication only.
I'm not that sure that it will work. The samplerate is incredible high. I think default is 2.4Msps?
SDR# offers lower (and even higher) samplerates. Have to look if we can use them..

Think you broke the code though.

I keep lowering down to 2.048Msps probably could go lower, tested it all the way down to the lowest setting but you don't see much of the waveform in the display.
 
I don't think I have posted this.. here s a link to a site in german language: https://elektronikbasteln.pl7.de/dvb-t-usb-sticks-als-scanner-von-9-khz-bis-ueber-1-ghz
( a very good translator is www.deepl.com)
Scroll down to "Empfang unterhalb von 22 MHz ohne Konverter durch Hardware-Modifikation"
There is a picture showing a simple hardware-modification. In short, you connect the antenna to an other point on the board. Then, you can receive with from 0-30MHz.
These are all the interesting frequencies - long wave, medium, short wave.
You'll need an other antenna of course... a very very long wire in the garden should do it for the first experiments.

With a wire that long I was able to receive stations thousands of kilometers away (with an other self-built SDR - did not try with this stick so far - i moved and can't use that type of antenna anymore :-( )
(That was with DD4WHs Teensy-SDR software and own SDR with good INA163 (expensive!) chips)
 
Last edited:
Status
Not open for further replies.
Back
Top