PDA

View Full Version : Problem getting libusb datarecieved event to send signal



sisco
1st December 2009, 13:32
hi the title may busbcom = new UsbCom();
connect(usbcom, SIGNAL(error(QString)), SLOT(usbError(QString)));
usbcom->start();e a little weird but i wasnt sure what to call it.

il try to explain what im trying to do.

i am trying to get data from the usb device with libusb_handle_events function
in my main class i use this code to start the thread for usb communication:

usbcom = new UsbCom();
connect(usbcom, SIGNAL(error(QString)), SLOT(usbError(QString)));
connect(usbcom, SIGNAL(dataRecieved(QString)), SLOT(usbDataRecieved(QString)));
usbcom->start();

UsbCom class:


#include "usbcom.h"
#include <QtGui>
#include "/usr/local/include/libusb-1.0/libusb.h"
#include "dataemit.h"
#include <QApplication>

#define idVENDOR 0x0483
#define idPRODUCT 0x5750
#define EP_INTR_OUT ( 1 | LIBUSB_ENDPOINT_OUT)
#define EP_INTR_IN ( 1 | LIBUSB_ENDPOINT_IN )

UsbCom::UsbCom()
{
}

void UsbCom::run()
{
int r;
int transf;
unsigned char data[2]={2,5};
r = libusb_init(NULL);
if (r < 0)
{
emit error("Failed to initialize USB!");
exit(1);
}

libusb_device_handle *devh = libusb_open_device_with_vid_pid(NULL, idVENDOR, idPRODUCT);

if(!devh)
{
emit error("Could not locate device");
exit();
}

r = libusb_kernel_driver_active (devh, 0);

if (r != 0)
{
if(r==1)
{
r = libusb_detach_kernel_driver(devh, 0);
if (r > 0)
{
emit error("some other random error:"+ QString::number(r));
exit(1);
}
}
}

r = libusb_claim_interface(devh, 0);

if (r < 0)
{
emit error("usb_claim_interface error"+ QString::number(r));
}

r = libusb_interrupt_transfer(devh, EP_INTR_OUT, data, sizeof(data), &transf,50);

emit error("did it work? r:" + QString::number(r));

irq_transfer = libusb_alloc_transfer(0);
unsigned char irqbuf[2];

libusb_fill_interrupt_transfer(irq_transfer, devh, EP_INTR_IN, irqbuf,sizeof(irqbuf), ep_irq_in_cb, NULL, 0);
r = libusb_submit_transfer(irq_transfer);

while(1)
{
r = libusb_handle_events(NULL);
}
}

void UsbCom::dataRecieve()
{
}

void ep_irq_in_cb(libusb_transfer *transfer)
{
if(transfer->status != LIBUSB_TRANSFER_COMPLETED)
{
// fprintf(stderr, "uncompleted transter\n");
}

//dont know what code goes here, try to call UsbCom::DataRecieve

if (libusb_submit_transfer(transfer) < 0){
fprintf(stderr,"couldnot resubmit irq \n");
exit(1);
}

}

the problem is that as you can see the
void ep_irq_in_cb(libusb_transfer *transfer) function is not in the UsbCom class. but when the code executes i need to call the UsbCom::DataRecieve() function so that it connects to the slot in my main thread.

if anyone can help me i would be very gratefull.

Sisco

high_flyer
1st December 2009, 13:51
what is the protype of libusb_fill_interrupt_transfer()?
Usually call back set functions take also a 'user param' to allow access to a user class.
What is the 'NULL' parameter?

sisco
1st December 2009, 13:55
what is the protype of libusb_fill_interrupt_transfer()?
Usually call back set functions take also a 'user param' to allow access to a user class.
What is the 'NULL' parameter?

from libusb documentation:


static void libusb_fill_interrupt_transfer ( struct libusb_transfer * transfer,
libusb_device_handle * dev_handle,
unsigned char endpoint,
unsigned char * buffer,
int length,
libusb_transfer_cb_fn callback,
void * user_data,
unsigned int timeout
) [inline, static]

Helper function to populate the required libusb_transfer fields for an interrupt transfer.

Parameters:
transfer the transfer to populate
dev_handle handle of the device that will handle the transfer
endpoint address of the endpoint where this transfer will be sent
buffer data buffer
length length of data buffer
callback callback function to be invoked on transfer completion
user_data user data to pass to callback function
timeout timeout for the transfer in milliseconds

the NULL parameter is the user_data param i thougnt since i didnt have anything i wanted to send with it i just used NULL.

sisco
2nd December 2009, 07:49
after some searching on the web i tried this:


irq_transfer = libusb_alloc_transfer(0);
unsigned char irqbuf[2];
libusb_fill_interrupt_transfer(irq_transfer, devh, EP_INTR_IN, irqbuf,sizeof(irqbuf), ep_irq_in_cb, &a, 0);
//libusb_fill_control_transfer(irq_transfer, devh, irqbuf, ep_irq_in_cb, NULL,0);
r = libusb_submit_transfer(irq_transfer);

while(1)
{
if (a == 1)
{
emit dataRecieved("o.o");
a = 0;
}
r = libusb_handle_events(NULL);
}


void ep_irq_in_cb(libusb_transfer *transfer)
{
if(transfer->status != LIBUSB_TRANSFER_COMPLETED)
{
// fprintf(stderr, "uncompleted transter\n");
}
else
{

int *data = transfer->user_data;
*data = 1;
}
if (libusb_submit_transfer(transfer) < 0){
fprintf(stderr,"could not resubmit irq \n");
exit(1);
}

}

wich gave me this error:


/home/sisco/Documents/School/Project 3/Project Software/Project/usbcom.cpp:93: error: invalid conversion from ‘void*’ to ‘int*’

high_flyer
2nd December 2009, 10:40
the NULL parameter is the user_data param i thougnt since i didnt have anything i wanted to send with it i just used NULL.

Read my last post again.
As you can see, my prediction was correct, and the parameter was user data.
You should change the call back function to take the user data parameter too, and then you can pass your Usb class pointer to it, and call the Usb object methods in it.

sisco
3rd December 2009, 07:05
yes, you were right fixed it now the way i posted before. i just had to cast the user data to an int.

thank you verry much.

sisco

havij000
7th November 2012, 05:13
hi every body,
I have a questoin about the libusb, libusb_fill_iso_transfer function.
What is the libusb_transfer_cb_fn callback, field in this function?
Is it a function I myself should write it or it is default function and there is no need to write it?

tanks
havij000