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? ;)