Page 1 of 1

AVR-USB and device access in OSX

Posted: Fri Apr 20, 2007 9:09 am
by lpx
Hi,

First of all let me congratulate you for this wonderfull job of creating such driver.

This really gives power to the people, for free!!

Thank you very much!

I'm using AVR-USB to create a custom MIDI controller using a Atmel Mega 32.

Since AVR-USB doesnt permit to implement the USB MIDI protocol since doesnt meet the speed needs i want to create a driver which transforms the AVR-USB device, in a MIDI device.

For now i'm just focus myself in the device reading within OSX.

I have never done this is with any operating system.

I can detect the device, filter its product/vendor id and get an interface to it. Then i can also analize its endpoints and the report says the it only has 1 pipe and it accepts control transfers.

My base AVR-USB code was from a project called AVR-HID which offers a USB interface for 6 sensors.

In your's site AVR-USB section it says that this drivers supports interrupt transfers and it also provides the possibility to implement 4 endpoints.

I would like to know how to turn on those interrupt transfers and adittional endpoints.

In all the cases, if i just can use the only endpoint (pipe 0, the default one) i don't need any thing more.

In OSX, to communicate with a device thru the endpoint 0 i need to use DeviceRequest in order to do it.

What should be my request in order to retrieve the data?

Many thx,

Nuno

Posted: Thu Apr 26, 2007 6:09 pm
by christian
For an example which uses an interrupt-in endpoint, see RemoteSensor. For an example with the full set of endpoints, see Osamu Tamura's AVR-CDC or our AVR-Doper.

I usually base my code on libusb because it offers the same API on all platforms. If your application is Mac only, you can use the Mac specific framework, of course.

Posted: Thu Apr 26, 2007 6:23 pm
by Guest
christian wrote:For an example which uses an interrupt-in endpoint, see RemoteSensor. For an example with the full set of endpoints, see Osamu Tamura's AVR-CDC or our AVR-Doper.

I usually base my code on libusb because it offers the same API on all platforms. If your application is Mac only, you can use the Mac specific framework, of course.


Cool! I need to inspect that!

Thx,

Nuno

Posted: Sat Apr 28, 2007 1:37 pm
by lpx
christian wrote:For an example which uses an interrupt-in endpoint, see RemoteSensor. For an example with the full set of endpoints, see Osamu Tamura's AVR-CDC or our AVR-Doper.

I usually base my code on libusb because it offers the same API on all platforms. If your application is Mac only, you can use the Mac specific framework, of course.


Hi,

I'm decided to try libusb. The api is much cleaner than Mac OSX.

I'm trying to obtain the data from my AVR-USB device.

As i said i'm using an implementation from a project named AVR-HID.

I think the author simplified the USB part a lot because the code is much simpler than powerswitch for example.

Well, i'm trying to get the report offered by the implementation but i still can get a thing.

Can you give me some help with the report specification?

This is my device listing by USB probe:

Code: Select all

Low Speed device @ 2 (0x1D100000): .............................................   Composite device: "AVR-HID"
    Device Descriptor   
        Descriptor Version Number:   0x0101
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   8
        Device VendorID/ProductID:   0x0000/0x0001   (unknown vendor)
        Device Version Number:   0x0100
        Number of Configurations:   1
        Manufacturer String:   1 "MUMT"
        Product String:   2 "AVR-HID"
        Serial Number String:   0 (none)
    Configuration Descriptor   
        Length (and contents):   34
            Raw Descriptor (hex)    0000: 09 02 22 00 01 01 00 40  32 09 04 00 00 01 03 00 
            Raw Descriptor (hex)    0010: 00 00 09 21 00 01 00 01  22 3C 00 07 05 81 03 08 
            Raw Descriptor (hex)    0020: 00 0A
        Number of Interfaces:   1
        Configuration Value:   1
        Attributes:   0x40 (self-powered)
        MaxPower:   100 ma
        Interface #0 - HID   
            Alternate Setting   0
            Number of Endpoints   1
            Interface Class:   3   (HID)
            Interface Subclass;   0
            Interface Protocol:   0
            HID Descriptor   
                Descriptor Version Number:   0x0100
                Country Code:   0
                Descriptor Count:   1
                Descriptor 1   
                    Type:   0x22  (Report Descriptor)
                    Length (and contents):   60
            Endpoint 0x81 - Interrupt Input   
                Address:   0x81  (IN)
                Attributes:   0x03  (Interrupt no synchronization data endpoint)
                Max Packet Size:   8
                Polling Interval:   10 ms


And this is the request i'm trying to make:

Code: Select all

udev = usb_open(dev);
   if (udev) {
      puts("Grabbed the device");
      
      char *dummy = NULL;
      
      usb_control_msg(udev,
                    0x000000a1,
                    0x00000022,
                    0,
                    0,
                    &dummy,
                    60,
                    5000);   
      
      if (dummy!=NULL) {
         for (i=0;i<60;i++) {
            printf("%c\n",dummy[i]);
         }
         puts("");
      }
      else {
         puts("null answer");
      }
            
      
   }


There is one thing that is confusing me a lot.

I thought that i needed to open an interface with my device in order to comunicate with it. However, i saw an example of libusb which doesnt make such thing, so i assumed that i can do that.


http://www.linuxjournal.com/node/7466/print

Can i communicate with my device without an interface?

Well, i hope you can give me some lights here. I'm building a custom MIDI device and i want to implement USB interface on it. Its the last challenge because everything else is done! :)

Many thx,

Best regards,

Nuno Santos

Posted: Sun Apr 29, 2007 10:08 pm
by christian
Please see the function usbGetStringAscii() in the file sensord.c of the RemoveSensor project. This function reads a string descriptor in Unicode and converts it to ASCII.

If you want to read the HID report descriptor, you don't need the ASCII conversion, but you (probably) need to interpret the structured descriptor.

Requests to endpoint 0 can be done without opening an interface. These requests are usually needed to configure the device and set an interface. If you use other endpoints, you need to set the appropriate configuration and interface. See the calls to usb_set_configuration() and usb_claim_interface() in sensord.c.

Posted: Mon Apr 30, 2007 12:07 am
by Guest
christian wrote:Please see the function usbGetStringAscii() in the file sensord.c of the RemoveSensor project. This function reads a string descriptor in Unicode and converts it to ASCII.

If you want to read the HID report descriptor, you don't need the ASCII conversion, but you (probably) need to interpret the structured descriptor.

Requests to endpoint 0 can be done without opening an interface. These requests are usually needed to configure the device and set an interface. If you use other endpoints, you need to set the appropriate configuration and interface. See the calls to usb_set_configuration() and usb_claim_interface() in sensord.c.


Hi Christian,

In the last days i've been pulling my days off trying to figure out what is happening and how can i get the report.

Today i just realized that i'm finally getting my report but the data is encoded.

How can i interpret the structured descriptor? Do i need to write a parser? Or should i start using OS API's for this?

By the way, i saw that it was you the author of avr-usb driver.

Nice work man! This is fantastic!!

With my best regards,

Nuno Santos

Posted: Mon Apr 30, 2007 9:15 pm
by christian
If you know the device, you don't need to decode the HID descriptor because you know it. Only if you want to build a general driver (e.g. for joysticks, not only your particular joystick) you need to parse the descriptor.

In this case I'd recommend using the operating system's functions, if there are any.