HID Variable data length
HID Variable data length
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.
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.
Re: HID Variable data length
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?
Re: HID Variable data length
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 ?
Re: HID Variable data length
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.
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.
Re: HID Variable data length
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
in ISO_TP mode the ECU should reply something like
(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
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
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
Re: HID Variable data length
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.
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.
Re: HID Variable data length
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 !
512 bytes should be enough for my use, anyway !
Re: HID Variable data length
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 ?
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 ?
Re: HID Variable data length
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.
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.
Re: HID Variable data length
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 :
That helps me understand, but I'm in trouble with this famous REPORT_COUNT value...
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...
Re: HID Variable data length
Ok, I think I found that macro to set to a higher value
Code: Select all
#define HID_ReportCountS(x) 0x96,(x&0xFF),((x>>8)&0xFF)
Re: HID Variable data length
0x96 is correct.
Re: HID Variable data length
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 :
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
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
Re: HID Variable data length
v-usb only uses one interrupt and it does not disable it at any time. I see no issues.