I'm actually using V-USB in a HID mouse code on Atmega 328P. The mouse port (descriptor, mvt...) is working very well. But the bad things came when I tried to implements HID features. I'd like to be able to read a mouse speed param using a HID feature request from a PC and to change it from PC to mouse.
My question is HOW ?
I'm using SimpleHIDwrite3 from usb.org on the PC host to read and write HID features.
here is my descriptor:
Code: Select all
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf) 0xb1, 0x00, // FEATURE (Data,Ary,Abs)
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)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
my main.c is :
Code: Select all
/../
typedef struct{
uchar buttonMask;
char dx;
char dy;
char dWheel;
}report_t;
static report_t reportBuffer;
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar setupData[8])
{
usbRequest_t *rq = (void *)setupData; // cast to structured data for parsing
switch(rq->bRequest){
case 1:
currentPosition = 0; // initialize position index
bytesRemaining = rq->wLength.word; // store the amount of data requested
return USB_NO_MSG; // tell driver to use usbFunctionRead()
}
return 0; // ignore all unknown requests
}
/* ------------------------------------------------------------------------- */
uchar usbFunctionRead(uchar *data, uchar len)
{
uchar i;
if(len > bytesRemaining) // len is max chunk size
len = bytesRemaining; // send an incomplete chunk
bytesRemaining -= len;
for(i = 0; i < len; i++)
data[i] = getData(currentPosition); // copy the data to the buffer
return len; // return real chunk size
}
int __attribute__((noreturn)) main(void)
{
wdt_enable(WDTO_1S);
/* RESET status: all port bits are inputs without pull-up.
* That's the way we need D+ and D-. Therefore we don't need any
* additional hardware initialization.
*/
PORTB |= (1 << PB0) | (1 << PB1); // enable pullups on button pins
_delay_ms(100);
usbInit();
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
uchar i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
sei();
for(;;){ /* main event loop */
reportBuffer.buttonMask = left_button_released;
wdt_reset();
usbPoll();
if(usbInterruptIsReady()){
getMouseMovement();
//DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
}
}
}
/* ------------------------------------------------------------------------- */
I read the page from http://vusb.wikidot.com/, USB_CFG_IMPLEMENT_FN_READ and USB_CFG_IMPLEMENT_FN_WRITE are set to 1.
A code exemple could be very appreciated.
Do someone have some clues ?
Regards,
hc