~ruther/qmk_firmware

d3b1af9572e123c939fc355474bf12402c86d292 — tmk 15 years ago e7c6839
add mouse function.
M .gitignore => .gitignore +1 -0
@@ 7,3 7,4 @@
*.lst
*.map
*.sym
tags

M Makefile => Makefile +6 -5
@@ 46,13 46,14 @@ TARGET = mykey

# List C source files here. (C dependencies are automatically generated.)
SRC =	$(TARGET).c \
	keymap.c \
	matrix.c \
	usb_device.c \
	usb.c \
	usb_keyboard.c \
	usb_mouse.c \
	usb_debug.c \
	print.c \
	jump_bootloader.c
	keymap.c \
	matrix.c \
	jump_bootloader.c \
	print.c


# MCU name, you MUST set this to match the board you are using

M keymap.h => keymap.h +1 -1
@@ 2,7 2,7 @@
#define KEYMAP_H 1

#include <stdint.h>
#include "usbkeycodes.h"
#include "usb_keycodes.h"

int get_layer(void);
uint8_t get_keycode(int layer, int row, int col);

M matrix.h => matrix.h +5 -0
@@ 1,3 1,6 @@
#ifndef MATRIX_H
#define  MATRIX_H 1

#include <stdbool.h>

extern uint8_t *matrix;


@@ 8,3 11,5 @@ uint8_t matrix_scan(void);
bool matrix_is_modified(void);
bool matrix_has_ghost(void);
bool matrix_has_ghost_in_row(uint8_t row);

#endif

M mykey.c => mykey.c +54 -73
@@ 30,7 30,9 @@
#include <avr/interrupt.h>
#include <util/delay.h>

#include "usb_device.h"
#include "usb.h"
#include "usb_keyboard.h"
#include "usb_mouse.h"
#include "print.h"
#include "matrix.h"
#include "keymap.h"


@@ 50,16 52,9 @@ uint16_t idle_count=0;

int main(void)
{
    bool modified = false;
    bool has_ghost = false;
    uint8_t key_index = 0;

    // set for 16 MHz clock
    CPU_PRESCALE(0);

    matrix_init();


    // Initialize the USB, and then wait for the host to set configuration.
    // If the Teensy is powered without a PC connected to the USB port,
    // this will wait forever.


@@ 78,99 73,85 @@ int main(void)
    TCCR0B = 0x05;
    TIMSK0 = (1<<TOIE0);


    matrix_init();
    print("firmware 0.2 for t.m.k.\n");

    bool modified = false;
    bool has_ghost = false;
    int key_index = 0;
    int loop_count = 0;
    int layer = 0;
    while (1) {
        int layer = 0;

        matrix_scan();
        layer = get_layer();

        modified = matrix_is_modified();
        has_ghost = matrix_has_ghost();

        // doesnt send keys during ghost occurs
        if (modified && !has_ghost) {
            key_index = 0;
            keyboard_modifier_keys = 0;
            for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
        // print matrix state for debug
        if (modified) {
            print_matrix();

            for (int row = 0; row < MATRIX_ROWS; row++) {
                for (int col = 0; col < MATRIX_COLS; col++) {
                    if (matrix[row] & 1<<col) continue;

                    uint8_t code = get_keycode(layer, row, col);
                    if (code == KB_NO) {
                        continue;
                    } else if (KB_LCTRL <= code && code <= KB_RGUI) {
                        // modifier keycode: 0xE0-0xE7
                        keyboard_modifier_keys |= 1<<(code & 0x07);
                    } else {
                        if (key_index < 6)
                            keyboard_keys[key_index] = code;
                        key_index++;
                    }
            // LED flush
            DDRD |= 1<<PD6;
            PORTD |= 1<<PD6;
        }

        // set matrix state to keyboard_keys, keyboard_modifier_keys
        key_index = 0;
        keyboard_modifier_keys = 0;
        for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
        for (int row = 0; row < MATRIX_ROWS; row++) {
            for (int col = 0; col < MATRIX_COLS; col++) {
                if (matrix[row] & 1<<col) continue;

                uint8_t code = get_keycode(layer, row, col);
                if (code == KB_NO) {
                    continue;
                } else if (KB_LCTRL <= code && code <= KB_RGUI) {
                    // modifier keycode: 0xE0-0xE7
                    keyboard_modifier_keys |= 1<<(code & 0x07);
                } else {
                    if (key_index < 6)
                        keyboard_keys[key_index] = code;
                    key_index++;
                }
            }
        }

            // run bootloader when 4 left modifier keys down
        if (!has_ghost)  {
            // when 4 left modifier keys down
            if (keyboard_modifier_keys == (MOD_LCTRL | MOD_LSHIFT | MOD_LALT | MOD_LGUI)) {
                // cancel all keys
                keyboard_modifier_keys = 0;
                for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
                usb_keyboard_send();

                /*
                print("jump to bootloader...\n");
                _delay_ms(1000);
                jump_bootloader();
            }
                */

            if (key_index > 6) {
                //Rollover
            }
                // mouse
                print("usb_mouse_move\n");
                usb_mouse_move(10, 0, 0);

            usb_keyboard_send();


            // variables shared with interrupt routines must be
            // accessed carefully so the interrupt routine doesn't
            // try to use the variable in the middle of our access
            cli();
            //idle_count = 0;
            sei();
        }

        // print matrix state for debug
        if (modified) {
            print_matrix();

            // LED flush
            DDRD |= 1<<PD6;
            PORTD |= 1<<PD6;
        }
                _delay_ms(100);
                continue;
            }

/*
        // print counts for debug
        if ((loop_count % 0x1000) == 0) {
            //print(".");
            print("idle_count: "); phex((idle_count & 0xFF00) >> 8); phex(idle_count & 0xFF); print("\n");
            print("loop_count: "); phex((loop_count & 0xFF00) >> 8); phex(loop_count & 0xFF); print("\n");
            print_matrix();
        }

        // teensy LED flush for debug
        if ((loop_count & 0x100) == 0) {
            DDRD |= 1<<PD6;
            PORTD |= 1<<PD6;
            // send keys to host
            if (modified) {
                if (key_index > 6) {
                    //Rollover
                }
                usb_keyboard_send();
            }
        }
*/

        // now the current pins will be the previous, and
        // wait a short delay so we're not highly sensitive
        // to mechanical "bounce".
        _delay_ms(2);
        loop_count++;
        _delay_ms(2);
    }
}


M print.c => print.c +0 -1
@@ 25,7 25,6 @@

#include <avr/io.h>
#include <avr/pgmspace.h>

#include "print.h"

void print_P(const char *s)

M print.h => print.h +2 -2
@@ 1,5 1,5 @@
#ifndef print_h__
#define print_h__
#ifndef PRINT_H__
#define PRINT_H__ 1

#include <avr/pgmspace.h>
#include "usb_debug.h"

R usb_device.c => usb.c +107 -12
@@ 21,10 21,12 @@
 * THE SOFTWARE.
 */

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "usb_device.h"
#include "usb.h"
#include "usb_keyboard.h"
#include "usb_mouse.h"
#include "usb_debug.h"




@@ 64,11 66,15 @@

#define ENDPOINT0_SIZE		32

// 0:control endpoint is enabled automatically by controller.
static const uint8_t PROGMEM endpoint_config_table[] = {
	0,
	0,
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER
	// enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, // 1
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(MOUSE_SIZE)    | MOUSE_BUFFER,    // 2
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
        0, // 4
        0, // 5
        0, // 6
};




@@ 138,6 144,36 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = {
        0xc0                 // End Collection
};

// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
static uint8_t PROGMEM mouse_hid_report_desc[] = {
	0x05, 0x01,			// Usage Page (Generic Desktop)
	0x09, 0x02,			// Usage (Mouse)
	0xA1, 0x01,			// Collection (Application)
	0x05, 0x09,			//   Usage Page (Button)
	0x19, 0x01,			//   Usage Minimum (Button #1)
	0x29, 0x03,			//   Usage Maximum (Button #3)
	0x15, 0x00,			//   Logical Minimum (0)
	0x25, 0x01,			//   Logical Maximum (1)
	0x95, 0x03,			//   Report Count (3)
	0x75, 0x01,			//   Report Size (1)
	0x81, 0x02,			//   Input (Data, Variable, Absolute)
	0x95, 0x01,			//   Report Count (1)
	0x75, 0x05,			//   Report Size (5)
	0x81, 0x03,			//   Input (Constant)
	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)
	0x09, 0x38,			//   Usage (Wheel)
	0x95, 0x01,			//   Report Count (1),
	0x81, 0x06,			//   Input (Data, Variable, Relative)
	0xC0				// End Collection
};

static uint8_t PROGMEM debug_hid_report_desc[] = {
	0x06, 0x31, 0xFF,			// Usage Page 0xFF31 (vendor defined)
	0x09, 0x74,				// Usage 0x74


@@ 151,20 187,22 @@ static uint8_t PROGMEM debug_hid_report_desc[] = {
	0xC0					// end collection
};

#define CONFIG1_DESC_SIZE        (9+9+9+7+9+9+7)
#define CONFIG1_DESC_SIZE        (9+(9+9+7)+(9+9+7)+(9+9+7))
#define KEYBOARD_HID_DESC_OFFSET (9+9)
#define DEBUG_HID_DESC_OFFSET    (9+9+9+7+9)
#define MOUSE_HID_DESC_OFFSET    (9+(9+9+7)+9)
#define DEBUG_HID_DESC_OFFSET    (9+(9+9+7)+(9+9+7)+9)
static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
	// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
	9, 					// bLength;
	2,					// bDescriptorType;
	LSB(CONFIG1_DESC_SIZE),			// wTotalLength
	MSB(CONFIG1_DESC_SIZE),
	2,					// bNumInterfaces
	3,					// bNumInterfaces
	1,					// bConfigurationValue
	0,					// iConfiguration
	0xC0,					// bmAttributes
	50,					// bMaxPower

	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
	9,					// bLength
	4,					// bDescriptorType


@@ 175,7 213,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
	0x01,					// bInterfaceSubClass (0x01 = Boot)
	0x01,					// bInterfaceProtocol (0x01 = Keyboard)
	0,					// iInterface
	// HID interface descriptor, HID 1.11 spec, section 6.2.1
	// HID descriptor, HID 1.11 spec, section 6.2.1
	9,					// bLength
	0x21,					// bDescriptorType
	0x11, 0x01,				// bcdHID


@@ 191,6 229,34 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
	0x03,					// bmAttributes (0x03=intr)
	KEYBOARD_SIZE, 0,			// wMaxPacketSize
	1,					// bInterval

	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
	9,					// bLength
	4,					// bDescriptorType
	MOUSE_INTERFACE,			// bInterfaceNumber
	0,					// bAlternateSetting
	1,					// bNumEndpoints
	0x03,					// bInterfaceClass (0x03 = HID)
	0x01,					// bInterfaceSubClass (0x01 = Boot)
	0x02,					// bInterfaceProtocol (0x02 = Mouse)
	0,					// iInterface
	// HID descriptor, HID 1.11 spec, section 6.2.1
	9,					// bLength
	0x21,					// bDescriptorType
	0x11, 0x01,				// bcdHID
	0,					// bCountryCode
	1,					// bNumDescriptors
	0x22,					// bDescriptorType
	sizeof(mouse_hid_report_desc),		// wDescriptorLength
	0,
	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
	7,					// bLength
	5,					// bDescriptorType
	MOUSE_ENDPOINT | 0x80,			// bEndpointAddress
	0x03,					// bmAttributes (0x03=intr)
	4, 0,					// wMaxPacketSize
	1,					// bInterval

	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
	9,					// bLength
	4,					// bDescriptorType


@@ 201,7 267,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
	0x00,					// bInterfaceSubClass
	0x00,					// bInterfaceProtocol
	0,					// iInterface
	// HID interface descriptor, HID 1.11 spec, section 6.2.1
	// HID descriptor, HID 1.11 spec, section 6.2.1
	9,					// bLength
	0x21,					// bDescriptorType
	0x11, 0x01,				// bcdHID


@@ 259,6 325,9 @@ static struct descriptor_list_struct {
	{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
	{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
        // HID REPORT
	{0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
	{0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
        // HID REPORT
	{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
	{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
        // STRING descriptor


@@ 470,7 539,7 @@ ISR(USB_COM_vect)
			usb_configuration = wValue;
			usb_send_in();
			cfg = endpoint_config_table;
			for (i=1; i<5; i++) {
			for (i=1; i<=6; i++) {
				UENUM = i;
				en = pgm_read_byte(cfg++);
				UECONX = en;


@@ 479,7 548,7 @@ ISR(USB_COM_vect)
					UECFG1X = pgm_read_byte(cfg++);
				}
			}
        		UERST = 0x1E;
        		UERST = 0x7E;
        		UERST = 0;
			return;
		}


@@ 571,6 640,32 @@ ISR(USB_COM_vect)
				}
			}
		}
		if (wIndex == MOUSE_INTERFACE) {
			if (bmRequestType == 0xA1) {
				if (bRequest == HID_GET_REPORT) {
					usb_wait_in_ready();
					UEDATX = mouse_buttons;
					UEDATX = 0;
					UEDATX = 0;
					UEDATX = 0;
					usb_send_in();
					return;
				}
				if (bRequest == HID_GET_PROTOCOL) {
					usb_wait_in_ready();
					UEDATX = mouse_protocol;
					usb_send_in();
					return;
				}
			}
			if (bmRequestType == 0x21) {
				if (bRequest == HID_SET_PROTOCOL) {
					mouse_protocol = wValue;
					usb_send_in();
					return;
				}
			}
		}
		if (wIndex == DEBUG_INTERFACE) {
			if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
				len = wLength;

R usb_device.h => usb.h +2 -4
@@ 1,10 1,8 @@
#ifndef USB_DEVICE_H
#define  USB_DEVICE_H 1
#ifndef USB_H
#define  USB_H 1

#include <stdint.h>
#include <avr/io.h>
#include "usb_keyboard.h"
#include "usb_debug.h"


void usb_init(void);			// initialize everything

M usb_debug.h => usb_debug.h +3 -3
@@ 2,11 2,11 @@
#define  USB_DEBUG_H 1

#include <stdint.h>
#include "usb_device.h"
#include "usb.h"


#define DEBUG_INTERFACE		1
#define DEBUG_TX_ENDPOINT	4
#define DEBUG_INTERFACE		2
#define DEBUG_TX_ENDPOINT	3
#define DEBUG_TX_SIZE		32
#define DEBUG_TX_BUFFER		EP_DOUBLE_BUFFER


M usb_keyboard.h => usb_keyboard.h +2 -2
@@ 2,11 2,11 @@
#define  USB_KEYBOARD_H 1

#include <stdint.h>
#include "usb_device.h"
#include "usb.h"


#define KEYBOARD_INTERFACE	0
#define KEYBOARD_ENDPOINT	3
#define KEYBOARD_ENDPOINT	1
#define KEYBOARD_SIZE		8
#define KEYBOARD_BUFFER		EP_DOUBLE_BUFFER


R usbkeycodes.h => usb_keycodes.h +10 -14
@@ 1,5 1,8 @@
/* Some modified from Keyboard Upgrade 0.3.0
 * 2010/08/22
/* 
 * Key codes from HID Keyboard/Keypad Page
 * http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
 *
 * Based on Keyboard Upgrade v0.3.0 http://github.com/rhomann/kbupgrade
 */
/*
 * Keyboard Upgrade -- Firmware for homebrew computer keyboard controllers.


@@ 30,17 33,10 @@
 * MA  02110-1301  USA
 */

#ifndef USBKEYCODES_H
#define USBKEYCODES_H
#ifndef USB_KEYCODES_H
#define USB_KEYCODES_H


/*
 * The USB keycodes are enumerated here - the first part is simply
 * an enumeration of the allowed scan-codes used for USB HID devices.
 */
/*
 * see 10 Keyboard/Keypad Page(0x07)
 * http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
 */
enum keycodes {
    KB_NO = 0,
    KB_ROLL_OVER,


@@ 265,11 261,11 @@ enum keycodes {
    KB_RALT,            /* 0x40 */
    KB_RGUI,            /* 0x80 */

    /* function keys */
    /* extensions for internal use */
    FN_0 = 0xF0,
    FN_1,
    FN_2,
    FN_3,
};

#endif /* USBKEYCODES_H */
#endif /* USB_KEYCODES_H */

A usb_mouse.c => usb_mouse.c +62 -0
@@ 0,0 1,62 @@
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usb_mouse.h"


// which buttons are currently pressed
uint8_t mouse_buttons=0;

// protocol setting from the host.  We use exactly the same report
// either way, so this variable only stores the setting since we
// are required to be able to report which setting is in use.
uint8_t mouse_protocol=1;


// Set the mouse buttons.  To create a "click", 2 calls are needed,
// one to push the button down and the second to release it
int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right)
{
	uint8_t mask=0;

	if (left) mask |= 1;
	if (middle) mask |= 4;
	if (right) mask |= 2;
	mouse_buttons = mask;
	return usb_mouse_move(0, 0, 0);
}

// Move the mouse.  x, y and wheel are -127 to 127.  Use 0 for no movement.
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel)
{
	uint8_t intr_state, timeout;

	if (!usb_configured()) return -1;
	if (x == -128) x = -127;
	if (y == -128) y = -127;
	if (wheel == -128) wheel = -127;
	intr_state = SREG;
	cli();
	UENUM = MOUSE_ENDPOINT;
	timeout = UDFNUML + 50;
	while (1) {
		// are we ready to transmit?
		if (UEINTX & (1<<RWAL)) break;
		SREG = intr_state;
		// has the USB gone offline?
		if (!usb_configured()) return -1;
		// have we waited too long?
		if (UDFNUML == timeout) return -1;
		// get ready to try checking again
		intr_state = SREG;
		cli();
		UENUM = MOUSE_ENDPOINT;
	}
	UEDATX = mouse_buttons;
	UEDATX = x;
	UEDATX = y;
	UEDATX = wheel;
	UEINTX = 0x3A;
	SREG = intr_state;
	return 0;
}


A usb_mouse.h => usb_mouse.h +20 -0
@@ 0,0 1,20 @@
#ifndef USB_MOUSE_H
#define  USB_MOUSE_H 1

#include <stdint.h>
#include "usb.h"


#define MOUSE_INTERFACE		1
#define MOUSE_ENDPOINT		2
#define MOUSE_SIZE		8
#define MOUSE_BUFFER		EP_DOUBLE_BUFFER

extern uint8_t mouse_buttons;
extern uint8_t mouse_protocol;


int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right);
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel);

#endif