HID Variable data length

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

HID Variable data length

Post by drquark » Mon Mar 12, 2018 4:35 pm

Hi,

I'm working on a project for vehicle diagnostic via CAN bus. I'd like to use the V-USB library to do the communication, but I'm wondering if it's possible to send data with non-fixed data length (as the electronic control units reply with variable data length). Is there any other project doing that ?
Thank you in advance.

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Mon Mar 12, 2018 7:27 pm

I'm working on a project for vehicle diagnostic via CAN bus.

I'd like to use the V-USB library to do the communication


Hi, honestly not trying to be wrong with you, I just don't follow and am curios. Can is a 12v LL and usb is 5, neither have anything in common other then two wires? USB bulk would be closer to none fixed data but that is not really going to get you far. Can requires no descriptions to be made like USB does, and 98% of V-usb is unusable for CAN_BUS data.


Are you just looking for a way to bit bang CAN on wires?

drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Mon Mar 12, 2018 10:18 pm

Sorry, I haven't been clear. I use a MCP2515 (CAN to SPI bus) to transfer data to/from avr and I want to use V-USB to communicate with a computer. The problem here is that CAN response have an arbitrary response length, and I want to know if it's manageable with V-USB. Is there any sample code using bulk transfer ?

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Tue Mar 13, 2018 2:27 pm

Things are a tab bit more clear now but there is still a void here? What you are attempting is perfectly fine but the data you acquire via usb does not get dumped to ISP, so you have time to format your data. For example, say you want to get x bytes of data from the usb, then write to CAN. Use a normal Feature report get/set data, set flag, possess data, and send via CAN.

Now, if you are looking to do stuff in real time know first that Can is slow and USB will be clocks a head of it. So that will not lend its self well as USB wants NAK/ACK all the time. Your better off using a shift register style to unload the data in a timely matter.

To answer your question in detail you will need to more more clearly what stops you from accomplishing your task but in general this should be ok if designed correctly. Bulk transfers are not interned to be accountable in a timely fashion so that may not be what you want. Using a feature get/set could be your best bet but v-usb struggles in ACK/NACK %80 of the time so its picky at best. If you are just reading from can a normal interrupt transfer with a fixed payload will be fine.

drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Tue Mar 13, 2018 3:18 pm

Thank you for your reply,
I'm studying the CDC232 source code as it seems a good starting point for me. About CAN network, standard vehicle frames (non ISO_TP) are fixed length (8 bytes long). But I'd like to use CAN ISO_TP format (for diagnostic operation) and in this operation mode, the frames can be of any length (input/output).
Example :
Send 2 bytes to CAN bus

Code: Select all

21 80

in ISO_TP mode the ECU should reply something like

Code: Select all

61 80 xx xx xx
(5 bytes, but maybe more or less)
How can I return such a frame to the host as it doesn't know how much data to expect ?

Thank you

My GitHub project

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Tue Mar 13, 2018 5:34 pm

I'm a CAN engineer actually, so I know what you mean in the way of CAN. I think what you are asking here is to tunnel CAN thru USB. You can do this very easily with Feature reports. With usb 1.1 you are limited to 512 message lengths.

To send you pick a report ID call it 20. You then send the data as
report ID, length, data...

to read you use report ID 19
report ID, data.

In usb the size of the report 19 will always need to be 512. but you flag the un set data..
ff,ff,ff,ff,ff,ff,ff,....
then place your reply in that
19,d0,d1,d2,ff,ff,ff,ff
now you know you have a message length of 3 to deal with.


example of a report id with 192 bytes 19 read, 20 send.
0x85, 0x13, // REPORT_ID (19)
0x95, 0xc0, // REPORT_COUNT (192)
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)

0x85, 0x14, // REPORT_ID (20)
0x95, 0xc4, // REPORT_COUNT (196) 192+(rid,usb info 3 bytes )
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)


You can check out the data send examples that comes with v-usb but there is a lot to learn here.

In the case where data > 512, you will need to make two acquisitions. If > 1024, 3 and so on. USB will always have data limits.

drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Tue Mar 13, 2018 7:05 pm

Thank you so much, I'll try to understand how to build a USB report descriptor of this type (didn't find an example doing it).
512 bytes should be enough for my use, anyway !

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Tue Mar 13, 2018 8:04 pm


drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Tue Mar 13, 2018 10:11 pm

Great !
If I set the first byte of the buffer with the message length to the host, is it possible to abort USB communication when I get the desired buffer size ?

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Wed Mar 14, 2018 1:30 pm

The host software can do anything you want in software obviously. It can not do anything driver wise (killing/resetting the port) unles you are low level like C or use devcon or like. Again though you are not showing your design.

Say you create a loop in your code.

while(x)
checkForData();

in checkForData you have feature reports as earlier discussed. You could always set X to false to stop communication. Feature reports are controlled by the host only as why I suggested them.

drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Wed Mar 14, 2018 4:48 pm

Good,
How do I transfer 512 bytes, as REPORT_COUNT is a byte with a max value of 0xFF (255) ?
I understand that I can define USB_CFG_LONG_TRANSFERS to 1 to make it possible, but finally what's the use of REPORT_COUNT in the usb report descriptor ?
in the wiki, I found this code snippet :

Code: Select all

static uchar buffer[64];
 
usbMsgLen_t usbFunctionSetup(uchar setupData[8])
{
    usbRequest_t *rq = (void *)setupData;   // cast to structured data for parsing
    switch(rq->bRequest){
    case VENDOR_RQ_READ_BUFFER:
        usbMsgLen_t len = 64;                     // we return up to 64 bytes
        if(len > rq->wLength.word)          // if the host requests less than we have
            len = rq->wLength.word;         // return only the amount requested
        usbMsgPtr = buffer;                 // tell driver where the buffer starts
        return len;                         // tell driver how many bytes to send
    }
    return 0;                               // ignore all unknown requests
}


That helps me understand, but I'm in trouble with this famous REPORT_COUNT value... :?:

drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Wed Mar 14, 2018 6:10 pm

Ok, I think I found that macro to set to a higher value :D

Code: Select all

#define HID_ReportCountS(x)     0x96,(x&0xFF),((x>>8)&0xFF)

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Thu Mar 15, 2018 1:42 pm

0x96 is correct.

drquark
Posts: 9
Joined: Mon Mar 12, 2018 4:30 pm

Re: HID Variable data length

Post by drquark » Thu Mar 15, 2018 10:14 pm

I'm almost ready to start my project, I have a last question : I'd like to use the millis() function from Arduino code, but it uses TIMER 0 overflow interrupt. I read in the wiki :
Make sure that you're not using interrupts higher than the interrupt you have set for VUSB. Also make sure you're not disabling interrupts for longer than a few millisecond

Knowing that this interrupt function is very fast to execute and its priority is lower, do I need to find an alternative method for millis() or it should be fine ?
Regards

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: HID Variable data length

Post by ulao » Fri Mar 16, 2018 5:07 pm

v-usb only uses one interrupt and it does not disable it at any time. I see no issues.

Post Reply