Hm, I tried using resport_size (16) and report_count (2), but then I don't know how to save my 16 bit values in the reportBuffer. Because each item is just 8bit (uchar). And when there is the handover in usbFunctionSetup() like "usbMsgPtr = reportBuffer", the Buffer needs to be only 8bit wide, because usbMsgPtr is only 8bit wide.
Can I fill reportBuffer with an upper and lower 8bit value? How are the rules for this in AVR-USB?
I understand, that Avr-USB can only send 8bit at a time, because of the USB low speed spec, but how would one send two 8bits after one another to the host and get it there interpreted as one 16bit value?
I hope this doesn't sound too stupid.
I'm okay with reading the HID spec, but I think my problem relates more to the understanding of AVR-USB internals, right?
Although my code is really basic I put together the relevant pices and commented my knowledge gaps:
Code: Select all
static uchar reportBuffer[5]; // buffer for HID reports, this is increased from 3 to 5, because of 2 more 8bit values, right way?
// the descriptor below only introduces 3 reports: one 8 bit for the button, one 16bit for the X coordinate and another 16bit for the Y coordinate
static uchar idleRate; /* in 4 ms units */
// absolute mouse hid descriptor, length is 62
char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] PROGMEM = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x00, 0x04, // LOGICAL_MAXIMUM (1024)
// 0x75, 0x08, // REPORT_SIZE (8)
0x75, 0x10, // REPORT_SIZE (16)
// 0x95, 0x02, // REPORT_COUNT (2)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Rel) absolute
0x09, 0x31, // USAGE (Y)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x00, 0x03, // LOGICAL_MAXIMUM (768)
// 0x75, 0x08, // REPORT_SIZE (8)
0x75, 0x10, // REPORT_SIZE (16)
// 0x95, 0x02, // REPORT_COUNT (2)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Rel) absolute
// 0x81, 0x06, // INPUT (Data,Var,Rel) relative
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
static char buildReport(void)
{
// retval 1 means, that something changed and we must send report
char retval = 0;
// button pressed? -> one absolute coordinate pair should be send
if ( (MPIN & _BV(RC)) == ACTIVE(_BV(RC)) ) {
// the test coordinate x=y=500 (somewhere in the lower middle of the screen) should be approached here, 500 dec is 0x01F4 hex
// set X
reportBuffer[1] = 0xf4; //how do I handover my 16 bit value in 8bit chunks here?
reportBuffer[2] = 0x01; // it doesn't work like this, only one of the two 8 bit values gets interpreted at the host, its not seen as one single 16bit value
// set Y
reportBuffer[3] = 0xf4; // here's the same problem
reportBuffer[4] = 0x01;
retval = 1;
}
return retval;
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
usbMsgPtr = reportBuffer; //because of this, reportBuffer needs to be 8bit wide and can't be changed to 16bit wide, right?
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* we only have one report type, so don't look at wValue */
buildReport();
return sizeof(reportBuffer);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
usbMsgPtr = &idleRate;
return 1;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
}
}else{
/* no vendor specific requests implemented */
}
return 0;
}
I'm really stuck here...
Many thanks in advance, for any help.
Ciao,
Oli
p.s. this touchscreen controller project will be published and documented as open source of course. I know this is required, but how many do it actually? ;)