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
 | 
			
		||||
#     To put object files in current directory, use a dot (.), do NOT make
 | 
			
		||||
#     this an empty or blank macro!
 | 
			
		||||
OBJDIR = .
 | 
			
		||||
OBJDIR = obj
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Optimization level, can be [0, 1, 2, 3, s]. 
 | 
			
		||||
| 
						 | 
				
			
			@ -347,7 +347,7 @@ AR = avr-ar rcs
 | 
			
		|||
NM = avr-nm
 | 
			
		||||
AVRDUDE = avrdude
 | 
			
		||||
REMOVE = rm -f
 | 
			
		||||
REMOVEDIR = rm -rf
 | 
			
		||||
REMOVEDIR = rmdir
 | 
			
		||||
COPY = cp
 | 
			
		||||
WINSHELL = cmd
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -601,7 +601,8 @@ clean_list :
 | 
			
		|||
	$(REMOVE) $(LST)
 | 
			
		||||
	$(REMOVE) $(OBJ:.o=.s)
 | 
			
		||||
	$(REMOVE) $(OBJ:.o=.i)
 | 
			
		||||
	$(REMOVEDIR) .dep
 | 
			
		||||
	$(REMOVE) -r .dep
 | 
			
		||||
	$(REMOVEDIR) $(OBJDIR)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Create object files directory
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,11 +9,13 @@ TARGET_DIR = .
 | 
			
		|||
 | 
			
		||||
# keyboard dependent files
 | 
			
		||||
TARGET_SRC =	main.c \
 | 
			
		||||
		keyboard_vusb.c \
 | 
			
		||||
		keyboard.c \
 | 
			
		||||
		mousekey.c \
 | 
			
		||||
		layer.c \
 | 
			
		||||
		keymap.c \
 | 
			
		||||
		matrix.c \
 | 
			
		||||
		ps2.c \
 | 
			
		||||
		host_vusb.c \
 | 
			
		||||
		print.c \
 | 
			
		||||
		util.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
 | 
			
		||||
#define KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#include "stdbool.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include "host.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define REPORT_KEYS 6
 | 
			
		||||
typedef struct{
 | 
			
		||||
    uint8_t mods;
 | 
			
		||||
    uint8_t rserved;    // not used
 | 
			
		||||
    uint8_t keys[REPORT_KEYS];
 | 
			
		||||
}report_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//extern report_t *report;
 | 
			
		||||
//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);
 | 
			
		||||
void keyboard_send(void);
 | 
			
		||||
bool keyboard_has_key(void);
 | 
			
		||||
void keyboard_add_mod(uint8_t mod);
 | 
			
		||||
void keyboard_add_key(uint8_t key);
 | 
			
		||||
void keyboard_add_code(uint8_t code);
 | 
			
		||||
void keyboard_swap_report(void);
 | 
			
		||||
void keyboard_clear_report(void);
 | 
			
		||||
report_keyboard_t *keyboard_report(void);
 | 
			
		||||
report_keyboard_t *keyboard_report_prev(void);
 | 
			
		||||
 | 
			
		||||
#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");
 | 
			
		||||
                }
 | 
			
		||||
            } 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);
 | 
			
		||||
                    if (_fn_to_send) {
 | 
			
		||||
                        debug("Fn case: 4(send Fn before other key pressed)\n");
 | 
			
		||||
                        // send only Fn key first
 | 
			
		||||
                        report_swap();
 | 
			
		||||
                        report_clear();
 | 
			
		||||
                        report_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
 | 
			
		||||
                        report_add_mod(last_mods);
 | 
			
		||||
                        report_send();
 | 
			
		||||
                        report_swap();
 | 
			
		||||
                        keyboard_swap_report();
 | 
			
		||||
                        keyboard_clear_report();
 | 
			
		||||
                        keyboard_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
 | 
			
		||||
                        keyboard_add_mod(last_mods);
 | 
			
		||||
                        keyboard_send();
 | 
			
		||||
                        keyboard_swap_report();
 | 
			
		||||
                        sent_fn |= _fn_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)
 | 
			
		||||
        uint8_t fn_changed = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ void layer_switching(uint8_t fn_bits)
 | 
			
		|||
        // pressed Fn
 | 
			
		||||
        if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) {
 | 
			
		||||
        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");
 | 
			
		||||
                sent_fn |= fn_changed;
 | 
			
		||||
            } 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
 | 
			
		||||
                    debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
 | 
			
		||||
                    // send only Fn key first
 | 
			
		||||
                    report_swap();
 | 
			
		||||
                    report_clear();
 | 
			
		||||
                    report_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
 | 
			
		||||
                    report_add_mod(last_mods);
 | 
			
		||||
                    report_send();
 | 
			
		||||
                    report_swap();
 | 
			
		||||
                    keyboard_swap_report();
 | 
			
		||||
                    keyboard_clear_report();
 | 
			
		||||
                    keyboard_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
 | 
			
		||||
                    keyboard_add_mod(last_mods);
 | 
			
		||||
                    keyboard_send();
 | 
			
		||||
                    keyboard_swap_report();
 | 
			
		||||
                    sent_fn |= fn_changed;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -165,13 +165,13 @@ void layer_switching(uint8_t fn_bits)
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        last_fn = fn_bits;
 | 
			
		||||
        last_mods = report_get()->mods;
 | 
			
		||||
        last_mods = keyboard_report()->mods;
 | 
			
		||||
        last_timer = timer_read();
 | 
			
		||||
    }
 | 
			
		||||
    // send Fn keys
 | 
			
		||||
    for (uint8_t i = 0; i < 8; 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)
 | 
			
		||||
 * 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 <avr/io.h>
 | 
			
		||||
#include <avr/wdt.h>
 | 
			
		||||
#include <avr/interrupt.h>  /* for sei() */
 | 
			
		||||
#include <util/delay.h>     /* for _delay_ms() */
 | 
			
		||||
 | 
			
		||||
#include <avr/pgmspace.h>   /* required by usbdrv.h */
 | 
			
		||||
#include <util/delay.h>     /* for _delay_ms() */
 | 
			
		||||
#include "usbdrv.h"
 | 
			
		||||
#include "usart_print.h"        /* This is also an example for using debug macros */
 | 
			
		||||
#include "ps2.h"
 | 
			
		||||
#include "usb_keycodes.h"
 | 
			
		||||
#include "matrix_skel.h"
 | 
			
		||||
#include "keymap_skel.h"
 | 
			
		||||
#include "mousekey.h"
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
#include "layer.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include "sendchar.h"
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
#include "host.h"
 | 
			
		||||
#include "host_vusb.h"
 | 
			
		||||
#include "timer.h"
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
/* ----------------------------- USB interface ----------------------------- */
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
uchar   i;
 | 
			
		||||
 | 
			
		||||
print_enable = true;
 | 
			
		||||
debug_enable = true;
 | 
			
		||||
timer_init();
 | 
			
		||||
matrix_init();
 | 
			
		||||
 | 
			
		||||
    wdt_enable(WDTO_1S);
 | 
			
		||||
    /* 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!
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* RESET status: all port bits are inputs without pull-up.
 | 
			
		||||
     * That's the way we need D+ and D-. Therefore we don't need any
 | 
			
		||||
     * additional hardware initialization.
 | 
			
		||||
     */
 | 
			
		||||
    odDebugInit();
 | 
			
		||||
    DBG1(0x00, 0, 0);       /* debug output: main starts */
 | 
			
		||||
    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 */
 | 
			
		||||
        wdt_reset();
 | 
			
		||||
        _delay_ms(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,49 +60,44 @@ matrix_init();
 | 
			
		|||
 | 
			
		||||
    uint8_t fn_bits = 0;
 | 
			
		||||
    while (1) {                /* main event loop */
 | 
			
		||||
        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
 | 
			
		||||
        wdt_reset();
 | 
			
		||||
        usbPoll();
 | 
			
		||||
        host_vusb_keyboard_send();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
static uint8_t code = 0;
 | 
			
		||||
code = ps2_host_recv();
 | 
			
		||||
if (code) {
 | 
			
		||||
    odDebug(0x05, &code, 1);
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
        matrix_scan();
 | 
			
		||||
        if (matrix_is_modified()) {
 | 
			
		||||
            //matrix_print();   // too heavy on USART
 | 
			
		||||
            fn_bits = 0;
 | 
			
		||||
            report_swap();
 | 
			
		||||
            report_clear();
 | 
			
		||||
            for (int row = 0; row < matrix_rows(); row++) {
 | 
			
		||||
                for (int col = 0; col < matrix_cols(); col++) {
 | 
			
		||||
                    if (!matrix_is_on(row, col)) continue;
 | 
			
		||||
        fn_bits = 0;
 | 
			
		||||
        keyboard_swap_report();
 | 
			
		||||
        keyboard_clear_report();
 | 
			
		||||
        mousekey_clear_report();
 | 
			
		||||
        for (int row = 0; row < matrix_rows(); row++) {
 | 
			
		||||
            for (int col = 0; col < matrix_cols(); col++) {
 | 
			
		||||
                if (!matrix_is_on(row, col)) continue;
 | 
			
		||||
 | 
			
		||||
                    uint8_t code = layer_get_keycode(row, col);
 | 
			
		||||
                    if (code == KB_NO) {
 | 
			
		||||
                        // do nothing
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (IS_MOD(code)) {
 | 
			
		||||
                        report_add_mod(MOD_BIT(code));
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (IS_KEY(code)) {
 | 
			
		||||
                        report_add_key(code);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (IS_FN(code)) {
 | 
			
		||||
                        fn_bits |= FN_BIT(code);
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        debug("ignore keycode: "); debug_hex(code); debug("\n");
 | 
			
		||||
                    }
 | 
			
		||||
                uint8_t code = layer_get_keycode(row, col);
 | 
			
		||||
                if (code == KB_NO) {
 | 
			
		||||
                    // do nothing
 | 
			
		||||
                }
 | 
			
		||||
                else if (IS_MOD(code)) {
 | 
			
		||||
                    keyboard_add_mod(MOD_BIT(code));
 | 
			
		||||
                }
 | 
			
		||||
                else if (IS_KEY(code)) {
 | 
			
		||||
                    keyboard_add_key(code);
 | 
			
		||||
                }
 | 
			
		||||
                else if (IS_FN(code)) {
 | 
			
		||||
                    fn_bits |= FN_BIT(code);
 | 
			
		||||
                }
 | 
			
		||||
                else if (IS_MOUSEKEY(code)) {
 | 
			
		||||
                    mousekey_decode(code);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    debug("ignore keycode: "); debug_hex(code); debug("\n");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        layer_switching(fn_bits);
 | 
			
		||||
        if (matrix_is_modified()) {
 | 
			
		||||
            report_send();
 | 
			
		||||
            keyboard_send();
 | 
			
		||||
        }
 | 
			
		||||
        mousekey_send();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,8 +190,10 @@ uint8_t matrix_scan(void)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t code;
 | 
			
		||||
    while ((code = ps2_host_recv())) {
 | 
			
		||||
//debug_hex(code); debug(" ");
 | 
			
		||||
    code = ps2_host_recv();
 | 
			
		||||
    if (code == 0x00) return 0;
 | 
			
		||||
    //while ((code = ps2_host_recv())) {
 | 
			
		||||
//phex(code); print(" ");
 | 
			
		||||
        switch (state) {
 | 
			
		||||
            case INIT:
 | 
			
		||||
                switch (code) {
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +350,8 @@ uint8_t matrix_scan(void)
 | 
			
		|||
            default:
 | 
			
		||||
                state = INIT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //}
 | 
			
		||||
//print("|");
 | 
			
		||||
 | 
			
		||||
    // handle LED indicators
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -463,6 +466,7 @@ static void matrix_make(uint8_t code)
 | 
			
		|||
    if (!matrix_is_on(ROW(code), COL(code))) {
 | 
			
		||||
        matrix[ROW(code)] |= 1<<COL(code);
 | 
			
		||||
        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))) {
 | 
			
		||||
        matrix[ROW(code)] &= ~(1<<COL(code));
 | 
			
		||||
        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
 | 
			
		||||
 * 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
 | 
			
		||||
 * default control endpoint 0, an interrupt-in endpoint 3 (or the number
 | 
			
		||||
 * 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!)
 | 
			
		||||
 * 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
 | 
			
		||||
 * 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
 | 
			
		||||
| 
						 | 
				
			
			@ -343,14 +343,17 @@ section at the end of this file).
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
#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_STRING_0                0
 | 
			
		||||
#define USB_CFG_DESCR_PROPS_STRING_VENDOR           0
 | 
			
		||||
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT          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_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
 | 
			
		||||
 | 
			
		||||
/* ----------------------- Optional MCU Description ------------------------ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue