forked from mirrors/qmk_userspace
		
	added initial support of mousekeys to ps2_vusb
This commit is contained in:
		
					parent
					
						
							
								4f5f1a53d4
							
						
					
				
			
			
				commit
				
					
						0632618d29
					
				
			
		
					 14 changed files with 676 additions and 270 deletions
				
			
		| 
						 | 
					@ -65,7 +65,7 @@ FORMAT = ihex
 | 
				
			||||||
# Object files directory
 | 
					# Object files directory
 | 
				
			||||||
#     To put object files in current directory, use a dot (.), do NOT make
 | 
					#     To put object files in current directory, use a dot (.), do NOT make
 | 
				
			||||||
#     this an empty or blank macro!
 | 
					#     this an empty or blank macro!
 | 
				
			||||||
OBJDIR = .
 | 
					OBJDIR = obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Optimization level, can be [0, 1, 2, 3, s]. 
 | 
					# Optimization level, can be [0, 1, 2, 3, s]. 
 | 
				
			||||||
| 
						 | 
					@ -347,7 +347,7 @@ AR = avr-ar rcs
 | 
				
			||||||
NM = avr-nm
 | 
					NM = avr-nm
 | 
				
			||||||
AVRDUDE = avrdude
 | 
					AVRDUDE = avrdude
 | 
				
			||||||
REMOVE = rm -f
 | 
					REMOVE = rm -f
 | 
				
			||||||
REMOVEDIR = rm -rf
 | 
					REMOVEDIR = rmdir
 | 
				
			||||||
COPY = cp
 | 
					COPY = cp
 | 
				
			||||||
WINSHELL = cmd
 | 
					WINSHELL = cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -601,7 +601,8 @@ clean_list :
 | 
				
			||||||
	$(REMOVE) $(LST)
 | 
						$(REMOVE) $(LST)
 | 
				
			||||||
	$(REMOVE) $(OBJ:.o=.s)
 | 
						$(REMOVE) $(OBJ:.o=.s)
 | 
				
			||||||
	$(REMOVE) $(OBJ:.o=.i)
 | 
						$(REMOVE) $(OBJ:.o=.i)
 | 
				
			||||||
	$(REMOVEDIR) .dep
 | 
						$(REMOVE) -r .dep
 | 
				
			||||||
 | 
						$(REMOVEDIR) $(OBJDIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Create object files directory
 | 
					# Create object files directory
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,11 +9,13 @@ TARGET_DIR = .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# keyboard dependent files
 | 
					# keyboard dependent files
 | 
				
			||||||
TARGET_SRC =	main.c \
 | 
					TARGET_SRC =	main.c \
 | 
				
			||||||
		keyboard_vusb.c \
 | 
							keyboard.c \
 | 
				
			||||||
 | 
							mousekey.c \
 | 
				
			||||||
		layer.c \
 | 
							layer.c \
 | 
				
			||||||
		keymap.c \
 | 
							keymap.c \
 | 
				
			||||||
		matrix.c \
 | 
							matrix.c \
 | 
				
			||||||
		ps2.c \
 | 
							ps2.c \
 | 
				
			||||||
 | 
							host_vusb.c \
 | 
				
			||||||
		print.c \
 | 
							print.c \
 | 
				
			||||||
		util.c \
 | 
							util.c \
 | 
				
			||||||
		timer.c \
 | 
							timer.c \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								ps2_vusb/host.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ps2_vusb/host.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					#ifndef HOST_H
 | 
				
			||||||
 | 
					#define HOST_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define REPORT_KEYS 6
 | 
				
			||||||
 | 
					#define MOUSE_BTN1 (1<<0)
 | 
				
			||||||
 | 
					#define MOUSE_BTN2 (1<<1)
 | 
				
			||||||
 | 
					#define MOUSE_BTN3 (1<<2)
 | 
				
			||||||
 | 
					#define MOUSE_BTN4 (1<<3)
 | 
				
			||||||
 | 
					#define MOUSE_BTN5 (1<<4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    uint8_t mods;
 | 
				
			||||||
 | 
					    uint8_t rserved;    // not used
 | 
				
			||||||
 | 
					    uint8_t keys[REPORT_KEYS];
 | 
				
			||||||
 | 
					} report_keyboard_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    uint8_t buttons;
 | 
				
			||||||
 | 
					    int8_t x;
 | 
				
			||||||
 | 
					    int8_t y;
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    int8_t v;
 | 
				
			||||||
 | 
					    int8_t h;
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					} report_mouse_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_keyboard_send(report_keyboard_t *report);
 | 
				
			||||||
 | 
					void host_mouse_send(report_mouse_t *report);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										345
									
								
								ps2_vusb/host_vusb.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								ps2_vusb/host_vusb.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,345 @@
 | 
				
			||||||
 | 
					#include "usbdrv.h"
 | 
				
			||||||
 | 
					#include "usbconfig.h"
 | 
				
			||||||
 | 
					#include "keyboard.h"
 | 
				
			||||||
 | 
					#include "print.h"
 | 
				
			||||||
 | 
					#include "host.h"
 | 
				
			||||||
 | 
					#include "host_vusb.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define KBUF_SIZE 8
 | 
				
			||||||
 | 
					static report_keyboard_t kbuf[KBUF_SIZE];
 | 
				
			||||||
 | 
					static uint8_t kbuf_head = 0;
 | 
				
			||||||
 | 
					static uint8_t kbuf_tail = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_vusb_keyboard_send()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (kbuf_head != kbuf_tail) {
 | 
				
			||||||
 | 
					        if (usbInterruptIsReady()) {
 | 
				
			||||||
 | 
					            usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
 | 
				
			||||||
 | 
					            kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_keyboard_send(report_keyboard_t *report)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
 | 
				
			||||||
 | 
					    if (next != kbuf_tail) {
 | 
				
			||||||
 | 
					        kbuf[kbuf_head] = *report;
 | 
				
			||||||
 | 
					        kbuf_head = next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_mouse_send(report_mouse_t *report)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // dirty hack to send twice a loop :(
 | 
				
			||||||
 | 
					    //while (!usbInterruptIsReady3()) usbPoll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (usbInterruptIsReady3()) {
 | 
				
			||||||
 | 
					        usbSetInterrupt3((void *)report, sizeof(*report));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        print("Int3 not ready\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uchar    idleRate;   /* repeat rate for keyboards, never used for mice */
 | 
				
			||||||
 | 
					usbMsgLen_t usbFunctionSetup(uchar data[8])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					usbRequest_t    *rq = (void *)data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print("Setup: ");
 | 
				
			||||||
 | 
					    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */
 | 
				
			||||||
 | 
					        print("CLASS: ");
 | 
				
			||||||
 | 
					        phex(rq->bRequest);
 | 
				
			||||||
 | 
					        if(rq->bRequest == USBRQ_HID_GET_REPORT){
 | 
				
			||||||
 | 
					            print("GET_REPORT");
 | 
				
			||||||
 | 
					            /* we only have one report type, so don't look at wValue */
 | 
				
			||||||
 | 
					            usbMsgPtr = (void *)keyboard_report;
 | 
				
			||||||
 | 
					            return sizeof(*keyboard_report);
 | 
				
			||||||
 | 
					        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
 | 
				
			||||||
 | 
					            print("GET_IDLE: ");
 | 
				
			||||||
 | 
					            phex(idleRate);
 | 
				
			||||||
 | 
					            usbMsgPtr = &idleRate;
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
 | 
				
			||||||
 | 
					            idleRate = rq->wValue.bytes[1];
 | 
				
			||||||
 | 
					            print("SET_IDLE: ");
 | 
				
			||||||
 | 
					            phex(idleRate);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        print("\n");
 | 
				
			||||||
 | 
					    }else{
 | 
				
			||||||
 | 
					        print("VENDOR\n");
 | 
				
			||||||
 | 
					        /* no vendor specific requests implemented */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;   /* default for not implemented requests: return no data back to host */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROGMEM uchar keyboard_hid_report[] = {
 | 
				
			||||||
 | 
					    0x05, 0x01,          // Usage Page (Generic Desktop),
 | 
				
			||||||
 | 
					    0x09, 0x06,          // Usage (Keyboard),
 | 
				
			||||||
 | 
					    0xA1, 0x01,          // Collection (Application),
 | 
				
			||||||
 | 
					    0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					    0x95, 0x08,          //   Report Count (8),
 | 
				
			||||||
 | 
					    0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					    0x19, 0xE0,          //   Usage Minimum (224),
 | 
				
			||||||
 | 
					    0x29, 0xE7,          //   Usage Maximum (231),
 | 
				
			||||||
 | 
					    0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					    0x25, 0x01,          //   Logical Maximum (1),
 | 
				
			||||||
 | 
					    0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
 | 
				
			||||||
 | 
					    0x95, 0x01,          //   Report Count (1),
 | 
				
			||||||
 | 
					    0x75, 0x08,          //   Report Size (8),
 | 
				
			||||||
 | 
					    0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
 | 
				
			||||||
 | 
					    0x95, 0x05,          //   Report Count (5),
 | 
				
			||||||
 | 
					    0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					    0x05, 0x08,          //   Usage Page (LEDs),
 | 
				
			||||||
 | 
					    0x19, 0x01,          //   Usage Minimum (1),
 | 
				
			||||||
 | 
					    0x29, 0x05,          //   Usage Maximum (5),
 | 
				
			||||||
 | 
					    0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
 | 
				
			||||||
 | 
					    0x95, 0x01,          //   Report Count (1),
 | 
				
			||||||
 | 
					    0x75, 0x03,          //   Report Size (3),
 | 
				
			||||||
 | 
					    0x91, 0x03,          //   Output (Constant),                 ;LED report padding
 | 
				
			||||||
 | 
					    0x95, 0x06,          //   Report Count (6),
 | 
				
			||||||
 | 
					    0x75, 0x08,          //   Report Size (8),
 | 
				
			||||||
 | 
					    0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					    0x25, 0xFF,          //   Logical Maximum(255),
 | 
				
			||||||
 | 
					    0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					    0x19, 0x00,          //   Usage Minimum (0),
 | 
				
			||||||
 | 
					    0x29, 0xFF,          //   Usage Maximum (255),
 | 
				
			||||||
 | 
					    0x81, 0x00,          //   Input (Data, Array),
 | 
				
			||||||
 | 
					    0xc0                 // End Collection
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
 | 
				
			||||||
 | 
					// http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
 | 
				
			||||||
 | 
					// http://www.keil.com/forum/15671/
 | 
				
			||||||
 | 
					// http://www.microsoft.com/whdc/device/input/wheel.mspx
 | 
				
			||||||
 | 
					PROGMEM uchar mouse_hid_report[] = {
 | 
				
			||||||
 | 
					    /* from HID 1.11 spec example */
 | 
				
			||||||
 | 
					    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 (Buttons),
 | 
				
			||||||
 | 
					    0x19, 0x01,     //     Usage Minimum (01),
 | 
				
			||||||
 | 
					    0x29, 0x03,     //     Usage Maximun (03),
 | 
				
			||||||
 | 
					    0x15, 0x00,     //     Logical Minimum (0),
 | 
				
			||||||
 | 
					    0x25, 0x01,     //     Logical Maximum (1),
 | 
				
			||||||
 | 
					    0x95, 0x03,     //     Report Count (3),
 | 
				
			||||||
 | 
					    0x75, 0x01,     //     Report Size (1),
 | 
				
			||||||
 | 
					    0x81, 0x02,     //     Input (Data, Variable, Absolute), ;3 button bits
 | 
				
			||||||
 | 
					    0x95, 0x01,     //     Report Count (1),
 | 
				
			||||||
 | 
					    0x75, 0x05,     //     Report Size (5),
 | 
				
			||||||
 | 
					    0x81, 0x01,     //     Input (Constant), ;5 bit padding
 | 
				
			||||||
 | 
					    0x05, 0x01,     //     Usage Page (Generic Desktop),
 | 
				
			||||||
 | 
					    0x09, 0x30,     //     Usage (X),
 | 
				
			||||||
 | 
					    0x09, 0x31,     //     Usage (Y),
 | 
				
			||||||
 | 
					    0x15, 0x81,     //     Logical Minimum (-127),
 | 
				
			||||||
 | 
					    0x25, 0x7F,     //     Logical Maximum (127),
 | 
				
			||||||
 | 
					    0x75, 0x08,     //     Report Size (8),
 | 
				
			||||||
 | 
					    0x95, 0x02,     //     Report Count (2),
 | 
				
			||||||
 | 
					    0x81, 0x06,     //     Input (Data, Variable, Relative), ;2 position bytes (X & Y)
 | 
				
			||||||
 | 
					    0xC0,           //   End Collection,
 | 
				
			||||||
 | 
					    0xC0,           // End Collection
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
 | 
				
			||||||
 | 
					    0x09, 0x02,        // USAGE (Mouse)
 | 
				
			||||||
 | 
					    0xa1, 0x01,        // COLLECTION (Application)
 | 
				
			||||||
 | 
					    0x09, 0x02,        //   USAGE (Mouse)
 | 
				
			||||||
 | 
					    0xa1, 0x02,        //   COLLECTION (Logical)
 | 
				
			||||||
 | 
					    0x09, 0x01,        //     USAGE (Pointer)
 | 
				
			||||||
 | 
					    0xa1, 0x00,        //     COLLECTION (Physical)
 | 
				
			||||||
 | 
					                       // ------------------------------  Buttons
 | 
				
			||||||
 | 
					    0x05, 0x09,        //       USAGE_PAGE (Button)
 | 
				
			||||||
 | 
					    0x19, 0x01,        //       USAGE_MINIMUM (Button 1)
 | 
				
			||||||
 | 
					    0x29, 0x05,        //       USAGE_MAXIMUM (Button 5)
 | 
				
			||||||
 | 
					    0x15, 0x00,        //       LOGICAL_MINIMUM (0)
 | 
				
			||||||
 | 
					    0x25, 0x01,        //       LOGICAL_MAXIMUM (1)
 | 
				
			||||||
 | 
					    0x75, 0x01,        //       REPORT_SIZE (1)
 | 
				
			||||||
 | 
					    0x95, 0x05,        //       REPORT_COUNT (5)
 | 
				
			||||||
 | 
					    0x81, 0x02,        //       INPUT (Data,Var,Abs)
 | 
				
			||||||
 | 
					                       // ------------------------------  Padding
 | 
				
			||||||
 | 
					    0x75, 0x03,        //       REPORT_SIZE (3)
 | 
				
			||||||
 | 
					    0x95, 0x01,        //       REPORT_COUNT (1)
 | 
				
			||||||
 | 
					    0x81, 0x03,        //       INPUT (Cnst,Var,Abs)
 | 
				
			||||||
 | 
					                       // ------------------------------  X,Y position
 | 
				
			||||||
 | 
					    0x05, 0x01,        //       USAGE_PAGE (Generic Desktop)
 | 
				
			||||||
 | 
					    0x09, 0x30,        //       USAGE (X)
 | 
				
			||||||
 | 
					    0x09, 0x31,        //       USAGE (Y)
 | 
				
			||||||
 | 
					    0x15, 0x81,        //       LOGICAL_MINIMUM (-127)
 | 
				
			||||||
 | 
					    0x25, 0x7f,        //       LOGICAL_MAXIMUM (127)
 | 
				
			||||||
 | 
					    0x75, 0x08,        //       REPORT_SIZE (8)
 | 
				
			||||||
 | 
					    0x95, 0x02,        //       REPORT_COUNT (2)
 | 
				
			||||||
 | 
					    0x81, 0x06,        //       INPUT (Data,Var,Rel)
 | 
				
			||||||
 | 
					    0xa1, 0x02,        //       COLLECTION (Logical)
 | 
				
			||||||
 | 
					                       // ------------------------------  Vertical wheel res multiplier
 | 
				
			||||||
 | 
					    0x09, 0x48,        //         USAGE (Resolution Multiplier)
 | 
				
			||||||
 | 
					    0x15, 0x00,        //         LOGICAL_MINIMUM (0)
 | 
				
			||||||
 | 
					    0x25, 0x01,        //         LOGICAL_MAXIMUM (1)
 | 
				
			||||||
 | 
					    0x35, 0x01,        //         PHYSICAL_MINIMUM (1)
 | 
				
			||||||
 | 
					    0x45, 0x04,        //         PHYSICAL_MAXIMUM (4)
 | 
				
			||||||
 | 
					    0x75, 0x02,        //         REPORT_SIZE (2)
 | 
				
			||||||
 | 
					    0x95, 0x01,        //         REPORT_COUNT (1)
 | 
				
			||||||
 | 
					    0xa4,              //         PUSH
 | 
				
			||||||
 | 
					    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
 | 
				
			||||||
 | 
					                       // ------------------------------  Vertical wheel
 | 
				
			||||||
 | 
					    0x09, 0x38,        //         USAGE (Wheel)
 | 
				
			||||||
 | 
					    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
 | 
				
			||||||
 | 
					    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
 | 
				
			||||||
 | 
					    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
 | 
				
			||||||
 | 
					    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
 | 
				
			||||||
 | 
					    0x75, 0x08,        //         REPORT_SIZE (8)
 | 
				
			||||||
 | 
					    0x81, 0x06,        //         INPUT (Data,Var,Rel)
 | 
				
			||||||
 | 
					    0xc0,              //       END_COLLECTION
 | 
				
			||||||
 | 
					    0xa1, 0x02,        //       COLLECTION (Logical)
 | 
				
			||||||
 | 
					                       // ------------------------------  Horizontal wheel res multiplier
 | 
				
			||||||
 | 
					    0x09, 0x48,        //         USAGE (Resolution Multiplier)
 | 
				
			||||||
 | 
					    0xb4,              //         POP
 | 
				
			||||||
 | 
					    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
 | 
				
			||||||
 | 
					                       // ------------------------------  Padding for Feature report
 | 
				
			||||||
 | 
					    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
 | 
				
			||||||
 | 
					    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
 | 
				
			||||||
 | 
					    0x75, 0x04,        //         REPORT_SIZE (4)
 | 
				
			||||||
 | 
					    0xb1, 0x03,        //         FEATURE (Cnst,Var,Abs)
 | 
				
			||||||
 | 
					                       // ------------------------------  Horizontal wheel
 | 
				
			||||||
 | 
					    0x05, 0x0c,        //         USAGE_PAGE (Consumer Devices)
 | 
				
			||||||
 | 
					    0x0a, 0x38, 0x02,  //         USAGE (AC Pan)
 | 
				
			||||||
 | 
					    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
 | 
				
			||||||
 | 
					    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
 | 
				
			||||||
 | 
					    0x75, 0x08,        //         REPORT_SIZE (8)
 | 
				
			||||||
 | 
					    0x81, 0x06,        //         INPUT (Data,Var,Rel)
 | 
				
			||||||
 | 
					    0xc0,              //       END_COLLECTION
 | 
				
			||||||
 | 
					    0xc0,              //     END_COLLECTION
 | 
				
			||||||
 | 
					    0xc0,              //   END_COLLECTION
 | 
				
			||||||
 | 
					    0xc0               // END_COLLECTION
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Descriptor for compite device: Keyboard + Mouse */
 | 
				
			||||||
 | 
					#if USB_CFG_DESCR_PROPS_CONFIGURATION
 | 
				
			||||||
 | 
					PROGMEM char usbDescriptorConfiguration[] = {    /* USB configuration descriptor */
 | 
				
			||||||
 | 
					    9,          /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
 | 
				
			||||||
 | 
					    USBDESCR_CONFIG,    /* descriptor type */
 | 
				
			||||||
 | 
					    9 + (9 + 9 + 7) + (9 + 9 + 7), 0,
 | 
				
			||||||
 | 
					    //18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 9, 0,
 | 
				
			||||||
 | 
					                /* total length of data returned (including inlined descriptors) */
 | 
				
			||||||
 | 
					    2,          /* number of interfaces in this configuration */
 | 
				
			||||||
 | 
					    1,          /* index of this configuration */
 | 
				
			||||||
 | 
					    0,          /* configuration name string index */
 | 
				
			||||||
 | 
					#if USB_CFG_IS_SELF_POWERED
 | 
				
			||||||
 | 
					    (1 << 7) | USBATTR_SELFPOWER,       /* attributes */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    (1 << 7),                           /* attributes */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    USB_CFG_MAX_BUS_POWER/2,            /* max USB current in 2mA units */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Keyboard interface
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    /* Interface descriptor */
 | 
				
			||||||
 | 
					    9,          /* sizeof(usbDescrInterface): length of descriptor in bytes */
 | 
				
			||||||
 | 
					    USBDESCR_INTERFACE, /* descriptor type */
 | 
				
			||||||
 | 
					    0,          /* index of this interface */
 | 
				
			||||||
 | 
					    0,          /* alternate setting for this interface */
 | 
				
			||||||
 | 
					    USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */
 | 
				
			||||||
 | 
					    USB_CFG_INTERFACE_CLASS,
 | 
				
			||||||
 | 
					    USB_CFG_INTERFACE_SUBCLASS,
 | 
				
			||||||
 | 
					    USB_CFG_INTERFACE_PROTOCOL,
 | 
				
			||||||
 | 
					    0,          /* string index for interface */
 | 
				
			||||||
 | 
					    /* HID descriptor */
 | 
				
			||||||
 | 
					    9,          /* sizeof(usbDescrHID): length of descriptor in bytes */
 | 
				
			||||||
 | 
					    USBDESCR_HID,   /* descriptor type: HID */
 | 
				
			||||||
 | 
					    0x01, 0x01, /* BCD representation of HID version */
 | 
				
			||||||
 | 
					    0x00,       /* target country code */
 | 
				
			||||||
 | 
					    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */
 | 
				
			||||||
 | 
					    0x22,       /* descriptor type: report */
 | 
				
			||||||
 | 
					    sizeof(keyboard_hid_report), 0,  /* total length of report descriptor */
 | 
				
			||||||
 | 
					    /* Endpoint descriptor */
 | 
				
			||||||
 | 
					#if USB_CFG_HAVE_INTRIN_ENDPOINT    /* endpoint descriptor for endpoint 1 */
 | 
				
			||||||
 | 
					    7,          /* sizeof(usbDescrEndpoint) */
 | 
				
			||||||
 | 
					    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
 | 
				
			||||||
 | 
					    (char)0x81, /* IN endpoint number 1 */
 | 
				
			||||||
 | 
					    0x03,       /* attrib: Interrupt endpoint */
 | 
				
			||||||
 | 
					    8, 0,       /* maximum packet size */
 | 
				
			||||||
 | 
					    USB_CFG_INTR_POLL_INTERVAL, /* in ms */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Mouse interface
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    /* Interface descriptor */
 | 
				
			||||||
 | 
					    9,          /* sizeof(usbDescrInterface): length of descriptor in bytes */
 | 
				
			||||||
 | 
					    USBDESCR_INTERFACE, /* descriptor type */
 | 
				
			||||||
 | 
					    1,          /* index of this interface */
 | 
				
			||||||
 | 
					    0,          /* alternate setting for this interface */
 | 
				
			||||||
 | 
					    USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */
 | 
				
			||||||
 | 
					    0x03,       /* CLASS: HID */
 | 
				
			||||||
 | 
					    0,          /* SUBCLASS: none */
 | 
				
			||||||
 | 
					    0,          /* PROTOCOL: none */
 | 
				
			||||||
 | 
					    0,          /* string index for interface */
 | 
				
			||||||
 | 
					    /* HID descriptor */
 | 
				
			||||||
 | 
					    9,          /* sizeof(usbDescrHID): length of descriptor in bytes */
 | 
				
			||||||
 | 
					    USBDESCR_HID,   /* descriptor type: HID */
 | 
				
			||||||
 | 
					    0x01, 0x01, /* BCD representation of HID version */
 | 
				
			||||||
 | 
					    0x00,       /* target country code */
 | 
				
			||||||
 | 
					    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */
 | 
				
			||||||
 | 
					    0x22,       /* descriptor type: report */
 | 
				
			||||||
 | 
					    sizeof(mouse_hid_report), 0,  /* total length of report descriptor */
 | 
				
			||||||
 | 
					#if USB_CFG_HAVE_INTRIN_ENDPOINT3   /* endpoint descriptor for endpoint 3 */
 | 
				
			||||||
 | 
					    /* Endpoint descriptor */
 | 
				
			||||||
 | 
					    7,          /* sizeof(usbDescrEndpoint) */
 | 
				
			||||||
 | 
					    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
 | 
				
			||||||
 | 
					    (char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */
 | 
				
			||||||
 | 
					    0x03,       /* attrib: Interrupt endpoint */
 | 
				
			||||||
 | 
					    8, 0,       /* maximum packet size */
 | 
				
			||||||
 | 
					    USB_CFG_INTR_POLL_INTERVAL, /* in ms */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    usbMsgLen_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print("usbFunctionDescriptor: ");
 | 
				
			||||||
 | 
					    phex(rq->bmRequestType); print(" ");
 | 
				
			||||||
 | 
					    phex(rq->bRequest); print(" ");
 | 
				
			||||||
 | 
					    phex16(rq->wValue.word); print(" ");
 | 
				
			||||||
 | 
					    phex16(rq->wIndex.word); print(" ");
 | 
				
			||||||
 | 
					    phex16(rq->wLength.word); print("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (rq->wValue.bytes[1]) {
 | 
				
			||||||
 | 
					#if USB_CFG_DESCR_PROPS_CONFIGURATION
 | 
				
			||||||
 | 
					        case USBDESCR_CONFIG:
 | 
				
			||||||
 | 
					            usbMsgPtr = (unsigned char *)usbDescriptorConfiguration;
 | 
				
			||||||
 | 
					            len = sizeof(usbDescriptorConfiguration);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        case USBDESCR_HID:
 | 
				
			||||||
 | 
					            usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 18);
 | 
				
			||||||
 | 
					            len = 9;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case USBDESCR_HID_REPORT:
 | 
				
			||||||
 | 
					            /* interface index */
 | 
				
			||||||
 | 
					            switch (rq->wIndex.word) {
 | 
				
			||||||
 | 
					                case 0:
 | 
				
			||||||
 | 
					                    usbMsgPtr = keyboard_hid_report;
 | 
				
			||||||
 | 
					                    len = sizeof(keyboard_hid_report);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 1:
 | 
				
			||||||
 | 
					                    usbMsgPtr = mouse_hid_report;
 | 
				
			||||||
 | 
					                    len = sizeof(mouse_hid_report);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    print("desc len: "); phex(len); print("\n");
 | 
				
			||||||
 | 
					    return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								ps2_vusb/host_vusb.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								ps2_vusb/host_vusb.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					#ifndef HOST_VUSB_H
 | 
				
			||||||
 | 
					#define HOST_VUSB_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_vusb_keyboard_send(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										79
									
								
								ps2_vusb/keyboard.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								ps2_vusb/keyboard.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,79 @@
 | 
				
			||||||
 | 
					#include "usb_keycodes.h"
 | 
				
			||||||
 | 
					#include "host.h"
 | 
				
			||||||
 | 
					#include "keyboard.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static report_keyboard_t report0;
 | 
				
			||||||
 | 
					static report_keyboard_t report1;
 | 
				
			||||||
 | 
					static report_keyboard_t *report = &report0;
 | 
				
			||||||
 | 
					static report_keyboard_t *report_prev = &report1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void keyboard_send(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    host_keyboard_send(report);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool keyboard_has_key(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (int i = 0; i < REPORT_KEYS; i++) {
 | 
				
			||||||
 | 
					        if (report->keys[i])
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void keyboard_add_mod(uint8_t mod)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    report->mods |= mod;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void keyboard_add_key(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int8_t i = 0;
 | 
				
			||||||
 | 
					    int8_t empty = -1;
 | 
				
			||||||
 | 
					    for (; i < REPORT_KEYS; i++) {
 | 
				
			||||||
 | 
					        if (report_prev->keys[i] == code) {
 | 
				
			||||||
 | 
					            report->keys[i] = code;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
 | 
				
			||||||
 | 
					            empty = i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (i == REPORT_KEYS && empty != -1) {
 | 
				
			||||||
 | 
					        report->keys[empty] = code;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void keyboard_add_code(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (IS_MOD(code)) {
 | 
				
			||||||
 | 
					        keyboard_add_mod(code);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        keyboard_add_key(code);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void keyboard_swap_report(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    report_keyboard_t *tmp = report_prev;
 | 
				
			||||||
 | 
					    report_prev = report;
 | 
				
			||||||
 | 
					    report = tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void keyboard_clear_report(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    report->mods = 0;
 | 
				
			||||||
 | 
					    for (int8_t i = 0; i < REPORT_KEYS; i++) {
 | 
				
			||||||
 | 
					        report->keys[i] = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					report_keyboard_t *keyboard_report(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return report;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					report_keyboard_t *keyboard_report_prev(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return report_prev;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,21 @@
 | 
				
			||||||
#ifndef KEYBOARD_H
 | 
					#ifndef KEYBOARD_H
 | 
				
			||||||
#define KEYBOARD_H
 | 
					#define KEYBOARD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "stdbool.h"
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include "host.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REPORT_KEYS 6
 | 
					void keyboard_send(void);
 | 
				
			||||||
typedef struct{
 | 
					bool keyboard_has_key(void);
 | 
				
			||||||
    uint8_t mods;
 | 
					void keyboard_add_mod(uint8_t mod);
 | 
				
			||||||
    uint8_t rserved;    // not used
 | 
					void keyboard_add_key(uint8_t key);
 | 
				
			||||||
    uint8_t keys[REPORT_KEYS];
 | 
					void keyboard_add_code(uint8_t code);
 | 
				
			||||||
}report_t;
 | 
					void keyboard_swap_report(void);
 | 
				
			||||||
 | 
					void keyboard_clear_report(void);
 | 
				
			||||||
 | 
					report_keyboard_t *keyboard_report(void);
 | 
				
			||||||
//extern report_t *report;
 | 
					report_keyboard_t *keyboard_report_prev(void);
 | 
				
			||||||
//extern report_t *report_prev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
report_t *report_get(void);
 | 
					 | 
				
			||||||
bool report_has_key(void);
 | 
					 | 
				
			||||||
void report_send(void);
 | 
					 | 
				
			||||||
void report_add_mod(uint8_t mod);
 | 
					 | 
				
			||||||
void report_add_key(uint8_t key);
 | 
					 | 
				
			||||||
void report_add_code(uint8_t code);
 | 
					 | 
				
			||||||
void report_swap(void);
 | 
					 | 
				
			||||||
void report_clear(void);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,156 +0,0 @@
 | 
				
			||||||
#include "usbdrv.h"
 | 
					 | 
				
			||||||
#include "usb_keycodes.h"
 | 
					 | 
				
			||||||
#include "keyboard.h"
 | 
					 | 
				
			||||||
#include "print.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static report_t report0;
 | 
					 | 
				
			||||||
static report_t report1;
 | 
					 | 
				
			||||||
static report_t *report = &report0;
 | 
					 | 
				
			||||||
static report_t *report_prev = &report1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report_send(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (usbInterruptIsReady()){
 | 
					 | 
				
			||||||
        usbSetInterrupt((void *)report, sizeof(*report));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
report_t *report_get(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return report;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint8_t report_mods(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return report->mods;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint8_t *report_keys(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return report->keys;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool report_has_key(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    for (int i = 0; i < REPORT_KEYS; i++) {
 | 
					 | 
				
			||||||
        if (report->keys[i])
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report_add_mod(uint8_t mod)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    report->mods |= mod;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report_add_key(uint8_t code)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int8_t i = 0;
 | 
					 | 
				
			||||||
    int8_t empty = -1;
 | 
					 | 
				
			||||||
    for (; i < REPORT_KEYS; i++) {
 | 
					 | 
				
			||||||
        if (report_prev->keys[i] == code) {
 | 
					 | 
				
			||||||
            report->keys[i] = code;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
 | 
					 | 
				
			||||||
            empty = i;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (i == REPORT_KEYS && empty != -1) {
 | 
					 | 
				
			||||||
        report->keys[empty] = code;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report_add_code(uint8_t code)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (IS_MOD(code)) {
 | 
					 | 
				
			||||||
        report_add_mod(code);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        report_add_key(code);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report_swap(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    report_t *tmp = report_prev;
 | 
					 | 
				
			||||||
    report_prev = report;
 | 
					 | 
				
			||||||
    report = tmp;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report_clear(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    report->mods = 0;
 | 
					 | 
				
			||||||
    for (int8_t i = 0; i < REPORT_KEYS; i++) {
 | 
					 | 
				
			||||||
        report->keys[i] = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uchar    idleRate;   /* repeat rate for keyboards, never used for mice */
 | 
					 | 
				
			||||||
usbMsgLen_t usbFunctionSetup(uchar data[8])
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
usbRequest_t    *rq = (void *)data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    print("Setup: ");
 | 
					 | 
				
			||||||
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */
 | 
					 | 
				
			||||||
        print("CLASS: ");
 | 
					 | 
				
			||||||
        phex(rq->bRequest);
 | 
					 | 
				
			||||||
        if(rq->bRequest == USBRQ_HID_GET_REPORT){
 | 
					 | 
				
			||||||
            print("GET_REPORT");
 | 
					 | 
				
			||||||
            /* we only have one report type, so don't look at wValue */
 | 
					 | 
				
			||||||
            usbMsgPtr = (void *)report;
 | 
					 | 
				
			||||||
            return sizeof(*report);
 | 
					 | 
				
			||||||
        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
 | 
					 | 
				
			||||||
            print("GET_IDLE: ");
 | 
					 | 
				
			||||||
            phex(idleRate);
 | 
					 | 
				
			||||||
            usbMsgPtr = &idleRate;
 | 
					 | 
				
			||||||
            return 1;
 | 
					 | 
				
			||||||
        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
 | 
					 | 
				
			||||||
            idleRate = rq->wValue.bytes[1];
 | 
					 | 
				
			||||||
            print("SET_IDLE: ");
 | 
					 | 
				
			||||||
            phex(idleRate);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        print("\n");
 | 
					 | 
				
			||||||
    }else{
 | 
					 | 
				
			||||||
        print("VENDOR\n");
 | 
					 | 
				
			||||||
        /* no vendor specific requests implemented */
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;   /* default for not implemented requests: return no data back to host */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
 | 
					 | 
				
			||||||
    0x05, 0x01,          // Usage Page (Generic Desktop),
 | 
					 | 
				
			||||||
    0x09, 0x06,          // Usage (Keyboard),
 | 
					 | 
				
			||||||
    0xA1, 0x01,          // Collection (Application),
 | 
					 | 
				
			||||||
    0x75, 0x01,          //   Report Size (1),
 | 
					 | 
				
			||||||
    0x95, 0x08,          //   Report Count (8),
 | 
					 | 
				
			||||||
    0x05, 0x07,          //   Usage Page (Key Codes),
 | 
					 | 
				
			||||||
    0x19, 0xE0,          //   Usage Minimum (224),
 | 
					 | 
				
			||||||
    0x29, 0xE7,          //   Usage Maximum (231),
 | 
					 | 
				
			||||||
    0x15, 0x00,          //   Logical Minimum (0),
 | 
					 | 
				
			||||||
    0x25, 0x01,          //   Logical Maximum (1),
 | 
					 | 
				
			||||||
    0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
 | 
					 | 
				
			||||||
    0x95, 0x01,          //   Report Count (1),
 | 
					 | 
				
			||||||
    0x75, 0x08,          //   Report Size (8),
 | 
					 | 
				
			||||||
    0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
 | 
					 | 
				
			||||||
    0x95, 0x05,          //   Report Count (5),
 | 
					 | 
				
			||||||
    0x75, 0x01,          //   Report Size (1),
 | 
					 | 
				
			||||||
    0x05, 0x08,          //   Usage Page (LEDs),
 | 
					 | 
				
			||||||
    0x19, 0x01,          //   Usage Minimum (1),
 | 
					 | 
				
			||||||
    0x29, 0x05,          //   Usage Maximum (5),
 | 
					 | 
				
			||||||
    0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
 | 
					 | 
				
			||||||
    0x95, 0x01,          //   Report Count (1),
 | 
					 | 
				
			||||||
    0x75, 0x03,          //   Report Size (3),
 | 
					 | 
				
			||||||
    0x91, 0x03,          //   Output (Constant),                 ;LED report padding
 | 
					 | 
				
			||||||
    0x95, 0x06,          //   Report Count (6),
 | 
					 | 
				
			||||||
    0x75, 0x08,          //   Report Size (8),
 | 
					 | 
				
			||||||
    0x15, 0x00,          //   Logical Minimum (0),
 | 
					 | 
				
			||||||
    0x25, 0xFF,          //   Logical Maximum(255),
 | 
					 | 
				
			||||||
    0x05, 0x07,          //   Usage Page (Key Codes),
 | 
					 | 
				
			||||||
    0x19, 0x00,          //   Usage Minimum (0),
 | 
					 | 
				
			||||||
    0x29, 0xFF,          //   Usage Maximum (255),
 | 
					 | 
				
			||||||
    0x81, 0x00,          //   Input (Data, Array),
 | 
					 | 
				
			||||||
    0xc0                 // End Collection
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -98,23 +98,23 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			||||||
                    debug(" -> "); debug_hex(current_layer); debug("\n");
 | 
					                    debug(" -> "); debug_hex(current_layer); debug("\n");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if (report_has_key()) { // other keys is pressed
 | 
					                if (keyboard_has_key()) { // other keys is pressed
 | 
				
			||||||
                    uint8_t _fn_to_send = BIT_SUBT(fn_bits, sent_fn);
 | 
					                    uint8_t _fn_to_send = BIT_SUBT(fn_bits, sent_fn);
 | 
				
			||||||
                    if (_fn_to_send) {
 | 
					                    if (_fn_to_send) {
 | 
				
			||||||
                        debug("Fn case: 4(send Fn before other key pressed)\n");
 | 
					                        debug("Fn case: 4(send Fn before other key pressed)\n");
 | 
				
			||||||
                        // send only Fn key first
 | 
					                        // send only Fn key first
 | 
				
			||||||
                        report_swap();
 | 
					                        keyboard_swap_report();
 | 
				
			||||||
                        report_clear();
 | 
					                        keyboard_clear_report();
 | 
				
			||||||
                        report_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
 | 
					                        keyboard_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
 | 
				
			||||||
                        report_add_mod(last_mods);
 | 
					                        keyboard_add_mod(last_mods);
 | 
				
			||||||
                        report_send();
 | 
					                        keyboard_send();
 | 
				
			||||||
                        report_swap();
 | 
					                        keyboard_swap_report();
 | 
				
			||||||
                        sent_fn |= _fn_to_send;
 | 
					                        sent_fn |= _fn_to_send;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // add Fn keys to send
 | 
					            // add Fn keys to send
 | 
				
			||||||
            //report_add_code(keymap_fn_keycode(fn_bits&sent_fn));  // TODO: do all Fn keys
 | 
					            //keyboard_add_code(keymap_fn_keycode(fn_bits&sent_fn));  // TODO: do all Fn keys
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else { // Fn state is changed(edge)
 | 
					    } else { // Fn state is changed(edge)
 | 
				
			||||||
        uint8_t fn_changed = 0;
 | 
					        uint8_t fn_changed = 0;
 | 
				
			||||||
| 
						 | 
					@ -128,7 +128,7 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			||||||
        // pressed Fn
 | 
					        // pressed Fn
 | 
				
			||||||
        if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) {
 | 
					        if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) {
 | 
				
			||||||
        debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
 | 
					        debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
 | 
				
			||||||
            if (report_has_key()) {
 | 
					            if (keyboard_has_key()) {
 | 
				
			||||||
                debug("Fn case: 5(pressed Fn with other key)\n");
 | 
					                debug("Fn case: 5(pressed Fn with other key)\n");
 | 
				
			||||||
                sent_fn |= fn_changed;
 | 
					                sent_fn |= fn_changed;
 | 
				
			||||||
            } else if (fn_changed & sent_fn) { // pressed same Fn in a row
 | 
					            } else if (fn_changed & sent_fn) { // pressed same Fn in a row
 | 
				
			||||||
| 
						 | 
					@ -149,12 +149,12 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			||||||
                if (BIT_SUBT(fn_changed, sent_fn)) {  // layer not used && Fn not sent
 | 
					                if (BIT_SUBT(fn_changed, sent_fn)) {  // layer not used && Fn not sent
 | 
				
			||||||
                    debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
 | 
					                    debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
 | 
				
			||||||
                    // send only Fn key first
 | 
					                    // send only Fn key first
 | 
				
			||||||
                    report_swap();
 | 
					                    keyboard_swap_report();
 | 
				
			||||||
                    report_clear();
 | 
					                    keyboard_clear_report();
 | 
				
			||||||
                    report_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
 | 
					                    keyboard_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
 | 
				
			||||||
                    report_add_mod(last_mods);
 | 
					                    keyboard_add_mod(last_mods);
 | 
				
			||||||
                    report_send();
 | 
					                    keyboard_send();
 | 
				
			||||||
                    report_swap();
 | 
					                    keyboard_swap_report();
 | 
				
			||||||
                    sent_fn |= fn_changed;
 | 
					                    sent_fn |= fn_changed;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -165,13 +165,13 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        last_fn = fn_bits;
 | 
					        last_fn = fn_bits;
 | 
				
			||||||
        last_mods = report_get()->mods;
 | 
					        last_mods = keyboard_report()->mods;
 | 
				
			||||||
        last_timer = timer_read();
 | 
					        last_timer = timer_read();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // send Fn keys
 | 
					    // send Fn keys
 | 
				
			||||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
					    for (uint8_t i = 0; i < 8; i++) {
 | 
				
			||||||
        if ((sent_fn & fn_bits) & (1<<i)) {
 | 
					        if ((sent_fn & fn_bits) & (1<<i)) {
 | 
				
			||||||
            report_add_code(keymap_fn_keycode(1<<i));
 | 
					            keyboard_add_code(keymap_fn_keycode(1<<i));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										109
									
								
								ps2_vusb/main.c
									
										
									
									
									
								
							
							
						
						
									
										109
									
								
								ps2_vusb/main.c
									
										
									
									
									
								
							| 
						 | 
					@ -7,68 +7,50 @@
 | 
				
			||||||
 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
 | 
					 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
 | 
				
			||||||
 * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $
 | 
					 * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
This example should run on most AVRs with only little changes. No special
 | 
					 | 
				
			||||||
hardware resources except INT0 are used. You may have to change usbconfig.h for
 | 
					 | 
				
			||||||
different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
 | 
					 | 
				
			||||||
at least be connected to INT0 as well.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't
 | 
					 | 
				
			||||||
publish any hardware using these IDs! This is for demonstration only!
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <avr/io.h>
 | 
					#include <avr/io.h>
 | 
				
			||||||
#include <avr/wdt.h>
 | 
					#include <avr/wdt.h>
 | 
				
			||||||
#include <avr/interrupt.h>  /* for sei() */
 | 
					#include <avr/interrupt.h>  /* for sei() */
 | 
				
			||||||
#include <util/delay.h>     /* for _delay_ms() */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <avr/pgmspace.h>   /* required by usbdrv.h */
 | 
					#include <avr/pgmspace.h>   /* required by usbdrv.h */
 | 
				
			||||||
 | 
					#include <util/delay.h>     /* for _delay_ms() */
 | 
				
			||||||
#include "usbdrv.h"
 | 
					#include "usbdrv.h"
 | 
				
			||||||
#include "usart_print.h"        /* This is also an example for using debug macros */
 | 
					#include "usart_print.h"        /* This is also an example for using debug macros */
 | 
				
			||||||
#include "ps2.h"
 | 
					 | 
				
			||||||
#include "usb_keycodes.h"
 | 
					#include "usb_keycodes.h"
 | 
				
			||||||
#include "matrix_skel.h"
 | 
					#include "matrix_skel.h"
 | 
				
			||||||
#include "keymap_skel.h"
 | 
					#include "keymap_skel.h"
 | 
				
			||||||
 | 
					#include "mousekey.h"
 | 
				
			||||||
 | 
					#include "keyboard.h"
 | 
				
			||||||
#include "layer.h"
 | 
					#include "layer.h"
 | 
				
			||||||
#include "print.h"
 | 
					#include "print.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
#include "sendchar.h"
 | 
					#include "sendchar.h"
 | 
				
			||||||
#include "keyboard.h"
 | 
					#include "host.h"
 | 
				
			||||||
 | 
					#include "host_vusb.h"
 | 
				
			||||||
#include "timer.h"
 | 
					#include "timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ------------------------------------------------------------------------- */
 | 
					 | 
				
			||||||
/* ----------------------------- USB interface ----------------------------- */
 | 
					 | 
				
			||||||
/* ------------------------------------------------------------------------- */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(void)
 | 
					int main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
uchar   i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
print_enable = true;
 | 
					 | 
				
			||||||
debug_enable = true;
 | 
					 | 
				
			||||||
timer_init();
 | 
					 | 
				
			||||||
matrix_init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    wdt_enable(WDTO_1S);
 | 
					    wdt_enable(WDTO_1S);
 | 
				
			||||||
    /* Even if you don't use the watchdog, turn it off here. On newer devices,
 | 
					    /* Even if you don't use the watchdog, turn it off here. On newer devices,
 | 
				
			||||||
     * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
 | 
					     * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* RESET status: all port bits are inputs without pull-up.
 | 
					    /* 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
 | 
					     * That's the way we need D+ and D-. Therefore we don't need any
 | 
				
			||||||
     * additional hardware initialization.
 | 
					     * additional hardware initialization.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    odDebugInit();
 | 
					    odDebugInit();
 | 
				
			||||||
    DBG1(0x00, 0, 0);       /* debug output: main starts */
 | 
					 | 
				
			||||||
    usbInit();
 | 
					    usbInit();
 | 
				
			||||||
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
 | 
					
 | 
				
			||||||
    i = 0;
 | 
					    print_enable = true;
 | 
				
			||||||
 | 
					    //debug_enable = true;
 | 
				
			||||||
 | 
					    timer_init();
 | 
				
			||||||
 | 
					    matrix_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* enforce re-enumeration, do this while interrupts are disabled! */
 | 
				
			||||||
 | 
					    usbDeviceDisconnect();
 | 
				
			||||||
 | 
					    uint8_t i = 0;
 | 
				
			||||||
    while(--i){             /* fake USB disconnect for > 250 ms */
 | 
					    while(--i){             /* fake USB disconnect for > 250 ms */
 | 
				
			||||||
        wdt_reset();
 | 
					        wdt_reset();
 | 
				
			||||||
        _delay_ms(1);
 | 
					        _delay_ms(1);
 | 
				
			||||||
| 
						 | 
					@ -78,49 +60,44 @@ matrix_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t fn_bits = 0;
 | 
					    uint8_t fn_bits = 0;
 | 
				
			||||||
    while (1) {                /* main event loop */
 | 
					    while (1) {                /* main event loop */
 | 
				
			||||||
        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
 | 
					 | 
				
			||||||
        wdt_reset();
 | 
					        wdt_reset();
 | 
				
			||||||
        usbPoll();
 | 
					        usbPoll();
 | 
				
			||||||
 | 
					        host_vusb_keyboard_send();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
static uint8_t code = 0;
 | 
					 | 
				
			||||||
code = ps2_host_recv();
 | 
					 | 
				
			||||||
if (code) {
 | 
					 | 
				
			||||||
    odDebug(0x05, &code, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
        matrix_scan();
 | 
					        matrix_scan();
 | 
				
			||||||
        if (matrix_is_modified()) {
 | 
					        fn_bits = 0;
 | 
				
			||||||
            //matrix_print();   // too heavy on USART
 | 
					        keyboard_swap_report();
 | 
				
			||||||
            fn_bits = 0;
 | 
					        keyboard_clear_report();
 | 
				
			||||||
            report_swap();
 | 
					        mousekey_clear_report();
 | 
				
			||||||
            report_clear();
 | 
					        for (int row = 0; row < matrix_rows(); row++) {
 | 
				
			||||||
            for (int row = 0; row < matrix_rows(); row++) {
 | 
					            for (int col = 0; col < matrix_cols(); col++) {
 | 
				
			||||||
                for (int col = 0; col < matrix_cols(); col++) {
 | 
					                if (!matrix_is_on(row, col)) continue;
 | 
				
			||||||
                    if (!matrix_is_on(row, col)) continue;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    uint8_t code = layer_get_keycode(row, col);
 | 
					                uint8_t code = layer_get_keycode(row, col);
 | 
				
			||||||
                    if (code == KB_NO) {
 | 
					                if (code == KB_NO) {
 | 
				
			||||||
                        // do nothing
 | 
					                    // do nothing
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
                    else if (IS_MOD(code)) {
 | 
					                else if (IS_MOD(code)) {
 | 
				
			||||||
                        report_add_mod(MOD_BIT(code));
 | 
					                    keyboard_add_mod(MOD_BIT(code));
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
                    else if (IS_KEY(code)) {
 | 
					                else if (IS_KEY(code)) {
 | 
				
			||||||
                        report_add_key(code);
 | 
					                    keyboard_add_key(code);
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
                    else if (IS_FN(code)) {
 | 
					                else if (IS_FN(code)) {
 | 
				
			||||||
                        fn_bits |= FN_BIT(code);
 | 
					                    fn_bits |= FN_BIT(code);
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
                    else {
 | 
					                else if (IS_MOUSEKEY(code)) {
 | 
				
			||||||
                        debug("ignore keycode: "); debug_hex(code); debug("\n");
 | 
					                    mousekey_decode(code);
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    debug("ignore keycode: "); debug_hex(code); debug("\n");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        layer_switching(fn_bits);
 | 
					        layer_switching(fn_bits);
 | 
				
			||||||
        if (matrix_is_modified()) {
 | 
					        if (matrix_is_modified()) {
 | 
				
			||||||
            report_send();
 | 
					            keyboard_send();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        mousekey_send();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,8 +190,10 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t code;
 | 
					    uint8_t code;
 | 
				
			||||||
    while ((code = ps2_host_recv())) {
 | 
					    code = ps2_host_recv();
 | 
				
			||||||
//debug_hex(code); debug(" ");
 | 
					    if (code == 0x00) return 0;
 | 
				
			||||||
 | 
					    //while ((code = ps2_host_recv())) {
 | 
				
			||||||
 | 
					//phex(code); print(" ");
 | 
				
			||||||
        switch (state) {
 | 
					        switch (state) {
 | 
				
			||||||
            case INIT:
 | 
					            case INIT:
 | 
				
			||||||
                switch (code) {
 | 
					                switch (code) {
 | 
				
			||||||
| 
						 | 
					@ -348,7 +350,8 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                state = INIT;
 | 
					                state = INIT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    //}
 | 
				
			||||||
 | 
					//print("|");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // handle LED indicators
 | 
					    // handle LED indicators
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -463,6 +466,7 @@ static void matrix_make(uint8_t code)
 | 
				
			||||||
    if (!matrix_is_on(ROW(code), COL(code))) {
 | 
					    if (!matrix_is_on(ROW(code), COL(code))) {
 | 
				
			||||||
        matrix[ROW(code)] |= 1<<COL(code);
 | 
					        matrix[ROW(code)] |= 1<<COL(code);
 | 
				
			||||||
        is_modified = true;
 | 
					        is_modified = true;
 | 
				
			||||||
 | 
					        //print("matrix_make: "); phex(code); print("\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -472,6 +476,7 @@ static void matrix_break(uint8_t code)
 | 
				
			||||||
    if (matrix_is_on(ROW(code), COL(code))) {
 | 
					    if (matrix_is_on(ROW(code), COL(code))) {
 | 
				
			||||||
        matrix[ROW(code)] &= ~(1<<COL(code));
 | 
					        matrix[ROW(code)] &= ~(1<<COL(code));
 | 
				
			||||||
        is_modified = true;
 | 
					        is_modified = true;
 | 
				
			||||||
 | 
					        //print("matrix_break: "); phex(code); print("\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										102
									
								
								ps2_vusb/mousekey.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								ps2_vusb/mousekey.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,102 @@
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <util/delay.h>
 | 
				
			||||||
 | 
					#include "usb_keycodes.h"
 | 
				
			||||||
 | 
					#include "host.h"
 | 
				
			||||||
 | 
					#include "timer.h"
 | 
				
			||||||
 | 
					#include "print.h"
 | 
				
			||||||
 | 
					#include "mousekey.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static report_mouse_t report;
 | 
				
			||||||
 | 
					static report_mouse_t report_prev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t mousekey_repeat =  0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * TODO: fix acceleration algorithm
 | 
				
			||||||
 | 
					 * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef MOUSEKEY_DELAY_TIME
 | 
				
			||||||
 | 
					#   define MOUSEKEY_DELAY_TIME 255
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint8_t move_unit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t unit = (10 + (mousekey_repeat));
 | 
				
			||||||
 | 
					    return unit > 127 ? 127 : unit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mousekey_decode(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if      (code == KB_MS_UP)      report.y -= move_unit();
 | 
				
			||||||
 | 
					    else if (code == KB_MS_DOWN)    report.y += move_unit();
 | 
				
			||||||
 | 
					    else if (code == KB_MS_LEFT)    report.x -= move_unit();
 | 
				
			||||||
 | 
					    else if (code == KB_MS_RIGHT)   report.x += move_unit();
 | 
				
			||||||
 | 
					    else if (code == KB_MS_BTN1)    report.buttons |= MOUSE_BTN1;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_BTN2)    report.buttons |= MOUSE_BTN2;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_BTN3)    report.buttons |= MOUSE_BTN3;
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    else if (code == KB_MS_BTN4)    report.buttons |= MOUSE_BTN4;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_BTN5)    report.buttons |= MOUSE_BTN5;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_WH_UP)   report.v += 1;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_WH_DOWN) report.v -= 1;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_WH_LEFT) report.h -= 1;
 | 
				
			||||||
 | 
					    else if (code == KB_MS_WH_RIGHT)report.h += 1;
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool mousekey_changed(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (report.buttons != report_prev.buttons ||
 | 
				
			||||||
 | 
					            report.x != report_prev.x ||
 | 
				
			||||||
 | 
					            report.y != report_prev.y ||
 | 
				
			||||||
 | 
					            report.x || report.y);
 | 
				
			||||||
 | 
					    //return (report.buttons != report_prev.buttons || report.x || report.y);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mousekey_send(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static uint16_t last_timer = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!mousekey_changed()) {
 | 
				
			||||||
 | 
					        mousekey_repeat = 0;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // send immediately when buttun state is changed
 | 
				
			||||||
 | 
					    if (report.buttons == report_prev.buttons) {
 | 
				
			||||||
 | 
					        // TODO: delay parameter setting
 | 
				
			||||||
 | 
					        if ((timer_elapsed(last_timer) < (mousekey_repeat == 1 ? 20 : 5))) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (report.x && report.y) {
 | 
				
			||||||
 | 
					        report.x *= 0.7;
 | 
				
			||||||
 | 
					        report.y *= 0.7;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    print("mousekey_repeat: "); phex(mousekey_repeat); print("\n");
 | 
				
			||||||
 | 
					    print("timer: "); phex16(timer_read()); print("\n");
 | 
				
			||||||
 | 
					    print("last_timer: "); phex16(last_timer); print("\n");
 | 
				
			||||||
 | 
					    print("mousekey: "); phex(report.buttons); print(" "); phex(report.x); print(" "); phex(report.y); print("\n");
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    host_mouse_send(&report);
 | 
				
			||||||
 | 
					    report_prev.buttons = report.buttons;
 | 
				
			||||||
 | 
					    report_prev.x = report.x;
 | 
				
			||||||
 | 
					    report_prev.y = report.y;
 | 
				
			||||||
 | 
					    if (mousekey_repeat != 0xFF) mousekey_repeat++;
 | 
				
			||||||
 | 
					    last_timer = timer_read();
 | 
				
			||||||
 | 
					    mousekey_clear_report();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mousekey_clear_report(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    report.buttons = 0;
 | 
				
			||||||
 | 
					    report.x = 0;
 | 
				
			||||||
 | 
					    report.y = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								ps2_vusb/mousekey.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								ps2_vusb/mousekey.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					#ifndef MOUSEKEY_H
 | 
				
			||||||
 | 
					#define  MOUSEKEY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include "host.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mousekey_decode(uint8_t code);
 | 
				
			||||||
 | 
					bool mousekey_changed(void);
 | 
				
			||||||
 | 
					void mousekey_send(void);
 | 
				
			||||||
 | 
					void mousekey_clear_report(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -77,7 +77,7 @@ section at the end of this file).
 | 
				
			||||||
 * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
 | 
					 * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
 | 
				
			||||||
 * number).
 | 
					 * number).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT3   0
 | 
					#define USB_CFG_HAVE_INTRIN_ENDPOINT3   1
 | 
				
			||||||
/* Define this to 1 if you want to compile a version with three endpoints: The
 | 
					/* Define this to 1 if you want to compile a version with three endpoints: The
 | 
				
			||||||
 * default control endpoint 0, an interrupt-in endpoint 3 (or the number
 | 
					 * default control endpoint 0, an interrupt-in endpoint 3 (or the number
 | 
				
			||||||
 * configured below) and a catch-all default interrupt-in endpoint as above.
 | 
					 * configured below) and a catch-all default interrupt-in endpoint as above.
 | 
				
			||||||
| 
						 | 
					@ -277,7 +277,7 @@ section at the end of this file).
 | 
				
			||||||
 * HID class is 3, no subclass and protocol required (but may be useful!)
 | 
					 * HID class is 3, no subclass and protocol required (but may be useful!)
 | 
				
			||||||
 * CDC class is 2, use subclass 2 and protocol 1 for ACM
 | 
					 * CDC class is 2, use subclass 2 and protocol 1 for ACM
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    63
 | 
					#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    0
 | 
				
			||||||
/* Define this to the length of the HID report descriptor, if you implement
 | 
					/* Define this to the length of the HID report descriptor, if you implement
 | 
				
			||||||
 * an HID device. Otherwise don't define it or define it to 0.
 | 
					 * an HID device. Otherwise don't define it or define it to 0.
 | 
				
			||||||
 * If you use this define, you must add a PROGMEM character array named
 | 
					 * If you use this define, you must add a PROGMEM character array named
 | 
				
			||||||
| 
						 | 
					@ -343,14 +343,17 @@ section at the end of this file).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_DEVICE                  0
 | 
					#define USB_CFG_DESCR_PROPS_DEVICE                  0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_CONFIGURATION           0
 | 
					#define USB_CFG_DESCR_PROPS_CONFIGURATION           USB_PROP_IS_DYNAMIC
 | 
				
			||||||
 | 
					//#define USB_CFG_DESCR_PROPS_CONFIGURATION           0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_STRINGS                 0
 | 
					#define USB_CFG_DESCR_PROPS_STRINGS                 0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_STRING_0                0
 | 
					#define USB_CFG_DESCR_PROPS_STRING_0                0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_STRING_VENDOR           0
 | 
					#define USB_CFG_DESCR_PROPS_STRING_VENDOR           0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT          0
 | 
					#define USB_CFG_DESCR_PROPS_STRING_PRODUCT          0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    0
 | 
					#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    0
 | 
				
			||||||
 | 
					//#define USB_CFG_DESCR_PROPS_HID                     USB_PROP_IS_DYNAMIC
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_HID                     0
 | 
					#define USB_CFG_DESCR_PROPS_HID                     0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_HID_REPORT              0
 | 
					#define USB_CFG_DESCR_PROPS_HID_REPORT              USB_PROP_IS_DYNAMIC
 | 
				
			||||||
 | 
					//#define USB_CFG_DESCR_PROPS_HID_REPORT              0
 | 
				
			||||||
#define USB_CFG_DESCR_PROPS_UNKNOWN                 0
 | 
					#define USB_CFG_DESCR_PROPS_UNKNOWN                 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------------------- Optional MCU Description ------------------------ */
 | 
					/* ----------------------- Optional MCU Description ------------------------ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue