static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) { USBHIDState *s = (USBHIDState *)dev; int ret = 0; switch(p->pid) { case USB_TOKEN_IN: if (p->devep == 1) { /* TODO: Implement finite idle delays. */ if (!(s->changed || s->idle)) return USB_RET_NAK; s->changed = 0; if (s->kind == USB_MOUSE) ret = usb_mouse_poll(s, p->data, p->len); else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, p->data, p->len); else if (s->kind == USB_KEYBOARD) ret = usb_keyboard_poll(&s->kbd, p->data, p->len); } else { goto fail; } break; case USB_TOKEN_OUT: default: fail: ret = USB_RET_STALL; break; } return ret; }
int main(void) { // Initialise the LED. led_init(); // Initialise the IR decoder. ir_init(); // Initialise the USB keyboard handler. usb_keyboard_init(); // Initialise timer 0 to use it as a 4ms timer. TCCR0A |= _BV(WGM01); // Mode = 2, CTC. TCCR0B |= _BV(CS02); // clkIO/256 OCR0A = ((256 * 4) / ((1000.0 * 256 * 256) / F_CPU)) - 1; // Desired interrupt frequency is once every 4ms. TIMSK0 |= _BV(OCIE0A); // Enable interrupts. sei(); // Flash the LED to indicate we're running. led_blink(LED_BLINK_PATTERN_3_MEDIUM); // Infinite loop. for(;;) { // USB polling. usb_keyboard_poll(); } }
static int usb_keyboard_handle_data(USBDevice *dev, int pid, uint8_t devep, uint8_t *data, int len) { USBKeyboardState *s = (USBKeyboardState *)dev; int ret = 0; unsigned char buf[8]; switch(pid) { case USB_TOKEN_IN: if (devep == 1) { ret = usb_keyboard_poll(s, data, len); } else { goto fail; } break; case USB_TOKEN_OUT: ret=0; memset(buf, 0, 8); buf[2]=data[1]; buf[3]=data[2]; buf[4]=data[3]; buf[5]=data[4]; // printf("Lamps %02X %02X %02X %02X %02X %02X %02X %02X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); CancelIo(usb_buzzer); WriteFile(usb_buzzer, buf, 8, 0, &ovl); break; default: fail: ret = USB_RET_STALL; break; } return ret; }
static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) { USBHIDState *s = (USBHIDState *)dev; int ret = 0; switch(p->pid) { case USB_TOKEN_IN: if (p->devep == 1) { if (s->kind == USB_MOUSE || s->kind == USB_TABLET) ret = usb_pointer_poll(s, p->data, p->len); else if (s->kind == USB_KEYBOARD) ret = usb_keyboard_poll(s, p->data, p->len); } else { goto fail; } break; case USB_TOKEN_OUT: default: fail: ret = USB_RET_STALL; break; } return ret; }
static int usb_hid_handle_control(USBDevice *dev, int request, int value, int index, int length, uint8_t *data) { USBHIDState *s = (USBHIDState *)dev; int ret = 0; switch(request) { case DeviceRequest | USB_REQ_GET_STATUS: data[0] = (1 << USB_DEVICE_SELF_POWERED) | (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); data[1] = 0x00; ret = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 0; } else { goto fail; } ret = 0; break; case DeviceOutRequest | USB_REQ_SET_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 1; } else { goto fail; } ret = 0; break; case DeviceOutRequest | USB_REQ_SET_ADDRESS: dev->addr = value; ret = 0; break; case DeviceRequest | USB_REQ_GET_DESCRIPTOR: switch(value >> 8) { case USB_DT_DEVICE: memcpy(data, qemu_mouse_dev_descriptor, sizeof(qemu_mouse_dev_descriptor)); ret = sizeof(qemu_mouse_dev_descriptor); break; case USB_DT_CONFIG: if (s->kind == USB_MOUSE) { memcpy(data, qemu_mouse_config_descriptor, sizeof(qemu_mouse_config_descriptor)); ret = sizeof(qemu_mouse_config_descriptor); } else if (s->kind == USB_TABLET) { memcpy(data, qemu_tablet_config_descriptor, sizeof(qemu_tablet_config_descriptor)); ret = sizeof(qemu_tablet_config_descriptor); } else if (s->kind == USB_KEYBOARD) { memcpy(data, qemu_keyboard_config_descriptor, sizeof(qemu_keyboard_config_descriptor)); ret = sizeof(qemu_keyboard_config_descriptor); } break; case USB_DT_STRING: switch(value & 0xff) { case 0: /* language ids */ data[0] = 4; data[1] = 3; data[2] = 0x09; data[3] = 0x04; ret = 4; break; case 1: /* serial number */ ret = set_usb_string(data, "1"); break; case 2: /* product description */ ret = set_usb_string(data, s->dev.devname); break; case 3: /* vendor description */ ret = set_usb_string(data, "QEMU " QEMU_VERSION); break; case 4: ret = set_usb_string(data, "HID Mouse"); break; case 5: ret = set_usb_string(data, "HID Tablet"); break; case 6: ret = set_usb_string(data, "HID Keyboard"); break; case 7: ret = set_usb_string(data, "Endpoint1 Interrupt Pipe"); break; default: goto fail; } break; default: goto fail; } break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: data[0] = 1; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: ret = 0; break; case DeviceRequest | USB_REQ_GET_INTERFACE: data[0] = 0; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_INTERFACE: ret = 0; break; /* hid specific requests */ case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: switch(value >> 8) { case 0x22: if (s->kind == USB_MOUSE) { memcpy(data, qemu_mouse_hid_report_descriptor, sizeof(qemu_mouse_hid_report_descriptor)); ret = sizeof(qemu_mouse_hid_report_descriptor); } else if (s->kind == USB_TABLET) { memcpy(data, qemu_tablet_hid_report_descriptor, sizeof(qemu_tablet_hid_report_descriptor)); ret = sizeof(qemu_tablet_hid_report_descriptor); } else if (s->kind == USB_KEYBOARD) { memcpy(data, qemu_keyboard_hid_report_descriptor, sizeof(qemu_keyboard_hid_report_descriptor)); ret = sizeof(qemu_keyboard_hid_report_descriptor); } break; default: goto fail; } break; case GET_REPORT: if (s->kind == USB_MOUSE) ret = usb_mouse_poll(s, data, length); else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, data, length); else if (s->kind == USB_KEYBOARD) ret = usb_keyboard_poll(&s->kbd, data, length); break; case SET_REPORT: if (s->kind == USB_KEYBOARD) ret = usb_keyboard_write(&s->kbd, data, length); else goto fail; break; case GET_PROTOCOL: if (s->kind != USB_KEYBOARD) goto fail; ret = 1; data[0] = s->protocol; break; case SET_PROTOCOL: if (s->kind != USB_KEYBOARD) goto fail; ret = 0; s->protocol = value; break; case GET_IDLE: ret = 1; data[0] = s->idle; break; case SET_IDLE: s->idle = value; ret = 0; break; default: fail: ret = USB_RET_STALL; break; } return ret; }
static int usb_keyboard_handle_control(USBDevice *dev, int request, int value, int index, int length, uint8_t *data) { USBKeyboardState *s = (USBKeyboardState *)dev; int ret = 0; unsigned char buf[8]; switch(request) { case DeviceRequest | USB_REQ_GET_STATUS: data[0] = (1 << USB_DEVICE_SELF_POWERED) | (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); data[1] = 0x00; ret = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 0; } else { goto fail; } ret = 0; break; case DeviceOutRequest | USB_REQ_SET_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 1; } else { goto fail; } ret = 0; break; case DeviceOutRequest | USB_REQ_SET_ADDRESS: dev->addr = value; ret = 0; break; case DeviceRequest | USB_REQ_GET_DESCRIPTOR: switch(value >> 8) { case USB_DT_DEVICE: memcpy(data, qemu_keyboard_dev_descriptor, sizeof(qemu_keyboard_dev_descriptor)); ret = sizeof(qemu_keyboard_dev_descriptor); break; case USB_DT_CONFIG: memcpy(data, qemu_keyboard_config_descriptor, sizeof(qemu_keyboard_config_descriptor)); ret = sizeof(qemu_keyboard_config_descriptor); break; case USB_DT_STRING: switch(value & 0xff) { case 0: /* language ids */ data[0] = 4; data[1] = 3; data[2] = 0x09; data[3] = 0x04; ret = 4; break; case 1: /* serial number */ ret = set_usb_string(data, "1"); break; case 2: /* product description */ ret = set_usb_string(data, "Generic USB Keyboard"); break; case 3: /* vendor description */ ret = set_usb_string(data, "PCSX2/QEMU"); break; case 4: ret = set_usb_string(data, "HID Keyboard"); break; case 5: ret = set_usb_string(data, "Endpoint1 Interrupt Pipe"); break; default: goto fail; } break; default: goto fail; } break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: data[0] = 1; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: ret = 0; break; case DeviceRequest | USB_REQ_GET_INTERFACE: data[0] = 0; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_INTERFACE: ret = 0; break; /* hid specific requests */ case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: switch(value >> 8) { case 0x22: memcpy(data, qemu_keyboard_hid_report_descriptor, sizeof(qemu_keyboard_hid_report_descriptor)); ret = sizeof(qemu_keyboard_hid_report_descriptor); break; default: goto fail; } break; case GET_REPORT: ret = usb_keyboard_poll(s, data, length); break; case 0x2109: ret=0; memset(buf, 0, 8); buf[2]=data[1]; buf[3]=data[2]; buf[4]=data[3]; buf[5]=data[4]; // printf("Lamps %02X %02X %02X %02X %02X %02X %02X\nlen = %i\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], length); CancelIo(usb_buzzer); WriteFile(usb_buzzer, buf, 8, 0, &ovl); break; case SET_IDLE: ret = 0; break; default: printf("Bad request value %08X", request); fail: ret = USB_RET_STALL; break; } return ret; }