diff --git a/docs/_summary.md b/docs/_summary.md index ce02220fbf2..b085c18d794 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -21,6 +21,7 @@ * [Leader Key](feature_leader_key.md) * [Macros](macros.md) * [Mouse keys](mouse_keys.md) + * [Pointing Device](feature_pointing_device.md) * [PS2 Mouse](feature_ps2_mouse.md) * [Space Cadet](space_cadet_shift.md) * [Tap Dance](tap_dance.md) diff --git a/keyboards/dichotemy/config.h b/keyboards/dichotemy/config.h new file mode 100644 index 00000000000..b3bd6d94212 --- /dev/null +++ b/keyboards/dichotemy/config.h @@ -0,0 +1,87 @@ +/* +Copyright 2012 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include "config_common.h" + +/* USB Device descriptor parameter */ + +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0xACC7 +#define DEVICE_VER 0x0001 +#define MANUFACTURER unknown +#define PRODUCT Dichotemy +#define DESCRIPTION q.m.k. keyboard firmware for Dichotemy + +/* key matrix size */ +#define MATRIX_ROWS 5 +#define MATRIX_COLS 12 + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* number of backlight levels */ +//#define BACKLIGHT_LEVELS 3 + +#define ONESHOT_TIMEOUT 500 + + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +#define PREVENT_STUCK_MODIFIERS + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +//UART settings for communication with the RF microcontroller +#define SERIAL_UART_BAUD 1000000 +#define SERIAL_UART_DATA UDR1 +#define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1) +#define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) +#define SERIAL_UART_RXD_PRESENT (UCSR1A & _BV(RXC1)) +#define SERIAL_UART_INIT() do { \ + /* baud rate */ \ + UBRR1L = SERIAL_UART_UBRR; \ + /* baud rate */ \ + UBRR1H = SERIAL_UART_UBRR >> 8; \ + /* enable TX and RX */ \ + UCSR1B = _BV(TXEN1) | _BV(RXEN1); \ + /* 8-bit data */ \ + UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ + } while(0) + +#endif diff --git a/keyboards/dichotemy/dichotemy.c b/keyboards/dichotemy/dichotemy.c new file mode 100644 index 00000000000..080c2654cd1 --- /dev/null +++ b/keyboards/dichotemy/dichotemy.c @@ -0,0 +1,86 @@ +#include "dichotemy.h" +#include "pointing_device.h" +#include "report.h" + +void uart_init(void) { + SERIAL_UART_INIT(); +} + +void pointing_device_task(void){ + report_mouse_t currentReport = {}; + SERIAL_UART_INIT(); + uint32_t timeout = 0; + + //the m character requests the RF slave to send the mouse report + SERIAL_UART_DATA = 'm'; + + //trust the external inputs completely, erase old data + uint8_t uart_data[5] = {0}; + + //there are 10 bytes corresponding to 10 columns, and an end byte + for (uint8_t i = 0; i < 5; i++) { + //wait for the serial data, timeout if it's been too long + //this only happened in testing with a loose wire, but does no + //harm to leave it in here + while(!SERIAL_UART_RXD_PRESENT){ + timeout++; + if (timeout > 10000){ + break; + } + } + uart_data[i] = SERIAL_UART_DATA; + } + + //check for the end packet, bits 1-4 are movement and scroll + //but bit 5 has bits 0-3 for the scroll button state + //(1000 if pressed, 0000 if not) and bits 4-7 are always 1 + //We can use this to verify the report sent properly. + if (uart_data[4] == 0x0F || uart_data[4] == 0x8F) + { + currentReport = pointing_device_get_report(); + //shifting and transferring the info to the mouse report varaible + //mouseReport.x = 127 max -127 min + currentReport.x = uart_data[0]; + //mouseReport.y = 127 max -127 min + currentReport.y = uart_data[1]; + //mouseReport.v = 127 max -127 min (scroll vertical) + currentReport.v = uart_data[2]; + //mouseReport.h = 127 max -127 min (scroll horizontal) + currentReport.h = uart_data[3]; + //mouseReport.buttons = 0x31 max (bitmask for mouse buttons 1-5) 0x00 min + //mouse buttons 1 and 2 are handled by the keymap, but not 3 + if (uart_data[4] == 0x0F) { //then 3 is not pressed + currentReport.buttons &= ~MOUSE_BTN3; //MOUSE_BTN3 is def in report.h + } else { //3 must be pressed + currentReport.buttons |= MOUSE_BTN3; + } + pointing_device_set_report(currentReport); + } + pointing_device_send(); +} + +void led_init(void) { + DDRD |= (1<<1); + PORTD |= (1<<1); + DDRF |= (1<<4) | (1<<5); + PORTF |= (1<<4) | (1<<5); +} + + +void matrix_init_kb(void) { + // put your keyboard start-up code here + // runs once when the firmware starts up + matrix_init_user(); + uart_init(); + led_init(); +} + +void matrix_scan_kb(void) { + // put your looping keyboard code here + // runs every cycle (a lot) + matrix_scan_user(); +} + +void led_set_kb(uint8_t usb_led) { + +} diff --git a/keyboards/dichotemy/dichotemy.h b/keyboards/dichotemy/dichotemy.h new file mode 100644 index 00000000000..09b9dfcf22a --- /dev/null +++ b/keyboards/dichotemy/dichotemy.h @@ -0,0 +1,67 @@ +#ifndef DICHOTEMY_H +#define DICHOTEMY_H + +#include "quantum.h" +#include "matrix.h" +#include "backlight.h" +#include + +#define red_led_off PORTF |= (1<<5) +#define red_led_on PORTF &= ~(1<<5) +#define blu_led_off PORTF |= (1<<4) +#define blu_led_on PORTF &= ~(1<<4) +#define grn_led_off PORTD |= (1<<1) +#define grn_led_on PORTD &= ~(1<<1) + +#define set_led_off red_led_off; grn_led_off; blu_led_off +#define set_led_red red_led_on; grn_led_off; blu_led_off +#define set_led_blue red_led_off; grn_led_off; blu_led_on +#define set_led_green red_led_off; grn_led_on; blu_led_off +#define set_led_yellow red_led_on; grn_led_on; blu_led_off +#define set_led_magenta red_led_on; grn_led_off; blu_led_on +#define set_led_cyan red_led_off; grn_led_on; blu_led_on +#define set_led_white red_led_on; grn_led_on; blu_led_on + +/* +#define LED_B 5 +#define LED_R 6 +#define LED_G 7 + +#define all_leds_off PORTF &= ~(1<event.pressed) { + num_timer = timer_read(); + number_singular_key = true; + layer_invert(_NM); + } else { + if (timer_elapsed(num_timer) < MAX_TOGGLE_LENGTH && number_singular_key) { + //do nothing, the layer has already been inverted + } else { + layer_invert(_NM); + } + } + update_tri_layer(_NM, _SF, _NS); + return false; + break; + //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held. + case SFTKEY: + if (record->event.pressed) { + shift_held = true; + shift_suspended = false; + shift_timer = timer_read(); + shift_singular_key = true; + layer_on(_SF); + register_code(KC_LSFT); + } else { + shift_held = false; + if (timer_elapsed(shift_timer) < MAX_TOGGLE_LENGTH && shift_singular_key) { + //this was basically a toggle, so activate/deactivate caps lock. + SEND_STRING(SS_TAP(X_CAPSLOCK)); + } + layer_off(_SF); + unregister_code(KC_LSFT); + } + update_tri_layer(_NM, _SF, _NS); + return false; + break; + //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift + case MOUSE: + if (record->event.pressed) { + mouse_timer = timer_read(); + mouse_singular_key = true; + layer_invert(_MS); + } else { + if (timer_elapsed(mouse_timer) < MAX_TOGGLE_LENGTH && number_singular_key){ + //do nothing, it was a toggle (and it's already been toggled) + } else { + layer_invert(_MS); + } + } + return false; + break; + //Custom macros for strange keys with different long-tap behavior + case CK_1G: + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + shift_singular_key = false; + number_singular_key = false; + mouse_singular_key = false; + if (record->event.pressed) { + special_timers[CK_1G-SAFE_RANGE] = timer_read(); + } else { + if (special_key_states[CK_1G-SAFE_RANGE]){ + //key was activated after longpress_delay, need to close those keycodes + special_key_states[CK_1G-SAFE_RANGE] = 0; + unregister_code(KC_GRAVE); + } else { + //key was not activated, return macro activating proper, pre-long-tap key + SEND_STRING(SS_TAP(X_1)); + } + special_timers[CK_1G-SAFE_RANGE] = 0xFFFF; + } + break; + case CK_BSPE: + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + shift_singular_key = false; + number_singular_key = false; + mouse_singular_key = false; + if (record->event.pressed) { + special_timers[CK_BSPE-SAFE_RANGE] = timer_read(); + } else { + if (special_key_states[CK_BSPE-SAFE_RANGE]){ + //key was activated after longpress_delay, need to close those keycodes + special_key_states[CK_BSPE-SAFE_RANGE] = 0; + unregister_code(KC_ENTER); + } else { + //key was not activated, return macro activating proper, pre-long-tap key + SEND_STRING(SS_TAP(X_BSLASH)); + } + special_timers[CK_BSPE-SAFE_RANGE] = 0xFFFF; + } + break; + case CK_QE: + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + shift_singular_key = false; + number_singular_key = false; + mouse_singular_key = false; + if (record->event.pressed) { + special_timers[CK_QE-SAFE_RANGE] = timer_read(); + } else { + if (special_key_states[CK_QE-SAFE_RANGE]){ + //key was activated after longpress_delay, need to close those keycodes + special_key_states[CK_QE-SAFE_RANGE] = 0; + unregister_code(KC_ENTER); + } else { + //key was not activated, return macro activating proper, pre-long-tap key + SEND_STRING(SS_TAP(X_QUOTE)); + } + special_timers[CK_QE-SAFE_RANGE] = 0xFFFF; + } + break; + case CK_TE: + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + if (record->event.pressed) { + special_timers[CK_TE-SAFE_RANGE] = timer_read(); + } else { + if (special_key_states[CK_TE-SAFE_RANGE]){ + //key was activated after longpress_delay, need to close those keycodes + special_key_states[CK_TE-SAFE_RANGE] = 0; + unregister_code(KC_ENTER); + } else { + //key was not activated, return macro activating proper, pre-long-tap key + SEND_STRING(SS_TAP(X_TAB)); + } + special_timers[CK_TE-SAFE_RANGE] = 0xFFFF; + } + break; + //No-shift keys, they unregister the KC_LSFT code so they can send + //unshifted values - but they don't change the bool. if any other + //key is pressed and the bool is set, KC_LSFT is registered again. + case NS_HYPH: + if (record->event.pressed) { + shift_suspended = true; + unregister_code(KC_LSFT); + register_code(KC_MINS); + } else { + unregister_code(KC_MINS); + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + } + break; + case NS_EQU: + if (record->event.pressed) { + shift_suspended = true; + unregister_code(KC_LSFT); + register_code(KC_EQUAL); + } else { + unregister_code(KC_EQUAL); + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + } + break; + + //mouse buttons, for 1-3, to update the mouse report: + case MS_BTN1: + currentReport = pointing_device_get_report(); + if (record->event.pressed) { + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + //update mouse report here + currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h + } else { + //update mouse report here + currentReport.buttons &= ~MOUSE_BTN1; + } + pointing_device_set_report(currentReport); + break; + case MS_BTN2: + currentReport = pointing_device_get_report(); + if (record->event.pressed) { + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + //update mouse report here + currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h + } else { + //update mouse report here + } + pointing_device_set_report(currentReport); + break; + //there is a case for button 3, but that's handled in dichotemy.c, and this is being + //disabled to avoid any conflict. + /*case MS_BTN3: + currentReport = pointing_device_get_report(); + if (record->event.pressed) { + if (shift_held && shift_suspended){ + register_code(KC_LSFT); + shift_suspended = false; + } + //update mouse report here + currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN2 is a const defined in report.h + } else { + //update mouse report here + } + pointing_device_set_report(currentReport); + break;*/ + + //If any other key was pressed during the layer mod hold period, + //then the layer mod was used momentarily, and should block latching + //Additionally, if NS_ keys are in use, then shift may be held (but is + //disabled for the unshifted keycodes to be send. Check the bool and + //register shift as necessary. + default: + if (shift_held){ + register_code(KC_LSFT); + } + shift_singular_key = false; + number_singular_key = false; + mouse_singular_key = false; + break; + } + return true; +}; + +void matrix_scan_user(void) { + uint8_t layer = biton32(layer_state); + for (uint8_t i = 0; i= LONGPRESS_DELAY && !special_key_states[i]){ + switch (i + SAFE_RANGE){ + case CK_1G: + register_code(KC_GRAVE); + break; + case CK_BSPE: + register_code(KC_ENTER); + break; + case CK_QE: + register_code(KC_ENTER); + break; + case CK_TE: + register_code(KC_ESCAPE); + break; + } + special_key_states[i] = 1; + } + } + switch (layer) { + case _BS: + set_led_off; + break; + case _NM: + set_led_blue; + break; + case _SF: + set_led_red; + break; + case _NS: + set_led_green; + break; + default: + break; + } +}; + diff --git a/keyboards/dichotemy/matrix.c b/keyboards/dichotemy/matrix.c new file mode 100644 index 00000000000..02e96e38caa --- /dev/null +++ b/keyboards/dichotemy/matrix.c @@ -0,0 +1,178 @@ +/* +Copyright 2012 Jun Wako +Copyright 2014 Jack Humbert + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include +#include +#if defined(__AVR__) +#include +#endif +#include "wait.h" +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" +#include "timer.h" + +#if (MATRIX_COLS <= 8) +# define print_matrix_header() print("\nr/c 01234567\n") +# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop(matrix[i]) +# define ROW_SHIFTER ((uint8_t)1) +#elif (MATRIX_COLS <= 16) +# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") +# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop16(matrix[i]) +# define ROW_SHIFTER ((uint16_t)1) +#elif (MATRIX_COLS <= 32) +# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") +# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop32(matrix[i]) +# define ROW_SHIFTER ((uint32_t)1) +#endif + +#define MAIN_ROWMASK 0xFFF0; +#define LOWER_ROWMASK 0x1F80; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; + +__attribute__ ((weak)) +void matrix_init_quantum(void) { + matrix_init_kb(); +} + +__attribute__ ((weak)) +void matrix_scan_quantum(void) { + matrix_scan_kb(); +} + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { +} + +inline +uint8_t matrix_rows(void) { + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) { + return MATRIX_COLS; +} + +void matrix_init(void) { + + matrix_init_quantum(); +} + +uint8_t matrix_scan(void) +{ + SERIAL_UART_INIT(); + + uint32_t timeout = 0; + + //the s character requests the RF slave to send the matrix + SERIAL_UART_DATA = 's'; + + //trust the external keystates entirely, erase the last data + uint8_t uart_data[7] = {0}; + + //there are 10 bytes corresponding to 10 columns, and an end byte + for (uint8_t i = 0; i < 7; i++) { + //wait for the serial data, timeout if it's been too long + //this only happened in testing with a loose wire, but does no + //harm to leave it in here + while(!SERIAL_UART_RXD_PRESENT){ + timeout++; + if (timeout > 10000){ + break; + } + } + uart_data[i] = SERIAL_UART_DATA; + } + + //check for the end packet, the key state bytes use the LSBs, so 0xE0 + //will only show up here if the correct bytes were recieved + if (uart_data[6] == 0x96) { //this is an arbitrary binary checksum (10010110) + //shifting and transferring the keystates to the QMK matrix variable + //bits 1-12 are row 1, 13-24 are row 2, 25-36 are row 3, + //bits 37-42 are row 4 (only 6 wide, 1-3 are 0, and 10-12 are 0) + //bits 43-48 are row 5 (same as row 4) + /* ASSUMING MSB FIRST */ + matrix[0] = (((uint16_t) uart_data[0] << 8) | ((uint16_t) uart_data[1])) & MAIN_ROWMASK; + matrix[1] = ((uint16_t) uart_data[1] << 12) | ((uint16_t) uart_data[2] << 4); + matrix[2] = (((uint16_t) uart_data[3] << 8) | ((uint16_t) uart_data[4])) & MAIN_ROWMASK; + matrix[3] = (((uint16_t) uart_data[4] << 9) | ((uint16_t) uart_data[5] << 1)) & LOWER_ROWMASK; + matrix[4] = ((uint16_t) uart_data[5] << 7) & LOWER_ROWMASK; + /* OK, TURNS OUT THAT WAS A BAD ASSUMPTION */ + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + //I've unpacked these into the mirror image of what QMK expects them to be, so... + matrix[i] = ((matrix[i] * 0x0802LU & 0x22110LU) | (matrix[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; + //bithack mirror! Doesn't make any sense, but works - and efficiently. + } + } + + + matrix_scan_quantum(); + return 1; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1.c` and see keymap document (you can find in top readme.md) and existent keymap files. + +To build the firmware binary hex file with a keymap just do `make` with a keymap like this: + +``` +$ make [default|jack|] +``` +Keymaps follow the format **__\.c__** and are stored in the `keymaps` folder. diff --git a/keyboards/dichotemy/rules.mk b/keyboards/dichotemy/rules.mk new file mode 100644 index 00000000000..c8a316f8432 --- /dev/null +++ b/keyboards/dichotemy/rules.mk @@ -0,0 +1,82 @@ + +OPT_DEFS += -DDICHOTEMY_PROMICRO +OPT_DEFS += -DCATERINA_BOOTLOADER +DICHOTEMY_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \ + avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB) + +# # project specific files +SRC = matrix.c + + +# MCU name +#MCU = at90usb1287 +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + +# Interrupt driven control endpoint task(+60) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + + +# Boot Section Size in *bytes* +# Teensy halfKay 512 +# Teensy++ halfKay 1024 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBaspLoader 2048 +OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + +# Build Options +# comment out to disable the options. +# +#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +#MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +POINTING_DEVICE_ENABLE = yes # Generic Pointer, not as big as mouse keys hopefully. +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +CUSTOM_MATRIX = yes # Remote matrix from the wireless bridge +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +# SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA +# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +# MIDI_ENABLE = YES # MIDI controls +UNICODE_ENABLE = YES # Unicode +# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID + +USB = /dev/ttyACM0 + +#upload: build +# $(DICHOTEMY_UPLOAD_COMMAND) diff --git a/quantum/pointing_device.c b/quantum/pointing_device.c index 0aaab84cd24..e60ae8d93e4 100644 --- a/quantum/pointing_device.c +++ b/quantum/pointing_device.c @@ -33,7 +33,7 @@ void pointing_device_init(void){ __attribute__ ((weak)) void pointing_device_send(void){ //If you need to do other things, like debugging, this is the place to do it. - host_mouse_send(mouseReport); + host_mouse_send(&mouseReport); //send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device mouseReport.x = 0; mouseReport.y = 0;