How to output data to e.g. HID device

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
vsovereign
Rank 1
Rank 1
Posts: 21
Joined: Wed Dec 30, 2009 3:24 pm

Re: How to output data to e.g. HID device

Post by vsovereign » Sun Feb 21, 2010 6:35 pm

Hi,

sorry for this newbie question.
I've run the HID_data example that is mentioned above.
It works okay.
But now I'm trying to understand it.
Especially the host part.

hidtool.c is how you read and write to the device.
But how does it actually accomplish this?

hiddata.c .....well I assume this is where the device is recognized?
Also where the size of the data is determined?
But I thought that the firmware part does the recognizing task.
Why do we need another program?
Is my understanding of hiddata.c correct?

Also what do these do? They're in : vusb -> examples -> hid_data -> commandline -> hid_tool


static void hexdump(char *buffer, int len)
{
int i;
FILE *fp = stdout;

for(i = 0; i < len; i++){
if(i != 0){
if(i % 16 == 0){
fprintf(fp, "\n");
}else{
fprintf(fp, " ");
}
}
fprintf(fp, "0x%02x", buffer[i] & 0xff);
}
if(i != 0)
fprintf(fp, "\n");
}

static int hexread(char *buffer, char *string, int buflen)
{
char *s;
int pos = 0;

while((s = strtok(string, ", ")) != NULL && pos < buflen){
string = NULL;
buffer[pos++] = (char)strtol(s, NULL, 0);
}
return pos;
}




Thank you

dima_hz
Posts: 3
Joined: Fri May 14, 2010 4:22 pm

How to output data to e.g. HID device

Post by dima_hz » Fri May 14, 2010 5:04 pm

Hello everyone here. Nice work i have found here. I also have a little time and just tried something from here. Also i know about this site from long time ago. Sincerely i like everything which is here.
Now i would like to ask something about increasing lenght from 254 to 512 or 1024... maximum which i could try was 254 bytes. If i try to put something bigger it returns strange values... In one word the result is not satisfactory. I am speaking about hiddata example. so there is what i have done:

1. increased the report count

PROGMEM char usbHidReportDescriptor[23] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
// 0x95, 0x80, // REPORT_COUNT (128)
// 0x95, 0xFF, // REPORT_COUNT (255)
// 0x96, 0x00, 0x01, // REPORT_COUNT (256)
0x96, 0x00, 0x02, // REPORT_COUNT (512)
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
0xc0 // END_COLLECTION
};





2. changed usbHidReportDescriptor[23] from 22 to 23

3. changed the same value at usbconfig.h
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 23

3. changed long transfers in usbconfig.h
#define USB_CFG_LONG_TRANSFERS 1

4. created one #define in main.c (firmware code) to work much easier and to not look everywere for values... and used this define everywhere in the code where was indicated 128 (original value) and replaced.

#define EEP_BITES 255 // number of bytes remaining. Original 128

usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;

if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID class request */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* since we have only one report type, we can ignore the report-ID */
bytesRemaining = EEP_BITES;
currentAddress = 0;
return USB_NO_MSG; /* use usbFunctionRead() to obtain data */
}else if(rq->bRequest == USBRQ_HID_SET_REPORT){
/* since we have only one report type, we can ignore the report-ID */
bytesRemaining = EEP_BITES;
currentAddress = 0;
return USB_NO_MSG; /* use usbFunctionWrite() to receive data from host */
}
}else{
//..... case 0.1.2....
}



5. Now speaking about hidtool.exe
i have changed lenght from 129 (128+1) to 513 (512+1)

int main(int argc, char **argv)
{
usbDevice_t *dev;
char buffer[513]; /* room for dummy report ID*/
int err;

if(argc < 2){
usage(argv[0]);
exit(1);
}
if((dev = openDevice()) == NULL)
exit(1);
if(strcasecmp(argv[1], "read") == 0){
int len = sizeof(buffer);
if((err = usbhidGetReport(dev, 0, buffer, &len)) != 0){
fprintf(stderr, "error reading data: %s\n", usbErrorMessage(err));
}else{
hexdump(buffer + 1, sizeof(buffer) - 1);
}
}else if(strcasecmp(argv[1], "write") == 0){
int i, pos;
memset(buffer, 0, sizeof(buffer));
for(pos = 1, i = 2; i < argc && pos < sizeof(buffer); i++){
pos += hexread(buffer + pos, argv[i], sizeof(buffer) - pos);
}
if((err = usbhidSetReport(dev, buffer, sizeof(buffer))) != 0) /* add a dummy report ID */
fprintf(stderr, "error writing data: %s\n", usbErrorMessage(err));
}else{
usage(argv[0]);
exit(1);
}
usbhidCloseDevice(dev);
return 0;
}


compiled with MinGW. everything work fine device reads 512 bytes. but correctly it reads only first 255 because in main.c there is (#define EEP_BITES 255 // number of bytes remaining. Original 128)
now when i try to increase this to 256 or much much more it doesn`t read even first 255 bytes. I guess it sends command in hex format like 0xFF (254 bytes) or maybe i am wrong why i can`t get it work???
should i increase this too in HidDescriptors: PROGMEM -->>>> 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) to 511 or bigger? any ideea please
I have increased it to read from 128 to 255 but how to do it for much more??? Now devices have bigger eeprom sizes. Thanks!!! and sorry for my long long message. I appreciate that from you! Soon i will post some examples which i have developed in C++ builder 2009 based on powerswitch... opening, closing ports ; read write some bits to eeprom ; controlling LCD in the same time, etc All with GUI interface.

dima_hz
Posts: 3
Joined: Fri May 14, 2010 4:22 pm

How to output data to e.g. HID device

Post by dima_hz » Fri May 14, 2010 5:08 pm

answer for (vsovereign)
regarding your last post. this functions are used for converting received data from USB device to strings and printing them into the application. Also All Bytes have in front the sign (0x) when they are shown to you in hidtool.c eg: 0xFF, 0x01, etc.

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

Re: How to output data to e.g. HID device

Post by christian » Mon May 17, 2010 3:14 pm

Have you checked that bytesRemaining is 16 bit, not 8 bit as in the example?

In any case, you don't need to change the logical maximum. that's just the value range of a byte explained to the host side driver.

Also, please check whether you use usbRequest->wLength anywhere. Most examples use the low 8 bit only in order to save code size. If you exceed 255 bytes, you must honor all 16 bits.

n-regen
Posts: 5
Joined: Tue Aug 10, 2010 9:51 pm

Re: How to output data to e.g. HID device

Post by n-regen » Tue Aug 10, 2010 9:57 pm

iphi wrote:Ok, I finally figured it out to feed HID_DATA from Delphi.
The JvHidController component works great.
If anybody would like the Pascal code, contact me.
Tom

Could you please upload your source somewhere or send it to nrsend-delphihiddata[at]yahoo[dot]de?
I spent the whole day trying different Delphi-implementations of the hid-data example and all of them failed, so a working example would be really helpful.

Post Reply