32#define MODNAME "PS2 USB mouse driver"
36#define PS2MOUSE_VERSION 0x100
38#define USB_SUBCLASS_BOOT 1
39#define USB_HIDPROTO_MOUSE 2
41#define PS2MOUSE_MAXDEV 2
42#define PS2MOUSE_MAXBUTTONS 3
44#define PS2MOUSE_DEFDBLCLICK 500
46#define PS2MOUSE_DEFACCEL (1 << 16)
47#define PS2MOUSE_DEFTHRES 65536;
53#define ABS(x) (x < 0 ? -x : x)
55void rpcMainThread(
void* param);
56void *rpcCommandHandler(u32 command,
void *buffer,
int size);
59void ps2mouse_config_set(
int resultCode,
int bytes,
void *arg);
60void ps2mouse_data_recv(
int resultCode,
int bytes,
void *arg);
61int ps2mouse_probe(
int devId);
62int ps2mouse_connect(
int devId);
63int ps2mouse_disconnect(
int devId);
64void usb_getstring(
int endp,
int index,
char *desc);
69 unsigned char buttons;
95int mouse_dblclicktime;
102sceUsbdLddOps mouse_driver = { NULL, NULL,
"PS2Mouse", ps2mouse_probe, ps2mouse_connect, ps2mouse_disconnect, 0, 0, 0, 0, 0, NULL };
104int _start (
int argc,
char *argv[])
115 param.thread = rpcMainThread;
117 param.stacksize = 0x800;
120 th = CreateThread(¶m);
122 StartThread(th, NULL);
123 return MODULE_RESIDENT_END;
125 else return MODULE_NO_RESIDENT_END;
128void rpcMainThread(
void* param)
137 printf(
"PS2MOUSE - USB Mouse Library\n");
140 SifSetRpcQueue(&ps2mouse_queue, tid);
141 SifRegisterRpc(&ps2mouse_server, PS2MOUSE_BIND_RPC_ID, (
void *) rpcCommandHandler, (u8 *) &_rpc_buffer, 0, 0, &ps2mouse_queue);
142 SifRpcLoop(&ps2mouse_queue);
145int ps2mouse_probe(
int devId)
154 if(dev_count >= PS2MOUSE_MAXDEV)
156 printf(
"ERROR: Maximum mouse devices reached\n");
162 dev = sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_DEVICE);
165 printf(
"ERROR: Couldn't get device descriptor\n");
171 if((dev->bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->bNumConfigurations < 1))
177 conf = sceUsbdScanStaticDescriptor(devId, dev, USB_DT_CONFIG);
187 printf(
"ERROR: No interfaces available\n");
196 if((intf->bInterfaceClass != USB_CLASS_HID) || (intf->bInterfaceSubClass != USB_SUBCLASS_BOOT) ||
197 (intf->bInterfaceProtocol != USB_HIDPROTO_MOUSE) || (intf->bNumEndpoints < 1))
208 if(((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) ||
209 ((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN))
211 printf(
"ERROR: Endpoint not interrupt type and/or an input\n");
215 printf(
"PS2MOUSE: Found a mouse device\n");
220int ps2mouse_connect(
int devId)
234 dev = sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_DEVICE);
237 printf(
"ERROR: Couldn't get device descriptor\n");
241 conf = sceUsbdScanStaticDescriptor(devId, dev, USB_DT_CONFIG);
244 printf(
"ERROR: Couldn't get configuration descriptor\n");
255 printf(
"ERROR: Couldn't allocate a device point for the mouse\n");
259 currDev->configEndp = sceUsbdOpenPipe(devId, NULL);
260 currDev->dataEndp = sceUsbdOpenPipe(devId, endp);
261 currDev->packetSize = endp->wMaxPacketSizeLB | ((int) endp->wMaxPacketSizeHB << 8);
267 currDev->devId = devId;
269 if(dev->iManufacturer)
271 usb_getstring(currDev->configEndp, dev->iManufacturer,
"Mouse Manufacturer");
276 usb_getstring(currDev->configEndp, dev->iProduct,
"Mouse Product");
279 for(devLoop = 0; devLoop < PS2MOUSE_MAXDEV; devLoop++)
288 if(devLoop == PS2MOUSE_MAXDEV)
291 printf(
"ERROR: Device Weirdness!!\n");
295 sceUsbdSetPrivateData(devId, currDev);
298 sceUsbdSetConfiguration(currDev->configEndp, conf->bConfigurationValue, ps2mouse_config_set, currDev);
301 printf(
"PS2MOUSE: Connected device\n");
306int ps2mouse_disconnect(
int devId)
312 for(devLoop = 0; devLoop < PS2MOUSE_MAXDEV; devLoop++)
317 FreeSysMemory(
devices[devLoop]);
319 printf(
"PS2MOUSE: Disconnected device\n");
335void ps2mouse_getstring_set(
int resultCode,
int bytes,
void *arg)
350 memset(
string, 0, 50);
351 for(strLoop = 0; strLoop < ((bytes - 2) / 2); strLoop++)
353 string[strLoop] = str->wData[strLoop] & 0xFF;
355 printf(
"%s: %s\n", strBuf->desc,
string);
361void usb_getstring(
int endp,
int index,
char *desc)
375 ret = sceUsbdControlTransfer(endp, 0x80, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | index,
379 printf(
"PS2MOUSE: Error sending string descriptor request\n");
385void ps2mouse_config_set(
int resultCode,
int bytes,
void *arg)
393 printf(
"PS2MOUSE: Configuration set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
403 sceUsbdInterruptTransfer(dev->dataEndp, &dev->
data, dev->packetSize, ps2mouse_data_recv, arg);
407void ps2mouse_data_recv(
int resultCode,
int bytes,
void *arg)
414 printf(
"PS2MOUSE: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg);
427 WaitSema(mouse_sema);
432 if(ABS(mx) >= mouse_thres)
434 mx = (mx * mouse_accel) >> 16;
437 if(ABS(my) >= mouse_thres)
439 my = (my * mouse_accel) >> 16;
452 for(buttonLoop = 0; buttonLoop < PS2MOUSE_MAXBUTTONS; buttonLoop++)
454 int currButton = 1 << buttonLoop;
456 if( ((
mouse.buttons & currButton) == 0) && (dev->
data.buttons & currButton))
463 SysClock2USec(&t, (u32 *)&sec, (u32 *)&usec);
464 msec = (sec * 1000) + (usec / 1000);
467 if(dev->
timer[buttonLoop])
469 if((msec - dev->
timer[buttonLoop]) < (u32)mouse_dblclicktime)
472 buttonData |= (1 << (buttonLoop + 8));
473 dev->
timer[buttonLoop] = 0;
477 dev->
timer[buttonLoop] = msec;
482 dev->
timer[buttonLoop] = msec;
486 mouse.buttons = dev->
data.buttons | buttonData;
487 if(mouse_readmode == PS2MOUSE_READMODE_ABS)
489 if(
mouse.x < mousex_min)
mouse.x = mousex_min;
490 if(
mouse.x > mousex_max)
mouse.x = mousex_max;
491 if(
mouse.y < mousey_min)
mouse.y = mousey_min;
492 if(
mouse.y > mousey_max)
mouse.y = mousey_max;
495 SignalSema(mouse_sema);
498 sceUsbdInterruptTransfer(dev->dataEndp, &dev->
data, dev->packetSize, ps2mouse_data_recv, arg);
511 mouse_sema = CreateSema(&s);
514 printf(
"ERROR: Couldn't create ps2mouse sema\n");
518 if(sceUsbdRegisterLdd(&mouse_driver) >= 0)
523 mouse_readmode = PS2MOUSE_READMODE_DIFF;
524 mousex_min = -1000000;
525 mousex_max = 1000000;
526 mousey_min = -1000000;
527 mousey_max = 1000000;
528 mouse_dblclicktime = PS2MOUSE_DEFDBLCLICK;
529 mouse_accel = PS2MOUSE_DEFACCEL;
530 mouse_thres = PS2MOUSE_DEFTHRES;
534 printf(
"ERROR: Couldn't register ps2mouse driver\n");
541void do_ps2mouse_read(u8 *data,
int size)
550 if(mouse_readmode == PS2MOUSE_READMODE_DIFF)
555 mouse.buttons &= 0xFF;
560 mouse.buttons &= 0xFF;
564void do_ps2mouse_setreadmode(
const u32 *data,
int size)
570 if(data[0] == (u32)mouse_readmode)
575 if((data[0] != PS2MOUSE_READMODE_DIFF) && (data[0] != PS2MOUSE_READMODE_ABS))
577 printf(
"ERROR: Invalid readmode\n");
582 mouse_readmode = data[0];
583 if(mouse_readmode == PS2MOUSE_READMODE_ABS)
585 mouse.x = mousex_min;
586 mouse.y = mousey_min;
590void do_ps2mouse_getreadmode(u32 *data,
int size)
596 data[0] = mouse_readmode;
599void do_ps2mouse_setthres(
const u32 *data,
int size)
605 mouse_thres = data[0];
608void do_ps2mouse_getthres(u32 *data,
int size)
614 data[0] = mouse_thres;
617void do_ps2mouse_setaccel(
const u32 *data,
int size)
623 mouse_accel = data[0];
626void do_ps2mouse_getaccel(u32 *data,
int size)
632 data[0] = mouse_accel;
635void do_ps2mouse_setboundary(
const s32 *data,
int size)
641 if(data[0] < data[1])
643 mousex_min = data[0];
644 mousex_max = data[1];
647 if(data[2] < data[3])
649 mousey_min = data[2];
650 mousey_max = data[3];
652 if(mouse_readmode == PS2MOUSE_READMODE_ABS)
655 mouse.x = mousex_min;
656 mouse.y = mousey_min;
660void do_ps2mouse_getboundary(s32 *data,
int size)
666 data[0] = mousex_min;
667 data[1] = mousex_max;
668 data[2] = mousey_min;
669 data[3] = mousey_max;
672void do_ps2mouse_setposition(
const s32 *data,
int size)
679 WaitSema(mouse_sema);
681 if(data[0] < mousex_min)
683 mouse.x = mousex_min;
685 else if(data[0] > mousex_max)
687 mouse.x = mousex_max;
694 if(data[1] < mousey_min)
696 mouse.y = mousey_min;
698 else if(data[1] > mousey_max)
700 mouse.y = mousey_max;
706 SignalSema(mouse_sema);
709void do_ps2mouse_reset()
714 if(mouse_readmode == PS2MOUSE_READMODE_ABS)
716 mouse.x = mousex_min;
717 mouse.y = mousey_min;
721void do_ps2mouse_enum(u32 *data,
int size)
730void do_ps2mouse_setdblclicktime(
const u32 *data,
int size)
736 mouse_dblclicktime = data[0];
739void do_ps2mouse_getdblclicktime(u32 *data,
int size)
745 data[0] = mouse_dblclicktime;
748void do_ps2mouse_getversion(u32 *data,
int size)
754 data[0] = PS2MOUSE_VERSION;
757void *rpcCommandHandler(u32 command,
void *buffer,
int size)
762 case PS2MOUSE_READ: do_ps2mouse_read((u8 *) buffer, size);
764 case PS2MOUSE_SETREADMODE: do_ps2mouse_setreadmode((u32 *) buffer, size);
766 case PS2MOUSE_GETREADMODE: do_ps2mouse_getreadmode((u32 *) buffer, size);
768 case PS2MOUSE_SETTHRES: do_ps2mouse_setthres((u32 *) buffer, size);
770 case PS2MOUSE_GETTHRES: do_ps2mouse_getthres((u32 *) buffer, size);
772 case PS2MOUSE_SETACCEL: do_ps2mouse_setaccel((u32 *) buffer, size);
774 case PS2MOUSE_GETACCEL: do_ps2mouse_getaccel((u32 *) buffer, size);
776 case PS2MOUSE_SETBOUNDARY: do_ps2mouse_setboundary((s32 *) buffer, size);
778 case PS2MOUSE_GETBOUNDARY: do_ps2mouse_getboundary((s32 *) buffer, size);
780 case PS2MOUSE_SETPOSITION: do_ps2mouse_setposition((s32 *) buffer, size);
782 case PS2MOUSE_RESET: do_ps2mouse_reset();
784 case PS2MOUSE_ENUM: do_ps2mouse_enum((u32 *) buffer, size);
786 case PS2MOUSE_SETDBLCLICKTIME: do_ps2mouse_setdblclicktime((u32 *) buffer, size);
788 case PS2MOUSE_GETDBLCLICKTIME: do_ps2mouse_getdblclicktime((u32 *) buffer, size);
790 case PS2MOUSE_GETVERSION: do_ps2mouse_getversion((u32 *) buffer, size);
792 default : printf(
"Unknown PS2MOUSE command %ld\n", command);
u32 timer[PS2MOUSE_MAXBUTTONS]
mouse_dev * devices[PS2MOUSE_MAXDEV]