Page 1 of 1

How to send on Interrupt transfer more than 8 bytes ?

Posted: Wed Dec 06, 2006 8:48 pm
by Gobol
Hello all,

First of all - congratulations for great project (avr-usb)!
I've got one question :
How to send on interrupt transfer (IN) more then 8 bytes ?
Function usbSetInterrupt accepts only 8 bytes, but I need to send 16 bytes simultaneously on one IN endpoint poll.
I need this, because of my HID descriptor - full datagram fits 16 bytes.

It is possible to send 0 bytes at the interrupt and call somehow usbFunctionRead ?

I've migrated my project from PIC usb capable devices, where it was possible to set 16 byte payload for IN-interrupt-endpoint (low-speed device), and the device-usb-driver sends that buffer succesfully on each interrupt.

Posted: Wed Dec 06, 2006 11:14 pm
by Guest
How to handle with interrupt request within usbFunctionSetup ? (or it is impossible)

Posted: Thu Dec 07, 2006 11:50 am
by christian
The driver is not really prepared to handle interrupt-IN transfers of more than 7 bytes (one USB transaction indicating End Of Transfer). Larger (interrupt-) transfers are built from multiple transactions.

You should be able to simulate a 16 byte interrupt transfer with the following procedure:
  • Pass the first 8 bytes with usbSetInterrupt().
  • Wait until they are transferred with usbInterruptIsReady().
  • Pass the next 8 bytes with usbSetInterrupt().
  • Wait until the transaction is complete with usbInterruptIsReady().
  • Call usbSetInterrupt() with 0 bytes to indicate the end of transfer.

If your payload is only 15 bytes, you save the last 0 byte transaction. The end of transfer is indicated by a transaction with less than 8 bytes.

Posted: Sat Dec 09, 2006 12:26 pm
by Gobol
Thanks for your reply!
That's the information I was looking for.

Greetz.

Posted: Sat Dec 09, 2006 2:18 pm
by Gobol

Code: Select all

void SendData(void)
{
    while (!usbInterruptIsReady())
   {
      wdReset();
      usbPoll();
   }
    usbSetInterrupt(BuildReport(0), 8);

    while (!usbInterruptIsReady())
   {
      wdReset();
      usbPoll();
   }
    usbSetInterrupt(BuildReport(8), 8);
    while (!usbInterruptIsReady())
   {
      wdReset();
      usbPoll();
   }
    usbSetInterrupt(&usbNullRep[0], 0);
}
where:
static uchar usbNullRep[1]; // = {0}
SendData() is called from void main() in the main while(1) {...} loop.


Is that it what you was thinking about ?
(I know it's rather dirty approach to the problem... :) )

Posted: Mon Dec 11, 2006 12:15 pm
by christian
I have not tested this approach, but I think it should work.

Yes, this is rather dirty coding, but that's what I meant with "The driver is not really prepared to handle interrupt-IN transfers of more than 7 bytes".