Merge upstream QMK Firmware at '0.12.52~1'
This commit is contained in:
@@ -154,38 +154,45 @@ dfu-split-left: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size
|
||||
dfu-split-right: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size
|
||||
$(call EXEC_DFU,eeprom-righthand.eep)
|
||||
|
||||
AVRDUDE_PROGRAMMER ?= avrdude
|
||||
|
||||
define EXEC_AVRDUDE
|
||||
USB= ;\
|
||||
if $(GREP) -q -s Microsoft /proc/version; then \
|
||||
echo 'ERROR: AVR flashing cannot be automated within the Windows Subsystem for Linux (WSL) currently. Instead, take the .hex file generated and flash it using QMK Toolbox, AVRDUDE, AVRDUDESS, or XLoader.'; \
|
||||
else \
|
||||
printf "Detecting USB port, reset your controller now."; \
|
||||
TMP1=`mktemp`; \
|
||||
TMP2=`mktemp`; \
|
||||
ls /dev/tty* > $$TMP1; \
|
||||
while [ -z $$USB ]; do \
|
||||
sleep 0.5; \
|
||||
printf "."; \
|
||||
ls /dev/tty* > $$TMP2; \
|
||||
USB=`comm -13 $$TMP1 $$TMP2 | $(GREP) -o '/dev/tty.*'`; \
|
||||
mv $$TMP2 $$TMP1; \
|
||||
done; \
|
||||
rm $$TMP1; \
|
||||
echo ""; \
|
||||
echo "Device $$USB has appeared; assuming it is the controller."; \
|
||||
if $(GREP) -q -s 'MINGW\|MSYS' /proc/version; then \
|
||||
USB=`echo "$$USB" | perl -pne 's/\/dev\/ttyS(\d+)/COM.($$1+1)/e'`; \
|
||||
echo "Remapped MSYS2 USB port to $$USB"; \
|
||||
sleep 1; \
|
||||
list_devices() { \
|
||||
if $(GREP) -q -s icrosoft /proc/version; then \
|
||||
wmic.exe path Win32_SerialPort get DeviceID 2>/dev/null | LANG=C perl -pne 's/COM(\d+)/COM.($$1-1)/e' | sed 's!COM!/dev/ttyS!' | xargs echo -n | sort; \
|
||||
elif [ "`uname`" = "FreeBSD" ]; then \
|
||||
ls /dev/tty* | grep -v '\.lock$$' | grep -v '\.init$$'; \
|
||||
else \
|
||||
printf "Waiting for $$USB to become writable."; \
|
||||
while [ ! -w "$$USB" ]; do sleep 0.5; printf "."; done; echo ""; \
|
||||
ls /dev/tty*; \
|
||||
fi; \
|
||||
if [ -z "$(1)" ]; then \
|
||||
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex; \
|
||||
else \
|
||||
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex -U eeprom:w:$(QUANTUM_PATH)/split_common/$(1); \
|
||||
fi \
|
||||
}; \
|
||||
USB= ;\
|
||||
printf "Detecting USB port, reset your controller now."; \
|
||||
TMP1=`mktemp`; \
|
||||
TMP2=`mktemp`; \
|
||||
list_devices > $$TMP1; \
|
||||
while [ -z "$$USB" ]; do \
|
||||
sleep 0.5; \
|
||||
printf "."; \
|
||||
list_devices > $$TMP2; \
|
||||
USB=`comm -13 $$TMP1 $$TMP2 | $(GREP) -o '/dev/tty.*'`; \
|
||||
mv $$TMP2 $$TMP1; \
|
||||
done; \
|
||||
rm $$TMP1; \
|
||||
echo ""; \
|
||||
echo "Device $$USB has appeared; assuming it is the controller."; \
|
||||
if $(GREP) -q -s 'MINGW\|MSYS\|icrosoft' /proc/version; then \
|
||||
USB=`echo "$$USB" | LANG=C perl -pne 's/\/dev\/ttyS(\d+)/COM.($$1+1)/e'`; \
|
||||
echo "Remapped USB port to $$USB"; \
|
||||
sleep 1; \
|
||||
else \
|
||||
printf "Waiting for $$USB to become writable."; \
|
||||
while [ ! -w "$$USB" ]; do sleep 0.5; printf "."; done; echo ""; \
|
||||
fi; \
|
||||
if [ -z "$(1)" ]; then \
|
||||
$(AVRDUDE_PROGRAMMER) -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex; \
|
||||
else \
|
||||
$(AVRDUDE_PROGRAMMER) -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex -U eeprom:w:$(QUANTUM_PATH)/split_common/$(1); \
|
||||
fi
|
||||
endef
|
||||
|
||||
@@ -204,7 +211,7 @@ avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
|
||||
$(call EXEC_AVRDUDE,eeprom-righthand.eep)
|
||||
|
||||
define EXEC_USBASP
|
||||
avrdude -p $(MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex
|
||||
$(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex
|
||||
endef
|
||||
|
||||
usbasp: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
|
||||
@@ -283,8 +290,11 @@ extcoff: $(BUILD_DIR)/$(TARGET).elf
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(BUILD_DIR)/$(TARGET).cof
|
||||
|
||||
bootloader:
|
||||
ifneq ($(strip $(BOOTLOADER)), qmk-dfu)
|
||||
$(error Please set BOOTLOADER = qmk-dfu first!)
|
||||
endif
|
||||
make -C lib/lufa/Bootloaders/DFU/ clean
|
||||
$(TMK_DIR)/make_dfu_header.sh $(ALL_CONFIGS)
|
||||
bin/qmk generate-dfu-header --quiet --keyboard $(KEYBOARD) --output lib/lufa/Bootloaders/DFU/Keyboard.h
|
||||
$(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | sed -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0))
|
||||
$(eval PROGRAM_SIZE_KB=$(shell n=`expr $(MAX_SIZE) / 1024` && echo $$(($$n)) || echo 0))
|
||||
$(eval BOOT_SECTION_SIZE_KB=$(shell n=`expr $(BOOTLOADER_SIZE) / 1024` && echo $$(($$n)) || echo 0))
|
||||
|
||||
@@ -71,6 +71,9 @@ else ifneq ("$(wildcard $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk)","
|
||||
BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD)
|
||||
BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk
|
||||
KEYBOARD_PATHS += $(BOARD_PATH)/configs
|
||||
ifneq ("$(wildcard $(BOARD_PATH)/rules.mk)","")
|
||||
include $(BOARD_PATH)/rules.mk
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ("$(wildcard $(BOARD_MK))","")
|
||||
@@ -309,6 +312,7 @@ LDFLAGS += -mno-thumb-interwork -mthumb
|
||||
LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
|
||||
LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
|
||||
LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS)
|
||||
LDFLAGS += --specs=nano.specs
|
||||
|
||||
OPT_DEFS += -DPROTOCOL_CHIBIOS
|
||||
|
||||
|
||||
@@ -10,27 +10,20 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
|
||||
$(COMMON_DIR)/action_macro.c \
|
||||
$(COMMON_DIR)/action_layer.c \
|
||||
$(COMMON_DIR)/action_util.c \
|
||||
$(COMMON_DIR)/print.c \
|
||||
$(COMMON_DIR)/debug.c \
|
||||
$(COMMON_DIR)/sendchar_null.c \
|
||||
$(COMMON_DIR)/util.c \
|
||||
$(COMMON_DIR)/eeconfig.c \
|
||||
$(COMMON_DIR)/report.c \
|
||||
$(PLATFORM_COMMON_DIR)/suspend.c \
|
||||
$(PLATFORM_COMMON_DIR)/timer.c \
|
||||
$(COMMON_DIR)/sync_timer.c \
|
||||
$(PLATFORM_COMMON_DIR)/bootloader.c \
|
||||
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
|
||||
else ifeq ($(PLATFORM),CHIBIOS)
|
||||
TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T
|
||||
VPATH += $(PRINTF_PATH)
|
||||
else ifeq ($(PLATFORM),ARM_ATSAM)
|
||||
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
|
||||
# Use platform provided print - fall back to lib/printf
|
||||
ifneq ("$(wildcard $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk)","")
|
||||
include $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk
|
||||
else
|
||||
include $(TMK_PATH)/$(COMMON_DIR)/lib_printf.mk
|
||||
endif
|
||||
|
||||
# Option modules
|
||||
@@ -67,10 +60,6 @@ ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
|
||||
TMK_COMMON_SRC += $(COMMON_DIR)/mousekey.c
|
||||
TMK_COMMON_DEFS += -DMOUSEKEY_ENABLE
|
||||
TMK_COMMON_DEFS += -DMOUSE_ENABLE
|
||||
|
||||
ifeq ($(strip $(MOUSE_SHARED_EP)), yes)
|
||||
TMK_COMMON_DEFS += -DMOUSE_SHARED_EP
|
||||
SHARED_EP_ENABLE = yes
|
||||
@@ -98,17 +87,16 @@ else
|
||||
TMK_COMMON_DEFS += -DNO_DEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(COMMAND_ENABLE)), yes)
|
||||
TMK_COMMON_SRC += $(COMMON_DIR)/command.c
|
||||
TMK_COMMON_DEFS += -DCOMMAND_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NKRO_ENABLE)), yes)
|
||||
ifneq ($(PROTOCOL),VUSB)
|
||||
ifeq ($(PROTOCOL), VUSB)
|
||||
$(info NKRO is not currently supported on V-USB, and has been disabled.)
|
||||
else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
||||
$(info NKRO is not currently supported with Bluetooth, and has been disabled.)
|
||||
else ifneq ($(BLUETOOTH),)
|
||||
$(info NKRO is not currently supported with Bluetooth, and has been disabled.)
|
||||
else
|
||||
TMK_COMMON_DEFS += -DNKRO_ENABLE
|
||||
SHARED_EP_ENABLE = yes
|
||||
else
|
||||
$(info NKRO is not currently supported on V-USB, and has been disabled.)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -47,10 +47,6 @@ int tp_buttons;
|
||||
int retro_tapping_counter = 0;
|
||||
#endif
|
||||
|
||||
#ifdef FAUXCLICKY_ENABLE
|
||||
# include "fauxclicky.h"
|
||||
#endif
|
||||
|
||||
#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
|
||||
__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; }
|
||||
#endif
|
||||
@@ -80,15 +76,10 @@ void action_exec(keyevent_t event) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FAUXCLICKY_ENABLE
|
||||
if (IS_PRESSED(event)) {
|
||||
FAUXCLICKY_ACTION_PRESS;
|
||||
if (event.pressed) {
|
||||
// clear the potential weak mods left by previously pressed keys
|
||||
clear_weak_mods();
|
||||
}
|
||||
if (IS_RELEASED(event)) {
|
||||
FAUXCLICKY_ACTION_RELEASE;
|
||||
}
|
||||
fauxclicky_check();
|
||||
#endif
|
||||
|
||||
#ifdef SWAP_HANDS_ENABLE
|
||||
if (!IS_NOEVENT(event)) {
|
||||
@@ -251,11 +242,6 @@ void process_action(keyrecord_t *record, action_t action) {
|
||||
uint8_t tap_count = record->tap.count;
|
||||
#endif
|
||||
|
||||
if (event.pressed) {
|
||||
// clear the potential weak mods left by previously pressed keys
|
||||
clear_weak_mods();
|
||||
}
|
||||
|
||||
#ifndef NO_ACTION_ONESHOT
|
||||
bool do_release_oneshot = false;
|
||||
// notice we only clear the one shot layer if the pressed key is not a modifier.
|
||||
@@ -424,56 +410,22 @@ void process_action(keyrecord_t *record, action_t action) {
|
||||
case ACT_MOUSEKEY:
|
||||
if (event.pressed) {
|
||||
mousekey_on(action.key.code);
|
||||
switch (action.key.code) {
|
||||
# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
|
||||
case KC_MS_BTN1:
|
||||
register_button(true, MOUSE_BTN1);
|
||||
break;
|
||||
case KC_MS_BTN2:
|
||||
register_button(true, MOUSE_BTN2);
|
||||
break;
|
||||
case KC_MS_BTN3:
|
||||
register_button(true, MOUSE_BTN3);
|
||||
break;
|
||||
# endif
|
||||
# ifdef POINTING_DEVICE_ENABLE
|
||||
case KC_MS_BTN4:
|
||||
register_button(true, MOUSE_BTN4);
|
||||
break;
|
||||
case KC_MS_BTN5:
|
||||
register_button(true, MOUSE_BTN5);
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
mousekey_send();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mousekey_off(action.key.code);
|
||||
switch (action.key.code) {
|
||||
}
|
||||
switch (action.key.code) {
|
||||
# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
|
||||
case KC_MS_BTN1:
|
||||
register_button(false, MOUSE_BTN1);
|
||||
break;
|
||||
case KC_MS_BTN2:
|
||||
register_button(false, MOUSE_BTN2);
|
||||
break;
|
||||
case KC_MS_BTN3:
|
||||
register_button(false, MOUSE_BTN3);
|
||||
break;
|
||||
# ifdef POINTING_DEVICE_ENABLE
|
||||
case KC_MS_BTN1 ... KC_MS_BTN8:
|
||||
# else
|
||||
case KC_MS_BTN1 ... KC_MS_BTN3:
|
||||
# endif
|
||||
register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1));
|
||||
break;
|
||||
# endif
|
||||
# ifdef POINTING_DEVICE_ENABLE
|
||||
case KC_MS_BTN4:
|
||||
register_button(false, MOUSE_BTN4);
|
||||
break;
|
||||
case KC_MS_BTN5:
|
||||
register_button(false, MOUSE_BTN5);
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
mousekey_send();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
mousekey_send();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -936,23 +888,28 @@ void unregister_code(uint8_t code) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Utilities for actions. (FIXME: Needs better description)
|
||||
/** \brief Tap a keycode with a delay.
|
||||
*
|
||||
* FIXME: Needs documentation.
|
||||
* \param code The basic keycode to tap.
|
||||
* \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it.
|
||||
*/
|
||||
void tap_code(uint8_t code) {
|
||||
void tap_code_delay(uint8_t code, uint16_t delay) {
|
||||
register_code(code);
|
||||
if (code == KC_CAPS) {
|
||||
wait_ms(TAP_HOLD_CAPS_DELAY);
|
||||
} else {
|
||||
wait_ms(TAP_CODE_DELAY);
|
||||
for (uint16_t i = delay; i > 0; i--) {
|
||||
wait_ms(1);
|
||||
}
|
||||
unregister_code(code);
|
||||
}
|
||||
|
||||
/** \brief Tap a keycode with the default delay.
|
||||
*
|
||||
* \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
|
||||
*/
|
||||
void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); }
|
||||
|
||||
/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.
|
||||
*
|
||||
* \param mods A bitfield of modifiers to unregister.
|
||||
* \param mods A bitfield of modifiers to register.
|
||||
*/
|
||||
void register_mods(uint8_t mods) {
|
||||
if (mods) {
|
||||
@@ -972,6 +929,7 @@ void unregister_mods(uint8_t mods) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** \brief Adds the given weak modifiers and sends a keyboard report immediately.
|
||||
*
|
||||
* \param mods A bitfield of modifiers to register.
|
||||
@@ -1017,6 +975,10 @@ void clear_keyboard_but_mods(void) {
|
||||
* FIXME: Needs documentation.
|
||||
*/
|
||||
void clear_keyboard_but_mods_and_keys() {
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
host_system_send(0);
|
||||
host_consumer_send(0);
|
||||
#endif
|
||||
clear_weak_mods();
|
||||
clear_macro_mods();
|
||||
send_keyboard_report();
|
||||
@@ -1024,10 +986,6 @@ void clear_keyboard_but_mods_and_keys() {
|
||||
mousekey_clear();
|
||||
mousekey_send();
|
||||
#endif
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
host_system_send(0);
|
||||
host_consumer_send(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Utilities for actions. (FIXME: Needs better description)
|
||||
|
||||
@@ -100,6 +100,7 @@ void process_action(keyrecord_t *record, action_t action);
|
||||
void register_code(uint8_t code);
|
||||
void unregister_code(uint8_t code);
|
||||
void tap_code(uint8_t code);
|
||||
void tap_code_delay(uint8_t code, uint16_t delay);
|
||||
void register_mods(uint8_t mods);
|
||||
void unregister_mods(uint8_t mods);
|
||||
void register_weak_mods(uint8_t mods);
|
||||
|
||||
@@ -120,14 +120,21 @@ bool process_tapping(keyrecord_t *keyp) {
|
||||
* useful for long TAPPING_TERM but may prevent fast typing.
|
||||
*/
|
||||
# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
|
||||
else if (
|
||||
else if (((
|
||||
# ifdef TAPPING_TERM_PER_KEY
|
||||
(get_tapping_term(get_event_keycode(tapping_key.event, false), keyp) >= 500) &&
|
||||
get_tapping_term(get_event_keycode(tapping_key.event, false), keyp)
|
||||
# else
|
||||
TAPPING_TERM
|
||||
# endif
|
||||
>= 500)
|
||||
|
||||
# ifdef PERMISSIVE_HOLD_PER_KEY
|
||||
!get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp) &&
|
||||
|| get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp)
|
||||
# elif defined(PERMISSIVE_HOLD)
|
||||
|| true
|
||||
# endif
|
||||
IS_RELEASED(event) && waiting_buffer_typed(event)) {
|
||||
) &&
|
||||
IS_RELEASED(event) && waiting_buffer_typed(event)) {
|
||||
debug("Tapping: End. No tap. Interfered by typing key\n");
|
||||
process_record(&tapping_key);
|
||||
tapping_key = (keyrecord_t){};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2012,2013 Jun Wako <wakojun@gmail.com> */
|
||||
/* Copyright 2012 Jun Wako <wakojun@gmail.com> */
|
||||
/* Very basic print functions, intended to be used with usb_debug_only.c
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2008 PJRC.COM, LLC
|
||||
@@ -21,27 +21,14 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "print.h"
|
||||
#include "arm_atsam/printf.h"
|
||||
|
||||
#ifndef NO_PRINT
|
||||
|
||||
# if defined(__AVR__)
|
||||
|
||||
# define sendchar(c) xputc(c)
|
||||
|
||||
void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { xdev_out(sendchar_func); }
|
||||
|
||||
# elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
|
||||
|
||||
// don't need anything extra
|
||||
|
||||
# elif defined(__arm__) /* __AVR__ */
|
||||
|
||||
// TODO
|
||||
// void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { }
|
||||
|
||||
# endif /* __AVR__ */
|
||||
|
||||
#endif
|
||||
// Create user & normal print defines
|
||||
#define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
#define print(s) __xprintf(s)
|
||||
#define println(s) __xprintf(s "\r\n")
|
||||
#define uprint(s) __xprintf(s)
|
||||
#define uprintln(s) __xprintf(s "\r\n")
|
||||
#define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
@@ -15,11 +15,13 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "printf.h"
|
||||
#include "sendchar.h"
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
|
||||
# include "samd51j18a.h"
|
||||
# include "arm_atsam_protocol.h"
|
||||
# include "printf.h"
|
||||
# include <string.h>
|
||||
# include <stdarg.h>
|
||||
|
||||
@@ -66,3 +68,8 @@ void console_printf(char *fmt, ...) {
|
||||
}
|
||||
|
||||
#endif // CONSOLE_ENABLE
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
void print_set_sendchar(sendchar_func_t send) {}
|
||||
>>>>>>> 0.12.52~1
|
||||
|
||||
1
tmk_core/common/arm_atsam/printf.mk
Normal file
1
tmk_core/common/arm_atsam/printf.mk
Normal file
@@ -0,0 +1 @@
|
||||
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
|
||||
@@ -7,7 +7,8 @@
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void suspend_idle(uint8_t time) { /* Note: Not used anywhere currently */ }
|
||||
void suspend_idle(uint8_t time) { /* Note: Not used anywhere currently */
|
||||
}
|
||||
|
||||
/** \brief Run user level Power down
|
||||
*
|
||||
|
||||
32
tmk_core/common/atomic_util.h
Normal file
32
tmk_core/common/atomic_util.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Macro to help make GPIO and other controls atomic.
|
||||
|
||||
#ifndef IGNORE_ATOMIC_BLOCK
|
||||
# if __has_include_next("atomic_util.h")
|
||||
# include_next "atomic_util.h" /* Include the platforms atomic.h */
|
||||
# else
|
||||
# define ATOMIC_BLOCK _Static_assert(0, "ATOMIC_BLOCK not implemented")
|
||||
# define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE not implemented")
|
||||
# define ATOMIC_BLOCK_FORCEON _Static_assert(0, "ATOMIC_BLOCK_FORCEON not implemented")
|
||||
# endif
|
||||
#else /* do nothing atomic macro */
|
||||
# define ATOMIC_BLOCK for (uint8_t __ToDo = 1; __ToDo; __ToDo = 0)
|
||||
# define ATOMIC_BLOCK_RESTORESTATE ATOMIC_BLOCK
|
||||
# define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK
|
||||
#endif
|
||||
33
tmk_core/common/avr/_print.h
Normal file
33
tmk_core/common/avr/_print.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Copyright 2012 Jun Wako <wakojun@gmail.com> */
|
||||
/* Very basic print functions, intended to be used with usb_debug_only.c
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2008 PJRC.COM, LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "avr/xprintf.h"
|
||||
|
||||
// Create user & normal print defines
|
||||
#define print(s) xputs(PSTR(s))
|
||||
#define println(s) xputs(PSTR(s "\r\n"))
|
||||
#define uprint(s) xputs(PSTR(s))
|
||||
#define uprintln(s) xputs(PSTR(s "\r\n"))
|
||||
#define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__)
|
||||
22
tmk_core/common/avr/atomic_util.h
Normal file
22
tmk_core/common/avr/atomic_util.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/* atomic macro for AVR */
|
||||
#include <util/atomic.h>
|
||||
|
||||
#define ATOMIC_BLOCK_RESTORESTATE ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
||||
#define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK(ATOMIC_FORCEON)
|
||||
@@ -77,7 +77,7 @@ uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void bootloader_jump(void) {
|
||||
__attribute__((weak)) void bootloader_jump(void) {
|
||||
#if !defined(BOOTLOADER_SIZE)
|
||||
uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
|
||||
|
||||
|
||||
34
tmk_core/common/avr/gpio.h
Normal file
34
tmk_core/common/avr/gpio.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "pin_defs.h"
|
||||
|
||||
typedef uint8_t pin_t;
|
||||
|
||||
#define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
|
||||
#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
|
||||
#define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low")
|
||||
#define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
|
||||
|
||||
#define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
|
||||
#define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
|
||||
#define writePin(pin, level) ((level) ? writePinHigh(pin) : writePinLow(pin))
|
||||
|
||||
#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
|
||||
|
||||
#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF))
|
||||
128
tmk_core/common/avr/pin_defs.h
Normal file
128
tmk_core/common/avr/pin_defs.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define PORT_SHIFTER 4 // this may be 4 for all AVR chips
|
||||
|
||||
// If you want to add more to this list, reference the PINx definitions in these header
|
||||
// files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr
|
||||
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
|
||||
# define ADDRESS_BASE 0x00
|
||||
# define PINB_ADDRESS 0x3
|
||||
# define PINC_ADDRESS 0x6
|
||||
# define PIND_ADDRESS 0x9
|
||||
# define PINE_ADDRESS 0xC
|
||||
# define PINF_ADDRESS 0xF
|
||||
#elif defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
|
||||
# define ADDRESS_BASE 0x00
|
||||
# define PINB_ADDRESS 0x3
|
||||
# define PINC_ADDRESS 0x6
|
||||
# define PIND_ADDRESS 0x9
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||
# define ADDRESS_BASE 0x00
|
||||
# define PINA_ADDRESS 0x0
|
||||
# define PINB_ADDRESS 0x3
|
||||
# define PINC_ADDRESS 0x6
|
||||
# define PIND_ADDRESS 0x9
|
||||
# define PINE_ADDRESS 0xC
|
||||
# define PINF_ADDRESS 0xF
|
||||
#elif defined(__AVR_ATmega32A__)
|
||||
# define ADDRESS_BASE 0x10
|
||||
# define PIND_ADDRESS 0x0
|
||||
# define PINC_ADDRESS 0x3
|
||||
# define PINB_ADDRESS 0x6
|
||||
# define PINA_ADDRESS 0x9
|
||||
#elif defined(__AVR_ATtiny85__)
|
||||
# define ADDRESS_BASE 0x10
|
||||
# define PINB_ADDRESS 0x6
|
||||
#else
|
||||
# error "Pins are not defined"
|
||||
#endif
|
||||
|
||||
#define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin)
|
||||
|
||||
#define _PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + ((p) >> PORT_SHIFTER) + (offset))
|
||||
// Port X Input Pins Address
|
||||
#define PINx_ADDRESS(p) _PIN_ADDRESS(p, 0)
|
||||
// Port X Data Direction Register, 0:input 1:output
|
||||
#define DDRx_ADDRESS(p) _PIN_ADDRESS(p, 1)
|
||||
// Port X Data Register
|
||||
#define PORTx_ADDRESS(p) _PIN_ADDRESS(p, 2)
|
||||
|
||||
/* I/O pins */
|
||||
#ifdef PORTA
|
||||
# define A0 PINDEF(A, 0)
|
||||
# define A1 PINDEF(A, 1)
|
||||
# define A2 PINDEF(A, 2)
|
||||
# define A3 PINDEF(A, 3)
|
||||
# define A4 PINDEF(A, 4)
|
||||
# define A5 PINDEF(A, 5)
|
||||
# define A6 PINDEF(A, 6)
|
||||
# define A7 PINDEF(A, 7)
|
||||
#endif
|
||||
#ifdef PORTB
|
||||
# define B0 PINDEF(B, 0)
|
||||
# define B1 PINDEF(B, 1)
|
||||
# define B2 PINDEF(B, 2)
|
||||
# define B3 PINDEF(B, 3)
|
||||
# define B4 PINDEF(B, 4)
|
||||
# define B5 PINDEF(B, 5)
|
||||
# define B6 PINDEF(B, 6)
|
||||
# define B7 PINDEF(B, 7)
|
||||
#endif
|
||||
#ifdef PORTC
|
||||
# define C0 PINDEF(C, 0)
|
||||
# define C1 PINDEF(C, 1)
|
||||
# define C2 PINDEF(C, 2)
|
||||
# define C3 PINDEF(C, 3)
|
||||
# define C4 PINDEF(C, 4)
|
||||
# define C5 PINDEF(C, 5)
|
||||
# define C6 PINDEF(C, 6)
|
||||
# define C7 PINDEF(C, 7)
|
||||
#endif
|
||||
#ifdef PORTD
|
||||
# define D0 PINDEF(D, 0)
|
||||
# define D1 PINDEF(D, 1)
|
||||
# define D2 PINDEF(D, 2)
|
||||
# define D3 PINDEF(D, 3)
|
||||
# define D4 PINDEF(D, 4)
|
||||
# define D5 PINDEF(D, 5)
|
||||
# define D6 PINDEF(D, 6)
|
||||
# define D7 PINDEF(D, 7)
|
||||
#endif
|
||||
#ifdef PORTE
|
||||
# define E0 PINDEF(E, 0)
|
||||
# define E1 PINDEF(E, 1)
|
||||
# define E2 PINDEF(E, 2)
|
||||
# define E3 PINDEF(E, 3)
|
||||
# define E4 PINDEF(E, 4)
|
||||
# define E5 PINDEF(E, 5)
|
||||
# define E6 PINDEF(E, 6)
|
||||
# define E7 PINDEF(E, 7)
|
||||
#endif
|
||||
#ifdef PORTF
|
||||
# define F0 PINDEF(F, 0)
|
||||
# define F1 PINDEF(F, 1)
|
||||
# define F2 PINDEF(F, 2)
|
||||
# define F3 PINDEF(F, 3)
|
||||
# define F4 PINDEF(F, 4)
|
||||
# define F5 PINDEF(F, 5)
|
||||
# define F6 PINDEF(F, 6)
|
||||
# define F7 PINDEF(F, 7)
|
||||
#endif
|
||||
@@ -14,34 +14,7 @@ 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "xprintf.h"
|
||||
#include "sendchar.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// convert to L string
|
||||
#define LSTR(s) XLSTR(s)
|
||||
#define XLSTR(s) L## #s
|
||||
// convert to string
|
||||
#define STR(s) XSTR(s)
|
||||
#define XSTR(s) #s
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint8_t bitpop(uint8_t bits);
|
||||
uint8_t bitpop16(uint16_t bits);
|
||||
uint8_t bitpop32(uint32_t bits);
|
||||
|
||||
uint8_t biton(uint8_t bits);
|
||||
uint8_t biton16(uint16_t bits);
|
||||
uint8_t biton32(uint32_t bits);
|
||||
|
||||
uint8_t bitrev(uint8_t bits);
|
||||
uint16_t bitrev16(uint16_t bits);
|
||||
uint32_t bitrev32(uint32_t bits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void print_set_sendchar(sendchar_func_t func) { xdev_out(func); }
|
||||
2
tmk_core/common/avr/printf.mk
Normal file
2
tmk_core/common/avr/printf.mk
Normal file
@@ -0,0 +1,2 @@
|
||||
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
|
||||
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
|
||||
@@ -90,7 +90,7 @@ void sleep_led_toggle(void) {
|
||||
*
|
||||
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
|
||||
*
|
||||
* http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
|
||||
* https://www.wolframalpha.com/input/?i=sin%28x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
|
||||
* (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
|
||||
*/
|
||||
static const uint8_t breathing_table[64] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include "matrix.h"
|
||||
#include "action.h"
|
||||
#include "suspend_avr.h"
|
||||
#include "suspend.h"
|
||||
#include "timer.h"
|
||||
#include "led.h"
|
||||
@@ -13,6 +12,9 @@
|
||||
#ifdef PROTOCOL_LUFA
|
||||
# include "lufa.h"
|
||||
#endif
|
||||
#ifdef PROTOCOL_VUSB
|
||||
# include "vusb.h"
|
||||
#endif
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
# include "backlight.h"
|
||||
@@ -52,7 +54,25 @@ __attribute__((weak)) void suspend_power_down_user(void) {}
|
||||
*/
|
||||
__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
|
||||
|
||||
#ifndef NO_SUSPEND_POWER_DOWN
|
||||
#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
|
||||
|
||||
// clang-format off
|
||||
#define wdt_intr_enable(value) \
|
||||
__asm__ __volatile__ ( \
|
||||
"in __tmp_reg__,__SREG__" "\n\t" \
|
||||
"cli" "\n\t" \
|
||||
"wdr" "\n\t" \
|
||||
"sts %0,%1" "\n\t" \
|
||||
"out __SREG__,__tmp_reg__" "\n\t" \
|
||||
"sts %0,%2" "\n\t" \
|
||||
: /* no outputs */ \
|
||||
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
|
||||
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
|
||||
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \
|
||||
: "r0" \
|
||||
)
|
||||
// clang-format on
|
||||
|
||||
/** \brief Power down MCU with watchdog timer
|
||||
*
|
||||
* wdto: watchdog timer timeout defined in <avr/wdt.h>
|
||||
@@ -74,35 +94,11 @@ static uint8_t wdt_timeout = 0;
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
static void power_down(uint8_t wdto) {
|
||||
# ifdef PROTOCOL_LUFA
|
||||
if (USB_DeviceState == DEVICE_STATE_Configured) return;
|
||||
# endif
|
||||
wdt_timeout = wdto;
|
||||
|
||||
// Watchdog Interrupt Mode
|
||||
wdt_intr_enable(wdto);
|
||||
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_set(0);
|
||||
# endif
|
||||
|
||||
// Turn off LED indicators
|
||||
uint8_t leds_off = 0;
|
||||
# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
|
||||
if (is_backlight_enabled()) {
|
||||
// Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
|
||||
leds_off |= (1 << USB_LED_CAPS_LOCK);
|
||||
}
|
||||
# endif
|
||||
led_set(leds_off);
|
||||
|
||||
# ifdef AUDIO_ENABLE
|
||||
stop_all_notes();
|
||||
# endif /* AUDIO_ENABLE */
|
||||
# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
|
||||
rgblight_suspend();
|
||||
# endif
|
||||
|
||||
// TODO: more power saving
|
||||
// See PicoPower application note
|
||||
// - I/O port input with pullup
|
||||
@@ -125,10 +121,45 @@ static void power_down(uint8_t wdto) {
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void suspend_power_down(void) {
|
||||
#ifdef PROTOCOL_LUFA
|
||||
if (USB_DeviceState == DEVICE_STATE_Configured) return;
|
||||
#endif
|
||||
#ifdef PROTOCOL_VUSB
|
||||
if (!vusb_suspended) return;
|
||||
#endif
|
||||
|
||||
suspend_power_down_kb();
|
||||
|
||||
#ifndef NO_SUSPEND_POWER_DOWN
|
||||
// Turn off backlight
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_set(0);
|
||||
# endif
|
||||
|
||||
// Turn off LED indicators
|
||||
uint8_t leds_off = 0;
|
||||
# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
|
||||
if (is_backlight_enabled()) {
|
||||
// Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
|
||||
leds_off |= (1 << USB_LED_CAPS_LOCK);
|
||||
}
|
||||
# endif
|
||||
led_set(leds_off);
|
||||
|
||||
// Turn off audio
|
||||
# ifdef AUDIO_ENABLE
|
||||
stop_all_notes();
|
||||
# endif
|
||||
|
||||
// Turn off underglow
|
||||
# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
|
||||
rgblight_suspend();
|
||||
# endif
|
||||
|
||||
// Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt)
|
||||
# if defined(WDT_vect)
|
||||
power_down(WDTO_15MS);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -163,17 +194,24 @@ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_us
|
||||
void suspend_wakeup_init(void) {
|
||||
// clear keyboard state
|
||||
clear_keyboard();
|
||||
|
||||
// Turn on backlight
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
backlight_init();
|
||||
#endif
|
||||
|
||||
// Restore LED indicators
|
||||
led_set(host_keyboard_leds());
|
||||
|
||||
// Wake up underglow
|
||||
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
|
||||
rgblight_wakeup();
|
||||
#endif
|
||||
|
||||
suspend_wakeup_init_kb();
|
||||
}
|
||||
|
||||
#ifndef NO_SUSPEND_POWER_DOWN
|
||||
#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
|
||||
/* watchdog timeout */
|
||||
ISR(WDT_vect) {
|
||||
// compensate timer for sleep
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
// clang-format off
|
||||
#define wdt_intr_enable(value) \
|
||||
__asm__ __volatile__ ( \
|
||||
"in __tmp_reg__,__SREG__" "\n\t" \
|
||||
"cli" "\n\t" \
|
||||
"wdr" "\n\t" \
|
||||
"sts %0,%1" "\n\t" \
|
||||
"out __SREG__,__tmp_reg__" "\n\t" \
|
||||
"sts %0,%2" "\n\t" \
|
||||
: /* no outputs */ \
|
||||
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
|
||||
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
|
||||
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
|
||||
_BV(WDIE) | (value & 0x07)) ) \
|
||||
: "r0" \
|
||||
)
|
||||
// clang-format on
|
||||
37
tmk_core/common/chibios/atomic_util.h
Normal file
37
tmk_core/common/chibios/atomic_util.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ch.h>
|
||||
|
||||
static __inline__ uint8_t __interrupt_disable__(void) {
|
||||
chSysLock();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ void __interrupt_enable__(const uint8_t *__s) {
|
||||
chSysUnlock();
|
||||
|
||||
__asm__ volatile("" ::: "memory");
|
||||
(void)__s;
|
||||
}
|
||||
|
||||
#define ATOMIC_BLOCK(type) for (type, __ToDo = __interrupt_disable__(); __ToDo; __ToDo = 0)
|
||||
#define ATOMIC_FORCEON uint8_t sreg_save __attribute__((__cleanup__(__interrupt_enable__))) = 0
|
||||
|
||||
#define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE not implemented")
|
||||
#define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK(ATOMIC_FORCEON)
|
||||
@@ -363,7 +363,7 @@ void eeprom_initialize(void) {
|
||||
return;
|
||||
}
|
||||
} while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
|
||||
flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
|
||||
flashend = (uint32_t)(p - 1);
|
||||
}
|
||||
|
||||
uint8_t eeprom_read_byte(const uint8_t *addr) {
|
||||
|
||||
34
tmk_core/common/chibios/gpio.h
Normal file
34
tmk_core/common/chibios/gpio.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <hal.h>
|
||||
#include "pin_defs.h"
|
||||
|
||||
typedef ioline_t pin_t;
|
||||
|
||||
#define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT)
|
||||
#define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)
|
||||
#define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)
|
||||
#define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)
|
||||
|
||||
#define writePinHigh(pin) palSetLine(pin)
|
||||
#define writePinLow(pin) palClearLine(pin)
|
||||
#define writePin(pin, level) ((level) ? (writePinHigh(pin)) : (writePinLow(pin)))
|
||||
|
||||
#define readPin(pin) palReadLine(pin)
|
||||
|
||||
#define togglePin(pin) palToggleLine(pin)
|
||||
242
tmk_core/common/chibios/pin_defs.h
Normal file
242
tmk_core/common/chibios/pin_defs.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Defines mapping for Proton C replacement
|
||||
#ifdef CONVERT_TO_PROTON_C
|
||||
// Left side (front)
|
||||
# define D3 PAL_LINE(GPIOA, 9)
|
||||
# define D2 PAL_LINE(GPIOA, 10)
|
||||
// GND
|
||||
// GND
|
||||
# define D1 PAL_LINE(GPIOB, 7)
|
||||
# define D0 PAL_LINE(GPIOB, 6)
|
||||
# define D4 PAL_LINE(GPIOB, 5)
|
||||
# define C6 PAL_LINE(GPIOB, 4)
|
||||
# define D7 PAL_LINE(GPIOB, 3)
|
||||
# define E6 PAL_LINE(GPIOB, 2)
|
||||
# define B4 PAL_LINE(GPIOB, 1)
|
||||
# define B5 PAL_LINE(GPIOB, 0)
|
||||
|
||||
// Right side (front)
|
||||
// RAW
|
||||
// GND
|
||||
// RESET
|
||||
// VCC
|
||||
# define F4 PAL_LINE(GPIOA, 2)
|
||||
# define F5 PAL_LINE(GPIOA, 1)
|
||||
# define F6 PAL_LINE(GPIOA, 0)
|
||||
# define F7 PAL_LINE(GPIOB, 8)
|
||||
# define B1 PAL_LINE(GPIOB, 13)
|
||||
# define B3 PAL_LINE(GPIOB, 14)
|
||||
# define B2 PAL_LINE(GPIOB, 15)
|
||||
# define B6 PAL_LINE(GPIOB, 9)
|
||||
|
||||
// LEDs (only D5/C13 uses an actual LED)
|
||||
# ifdef CONVERT_TO_PROTON_C_RXLED
|
||||
# define D5 PAL_LINE(GPIOC, 14)
|
||||
# define B0 PAL_LINE(GPIOC, 13)
|
||||
# else
|
||||
# define D5 PAL_LINE(GPIOC, 13)
|
||||
# define B0 PAL_LINE(GPIOC, 14)
|
||||
# endif
|
||||
#else
|
||||
# define A0 PAL_LINE(GPIOA, 0)
|
||||
# define A1 PAL_LINE(GPIOA, 1)
|
||||
# define A2 PAL_LINE(GPIOA, 2)
|
||||
# define A3 PAL_LINE(GPIOA, 3)
|
||||
# define A4 PAL_LINE(GPIOA, 4)
|
||||
# define A5 PAL_LINE(GPIOA, 5)
|
||||
# define A6 PAL_LINE(GPIOA, 6)
|
||||
# define A7 PAL_LINE(GPIOA, 7)
|
||||
# define A8 PAL_LINE(GPIOA, 8)
|
||||
# define A9 PAL_LINE(GPIOA, 9)
|
||||
# define A10 PAL_LINE(GPIOA, 10)
|
||||
# define A11 PAL_LINE(GPIOA, 11)
|
||||
# define A12 PAL_LINE(GPIOA, 12)
|
||||
# define A13 PAL_LINE(GPIOA, 13)
|
||||
# define A14 PAL_LINE(GPIOA, 14)
|
||||
# define A15 PAL_LINE(GPIOA, 15)
|
||||
# define B0 PAL_LINE(GPIOB, 0)
|
||||
# define B1 PAL_LINE(GPIOB, 1)
|
||||
# define B2 PAL_LINE(GPIOB, 2)
|
||||
# define B3 PAL_LINE(GPIOB, 3)
|
||||
# define B4 PAL_LINE(GPIOB, 4)
|
||||
# define B5 PAL_LINE(GPIOB, 5)
|
||||
# define B6 PAL_LINE(GPIOB, 6)
|
||||
# define B7 PAL_LINE(GPIOB, 7)
|
||||
# define B8 PAL_LINE(GPIOB, 8)
|
||||
# define B9 PAL_LINE(GPIOB, 9)
|
||||
# define B10 PAL_LINE(GPIOB, 10)
|
||||
# define B11 PAL_LINE(GPIOB, 11)
|
||||
# define B12 PAL_LINE(GPIOB, 12)
|
||||
# define B13 PAL_LINE(GPIOB, 13)
|
||||
# define B14 PAL_LINE(GPIOB, 14)
|
||||
# define B15 PAL_LINE(GPIOB, 15)
|
||||
# define B16 PAL_LINE(GPIOB, 16)
|
||||
# define B17 PAL_LINE(GPIOB, 17)
|
||||
# define B18 PAL_LINE(GPIOB, 18)
|
||||
# define B19 PAL_LINE(GPIOB, 19)
|
||||
# define C0 PAL_LINE(GPIOC, 0)
|
||||
# define C1 PAL_LINE(GPIOC, 1)
|
||||
# define C2 PAL_LINE(GPIOC, 2)
|
||||
# define C3 PAL_LINE(GPIOC, 3)
|
||||
# define C4 PAL_LINE(GPIOC, 4)
|
||||
# define C5 PAL_LINE(GPIOC, 5)
|
||||
# define C6 PAL_LINE(GPIOC, 6)
|
||||
# define C7 PAL_LINE(GPIOC, 7)
|
||||
# define C8 PAL_LINE(GPIOC, 8)
|
||||
# define C9 PAL_LINE(GPIOC, 9)
|
||||
# define C10 PAL_LINE(GPIOC, 10)
|
||||
# define C11 PAL_LINE(GPIOC, 11)
|
||||
# define C12 PAL_LINE(GPIOC, 12)
|
||||
# define C13 PAL_LINE(GPIOC, 13)
|
||||
# define C14 PAL_LINE(GPIOC, 14)
|
||||
# define C15 PAL_LINE(GPIOC, 15)
|
||||
# define D0 PAL_LINE(GPIOD, 0)
|
||||
# define D1 PAL_LINE(GPIOD, 1)
|
||||
# define D2 PAL_LINE(GPIOD, 2)
|
||||
# define D3 PAL_LINE(GPIOD, 3)
|
||||
# define D4 PAL_LINE(GPIOD, 4)
|
||||
# define D5 PAL_LINE(GPIOD, 5)
|
||||
# define D6 PAL_LINE(GPIOD, 6)
|
||||
# define D7 PAL_LINE(GPIOD, 7)
|
||||
# define D8 PAL_LINE(GPIOD, 8)
|
||||
# define D9 PAL_LINE(GPIOD, 9)
|
||||
# define D10 PAL_LINE(GPIOD, 10)
|
||||
# define D11 PAL_LINE(GPIOD, 11)
|
||||
# define D12 PAL_LINE(GPIOD, 12)
|
||||
# define D13 PAL_LINE(GPIOD, 13)
|
||||
# define D14 PAL_LINE(GPIOD, 14)
|
||||
# define D15 PAL_LINE(GPIOD, 15)
|
||||
# define E0 PAL_LINE(GPIOE, 0)
|
||||
# define E1 PAL_LINE(GPIOE, 1)
|
||||
# define E2 PAL_LINE(GPIOE, 2)
|
||||
# define E3 PAL_LINE(GPIOE, 3)
|
||||
# define E4 PAL_LINE(GPIOE, 4)
|
||||
# define E5 PAL_LINE(GPIOE, 5)
|
||||
# define E6 PAL_LINE(GPIOE, 6)
|
||||
# define E7 PAL_LINE(GPIOE, 7)
|
||||
# define E8 PAL_LINE(GPIOE, 8)
|
||||
# define E9 PAL_LINE(GPIOE, 9)
|
||||
# define E10 PAL_LINE(GPIOE, 10)
|
||||
# define E11 PAL_LINE(GPIOE, 11)
|
||||
# define E12 PAL_LINE(GPIOE, 12)
|
||||
# define E13 PAL_LINE(GPIOE, 13)
|
||||
# define E14 PAL_LINE(GPIOE, 14)
|
||||
# define E15 PAL_LINE(GPIOE, 15)
|
||||
# define F0 PAL_LINE(GPIOF, 0)
|
||||
# define F1 PAL_LINE(GPIOF, 1)
|
||||
# define F2 PAL_LINE(GPIOF, 2)
|
||||
# define F3 PAL_LINE(GPIOF, 3)
|
||||
# define F4 PAL_LINE(GPIOF, 4)
|
||||
# define F5 PAL_LINE(GPIOF, 5)
|
||||
# define F6 PAL_LINE(GPIOF, 6)
|
||||
# define F7 PAL_LINE(GPIOF, 7)
|
||||
# define F8 PAL_LINE(GPIOF, 8)
|
||||
# define F9 PAL_LINE(GPIOF, 9)
|
||||
# define F10 PAL_LINE(GPIOF, 10)
|
||||
# define F11 PAL_LINE(GPIOF, 11)
|
||||
# define F12 PAL_LINE(GPIOF, 12)
|
||||
# define F13 PAL_LINE(GPIOF, 13)
|
||||
# define F14 PAL_LINE(GPIOF, 14)
|
||||
# define F15 PAL_LINE(GPIOF, 15)
|
||||
# define G0 PAL_LINE(GPIOG, 0)
|
||||
# define G1 PAL_LINE(GPIOG, 1)
|
||||
# define G2 PAL_LINE(GPIOG, 2)
|
||||
# define G3 PAL_LINE(GPIOG, 3)
|
||||
# define G4 PAL_LINE(GPIOG, 4)
|
||||
# define G5 PAL_LINE(GPIOG, 5)
|
||||
# define G6 PAL_LINE(GPIOG, 6)
|
||||
# define G7 PAL_LINE(GPIOG, 7)
|
||||
# define G8 PAL_LINE(GPIOG, 8)
|
||||
# define G9 PAL_LINE(GPIOG, 9)
|
||||
# define G10 PAL_LINE(GPIOG, 10)
|
||||
# define G11 PAL_LINE(GPIOG, 11)
|
||||
# define G12 PAL_LINE(GPIOG, 12)
|
||||
# define G13 PAL_LINE(GPIOG, 13)
|
||||
# define G14 PAL_LINE(GPIOG, 14)
|
||||
# define G15 PAL_LINE(GPIOG, 15)
|
||||
# define H0 PAL_LINE(GPIOH, 0)
|
||||
# define H1 PAL_LINE(GPIOH, 1)
|
||||
# define H2 PAL_LINE(GPIOH, 2)
|
||||
# define H3 PAL_LINE(GPIOH, 3)
|
||||
# define H4 PAL_LINE(GPIOH, 4)
|
||||
# define H5 PAL_LINE(GPIOH, 5)
|
||||
# define H6 PAL_LINE(GPIOH, 6)
|
||||
# define H7 PAL_LINE(GPIOH, 7)
|
||||
# define H8 PAL_LINE(GPIOH, 8)
|
||||
# define H9 PAL_LINE(GPIOH, 9)
|
||||
# define H10 PAL_LINE(GPIOH, 10)
|
||||
# define H11 PAL_LINE(GPIOH, 11)
|
||||
# define H12 PAL_LINE(GPIOH, 12)
|
||||
# define H13 PAL_LINE(GPIOH, 13)
|
||||
# define H14 PAL_LINE(GPIOH, 14)
|
||||
# define H15 PAL_LINE(GPIOH, 15)
|
||||
# define I0 PAL_LINE(GPIOI, 0)
|
||||
# define I1 PAL_LINE(GPIOI, 1)
|
||||
# define I2 PAL_LINE(GPIOI, 2)
|
||||
# define I3 PAL_LINE(GPIOI, 3)
|
||||
# define I4 PAL_LINE(GPIOI, 4)
|
||||
# define I5 PAL_LINE(GPIOI, 5)
|
||||
# define I6 PAL_LINE(GPIOI, 6)
|
||||
# define I7 PAL_LINE(GPIOI, 7)
|
||||
# define I8 PAL_LINE(GPIOI, 8)
|
||||
# define I9 PAL_LINE(GPIOI, 9)
|
||||
# define I10 PAL_LINE(GPIOI, 10)
|
||||
# define I11 PAL_LINE(GPIOI, 11)
|
||||
# define I12 PAL_LINE(GPIOI, 12)
|
||||
# define I13 PAL_LINE(GPIOI, 13)
|
||||
# define I14 PAL_LINE(GPIOI, 14)
|
||||
# define I15 PAL_LINE(GPIOI, 15)
|
||||
# define J0 PAL_LINE(GPIOJ, 0)
|
||||
# define J1 PAL_LINE(GPIOJ, 1)
|
||||
# define J2 PAL_LINE(GPIOJ, 2)
|
||||
# define J3 PAL_LINE(GPIOJ, 3)
|
||||
# define J4 PAL_LINE(GPIOJ, 4)
|
||||
# define J5 PAL_LINE(GPIOJ, 5)
|
||||
# define J6 PAL_LINE(GPIOJ, 6)
|
||||
# define J7 PAL_LINE(GPIOJ, 7)
|
||||
# define J8 PAL_LINE(GPIOJ, 8)
|
||||
# define J9 PAL_LINE(GPIOJ, 9)
|
||||
# define J10 PAL_LINE(GPIOJ, 10)
|
||||
# define J11 PAL_LINE(GPIOJ, 11)
|
||||
# define J12 PAL_LINE(GPIOJ, 12)
|
||||
# define J13 PAL_LINE(GPIOJ, 13)
|
||||
# define J14 PAL_LINE(GPIOJ, 14)
|
||||
# define J15 PAL_LINE(GPIOJ, 15)
|
||||
// Keyboards can `#define KEYBOARD_REQUIRES_GPIOK` if they need to access GPIO-K pins. These conflict with a whole
|
||||
// bunch of layout definitions, so it's intentionally left out unless absolutely required -- in that case, the
|
||||
// keyboard designer should use a different symbol when defining their layout macros.
|
||||
# ifdef KEYBOARD_REQUIRES_GPIOK
|
||||
# define K0 PAL_LINE(GPIOK, 0)
|
||||
# define K1 PAL_LINE(GPIOK, 1)
|
||||
# define K2 PAL_LINE(GPIOK, 2)
|
||||
# define K3 PAL_LINE(GPIOK, 3)
|
||||
# define K4 PAL_LINE(GPIOK, 4)
|
||||
# define K5 PAL_LINE(GPIOK, 5)
|
||||
# define K6 PAL_LINE(GPIOK, 6)
|
||||
# define K7 PAL_LINE(GPIOK, 7)
|
||||
# define K8 PAL_LINE(GPIOK, 8)
|
||||
# define K9 PAL_LINE(GPIOK, 9)
|
||||
# define K10 PAL_LINE(GPIOK, 10)
|
||||
# define K11 PAL_LINE(GPIOK, 11)
|
||||
# define K12 PAL_LINE(GPIOK, 12)
|
||||
# define K13 PAL_LINE(GPIOK, 13)
|
||||
# define K14 PAL_LINE(GPIOK, 14)
|
||||
# define K15 PAL_LINE(GPIOK, 15)
|
||||
# endif
|
||||
#endif
|
||||
@@ -1,787 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "wait.h"
|
||||
#include "keycode.h"
|
||||
#include "host.h"
|
||||
#include "keymap.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "timer.h"
|
||||
#include "keyboard.h"
|
||||
#include "bootloader.h"
|
||||
#include "action_layer.h"
|
||||
#include "action_util.h"
|
||||
#include "eeconfig.h"
|
||||
#include "sleep_led.h"
|
||||
#include "led.h"
|
||||
#include "command.h"
|
||||
#include "quantum.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
# include "backlight.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
|
||||
# include "mousekey.h"
|
||||
#endif
|
||||
|
||||
#ifdef AUDIO_ENABLE
|
||||
# include "audio.h"
|
||||
#endif /* AUDIO_ENABLE */
|
||||
|
||||
static bool command_common(uint8_t code);
|
||||
static void command_common_help(void);
|
||||
static void print_version(void);
|
||||
static void print_status(void);
|
||||
static bool command_console(uint8_t code);
|
||||
static void command_console_help(void);
|
||||
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
|
||||
static bool mousekey_console(uint8_t code);
|
||||
static void mousekey_console_help(void);
|
||||
#endif
|
||||
|
||||
static void switch_default_layer(uint8_t layer);
|
||||
|
||||
command_state_t command_state = ONESHOT;
|
||||
|
||||
bool command_proc(uint8_t code) {
|
||||
switch (command_state) {
|
||||
case ONESHOT:
|
||||
if (!IS_COMMAND()) return false;
|
||||
return (command_extra(code) || command_common(code));
|
||||
break;
|
||||
case CONSOLE:
|
||||
if (IS_COMMAND())
|
||||
return (command_extra(code) || command_common(code));
|
||||
else
|
||||
return (command_console_extra(code) || command_console(code));
|
||||
break;
|
||||
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
|
||||
case MOUSEKEY:
|
||||
mousekey_console(code);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
command_state = ONESHOT;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO: Refactoring is needed. */
|
||||
/* This allows to define extra commands. return false when not processed. */
|
||||
bool command_extra(uint8_t code) __attribute__((weak));
|
||||
bool command_extra(uint8_t code) {
|
||||
(void)code;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool command_console_extra(uint8_t code) __attribute__((weak));
|
||||
bool command_console_extra(uint8_t code) {
|
||||
(void)code;
|
||||
return false;
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Command common
|
||||
***********************************************************/
|
||||
static void command_common_help(void) {
|
||||
print("\n\t- Magic -\n" STR(MAGIC_KEY_DEBUG) ": Debug Message Toggle\n" STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle - Show keypresses in matrix grid\n" STR(MAGIC_KEY_DEBUG_KBD) ": Keyboard Debug Toggle - Show keypress report\n" STR(MAGIC_KEY_DEBUG_MOUSE) ": Debug Mouse Toggle\n" STR(MAGIC_KEY_VERSION) ": Version\n" STR(MAGIC_KEY_STATUS) ": Status\n" STR(MAGIC_KEY_CONSOLE) ": Activate Console Mode\n"
|
||||
|
||||
#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
STR(MAGIC_KEY_LAYER0) ": Switch to Layer 0\n" STR(MAGIC_KEY_LAYER1) ": Switch to Layer 1\n" STR(MAGIC_KEY_LAYER2) ": Switch to Layer 2\n" STR(MAGIC_KEY_LAYER3) ": Switch to Layer 3\n" STR(MAGIC_KEY_LAYER4) ": Switch to Layer 4\n" STR(MAGIC_KEY_LAYER5) ": Switch to Layer 5\n" STR(MAGIC_KEY_LAYER6) ": Switch to Layer 6\n" STR(MAGIC_KEY_LAYER7) ": Switch to Layer 7\n" STR(MAGIC_KEY_LAYER8) ": Switch to Layer 8\n" STR(MAGIC_KEY_LAYER9) ": Switch to Layer 9\n"
|
||||
#endif
|
||||
|
||||
#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
"F1-F10: Switch to Layer 0-9 (F10 = L0)\n"
|
||||
#endif
|
||||
|
||||
#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
"0-9: Switch to Layer 0-9\n"
|
||||
#endif
|
||||
|
||||
STR(MAGIC_KEY_LAYER0_ALT) ": Switch to Layer 0 (alternate)\n"
|
||||
|
||||
STR(MAGIC_KEY_BOOTLOADER) ": Jump to Bootloader\n" STR(MAGIC_KEY_BOOTLOADER_ALT) ": Jump to Bootloader (alternate)\n"
|
||||
|
||||
#ifdef KEYBOARD_LOCK_ENABLE
|
||||
STR(MAGIC_KEY_LOCK) ": Lock Keyboard\n"
|
||||
#endif
|
||||
|
||||
STR(MAGIC_KEY_EEPROM) ": Print EEPROM Settings\n" STR(MAGIC_KEY_EEPROM_CLEAR) ": Clear EEPROM\n"
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
STR(MAGIC_KEY_NKRO) ": NKRO Toggle\n"
|
||||
#endif
|
||||
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
STR(MAGIC_KEY_SLEEP_LED) ": Sleep LED Test\n"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
static void print_version(void) {
|
||||
// print version & information
|
||||
print("\n\t- Version -\n");
|
||||
print("DESC: " STR(DESCRIPTION) "\n");
|
||||
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
|
||||
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
|
||||
"VER: " STR(DEVICE_VER) "\n");
|
||||
print("BUILD: (" __DATE__ ")\n");
|
||||
#ifndef SKIP_VERSION
|
||||
# ifdef PROTOCOL_CHIBIOS
|
||||
print("CHIBIOS: " STR(CHIBIOS_VERSION) ", CONTRIB: " STR(CHIBIOS_CONTRIB_VERSION) "\n");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* build options */
|
||||
print("OPTIONS:"
|
||||
|
||||
#ifdef PROTOCOL_LUFA
|
||||
" LUFA"
|
||||
#endif
|
||||
#ifdef PROTOCOL_VUSB
|
||||
" VUSB"
|
||||
#endif
|
||||
#ifdef BOOTMAGIC_ENABLE
|
||||
" BOOTMAGIC"
|
||||
#endif
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
" MOUSEKEY"
|
||||
#endif
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
" EXTRAKEY"
|
||||
#endif
|
||||
#ifdef CONSOLE_ENABLE
|
||||
" CONSOLE"
|
||||
#endif
|
||||
#ifdef COMMAND_ENABLE
|
||||
" COMMAND"
|
||||
#endif
|
||||
#ifdef NKRO_ENABLE
|
||||
" NKRO"
|
||||
#endif
|
||||
#ifdef LTO_ENABLE
|
||||
" LTO"
|
||||
#endif
|
||||
|
||||
" " STR(BOOTLOADER_SIZE) "\n");
|
||||
|
||||
print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
|
||||
#if defined(__AVR__)
|
||||
" AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR_ARCH: avr" STR(__AVR_ARCH__)
|
||||
#endif
|
||||
"\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void print_status(void) {
|
||||
print("\n\t- Status -\n");
|
||||
|
||||
print_val_hex8(host_keyboard_leds());
|
||||
#ifndef PROTOCOL_VUSB
|
||||
// these aren't set on the V-USB protocol, so we just ignore them for now
|
||||
print_val_hex8(keyboard_protocol);
|
||||
print_val_hex8(keyboard_idle);
|
||||
#endif
|
||||
#ifdef NKRO_ENABLE
|
||||
print_val_hex8(keymap_config.nkro);
|
||||
#endif
|
||||
print_val_hex32(timer_read32());
|
||||
return;
|
||||
}
|
||||
|
||||
static void print_eeconfig(void) {
|
||||
// Print these variables if NO_PRINT or USER_PRINT are not defined.
|
||||
#if !defined(NO_PRINT) && !defined(USER_PRINT)
|
||||
|
||||
print("default_layer: ");
|
||||
print_dec(eeconfig_read_default_layer());
|
||||
print("\n");
|
||||
|
||||
debug_config_t dc;
|
||||
dc.raw = eeconfig_read_debug();
|
||||
print("debug_config.raw: ");
|
||||
print_hex8(dc.raw);
|
||||
print("\n");
|
||||
print(".enable: ");
|
||||
print_dec(dc.enable);
|
||||
print("\n");
|
||||
print(".matrix: ");
|
||||
print_dec(dc.matrix);
|
||||
print("\n");
|
||||
print(".keyboard: ");
|
||||
print_dec(dc.keyboard);
|
||||
print("\n");
|
||||
print(".mouse: ");
|
||||
print_dec(dc.mouse);
|
||||
print("\n");
|
||||
|
||||
keymap_config_t kc;
|
||||
kc.raw = eeconfig_read_keymap();
|
||||
print("keymap_config.raw: ");
|
||||
print_hex8(kc.raw);
|
||||
print("\n");
|
||||
print(".swap_control_capslock: ");
|
||||
print_dec(kc.swap_control_capslock);
|
||||
print("\n");
|
||||
print(".capslock_to_control: ");
|
||||
print_dec(kc.capslock_to_control);
|
||||
print("\n");
|
||||
print(".swap_lctl_lgui: ");
|
||||
print_dec(kc.swap_lctl_lgui);
|
||||
print("\n");
|
||||
print(".swap_rctl_rgui: ");
|
||||
print_dec(kc.swap_rctl_rgui);
|
||||
print("\n");
|
||||
print(".swap_lalt_lgui: ");
|
||||
print_dec(kc.swap_lalt_lgui);
|
||||
print("\n");
|
||||
print(".swap_ralt_rgui: ");
|
||||
print_dec(kc.swap_ralt_rgui);
|
||||
print("\n");
|
||||
print(".no_gui: ");
|
||||
print_dec(kc.no_gui);
|
||||
print("\n");
|
||||
print(".swap_grave_esc: ");
|
||||
print_dec(kc.swap_grave_esc);
|
||||
print("\n");
|
||||
print(".swap_backslash_backspace: ");
|
||||
print_dec(kc.swap_backslash_backspace);
|
||||
print("\n");
|
||||
print(".nkro: ");
|
||||
print_dec(kc.nkro);
|
||||
print("\n");
|
||||
|
||||
# ifdef BACKLIGHT_ENABLE
|
||||
backlight_config_t bc;
|
||||
bc.raw = eeconfig_read_backlight();
|
||||
print("backlight_config.raw: ");
|
||||
print_hex8(bc.raw);
|
||||
print("\n");
|
||||
print(".enable: ");
|
||||
print_dec(bc.enable);
|
||||
print("\n");
|
||||
print(".level: ");
|
||||
print_dec(bc.level);
|
||||
print("\n");
|
||||
# endif /* BACKLIGHT_ENABLE */
|
||||
|
||||
#endif /* !NO_PRINT */
|
||||
}
|
||||
|
||||
static bool command_common(uint8_t code) {
|
||||
#ifdef KEYBOARD_LOCK_ENABLE
|
||||
static host_driver_t *host_driver = 0;
|
||||
#endif
|
||||
|
||||
switch (code) {
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
|
||||
// test breathing sleep LED
|
||||
case MAGIC_KC(MAGIC_KEY_SLEEP_LED):
|
||||
print("Sleep LED Test\n");
|
||||
sleep_led_toggle();
|
||||
led_set(host_keyboard_leds());
|
||||
break;
|
||||
#endif
|
||||
|
||||
// print stored eeprom config
|
||||
case MAGIC_KC(MAGIC_KEY_EEPROM):
|
||||
print("eeconfig:\n");
|
||||
print_eeconfig();
|
||||
break;
|
||||
|
||||
// clear eeprom
|
||||
case MAGIC_KC(MAGIC_KEY_EEPROM_CLEAR):
|
||||
print("Clearing EEPROM\n");
|
||||
eeconfig_init();
|
||||
break;
|
||||
|
||||
#ifdef KEYBOARD_LOCK_ENABLE
|
||||
|
||||
// lock/unlock keyboard
|
||||
case MAGIC_KC(MAGIC_KEY_LOCK):
|
||||
if (host_get_driver()) {
|
||||
host_driver = host_get_driver();
|
||||
clear_keyboard();
|
||||
host_set_driver(0);
|
||||
print("Locked.\n");
|
||||
} else {
|
||||
host_set_driver(host_driver);
|
||||
print("Unlocked.\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
// print help
|
||||
case MAGIC_KC(MAGIC_KEY_HELP):
|
||||
case MAGIC_KC(MAGIC_KEY_HELP_ALT):
|
||||
command_common_help();
|
||||
break;
|
||||
|
||||
// activate console
|
||||
case MAGIC_KC(MAGIC_KEY_CONSOLE):
|
||||
debug_matrix = false;
|
||||
debug_keyboard = false;
|
||||
debug_mouse = false;
|
||||
debug_enable = false;
|
||||
command_console_help();
|
||||
print("C> ");
|
||||
command_state = CONSOLE;
|
||||
break;
|
||||
|
||||
// jump to bootloader
|
||||
case MAGIC_KC(MAGIC_KEY_BOOTLOADER):
|
||||
case MAGIC_KC(MAGIC_KEY_BOOTLOADER_ALT):
|
||||
print("\n\nJumping to bootloader... ");
|
||||
reset_keyboard();
|
||||
break;
|
||||
|
||||
// debug toggle
|
||||
case MAGIC_KC(MAGIC_KEY_DEBUG):
|
||||
debug_enable = !debug_enable;
|
||||
if (debug_enable) {
|
||||
print("\ndebug: on\n");
|
||||
} else {
|
||||
print("\ndebug: off\n");
|
||||
debug_matrix = false;
|
||||
debug_keyboard = false;
|
||||
debug_mouse = false;
|
||||
}
|
||||
break;
|
||||
|
||||
// debug matrix toggle
|
||||
case MAGIC_KC(MAGIC_KEY_DEBUG_MATRIX):
|
||||
debug_matrix = !debug_matrix;
|
||||
if (debug_matrix) {
|
||||
print("\nmatrix: on\n");
|
||||
debug_enable = true;
|
||||
} else {
|
||||
print("\nmatrix: off\n");
|
||||
}
|
||||
break;
|
||||
|
||||
// debug keyboard toggle
|
||||
case MAGIC_KC(MAGIC_KEY_DEBUG_KBD):
|
||||
debug_keyboard = !debug_keyboard;
|
||||
if (debug_keyboard) {
|
||||
print("\nkeyboard: on\n");
|
||||
debug_enable = true;
|
||||
} else {
|
||||
print("\nkeyboard: off\n");
|
||||
}
|
||||
break;
|
||||
|
||||
// debug mouse toggle
|
||||
case MAGIC_KC(MAGIC_KEY_DEBUG_MOUSE):
|
||||
debug_mouse = !debug_mouse;
|
||||
if (debug_mouse) {
|
||||
print("\nmouse: on\n");
|
||||
debug_enable = true;
|
||||
} else {
|
||||
print("\nmouse: off\n");
|
||||
}
|
||||
break;
|
||||
|
||||
// print version
|
||||
case MAGIC_KC(MAGIC_KEY_VERSION):
|
||||
print_version();
|
||||
break;
|
||||
|
||||
// print status
|
||||
case MAGIC_KC(MAGIC_KEY_STATUS):
|
||||
print_status();
|
||||
break;
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
|
||||
// NKRO toggle
|
||||
case MAGIC_KC(MAGIC_KEY_NKRO):
|
||||
clear_keyboard(); // clear to prevent stuck keys
|
||||
keymap_config.nkro = !keymap_config.nkro;
|
||||
if (keymap_config.nkro) {
|
||||
print("NKRO: on\n");
|
||||
} else {
|
||||
print("NKRO: off\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
// switch layers
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER0_ALT):
|
||||
switch_default_layer(0);
|
||||
break;
|
||||
|
||||
#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER0):
|
||||
switch_default_layer(0);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER1):
|
||||
switch_default_layer(1);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER2):
|
||||
switch_default_layer(2);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER3):
|
||||
switch_default_layer(3);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER4):
|
||||
switch_default_layer(4);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER5):
|
||||
switch_default_layer(5);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER6):
|
||||
switch_default_layer(6);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER7):
|
||||
switch_default_layer(7);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER8):
|
||||
switch_default_layer(8);
|
||||
break;
|
||||
|
||||
case MAGIC_KC(MAGIC_KEY_LAYER9):
|
||||
switch_default_layer(9);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
|
||||
case KC_F1 ... KC_F9:
|
||||
switch_default_layer((code - KC_F1) + 1);
|
||||
break;
|
||||
case KC_F10:
|
||||
switch_default_layer(0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
|
||||
case KC_1 ... KC_9:
|
||||
switch_default_layer((code - KC_1) + 1);
|
||||
break;
|
||||
case KC_0:
|
||||
switch_default_layer(0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
print("?");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Command console
|
||||
***********************************************************/
|
||||
static void command_console_help(void) {
|
||||
print("\n\t- Console -\n"
|
||||
"ESC/q: quit\n"
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
"m: mousekey\n"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
static bool command_console(uint8_t code) {
|
||||
switch (code) {
|
||||
case KC_H:
|
||||
case KC_SLASH: /* ? */
|
||||
command_console_help();
|
||||
break;
|
||||
case KC_Q:
|
||||
case KC_ESC:
|
||||
command_state = ONESHOT;
|
||||
return false;
|
||||
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
|
||||
case KC_M:
|
||||
mousekey_console_help();
|
||||
print("M> ");
|
||||
command_state = MOUSEKEY;
|
||||
return true;
|
||||
#endif
|
||||
default:
|
||||
print("?");
|
||||
return false;
|
||||
}
|
||||
print("C> ");
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
|
||||
/***********************************************************
|
||||
* Mousekey console
|
||||
***********************************************************/
|
||||
static uint8_t mousekey_param = 0;
|
||||
|
||||
static void mousekey_param_print(void) {
|
||||
// Print these variables if NO_PRINT or USER_PRINT are not defined.
|
||||
# if !defined(NO_PRINT) && !defined(USER_PRINT)
|
||||
print("\n\t- Values -\n");
|
||||
print("1: delay(*10ms): ");
|
||||
pdec(mk_delay);
|
||||
print("\n");
|
||||
print("2: interval(ms): ");
|
||||
pdec(mk_interval);
|
||||
print("\n");
|
||||
print("3: max_speed: ");
|
||||
pdec(mk_max_speed);
|
||||
print("\n");
|
||||
print("4: time_to_max: ");
|
||||
pdec(mk_time_to_max);
|
||||
print("\n");
|
||||
print("5: wheel_max_speed: ");
|
||||
pdec(mk_wheel_max_speed);
|
||||
print("\n");
|
||||
print("6: wheel_time_to_max: ");
|
||||
pdec(mk_wheel_time_to_max);
|
||||
print("\n");
|
||||
# endif /* !NO_PRINT */
|
||||
}
|
||||
|
||||
//#define PRINT_SET_VAL(v) print(#v " = "); print_dec(v); print("\n");
|
||||
# define PRINT_SET_VAL(v) xprintf(# v " = %d\n", (v))
|
||||
static void mousekey_param_inc(uint8_t param, uint8_t inc) {
|
||||
switch (param) {
|
||||
case 1:
|
||||
if (mk_delay + inc < UINT8_MAX)
|
||||
mk_delay += inc;
|
||||
else
|
||||
mk_delay = UINT8_MAX;
|
||||
PRINT_SET_VAL(mk_delay);
|
||||
break;
|
||||
case 2:
|
||||
if (mk_interval + inc < UINT8_MAX)
|
||||
mk_interval += inc;
|
||||
else
|
||||
mk_interval = UINT8_MAX;
|
||||
PRINT_SET_VAL(mk_interval);
|
||||
break;
|
||||
case 3:
|
||||
if (mk_max_speed + inc < UINT8_MAX)
|
||||
mk_max_speed += inc;
|
||||
else
|
||||
mk_max_speed = UINT8_MAX;
|
||||
PRINT_SET_VAL(mk_max_speed);
|
||||
break;
|
||||
case 4:
|
||||
if (mk_time_to_max + inc < UINT8_MAX)
|
||||
mk_time_to_max += inc;
|
||||
else
|
||||
mk_time_to_max = UINT8_MAX;
|
||||
PRINT_SET_VAL(mk_time_to_max);
|
||||
break;
|
||||
case 5:
|
||||
if (mk_wheel_max_speed + inc < UINT8_MAX)
|
||||
mk_wheel_max_speed += inc;
|
||||
else
|
||||
mk_wheel_max_speed = UINT8_MAX;
|
||||
PRINT_SET_VAL(mk_wheel_max_speed);
|
||||
break;
|
||||
case 6:
|
||||
if (mk_wheel_time_to_max + inc < UINT8_MAX)
|
||||
mk_wheel_time_to_max += inc;
|
||||
else
|
||||
mk_wheel_time_to_max = UINT8_MAX;
|
||||
PRINT_SET_VAL(mk_wheel_time_to_max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mousekey_param_dec(uint8_t param, uint8_t dec) {
|
||||
switch (param) {
|
||||
case 1:
|
||||
if (mk_delay > dec)
|
||||
mk_delay -= dec;
|
||||
else
|
||||
mk_delay = 0;
|
||||
PRINT_SET_VAL(mk_delay);
|
||||
break;
|
||||
case 2:
|
||||
if (mk_interval > dec)
|
||||
mk_interval -= dec;
|
||||
else
|
||||
mk_interval = 0;
|
||||
PRINT_SET_VAL(mk_interval);
|
||||
break;
|
||||
case 3:
|
||||
if (mk_max_speed > dec)
|
||||
mk_max_speed -= dec;
|
||||
else
|
||||
mk_max_speed = 0;
|
||||
PRINT_SET_VAL(mk_max_speed);
|
||||
break;
|
||||
case 4:
|
||||
if (mk_time_to_max > dec)
|
||||
mk_time_to_max -= dec;
|
||||
else
|
||||
mk_time_to_max = 0;
|
||||
PRINT_SET_VAL(mk_time_to_max);
|
||||
break;
|
||||
case 5:
|
||||
if (mk_wheel_max_speed > dec)
|
||||
mk_wheel_max_speed -= dec;
|
||||
else
|
||||
mk_wheel_max_speed = 0;
|
||||
PRINT_SET_VAL(mk_wheel_max_speed);
|
||||
break;
|
||||
case 6:
|
||||
if (mk_wheel_time_to_max > dec)
|
||||
mk_wheel_time_to_max -= dec;
|
||||
else
|
||||
mk_wheel_time_to_max = 0;
|
||||
PRINT_SET_VAL(mk_wheel_time_to_max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mousekey_console_help(void) {
|
||||
print("\n\t- Mousekey -\n"
|
||||
"ESC/q: quit\n"
|
||||
"1: delay(*10ms)\n"
|
||||
"2: interval(ms)\n"
|
||||
"3: max_speed\n"
|
||||
"4: time_to_max\n"
|
||||
"5: wheel_max_speed\n"
|
||||
"6: wheel_time_to_max\n"
|
||||
"\n"
|
||||
"p: print values\n"
|
||||
"d: set defaults\n"
|
||||
"up: +1\n"
|
||||
"down: -1\n"
|
||||
"pgup: +10\n"
|
||||
"pgdown: -10\n"
|
||||
"\n"
|
||||
"speed = delta * max_speed * (repeat / time_to_max)\n");
|
||||
xprintf("where delta: cursor=%d, wheel=%d\n"
|
||||
"See http://en.wikipedia.org/wiki/Mouse_keys\n",
|
||||
MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA);
|
||||
}
|
||||
|
||||
static bool mousekey_console(uint8_t code) {
|
||||
switch (code) {
|
||||
case KC_H:
|
||||
case KC_SLASH: /* ? */
|
||||
mousekey_console_help();
|
||||
break;
|
||||
case KC_Q:
|
||||
case KC_ESC:
|
||||
if (mousekey_param) {
|
||||
mousekey_param = 0;
|
||||
} else {
|
||||
print("C> ");
|
||||
command_state = CONSOLE;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case KC_P:
|
||||
mousekey_param_print();
|
||||
break;
|
||||
case KC_1:
|
||||
case KC_2:
|
||||
case KC_3:
|
||||
case KC_4:
|
||||
case KC_5:
|
||||
case KC_6:
|
||||
mousekey_param = numkey2num(code);
|
||||
break;
|
||||
case KC_UP:
|
||||
mousekey_param_inc(mousekey_param, 1);
|
||||
break;
|
||||
case KC_DOWN:
|
||||
mousekey_param_dec(mousekey_param, 1);
|
||||
break;
|
||||
case KC_PGUP:
|
||||
mousekey_param_inc(mousekey_param, 10);
|
||||
break;
|
||||
case KC_PGDN:
|
||||
mousekey_param_dec(mousekey_param, 10);
|
||||
break;
|
||||
case KC_D:
|
||||
mk_delay = MOUSEKEY_DELAY / 10;
|
||||
mk_interval = MOUSEKEY_INTERVAL;
|
||||
mk_max_speed = MOUSEKEY_MAX_SPEED;
|
||||
mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
|
||||
mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
|
||||
mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
|
||||
print("set default\n");
|
||||
break;
|
||||
default:
|
||||
print("?");
|
||||
return false;
|
||||
}
|
||||
if (mousekey_param) {
|
||||
xprintf("M%d> ", mousekey_param);
|
||||
} else {
|
||||
print("M>");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************
|
||||
* Utilities
|
||||
***********************************************************/
|
||||
uint8_t numkey2num(uint8_t code) {
|
||||
switch (code) {
|
||||
case KC_1:
|
||||
return 1;
|
||||
case KC_2:
|
||||
return 2;
|
||||
case KC_3:
|
||||
return 3;
|
||||
case KC_4:
|
||||
return 4;
|
||||
case KC_5:
|
||||
return 5;
|
||||
case KC_6:
|
||||
return 6;
|
||||
case KC_7:
|
||||
return 7;
|
||||
case KC_8:
|
||||
return 8;
|
||||
case KC_9:
|
||||
return 9;
|
||||
case KC_0:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void switch_default_layer(uint8_t layer) {
|
||||
xprintf("L%d\n", layer);
|
||||
default_layer_set(1UL << layer);
|
||||
clear_keyboard();
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* FIXME: Add doxygen comments for the behavioral defines in here. */
|
||||
|
||||
/* TODO: Refactoring */
|
||||
typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t;
|
||||
extern command_state_t command_state;
|
||||
|
||||
/* This allows to extend commands. Return false when command is not processed. */
|
||||
bool command_extra(uint8_t code);
|
||||
bool command_console_extra(uint8_t code);
|
||||
|
||||
#ifdef COMMAND_ENABLE
|
||||
uint8_t numkey2num(uint8_t code);
|
||||
bool command_proc(uint8_t code);
|
||||
#else
|
||||
# define command_proc(code) false
|
||||
#endif
|
||||
|
||||
#ifndef IS_COMMAND
|
||||
# define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
# define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
# define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
# define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_HELP
|
||||
# define MAGIC_KEY_HELP H
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_HELP_ALT
|
||||
# define MAGIC_KEY_HELP_ALT SLASH
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_DEBUG
|
||||
# define MAGIC_KEY_DEBUG D
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_DEBUG_MATRIX
|
||||
# define MAGIC_KEY_DEBUG_MATRIX X
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_DEBUG_KBD
|
||||
# define MAGIC_KEY_DEBUG_KBD K
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_DEBUG_MOUSE
|
||||
# define MAGIC_KEY_DEBUG_MOUSE M
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_VERSION
|
||||
# define MAGIC_KEY_VERSION V
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_STATUS
|
||||
# define MAGIC_KEY_STATUS S
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_CONSOLE
|
||||
# define MAGIC_KEY_CONSOLE C
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER0
|
||||
# define MAGIC_KEY_LAYER0 0
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER0_ALT
|
||||
# define MAGIC_KEY_LAYER0_ALT GRAVE
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER1
|
||||
# define MAGIC_KEY_LAYER1 1
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER2
|
||||
# define MAGIC_KEY_LAYER2 2
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER3
|
||||
# define MAGIC_KEY_LAYER3 3
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER4
|
||||
# define MAGIC_KEY_LAYER4 4
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER5
|
||||
# define MAGIC_KEY_LAYER5 5
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER6
|
||||
# define MAGIC_KEY_LAYER6 6
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER7
|
||||
# define MAGIC_KEY_LAYER7 7
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER8
|
||||
# define MAGIC_KEY_LAYER8 8
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LAYER9
|
||||
# define MAGIC_KEY_LAYER9 9
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_BOOTLOADER
|
||||
# define MAGIC_KEY_BOOTLOADER B
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_BOOTLOADER_ALT
|
||||
# define MAGIC_KEY_BOOTLOADER_ALT ESC
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_LOCK
|
||||
# define MAGIC_KEY_LOCK CAPS
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_EEPROM
|
||||
# define MAGIC_KEY_EEPROM E
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_EEPROM_CLEAR
|
||||
# define MAGIC_KEY_EEPROM_CLEAR BSPACE
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_NKRO
|
||||
# define MAGIC_KEY_NKRO N
|
||||
#endif
|
||||
|
||||
#ifndef MAGIC_KEY_SLEEP_LED
|
||||
# define MAGIC_KEY_SLEEP_LED Z
|
||||
|
||||
#endif
|
||||
|
||||
#define XMAGIC_KC(key) KC_##key
|
||||
#define MAGIC_KC(key) XMAGIC_KC(key)
|
||||
@@ -1,24 +1,25 @@
|
||||
#include <stdbool.h>
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "debug.h"
|
||||
|
||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
|
||||
debug_config_t debug_config = {
|
||||
/* GCC Bug 10676 - Using unnamed fields in initializers
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 */
|
||||
#if GCC_VERSION >= 40600
|
||||
.enable = false,
|
||||
.matrix = false,
|
||||
.keyboard = false,
|
||||
.mouse = false,
|
||||
.reserved = 0
|
||||
#else
|
||||
{
|
||||
false, // .enable
|
||||
false, // .matrix
|
||||
false, // .keyboard
|
||||
false, // .mouse
|
||||
0 // .reserved
|
||||
}
|
||||
#endif
|
||||
.enable = false, //
|
||||
.matrix = false, //
|
||||
.keyboard = false, //
|
||||
.mouse = false, //
|
||||
.reserved = 0 //
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifdef ORYX_ENABLE
|
||||
# include "oryx.h"
|
||||
#endif
|
||||
|
||||
#ifdef STM32_EEPROM_ENABLE
|
||||
# include <hal.h>
|
||||
# include "eeprom_stm32.h"
|
||||
@@ -60,19 +61,18 @@ void eeconfig_init_quantum(void) {
|
||||
eeprom_update_byte(EECONFIG_VELOCIKEY, 0);
|
||||
eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
|
||||
eeprom_update_byte(EECONFIG_RGB_MATRIX_SPEED, 0);
|
||||
|
||||
#ifdef ORYX_ENABLE
|
||||
eeconfig_init_oryx();
|
||||
#endif
|
||||
// TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
|
||||
// within the emulated eeprom via dfu-util or another tool
|
||||
#if defined INIT_EE_HANDS_LEFT
|
||||
#pragma message "Faking EE_HANDS for left hand"
|
||||
# pragma message "Faking EE_HANDS for left hand"
|
||||
eeprom_update_byte(EECONFIG_HANDEDNESS, 1);
|
||||
#elif defined INIT_EE_HANDS_RIGHT
|
||||
#pragma message "Faking EE_HANDS for right hand"
|
||||
# pragma message "Faking EE_HANDS for right hand"
|
||||
eeprom_update_byte(EECONFIG_HANDEDNESS, 0);
|
||||
#endif
|
||||
#ifdef ORYX_ENABLE
|
||||
eeconfig_init_oryx();
|
||||
#endif
|
||||
|
||||
#if defined(HAPTIC_ENABLE)
|
||||
haptic_reset();
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef EECONFIG_MAGIC_NUMBER
|
||||
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEF
|
||||
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEB // When changing, decrement this value to avoid future re-init issues
|
||||
#endif
|
||||
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
|
||||
|
||||
|
||||
22
tmk_core/common/gpio.h
Normal file
22
tmk_core/common/gpio.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "pin_defs.h"
|
||||
|
||||
#if __has_include_next("gpio.h")
|
||||
# include_next "gpio.h" /* Include the platforms gpio.h */
|
||||
#endif
|
||||
@@ -41,7 +41,7 @@ uint8_t host_keyboard_leds(void) {
|
||||
}
|
||||
|
||||
led_t host_keyboard_led_state(void) {
|
||||
if (!driver) return (led_t) {0};
|
||||
if (!driver) return (led_t){0};
|
||||
return (led_t)((*driver->keyboard_leds)());
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "led.h"
|
||||
#include "keycode.h"
|
||||
#include "timer.h"
|
||||
#include "sync_timer.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "command.h"
|
||||
@@ -53,15 +54,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
# include "rgblight.h"
|
||||
#endif
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
# include "rgb_matrix.h"
|
||||
#endif
|
||||
#ifdef ENCODER_ENABLE
|
||||
# include "encoder.h"
|
||||
#endif
|
||||
#ifdef STENO_ENABLE
|
||||
# include "process_steno.h"
|
||||
#endif
|
||||
#ifdef FAUXCLICKY_ENABLE
|
||||
# include "fauxclicky.h"
|
||||
#endif
|
||||
#ifdef SERIAL_LINK_ENABLE
|
||||
# include "serial_link/system/serial_link.h"
|
||||
#endif
|
||||
@@ -96,10 +97,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# include "dip_switch.h"
|
||||
#endif
|
||||
|
||||
static uint32_t last_input_modification_time = 0;
|
||||
uint32_t last_input_activity_time(void) { return last_input_modification_time; }
|
||||
uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); }
|
||||
|
||||
static uint32_t last_matrix_modification_time = 0;
|
||||
uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
|
||||
uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
|
||||
void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); }
|
||||
|
||||
static uint32_t last_encoder_modification_time = 0;
|
||||
uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; }
|
||||
uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); }
|
||||
void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); }
|
||||
|
||||
// Only enable this if console is enabled to print to
|
||||
#if defined(DEBUG_MATRIX_SCAN_RATE)
|
||||
static uint32_t matrix_timer = 0;
|
||||
static uint32_t matrix_scan_count = 0;
|
||||
static uint32_t matrix_timer = 0;
|
||||
static uint32_t matrix_scan_count = 0;
|
||||
static uint32_t last_matrix_scan_count = 0;
|
||||
|
||||
void matrix_scan_perf_task(void) {
|
||||
@@ -108,17 +123,15 @@ void matrix_scan_perf_task(void) {
|
||||
uint32_t timer_now = timer_read32();
|
||||
if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) {
|
||||
# if defined(CONSOLE_ENABLE)
|
||||
dprintf("matrix scan frequency: %d\n", matrix_scan_count);
|
||||
dprintf("matrix scan frequency: %lu\n", matrix_scan_count);
|
||||
# endif
|
||||
last_matrix_scan_count = matrix_scan_count;
|
||||
matrix_timer = timer_now;
|
||||
matrix_scan_count = 0;
|
||||
matrix_timer = timer_now;
|
||||
matrix_scan_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t get_matrix_scan_rate(void) {
|
||||
return last_matrix_scan_count;
|
||||
}
|
||||
uint32_t get_matrix_scan_rate(void) { return last_matrix_scan_count; }
|
||||
#else
|
||||
# define matrix_scan_perf_task()
|
||||
#endif
|
||||
@@ -173,6 +186,9 @@ void disable_jtag(void) {
|
||||
#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
MCUCR |= _BV(JTD);
|
||||
MCUCR |= _BV(JTD);
|
||||
#elif defined(__AVR_ATmega32A__)
|
||||
MCUCSR |= _BV(JTD);
|
||||
MCUCSR |= _BV(JTD);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -213,7 +229,10 @@ __attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void keyboard_setup(void) {
|
||||
#ifndef NO_JTAG_DISABLE
|
||||
disable_jtag();
|
||||
#endif
|
||||
print_set_sendchar(sendchar);
|
||||
matrix_setup();
|
||||
keyboard_pre_init_kb();
|
||||
}
|
||||
@@ -257,6 +276,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
|
||||
*/
|
||||
void keyboard_init(void) {
|
||||
timer_init();
|
||||
sync_timer_init();
|
||||
matrix_init();
|
||||
#ifdef VIA_ENABLE
|
||||
via_init();
|
||||
@@ -293,9 +313,6 @@ void keyboard_init(void) {
|
||||
#ifdef STENO_ENABLE
|
||||
steno_init();
|
||||
#endif
|
||||
#ifdef FAUXCLICKY_ENABLE
|
||||
fauxclicky_init();
|
||||
#endif
|
||||
#ifdef POINTING_DEVICE_ENABLE
|
||||
pointing_device_init();
|
||||
#endif
|
||||
@@ -314,6 +331,17 @@ void keyboard_init(void) {
|
||||
keyboard_post_init_kb(); /* Always keep this last */
|
||||
}
|
||||
|
||||
/** \brief key_event_task
|
||||
*
|
||||
* This function is responsible for calling into other systems when they need to respond to electrical switch press events.
|
||||
* This is differnet than keycode events as no layer processing, or filtering occurs.
|
||||
*/
|
||||
void switch_events(uint8_t row, uint8_t col, bool pressed) {
|
||||
#if defined(RGB_MATRIX_ENABLE)
|
||||
process_rgb_matrix(row, col, pressed);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Keyboard task: Do keyboard routine jobs
|
||||
*
|
||||
* Do routine keyboard jobs:
|
||||
@@ -334,42 +362,45 @@ void keyboard_task(void) {
|
||||
#ifdef QMK_KEYS_PER_SCAN
|
||||
uint8_t keys_processed = 0;
|
||||
#endif
|
||||
#ifdef ENCODER_ENABLE
|
||||
bool encoders_changed = false;
|
||||
#endif
|
||||
|
||||
housekeeping_task_kb();
|
||||
housekeeping_task_user();
|
||||
|
||||
#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT)
|
||||
uint8_t ret = matrix_scan();
|
||||
#else
|
||||
matrix_scan();
|
||||
#endif
|
||||
uint8_t matrix_changed = matrix_scan();
|
||||
if (matrix_changed) last_matrix_activity_trigger();
|
||||
|
||||
if (should_process_keypress()) {
|
||||
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
|
||||
matrix_row = matrix_get_row(r);
|
||||
matrix_change = matrix_row ^ matrix_prev[r];
|
||||
if (matrix_change) {
|
||||
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
|
||||
matrix_row = matrix_get_row(r);
|
||||
matrix_change = matrix_row ^ matrix_prev[r];
|
||||
if (matrix_change) {
|
||||
#ifdef MATRIX_HAS_GHOST
|
||||
if (has_ghost_in_row(r, matrix_row)) {
|
||||
continue;
|
||||
}
|
||||
if (has_ghost_in_row(r, matrix_row)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (debug_matrix) matrix_print();
|
||||
matrix_row_t col_mask = 1;
|
||||
for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) {
|
||||
if (matrix_change & col_mask) {
|
||||
if (debug_matrix) matrix_print();
|
||||
matrix_row_t col_mask = 1;
|
||||
for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) {
|
||||
if (matrix_change & col_mask) {
|
||||
if (should_process_keypress()) {
|
||||
action_exec((keyevent_t){
|
||||
.key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */
|
||||
});
|
||||
// record a processed key
|
||||
matrix_prev[r] ^= col_mask;
|
||||
#ifdef QMK_KEYS_PER_SCAN
|
||||
// only jump out if we have processed "enough" keys.
|
||||
if (++keys_processed >= QMK_KEYS_PER_SCAN)
|
||||
#endif
|
||||
// process a key per task call
|
||||
goto MATRIX_LOOP_END;
|
||||
}
|
||||
// record a processed key
|
||||
matrix_prev[r] ^= col_mask;
|
||||
|
||||
switch_events(r, c, (matrix_row & col_mask));
|
||||
|
||||
#ifdef QMK_KEYS_PER_SCAN
|
||||
// only jump out if we have processed "enough" keys.
|
||||
if (++keys_processed >= QMK_KEYS_PER_SCAN)
|
||||
#endif
|
||||
// process a key per task call
|
||||
goto MATRIX_LOOP_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,6 +422,10 @@ MATRIX_LOOP_END:
|
||||
rgblight_task();
|
||||
#endif
|
||||
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
rgb_matrix_task();
|
||||
#endif
|
||||
|
||||
#if defined(BACKLIGHT_ENABLE)
|
||||
# if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)
|
||||
backlight_task();
|
||||
@@ -398,7 +433,8 @@ MATRIX_LOOP_END:
|
||||
#endif
|
||||
|
||||
#ifdef ENCODER_ENABLE
|
||||
encoder_read();
|
||||
encoders_changed = encoder_read();
|
||||
if (encoders_changed) last_encoder_activity_trigger();
|
||||
#endif
|
||||
|
||||
#ifdef QWIIC_ENABLE
|
||||
@@ -408,8 +444,12 @@ MATRIX_LOOP_END:
|
||||
#ifdef OLED_DRIVER_ENABLE
|
||||
oled_task();
|
||||
# ifndef OLED_DISABLE_TIMEOUT
|
||||
// Wake up oled if user is using those fabulous keys!
|
||||
if (ret) oled_on();
|
||||
// Wake up oled if user is using those fabulous keys or spinning those encoders!
|
||||
# ifdef ENCODER_ENABLE
|
||||
if (matrix_changed || encoders_changed) oled_on();
|
||||
# else
|
||||
if (matrix_changed) oled_on();
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -52,8 +52,6 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
|
||||
#define TICK \
|
||||
(keyevent_t) { .key = (keypos_t){.row = 255, .col = 255}, .pressed = false, .time = (timer_read() | 1) }
|
||||
|
||||
void disable_jtag(void);
|
||||
|
||||
/* it runs once at early stage of startup before keyboard_init. */
|
||||
void keyboard_setup(void);
|
||||
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
|
||||
@@ -75,6 +73,15 @@ void keyboard_post_init_user(void);
|
||||
void housekeeping_task_kb(void);
|
||||
void housekeeping_task_user(void);
|
||||
|
||||
uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity
|
||||
uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity
|
||||
|
||||
uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity
|
||||
uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
|
||||
|
||||
uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity
|
||||
uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity
|
||||
|
||||
uint32_t get_matrix_scan_rate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
|
||||
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
|
||||
#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5)
|
||||
#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
|
||||
#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
|
||||
#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
|
||||
|
||||
@@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define KC_BTN3 KC_MS_BTN3
|
||||
#define KC_BTN4 KC_MS_BTN4
|
||||
#define KC_BTN5 KC_MS_BTN5
|
||||
#define KC_BTN6 KC_MS_BTN6
|
||||
#define KC_BTN7 KC_MS_BTN7
|
||||
#define KC_BTN8 KC_MS_BTN8
|
||||
#define KC_WH_U KC_MS_WH_UP
|
||||
#define KC_WH_D KC_MS_WH_DOWN
|
||||
#define KC_WH_L KC_MS_WH_LEFT
|
||||
@@ -520,16 +523,29 @@ enum internal_special_keycodes {
|
||||
};
|
||||
|
||||
enum mouse_keys {
|
||||
/* Mouse Buttons */
|
||||
/* Mouse Buttons */
|
||||
#ifdef VIA_ENABLE
|
||||
KC_MS_UP = 0xF0,
|
||||
#else
|
||||
KC_MS_UP = 0xED,
|
||||
#endif
|
||||
KC_MS_DOWN,
|
||||
KC_MS_LEFT,
|
||||
KC_MS_RIGHT,
|
||||
KC_MS_RIGHT, // 0xF0
|
||||
KC_MS_BTN1,
|
||||
KC_MS_BTN2,
|
||||
KC_MS_BTN3,
|
||||
KC_MS_BTN4,
|
||||
KC_MS_BTN5,
|
||||
#ifdef VIA_ENABLE
|
||||
KC_MS_BTN6 = KC_MS_BTN5,
|
||||
KC_MS_BTN7 = KC_MS_BTN5,
|
||||
KC_MS_BTN8 = KC_MS_BTN5,
|
||||
#else
|
||||
KC_MS_BTN6,
|
||||
KC_MS_BTN7,
|
||||
KC_MS_BTN8,
|
||||
#endif
|
||||
|
||||
/* Mouse Wheel */
|
||||
KC_MS_WH_UP,
|
||||
@@ -540,5 +556,5 @@ enum mouse_keys {
|
||||
/* Acceleration */
|
||||
KC_MS_ACCEL0,
|
||||
KC_MS_ACCEL1,
|
||||
KC_MS_ACCEL2
|
||||
KC_MS_ACCEL2 // 0xFF
|
||||
};
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* FIXME: Add doxygen comments here. */
|
||||
|
||||
/* keyboard LEDs */
|
||||
#define USB_LED_NUM_LOCK 0
|
||||
#define USB_LED_CAPS_LOCK 1
|
||||
#define USB_LED_SCROLL_LOCK 2
|
||||
#define USB_LED_COMPOSE 3
|
||||
#define USB_LED_KANA 4
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
uint8_t raw;
|
||||
struct {
|
||||
bool num_lock : 1;
|
||||
bool caps_lock : 1;
|
||||
bool scroll_lock : 1;
|
||||
bool compose : 1;
|
||||
bool kana : 1;
|
||||
uint8_t reserved : 3;
|
||||
};
|
||||
} led_t;
|
||||
|
||||
void led_set(uint8_t usb_led);
|
||||
|
||||
void led_init_ports(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
9
tmk_core/common/lib_printf.mk
Normal file
9
tmk_core/common/lib_printf.mk
Normal file
@@ -0,0 +1,9 @@
|
||||
PRINTF_PATH = $(LIB_PATH)/printf
|
||||
|
||||
TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c
|
||||
TMK_COMMON_SRC += $(COMMON_DIR)/printf.c
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG
|
||||
TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T
|
||||
VPATH += $(PRINTF_PATH)
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if (MATRIX_COLS <= 8)
|
||||
typedef uint8_t matrix_row_t;
|
||||
#elif (MATRIX_COLS <= 16)
|
||||
typedef uint16_t matrix_row_t;
|
||||
#elif (MATRIX_COLS <= 32)
|
||||
typedef uint32_t matrix_row_t;
|
||||
#else
|
||||
# error "MATRIX_COLS: invalid value"
|
||||
#endif
|
||||
|
||||
#define MATRIX_ROW_SHIFTER ((matrix_row_t)1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* number of matrix rows */
|
||||
uint8_t matrix_rows(void);
|
||||
/* number of matrix columns */
|
||||
uint8_t matrix_cols(void);
|
||||
/* should be called at early stage of startup before matrix_init.(optional) */
|
||||
void matrix_setup(void);
|
||||
/* intialize matrix for scaning. */
|
||||
void matrix_init(void);
|
||||
/* scan all key states on matrix */
|
||||
uint8_t matrix_scan(void);
|
||||
/* whether modified from previous scan. used after matrix_scan. */
|
||||
bool matrix_is_modified(void) __attribute__((deprecated));
|
||||
/* whether a switch is on */
|
||||
bool matrix_is_on(uint8_t row, uint8_t col);
|
||||
/* matrix state on row */
|
||||
matrix_row_t matrix_get_row(uint8_t row);
|
||||
/* print matrix for debug */
|
||||
void matrix_print(void);
|
||||
/* delay between changing matrix pin state and reading values */
|
||||
void matrix_io_delay(void);
|
||||
|
||||
/* power control */
|
||||
void matrix_power_up(void);
|
||||
void matrix_power_down(void);
|
||||
|
||||
/* executes code for Quantum */
|
||||
void matrix_init_quantum(void);
|
||||
void matrix_scan_quantum(void);
|
||||
|
||||
void matrix_init_kb(void);
|
||||
void matrix_scan_kb(void);
|
||||
|
||||
void matrix_init_user(void);
|
||||
void matrix_scan_user(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,446 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "keycode.h"
|
||||
#include "host.h"
|
||||
#include "timer.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "mousekey.h"
|
||||
|
||||
inline int8_t times_inv_sqrt2(int8_t x) {
|
||||
// 181/256 is pretty close to 1/sqrt(2)
|
||||
// 0.70703125 0.707106781
|
||||
// 1 too small for x=99 and x=198
|
||||
// This ends up being a mult and discard lower 8 bits
|
||||
return (x * 181) >> 8;
|
||||
}
|
||||
|
||||
static report_mouse_t mouse_report = {0};
|
||||
static void mousekey_debug(void);
|
||||
static uint8_t mousekey_accel = 0;
|
||||
static uint8_t mousekey_repeat = 0;
|
||||
static uint8_t mousekey_wheel_repeat = 0;
|
||||
|
||||
#ifndef MK_3_SPEED
|
||||
|
||||
static uint16_t last_timer_c = 0;
|
||||
static uint16_t last_timer_w = 0;
|
||||
|
||||
/*
|
||||
* Mouse keys acceleration algorithm
|
||||
* http://en.wikipedia.org/wiki/Mouse_keys
|
||||
*
|
||||
* speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
|
||||
*/
|
||||
/* milliseconds between the initial key press and first repeated motion event (0-2550) */
|
||||
uint8_t mk_delay = MOUSEKEY_DELAY / 10;
|
||||
/* milliseconds between repeated motion events (0-255) */
|
||||
uint8_t mk_interval = MOUSEKEY_INTERVAL;
|
||||
/* steady speed (in action_delta units) applied each event (0-255) */
|
||||
uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED;
|
||||
/* number of events (count) accelerating to steady speed (0-255) */
|
||||
uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
|
||||
/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */
|
||||
// int8_t mk_curve = 0;
|
||||
/* wheel params */
|
||||
/* milliseconds between the initial key press and first repeated motion event (0-2550) */
|
||||
uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10;
|
||||
/* milliseconds between repeated motion events (0-255) */
|
||||
uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
|
||||
uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
|
||||
uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
|
||||
|
||||
# ifndef MK_COMBINED
|
||||
|
||||
static uint8_t move_unit(void) {
|
||||
uint16_t unit;
|
||||
if (mousekey_accel & (1 << 0)) {
|
||||
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4;
|
||||
} else if (mousekey_accel & (1 << 1)) {
|
||||
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
|
||||
} else if (mousekey_accel & (1 << 2)) {
|
||||
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed);
|
||||
} else if (mousekey_repeat == 0) {
|
||||
unit = MOUSEKEY_MOVE_DELTA;
|
||||
} else if (mousekey_repeat >= mk_time_to_max) {
|
||||
unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
|
||||
} else {
|
||||
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
|
||||
}
|
||||
return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
|
||||
}
|
||||
|
||||
static uint8_t wheel_unit(void) {
|
||||
uint16_t unit;
|
||||
if (mousekey_accel & (1 << 0)) {
|
||||
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4;
|
||||
} else if (mousekey_accel & (1 << 1)) {
|
||||
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
|
||||
} else if (mousekey_accel & (1 << 2)) {
|
||||
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
|
||||
} else if (mousekey_wheel_repeat == 0) {
|
||||
unit = MOUSEKEY_WHEEL_DELTA;
|
||||
} else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) {
|
||||
unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
|
||||
} else {
|
||||
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max;
|
||||
}
|
||||
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
|
||||
}
|
||||
|
||||
# else /* #ifndef MK_COMBINED */
|
||||
|
||||
static uint8_t move_unit(void) {
|
||||
uint16_t unit;
|
||||
if (mousekey_accel & (1 << 0)) {
|
||||
unit = 1;
|
||||
} else if (mousekey_accel & (1 << 1)) {
|
||||
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
|
||||
} else if (mousekey_accel & (1 << 2)) {
|
||||
unit = MOUSEKEY_MOVE_MAX;
|
||||
} else if (mousekey_repeat == 0) {
|
||||
unit = MOUSEKEY_MOVE_DELTA;
|
||||
} else if (mousekey_repeat >= mk_time_to_max) {
|
||||
unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
|
||||
} else {
|
||||
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
|
||||
}
|
||||
return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
|
||||
}
|
||||
|
||||
static uint8_t wheel_unit(void) {
|
||||
uint16_t unit;
|
||||
if (mousekey_accel & (1 << 0)) {
|
||||
unit = 1;
|
||||
} else if (mousekey_accel & (1 << 1)) {
|
||||
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
|
||||
} else if (mousekey_accel & (1 << 2)) {
|
||||
unit = MOUSEKEY_WHEEL_MAX;
|
||||
} else if (mousekey_repeat == 0) {
|
||||
unit = MOUSEKEY_WHEEL_DELTA;
|
||||
} else if (mousekey_repeat >= mk_wheel_time_to_max) {
|
||||
unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
|
||||
} else {
|
||||
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
|
||||
}
|
||||
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
|
||||
}
|
||||
|
||||
# endif /* #ifndef MK_COMBINED */
|
||||
|
||||
void mousekey_task(void) {
|
||||
// report cursor and scroll movement independently
|
||||
report_mouse_t const tmpmr = mouse_report;
|
||||
|
||||
mouse_report.x = 0;
|
||||
mouse_report.y = 0;
|
||||
mouse_report.v = 0;
|
||||
mouse_report.h = 0;
|
||||
|
||||
if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {
|
||||
if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
|
||||
if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1);
|
||||
if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1);
|
||||
|
||||
/* diagonal move [1/sqrt(2)] */
|
||||
if (mouse_report.x && mouse_report.y) {
|
||||
mouse_report.x = times_inv_sqrt2(mouse_report.x);
|
||||
if (mouse_report.x == 0) {
|
||||
mouse_report.x = 1;
|
||||
}
|
||||
mouse_report.y = times_inv_sqrt2(mouse_report.y);
|
||||
if (mouse_report.y == 0) {
|
||||
mouse_report.y = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
|
||||
if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++;
|
||||
if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1);
|
||||
if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1);
|
||||
|
||||
/* diagonal move [1/sqrt(2)] */
|
||||
if (mouse_report.v && mouse_report.h) {
|
||||
mouse_report.v = times_inv_sqrt2(mouse_report.v);
|
||||
if (mouse_report.v == 0) {
|
||||
mouse_report.v = 1;
|
||||
}
|
||||
mouse_report.h = times_inv_sqrt2(mouse_report.h);
|
||||
if (mouse_report.h == 0) {
|
||||
mouse_report.h = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
|
||||
mouse_report = tmpmr;
|
||||
}
|
||||
|
||||
void mousekey_on(uint8_t code) {
|
||||
if (code == KC_MS_UP)
|
||||
mouse_report.y = move_unit() * -1;
|
||||
else if (code == KC_MS_DOWN)
|
||||
mouse_report.y = move_unit();
|
||||
else if (code == KC_MS_LEFT)
|
||||
mouse_report.x = move_unit() * -1;
|
||||
else if (code == KC_MS_RIGHT)
|
||||
mouse_report.x = move_unit();
|
||||
else if (code == KC_MS_WH_UP)
|
||||
mouse_report.v = wheel_unit();
|
||||
else if (code == KC_MS_WH_DOWN)
|
||||
mouse_report.v = wheel_unit() * -1;
|
||||
else if (code == KC_MS_WH_LEFT)
|
||||
mouse_report.h = wheel_unit() * -1;
|
||||
else if (code == KC_MS_WH_RIGHT)
|
||||
mouse_report.h = wheel_unit();
|
||||
else if (code == KC_MS_BTN1)
|
||||
mouse_report.buttons |= MOUSE_BTN1;
|
||||
else if (code == KC_MS_BTN2)
|
||||
mouse_report.buttons |= MOUSE_BTN2;
|
||||
else if (code == KC_MS_BTN3)
|
||||
mouse_report.buttons |= MOUSE_BTN3;
|
||||
else if (code == KC_MS_BTN4)
|
||||
mouse_report.buttons |= MOUSE_BTN4;
|
||||
else if (code == KC_MS_BTN5)
|
||||
mouse_report.buttons |= MOUSE_BTN5;
|
||||
else if (code == KC_MS_ACCEL0)
|
||||
mousekey_accel |= (1 << 0);
|
||||
else if (code == KC_MS_ACCEL1)
|
||||
mousekey_accel |= (1 << 1);
|
||||
else if (code == KC_MS_ACCEL2)
|
||||
mousekey_accel |= (1 << 2);
|
||||
}
|
||||
|
||||
void mousekey_off(uint8_t code) {
|
||||
if (code == KC_MS_UP && mouse_report.y < 0)
|
||||
mouse_report.y = 0;
|
||||
else if (code == KC_MS_DOWN && mouse_report.y > 0)
|
||||
mouse_report.y = 0;
|
||||
else if (code == KC_MS_LEFT && mouse_report.x < 0)
|
||||
mouse_report.x = 0;
|
||||
else if (code == KC_MS_RIGHT && mouse_report.x > 0)
|
||||
mouse_report.x = 0;
|
||||
else if (code == KC_MS_WH_UP && mouse_report.v > 0)
|
||||
mouse_report.v = 0;
|
||||
else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
|
||||
mouse_report.v = 0;
|
||||
else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
|
||||
mouse_report.h = 0;
|
||||
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
|
||||
mouse_report.h = 0;
|
||||
else if (code == KC_MS_BTN1)
|
||||
mouse_report.buttons &= ~MOUSE_BTN1;
|
||||
else if (code == KC_MS_BTN2)
|
||||
mouse_report.buttons &= ~MOUSE_BTN2;
|
||||
else if (code == KC_MS_BTN3)
|
||||
mouse_report.buttons &= ~MOUSE_BTN3;
|
||||
else if (code == KC_MS_BTN4)
|
||||
mouse_report.buttons &= ~MOUSE_BTN4;
|
||||
else if (code == KC_MS_BTN5)
|
||||
mouse_report.buttons &= ~MOUSE_BTN5;
|
||||
else if (code == KC_MS_ACCEL0)
|
||||
mousekey_accel &= ~(1 << 0);
|
||||
else if (code == KC_MS_ACCEL1)
|
||||
mousekey_accel &= ~(1 << 1);
|
||||
else if (code == KC_MS_ACCEL2)
|
||||
mousekey_accel &= ~(1 << 2);
|
||||
if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0;
|
||||
if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
|
||||
}
|
||||
|
||||
#else /* #ifndef MK_3_SPEED */
|
||||
|
||||
enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT };
|
||||
# ifndef MK_MOMENTARY_ACCEL
|
||||
static uint8_t mk_speed = mkspd_1;
|
||||
# else
|
||||
static uint8_t mk_speed = mkspd_unmod;
|
||||
static uint8_t mkspd_DEFAULT = mkspd_unmod;
|
||||
# endif
|
||||
static uint16_t last_timer_c = 0;
|
||||
static uint16_t last_timer_w = 0;
|
||||
uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2};
|
||||
uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2};
|
||||
uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2};
|
||||
uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2};
|
||||
|
||||
void mousekey_task(void) {
|
||||
// report cursor and scroll movement independently
|
||||
report_mouse_t const tmpmr = mouse_report;
|
||||
mouse_report.x = 0;
|
||||
mouse_report.y = 0;
|
||||
mouse_report.v = 0;
|
||||
mouse_report.h = 0;
|
||||
|
||||
if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
|
||||
mouse_report.x = tmpmr.x;
|
||||
mouse_report.y = tmpmr.y;
|
||||
}
|
||||
if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
|
||||
mouse_report.v = tmpmr.v;
|
||||
mouse_report.h = tmpmr.h;
|
||||
}
|
||||
|
||||
if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
|
||||
mouse_report = tmpmr;
|
||||
}
|
||||
|
||||
void adjust_speed(void) {
|
||||
uint16_t const c_offset = c_offsets[mk_speed];
|
||||
uint16_t const w_offset = w_offsets[mk_speed];
|
||||
if (mouse_report.x > 0) mouse_report.x = c_offset;
|
||||
if (mouse_report.x < 0) mouse_report.x = c_offset * -1;
|
||||
if (mouse_report.y > 0) mouse_report.y = c_offset;
|
||||
if (mouse_report.y < 0) mouse_report.y = c_offset * -1;
|
||||
if (mouse_report.h > 0) mouse_report.h = w_offset;
|
||||
if (mouse_report.h < 0) mouse_report.h = w_offset * -1;
|
||||
if (mouse_report.v > 0) mouse_report.v = w_offset;
|
||||
if (mouse_report.v < 0) mouse_report.v = w_offset * -1;
|
||||
// adjust for diagonals
|
||||
if (mouse_report.x && mouse_report.y) {
|
||||
mouse_report.x = times_inv_sqrt2(mouse_report.x);
|
||||
if (mouse_report.x == 0) {
|
||||
mouse_report.x = 1;
|
||||
}
|
||||
mouse_report.y = times_inv_sqrt2(mouse_report.y);
|
||||
if (mouse_report.y == 0) {
|
||||
mouse_report.y = 1;
|
||||
}
|
||||
}
|
||||
if (mouse_report.h && mouse_report.v) {
|
||||
mouse_report.h = times_inv_sqrt2(mouse_report.h);
|
||||
mouse_report.v = times_inv_sqrt2(mouse_report.v);
|
||||
}
|
||||
}
|
||||
|
||||
void mousekey_on(uint8_t code) {
|
||||
uint16_t const c_offset = c_offsets[mk_speed];
|
||||
uint16_t const w_offset = w_offsets[mk_speed];
|
||||
uint8_t const old_speed = mk_speed;
|
||||
if (code == KC_MS_UP)
|
||||
mouse_report.y = c_offset * -1;
|
||||
else if (code == KC_MS_DOWN)
|
||||
mouse_report.y = c_offset;
|
||||
else if (code == KC_MS_LEFT)
|
||||
mouse_report.x = c_offset * -1;
|
||||
else if (code == KC_MS_RIGHT)
|
||||
mouse_report.x = c_offset;
|
||||
else if (code == KC_MS_WH_UP)
|
||||
mouse_report.v = w_offset;
|
||||
else if (code == KC_MS_WH_DOWN)
|
||||
mouse_report.v = w_offset * -1;
|
||||
else if (code == KC_MS_WH_LEFT)
|
||||
mouse_report.h = w_offset * -1;
|
||||
else if (code == KC_MS_WH_RIGHT)
|
||||
mouse_report.h = w_offset;
|
||||
else if (code == KC_MS_BTN1)
|
||||
mouse_report.buttons |= MOUSE_BTN1;
|
||||
else if (code == KC_MS_BTN2)
|
||||
mouse_report.buttons |= MOUSE_BTN2;
|
||||
else if (code == KC_MS_BTN3)
|
||||
mouse_report.buttons |= MOUSE_BTN3;
|
||||
else if (code == KC_MS_BTN4)
|
||||
mouse_report.buttons |= MOUSE_BTN4;
|
||||
else if (code == KC_MS_BTN5)
|
||||
mouse_report.buttons |= MOUSE_BTN5;
|
||||
else if (code == KC_MS_ACCEL0)
|
||||
mk_speed = mkspd_0;
|
||||
else if (code == KC_MS_ACCEL1)
|
||||
mk_speed = mkspd_1;
|
||||
else if (code == KC_MS_ACCEL2)
|
||||
mk_speed = mkspd_2;
|
||||
if (mk_speed != old_speed) adjust_speed();
|
||||
}
|
||||
|
||||
void mousekey_off(uint8_t code) {
|
||||
# ifdef MK_MOMENTARY_ACCEL
|
||||
uint8_t const old_speed = mk_speed;
|
||||
# endif
|
||||
if (code == KC_MS_UP && mouse_report.y < 0)
|
||||
mouse_report.y = 0;
|
||||
else if (code == KC_MS_DOWN && mouse_report.y > 0)
|
||||
mouse_report.y = 0;
|
||||
else if (code == KC_MS_LEFT && mouse_report.x < 0)
|
||||
mouse_report.x = 0;
|
||||
else if (code == KC_MS_RIGHT && mouse_report.x > 0)
|
||||
mouse_report.x = 0;
|
||||
else if (code == KC_MS_WH_UP && mouse_report.v > 0)
|
||||
mouse_report.v = 0;
|
||||
else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
|
||||
mouse_report.v = 0;
|
||||
else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
|
||||
mouse_report.h = 0;
|
||||
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
|
||||
mouse_report.h = 0;
|
||||
else if (code == KC_MS_BTN1)
|
||||
mouse_report.buttons &= ~MOUSE_BTN1;
|
||||
else if (code == KC_MS_BTN2)
|
||||
mouse_report.buttons &= ~MOUSE_BTN2;
|
||||
else if (code == KC_MS_BTN3)
|
||||
mouse_report.buttons &= ~MOUSE_BTN3;
|
||||
else if (code == KC_MS_BTN4)
|
||||
mouse_report.buttons &= ~MOUSE_BTN4;
|
||||
else if (code == KC_MS_BTN5)
|
||||
mouse_report.buttons &= ~MOUSE_BTN5;
|
||||
# ifdef MK_MOMENTARY_ACCEL
|
||||
else if (code == KC_MS_ACCEL0)
|
||||
mk_speed = mkspd_DEFAULT;
|
||||
else if (code == KC_MS_ACCEL1)
|
||||
mk_speed = mkspd_DEFAULT;
|
||||
else if (code == KC_MS_ACCEL2)
|
||||
mk_speed = mkspd_DEFAULT;
|
||||
if (mk_speed != old_speed) adjust_speed();
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif /* #ifndef MK_3_SPEED */
|
||||
|
||||
void mousekey_send(void) {
|
||||
mousekey_debug();
|
||||
uint16_t time = timer_read();
|
||||
if (mouse_report.x || mouse_report.y) last_timer_c = time;
|
||||
if (mouse_report.v || mouse_report.h) last_timer_w = time;
|
||||
host_mouse_send(&mouse_report);
|
||||
}
|
||||
|
||||
void mousekey_clear(void) {
|
||||
mouse_report = (report_mouse_t){};
|
||||
mousekey_repeat = 0;
|
||||
mousekey_wheel_repeat = 0;
|
||||
mousekey_accel = 0;
|
||||
}
|
||||
|
||||
static void mousekey_debug(void) {
|
||||
if (!debug_mouse) return;
|
||||
print("mousekey [btn|x y v h](rep/acl): [");
|
||||
phex(mouse_report.buttons);
|
||||
print("|");
|
||||
print_decs(mouse_report.x);
|
||||
print(" ");
|
||||
print_decs(mouse_report.y);
|
||||
print(" ");
|
||||
print_decs(mouse_report.v);
|
||||
print(" ");
|
||||
print_decs(mouse_report.h);
|
||||
print("](");
|
||||
print_dec(mousekey_repeat);
|
||||
print("/");
|
||||
print_dec(mousekey_accel);
|
||||
print(")\n");
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "host.h"
|
||||
|
||||
#ifndef MK_3_SPEED
|
||||
|
||||
/* max value on report descriptor */
|
||||
# ifndef MOUSEKEY_MOVE_MAX
|
||||
# define MOUSEKEY_MOVE_MAX 127
|
||||
# elif MOUSEKEY_MOVE_MAX > 127
|
||||
# error MOUSEKEY_MOVE_MAX needs to be smaller than 127
|
||||
# endif
|
||||
|
||||
# ifndef MOUSEKEY_WHEEL_MAX
|
||||
# define MOUSEKEY_WHEEL_MAX 127
|
||||
# elif MOUSEKEY_WHEEL_MAX > 127
|
||||
# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
|
||||
# endif
|
||||
|
||||
# ifndef MOUSEKEY_MOVE_DELTA
|
||||
# define MOUSEKEY_MOVE_DELTA 5
|
||||
# endif
|
||||
# ifndef MOUSEKEY_WHEEL_DELTA
|
||||
# define MOUSEKEY_WHEEL_DELTA 1
|
||||
# endif
|
||||
# ifndef MOUSEKEY_DELAY
|
||||
# define MOUSEKEY_DELAY 300
|
||||
# endif
|
||||
# ifndef MOUSEKEY_INTERVAL
|
||||
# define MOUSEKEY_INTERVAL 50
|
||||
# endif
|
||||
# ifndef MOUSEKEY_MAX_SPEED
|
||||
# define MOUSEKEY_MAX_SPEED 10
|
||||
# endif
|
||||
# ifndef MOUSEKEY_TIME_TO_MAX
|
||||
# define MOUSEKEY_TIME_TO_MAX 20
|
||||
# endif
|
||||
# ifndef MOUSEKEY_WHEEL_DELAY
|
||||
# define MOUSEKEY_WHEEL_DELAY 300
|
||||
# endif
|
||||
# ifndef MOUSEKEY_WHEEL_INTERVAL
|
||||
# define MOUSEKEY_WHEEL_INTERVAL 100
|
||||
# endif
|
||||
# ifndef MOUSEKEY_WHEEL_MAX_SPEED
|
||||
# define MOUSEKEY_WHEEL_MAX_SPEED 8
|
||||
# endif
|
||||
# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
|
||||
# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
|
||||
# endif
|
||||
|
||||
#else /* #ifndef MK_3_SPEED */
|
||||
|
||||
# ifndef MK_C_OFFSET_UNMOD
|
||||
# define MK_C_OFFSET_UNMOD 16
|
||||
# endif
|
||||
# ifndef MK_C_INTERVAL_UNMOD
|
||||
# define MK_C_INTERVAL_UNMOD 16
|
||||
# endif
|
||||
# ifndef MK_C_OFFSET_0
|
||||
# define MK_C_OFFSET_0 1
|
||||
# endif
|
||||
# ifndef MK_C_INTERVAL_0
|
||||
# define MK_C_INTERVAL_0 32
|
||||
# endif
|
||||
# ifndef MK_C_OFFSET_1
|
||||
# define MK_C_OFFSET_1 4
|
||||
# endif
|
||||
# ifndef MK_C_INTERVAL_1
|
||||
# define MK_C_INTERVAL_1 16
|
||||
# endif
|
||||
# ifndef MK_C_OFFSET_2
|
||||
# define MK_C_OFFSET_2 32
|
||||
# endif
|
||||
# ifndef MK_C_INTERVAL_2
|
||||
# define MK_C_INTERVAL_2 16
|
||||
# endif
|
||||
|
||||
# ifndef MK_W_OFFSET_UNMOD
|
||||
# define MK_W_OFFSET_UNMOD 1
|
||||
# endif
|
||||
# ifndef MK_W_INTERVAL_UNMOD
|
||||
# define MK_W_INTERVAL_UNMOD 40
|
||||
# endif
|
||||
# ifndef MK_W_OFFSET_0
|
||||
# define MK_W_OFFSET_0 1
|
||||
# endif
|
||||
# ifndef MK_W_INTERVAL_0
|
||||
# define MK_W_INTERVAL_0 360
|
||||
# endif
|
||||
# ifndef MK_W_OFFSET_1
|
||||
# define MK_W_OFFSET_1 1
|
||||
# endif
|
||||
# ifndef MK_W_INTERVAL_1
|
||||
# define MK_W_INTERVAL_1 120
|
||||
# endif
|
||||
# ifndef MK_W_OFFSET_2
|
||||
# define MK_W_OFFSET_2 1
|
||||
# endif
|
||||
# ifndef MK_W_INTERVAL_2
|
||||
# define MK_W_INTERVAL_2 20
|
||||
# endif
|
||||
|
||||
#endif /* #ifndef MK_3_SPEED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint8_t mk_delay;
|
||||
extern uint8_t mk_interval;
|
||||
extern uint8_t mk_max_speed;
|
||||
extern uint8_t mk_time_to_max;
|
||||
extern uint8_t mk_wheel_max_speed;
|
||||
extern uint8_t mk_wheel_time_to_max;
|
||||
|
||||
void mousekey_task(void);
|
||||
void mousekey_on(uint8_t code);
|
||||
void mousekey_off(uint8_t code);
|
||||
void mousekey_clear(void);
|
||||
void mousekey_send(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
23
tmk_core/common/pin_defs.h
Normal file
23
tmk_core/common/pin_defs.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// useful for direct pin mapping
|
||||
#define NO_PIN (pin_t)(~0)
|
||||
|
||||
#if __has_include_next("pin_defs.h")
|
||||
# include_next "pin_defs.h" /* Include the platforms pin_defs.h */
|
||||
#endif
|
||||
@@ -27,104 +27,76 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "util.h"
|
||||
#include "sendchar.h"
|
||||
#include "progmem.h"
|
||||
|
||||
#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
|
||||
# define PSTR(x) x
|
||||
#endif
|
||||
void print_set_sendchar(sendchar_func_t func);
|
||||
|
||||
#ifndef NO_PRINT
|
||||
|
||||
# if defined(__AVR__) /* __AVR__ */
|
||||
|
||||
# include "avr/xprintf.h"
|
||||
|
||||
# ifdef USER_PRINT /* USER_PRINT */
|
||||
|
||||
// Remove normal print defines
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# undef xprintf
|
||||
# define xprintf(fmt, ...)
|
||||
|
||||
// Create user print defines
|
||||
# define uprint(s) xputs(PSTR(s))
|
||||
# define uprintln(s) xputs(PSTR(s "\r\n"))
|
||||
# define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__)
|
||||
|
||||
# else /* NORMAL PRINT */
|
||||
|
||||
// Create user & normal print defines
|
||||
# define print(s) xputs(PSTR(s))
|
||||
# define println(s) xputs(PSTR(s "\r\n"))
|
||||
# define uprint(s) print(s)
|
||||
# define uprintln(s) println(s)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
|
||||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
/* function pointer of sendchar to be used by print utility */
|
||||
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
|
||||
|
||||
# elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
|
||||
|
||||
# if __has_include_next("_print.h")
|
||||
# include_next "_print.h" /* Include the platforms print.h */
|
||||
# else
|
||||
// Fall back to lib/printf
|
||||
# include "printf.h" // lib/printf/printf.h
|
||||
|
||||
# ifdef USER_PRINT /* USER_PRINT */
|
||||
|
||||
// Remove normal print defines
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# define xprintf(fmt, ...)
|
||||
|
||||
// Create user print defines
|
||||
# define uprint(s) printf(s)
|
||||
# define uprintln(s) printf(s "\r\n")
|
||||
# define uprintf printf
|
||||
|
||||
# else /* NORMAL PRINT */
|
||||
// Create user & normal print defines
|
||||
# define print(s) printf(s)
|
||||
# define println(s) printf(s "\r\n")
|
||||
# define xprintf printf
|
||||
# define uprint(s) printf(s)
|
||||
# define uprintln(s) printf(s "\r\n")
|
||||
# define uprintf printf
|
||||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
|
||||
# elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
|
||||
|
||||
# include "arm_atsam/printf.h"
|
||||
|
||||
# ifdef USER_PRINT /* USER_PRINT */
|
||||
|
||||
// Remove normal print defines
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# define xprintf(fmt, ...)
|
||||
|
||||
// Create user print defines
|
||||
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
# define uprint(s) xprintf(s)
|
||||
# define uprintln(s) xprintf(s "\r\n")
|
||||
|
||||
# else /* NORMAL PRINT */
|
||||
|
||||
// Create user & normal print defines
|
||||
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
# define print(s) xprintf(s)
|
||||
# define println(s) xprintf(s "\r\n")
|
||||
# define uprint(s) print(s)
|
||||
# define uprintln(s) println(s)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
|
||||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
# define print(s) printf(s)
|
||||
# define println(s) printf(s "\r\n")
|
||||
# define xprintf printf
|
||||
# define uprint(s) printf(s)
|
||||
# define uprintln(s) printf(s "\r\n")
|
||||
# define uprintf printf
|
||||
|
||||
# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */
|
||||
#else /* NO_PRINT */
|
||||
# undef xprintf
|
||||
// Remove print defines
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# define xprintf(fmt, ...)
|
||||
# define uprintf(fmt, ...)
|
||||
# define uprint(s)
|
||||
# define uprintln(s)
|
||||
|
||||
#endif /* NO_PRINT */
|
||||
|
||||
#ifdef USER_PRINT
|
||||
// Remove normal print defines
|
||||
# undef print
|
||||
# undef println
|
||||
# undef xprintf
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# define xprintf(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define print_dec(i) xprintf("%u", i)
|
||||
#define print_decs(i) xprintf("%d", i)
|
||||
/* hex */
|
||||
#define print_hex4(i) xprintf("%X", i)
|
||||
#define print_hex8(i) xprintf("%02X", i)
|
||||
#define print_hex16(i) xprintf("%04X", i)
|
||||
#define print_hex32(i) xprintf("%08lX", i)
|
||||
/* binary */
|
||||
#define print_bin4(i) xprintf("%04b", i)
|
||||
#define print_bin8(i) xprintf("%08b", i)
|
||||
#define print_bin16(i) xprintf("%016b", i)
|
||||
#define print_bin32(i) xprintf("%032lb", i)
|
||||
#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
|
||||
#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
|
||||
#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
|
||||
/* print value utility */
|
||||
#define print_val_dec(v) xprintf(#v ": %u\n", v)
|
||||
#define print_val_decs(v) xprintf(#v ": %d\n", v)
|
||||
#define print_val_hex8(v) xprintf(#v ": %X\n", v)
|
||||
#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
|
||||
#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
|
||||
#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
|
||||
#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
|
||||
#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
|
||||
#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
|
||||
#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
|
||||
#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
|
||||
|
||||
// User print disables the normal print messages in the body of QMK/TMK code and
|
||||
// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
|
||||
@@ -132,139 +104,32 @@ extern "C"
|
||||
// print (and store their wasteful strings).
|
||||
//
|
||||
// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!!
|
||||
//
|
||||
# ifdef USER_PRINT
|
||||
|
||||
// Disable normal print
|
||||
# define print_dec(data)
|
||||
# define print_decs(data)
|
||||
# define print_hex4(data)
|
||||
# define print_hex8(data)
|
||||
# define print_hex16(data)
|
||||
# define print_hex32(data)
|
||||
# define print_bin4(data)
|
||||
# define print_bin8(data)
|
||||
# define print_bin16(data)
|
||||
# define print_bin32(data)
|
||||
# define print_bin_reverse8(data)
|
||||
# define print_bin_reverse16(data)
|
||||
# define print_bin_reverse32(data)
|
||||
# define print_val_dec(v)
|
||||
# define print_val_decs(v)
|
||||
# define print_val_hex8(v)
|
||||
# define print_val_hex16(v)
|
||||
# define print_val_hex32(v)
|
||||
# define print_val_bin8(v)
|
||||
# define print_val_bin16(v)
|
||||
# define print_val_bin32(v)
|
||||
# define print_val_bin_reverse8(v)
|
||||
# define print_val_bin_reverse16(v)
|
||||
# define print_val_bin_reverse32(v)
|
||||
|
||||
# else /* NORMAL_PRINT */
|
||||
|
||||
// Enable normal print
|
||||
/* decimal */
|
||||
# define print_dec(i) xprintf("%u", i)
|
||||
# define print_decs(i) xprintf("%d", i)
|
||||
/* hex */
|
||||
# define print_hex4(i) xprintf("%X", i)
|
||||
# define print_hex8(i) xprintf("%02X", i)
|
||||
# define print_hex16(i) xprintf("%04X", i)
|
||||
# define print_hex32(i) xprintf("%08lX", i)
|
||||
/* binary */
|
||||
# define print_bin4(i) xprintf("%04b", i)
|
||||
# define print_bin8(i) xprintf("%08b", i)
|
||||
# define print_bin16(i) xprintf("%016b", i)
|
||||
# define print_bin32(i) xprintf("%032lb", i)
|
||||
# define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
|
||||
# define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
|
||||
# define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
|
||||
/* print value utility */
|
||||
# define print_val_dec(v) xprintf(# v ": %u\n", v)
|
||||
# define print_val_decs(v) xprintf(# v ": %d\n", v)
|
||||
# define print_val_hex8(v) xprintf(# v ": %X\n", v)
|
||||
# define print_val_hex16(v) xprintf(# v ": %02X\n", v)
|
||||
# define print_val_hex32(v) xprintf(# v ": %04lX\n", v)
|
||||
# define print_val_bin8(v) xprintf(# v ": %08b\n", v)
|
||||
# define print_val_bin16(v) xprintf(# v ": %016b\n", v)
|
||||
# define print_val_bin32(v) xprintf(# v ": %032lb\n", v)
|
||||
# define print_val_bin_reverse8(v) xprintf(# v ": %08b\n", bitrev(v))
|
||||
# define print_val_bin_reverse16(v) xprintf(# v ": %016b\n", bitrev16(v))
|
||||
# define print_val_bin_reverse32(v) xprintf(# v ": %032lb\n", bitrev32(v))
|
||||
|
||||
# endif /* USER_PRINT / NORMAL_PRINT */
|
||||
|
||||
// User Print
|
||||
|
||||
/* decimal */
|
||||
# define uprint_dec(i) uprintf("%u", i)
|
||||
# define uprint_decs(i) uprintf("%d", i)
|
||||
#define uprint_dec(i) uprintf("%u", i)
|
||||
#define uprint_decs(i) uprintf("%d", i)
|
||||
/* hex */
|
||||
# define uprint_hex4(i) uprintf("%X", i)
|
||||
# define uprint_hex8(i) uprintf("%02X", i)
|
||||
# define uprint_hex16(i) uprintf("%04X", i)
|
||||
# define uprint_hex32(i) uprintf("%08lX", i)
|
||||
#define uprint_hex4(i) uprintf("%X", i)
|
||||
#define uprint_hex8(i) uprintf("%02X", i)
|
||||
#define uprint_hex16(i) uprintf("%04X", i)
|
||||
#define uprint_hex32(i) uprintf("%08lX", i)
|
||||
/* binary */
|
||||
# define uprint_bin4(i) uprintf("%04b", i)
|
||||
# define uprint_bin8(i) uprintf("%08b", i)
|
||||
# define uprint_bin16(i) uprintf("%016b", i)
|
||||
# define uprint_bin32(i) uprintf("%032lb", i)
|
||||
# define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
|
||||
# define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
|
||||
# define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
|
||||
#define uprint_bin4(i) uprintf("%04b", i)
|
||||
#define uprint_bin8(i) uprintf("%08b", i)
|
||||
#define uprint_bin16(i) uprintf("%016b", i)
|
||||
#define uprint_bin32(i) uprintf("%032lb", i)
|
||||
#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
|
||||
#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
|
||||
#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
|
||||
/* print value utility */
|
||||
# define uprint_val_dec(v) uprintf(# v ": %u\n", v)
|
||||
# define uprint_val_decs(v) uprintf(# v ": %d\n", v)
|
||||
# define uprint_val_hex8(v) uprintf(# v ": %X\n", v)
|
||||
# define uprint_val_hex16(v) uprintf(# v ": %02X\n", v)
|
||||
# define uprint_val_hex32(v) uprintf(# v ": %04lX\n", v)
|
||||
# define uprint_val_bin8(v) uprintf(# v ": %08b\n", v)
|
||||
# define uprint_val_bin16(v) uprintf(# v ": %016b\n", v)
|
||||
# define uprint_val_bin32(v) uprintf(# v ": %032lb\n", v)
|
||||
# define uprint_val_bin_reverse8(v) uprintf(# v ": %08b\n", bitrev(v))
|
||||
# define uprint_val_bin_reverse16(v) uprintf(# v ": %016b\n", bitrev16(v))
|
||||
# define uprint_val_bin_reverse32(v) uprintf(# v ": %032lb\n", bitrev32(v))
|
||||
|
||||
#else /* NO_PRINT */
|
||||
|
||||
# define xprintf(fmt, ...)
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# define print_set_sendchar(func)
|
||||
# define print_dec(data)
|
||||
# define print_decs(data)
|
||||
# define print_hex4(data)
|
||||
# define print_hex8(data)
|
||||
# define print_hex16(data)
|
||||
# define print_hex32(data)
|
||||
# define print_bin4(data)
|
||||
# define print_bin8(data)
|
||||
# define print_bin16(data)
|
||||
# define print_bin32(data)
|
||||
# define print_bin_reverse8(data)
|
||||
# define print_bin_reverse16(data)
|
||||
# define print_bin_reverse32(data)
|
||||
# define print_val_dec(v)
|
||||
# define print_val_decs(v)
|
||||
# define print_val_hex8(v)
|
||||
# define print_val_hex16(v)
|
||||
# define print_val_hex32(v)
|
||||
# define print_val_bin8(v)
|
||||
# define print_val_bin16(v)
|
||||
# define print_val_bin32(v)
|
||||
# define print_val_bin_reverse8(v)
|
||||
# define print_val_bin_reverse16(v)
|
||||
# define print_val_bin_reverse32(v)
|
||||
|
||||
#endif /* NO_PRINT */
|
||||
|
||||
/* Backward compatiblitly for old name */
|
||||
#define pdec(data) print_dec(data)
|
||||
#define pdec16(data) print_dec(data)
|
||||
#define phex(data) print_hex8(data)
|
||||
#define phex16(data) print_hex16(data)
|
||||
#define pbin(data) print_bin8(data)
|
||||
#define pbin16(data) print_bin16(data)
|
||||
#define pbin_reverse(data) print_bin_reverse8(data)
|
||||
#define pbin_reverse16(data) print_bin_reverse16(data)
|
||||
#define uprint_val_dec(v) uprintf(#v ": %u\n", v)
|
||||
#define uprint_val_decs(v) uprintf(#v ": %d\n", v)
|
||||
#define uprint_val_hex8(v) uprintf(#v ": %X\n", v)
|
||||
#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v)
|
||||
#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v)
|
||||
#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v)
|
||||
#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v)
|
||||
#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v)
|
||||
#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v))
|
||||
#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v))
|
||||
#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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
|
||||
@@ -14,17 +14,14 @@ 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "sendchar.h"
|
||||
|
||||
#pragma once
|
||||
// bind lib/printf to console interface - sendchar
|
||||
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0xCAFE
|
||||
#define DEVICE_VER 0x0814
|
||||
#define MANUFACTURER t.m.k.
|
||||
#define PRODUCT USB to USB keyboard converter
|
||||
static int8_t null_sendchar_func(uint8_t c) { return 0; }
|
||||
static sendchar_func_t func = null_sendchar_func;
|
||||
|
||||
#define DESCRIPTION Product from t.m.k. keyboard firmware project
|
||||
void print_set_sendchar(sendchar_func_t send) { func = send; }
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 32
|
||||
#define MATRIX_COLS 8
|
||||
void _putchar(char character) { func(character); }
|
||||
@@ -4,6 +4,7 @@
|
||||
# include <avr/pgmspace.h>
|
||||
#else
|
||||
# define PROGMEM
|
||||
# define PSTR(x) x
|
||||
# define PGM_P const char*
|
||||
# define memcpy_P(dest, src, n) memcpy(dest, src, n)
|
||||
# define pgm_read_byte(address_short) *((uint8_t*)(address_short))
|
||||
|
||||
@@ -34,12 +34,16 @@ enum hid_report_ids {
|
||||
};
|
||||
|
||||
/* Mouse buttons */
|
||||
#define MOUSE_BTN_MASK(n) (1 << (n))
|
||||
enum mouse_buttons {
|
||||
MOUSE_BTN1 = (1 << 0),
|
||||
MOUSE_BTN2 = (1 << 1),
|
||||
MOUSE_BTN3 = (1 << 2),
|
||||
MOUSE_BTN4 = (1 << 3),
|
||||
MOUSE_BTN5 = (1 << 4)
|
||||
MOUSE_BTN1 = MOUSE_BTN_MASK(0),
|
||||
MOUSE_BTN2 = MOUSE_BTN_MASK(1),
|
||||
MOUSE_BTN3 = MOUSE_BTN_MASK(2),
|
||||
MOUSE_BTN4 = MOUSE_BTN_MASK(3),
|
||||
MOUSE_BTN5 = MOUSE_BTN_MASK(4),
|
||||
MOUSE_BTN6 = MOUSE_BTN_MASK(5),
|
||||
MOUSE_BTN7 = MOUSE_BTN_MASK(6),
|
||||
MOUSE_BTN8 = MOUSE_BTN_MASK(7)
|
||||
};
|
||||
|
||||
/* Consumer Page (0x0C)
|
||||
@@ -76,7 +80,21 @@ enum consumer_usages {
|
||||
AL_ASSISTANT = 0x1CB,
|
||||
AL_KEYBOARD_LAYOUT = 0x1AE,
|
||||
// 15.16 Generic GUI Application Controls
|
||||
AC_NEW = 0x201,
|
||||
AC_OPEN = 0x202,
|
||||
AC_CLOSE = 0x203,
|
||||
AC_EXIT = 0x204,
|
||||
AC_MAXIMIZE = 0x205,
|
||||
AC_MINIMIZE = 0x206,
|
||||
AC_SAVE = 0x207,
|
||||
AC_PRINT = 0x208,
|
||||
AC_PROPERTIES = 0x209,
|
||||
AC_UNDO = 0x21A,
|
||||
AC_COPY = 0x21B,
|
||||
AC_CUT = 0x21C,
|
||||
AC_PASTE = 0x21D,
|
||||
AC_SELECT_ALL = 0x21E,
|
||||
AC_FIND = 0x21F,
|
||||
AC_SEARCH = 0x221,
|
||||
AC_HOME = 0x223,
|
||||
AC_BACK = 0x224,
|
||||
@@ -92,9 +110,12 @@ enum consumer_usages {
|
||||
*/
|
||||
enum desktop_usages {
|
||||
// 4.5.1 System Controls - Power Controls
|
||||
SYSTEM_POWER_DOWN = 0x81,
|
||||
SYSTEM_SLEEP = 0x82,
|
||||
SYSTEM_WAKE_UP = 0x83
|
||||
SYSTEM_POWER_DOWN = 0x81,
|
||||
SYSTEM_SLEEP = 0x82,
|
||||
SYSTEM_WAKE_UP = 0x83,
|
||||
SYSTEM_RESTART = 0x8F,
|
||||
// 4.10 System Display Controls
|
||||
SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -23,6 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int8_t (*sendchar_func_t)(uint8_t c);
|
||||
|
||||
/* transmit a character. return 0 on success, -1 on error. */
|
||||
int8_t sendchar(uint8_t c);
|
||||
|
||||
|
||||
@@ -14,5 +14,5 @@ void suspend_power_down_user(void);
|
||||
void suspend_power_down_kb(void);
|
||||
|
||||
#ifndef USB_SUSPEND_WAKEUP_DELAY
|
||||
# define USB_SUSPEND_WAKEUP_DELAY 200
|
||||
# define USB_SUSPEND_WAKEUP_DELAY 0
|
||||
#endif
|
||||
|
||||
58
tmk_core/common/sync_timer.c
Normal file
58
tmk_core/common/sync_timer.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
If you happen to meet one of the copyright holders in a bar you are obligated
|
||||
to buy them one pint of beer.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sync_timer.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
|
||||
volatile int32_t sync_timer_ms;
|
||||
|
||||
void sync_timer_init(void) { sync_timer_ms = 0; }
|
||||
|
||||
void sync_timer_update(uint32_t time) {
|
||||
if (is_keyboard_master()) return;
|
||||
sync_timer_ms = time - timer_read32();
|
||||
}
|
||||
|
||||
uint16_t sync_timer_read(void) {
|
||||
if (is_keyboard_master()) return timer_read();
|
||||
return sync_timer_read32();
|
||||
}
|
||||
|
||||
uint32_t sync_timer_read32(void) {
|
||||
if (is_keyboard_master()) return timer_read32();
|
||||
return sync_timer_ms + timer_read32();
|
||||
}
|
||||
|
||||
uint16_t sync_timer_elapsed(uint16_t last) {
|
||||
if (is_keyboard_master()) return timer_elapsed(last);
|
||||
return TIMER_DIFF_16(sync_timer_read(), last);
|
||||
}
|
||||
|
||||
uint32_t sync_timer_elapsed32(uint32_t last) {
|
||||
if (is_keyboard_master()) return timer_elapsed32(last);
|
||||
return TIMER_DIFF_32(sync_timer_read32(), last);
|
||||
}
|
||||
#endif
|
||||
54
tmk_core/common/sync_timer.h
Normal file
54
tmk_core/common/sync_timer.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
If you happen to meet one of the copyright holders in a bar you are obligated
|
||||
to buy them one pint of beer.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
|
||||
void sync_timer_init(void);
|
||||
void sync_timer_update(uint32_t time);
|
||||
uint16_t sync_timer_read(void);
|
||||
uint32_t sync_timer_read32(void);
|
||||
uint16_t sync_timer_elapsed(uint16_t last);
|
||||
uint32_t sync_timer_elapsed32(uint32_t last);
|
||||
#else
|
||||
# define sync_timer_init()
|
||||
# define sync_timer_clear()
|
||||
# define sync_timer_update(t)
|
||||
# define sync_timer_read() timer_read()
|
||||
# define sync_timer_read32() timer_read32()
|
||||
# define sync_timer_elapsed(t) timer_elapsed(t)
|
||||
# define sync_timer_elapsed32(t) timer_elapsed32(t)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,172 +0,0 @@
|
||||
// TODO: Teensy support(ATMega32u4/AT90USB128)
|
||||
// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
|
||||
/* UART Example for Teensy USB Development Board
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2009 PJRC.COM, LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Version 1.0: Initial Release
|
||||
// Version 1.1: Add support for Teensy 2.0, minor optimizations
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
|
||||
# define UDRn UDR0
|
||||
# define UBRRnL UBRR0L
|
||||
# define UCSRnA UCSR0A
|
||||
# define UCSRnB UCSR0B
|
||||
# define UCSRnC UCSR0C
|
||||
# define U2Xn U2X0
|
||||
# define RXENn RXEN0
|
||||
# define TXENn TXEN0
|
||||
# define RXCIEn RXCIE0
|
||||
# define UCSZn1 UCSZ01
|
||||
# define UCSZn0 UCSZ00
|
||||
# define UDRIEn UDRIE0
|
||||
# define USARTn_UDRE_vect USART_UDRE_vect
|
||||
# define USARTn_RX_vect USART_RX_vect
|
||||
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||
# define UDRn UDR1
|
||||
# define UBRRnL UBRR1L
|
||||
# define UCSRnA UCSR1A
|
||||
# define UCSRnB UCSR1B
|
||||
# define UCSRnC UCSR1C
|
||||
# define U2Xn U2X1
|
||||
# define RXENn RXEN1
|
||||
# define TXENn TXEN1
|
||||
# define RXCIEn RXCIE1
|
||||
# define UCSZn1 UCSZ11
|
||||
# define UCSZn0 UCSZ10
|
||||
# define UDRIEn UDRIE1
|
||||
# define USARTn_UDRE_vect USART1_UDRE_vect
|
||||
# define USARTn_RX_vect USART1_RX_vect
|
||||
#elif defined(__AVR_ATmega32A__)
|
||||
# define UDRn UDR
|
||||
# define UBRRnL UBRRL
|
||||
# define UCSRnA UCSRA
|
||||
# define UCSRnB UCSRB
|
||||
# define UCSRnC UCSRC
|
||||
# define U2Xn U2X
|
||||
# define RXENn RXEN
|
||||
# define TXENn TXEN
|
||||
# define RXCIEn RXCIE
|
||||
# define UCSZn1 UCSZ1
|
||||
# define UCSZn0 UCSZ0
|
||||
# define UDRIEn UDRIE
|
||||
# define USARTn_UDRE_vect USART_UDRE_vect
|
||||
# define USARTn_RX_vect USART_RX_vect
|
||||
#endif
|
||||
|
||||
// These buffers may be any size from 2 to 256 bytes.
|
||||
#define RX_BUFFER_SIZE 64
|
||||
#define TX_BUFFER_SIZE 256
|
||||
|
||||
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx_buffer_head;
|
||||
static volatile uint8_t tx_buffer_tail;
|
||||
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
|
||||
static volatile uint8_t rx_buffer_head;
|
||||
static volatile uint8_t rx_buffer_tail;
|
||||
|
||||
// Initialize the UART
|
||||
void uart_init(uint32_t baud) {
|
||||
cli();
|
||||
UBRRnL = (F_CPU / 4 / baud - 1) / 2;
|
||||
UCSRnA = (1 << U2Xn);
|
||||
UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
|
||||
UCSRnC = (1 << UCSZn1) | (1 << UCSZn0);
|
||||
tx_buffer_head = tx_buffer_tail = 0;
|
||||
rx_buffer_head = rx_buffer_tail = 0;
|
||||
sei();
|
||||
}
|
||||
|
||||
// Transmit a byte
|
||||
void uart_putchar(uint8_t c) {
|
||||
uint8_t i;
|
||||
|
||||
i = tx_buffer_head + 1;
|
||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||
// return immediately to avoid deadlock when interrupt is disabled(called from ISR)
|
||||
if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return;
|
||||
while (tx_buffer_tail == i)
|
||||
; // wait until space in buffer
|
||||
// cli();
|
||||
tx_buffer[i] = c;
|
||||
tx_buffer_head = i;
|
||||
UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
|
||||
// sei();
|
||||
}
|
||||
|
||||
// Receive a byte
|
||||
uint8_t uart_getchar(void) {
|
||||
uint8_t c, i;
|
||||
|
||||
while (rx_buffer_head == rx_buffer_tail)
|
||||
; // wait for character
|
||||
i = rx_buffer_tail + 1;
|
||||
if (i >= RX_BUFFER_SIZE) i = 0;
|
||||
c = rx_buffer[i];
|
||||
rx_buffer_tail = i;
|
||||
return c;
|
||||
}
|
||||
|
||||
// Return the number of bytes waiting in the receive buffer.
|
||||
// Call this before uart_getchar() to check if it will need
|
||||
// to wait for a byte to arrive.
|
||||
uint8_t uart_available(void) {
|
||||
uint8_t head, tail;
|
||||
|
||||
head = rx_buffer_head;
|
||||
tail = rx_buffer_tail;
|
||||
if (head >= tail) return head - tail;
|
||||
return RX_BUFFER_SIZE + head - tail;
|
||||
}
|
||||
|
||||
// Transmit Interrupt
|
||||
ISR(USARTn_UDRE_vect) {
|
||||
uint8_t i;
|
||||
|
||||
if (tx_buffer_head == tx_buffer_tail) {
|
||||
// buffer is empty, disable transmit interrupt
|
||||
UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
|
||||
} else {
|
||||
i = tx_buffer_tail + 1;
|
||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||
UDRn = tx_buffer[i];
|
||||
tx_buffer_tail = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Receive Interrupt
|
||||
ISR(USARTn_RX_vect) {
|
||||
uint8_t c, i;
|
||||
|
||||
c = UDRn;
|
||||
i = rx_buffer_head + 1;
|
||||
if (i >= RX_BUFFER_SIZE) i = 0;
|
||||
if (i != rx_buffer_tail) {
|
||||
rx_buffer[i] = c;
|
||||
rx_buffer_head = i;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void uart_init(uint32_t baud);
|
||||
void uart_putchar(uint8_t c);
|
||||
uint8_t uart_getchar(void);
|
||||
uint8_t uart_available(void);
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
|
||||
// bit population - return number of on-bit
|
||||
__attribute__((noinline)) uint8_t bitpop(uint8_t bits) {
|
||||
uint8_t c;
|
||||
for (c = 0; bits; c++) bits &= bits - 1;
|
||||
return c;
|
||||
/*
|
||||
const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
||||
return bit_count[bits>>4] + bit_count[bits&0x0F]
|
||||
*/
|
||||
}
|
||||
|
||||
uint8_t bitpop16(uint16_t bits) {
|
||||
uint8_t c;
|
||||
for (c = 0; bits; c++) bits &= bits - 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
uint8_t bitpop32(uint32_t bits) {
|
||||
uint8_t c;
|
||||
for (c = 0; bits; c++) bits &= bits - 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
// most significant on-bit - return highest location of on-bit
|
||||
// NOTE: return 0 when bit0 is on or all bits are off
|
||||
__attribute__((noinline)) uint8_t biton(uint8_t bits) {
|
||||
uint8_t n = 0;
|
||||
if (bits >> 4) {
|
||||
bits >>= 4;
|
||||
n += 4;
|
||||
}
|
||||
if (bits >> 2) {
|
||||
bits >>= 2;
|
||||
n += 2;
|
||||
}
|
||||
if (bits >> 1) {
|
||||
bits >>= 1;
|
||||
n += 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
uint8_t biton16(uint16_t bits) {
|
||||
uint8_t n = 0;
|
||||
if (bits >> 8) {
|
||||
bits >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
if (bits >> 4) {
|
||||
bits >>= 4;
|
||||
n += 4;
|
||||
}
|
||||
if (bits >> 2) {
|
||||
bits >>= 2;
|
||||
n += 2;
|
||||
}
|
||||
if (bits >> 1) {
|
||||
bits >>= 1;
|
||||
n += 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
uint8_t biton32(uint32_t bits) {
|
||||
uint8_t n = 0;
|
||||
if (bits >> 16) {
|
||||
bits >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if (bits >> 8) {
|
||||
bits >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
if (bits >> 4) {
|
||||
bits >>= 4;
|
||||
n += 4;
|
||||
}
|
||||
if (bits >> 2) {
|
||||
bits >>= 2;
|
||||
n += 2;
|
||||
}
|
||||
if (bits >> 1) {
|
||||
bits >>= 1;
|
||||
n += 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
__attribute__((noinline)) uint8_t bitrev(uint8_t bits) {
|
||||
bits = (bits & 0x0f) << 4 | (bits & 0xf0) >> 4;
|
||||
bits = (bits & 0b00110011) << 2 | (bits & 0b11001100) >> 2;
|
||||
bits = (bits & 0b01010101) << 1 | (bits & 0b10101010) >> 1;
|
||||
return bits;
|
||||
}
|
||||
|
||||
uint16_t bitrev16(uint16_t bits) {
|
||||
bits = bitrev(bits & 0x00ff) << 8 | bitrev((bits & 0xff00) >> 8);
|
||||
return bits;
|
||||
}
|
||||
|
||||
uint32_t bitrev32(uint32_t bits) {
|
||||
bits = (uint32_t)bitrev16(bits & 0x0000ffff) << 16 | bitrev16((bits & 0xffff0000) >> 16);
|
||||
return bits;
|
||||
}
|
||||
@@ -6,10 +6,89 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__ARMEL__) || defined(__ARMEB__)
|
||||
# ifndef __OPTIMIZE__
|
||||
# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
|
||||
# endif
|
||||
|
||||
# define wait_cpuclock(x) wait_cpuclock_allnop(x)
|
||||
|
||||
# define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t"
|
||||
|
||||
__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
|
||||
/* The argument n must be a constant expression.
|
||||
* That way, compiler optimization will remove unnecessary code. */
|
||||
if (n < 1) {
|
||||
return;
|
||||
}
|
||||
if (n > 8) {
|
||||
unsigned int n8 = n / 8;
|
||||
n = n - n8 * 8;
|
||||
switch (n8) {
|
||||
case 16:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 15:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 14:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 13:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 12:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 11:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 10:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 9:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 8:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 7:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 6:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 5:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 4:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 3:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 2:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 1:
|
||||
asm volatile(CLOCK_DELAY_NOP8::: "memory");
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (n) {
|
||||
case 8:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 7:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 6:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 5:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 4:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 3:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 2:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 1:
|
||||
asm volatile("nop" ::: "memory");
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__)
|
||||
# include <util/delay.h>
|
||||
# define wait_ms(ms) _delay_ms(ms)
|
||||
# define wait_us(us) _delay_us(us)
|
||||
# define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
|
||||
#elif defined PROTOCOL_CHIBIOS
|
||||
# include <ch.h>
|
||||
# define wait_ms(ms) \
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/sh
|
||||
ALL_CONFIGS=$*
|
||||
GREP="grep"
|
||||
|
||||
cat <<- EOF > lib/lufa/Bootloaders/DFU/Keyboard.h
|
||||
#pragma once
|
||||
|
||||
$($GREP "MANUFACTURER[ \t]" $ALL_CONFIGS -h | tail -1)
|
||||
$($GREP "PRODUCT[ \t]" $ALL_CONFIGS -h | tail -1 | tr -d '\r') Bootloader
|
||||
$($GREP "QMK_ESC_OUTPUT[ \t]" $ALL_CONFIGS -h | tail -1)
|
||||
$($GREP "QMK_ESC_INPUT[ \t]" $ALL_CONFIGS -h | tail -1)
|
||||
$($GREP "QMK_LED[ \t]" $ALL_CONFIGS -h | tail -1)
|
||||
$($GREP "QMK_SPEAKER[ \t]" $ALL_CONFIGS -h | tail -1)
|
||||
EOF
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2013 Shay Green <gblargg@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "adb.h"
|
||||
#include "print.h"
|
||||
|
||||
// GCC doesn't inline functions normally
|
||||
#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
|
||||
@@ -59,7 +60,6 @@ static inline void place_bit1(void);
|
||||
static inline void send_byte(uint8_t data);
|
||||
static inline uint16_t wait_data_lo(uint16_t us);
|
||||
static inline uint16_t wait_data_hi(uint16_t us);
|
||||
static inline uint16_t adb_host_dev_recv(uint8_t device);
|
||||
|
||||
void adb_host_init(void) {
|
||||
ADB_PORT &= ~(1 << ADB_DATA_BIT);
|
||||
@@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }
|
||||
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
|
||||
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
|
||||
*/
|
||||
|
||||
// ADB Bit Cells
|
||||
//
|
||||
// bit cell time: 70-130us
|
||||
// low part of bit0: 60-70% of bit cell
|
||||
// low part of bit1: 30-40% of bit cell
|
||||
//
|
||||
// bit cell time 70us 130us
|
||||
// --------------------------------------------
|
||||
// low part of bit0 42-49 78-91
|
||||
// high part of bit0 21-28 39-52
|
||||
// low part of bit1 21-28 39-52
|
||||
// high part of bit1 42-49 78-91
|
||||
//
|
||||
//
|
||||
// bit0:
|
||||
// 70us bit cell:
|
||||
// ____________~~~~~~
|
||||
// 42-49 21-28
|
||||
//
|
||||
// 130us bit cell:
|
||||
// ____________~~~~~~
|
||||
// 78-91 39-52
|
||||
//
|
||||
// bit1:
|
||||
// 70us bit cell:
|
||||
// ______~~~~~~~~~~~~
|
||||
// 21-28 42-49
|
||||
//
|
||||
// 130us bit cell:
|
||||
// ______~~~~~~~~~~~~
|
||||
// 39-52 78-91
|
||||
//
|
||||
// [from Apple IIgs Hardware Reference Second Edition]
|
||||
|
||||
enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
|
||||
|
||||
uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
|
||||
uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
|
||||
|
||||
#ifdef ADB_MOUSE_ENABLE
|
||||
void adb_mouse_init(void) { return; }
|
||||
__attribute__((weak)) void adb_mouse_init(void) { return; }
|
||||
|
||||
uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); }
|
||||
__attribute__((weak)) void adb_mouse_task(void) { return; }
|
||||
|
||||
uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
|
||||
#endif
|
||||
|
||||
static inline uint16_t adb_host_dev_recv(uint8_t device) {
|
||||
uint16_t data = 0;
|
||||
// This sends Talk command to read data from register and returns length of the data.
|
||||
uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
|
||||
for (int8_t i = 0; i < len; i++) buf[i] = 0;
|
||||
|
||||
cli();
|
||||
attention();
|
||||
send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
|
||||
place_bit0(); // Stopbit(0)
|
||||
send_byte((addr << 4) | ADB_CMD_TALK | reg);
|
||||
place_bit0(); // Stopbit(0)
|
||||
// TODO: Service Request(Srq):
|
||||
// Device holds low part of comannd stopbit for 140-260us
|
||||
//
|
||||
// Command:
|
||||
// ......._ ______________________ ___ ............_ -------
|
||||
// | | | | | | |
|
||||
// Command | | | | | Data bytes | |
|
||||
// ........|___| | 140-260 |__| |_............|___|
|
||||
// |stop0 | Tlt Stop-to-Start |start1| |stop0 |
|
||||
//
|
||||
// Command without data:
|
||||
// ......._ __________________________
|
||||
// | |
|
||||
// Command | |
|
||||
// ........|___| | 140-260 |
|
||||
// |stop0 | Tlt Stop-to-Start |
|
||||
//
|
||||
// Service Request:
|
||||
// ......._ ______ ___ ............_ -------
|
||||
// | 140-260 | | | | | |
|
||||
// Command | Service Request | | | | Data bytes | |
|
||||
// ........|___________________| |__| |_............|___|
|
||||
// |stop0 | |start1| |stop0 |
|
||||
// ......._ __________
|
||||
// | 140-260 |
|
||||
// Command | Service Request |
|
||||
// ........|___________________|
|
||||
// |stop0 |
|
||||
// This can be happened?
|
||||
// ......._ ______________________ ___ ............_ -----
|
||||
// | | | | | | 140-260 |
|
||||
// Command | | | | | Data bytes | Service Request |
|
||||
// ........|___| | 140-260 |__| |_............|_________________|
|
||||
// |stop0 | Tlt Stop-to-Start |start1| |stop0 |
|
||||
//
|
||||
// "Service requests are issued by the devices during a very specific time at the
|
||||
// end of the reception of the command packet.
|
||||
// If a device in need of service issues a service request, it must do so within
|
||||
// the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
|
||||
//
|
||||
// "A device sends a Service Request signal by holding the bus low during the low
|
||||
// portion of the stop bit of any command or data transaction. The device must lengthen
|
||||
// the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
|
||||
// http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
|
||||
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
|
||||
xprintf("R");
|
||||
sei();
|
||||
return -30; // something wrong
|
||||
return 0;
|
||||
}
|
||||
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
|
||||
sei();
|
||||
return 0; // No data to send
|
||||
return 0; // No data from device(not error);
|
||||
}
|
||||
|
||||
uint8_t n = 17; // start bit + 16 data bits
|
||||
// start bit(1)
|
||||
if (!wait_data_hi(40)) {
|
||||
xprintf("S");
|
||||
sei();
|
||||
return 0;
|
||||
}
|
||||
if (!wait_data_lo(100)) {
|
||||
xprintf("s");
|
||||
sei();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t n = 0; // bit count
|
||||
do {
|
||||
//
|
||||
// |<- bit_cell_max(130) ->|
|
||||
// | |<- lo ->|
|
||||
// | | |<-hi->|
|
||||
// _______
|
||||
// | | |
|
||||
// | 130-lo | lo-hi |
|
||||
// |________| |
|
||||
//
|
||||
uint8_t lo = (uint8_t)wait_data_hi(130);
|
||||
if (!lo) goto error;
|
||||
if (!lo) goto error; // no more bit or after stop bit
|
||||
|
||||
uint8_t hi = (uint8_t)wait_data_lo(lo);
|
||||
if (!hi) goto error;
|
||||
if (!hi) goto error; // stop bit extedned by Srq?
|
||||
|
||||
hi = lo - hi;
|
||||
lo = 130 - lo;
|
||||
if (n / 8 >= len) continue; // can't store in buf
|
||||
|
||||
data <<= 1;
|
||||
if (lo < hi) {
|
||||
data |= 1;
|
||||
} else if (n == 17) {
|
||||
sei();
|
||||
return -20;
|
||||
buf[n / 8] <<= 1;
|
||||
if ((130 - lo) < (lo - hi)) {
|
||||
buf[n / 8] |= 1;
|
||||
}
|
||||
} while (--n);
|
||||
|
||||
// Stop bit can't be checked normally since it could have service request lenghtening
|
||||
// and its high state never goes low.
|
||||
if (!wait_data_hi(351) || wait_data_lo(91)) {
|
||||
sei();
|
||||
return -21;
|
||||
}
|
||||
sei();
|
||||
return data;
|
||||
} while (++n);
|
||||
|
||||
error:
|
||||
sei();
|
||||
return -n;
|
||||
return n / 8;
|
||||
}
|
||||
|
||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) {
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
|
||||
uint8_t len;
|
||||
uint8_t buf[8];
|
||||
len = adb_host_talk_buf(addr, reg, buf, 8);
|
||||
if (len != 2) return 0;
|
||||
return (buf[0] << 8 | buf[1]);
|
||||
}
|
||||
|
||||
void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
|
||||
cli();
|
||||
attention();
|
||||
send_byte(cmd);
|
||||
place_bit0(); // Stopbit(0)
|
||||
send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
|
||||
place_bit0(); // Stopbit(0)
|
||||
// TODO: Service Request
|
||||
_delay_us(200); // Tlt/Stop to Start
|
||||
place_bit1(); // Startbit(1)
|
||||
send_byte(data_h);
|
||||
send_byte(data_l);
|
||||
for (int8_t i = 0; i < len; i++) {
|
||||
send_byte(buf[i]);
|
||||
// xprintf("%02X ", buf[i]);
|
||||
}
|
||||
place_bit0(); // Stopbit(0);
|
||||
sei();
|
||||
}
|
||||
|
||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
|
||||
uint8_t buf[2] = {data_h, data_l};
|
||||
adb_host_listen_buf(addr, reg, buf, 2);
|
||||
}
|
||||
|
||||
void adb_host_flush(uint8_t addr) {
|
||||
cli();
|
||||
attention();
|
||||
send_byte((addr << 4) | ADB_CMD_FLUSH);
|
||||
place_bit0(); // Stopbit(0)
|
||||
_delay_us(200); // Tlt/Stop to Start
|
||||
sei();
|
||||
}
|
||||
|
||||
// send state of LEDs
|
||||
void adb_host_kbd_led(uint8_t led) {
|
||||
// Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
|
||||
// send upper byte (not used)
|
||||
// send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
|
||||
adb_host_listen(0x2A, 0, led & 0x07);
|
||||
// Listen Register2
|
||||
// upper byte: not used
|
||||
// lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
|
||||
adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
|
||||
}
|
||||
|
||||
#ifdef ADB_PSW_BIT
|
||||
@@ -327,7 +372,7 @@ Commands
|
||||
|
||||
bits commands
|
||||
------------------------------------------------------
|
||||
- - - - 0 0 0 0 Send Request(reset all devices)
|
||||
- - - - 0 0 0 0 Send Reset(reset all devices)
|
||||
A A A A 0 0 0 1 Flush(reset a device)
|
||||
- - - - 0 0 1 0 Reserved
|
||||
- - - - 0 0 1 1 Reserved
|
||||
@@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)
|
||||
| +----------------------------- Delete
|
||||
+------------------------------- Reserved
|
||||
|
||||
Address, Handler ID and bits(Register3)
|
||||
1514131211 . . 8 7 . . . . . . 0
|
||||
| | | | | | | | | | | | | | | |
|
||||
| | | | | | | | +-+-+-+-+-+-+-+- Handler ID
|
||||
| | | | +-+-+-+----------------- Address
|
||||
| | | +------------------------- 0
|
||||
| | +--------------------------- Service request enable(1 = enabled)
|
||||
| +----------------------------- Exceptional event(alwyas 1 if not used)
|
||||
+------------------------------- 0
|
||||
|
||||
ADB Bit Cells
|
||||
bit cell time: 70-130us
|
||||
low part of bit0: 60-70% of bit cell
|
||||
low part of bit1: 30-40% of bit cell
|
||||
|
||||
bit cell time 70us 130us
|
||||
--------------------------------------------
|
||||
low part of bit0 42-49 78-91
|
||||
high part of bit0 21-28 39-52
|
||||
low part of bit1 21-28 39-52
|
||||
high part of bit1 42-49 78-91
|
||||
|
||||
|
||||
bit0:
|
||||
70us bit cell:
|
||||
____________~~~~~~
|
||||
42-49 21-28
|
||||
|
||||
130us bit cell:
|
||||
____________~~~~~~
|
||||
78-91 39-52
|
||||
|
||||
bit1:
|
||||
70us bit cell:
|
||||
______~~~~~~~~~~~~
|
||||
21-28 42-49
|
||||
|
||||
130us bit cell:
|
||||
______~~~~~~~~~~~~
|
||||
39-52 78-91
|
||||
|
||||
[from Apple IIgs Hardware Reference Second Edition]
|
||||
|
||||
Keyboard Handle ID
|
||||
Apple Standard Keyboard M0116: 0x01
|
||||
Apple Extended Keyboard M0115: 0x02
|
||||
Apple Extended Keyboard II M3501: 0x02
|
||||
Apple Adjustable Keybaord: 0x10
|
||||
|
||||
http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
|
||||
|
||||
END_OF_ADB
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
@@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#define ADB_POWER 0x7F
|
||||
#define ADB_CAPS 0x39
|
||||
|
||||
/* ADB commands */
|
||||
// Default Address
|
||||
#define ADB_ADDR_0 0
|
||||
#define ADB_ADDR_DONGLE 1
|
||||
#define ADB_ADDR_KEYBOARD 2
|
||||
#define ADB_ADDR_MOUSE 3
|
||||
#define ADB_ADDR_TABLET 4
|
||||
#define ADB_ADDR_APPLIANCE 7
|
||||
#define ADB_ADDR_8 8
|
||||
#define ADB_ADDR_9 9
|
||||
#define ADB_ADDR_10 10
|
||||
#define ADB_ADDR_11 11
|
||||
#define ADB_ADDR_12 12
|
||||
#define ADB_ADDR_13 13
|
||||
#define ADB_ADDR_14 14
|
||||
#define ADB_ADDR_15 15
|
||||
// for temporary purpose, do not use for polling
|
||||
#define ADB_ADDR_TMP 15
|
||||
#define ADB_ADDR_MOUSE_POLL 10
|
||||
// Command Type
|
||||
#define ADB_CMD_RESET 0
|
||||
#define ADB_CMD_FLUSH 1
|
||||
#define ADB_CMD_LISTEN 8
|
||||
#define ADB_CMD_TALK 12
|
||||
// Register
|
||||
#define ADB_REG_0 0
|
||||
#define ADB_REG_1 1
|
||||
#define ADB_REG_2 2
|
||||
#define ADB_REG_3 3
|
||||
|
||||
/* ADB keyboard handler id */
|
||||
#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
|
||||
#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
|
||||
#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
|
||||
#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
|
||||
#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
|
||||
#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
|
||||
#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
|
||||
#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
|
||||
#define ADB_HANDLER_EXTENDED_MOUSE 0x04
|
||||
#define ADB_HANDLER_TURBO_MOUSE 0x32
|
||||
|
||||
// ADB host
|
||||
void adb_host_init(void);
|
||||
bool adb_host_psw(void);
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
|
||||
uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
|
||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
|
||||
void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
|
||||
void adb_host_flush(uint8_t addr);
|
||||
void adb_host_kbd_led(uint8_t led);
|
||||
uint16_t adb_host_kbd_recv(void);
|
||||
uint16_t adb_host_mouse_recv(void);
|
||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
|
||||
void adb_host_kbd_led(uint8_t led);
|
||||
void adb_mouse_task(void);
|
||||
void adb_mouse_init(void);
|
||||
|
||||
// ADB Mouse
|
||||
void adb_mouse_task(void);
|
||||
void adb_mouse_init(void);
|
||||
|
||||
@@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
|
||||
|
||||
DmacDescriptor dmac_desc;
|
||||
DmacDescriptor dmac_desc_wb;
|
||||
|
||||
static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
|
||||
static uint8_t i2c_led_q_s; // Start of circular buffer
|
||||
static uint8_t i2c_led_q_e; // End of circular buffer
|
||||
|
||||
@@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# include "issi3733_driver.h"
|
||||
# include "config.h"
|
||||
|
||||
__attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
|
||||
__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
|
||||
extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
|
||||
extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
|
||||
|
||||
uint8_t I2C3733_Init_Control(void);
|
||||
uint8_t I2C3733_Init_Drivers(void);
|
||||
|
||||
@@ -305,11 +305,5 @@ int main(void) {
|
||||
// dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
|
||||
}
|
||||
#endif // CONSOLE_ENABLE
|
||||
|
||||
// Run housekeeping
|
||||
housekeeping_task_kb();
|
||||
housekeeping_task_user();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -15,16 +15,17 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arm_atsam_protocol.h"
|
||||
#include "tmk_core/common/led.h"
|
||||
#include "rgb_matrix.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
# include "arm_atsam_protocol.h"
|
||||
# include "led.h"
|
||||
# include "rgb_matrix.h"
|
||||
# include <string.h>
|
||||
# include <math.h>
|
||||
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
|
||||
static void md_rgb_matrix_config_override(int i);
|
||||
#endif // USE_MASSDROP_CONFIGURATOR
|
||||
# endif // USE_MASSDROP_CONFIGURATOR
|
||||
|
||||
void SERCOM1_0_Handler(void) {
|
||||
if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
|
||||
@@ -58,17 +59,17 @@ RGB led_buffer[ISSI3733_LED_COUNT];
|
||||
uint8_t gcr_desired;
|
||||
uint8_t gcr_actual;
|
||||
uint8_t gcr_actual_last;
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
uint8_t gcr_breathe;
|
||||
float breathe_mult;
|
||||
float pomod;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#define ACT_GCR_NONE 0
|
||||
#define ACT_GCR_INC 1
|
||||
#define ACT_GCR_DEC 2
|
||||
# define ACT_GCR_NONE 0
|
||||
# define ACT_GCR_INC 1
|
||||
# define ACT_GCR_DEC 2
|
||||
|
||||
#define LED_GCR_STEP_AUTO 2
|
||||
# define LED_GCR_STEP_AUTO 2
|
||||
|
||||
static uint8_t gcr_min_counter;
|
||||
static uint8_t v_5v_cat_hit;
|
||||
@@ -78,11 +79,11 @@ void gcr_compute(void) {
|
||||
uint8_t action = ACT_GCR_NONE;
|
||||
uint8_t gcr_use = gcr_desired;
|
||||
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
if (led_animation_breathing) {
|
||||
gcr_use = gcr_breathe;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
// If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
|
||||
if (v_5v < V5_CAT) {
|
||||
@@ -150,7 +151,7 @@ void gcr_compute(void) {
|
||||
gcr_actual -= LED_GCR_STEP_AUTO;
|
||||
gcr_min_counter = 0;
|
||||
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
// If breathe mode is active, the top end can fluctuate if the host can not supply enough current
|
||||
// So set the breathe GCR to where it becomes stable
|
||||
if (led_animation_breathing == 1) {
|
||||
@@ -159,7 +160,7 @@ void gcr_compute(void) {
|
||||
// and the same would happen maybe one or two more times. Therefore I'm favoring
|
||||
// powering through one full breathe and letting gcr settle completely
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,25 +197,25 @@ void md_rgb_matrix_prepare(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
|
||||
static void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
|
||||
if (i < ISSI3733_LED_COUNT) {
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
md_rgb_matrix_config_override(i);
|
||||
#else
|
||||
# else
|
||||
led_buffer[i].r = r;
|
||||
led_buffer[i].g = g;
|
||||
led_buffer[i].b = b;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
|
||||
static void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
|
||||
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
|
||||
led_set_one(i, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void init(void) {
|
||||
static void init(void) {
|
||||
DBGC(DC_LED_MATRIX_INIT_BEGIN);
|
||||
|
||||
issi3733_prepare_arrays();
|
||||
@@ -227,16 +228,16 @@ void init(void) {
|
||||
DBGC(DC_LED_MATRIX_INIT_COMPLETE);
|
||||
}
|
||||
|
||||
void flush(void) {
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
static void flush(void) {
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
if (!led_enabled) {
|
||||
return;
|
||||
} // Prevent calculations and I2C traffic if LED drivers are not enabled
|
||||
#else
|
||||
# else
|
||||
if (!sr_exp_data.bit.SDB_N) {
|
||||
return;
|
||||
} // Prevent calculations and I2C traffic if LED drivers are not enabled
|
||||
#endif
|
||||
# endif
|
||||
|
||||
// Wait for previous transfer to complete
|
||||
while (i2c_led_q_running) {
|
||||
@@ -249,7 +250,7 @@ void flush(void) {
|
||||
*led_map[i].rgb.b = led_buffer[i].b;
|
||||
}
|
||||
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
breathe_mult = 1;
|
||||
|
||||
if (led_animation_breathing) {
|
||||
@@ -275,7 +276,7 @@ void flush(void) {
|
||||
pomod = (uint32_t)pomod % 10000;
|
||||
pomod /= 100.0f;
|
||||
|
||||
#endif // USE_MASSDROP_CONFIGURATOR
|
||||
# endif // USE_MASSDROP_CONFIGURATOR
|
||||
|
||||
uint8_t drvid;
|
||||
|
||||
@@ -295,25 +296,27 @@ void md_rgb_matrix_indicators(void) {
|
||||
if (kbled && rgb_matrix_config.enable) {
|
||||
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
|
||||
if (
|
||||
#if USB_LED_NUM_LOCK_SCANCODE != 255
|
||||
# if USB_LED_NUM_LOCK_SCANCODE != 255
|
||||
(led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) ||
|
||||
#endif // NUM LOCK
|
||||
#if USB_LED_CAPS_LOCK_SCANCODE != 255
|
||||
# endif // NUM LOCK
|
||||
# if USB_LED_CAPS_LOCK_SCANCODE != 255
|
||||
(led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) ||
|
||||
#endif // CAPS LOCK
|
||||
#if USB_LED_SCROLL_LOCK_SCANCODE != 255
|
||||
# endif // CAPS LOCK
|
||||
# if USB_LED_SCROLL_LOCK_SCANCODE != 255
|
||||
(led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) ||
|
||||
#endif // SCROLL LOCK
|
||||
#if USB_LED_COMPOSE_SCANCODE != 255
|
||||
# endif // SCROLL LOCK
|
||||
# if USB_LED_COMPOSE_SCANCODE != 255
|
||||
(led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) ||
|
||||
#endif // COMPOSE
|
||||
#if USB_LED_KANA_SCANCODE != 255
|
||||
# endif // COMPOSE
|
||||
# if USB_LED_KANA_SCANCODE != 255
|
||||
(led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) ||
|
||||
#endif // KANA
|
||||
# endif // KANA
|
||||
(0)) {
|
||||
led_buffer[i].r = 255 - led_buffer[i].r;
|
||||
led_buffer[i].g = 255 - led_buffer[i].g;
|
||||
led_buffer[i].b = 255 - led_buffer[i].b;
|
||||
if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
|
||||
led_buffer[i].r = 255 - led_buffer[i].r;
|
||||
led_buffer[i].g = 255 - led_buffer[i].g;
|
||||
led_buffer[i].b = 255 - led_buffer[i].b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,7 +328,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .se
|
||||
= Legacy Lighting Support =
|
||||
==============================================================================*/
|
||||
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
// Ported from Massdrop QMK GitHub Repo
|
||||
|
||||
// TODO?: wire these up to keymap.c
|
||||
@@ -467,4 +470,5 @@ static void md_rgb_matrix_config_override(int i) {
|
||||
led_buffer[i].b = (uint8_t)bo;
|
||||
}
|
||||
|
||||
#endif // USE_MASSDROP_CONFIGURATOR
|
||||
# endif // USE_MASSDROP_CONFIGURATOR
|
||||
#endif // RGB_MATRIX_ENABLE
|
||||
|
||||
@@ -15,9 +15,10 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_MASSDROP_CONFIGURATOR
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
|
||||
# include "md_rgb_matrix.h"
|
||||
# include "md_rgb_matrix.h"
|
||||
|
||||
// Teal <-> Salmon
|
||||
led_setup_t leds_teal_salmon[] = {
|
||||
@@ -96,4 +97,5 @@ void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_ye
|
||||
|
||||
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);
|
||||
|
||||
#endif
|
||||
# endif // USE_MASSDROP_CONFIGURATOR
|
||||
#endif // RGB_MATRIX_ENABLE
|
||||
|
||||
@@ -374,39 +374,33 @@ static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
|
||||
|
||||
COMPILER_WORD_ALIGNED
|
||||
UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
|
||||
// clang-format off
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x80, // Usage (System Control)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, REPORT_ID_SYSTEM, // Report ID
|
||||
0x1A, 0x81,
|
||||
0x00, // Usage Minimum (81) (System Power Down)
|
||||
0x2A, 0x83,
|
||||
0x00, // Usage Maximum (83) (System Wake Up)
|
||||
0x16, 0x01,
|
||||
0x00, // Logical Minimum (1)
|
||||
0x26, 0x03,
|
||||
0x00, // Logical Maximum (3)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0xC0, // End Collection
|
||||
0x19, 0x01, // Usage Minimum (Pointer)
|
||||
0x2A, 0xB7, 0x00, // Usage Maximum (System Display LCD Autoscale)
|
||||
0x15, 0x01, // Logical Minimum
|
||||
0x26, 0xB7, 0x00, // Logical Maximum
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0xC0, // End Collection
|
||||
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x09, 0x01, // Usage (Consumer Control)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, REPORT_ID_CONSUMER, // Report ID
|
||||
0x1A, 0x01,
|
||||
0x00, // Usage Minimum (Consumer Control)
|
||||
0x2A, 0x9C,
|
||||
0x02, // Usage Maximum (AC Distribute Vertically)
|
||||
0x16, 0x01,
|
||||
0x00, // Logical Minimum
|
||||
0x26, 0x9C,
|
||||
0x02, // Logical Maximum
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0xC0 // End Collection
|
||||
0x19, 0x01, // Usage Minimum (Consumer Control)
|
||||
0x2A, 0xA0, 0x02, // Usage Maximum (AC Desktop Show All Applications)
|
||||
0x15, 0x01, // Logical Minimum
|
||||
0x26, 0xA0, 0x02, // Logical Maximum
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0xC0 // End Collection
|
||||
//clang-format on
|
||||
}};
|
||||
|
||||
static bool udi_hid_exk_setreport(void);
|
||||
|
||||
@@ -186,9 +186,10 @@ COMPILER_PACK_RESET()
|
||||
#define USB_HID_COUNTRY_UK 32 // UK
|
||||
#define USB_HID_COUNTRY_US 33 // US
|
||||
#define USB_HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia
|
||||
#define USB_HID_COUNTRY_TURKISH_F 35 // Turkish-F
|
||||
//! @}
|
||||
//! @}
|
||||
#define USB_HID_COUNTRY_TURKISH_F \
|
||||
35 // Turkish-F
|
||||
//! @}
|
||||
//! @}
|
||||
//! @}
|
||||
|
||||
//! \name HID KEYS values
|
||||
|
||||
@@ -167,6 +167,7 @@ int main(void) {
|
||||
keyboard_setup();
|
||||
|
||||
/* Init USB */
|
||||
usb_event_queue_init();
|
||||
init_usb_driver(&USB_DRIVER);
|
||||
|
||||
#ifdef MIDI_ENABLE
|
||||
@@ -225,6 +226,8 @@ int main(void) {
|
||||
|
||||
/* Main loop */
|
||||
while (true) {
|
||||
usb_event_queue_task();
|
||||
|
||||
#if !defined(NO_USB_STARTUP_CHECK)
|
||||
if (USB_DRIVER.state == USB_SUSPENDED) {
|
||||
print("[s]");
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <ch.h>
|
||||
#include <hal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usb_main.h"
|
||||
|
||||
@@ -50,6 +51,7 @@ extern keymap_config_t keymap_config;
|
||||
#ifdef WEBUSB_ENABLE
|
||||
# include "webusb.h"
|
||||
#endif
|
||||
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
# include "joystick.h"
|
||||
#endif
|
||||
@@ -168,6 +170,7 @@ static const USBEndpointConfig shared_ep_config = {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WEBUSB_ENABLE
|
||||
/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device.
|
||||
*
|
||||
@@ -397,6 +400,69 @@ static usb_driver_configs_t drivers = {
|
||||
* ---------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define USB_EVENT_QUEUE_SIZE 16
|
||||
usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
|
||||
uint8_t event_queue_head;
|
||||
uint8_t event_queue_tail;
|
||||
|
||||
void usb_event_queue_init(void) {
|
||||
// Initialise the event queue
|
||||
memset(&event_queue, 0, sizeof(event_queue));
|
||||
event_queue_head = 0;
|
||||
event_queue_tail = 0;
|
||||
}
|
||||
|
||||
static inline bool usb_event_queue_enqueue(usbevent_t event) {
|
||||
uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
|
||||
if (next == event_queue_tail) {
|
||||
return false;
|
||||
}
|
||||
event_queue[event_queue_head] = event;
|
||||
event_queue_head = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool usb_event_queue_dequeue(usbevent_t *event) {
|
||||
if (event_queue_head == event_queue_tail) {
|
||||
return false;
|
||||
}
|
||||
*event = event_queue[event_queue_tail];
|
||||
event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void usb_event_suspend_handler(void) {
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_enable();
|
||||
#endif /* SLEEP_LED_ENABLE */
|
||||
}
|
||||
|
||||
static inline void usb_event_wakeup_handler(void) {
|
||||
suspend_wakeup_init();
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_disable();
|
||||
// NOTE: converters may not accept this
|
||||
led_set(host_keyboard_leds());
|
||||
#endif /* SLEEP_LED_ENABLE */
|
||||
}
|
||||
|
||||
void usb_event_queue_task(void) {
|
||||
usbevent_t event;
|
||||
while (usb_event_queue_dequeue(&event)) {
|
||||
switch (event) {
|
||||
case USB_EVENT_SUSPEND:
|
||||
usb_event_suspend_handler();
|
||||
break;
|
||||
case USB_EVENT_WAKEUP:
|
||||
usb_event_wakeup_handler();
|
||||
break;
|
||||
default:
|
||||
// Nothing to do, we don't handle it.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handles the USB driver global events
|
||||
* TODO: maybe disable some things when connection is lost? */
|
||||
static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||
@@ -431,9 +497,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||
osalSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_SUSPEND:
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_enable();
|
||||
#endif /* SLEEP_LED_ENABLE */
|
||||
usb_event_queue_enqueue(USB_EVENT_SUSPEND);
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_UNCONFIGURED:
|
||||
/* Falls into.*/
|
||||
@@ -454,12 +518,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
|
||||
qmkusbWakeupHookI(&drivers.array[i].driver);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
suspend_wakeup_init();
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_disable();
|
||||
// NOTE: converters may not accept this
|
||||
led_set(host_keyboard_leds());
|
||||
#endif /* SLEEP_LED_ENABLE */
|
||||
usb_event_queue_enqueue(USB_EVENT_WAKEUP);
|
||||
return;
|
||||
|
||||
case USB_EVENT_STALLED:
|
||||
@@ -575,7 +634,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
|
||||
if (!keymap_config.nkro && keyboard_idle) {
|
||||
#else /* NKRO_ENABLE */
|
||||
if (keyboard_idle) {
|
||||
#endif /* NKRO_ENABLE */
|
||||
#endif /* NKRO_ENABLE */
|
||||
/* arm the idle timer if boot protocol & idle */
|
||||
osalSysLockFromISR();
|
||||
chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
|
||||
@@ -867,7 +926,7 @@ void send_mouse(report_mouse_t *report) {
|
||||
}
|
||||
|
||||
#else /* MOUSE_ENABLE */
|
||||
void send_mouse(report_mouse_t *report) { (void)report; }
|
||||
void send_mouse(report_mouse_t *report) { (void)report; }
|
||||
#endif /* MOUSE_ENABLE */
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
@@ -923,9 +982,32 @@ void send_consumer(uint16_t data) {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
|
||||
int8_t sendchar(uint8_t c) {
|
||||
// The previous implmentation had timeouts, but I think it's better to just slow down
|
||||
// and make sure that everything is transferred, rather than dropping stuff
|
||||
return chnWrite(&drivers.console_driver.driver, &c, 1);
|
||||
static bool timed_out = false;
|
||||
/* The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
|
||||
*
|
||||
* When a 5ms timeout write has timed out, hid_listen is most likely not running, or not
|
||||
* listening to this keyboard, so we go into the timed_out state. In this state we assume
|
||||
* that hid_listen is most likely not gonna be connected to us any time soon, so it would
|
||||
* be wasteful to write follow-up characters with a 5ms timeout, it would all add up and
|
||||
* unncecessarily slow down the firmware. However instead of just dropping the characters,
|
||||
* we write them with a TIME_IMMEDIATE timeout, which is a zero timeout,
|
||||
* and this will succeed only if hid_listen gets connected again. When a write with
|
||||
* TIME_IMMEDIATE timeout succeeds, we know that hid_listen is listening to us again, and
|
||||
* we can go back to the timed_out = false state, and following writes will be executed
|
||||
* with a 5ms timeout. The reason we don't just send all characters with the TIME_IMMEDIATE
|
||||
* timeout is that this could cause bytes to be lost even if hid_listen is running, if there
|
||||
* is a lot of data being sent over the console.
|
||||
*
|
||||
* This logic will work correctly as long as hid_listen is able to receive at least 200
|
||||
* bytes per second. On a heavily overloaded machine that's so overloaded that it's
|
||||
* unusable, and constantly swapping, hid_listen might have trouble receiving 200 bytes per
|
||||
* second, so some bytes might be lost on the console.
|
||||
*/
|
||||
|
||||
const sysinterval_t timeout = timed_out ? TIME_IMMEDIATE : TIME_MS2I(5);
|
||||
const size_t result = chnWriteTimeout(&drivers.console_driver.driver, &c, 1, timeout);
|
||||
timed_out = (result == 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Just a dummy function for now, this could be exposed as a weak function
|
||||
@@ -946,15 +1028,8 @@ void console_task(void) {
|
||||
} while (size > 0);
|
||||
}
|
||||
|
||||
#else /* CONSOLE_ENABLE */
|
||||
int8_t sendchar(uint8_t c) {
|
||||
(void)c;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONSOLE_ENABLE */
|
||||
|
||||
void _putchar(char character) { sendchar(character); }
|
||||
|
||||
#ifdef RAW_ENABLE
|
||||
void raw_hid_send(uint8_t *data, uint8_t length) {
|
||||
// TODO: implement variable size packet
|
||||
|
||||
@@ -37,6 +37,17 @@ void init_usb_driver(USBDriver *usbp);
|
||||
/* Restart the USB driver and bus */
|
||||
void restart_usb_driver(USBDriver *usbp);
|
||||
|
||||
/* ---------------
|
||||
* USB Event queue
|
||||
* ---------------
|
||||
*/
|
||||
|
||||
/* Initialisation of the FIFO */
|
||||
void usb_event_queue_init(void);
|
||||
|
||||
/* Task to dequeue and execute any handlers for the USB events on the main thread */
|
||||
void usb_event_queue_task(void);
|
||||
|
||||
/* ---------------
|
||||
* Keyboard header
|
||||
* ---------------
|
||||
|
||||
@@ -782,9 +782,7 @@ static void send_keyboard(report_keyboard_t *report) {
|
||||
uint8_t timeout = 255;
|
||||
|
||||
#ifdef BLUETOOTH_ENABLE
|
||||
uint8_t where = where_to_send();
|
||||
|
||||
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
|
||||
if (where_to_send() == OUTPUT_BLUETOOTH) {
|
||||
# ifdef MODULE_ADAFRUIT_BLE
|
||||
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
|
||||
# elif MODULE_RN42
|
||||
@@ -797,9 +795,6 @@ static void send_keyboard(report_keyboard_t *report) {
|
||||
serial_send(report->keys[i]);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -840,9 +835,7 @@ static void send_mouse(report_mouse_t *report) {
|
||||
uint8_t timeout = 255;
|
||||
|
||||
# ifdef BLUETOOTH_ENABLE
|
||||
uint8_t where = where_to_send();
|
||||
|
||||
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
|
||||
if (where_to_send() == OUTPUT_BLUETOOTH) {
|
||||
# ifdef MODULE_ADAFRUIT_BLE
|
||||
// FIXME: mouse buttons
|
||||
adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
|
||||
@@ -857,9 +850,6 @@ static void send_mouse(report_mouse_t *report) {
|
||||
serial_send(report->h); // should try sending the wheel h here
|
||||
serial_send(0x00);
|
||||
# endif
|
||||
}
|
||||
|
||||
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
@@ -918,9 +908,13 @@ static void send_system(uint16_t data) {
|
||||
static void send_consumer(uint16_t data) {
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
# ifdef BLUETOOTH_ENABLE
|
||||
<<<<<<< HEAD
|
||||
uint8_t where = where_to_send();
|
||||
|
||||
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
|
||||
=======
|
||||
if (where_to_send() == OUTPUT_BLUETOOTH) {
|
||||
>>>>>>> 0.12.52~1
|
||||
# ifdef MODULE_ADAFRUIT_BLE
|
||||
adafruit_ble_send_consumer_key(data);
|
||||
# elif MODULE_RN42
|
||||
@@ -934,9 +928,12 @@ static void send_consumer(uint16_t data) {
|
||||
serial_send(bitmap & 0xFF);
|
||||
serial_send((bitmap >> 8) & 0xFF);
|
||||
# endif
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
|
||||
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
|
||||
=======
|
||||
>>>>>>> 0.12.52~1
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
@@ -955,9 +952,14 @@ static void send_consumer(uint16_t data) {
|
||||
* FIXME: Needs doc
|
||||
*/
|
||||
int8_t sendchar(uint8_t c) {
|
||||
<<<<<<< HEAD
|
||||
// Not wait once timeouted.
|
||||
=======
|
||||
// Do not wait if the previous write has timed_out.
|
||||
>>>>>>> 0.12.52~1
|
||||
// Because sendchar() is called so many times, waiting each call causes big lag.
|
||||
static bool timeouted = false;
|
||||
// The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
|
||||
static bool timed_out = false;
|
||||
|
||||
// prevents Console_Task() from running during sendchar() runs.
|
||||
// or char will be lost. These two function is mutually exclusive.
|
||||
@@ -971,11 +973,11 @@ int8_t sendchar(uint8_t c) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
if (timeouted && !Endpoint_IsReadWriteAllowed()) {
|
||||
if (timed_out && !Endpoint_IsReadWriteAllowed()) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
timeouted = false;
|
||||
timed_out = false;
|
||||
|
||||
uint8_t timeout = SEND_TIMEOUT;
|
||||
while (!Endpoint_IsReadWriteAllowed()) {
|
||||
@@ -986,7 +988,7 @@ int8_t sendchar(uint8_t c) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
if (!(timeout--)) {
|
||||
timeouted = true;
|
||||
timed_out = true;
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
_delay_ms(1);
|
||||
@@ -1136,7 +1138,6 @@ static void setup_usb(void) {
|
||||
|
||||
// for Console_Task
|
||||
USB_Device_EnableSOFEvents();
|
||||
print_set_sendchar(sendchar);
|
||||
}
|
||||
|
||||
/** \brief Main
|
||||
|
||||
@@ -21,21 +21,11 @@ enum outputs {
|
||||
|
||||
OUTPUT_NONE,
|
||||
OUTPUT_USB,
|
||||
OUTPUT_BLUETOOTH,
|
||||
|
||||
// backward compatibility
|
||||
OUTPUT_USB_AND_BT
|
||||
OUTPUT_BLUETOOTH
|
||||
};
|
||||
|
||||
/**
|
||||
* backward compatibility for BLUETOOTH_ENABLE, send to BT and USB by default
|
||||
*/
|
||||
#ifndef OUTPUT_DEFAULT
|
||||
# ifdef BLUETOOTH_ENABLE
|
||||
# define OUTPUT_DEFAULT OUTPUT_USB_AND_BT
|
||||
# else
|
||||
# define OUTPUT_DEFAULT OUTPUT_AUTO
|
||||
# endif
|
||||
# define OUTPUT_DEFAULT OUTPUT_AUTO
|
||||
#endif
|
||||
|
||||
void set_output(uint8_t output);
|
||||
|
||||
@@ -95,11 +95,11 @@ void m0110_init(void) {
|
||||
uint8_t data;
|
||||
m0110_send(M0110_MODEL);
|
||||
data = m0110_recv();
|
||||
print("m0110_init model: "); phex(data); print("\n");
|
||||
print("m0110_init model: "); print_hex8(data); print("\n");
|
||||
|
||||
m0110_send(M0110_TEST);
|
||||
data = m0110_recv();
|
||||
print("m0110_init test: "); phex(data); print("\n");
|
||||
print("m0110_init test: "); print_hex8(data); print("\n");
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ uint8_t m0110_send(uint8_t data) {
|
||||
return 1;
|
||||
ERROR:
|
||||
print("m0110_send err: ");
|
||||
phex(m0110_error);
|
||||
print_hex8(m0110_error);
|
||||
print("\n");
|
||||
_delay_ms(500);
|
||||
idle();
|
||||
@@ -146,7 +146,7 @@ uint8_t m0110_recv(void) {
|
||||
return data;
|
||||
ERROR:
|
||||
print("m0110_recv err: ");
|
||||
phex(m0110_error);
|
||||
print_hex8(m0110_error);
|
||||
print("\n");
|
||||
_delay_ms(500);
|
||||
idle();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "usb_descriptor.h"
|
||||
#include "process_midi.h"
|
||||
#if API_SYSEX_ENABLE
|
||||
# include "api.h"
|
||||
# include "api_sysex.h"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -190,7 +190,7 @@ static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {
|
||||
static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) {
|
||||
if (!debug_mouse) return;
|
||||
print("ps2_mouse: [");
|
||||
phex(mouse_report->buttons);
|
||||
print_hex8(mouse_report->buttons);
|
||||
print("|");
|
||||
print_hex8((uint8_t)mouse_report->x);
|
||||
print(" ");
|
||||
|
||||
@@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SERIAL_UART_DATA UDR1
|
||||
|
||||
/* host role */
|
||||
void serial_init(void);
|
||||
uint8_t serial_recv(void);
|
||||
|
||||
@@ -40,6 +40,22 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <avr/interrupt.h>
|
||||
#include "serial.h"
|
||||
|
||||
#ifndef SERIAL_UART_BAUD
|
||||
# define SERIAL_UART_BAUD 9600
|
||||
#endif
|
||||
|
||||
#define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1)
|
||||
#define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
|
||||
#define SERIAL_UART_RXD_VECT USART1_RX_vect
|
||||
|
||||
#ifndef SERIAL_UART_INIT_CUSTOM
|
||||
# define SERIAL_UART_INIT_CUSTOM \
|
||||
/* enable TX */ \
|
||||
UCSR1B = _BV(TXEN1); \
|
||||
/* 8-bit data */ \
|
||||
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
|
||||
// Buffer state
|
||||
// Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
|
||||
@@ -61,7 +77,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
# define rbuf_check_rts_hi()
|
||||
#endif
|
||||
|
||||
void serial_init(void) { SERIAL_UART_INIT(); }
|
||||
void serial_init(void) {
|
||||
do {
|
||||
// Set baud rate
|
||||
UBRR1L = SERIAL_UART_UBRR;
|
||||
UBRR1L = SERIAL_UART_UBRR >> 8;
|
||||
SERIAL_UART_INIT_CUSTOM;
|
||||
} while (0);
|
||||
}
|
||||
|
||||
// RX ring buffer
|
||||
#define RBUF_SIZE 256
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "report.h"
|
||||
#include "usb_descriptor.h"
|
||||
#ifdef WEBUSB_ENABLE
|
||||
#include "webusb_descriptor.h"
|
||||
# include "webusb_descriptor.h"
|
||||
#endif
|
||||
#include "usb_descriptor_common.h"
|
||||
|
||||
@@ -119,19 +119,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
|
||||
# endif
|
||||
HID_RI_USAGE(8, 0x01), // Pointer
|
||||
HID_RI_COLLECTION(8, 0x00), // Physical
|
||||
// Buttons (5 bits)
|
||||
// Buttons (8 bits)
|
||||
HID_RI_USAGE_PAGE(8, 0x09), // Button
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
|
||||
HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5
|
||||
HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
|
||||
HID_RI_REPORT_COUNT(8, 0x05),
|
||||
HID_RI_REPORT_COUNT(8, 0x08),
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
// Button padding (3 bits)
|
||||
HID_RI_REPORT_COUNT(8, 0x01),
|
||||
HID_RI_REPORT_SIZE(8, 0x03),
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT),
|
||||
|
||||
// X/Y position (2 bytes)
|
||||
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
|
||||
@@ -288,8 +284,8 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
|
||||
|
||||
#ifdef WEBUSB_ENABLE
|
||||
const USB_Descriptor_BOS_t PROGMEM BOSDescriptor = BOS_DESCRIPTOR(
|
||||
(MS_OS_20_PLATFORM_DESCRIPTOR(MS_OS_20_VENDOR_CODE, MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH))
|
||||
(WEBUSB_PLATFORM_DESCRIPTOR(WEBUSB_VENDOR_CODE, WEBUSB_LANDING_PAGE_INDEX))
|
||||
(MS_OS_20_PLATFORM_DESCRIPTOR(MS_OS_20_VENDOR_CODE, MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH))
|
||||
(WEBUSB_PLATFORM_DESCRIPTOR(WEBUSB_VENDOR_CODE, WEBUSB_LANDING_PAGE_INDEX))
|
||||
);
|
||||
#endif
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
@@ -369,6 +365,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
|
||||
#else
|
||||
.USBSpecification = VERSION_BCD(1, 1, 0),
|
||||
#endif
|
||||
|
||||
#if VIRTSER_ENABLE
|
||||
.Class = USB_CSCP_IADDeviceClass,
|
||||
.SubClass = USB_CSCP_IADDeviceSubclass,
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
# include <hal.h>
|
||||
#endif
|
||||
#ifdef WEBUSB_ENABLE
|
||||
#include "webusb_descriptor.h"
|
||||
# include "webusb_descriptor.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -271,6 +271,7 @@ enum usb_endpoints {
|
||||
# define WEBUSB_IN_EPADDR (ENDPOINT_DIR_IN | WEBUSB_IN_EPNUM)
|
||||
# define WEBUSB_OUT_EPADDR (ENDPOINT_DIR_OUT | WEBUSB_OUT_EPNUM)
|
||||
#endif
|
||||
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
JOYSTICK_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device.
|
||||
# Please customize your programmer settings(PROGRAM_CMD)
|
||||
#
|
||||
# make teensy = Download the hex file to the device, using teensy_loader_cli.
|
||||
# (must have teensy_loader_cli installed).
|
||||
#
|
||||
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
||||
# have dfu-programmer installed).
|
||||
#
|
||||
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
||||
# have Atmel FLIP installed).
|
||||
#
|
||||
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
||||
# (must have dfu-programmer installed).
|
||||
#
|
||||
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
||||
# (must have Atmel FLIP installed).
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = usb_hid_test
|
||||
|
||||
TMK_DIR = ../../..
|
||||
|
||||
# Directory keyboard dependent files exist
|
||||
TARGET_DIR = .
|
||||
|
||||
# MCU name
|
||||
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
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
# Console for debug
|
||||
OPT_DEFS += -DCONSOLE_ENABLE
|
||||
|
||||
# Boot Section Size in bytes
|
||||
# Teensy halfKay 512
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
#OPT_DEFS += -DBOOT_SIZE=4096
|
||||
|
||||
|
||||
|
||||
SRC = test.cpp
|
||||
SRC += common/debug.c
|
||||
SRC += common/print.c
|
||||
|
||||
CONFIG_H = config.h
|
||||
|
||||
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TMK_DIR)
|
||||
VPATH += $(TMK_DIR)/common
|
||||
|
||||
|
||||
|
||||
# program Leonardo
|
||||
PROGRAM_CMD = avrdude -p$(MCU) -cavr109 -P$(DEV) -b57600 -Uflash:w:$(TARGET).hex
|
||||
|
||||
|
||||
|
||||
include $(TMK_DIR)/protocol/usb_hid.mk
|
||||
include $(TMK_DIR)/protocol/lufa.mk
|
||||
include $(TMK_DIR)/rules.mk
|
||||
@@ -1,92 +0,0 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <util/delay.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
// USB HID host
|
||||
#include "Usb.h"
|
||||
#include "hid.h"
|
||||
#include "hidboot.h"
|
||||
#include "parser.h"
|
||||
|
||||
// LUFA
|
||||
#include "lufa.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include "leonardo_led.h"
|
||||
|
||||
|
||||
static USB usb_host;
|
||||
static HIDBoot<HID_PROTOCOL_KEYBOARD> kbd(&usb_host);
|
||||
static KBDReportParser kbd_parser;
|
||||
|
||||
static void LUFA_setup(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
// Leonardo needs. Without this USB device is not recognized.
|
||||
USB_Disable();
|
||||
|
||||
USB_Init();
|
||||
|
||||
// for Console_Task
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
static void HID_setup()
|
||||
{
|
||||
// Arduino Timer startup: wiring.c
|
||||
init();
|
||||
|
||||
if (usb_host.Init() == -1) {
|
||||
debug("HID init: failed\n");
|
||||
LED_TX_OFF;
|
||||
}
|
||||
|
||||
_delay_ms(200);
|
||||
|
||||
kbd.SetReportParser(0, (HIDReportParser*)&kbd_parser);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// LED for debug
|
||||
LED_TX_INIT;
|
||||
LED_TX_ON;
|
||||
|
||||
print_enable = true;
|
||||
debug_enable = true;
|
||||
debug_matrix = true;
|
||||
debug_keyboard = true;
|
||||
debug_mouse = true;
|
||||
|
||||
LUFA_setup();
|
||||
sei();
|
||||
|
||||
// wait for startup of sendchar routine
|
||||
while (USB_DeviceState != DEVICE_STATE_Configured) ;
|
||||
if (debug_enable) {
|
||||
_delay_ms(1000);
|
||||
}
|
||||
|
||||
HID_setup();
|
||||
|
||||
debug("init: done\n");
|
||||
for (;;) {
|
||||
usb_host.Task();
|
||||
|
||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
// LUFA Task for control request
|
||||
USB_USBTask();
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -53,10 +53,10 @@ static void initForUsbConnectivity(void) {
|
||||
usbDeviceConnect();
|
||||
}
|
||||
|
||||
static void usb_remote_wakeup(void) {
|
||||
static void vusb_send_remote_wakeup(void) {
|
||||
cli();
|
||||
|
||||
int8_t ddr_orig = USBDDR;
|
||||
uint8_t ddr_orig = USBDDR;
|
||||
USBOUT |= (1 << USBMINUS);
|
||||
USBDDR = ddr_orig | USBMASK;
|
||||
USBOUT ^= USBMASK;
|
||||
@@ -70,16 +70,34 @@ static void usb_remote_wakeup(void) {
|
||||
sei();
|
||||
}
|
||||
|
||||
bool vusb_suspended = false;
|
||||
|
||||
static void vusb_suspend(void) {
|
||||
vusb_suspended = true;
|
||||
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_enable();
|
||||
#endif
|
||||
|
||||
suspend_power_down();
|
||||
}
|
||||
|
||||
#if USB_COUNT_SOF
|
||||
static void vusb_wakeup(void) {
|
||||
vusb_suspended = false;
|
||||
suspend_wakeup_init();
|
||||
|
||||
# ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_disable();
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Setup USB
|
||||
*
|
||||
* FIXME: Needs doc
|
||||
*/
|
||||
static void setup_usb(void) {
|
||||
initForUsbConnectivity();
|
||||
|
||||
// for Console_Task
|
||||
print_set_sendchar(sendchar);
|
||||
}
|
||||
static void setup_usb(void) { initForUsbConnectivity(); }
|
||||
|
||||
/** \brief Main
|
||||
*
|
||||
@@ -87,9 +105,8 @@ static void setup_usb(void) {
|
||||
*/
|
||||
int main(void) __attribute__((weak));
|
||||
int main(void) {
|
||||
bool suspended = false;
|
||||
#if USB_COUNT_SOF
|
||||
uint16_t last_timer = timer_read();
|
||||
uint16_t sof_timer = timer_read();
|
||||
#endif
|
||||
|
||||
#ifdef CLKPR
|
||||
@@ -112,23 +129,24 @@ int main(void) {
|
||||
while (1) {
|
||||
#if USB_COUNT_SOF
|
||||
if (usbSofCount != 0) {
|
||||
suspended = false;
|
||||
usbSofCount = 0;
|
||||
last_timer = timer_read();
|
||||
# ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_disable();
|
||||
# endif
|
||||
sof_timer = timer_read();
|
||||
if (vusb_suspended) {
|
||||
vusb_wakeup();
|
||||
}
|
||||
} else {
|
||||
// Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
|
||||
if (timer_elapsed(last_timer) > 5) {
|
||||
suspended = true;
|
||||
# ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_enable();
|
||||
# endif
|
||||
if (!vusb_suspended && timer_elapsed(sof_timer) > 5) {
|
||||
vusb_suspend();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!suspended) {
|
||||
if (vusb_suspended) {
|
||||
vusb_suspend();
|
||||
if (suspend_wakeup_condition()) {
|
||||
vusb_send_remote_wakeup();
|
||||
}
|
||||
} else {
|
||||
usbPoll();
|
||||
|
||||
// TODO: configuration process is inconsistent. it sometime fails.
|
||||
@@ -145,6 +163,7 @@ int main(void) {
|
||||
raw_hid_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
usbPoll();
|
||||
|
||||
@@ -154,10 +173,7 @@ int main(void) {
|
||||
#endif
|
||||
|
||||
// Run housekeeping
|
||||
housekeeping_task_kb();
|
||||
housekeeping_task_user();
|
||||
} else if (suspend_wakeup_condition()) {
|
||||
usb_remote_wakeup();
|
||||
housekeeping_task();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
356
tmk_core/protocol/vusb/usbconfig.h
Normal file
356
tmk_core/protocol/vusb/usbconfig.h
Normal file
@@ -0,0 +1,356 @@
|
||||
/* Name: usbconfig.h
|
||||
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||
* Author: Christian Starkjohann
|
||||
* Creation Date: 2005-04-01
|
||||
* Tabsize: 4
|
||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||
* This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
General Description:
|
||||
This file is an example configuration (with inline documentation) for the USB
|
||||
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
|
||||
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
||||
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
||||
other hardware interrupt, as long as it is the highest level interrupt, see
|
||||
section at the end of this file).
|
||||
*/
|
||||
|
||||
/* ---------------------------- Hardware Config ---------------------------- */
|
||||
|
||||
#ifndef USB_CFG_IOPORTNAME
|
||||
#define USB_CFG_IOPORTNAME D
|
||||
#endif
|
||||
/* This is the port where the USB bus is connected. When you configure it to
|
||||
* "B", the registers PORTB, PINB and DDRB will be used.
|
||||
*/
|
||||
#ifndef USB_CFG_DMINUS_BIT
|
||||
#define USB_CFG_DMINUS_BIT 3
|
||||
#endif
|
||||
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
|
||||
* This may be any bit in the port.
|
||||
*/
|
||||
#ifndef USB_CFG_DPLUS_BIT
|
||||
#define USB_CFG_DPLUS_BIT 2
|
||||
#endif
|
||||
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
|
||||
* This may be any bit in the port. Please note that D+ must also be connected
|
||||
* to interrupt pin INT0! [You can also use other interrupts, see section
|
||||
* "Optional MCU Description" below, or you can connect D- to the interrupt, as
|
||||
* it is required if you use the USB_COUNT_SOF feature. If you use D- for the
|
||||
* interrupt, the USB interrupt will also be triggered at Start-Of-Frame
|
||||
* markers every millisecond.]
|
||||
*/
|
||||
#define USB_CFG_CHECK_CRC 0
|
||||
/* Define this to 1 if you want that the driver checks integrity of incoming
|
||||
* data packets (CRC checks). CRC checks cost quite a bit of code size and are
|
||||
* currently only available for 18 MHz crystal clock. You must choose
|
||||
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
|
||||
*/
|
||||
|
||||
/* ----------------------- Optional Hardware Config ------------------------ */
|
||||
|
||||
/* #define USB_CFG_PULLUP_IOPORTNAME D */
|
||||
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
||||
* V+, you can connect and disconnect the device from firmware by calling
|
||||
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
||||
* This constant defines the port on which the pullup resistor is connected.
|
||||
*/
|
||||
/* #define USB_CFG_PULLUP_BIT 4 */
|
||||
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
||||
* above) where the 1.5k pullup resistor is connected. See description
|
||||
* above for details.
|
||||
*/
|
||||
|
||||
/* --------------------------- Functional Range ---------------------------- */
|
||||
|
||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
|
||||
/* Define this to 1 if you want to compile a version with two endpoints: The
|
||||
* default control endpoint 0 and an interrupt-in endpoint (any other endpoint
|
||||
* number).
|
||||
*/
|
||||
#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.
|
||||
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
|
||||
*/
|
||||
#define USB_CFG_EP3_NUMBER 3
|
||||
/* If the so-called endpoint 3 is used, it can now be configured to any other
|
||||
* endpoint number (except 0) with this macro. Default if undefined is 3.
|
||||
*/
|
||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT4 1
|
||||
/* Define this to 1 if you want to compile a version with three endpoints: The
|
||||
* default control endpoint 0, an interrupt-in endpoint 4 (or the number
|
||||
* configured below) and a catch-all default interrupt-in endpoint as above.
|
||||
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
|
||||
*/
|
||||
#define USB_CFG_EP4_NUMBER 4
|
||||
/* If the so-called endpoint 4 is used, it can now be configured to any other
|
||||
* endpoint number (except 0) with this macro. Default if undefined is 4.
|
||||
*/
|
||||
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
|
||||
/* The above macro defines the startup condition for data toggling on the
|
||||
* interrupt/bulk endpoints 1, 3 and 4. Defaults to USBPID_DATA1.
|
||||
* Since the token is toggled BEFORE sending any data, the first packet is
|
||||
* sent with the oposite value of this configuration!
|
||||
*/
|
||||
#define USB_CFG_IMPLEMENT_HALT 0
|
||||
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
|
||||
* for endpoint 1 (interrupt endpoint). Although you may not need this feature,
|
||||
* it is required by the standard. We have made it a config option because it
|
||||
* bloats the code considerably.
|
||||
*/
|
||||
#define USB_CFG_SUPPRESS_INTR_CODE 0
|
||||
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
|
||||
* want to send any data over them. If this macro is defined to 1, functions
|
||||
* usbSetInterrupt(), usbSetInterrupt3() and usbSetInterrupt4() are omitted.
|
||||
* This is useful if you need the interrupt-in endpoints in order to comply
|
||||
* to an interface (e.g. HID), but never want to send any data. This option
|
||||
* saves a couple of bytes in flash memory and the transmit buffers in RAM.
|
||||
*/
|
||||
#define USB_CFG_IS_SELF_POWERED 0
|
||||
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
|
||||
* device is powered from the USB bus.
|
||||
*/
|
||||
#define USB_CFG_IMPLEMENT_FN_WRITE 1
|
||||
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
|
||||
* transfers. Set it to 0 if you don't need it and want to save a couple of
|
||||
* bytes.
|
||||
*/
|
||||
#define USB_CFG_IMPLEMENT_FN_READ 0
|
||||
/* Set this to 1 if you need to send control replies which are generated
|
||||
* "on the fly" when usbFunctionRead() is called. If you only want to send
|
||||
* data from a static buffer, set it to 0 and return the data from
|
||||
* usbFunctionSetup(). This saves a couple of bytes.
|
||||
*/
|
||||
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 1
|
||||
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
|
||||
* You must implement the function usbFunctionWriteOut() which receives all
|
||||
* interrupt/bulk data sent to any endpoint other than 0. The endpoint number
|
||||
* can be found in 'usbRxToken'.
|
||||
*/
|
||||
#define USB_CFG_HAVE_FLOWCONTROL 0
|
||||
/* Define this to 1 if you want flowcontrol over USB data. See the definition
|
||||
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
||||
* usbdrv.h.
|
||||
*/
|
||||
#define USB_CFG_DRIVER_FLASH_PAGE 0
|
||||
/* If the device has more than 64 kBytes of flash, define this to the 64 k page
|
||||
* where the driver's constants (descriptors) are located. Or in other words:
|
||||
* Define this to 1 for boot loaders on the ATMega128.
|
||||
*/
|
||||
#define USB_CFG_LONG_TRANSFERS 0
|
||||
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
||||
* in a single control-in or control-out transfer. Note that the capability
|
||||
* for long transfers increases the driver size.
|
||||
*/
|
||||
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
|
||||
/* This macro is a hook if you want to do unconventional things. If it is
|
||||
* defined, it's inserted at the beginning of received message processing.
|
||||
* If you eat the received message and don't want default processing to
|
||||
* proceed, do a return after doing your things. One possible application
|
||||
* (besides debugging) is to flash a status LED on each packet.
|
||||
*/
|
||||
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
|
||||
/* This macro is a hook if you need to know when an USB RESET occurs. It has
|
||||
* one parameter which distinguishes between the start of RESET state and its
|
||||
* end.
|
||||
*/
|
||||
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
|
||||
/* This macro (if defined) is executed when a USB SET_ADDRESS request was
|
||||
* received.
|
||||
*/
|
||||
#ifndef USB_COUNT_SOF
|
||||
#define USB_COUNT_SOF 1
|
||||
#endif
|
||||
/* define this macro to 1 if you need the global variable "usbSofCount" which
|
||||
* counts SOF packets. This feature requires that the hardware interrupt is
|
||||
* connected to D- instead of D+.
|
||||
*/
|
||||
/* #ifdef __ASSEMBLER__
|
||||
* macro myAssemblerMacro
|
||||
* in YL, TCNT0
|
||||
* sts timer0Snapshot, YL
|
||||
* endm
|
||||
* #endif
|
||||
* #define USB_SOF_HOOK myAssemblerMacro
|
||||
* This macro (if defined) is executed in the assembler module when a
|
||||
* Start Of Frame condition is detected. It is recommended to define it to
|
||||
* the name of an assembler macro which is defined here as well so that more
|
||||
* than one assembler instruction can be used. The macro may use the register
|
||||
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
|
||||
* immediately after an SOF pulse may be lost and must be retried by the host.
|
||||
* What can you do with this hook? Since the SOF signal occurs exactly every
|
||||
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
|
||||
* designs running on the internal RC oscillator.
|
||||
* Please note that Start Of Frame detection works only if D- is wired to the
|
||||
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
|
||||
*/
|
||||
#define USB_CFG_CHECK_DATA_TOGGLING 0
|
||||
/* define this macro to 1 if you want to filter out duplicate data packets
|
||||
* sent by the host. Duplicates occur only as a consequence of communication
|
||||
* errors, when the host does not receive an ACK. Please note that you need to
|
||||
* implement the filtering yourself in usbFunctionWriteOut() and
|
||||
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
|
||||
* for each control- and out-endpoint to check for duplicate packets.
|
||||
*/
|
||||
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
||||
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
||||
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
||||
*/
|
||||
#define USB_USE_FAST_CRC 0
|
||||
/* The assembler module has two implementations for the CRC algorithm. One is
|
||||
* faster, the other is smaller. This CRC routine is only used for transmitted
|
||||
* messages where timing is not critical. The faster routine needs 31 cycles
|
||||
* per byte while the smaller one needs 61 to 69 cycles. The faster routine
|
||||
* may be worth the 32 bytes bigger code size if you transmit lots of data and
|
||||
* run the AVR close to its limit.
|
||||
*/
|
||||
|
||||
/* -------------------------- Device Description --------------------------- */
|
||||
|
||||
#define USB_CFG_VENDOR_ID
|
||||
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||
* own Vendor ID, define it here. Otherwise you may use one of obdev's free
|
||||
* shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
|
||||
* *** IMPORTANT NOTE ***
|
||||
* This template uses obdev's shared VID/PID pair for Vendor Class devices
|
||||
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
|
||||
* the implications!
|
||||
*/
|
||||
#define USB_CFG_DEVICE_ID
|
||||
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||
* you may use one of obdev's free shared VID/PID pairs. See the file
|
||||
* USB-IDs-for-free.txt for details!
|
||||
* *** IMPORTANT NOTE ***
|
||||
* This template uses obdev's shared VID/PID pair for Vendor Class devices
|
||||
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
|
||||
* the implications!
|
||||
*/
|
||||
#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
|
||||
* "usbHidReportDescriptor" to your code which contains the report descriptor.
|
||||
* Don't forget to keep the array and this define in sync!
|
||||
*/
|
||||
|
||||
/* #define USB_PUBLIC static */
|
||||
/* Use the define above if you #include usbdrv.c instead of linking against it.
|
||||
* This technique saves a couple of bytes in flash memory.
|
||||
*/
|
||||
|
||||
/* ------------------- Fine Control over USB Descriptors ------------------- */
|
||||
/* If you don't want to use the driver's default USB descriptors, you can
|
||||
* provide our own. These can be provided as (1) fixed length static data in
|
||||
* flash memory, (2) fixed length static data in RAM or (3) dynamically at
|
||||
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
|
||||
* information about this function.
|
||||
* Descriptor handling is configured through the descriptor's properties. If
|
||||
* no properties are defined or if they are 0, the default descriptor is used.
|
||||
* Possible properties are:
|
||||
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
||||
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
|
||||
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
|
||||
* you want RAM pointers.
|
||||
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
||||
* in static memory is in RAM, not in flash memory.
|
||||
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
||||
* the driver must know the descriptor's length. The descriptor itself is
|
||||
* found at the address of a well known identifier (see below).
|
||||
* List of static descriptor names (must be declared PROGMEM if in flash):
|
||||
* char usbDescriptorDevice[];
|
||||
* char usbDescriptorConfiguration[];
|
||||
* char usbDescriptorHidReport[];
|
||||
* char usbDescriptorString0[];
|
||||
* int usbDescriptorStringVendor[];
|
||||
* int usbDescriptorStringDevice[];
|
||||
* int usbDescriptorStringSerialNumber[];
|
||||
* Other descriptors can't be provided statically, they must be provided
|
||||
* dynamically at runtime.
|
||||
*
|
||||
* Descriptor properties are or-ed or added together, e.g.:
|
||||
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
|
||||
*
|
||||
* The following descriptors are defined:
|
||||
* USB_CFG_DESCR_PROPS_DEVICE
|
||||
* USB_CFG_DESCR_PROPS_CONFIGURATION
|
||||
* USB_CFG_DESCR_PROPS_STRINGS
|
||||
* USB_CFG_DESCR_PROPS_STRING_0
|
||||
* USB_CFG_DESCR_PROPS_STRING_VENDOR
|
||||
* USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
||||
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
||||
* USB_CFG_DESCR_PROPS_HID
|
||||
* USB_CFG_DESCR_PROPS_HID_REPORT
|
||||
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
||||
*
|
||||
* Note about string descriptors: String descriptors are not just strings, they
|
||||
* are Unicode strings prefixed with a 2 byte header. Example:
|
||||
* int serialNumberDescriptor[] = {
|
||||
* USB_STRING_DESCRIPTOR_HEADER(6),
|
||||
* 'S', 'e', 'r', 'i', 'a', 'l'
|
||||
* };
|
||||
*/
|
||||
|
||||
#define USB_CFG_DESCR_PROPS_DEVICE USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_STRINGS USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_STRING_0 USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_STRING_VENDOR USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
|
||||
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
||||
|
||||
#define usbMsgPtr_t unsigned short
|
||||
/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
|
||||
* a scalar type here because gcc generates slightly shorter code for scalar
|
||||
* arithmetics than for pointer arithmetics. Remove this define for backward
|
||||
* type compatibility or define it to an 8 bit type if you use data in RAM only
|
||||
* and all RAM is below 256 bytes (tiny memory model in IAR CC).
|
||||
*/
|
||||
|
||||
/* ----------------------- Optional MCU Description ------------------------ */
|
||||
|
||||
/* The following configurations have working defaults in usbdrv.h. You
|
||||
* usually don't need to set them explicitly. Only if you want to run
|
||||
* the driver on a device which is not yet supported or with a compiler
|
||||
* which is not fully supported (such as IAR C) or if you use a differnt
|
||||
* interrupt than INT0, you may have to define some of these.
|
||||
*/
|
||||
/* #define USB_INTR_CFG MCUCR */
|
||||
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
|
||||
/* #define USB_INTR_CFG_CLR 0 */
|
||||
/* #define USB_INTR_ENABLE GIMSK */
|
||||
/* #define USB_INTR_ENABLE_BIT INT0 */
|
||||
/* #define USB_INTR_PENDING GIFR */
|
||||
/* #define USB_INTR_PENDING_BIT INTF0 */
|
||||
/* #define USB_INTR_VECTOR INT0_vect */
|
||||
|
||||
/* Set INT1 for D- falling edge to count SOF */
|
||||
/* #define USB_INTR_CFG EICRA */
|
||||
#ifndef USB_INTR_CFG_SET
|
||||
#define USB_INTR_CFG_SET ((1 << ISC11) | (0 << ISC10))
|
||||
#endif
|
||||
/* #define USB_INTR_CFG_CLR 0 */
|
||||
/* #define USB_INTR_ENABLE EIMSK */
|
||||
#ifndef USB_INTR_ENABLE_BIT
|
||||
#define USB_INTR_ENABLE_BIT INT1
|
||||
#endif
|
||||
/* #define USB_INTR_PENDING EIFR */
|
||||
#ifndef USB_INTR_PENDING_BIT
|
||||
#define USB_INTR_PENDING_BIT INTF1
|
||||
#endif
|
||||
#ifndef USB_INTR_VECTOR
|
||||
#define USB_INTR_VECTOR INT1_vect
|
||||
#endif
|
||||
@@ -296,7 +296,7 @@ static void send_consumer(uint16_t data) {
|
||||
*------------------------------------------------------------------*/
|
||||
static struct {
|
||||
uint16_t len;
|
||||
enum { NONE, BOOTLOADER, SET_LED } kind;
|
||||
enum { NONE, SET_LED } kind;
|
||||
} last_req;
|
||||
|
||||
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||
@@ -323,11 +323,6 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||
dprint("SET_LED:");
|
||||
last_req.kind = SET_LED;
|
||||
last_req.len = rq->wLength.word;
|
||||
#ifdef BOOTLOADER_SIZE
|
||||
} else if (rq->wValue.word == 0x0301) {
|
||||
last_req.kind = BOOTLOADER;
|
||||
last_req.len = rq->wLength.word;
|
||||
#endif
|
||||
}
|
||||
return USB_NO_MSG; // to get data in usbFunctionWrite
|
||||
} else {
|
||||
@@ -352,11 +347,6 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||
last_req.len = 0;
|
||||
return 1;
|
||||
break;
|
||||
case BOOTLOADER:
|
||||
usbDeviceDisconnect();
|
||||
bootloader_jump();
|
||||
return 1;
|
||||
break;
|
||||
case NONE:
|
||||
default:
|
||||
return -1;
|
||||
@@ -454,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = {
|
||||
0x85, REPORT_ID_MOUSE, // Report ID
|
||||
0x09, 0x01, // Usage (Pointer)
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
// Buttons (5 bits)
|
||||
// Buttons (8 bits)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (Button 1)
|
||||
0x29, 0x05, // Usage Maximum (Button 5)
|
||||
0x29, 0x08, // Usage Maximum (Button 8)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, 0x05, // Report Count (5)
|
||||
0x95, 0x08, // Report Count (8)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||
// Button padding (3 bits)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x03, // Report Size (3)
|
||||
0x81, 0x03, // Input (Constant)
|
||||
|
||||
// X/Y position (2 bytes)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
|
||||
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#pragma once
|
||||
|
||||
#include "host_driver.h"
|
||||
#include <usbdrv/usbdrv.h>
|
||||
|
||||
typedef struct usbDescriptorHeader {
|
||||
uchar bLength;
|
||||
@@ -119,5 +120,7 @@ typedef struct usbConfigurationDescriptor {
|
||||
|
||||
#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1))
|
||||
|
||||
extern bool vusb_suspended;
|
||||
|
||||
host_driver_t *vusb_driver(void);
|
||||
void vusb_transfer_keyboard(void);
|
||||
|
||||
@@ -38,33 +38,36 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define XT_DATA_IN() \
|
||||
do { \
|
||||
XT_DATA_DDR &= ~(1 << XT_DATA_BIT); \
|
||||
XT_DATA_PORT |= (1 << XT_DATA_BIT); \
|
||||
#include "quantum.h"
|
||||
|
||||
#define XT_DATA_IN() \
|
||||
do { \
|
||||
setPinInput(XT_DATA_PIN); \
|
||||
writePinHigh(XT_DATA_PIN); \
|
||||
} while (0)
|
||||
|
||||
#define XT_DATA_READ() (XT_DATA_PIN & (1 << XT_DATA_BIT))
|
||||
#define XT_DATA_READ() readPin(XT_DATA_PIN)
|
||||
|
||||
#define XT_DATA_LO() \
|
||||
do { \
|
||||
XT_DATA_PORT &= ~(1 << XT_DATA_BIT); \
|
||||
XT_DATA_DDR |= (1 << XT_DATA_BIT); \
|
||||
#define XT_DATA_LO() \
|
||||
do { \
|
||||
writePinLow(XT_DATA_PIN); \
|
||||
setPinOutput(XT_DATA_PIN); \
|
||||
} while (0)
|
||||
|
||||
#define XT_CLOCK_IN() \
|
||||
do { \
|
||||
XT_CLOCK_DDR &= ~(1 << XT_CLOCK_BIT); \
|
||||
XT_CLOCK_PORT |= (1 << XT_CLOCK_BIT); \
|
||||
#define XT_CLOCK_IN() \
|
||||
do { \
|
||||
setPinInput(XT_CLOCK_PIN); \
|
||||
writePinHigh(XT_CLOCK_PIN); \
|
||||
} while (0)
|
||||
|
||||
#define XT_CLOCK_READ() (XT_CLOCK_PIN & (1 << XT_CLOCK_BIT))
|
||||
#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN)
|
||||
|
||||
#define XT_CLOCK_LO() \
|
||||
do { \
|
||||
XT_CLOCK_PORT &= ~(1 << XT_CLOCK_BIT); \
|
||||
XT_CLOCK_DDR |= (1 << XT_CLOCK_BIT); \
|
||||
#define XT_CLOCK_LO() \
|
||||
do { \
|
||||
writePinLow(XT_CLOCK_PIN); \
|
||||
setPinOutput(XT_CLOCK_PIN); \
|
||||
} while (0)
|
||||
|
||||
void xt_host_init(void);
|
||||
void xt_host_init(void);
|
||||
|
||||
uint8_t xt_host_recv(void);
|
||||
|
||||
@@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "xt.h"
|
||||
#include "wait.h"
|
||||
#include "debug.h"
|
||||
@@ -60,7 +59,7 @@ void xt_host_init(void) {
|
||||
/* soft reset: pull clock line down for 20ms */
|
||||
XT_DATA_LO();
|
||||
XT_CLOCK_LO();
|
||||
_delay_ms(20);
|
||||
wait_ms(20);
|
||||
|
||||
/* input mode with pullup */
|
||||
XT_CLOCK_IN();
|
||||
@@ -120,9 +119,10 @@ ISR(XT_INT_VECT) {
|
||||
* Ring buffer to store scan codes from keyboard
|
||||
*------------------------------------------------------------------*/
|
||||
#define PBUF_SIZE 32
|
||||
static uint8_t pbuf[PBUF_SIZE];
|
||||
static uint8_t pbuf_head = 0;
|
||||
static uint8_t pbuf_tail = 0;
|
||||
static uint8_t pbuf[PBUF_SIZE];
|
||||
static uint8_t pbuf_head = 0;
|
||||
static uint8_t pbuf_tail = 0;
|
||||
|
||||
static inline void pbuf_enqueue(uint8_t data) {
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
@@ -135,6 +135,7 @@ static inline void pbuf_enqueue(uint8_t data) {
|
||||
}
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
static inline uint8_t pbuf_dequeue(void) {
|
||||
uint8_t val = 0;
|
||||
|
||||
@@ -148,6 +149,7 @@ static inline uint8_t pbuf_dequeue(void) {
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline bool pbuf_has_data(void) {
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
@@ -155,6 +157,7 @@ static inline bool pbuf_has_data(void) {
|
||||
SREG = sreg;
|
||||
return has_data;
|
||||
}
|
||||
|
||||
static inline void pbuf_clear(void) {
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
|
||||
@@ -67,7 +67,6 @@ Start Your Own Project
|
||||
#define PRODUCT_ID 0xBEEF
|
||||
#define MANUFACTURER t.m.k.
|
||||
#define PRODUCT Macway mod
|
||||
#define DESCRIPTION t.m.k. keyboard firmware for Macway mod
|
||||
|
||||
#### 2. Keyboard matrix configuration
|
||||
#define MATRIX_ROWS 8
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Ring buffer to store scan codes from keyboard
|
||||
*------------------------------------------------------------------*/
|
||||
#ifndef RBUF_SIZE
|
||||
# define RBUF_SIZE 32
|
||||
#endif
|
||||
#include <util/atomic.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
static uint8_t rbuf[RBUF_SIZE];
|
||||
static uint8_t rbuf_head = 0;
|
||||
static uint8_t rbuf_tail = 0;
|
||||
static inline bool rbuf_enqueue(uint8_t data) {
|
||||
bool ret = false;
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
|
||||
if (next != rbuf_tail) {
|
||||
rbuf[rbuf_head] = data;
|
||||
rbuf_head = next;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static inline uint8_t rbuf_dequeue(void) {
|
||||
uint8_t val = 0;
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
if (rbuf_head != rbuf_tail) {
|
||||
val = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
static inline bool rbuf_has_data(void) {
|
||||
bool has_data;
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { has_data = (rbuf_head != rbuf_tail); }
|
||||
return has_data;
|
||||
}
|
||||
static inline void rbuf_clear(void) {
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { rbuf_head = rbuf_tail = 0; }
|
||||
}
|
||||
@@ -108,6 +108,10 @@ endif
|
||||
CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
|
||||
CFLAGS += $(CSTANDARD)
|
||||
|
||||
# This fixes lots of keyboards linking errors but SHOULDN'T BE A FINAL SOLUTION
|
||||
# Fixing of multiple variable definitions must be made.
|
||||
CFLAGS += -fcommon
|
||||
|
||||
#---------------- Compiler Options C++ ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
@@ -124,6 +128,7 @@ CXXFLAGS += -O$(OPT)
|
||||
CXXFLAGS += -w
|
||||
CXXFLAGS += -Wall
|
||||
CXXFLAGS += -Wundef
|
||||
|
||||
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
|
||||
CXXFLAGS += -Werror
|
||||
endif
|
||||
|
||||
Reference in New Issue
Block a user