Problems getting usbFunctionRead() called

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
Guest

Problems getting usbFunctionRead() called

Post by Guest » Mon Nov 20, 2006 5:32 pm

I have a problem with AVR-USB and control-in transfers.

USB_CFG_IMPLEMENT_FN_READ and USB_CFG_IMPLEMENT_FN_WRITE
are both defined to 1.

The device gets detected without problems.

The codesnippet below is the content of the
callbacks

Code: Select all

uchar usbFunctionSetup(uchar data[8])
{
 uart_putc('s');
 switch(data[1]){
    case STEST:{
        buffer[0]=1;
        usbMsgPtr=buffer;
        return 1;
    }break; 
    case RTEST:{
        return 0xff; // get usbFunctionRead called;
    }break;
    case WTEST:{
        return 0xff; // get usbFunctionWrite called;
    }break;
 }
}

uchar usbFunctionWrite(uchar* data,uchar len)
{
  uart_putc('w');
  return 1;
}

uchar usbFunctionRead(uchar* data,uchar len)
{
  uart_putc('r');
  return 1;
}




On the client side:

Performing

Code: Select all

usb_control_msg(hDev,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,WTEST, 0, 0, buf, strlen(buffer), 1000);

Results in "sw" in the terminal app and usbFunctionWrite getting called.

Performing

Code: Select all

usb_control_msg(hDev,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,STEST, 0, 0, buf, sizeof(buffer), 1000);

Results in "s" in the terminal app and correct data getting returned
to the client app.

Performing

Code: Select all

usb_control_msg(hDev,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,RTEST, 0, 0, buf, sizeof(buffer), 1000);

Results in "s" in the terminal app and no usbFunctionRead getting called.
Thus no data is supplied to the client application.

I'm using AVR-USB on an mega8515 with 8kb of external sram.
I thought of usbFunctionRead as a Way to conveniently read the
xmem in larger chunks than 254.
The firmware code contains atm just the xmem initialization, since i am trying to understand where the problem lies.

The usbdriver is from the latest PowerSwitcher zipfile.

Best Regards,
Tobias

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Tue Nov 21, 2006 10:54 am

Did you ensure that you recompiled the driver after defining USB_CFG_IMPLEMENT_FN_READ? Our makefiles don't have dependencies on usbconfig.h, so you must do a "make clean" after updating this header.

You can verify that usbFunctionRead() is actually linked by changing the name of your function. You should get a linker error when linking.

If that's all OK, please enable debugging by adding -DDEBUG_LEVEL=2 to the compiler command line. This will give more information about data received and actions taken.

Guest

Post by Guest » Tue Nov 21, 2006 6:31 pm

Performing

Code: Select all

usb_control_msg(hDev,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,RTEST, 0, 0, buf, sizeof(buffer), 1000);

yields

Code: Select all

10: c0 01 00 00 00 00 00 04
s20: 4b 00 00

on the serial console with debuglevel=2.

The 's' marks the entry to usbFunctionSetup();

Below is the trace of sending "asdasdasdasd\0".

Code: Select all

10: 40 02 00 00 00 00 13 00
s13: 61 73 64 61 73 64 61 73
w20: 4b 00 00
13: 64 61 73 64 61 73 64 61
w20: 4b 00 00
13: 73 64 0a
w20: 4b 00 00


Is there more information i should provide?

I get the linker-error about missing the usbFunctionRead() symbol as i should.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Tue Nov 21, 2006 6:59 pm

This one is tricky :-)

10: c0 01 00 00 00 00 00 04


The last two bytes here indicate a length of 0x400 = 1024 bytes. That's more than the maximum of 254 which is allowed by AVR-USB.

The driver evaluates only the low byte of the length (since 254 can be expressed in one byte). And the low byte of 0x400 is 0, which indicates a zero sized read.

Simply change the host code to

Code: Select all

usb_control_msg(hDev,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,RTEST, 0, 0, buf, 254, 1000);


(assuming that the buffer is always at least 254 bytes in size).

Guest

Post by Guest » Tue Nov 21, 2006 7:27 pm

tricky indeed ;-)


Code: Select all

10: c0 01 00 00 00 00 fe 00
sr20: 4b 00 00

So now it works ;-)

Thankyou very much!

Best regards,
Tobias

Guest

Post by Guest » Tue Dec 05, 2006 11:37 pm

christian wrote:This one is tricky :-)

10: c0 01 00 00 00 00 00 04


The last two bytes here indicate a length of 0x400 = 1024 bytes. That's more than the maximum of 254 which is allowed by AVR-USB.

The driver evaluates only the low byte of the length (since 254 can be expressed in one byte). And the low byte of 0x400 is 0, which indicates a zero sized read.

Simply change the host code to

Code: Select all

usb_control_msg(hDev,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,RTEST, 0, 0, buf, 254, 1000);


(assuming that the buffer is always at least 254 bytes in size).

Post Reply