Jan Axelson's WinUSB example under Linux with libusb

Page: 1234 > Showing page 1 of 4
Author
xiaofan
Super Member
  • Total Posts : 6247
  • Reward points : 0
  • Joined: 2005/04/14 07:05:25
  • Location: Singapore
  • Status: offline
2008/05/25 06:04:30 (permalink)
0

Jan Axelson's WinUSB example under Linux with libusb

I just write a simple libusb program to test Jan Axelson's WinUSB example. It is a bit strange that the program will fail using interrupt transfer. It works with bulk transfer.


#include <usb.h>
#include <stdio.h>



#define VERSION "0.1.0"

#define VENDOR_ID 0x0925

#define PRODUCT_ID 0x1456

#define INTERFACE 0

const static int reqIntLen=8;
const static int reqBulkLen=64;
const static int endpoint_Int_in=0x81; /* endpoint 0x81 address for IN */
const static int endpoint_Int_out=0x01; /* endpoint 1 address for OUT */
const static int endpoint_Bulk_in=0x82; /* endpoint 0x81 address for IN */
const static int endpoint_Bulk_out=0x02; /* endpoint 1 address for OUT */
const static int timeout=5000; /* timeout in ms */


void bad(const char *why) {
fprintf(stderr,"Fatal error> %s\n",why);
exit(17);
}


usb_dev_handle *find_lvr_winusb();



usb_dev_handle* setup_libusb_access() {

usb_dev_handle *lvr_winusb;

usb_set_debug(255);

usb_init();

usb_find_busses();

usb_find_devices();



if(!(lvr_winusb = find_lvr_winusb())) {

printf("Couldn't find the USB device, Exiting\n");

return NULL;

}

if (usb_set_configuration(lvr_winusb, 1) < 0) {

printf("Could not set configuration 1 : %s\n");

return NULL;

}

if (usb_claim_interface(lvr_winusb, INTERFACE) < 0) {

printf("Could not claim interface: %s\n");

return NULL;

}

return lvr_winusb;

}



usb_dev_handle *find_lvr_winusb()

{

struct usb_bus *bus;

struct usb_device *dev;



for (bus = usb_busses; bus; bus = bus->next) {

for (dev = bus->devices; dev; dev = dev->next) {

if (dev->descriptor.idVendor == VENDOR_ID &&

dev->descriptor.idProduct == PRODUCT_ID ) {

usb_dev_handle *handle;

printf("lvr_winusb with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID);

if (!(handle = usb_open(dev))) {

printf("Could not open USB device\n");

return NULL;

}

return handle;

}

}

}

return NULL;

}



/*
void test_control_transfer(usb_dev_handle *dev)

{
// usb_set_altinterface(dev, 0);

usb_release_interface(dev, 0);

}

*/
void test_interrupt_transfer(usb_dev_handle *dev)

{

int r,i;
char answer[reqIntLen];
char question[reqIntLen];
for (i=0;i<reqIntLen; i++) question[i]=i;
r = usb_interrupt_write(dev, endpoint_Int_out, question, reqIntLen, timeout);
if( r < 0 )
{
perror("USB interrupt write"); bad("USB write failed");
}
r = usb_interrupt_read(dev, endpoint_Int_in, answer, reqIntLen, timeout);
if( r != reqIntLen )
{
perror("USB interrupt read"); bad("USB read failed");
}
for (i=0;i<reqIntLen; i++) printf("%i, %i, \n",question[i],answer[i]);
// usb_set_altinterface(dev, 0);

usb_release_interface(dev, 0);

}


void test_bulk_transfer(usb_dev_handle *dev)

{

int r,i;
char answer[reqBulkLen];
char question[reqBulkLen];
for (i=0;i<reqBulkLen; i++) question[i]=i;
r = usb_bulk_write(dev, endpoint_Bulk_out, question, reqBulkLen, timeout);
if( r < 0 )
{
perror("USB bulk write"); bad("USB write failed");
}
r = usb_bulk_read(dev, endpoint_Bulk_in, answer, reqBulkLen, timeout);
if( r != reqBulkLen )
{
perror("USB bulk read"); bad("USB read failed");
}
for (i=0;i<reqBulkLen;i++) printf("%i, %i, \n",question[i],answer[i]);
// usb_set_altinterface(dev, 0);

usb_release_interface(dev, 0);

}



int main( int argc, char **argv)

{

usb_dev_handle *lvr_winusb;

if ((lvr_winusb = setup_libusb_access()) == NULL) {

exit(-1);

}
// test_control_transfer(lvr_winusb);

// test_interrupt_transfer(lvr_winusb);
test_bulk_transfer(lvr_winusb);

usb_close(lvr_winusb);



return 0;

}


}



Somehow test_interrupt_transfer() does not work. test_bulk_transfer() works.

With test_interrupt_transfer(lvr_winusb) uncommented, the result is the following.
mcuee@ubuntu804:~/Desktop/build/winusb$ sudo ./libusb_winusb
lvr_winusb with Vendor Id: 925 and Product Id: 1456 found.
USB interrupt write: Success
Fatal error> USB write failed

With test_interrupt_transfer(lvr_winusb) commented out, the result is the following.
mcuee@ubuntu804:~/Desktop/build/winusb$ sudo ./libusb_winusb
lvr_winusb with Vendor Id: 925 and Product Id: 1456 found.
0, 0,
1, 1,
2, 2,
3, 3,
4, 4,
5, 5,
6, 6,
7, 7,
8, 8,
9, 9,
10, 10,
11, 11,
12, 12,
13, 13,
14, 14,
15, 15,
16, 16,
17, 17,
18, 18,
19, 19,
20, 20,
21, 21,
22, 22,
23, 23,
24, 24,
25, 25,
26, 26,
27, 27,
28, 28,
29, 29,
30, 30,
31, 31,
32, 32,
33, 33,
34, 34,
35, 35,
36, 36,
37, 37,
38, 38,
39, 39,
40, 40,
41, 41,
42, 42,
43, 43,
44, 44,
45, 45,
46, 46,
47, 47,
48, 48,
49, 49,
50, 50,
51, 51,
52, 52,
53, 53,
54, 54,
55, 55,
56, 56,
57, 57,
58, 58,
59, 59,
60, 60,
61, 61,
62, 62,
63, 63,

"lsusb -v" output

Bus 001 Device 004: ID 0925:1456 Lakeview Research
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0925 Lakeview Research
idProduct 0x1456
bcdDevice 0.01
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 46
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 4
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
post edited by xiaofan - 2008/05/25 07:09:01

  USB_Links and libusb
#1

61 Replies Related Threads

    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/05/28 05:24:16 (permalink)
    0
    A simple port using openusb. There must be a bug somewhere in the code that it only works the 1st time.
    http://openusb.wiki.sourceforge.net/


    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    #include <openusb.h>



    #define VENDOR_ID 0x0925

    #define PRODUCT_ID 0x1456

    #define CLASS_CODE 0
    #define SUBCLASS_CODE 0

    const static int INT_DATA_LEN=8;
    const static int BULK_DATA_LEN=64;
    const static int INTERFACE=0;
    const static int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */
    const static int ENDPOINT_BULK_IN=0x82; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */
    const static int TIMEOUT=5000; /* timeout in ms */


    /*
    void test_control_transfer(openusb_dev_handle_t hdev)

    {
    }

    */
    /*
    void test_interrupt_transfer(openusb_dev_handle_t hdev)

    {

    }

    */

    int test_bulk_transfer(openusb_dev_handle_t devh)

    {

    char bulkdata[BULK_DATA_LEN];
    char bulkrd[BULK_DATA_LEN];
    int i,ret;
    openusb_bulk_request_t bulk;

    printf("Test BULK transfer:\n");

    memset(&bulk, 0, sizeof(bulk));
    memset(bulkrd, 0, BULK_DATA_LEN);

    for(i = 0; i< BULK_DATA_LEN; i++) {
    bulkdata[i] = i;
    }

    bulk.payload = bulkdata;
    bulk.length = BULK_DATA_LEN;
    bulk.timeout = TIMEOUT;

    /* Write BULK */
    ret = openusb_bulk_xfer(devh, INTERFACE, ENDPOINT_BULK_OUT, &bulk);

    if (ret != 0) {
    printf("BULK sync xfer test fail:%s\n", openusb_strerror(ret));
    return -1;
    }
    printf("bulk sync xfer result.status = %d,xfer_bytes=%d, ret=%d\n",
    bulk.result.status, bulk.result.transferred_bytes,ret);

    /* READ BULK */
    bulk.payload = bulkrd;
    ret = openusb_bulk_xfer(devh, INTERFACE, ENDPOINT_BULK_IN, &bulk);
    if (ret != 0) {
    printf("bulk sync xfer fail:%s\n", openusb_strerror(ret));
    return -1;
    }

    printf("\nBULK DATA:\n");

    for(i = 0;i < BULK_DATA_LEN; i++) {
    if(i%16 == 0)
    printf("\n");
    printf("%02x ",(unsigned char)bulkrd[i]);
    }

    printf("\n");

    /* this can be enhanced to check data integrity */

    printf("BULK SYNC xfer test: PASS\n");

    return 0;
    }




    int main( int argc, char **argv)

    {
    openusb_handle_t libhandle;

    openusb_dev_handle_t lvr_winusb;


    openusb_busid_t *bus = NULL;
    openusb_devid_t *devids = NULL;
    openusb_dev_data_t *devdata;
    unsigned int devnum = 0;
    unsigned int busnum = 0;
    int i, j;

    /* openusb initialization */
    if (openusb_init(0, &libhandle) != OPENUSB_SUCCESS)
    {
    printf("OpenUSB initalization error.\n");
    }

    /* find all usb buses on system */
    openusb_get_busid_list(libhandle, &bus, &busnum);

    /* search device in all devices on system */
    for (j = 0; j < busnum; j++)
    {
    openusb_get_devids_by_bus(libhandle, bus[j], &devids, &devnum);
    for (i = 0; i < devnum; i++)
    {
    openusb_get_device_data(libhandle, devids[i], 0, &devdata);
    if (devdata->dev_desc.bDeviceSubClass == SUBCLASS_CODE &&
    devdata->dev_desc.bDeviceClass == CLASS_CODE &&
    devdata->dev_desc.idProduct == PRODUCT_ID &&
    devdata->dev_desc.idVendor == VENDOR_ID)
    {
    openusb_free_device_data(devdata);
    break;
    }
    openusb_free_device_data(devdata);
    }
    if (i >= devnum)
    {
    openusb_free_devid_list(devids);
    }
    else
    {
    break;
    }
    }

    if (j >= busnum)
    {
    printf("Cannot find specified device.\n");
    exit(-1);
    }

    if (openusb_open_device(libhandle, devids[i], USB_INIT_DEFAULT, &lvr_winusb) != OPENUSB_SUCCESS)
    {
    printf("Cannot open specified device.\n");
    exit(-1);
    }
    printf("Specified USB device found.\n");
    openusb_free_devid_list(devids);
    openusb_free_busid_list(bus);

    if (openusb_claim_interface(lvr_winusb, INTERFACE, USB_INIT_DEFAULT) != OPENUSB_SUCCESS)
    {
    printf("Cannot claim interface.\n");
    exit(-1);
    }
    printf("Successfully claim the interface.\n");
    // test_control_transfer(lvr_winusb); //Not implemented yet

    // test_interrupt_transfer(lvr_winusb); //Not implemented yet
    test_bulk_transfer(lvr_winusb);

    /* release interfaces */
    openusb_release_interface(lvr_winusb, INTERFACE);
    /* close device */
    openusb_close_device(lvr_winusb);
    /* deinitialize openusb */
    openusb_fini(libhandle);



    return 0;

    }



    mcuee@ubuntu804:~/Desktop/build/winusb$ ./openusb_winusb
    Specified USB device found.
    Successfully claim the interface.
    Test BULK transfer:
    bulk sync xfer result.status = 0,xfer_bytes=64, ret=0

    BULK DATA:

    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
    10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
    20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
    30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
    BULK SYNC xfer test: PASS

    mcuee@ubuntu804:~/Desktop/build/winusb$ ./openusb_winusb
    Specified USB device found.
    Successfully claim the interface.
    Test BULK transfer:
    bulk sync xfer result.status = 0,xfer_bytes=64, ret=0
    bulk sync xfer fail:I/O timeout


      USB_Links and libusb
    #2
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/05/28 07:22:53 (permalink)
    0
    Hmm, I must miss something very obvious. I just port the program to the upcoming libusb-1.0. Now it has the same problem with the program based on OpenUSB. The first run will be ok. After that, it will not work any more.

    The original program based on libusb-0.1 works fine every time.

    The new program based on libubs-1.0 (using the sample program dpfp.c as the template):

    #include <errno.h>
    #include <signal.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>

    #include <libusb-1.0/libusb.h>



    #define VERSION "0.1.0"

    #define VENDOR_ID 0x0925

    #define PRODUCT_ID 0x1456

    const static int PACKET_INT_LEN=8;
    const static int PACKET_BULK_LEN=64;
    const static int INTERFACE=0;
    const static int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */
    const static int ENDPOINT_BULK_IN=0x82; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */
    const static int TIMEOUT=5000; /* timeout in ms */


    void bad(const char *why) {
    fprintf(stderr,"Fatal error> %s\n",why);
    exit(17);
    }


    static struct libusb_device_handle *devh = NULL;



    static int find_lvr_winusb(void)
    {
    devh = libusb_open_device_with_vid_pid(VENDOR_ID, PRODUCT_ID);
    return devh ? 0 : -EIO;
    }



    static int test_bulk_transfer(void)
    {
    int r,i;
    int transferred;
    char answer[PACKET_BULK_LEN];
    char question[PACKET_BULK_LEN];
    for (i=0;i<PACKET_BULK_LEN; i++) question[i]=i;

    r = libusb_bulk_transfer(devh, ENDPOINT_BULK_OUT, question, PACKET_BULK_LEN,
    &transferred,TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Bulk write error %d\n", r);
    return r;
    }
    r = libusb_bulk_transfer(devh, ENDPOINT_BULK_IN, answer,PACKET_BULK_LEN,
    &transferred, TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Bulk read error %d\n", r);
    return r;
    }
    if (transferred < PACKET_BULK_LEN) {
    fprintf(stderr, "Bulk transfer short read (%d)\n", r);
    return -1;
    }

    // for (i=0;i< PACKET_BULK_LEN;i++) printf("%i, %i,\n
    ",question[i],answer[i]);
    for(i = 0;i < PACKET_BULK_LEN; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");

    return 0;
    }


    int main(void)
    {
    struct sigaction sigact;
    int r = 1;

    r = libusb_init();
    if (r < 0) {
    fprintf(stderr, "failed to initialise libusb\n");
    exit(1);
    }

    r = find_lvr_winusb();
    if (r < 0) {
    fprintf(stderr, "Could not find/open device\n");
    goto out;
    }
    printf("Successfully find the LVR WINUSB device\n");
    r = libusb_claim_interface(devh, 0);
    if (r < 0) {
    fprintf(stderr, "usb_claim_interface error %d\n", r);
    goto out;
    }
    printf("Successfully claimed interface\n");
    test_bulk_transfer();

    libusb_release_interface(devh, 0);
    out:
    libusb_close(devh);
    libusb_exit();
    return r >= 0 ? r : -r;

    }


    mcuee@ubuntu804:~/Desktop/build/winusb$ ./libusb1_winusb
    Successfully find the LVR WINUSB device
    Successfully claimed interface

    00, 00; 01, 01; 02, 02; 03, 03; 04, 04; 05, 05; 06, 06; 07, 07;
    08, 08; 09, 09; 0a, 0a; 0b, 0b; 0c, 0c; 0d, 0d; 0e, 0e; 0f, 0f;
    10, 10; 11, 11; 12, 12; 13, 13; 14, 14; 15, 15; 16, 16; 17, 17;
    18, 18; 19, 19; 1a, 1a; 1b, 1b; 1c, 1c; 1d, 1d; 1e, 1e; 1f, 1f;
    20, 20; 21, 21; 22, 22; 23, 23; 24, 24; 25, 25; 26, 26; 27, 27;
    28, 28; 29, 29; 2a, 2a; 2b, 2b; 2c, 2c; 2d, 2d; 2e, 2e; 2f, 2f;
    30, 30; 31, 31; 32, 32; 33, 33; 34, 34; 35, 35; 36, 36; 37, 37;
    38, 38; 39, 39; 3a, 3a; 3b, 3b; 3c, 3c; 3d, 3d; 3e, 3e; 3f, 3f;

    mcuee@ubuntu804:~/Desktop/build/winusb$ ./libusb1_winusb
    Successfully find the LVR WINUSB device
    Successfully claimed interface
    Bulk read error -7


      USB_Links and libusb
    #3
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/05/29 06:18:47 (permalink)
    0
    After some trying, it seems to me that I need to add a usb reset call in the end of the two failed programs.


    test_bulk_transfer(lvr_winusb);

    /* release interfaces */
    openusb_release_interface(lvr_winusb, INTERFACE);
    openusb_reset(lvr_winusb); //adding this line will make the program happy
    /* close device */
    openusb_close_device(lvr_winusb);
    /* deinitialize openusb */
    openusb_fini(libhandle);



    test_bulk_transfer();
    libusb_release_interface(devh, 0);
    out:
    libusb_reset_device(devh); //adding this line makes the program happy
    libusb_close(devh);
    libusb_exit();
    return r >= 0 ? r : -r;


    This is a bit strange and maybe there is a potential problem (maybe data toggle problem) with the firmware.


      USB_Links and libusb
    #4
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/05/29 16:48:08 (permalink)
    0
    A better solution for libusb-0.1: adding libusb_set_configuration() call (and remove the reset call) will make the libusb-1.0 based program working.


    int main(void)
    {
    struct sigaction sigact;
    int r = 1;

    r = libusb_init();
    if (r < 0) {
    fprintf(stderr, "failed to initialise libusb\n");
    exit(1);
    }

    r = find_lvr_winusb();
    if (r < 0) {
    fprintf(stderr, "Could not find/open device\n");
    goto out;
    }
    printf("Successfully find the LVR WINUSB device\n");
    r = libusb_set_configuration(devh, 1);
    if (r < 0) {
    fprintf(stderr, "libusb_set_configuration error %d\n", r);
    goto out;
    }
    printf("Successfully set usb configuration 1\n");
    r = libusb_claim_interface(devh, 0);
    if (r < 0) {
    fprintf(stderr, "libusb_claim_interface error %d\n", r);
    goto out;
    }
    printf("Successfully claimed interface\n");
    test_bulk_transfer();

    libusb_release_interface(devh, 0);
    out:
    // libusb_reset_device(devh);
    libusb_close(devh);
    libusb_exit();
    return r >= 0 ? r : -r;

    }





      USB_Links and libusb
    #5
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/05/29 16:49:40 (permalink)
    0
    Unfortunately, this does not work for openusb based program.

    I add the following code before claiming the interface.

    ret = openusb_set_configuration(lvr_winusb, 1);
    if ( ret != OPENUSB_SUCCESS)
    {
    printf("Cannot set configuration 1.\n");
    printf("Error code %d.\n",ret);
    exit(-1);
    }


    However this will fail.

    mcuee@ubuntu804:~/Desktop/build/winusb$ ./openusb_winusb
    Specified USB device found.
    Cannot set configuration 1.
    Error code -8.

    According to openusb.h, it means invalid parameter. Strange.
    #define OPENUSB_BADARG -8 /* Invalid parameter */

      USB_Links and libusb
    #6
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/05/30 06:19:19 (permalink)
    0
    Now I know that why the interrupt transfer test will fail, the firmware defines that interrupt transfer is only using 2 bytes.


    #define WINUSB_INTERRUPT_IN_BYTES 2

    #define WINUSB_INTERRUPT_OUT_BYTES 2

    #define WINUSB_INTERRUPT_IN_EP_SIZE 8

    #define WINUSB_INTERRUPT_OUT_EP_SIZE 8



    So changing
     const static int reqIntLen=8; 
    to
    const static int reqIntLen=2;
    will solve the problem.

      USB_Links and libusb
    #7
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/06/01 20:46:23 (permalink)
    0
    This is the fully working example in libusb-1.0 with the tests of loopback for the control transfer (vendor requests), interrupt transfer and bulk transfer.

    Tested with libusb-1.0 git version 29-May-2008 and Ubuntu 8.10.


    #include <errno.h>
    #include <signal.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>

    #include <libusb-1.0/libusb.h>



    #define VERSION "0.1.0"

    #define VENDOR_ID 0x0925

    #define PRODUCT_ID 0x1456
    #define WINUSB_REQUEST_1 0x01

    #define WINUSB_REQUEST_2 0x02
    #define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE)
    #define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT | LIBUSB_RECIPIENT_INTERFACE)
    const static int PACKET_CTRL_LEN=2;

    const static int PACKET_INT_LEN=2;
    const static int PACKET_BULK_LEN=64;
    const static int INTERFACE=0;
    const static int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */
    const static int ENDPOINT_BULK_IN=0x82; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */
    const static int TIMEOUT=5000; /* timeout in ms */


    void bad(const char *why) {
    fprintf(stderr,"Fatal error> %s\n",why);
    exit(17);
    }


    static struct libusb_device_handle *devh = NULL;



    static int find_lvr_winusb(void)
    {
    devh = libusb_open_device_with_vid_pid(VENDOR_ID, PRODUCT_ID);
    return devh ? 0 : -EIO;
    }


    static int test_control_transfer(void)
    {
    int r,i;
    char answer[PACKET_CTRL_LEN];
    char question[PACKET_CTRL_LEN];
    for (i=0;i<PACKET_CTRL_LEN; i++) question[i]=0x20+i;

    r = libusb_control_transfer(devh,CTRL_OUT,WINUSB_REQUEST_1,2, 0,question, PACKET_CTRL_LEN,TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Control Out error %d\n", r);
    return r;
    }
    r = libusb_control_transfer(devh,CTRL_IN,WINUSB_REQUEST_2,2,0, answer,PACKET_CTRL_LEN, TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Control IN error %d\n", r);
    return r;
    }
    printf("Control Transfer Loop Test Result:\n");
    // for (i=0;i< PACKET_CTRL_LEN;i++) printf("%i, %i,\n ",question[i],answer[i]);
    for(i = 0;i < PACKET_CTRL_LEN; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");
    printf("\n");

    return 0;
    }


    static int test_interrupt_transfer(void)
    {
    int r,i;
    int transferred;
    char answer[PACKET_INT_LEN];
    char question[PACKET_INT_LEN];
    for (i=0;i<PACKET_INT_LEN; i++) question[i]=0x40+i;

    r = libusb_interrupt_transfer(devh, ENDPOINT_INT_OUT, question, PACKET_INT_LEN,
    &transferred,TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Interrupt write error %d\n", r);
    return r;
    }
    r = libusb_interrupt_transfer(devh, ENDPOINT_INT_IN, answer,PACKET_INT_LEN,
    &transferred, TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Interrupt read error %d\n", r);
    return r;
    }
    if (transferred < PACKET_INT_LEN) {
    fprintf(stderr, "Interrupt transfer short read (%d)\n", r);
    return -1;
    }
    printf("Interrupt Transfer Loop Test Result:\n");
    // for (i=0;i< PACKET_INT_LEN;i++) printf("%i, %i,\n ",question[i],answer[i]);
    for(i = 0;i < PACKET_INT_LEN; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");
    printf("\n");

    return 0;
    }



    static int test_bulk_transfer(void)
    {
    int r,i;
    int transferred;
    char answer[PACKET_BULK_LEN];
    char question[PACKET_BULK_LEN];
    for (i=0;i<PACKET_BULK_LEN; i++) question[i]=i;

    r = libusb_bulk_transfer(devh, ENDPOINT_BULK_OUT, question, PACKET_BULK_LEN,
    &transferred,TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Bulk write error %d\n", r);
    return r;
    }
    r = libusb_bulk_transfer(devh, ENDPOINT_BULK_IN, answer,PACKET_BULK_LEN,
    &transferred, TIMEOUT);
    if (r < 0) {
    fprintf(stderr, "Bulk read error %d\n", r);
    return r;
    }
    if (transferred < PACKET_BULK_LEN) {
    fprintf(stderr, "Bulk transfer short read (%d)\n", r);
    return -1;
    }
    printf("Bulk Transfer Loop Test Result:\n");
    // for (i=0;i< PACKET_BULK_LEN;i++) printf("%i, %i,\n ",question[i],answer[i]);
    for(i = 0;i < PACKET_BULK_LEN; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");
    printf("\n");

    return 0;
    }


    int main(void)
    {
    struct sigaction sigact;
    int r = 1;

    r = libusb_init();
    if (r < 0) {
    fprintf(stderr, "failed to initialise libusb\n");
    exit(1);
    }

    r = find_lvr_winusb();
    if (r < 0) {
    fprintf(stderr, "Could not find/open device\n");
    goto out;
    }
    printf("Successfully find the LVR WINUSB device\n");
    r = libusb_set_configuration(devh, 1);
    if (r < 0) {
    fprintf(stderr, "libusb_set_configuration error %d\n", r);
    goto out;
    }
    printf("Successfully set usb configuration 1\n");
    r = libusb_claim_interface(devh, 0);
    if (r < 0) {
    fprintf(stderr, "libusb_claim_interface error %d\n", r);
    goto out;
    }
    printf("Successfully claimed interface\n");

    test_control_transfer();
    test_interrupt_transfer();
    test_bulk_transfer();


    libusb_release_interface(devh, 0);
    out:
    //This should not be necessary if the libusb_set_configuration call is changed in the future
    libusb_reset_device(devh);
    libusb_close(devh);
    libusb_exit();
    return r >= 0 ? r : -r;

    }


      USB_Links and libusb
    #8
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/06/01 20:58:02 (permalink)
    0
    With libusb-0.1..12 which comes with Ubuntu 8.04.

    Edit: fixed a bug, not to release the interface inside the test.


    #include <usb.h>
    #include <stdio.h>



    #define VERSION "0.1.0"

    #define VENDOR_ID 0x0925

    #define PRODUCT_ID 0x1456

    #define INTERFACE 0
    #define WINUSB_REQUEST_1 0x01

    #define WINUSB_REQUEST_2 0x02
    #define CTRL_IN (USB_TYPE_VENDOR | USB_ENDPOINT_IN | USB_RECIP_INTERFACE)
    #define CTRL_OUT (USB_TYPE_VENDOR | USB_ENDPOINT_OUT | USB_RECIP_INTERFACE)
    const static int reqCTRLLen=2;

    const static int reqIntLen=2;
    const static int reqBulkLen=64;
    const static int endpoint_Int_in=0x81; /* endpoint 0x81 address for IN */
    const static int endpoint_Int_out=0x01; /* endpoint 1 address for OUT */
    const static int endpoint_Bulk_in=0x82; /* endpoint 0x81 address for IN */
    const static int endpoint_Bulk_out=0x02; /* endpoint 1 address for OUT */
    const static int timeout=5000; /* timeout in ms */


    void bad(const char *why) {
    fprintf(stderr,"Fatal error> %s\n",why);
    // exit(17);
    }


    usb_dev_handle *find_lvr_winusb();



    usb_dev_handle* setup_libusb_access() {

    usb_dev_handle *lvr_winusb;

    usb_set_debug(255);

    usb_init();

    usb_find_busses();

    usb_find_devices();



    if(!(lvr_winusb = find_lvr_winusb())) {

    printf("Couldn't find the USB device, Exiting\n");

    return NULL;

    }

    if (usb_set_configuration(lvr_winusb, 1) < 0) {

    printf("Could not set configuration 1 : %s\n");

    return NULL;

    }

    if (usb_claim_interface(lvr_winusb, INTERFACE) < 0) {

    printf("Could not claim interface: %s\n");

    return NULL;

    }

    return lvr_winusb;

    }



    usb_dev_handle *find_lvr_winusb()

    {

    struct usb_bus *bus;

    struct usb_device *dev;



    for (bus = usb_busses; bus; bus = bus->next) {

    for (dev = bus->devices; dev; dev = dev->next) {

    if (dev->descriptor.idVendor == VENDOR_ID &&

    dev->descriptor.idProduct == PRODUCT_ID ) {

    usb_dev_handle *handle;

    printf("lvr_winusb with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID);

    if (!(handle = usb_open(dev))) {

    printf("Could not open USB device\n");

    return NULL;

    }

    return handle;

    }

    }

    }

    return NULL;

    }




    void test_control_transfer(usb_dev_handle *dev)

    {
    int r,i;
    char answer[reqCTRLLen];
    char question[reqCTRLLen];
    for (i=0;i<reqCTRLLen; i++) question[i]=0x20+i;

    r = usb_control_msg(dev,CTRL_OUT,WINUSB_REQUEST_1,0, 0,question, reqCTRLLen,timeout);
    if (r < 0) {
    perror("USB control transfer out"); bad("USB write failed");
    }
    r = usb_control_msg(dev,CTRL_IN,WINUSB_REQUEST_2,0,0, answer,reqCTRLLen, timeout);
    if (r < 0) {
    perror("USB control transfer in"); bad("USB read failed");
    }
    printf("Control Transfer Loop Test Result:\n");
    // for (i=0;i<reqIntLen; i++) printf("%i, %i, \n",question[i],answer[i]);
    for(i = 0;i < reqIntLen; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");
    printf("\n");
    }




    void test_interrupt_transfer(usb_dev_handle *dev)

    {

    int r,i;
    char answer[reqIntLen];
    char question[reqIntLen];
    for (i=0;i<reqIntLen; i++) question[i]=0x40+i;
    r = usb_interrupt_write(dev, endpoint_Int_out, question, reqIntLen, timeout);
    if( r < 0 )
    {
    perror("USB interrupt write"); bad("USB write failed");
    }
    r = usb_interrupt_read(dev, endpoint_Int_in, answer, reqIntLen, timeout);
    if( r != reqIntLen )
    {
    perror("USB interrupt read"); bad("USB read failed");
    }
    printf("Interrupt Transfer Loop Test Result:\n");
    // for (i=0;i<reqIntLen; i++) printf("%i, %i, \n",question[i],answer[i]);
    for(i = 0;i < reqIntLen; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");
    printf("\n");

    }


    void test_bulk_transfer(usb_dev_handle *dev)

    {

    int r,i;
    char answer[reqBulkLen];
    char question[reqBulkLen];
    for (i=0;i<reqBulkLen; i++) question[i]=i;
    r = usb_bulk_write(dev, endpoint_Bulk_out, question, reqBulkLen, timeout);
    if( r < 0 )
    {
    perror("USB bulk write"); bad("USB write failed");
    }
    r = usb_bulk_read(dev, endpoint_Bulk_in, answer, reqBulkLen, timeout);
    if( r != reqBulkLen )
    {
    perror("USB bulk read"); bad("USB read failed");
    }
    printf("Bulk Transfer Loop Test Result:\n");
    // for (i=0;i<reqBulkLen;i++) printf("%i, %i, \n",question[i],answer[i]);
    for(i = 0;i < reqBulkLen; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x, %02x; ",question[i],answer[i]);
    }
    printf("\n");
    printf("\n");

    }



    int main( int argc, char **argv)

    {

    usb_dev_handle *lvr_winusb;

    if ((lvr_winusb = setup_libusb_access()) == NULL) {

    exit(-1);

    }
    test_control_transfer(lvr_winusb);

    test_interrupt_transfer(lvr_winusb);
    test_bulk_transfer(lvr_winusb);
    usb_release_interface(lvr_winusb, 0);
    usb_close(lvr_winusb);

    return 0;

    }




    mcuee@ubuntu804:~/Desktop/build/winusb/libusb01$ ./libusb_winusb2
    usb_set_debug: Setting debugging level to 255 (on)
    usb_os_init: Found USB VFS at /dev/bus/usb
    usb_os_find_busses: Found 003
    usb_os_find_busses: Found 002
    usb_os_find_busses: Found 001
    usb_os_find_devices: couldn't get connect info
    usb_os_find_devices: Found 001 on 003
    error obtaining child information: Operation not permitted
    usb_os_find_devices: couldn't get connect info
    usb_os_find_devices: Found 001 on 002
    error obtaining child information: Operation not permitted
    usb_os_find_devices: Found 004 on 001
    usb_os_find_devices: Found 003 on 001
    skipped 1 class/vendor specific interface descriptors
    usb_os_find_devices: couldn't get connect info
    usb_os_find_devices: Found 001 on 001
    error obtaining child information: Inappropriate ioctl for device
    error obtaining child information: Inappropriate ioctl for device
    error obtaining child information: Operation not permitted
    lvr_winusb with Vendor Id: 925 and Product Id: 1456 found.
    Control Transfer Loop Test Result:

    20, 20; 21, 21;

    Interrupt Transfer Loop Test Result:

    40, 40; 41, 41;

    Bulk Transfer Loop Test Result:

    00, 00; 01, 01; 02, 02; 03, 03; 04, 04; 05, 05; 06, 06; 07, 07;
    08, 08; 09, 09; 0a, 0a; 0b, 0b; 0c, 0c; 0d, 0d; 0e, 0e; 0f, 0f;
    10, 10; 11, 11; 12, 12; 13, 13; 14, 14; 15, 15; 16, 16; 17, 17;
    18, 18; 19, 19; 1a, 1a; 1b, 1b; 1c, 1c; 1d, 1d; 1e, 1e; 1f, 1f;
    20, 20; 21, 21; 22, 22; 23, 23; 24, 24; 25, 25; 26, 26; 27, 27;
    28, 28; 29, 29; 2a, 2a; 2b, 2b; 2c, 2c; 2d, 2d; 2e, 2e; 2f, 2f;
    30, 30; 31, 31; 32, 32; 33, 33; 34, 34; 35, 35; 36, 36; 37, 37;
    38, 38; 39, 39; 3a, 3a; 3b, 3b; 3c, 3c; 3d, 3d; 3e, 3e; 3f, 3f;
    post edited by xiaofan - 2008/06/10 04:24:56

      USB_Links and libusb
    #9
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/06/07 07:38:11 (permalink)
    0

    ORIGINAL: xiaofan
    Unfortunately, this does not work for openusb based program.


    This has been fixed with the latest openusb svn code.


    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    #include <openusb.h>



    #define VENDOR_ID 0x0925

    #define PRODUCT_ID 0x1456

    #define CLASS_CODE 0
    #define SUBCLASS_CODE 0

    const static int INT_DATA_LEN=2;
    const static int BULK_DATA_LEN=64;
    const static int INTERFACE=0;
    const static int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */
    const static int ENDPOINT_BULK_IN=0x82; /* endpoint 0x81 address for IN */
    const static int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */
    const static int TIMEOUT=5000; /* timeout in ms */


    /*
    void test_control_transfer(openusb_dev_handle_t hdev)

    {
    }

    */

    int test_interrupt_transfer(openusb_dev_handle_t devh)

    {
    char intrdata[INT_DATA_LEN];
    char intrrd[INT_DATA_LEN];
    int i,ret;
    openusb_intr_request_t intr;

    printf("Test Interrupt transfer:\n");

    memset(&intr, 0, sizeof(intr));
    memset(intrrd, 0, INT_DATA_LEN);

    for(i = 0; i< INT_DATA_LEN; i++) {
    intrdata[i] = 0x20+i;
    }

    intr.payload = intrdata;
    intr.length = INT_DATA_LEN;
    intr.timeout = TIMEOUT;

    /* Interrupt Write */
    ret = openusb_intr_xfer(devh, INTERFACE, ENDPOINT_INT_OUT, &intr);

    if (ret != 0) {
    printf("intr sync xfer test write fail:%s\n", openusb_strerror(ret));
    return -1;
    }
    printf("intr sync xfer write result.status = %d,xfer_bytes=%d, ret=%d\n",
    intr.result.status, intr.result.transferred_bytes,ret);

    /* Interrupt READ */
    intr.payload = intrrd;
    intr.length = INT_DATA_LEN;
    intr.timeout = TIMEOUT;
    ret = openusb_intr_xfer(devh, INTERFACE, ENDPOINT_INT_IN, &intr);
    if (ret != 0) {
    printf("intr sync xfer test read fail:%s\n", openusb_strerror(ret));
    return -1;
    }
    printf("intr sync xfer read result.status = %d,xfer_bytes=%d, ret=%d\n",
    intr.result.status, intr.result.transferred_bytes,ret);

    printf("\nInterrupt DATA: write,readback\n");
    for(i = 0;i < INT_DATA_LEN; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x,%02x ",(unsigned char)intrdata[i],(unsigned char)intrrd[i]);
    }

    printf("\n");

    /* this can be enhanced to check data integrity */

    printf("Interrupt SYNC xfer test: PASS\n");
    printf("\n");

    return 0;


    }



    int test_bulk_transfer(openusb_dev_handle_t devh)

    {

    char bulkdata[BULK_DATA_LEN];
    char bulkrd[BULK_DATA_LEN];
    int i,ret;
    openusb_bulk_request_t bulk;

    printf("Test BULK transfer:\n");

    memset(&bulk, 0, sizeof(bulk));
    memset(bulkrd, 0, BULK_DATA_LEN);

    for(i = 0; i< BULK_DATA_LEN; i++) {
    bulkdata[i] = i;
    }

    bulk.payload = bulkdata;
    bulk.length = BULK_DATA_LEN;
    bulk.timeout = TIMEOUT;

    /* Write BULK */
    ret = openusb_bulk_xfer(devh, INTERFACE, ENDPOINT_BULK_OUT, &bulk);

    if (ret != 0) {
    printf("BULK sync xfer test write fail:%s\n", openusb_strerror(ret));
    return -1;
    }
    printf("bulk sync xfer write result.status = %d,xfer_bytes=%d, ret=%d\n",
    bulk.result.status, bulk.result.transferred_bytes,ret);

    /* READ BULK */
    bulk.payload = bulkrd;
    bulk.length = BULK_DATA_LEN;
    bulk.timeout = TIMEOUT;
    ret = openusb_bulk_xfer(devh, INTERFACE, ENDPOINT_BULK_IN, &bulk);
    if (ret != 0) {
    printf("bulk sync xfer test read fail:%s\n", openusb_strerror(ret));
    return -1;
    }
    printf("bulk sync xfer read result.status = %d,xfer_bytes=%d, ret=%d\n",
    bulk.result.status, bulk.result.transferred_bytes,ret);

    printf("\nBULK DATA: write,readback\n");
    for(i = 0;i < BULK_DATA_LEN; i++) {
    if(i%8 == 0)
    printf("\n");
    printf("%02x,%02x ",(unsigned char)bulkdata[i],(unsigned char)bulkrd[i]);
    }

    printf("\n");

    /* this can be enhanced to check data integrity */

    printf("BULK SYNC xfer test: PASS\n");
    printf("\n");

    return 0;
    }




    int main( int argc, char **argv)

    {
    openusb_handle_t libhandle;

    openusb_dev_handle_t lvr_winusb;


    openusb_busid_t *bus = NULL;
    openusb_devid_t *devids = NULL;
    openusb_dev_data_t *devdata;
    unsigned int devnum = 0;
    unsigned int busnum = 0;
    int i, j;
    int ret;

    /* openusb initialization */
    if (openusb_init(0, &libhandle) != OPENUSB_SUCCESS)
    {
    printf("OpenUSB initalization error.\n");
    }

    /* find all usb buses on system */
    openusb_get_busid_list(libhandle, &bus, &busnum);

    /* search device in all devices on system */
    for (j = 0; j < busnum; j++)
    {
    openusb_get_devids_by_bus(libhandle, bus[j], &devids, &devnum);
    for (i = 0; i < devnum; i++)
    {
    openusb_get_device_data(libhandle, devids[i], 0, &devdata);
    if (devdata->dev_desc.bDeviceSubClass == SUBCLASS_CODE &&
    devdata->dev_desc.bDeviceClass == CLASS_CODE &&
    devdata->dev_desc.idProduct == PRODUCT_ID &&
    devdata->dev_desc.idVendor == VENDOR_ID)
    {
    openusb_free_device_data(devdata);
    break;
    }
    openusb_free_device_data(devdata);
    }
    if (i >= devnum)
    {
    openusb_free_devid_list(devids);
    }
    else
    {
    break;
    }
    }

    if (j >= busnum)
    {
    printf("Cannot find specified device.\n");
    exit(-1);
    }

    ret = openusb_open_device(libhandle, devids[i], USB_INIT_DEFAULT, &lvr_winusb);
    if (ret != OPENUSB_SUCCESS)
    {
    printf("Cannot open specified device.\n");
    printf("Error code %d.\n",ret);
    exit(-1);
    }
    printf("Specified USB device found.\n");

    ret = openusb_set_configuration(lvr_winusb, 1);
    if ( ret != OPENUSB_SUCCESS)
    {
    printf("Cannot set configuration 1.\n");
    printf("Error code %d.\n",ret);
    exit(-1);
    }
    printf("Successfully set usb configuration 1.\n");
    ret = openusb_claim_interface(lvr_winusb, INTERFACE, USB_INIT_DEFAULT);
    if ( ret != OPENUSB_SUCCESS)
    {
    printf("Cannot claim interface.\n");
    printf("Error code %d.\n",ret);
    exit(-1);
    }
    printf("Successfully claim the interface.\n");

    openusb_free_devid_list(devids);
    openusb_free_busid_list(bus);

    // test_control_transfer(lvr_winusb); //Not implemented yet

    test_interrupt_transfer(lvr_winusb);
    test_bulk_transfer(lvr_winusb);

    /* release interfaces */
    openusb_release_interface(lvr_winusb, INTERFACE);
    // openusb_reset(lvr_winusb);
    /* close device */
    openusb_close_device(lvr_winusb);
    /* deinitialize openusb */
    openusb_fini(libhandle);



    return 0;

    }




    mcuee@ubuntu804:~/Desktop/build/winusb/openusb$ ./openusb_winusb3
    Specified USB device found.
    Successfully set usb configuration 1.
    Successfully claim the interface.
    Test Interrupt transfer:
    intr sync xfer write result.status = 0,xfer_bytes=2, ret=0
    intr sync xfer read result.status = 0,xfer_bytes=2, ret=0

    Interrupt DATA: write,readback

    20,20 21,21
    Interrupt SYNC xfer test: PASS

    Test BULK transfer:
    bulk sync xfer write result.status = 0,xfer_bytes=64, ret=0
    bulk sync xfer read result.status = 0,xfer_bytes=64, ret=0

    BULK DATA: write,readback

    00,00 01,01 02,02 03,03 04,04 05,05 06,06 07,07
    08,08 09,09 0a,0a 0b,0b 0c,0c 0d,0d 0e,0e 0f,0f
    10,10 11,11 12,12 13,13 14,14 15,15 16,16 17,17
    18,18 19,19 1a,1a 1b,1b 1c,1c 1d,1d 1e,1e 1f,1f
    20,20 21,21 22,22 23,23 24,24 25,25 26,26 27,27
    28,28 29,29 2a,2a 2b,2b 2c,2c 2d,2d 2e,2e 2f,2f
    30,30 31,31 32,32 33,33 34,34 35,35 36,36 37,37
    38,38 39,39 3a,3a 3b,3b 3c,3c 3d,3d 3e,3e 3f,3f
    BULK SYNC xfer test: PASS


      USB_Links and libusb
    #10
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/07/04 06:56:42 (permalink)
    0
    I just tested the libusb-0.1 code under FreeBSD 7 with HPS stack (http://mcuee.blogspot.com/search/label/FreeBSD) and it works.

    [mcuee@freebsd7 /usr/home/mcuee/Desktop/build/winusb]$ uname -a
    FreeBSD freebsd7.MSHOME.net 7.0-RELEASE FreeBSD 7.0-RELEASE #2: Tue Apr 29 19:47:40 SGT 2008 root@freebsd7.MSHOME.net:/usr/obj/usr/src/sys/custom i386


    [mcuee@freebsd7 /usr/home/mcuee/Desktop/build/winusb]$ lsusb
    Bus /dev/usb0 Device /dev/ugen1: ID 04d8:0033 Microchip Technology, Inc.
    Bus /dev/usb0 Device /dev/ugen2: ID 0925:1456 Lakeview Research
    Bus /dev/usb1 Device /dev/ugen0: ID 04d8:0033 Microchip Technology, Inc.

    [mcuee@freebsd7 /usr/home/mcuee/Desktop/build/winusb]$ ./winusb
    usb_set_debug: Setting debugging level to 255 (on)
    usb_os_find_busses: Found /dev/usb0
    usb_os_find_busses: Found /dev/usb1
    usb_os_find_busses: can't open /dev/usb2: Permission denied
    usb_os_find_devices: Found /dev/ugen1 on /dev/usb0
    usb_os_find_devices: Found /dev/ugen2 on /dev/usb0
    usb_control_msg: 128 6 512 0 0xbfbfe994 8 1000
    usb_control_msg: 128 6 512 0 0x2820b040 46 1000
    usb_control_msg: 128 6 512 0 0xbfbfe994 8 1000
    usb_control_msg: 128 6 512 0 0x2820b070 41 1000
    skipped 1 class/vendor specific interface descriptors
    usb_control_msg: 128 6 513 0 0xbfbfe994 8 1000
    usb_control_msg: 128 6 513 0 0x282090c0 32 1000
    usb_os_find_devices: Found /dev/ugen0 on /dev/usb1
    usb_control_msg: 128 6 512 0 0xbfbfe994 8 1000
    usb_control_msg: 128 6 512 0 0x2820b100 41 1000
    skipped 1 class/vendor specific interface descriptors
    usb_control_msg: 128 6 513 0 0xbfbfe994 8 1000
    usb_control_msg: 128 6 513 0 0x28209100 32 1000
    lvr_winusb with Vendor Id: 925 and Product Id: 1456 found.
    usb_control_msg: 65 1 0 0 0xbfbfe9c0 2 5000
    usb_control_msg: 193 2 0 0 0xbfbfe9e0 2 5000
    Control Transfer Loop Test Result:

    20, 20; 21, 21;

    Interrupt Transfer Loop Test Result:

    40, 40; 41, 41;

    Bulk Transfer Loop Test Result:

    00, 00; 01, 01; 02, 02; 03, 03; 04, 04; 05, 05; 06, 06; 07, 07;
    08, 08; 09, 09; 0a, 0a; 0b, 0b; 0c, 0c; 0d, 0d; 0e, 0e; 0f, 0f;
    10, 10; 11, 11; 12, 12; 13, 13; 14, 14; 15, 15; 16, 16; 17, 17;
    18, 18; 19, 19; 1a, 1a; 1b, 1b; 1c, 1c; 1d, 1d; 1e, 1e; 1f, 1f;
    20, 20; 21, 21; 22, 22; 23, 23; 24, 24; 25, 25; 26, 26; 27, 27;
    28, 28; 29, 29; 2a, 2a; 2b, 2b; 2c, 2c; 2d, 2d; 2e, 2e; 2f, 2f;
    30, 30; 31, 31; 32, 32; 33, 33; 34, 34; 35, 35; 36, 36; 37, 37;
    38, 38; 39, 39; 3a, 3a; 3b, 3b; 3c, 3c; 3d, 3d; 3e, 3e; 3f, 3f;

    usb_os_close: closing endpoint 4
    usb_os_close: closing endpoint 5


      USB_Links and libusb
    #11
    Ze
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2008/07/24 04:11:56
    • Location: 0
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/08/24 03:33:04 (permalink)
    0
    Am I better off using WinUSB + linusb or Microchips Generic Firmware + linusb?
    #12
    TCM
    Super Member
    • Total Posts : 502
    • Reward points : 0
    • Joined: 2005/06/26 02:01:25
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/08/24 13:20:17 (permalink)
    0
    I don't know if everybody got the message here....

    WinUSB is a custom driver supported by Microsoft. So, it relates to windows only (XP and Vista).
    It really does not have anything in common with Linux.


    However, since the firmware is a custom class, you can declare in the *.inf file almost any driver you want. So you can use libusb also. 



    Once i had a spectrum computer , today i am throwing away my pentium PC , tomorow i will write to you from a Microchip internet-enabled device.
    #13
    Ze
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2008/07/24 04:11:56
    • Location: 0
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/08/24 16:49:35 (permalink)
    0
    I understand that , but what I'm talking about is there any difference between the USB Device - MCHPUSB - Generic Driver Demo and USB Device - WinUSB - Generic Driver Demo firmware? that I should keep in mind when I'm basing my firmware and linusb driver off it?
    #14
    TCM
    Super Member
    • Total Posts : 502
    • Reward points : 0
    • Joined: 2005/06/26 02:01:25
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2008/08/25 04:18:41 (permalink)
    0
    Both of them are using Generic Drivers (as their names are specifying that). From the firmware standpoint the differences are little to none. Probably minor changes in the descriptor. 

    Once i had a spectrum computer , today i am throwing away my pentium PC , tomorow i will write to you from a Microchip internet-enabled device.
    #15
    skaman
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2008/11/25 03:56:21
    • Location: 0
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2009/08/17 04:24:35 (permalink)
    0
    Hi to all... this post is really interesting and i'm interested to use openusb in my project (openusb.. not libusb... i need at least an lgpl license)

    First of all i'm working on a fedora 11 x86_64, i'm using microchip usb framework 2.4 and original microchip winusb example.
    I preferred original example because microchip keep it updated.. and if something change inside the framework i've always a working example from microchip. For me one endpoint with bulk read/write is enought.

    I'm working with QT and i created a simple c++ class with 3 function: Open, Read, Write

    USB::USB()
    {
    this->m_IsOpened = false;

    qDebug ("Initializing OpenUSB");
    if (openusb_init(0, &this->m_LibHandle) != OPENUSB_SUCCESS)
    qCritical ("OpenUSB initialization error");
    }

    bool USB::Open(quint16 VendorId, quint16 ProductId)
    {
    openusb_busid_t *bus = NULL;
    openusb_devid_t *devids = NULL;
    openusb_dev_data_t *devdata;

    quint32 devnum = 0;
    quint32 busnum = 0;

    quint32 i, j;
    int ret;

    qDebug ("Scanning for device with VendorId = %04x and ProductId = %04x", VendorId, ProductId);
    openusb_get_busid_list(this->m_LibHandle, &bus, &busnum);

    for (j=0; j<busnum; j++)
    {
    openusb_get_devids_by_bus(this->m_LibHandle, bus[j], &devids, &devnum);
    for (i=0; i<devnum; i++)
    {
    openusb_get_device_data(this->m_LibHandle, devids[i], 0, &devdata);
    if (devdata->dev_desc.bDeviceSubClass == 0 &&
    devdata->dev_desc.bDeviceClass == 0 &&
    devdata->dev_desc.idProduct == ProductId &&
    devdata->dev_desc.idVendor == VendorId)
    {
    openusb_free_device_data (devdata);
    break;
    }
    // TODO: check why go in corruption or double free !!!!
    //openusb_free_device_data (devdata);
    }
    if (i >= devnum) openusb_free_devid_list (devids);
    else break;
    }

    openusb_free_busid_list (bus);

    if (j >= busnum)
    {
    qDebug ("Cannot find specified device");
    return false;
    }

    if ((ret = openusb_open_device (this->m_LibHandle, devids[i], USB_INIT_DEFAULT, &m_UsbDevice)) != OPENUSB_SUCCESS)
    {
    qCritical ("Cannot open specified device. Error code %d", ret);
    openusb_free_devid_list (devids);
    return false;
    }
    qDebug ("Specified USB device found");
    openusb_free_devid_list (devids);

    if ((ret = openusb_set_configuration (this->m_UsbDevice, this->CONFIGURATION)) != OPENUSB_SUCCESS)
    {
    qCritical ("Cannot set configuration 1. Error code %d", ret);
    return false;
    }
    qDebug ("Configuration 1 setted");

    if ((ret = openusb_claim_interface (this->m_UsbDevice, this->INTERFACE, USB_INIT_DEFAULT)) != OPENUSB_SUCCESS)
    {
    qCritical ("Cannot claim interface. Error code %d", ret);
    return false;
    }
    qDebug ("Interface claimed");
    this->m_IsOpened = true;
    return true;
    }

    bool USB::Write (const char *packet, quint8 size)
    {
    int ret;

    if (!this->m_IsOpened) return false;

    openusb_bulk_request_t bulk;
    memset (&bulk, 0, sizeof (bulk));
    bulk.payload = (uint8_t*)packet;
    bulk.length = size;
    bulk.timeout = this->TIMEOUT;

    if ((ret = openusb_bulk_xfer (this->m_UsbDevice, this->INTERFACE, this->ENDPOINT_BULK_OUT, &bulk)) != OPENUSB_SUCCESS)
    {
    qCritical ("Bulk xfer write failed: %s", openusb_strerror (ret));
    return false;
    }
    qDebug ("Bulk xfer write result:\n- status = %d\n- xfer_bytes = %d\n", bulk.result.status, bulk.result.transferred_bytes);
    return true;
    }

    bool USB::Read (const char *packet, quint8 size)
    {
    int ret;

    if (!this->m_IsOpened) return false;

    openusb_bulk_request_t bulk;
    memset (&bulk, 0, sizeof (bulk));
    bulk.payload = (uint8_t*)packet;
    bulk.length = size;
    bulk.timeout = this->TIMEOUT;

    if ((ret = openusb_bulk_xfer (this->m_UsbDevice, this->INTERFACE, this->ENDPOINT_BULK_IN, &bulk)) != OPENUSB_SUCCESS)
    {
    qCritical ("Bulk xfer read failed: %s", openusb_strerror (ret));
    return false;
    }
    qDebug ("Bulk xfer read result:\n- status = %d\n- xfer_bytes = %d\n", bulk.result.status, bulk.result.transferred_bytes);
    return true;
    }

    And this is the class definition:
    #ifndef USB_H
    #define USB_H

    #include <QObject>
    #include <QtGlobal>

    #include <openusb.h>

    class USB : public QObject
    {
    private:
    const static int INTERFACE = 0;
    const static int CONFIGURATION = 1;
    const static int ENDPOINT_BULK_IN = 0x81;
    const static int ENDPOINT_BULK_OUT = 0x01;
    const static int TIMEOUT = 5000;

    bool m_IsOpened;
    openusb_handle_t m_LibHandle;
    openusb_dev_handle_t m_UsbDevice;

    public:
    USB();

    bool Open (quint16 VendorId, quint16 ProductId);
    bool Write (const char *packet, quint8 size);
    bool Read (const char *packet, quint8 size);
    };

    #endif // USB_H


    After that i call this functions in this way:

        this->m_Usb = new USB();
    if (this->m_Usb->Open(0x04d8, 0x0053))
    {
    char test[64];
    //int i;
    //for (i=0; i<64; i++) test[i] = i+1;
    test[0] = 0x81;
    this->m_Usb->Write(test, 1);
    this->m_Usb->Read(test, 1);
    }


    When i start the code i write correctly my packet to the board but i obtain a timeout when i try to read from it
    Initializing OpenUSB
    Scanning for device with VendorId = 04d8 and ProductId = 0053
    Specified USB device found
    Configuration 1 setted
    Interface claimed
    Bulk xfer write result:
    - status = 0
    - xfer_bytes = 1

    Bulk xfer read failed: I/O timeout


    I checked my code and example thousands of times... and it making me crazy !!
    Someone have an idea why it go in timeout when i'm reading from it?

    Thanks in advance... and thanks again for this useful post!
    #16
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2009/08/17 05:54:00 (permalink)
    0
    When i start the code i write correctly my packet to the board but i obtain a timeout when i try to read from it

    Does your device correctly return the reply?
    Watch the USB traffic.
    If you don't have a hardware bus analyzer, use usbmon over command line, or over WireShark.
    It may be hard to interpret the usbmon outputs (also WireShark's), because usbmon puts RAW output and it doesn't interpret the output so friendly as Windows sniffers (or Mac USBProber) do.

    usbmon package on fedra
    https://admin.fedoraproject.org/pkgdb/packages/name/usbmon

    Documentation / usb / usbmon.txt
    http://www.mjmwired.net/kernel/Documentation/usb/usbmon.txt

    WireShark - USB capture setup
    http://wiki.wireshark.org/CaptureSetup/USB

    Tsuneo
    #17
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2009/08/17 06:20:53 (permalink)
    0
    ORIGINAL: skaman
    Hi to all... this post is really interesting and i'm interested to use openusb in my project (openusb.. not libusb... i need at least an lgpl license)


    libusb is licensed under LGPL 2.1.
    http://www.libusb.org/

    IMHO OpenUSB is less mature than libusb.

      USB_Links and libusb
    #18
    skaman
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2008/11/25 03:56:21
    • Location: 0
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2009/08/17 08:05:59 (permalink)
    0
    @chinzei
    i tested it with usbmon but i don't see any type of reply from my board... instead, under windows with winusb driver, it work ok.

    @xiaofan
    uhm.. you're right... i don't know why but i was sure libusb it was GPL! Tomorrow i'll rewrite it with libusb... thank you again for your examples and sorry for my mistake
    #19
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: Jan Axelson's WinUSB example under Linux with libusb 2009/08/17 08:39:51 (permalink)
    0
    instead, under windows with winusb driver, it work ok.

    Hum, then the device is working as expected.

    When i start the code i write correctly my packet to the board but i obtain a timeout when i try to read from it
    ...
    i tested it with usbmon but i don't see any type of reply from my board...

    Do you see the packet sent from your app to the board on usbmon?
    Is the format of this "command" packet fine?

    The device may receive the "command" packet, but ignore it because the format (or value) is incorrect.

    Tsuneo
    #20
    Page: 1234 > Showing page 1 of 4
    Jump to:
    © 2017 APG vNext Commercial Version 4.5