Merge remote-tracking branch 'qmk/master' into vial

This commit is contained in:
Ilya Zhuravlev
2021-03-03 11:12:07 -05:00
8590 changed files with 251950 additions and 200108 deletions
+62 -65
View File
@@ -37,20 +37,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "nodebug.h"
#endif
int tp_buttons;
#ifdef RETRO_TAPPING
int retro_tapping_counter = 0;
#ifdef POINTING_DEVICE_ENABLE
# include "pointing_device.h"
#endif
#ifdef FAUXCLICKY_ENABLE
# include <fauxclicky.h>
int tp_buttons;
#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
int retro_tapping_counter = 0;
#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
#ifdef RETRO_TAPPING_PER_KEY
__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; }
#endif
#ifndef TAP_CODE_DELAY
# define TAP_CODE_DELAY 0
#endif
@@ -67,20 +71,15 @@ void action_exec(keyevent_t event) {
dprint("EVENT: ");
debug_event(event);
dprintln();
#ifdef RETRO_TAPPING
#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
retro_tapping_counter++;
#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)) {
@@ -220,6 +219,19 @@ void process_record_handler(keyrecord_t *record) {
process_action(record, action);
}
#if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
void register_button(bool pressed, enum mouse_buttons button) {
# ifdef PS2_MOUSE_ENABLE
tp_buttons = pressed ? tp_buttons | button : tp_buttons & ~button;
# endif
# ifdef POINTING_DEVICE_ENABLE
report_mouse_t currentReport = pointing_device_get_report();
currentReport.buttons = pressed ? currentReport.buttons | button : currentReport.buttons & ~button;
pointing_device_set_report(currentReport);
# endif
}
#endif
/** \brief Take an action and processes it.
*
* FIXME: Needs documentation.
@@ -230,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.
@@ -403,40 +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) {
# ifdef PS2_MOUSE_ENABLE
case KC_MS_BTN1:
tp_buttons |= (1 << 0);
break;
case KC_MS_BTN2:
tp_buttons |= (1 << 1);
break;
case KC_MS_BTN3:
tp_buttons |= (1 << 2);
break;
# endif
default:
mousekey_send();
break;
}
} else {
mousekey_off(action.key.code);
switch (action.key.code) {
# ifdef PS2_MOUSE_ENABLE
case KC_MS_BTN1:
tp_buttons &= ~(1 << 0);
break;
case KC_MS_BTN2:
tp_buttons &= ~(1 << 1);
break;
case KC_MS_BTN3:
tp_buttons &= ~(1 << 2);
break;
}
switch (action.key.code) {
# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
# 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
default:
mousekey_send();
break;
}
default:
mousekey_send();
break;
}
break;
#endif
@@ -692,20 +681,23 @@ void process_action(keyrecord_t *record, action_t action) {
#endif
#ifndef NO_ACTION_TAPPING
# ifdef RETRO_TAPPING
# if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
if (!is_tap_action(action)) {
retro_tapping_counter = 0;
} else {
if (event.pressed) {
if (tap_count > 0) {
retro_tapping_counter = 0;
} else {
}
} else {
if (tap_count > 0) {
retro_tapping_counter = 0;
} else {
if (retro_tapping_counter == 2) {
if (
# ifdef RETRO_TAPPING_PER_KEY
get_retro_tapping(get_event_keycode(record->event, false), record) &&
# endif
retro_tapping_counter == 2) {
tap_code(action.layer_tap.code);
}
retro_tapping_counter = 0;
@@ -896,20 +888,25 @@ 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 register.
@@ -977,6 +974,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();
@@ -984,10 +985,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)
+3 -4
View File
@@ -14,8 +14,8 @@ 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/>.
*/
#ifndef ACTION_H
#define ACTION_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -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);
@@ -124,5 +125,3 @@ void debug_action(action_t action);
#ifdef __cplusplus
}
#endif
#endif /* ACTION_H */
+2 -4
View File
@@ -14,8 +14,8 @@ 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/>.
*/
#ifndef ACTION_CODE_H
#define ACTION_CODE_H
#pragma once
/** \brief Action codes
*
@@ -306,5 +306,3 @@ enum swap_hands_param_tap_op {
#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON)
#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON)
#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF)
#endif /* ACTION_CODE_H */
+2 -4
View File
@@ -14,8 +14,8 @@ 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/>.
*/
#ifndef ACTION_LAYER_H
#define ACTION_LAYER_H
#pragma once
#include <stdint.h>
#include "keyboard.h"
@@ -120,5 +120,3 @@ uint8_t layer_switch_get_layer(keypos_t key);
/* return action depending on current layer status */
action_t layer_switch_get_action(keypos_t key);
#endif
+3 -4
View File
@@ -14,8 +14,9 @@ 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/>.
*/
#ifndef ACTION_MACRO_H
#define ACTION_MACRO_H
#pragma once
#include <stdint.h>
#include "progmem.h"
@@ -120,5 +121,3 @@ enum macro_command_id {
/* for backward comaptibility */
#define MD(key) DOWN(KC_##key)
#define MU(key) UP(KC_##key)
#endif /* ACTION_MACRO_H */
+7 -6
View File
@@ -14,16 +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/>.
*/
#ifndef ACTION_TAPPING_H
#define ACTION_TAPPING_H
#pragma once
/* period of tapping(ms) */
#ifndef TAPPING_TERM
# define TAPPING_TERM 200
#endif
//#define RETRO_TAPPING // Tap anyway, even after TAPPING_TERM, as long as there was no interruption
/* tap count needed for toggling a feature */
#ifndef TAPPING_TOGGLE
# define TAPPING_TOGGLE 5
@@ -33,8 +31,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NO_ACTION_TAPPING
uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record);
void action_tapping_process(keyrecord_t record);
#endif
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record);
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record);
bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record);
bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record);
bool get_retro_tapping(uint16_t keycode, keyrecord_t *record);
#endif
+26 -5
View File
@@ -290,6 +290,32 @@ void set_macro_mods(uint8_t mods) { macro_mods = mods; }
void clear_macro_mods(void) { macro_mods = 0; }
#ifndef NO_ACTION_ONESHOT
/** \brief get oneshot mods
*
* FIXME: needs doc
*/
uint8_t get_oneshot_mods(void) { return oneshot_mods; }
void add_oneshot_mods(uint8_t mods) {
if ((oneshot_mods & mods) != mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read();
# endif
oneshot_mods |= mods;
oneshot_mods_changed_kb(mods);
}
}
void del_oneshot_mods(uint8_t mods) {
if (oneshot_mods & mods) {
oneshot_mods &= ~mods;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = oneshot_mods ? timer_read() : 0;
# endif
oneshot_mods_changed_kb(oneshot_mods);
}
}
/** \brief set oneshot mods
*
* FIXME: needs doc
@@ -316,11 +342,6 @@ void clear_oneshot_mods(void) {
oneshot_mods_changed_kb(oneshot_mods);
}
}
/** \brief get oneshot mods
*
* FIXME: needs doc
*/
uint8_t get_oneshot_mods(void) { return oneshot_mods; }
#endif
/** \brief Called when the one shot modifiers have been changed.
+5 -8
View File
@@ -14,8 +14,8 @@ 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/>.
*/
#ifndef ACTION_UTIL_H
#define ACTION_UTIL_H
#pragma once
#include <stdint.h>
#include "report.h"
@@ -57,12 +57,11 @@ void set_macro_mods(uint8_t mods);
void clear_macro_mods(void);
/* oneshot modifier */
void set_oneshot_mods(uint8_t mods);
uint8_t get_oneshot_mods(void);
void add_oneshot_mods(uint8_t mods);
void del_oneshot_mods(uint8_t mods);
void set_oneshot_mods(uint8_t mods);
void clear_oneshot_mods(void);
void oneshot_toggle(void);
void oneshot_enable(void);
void oneshot_disable(void);
bool has_oneshot_mods_timed_out(void);
uint8_t get_oneshot_locked_mods(void);
@@ -99,5 +98,3 @@ void clear_oneshot_swaphands(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -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) print(s)
#define uprintln(s) println(s)
#define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
+5 -1
View File
@@ -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,5 @@ void console_printf(char *fmt, ...) {
}
#endif // CONSOLE_ENABLE
void print_set_sendchar(sendchar_func_t send) {}
+1 -4
View File
@@ -1,10 +1,7 @@
#ifndef _PRINTF_H_
#define _PRINTF_H_
#pragma once
#define CONSOLE_PRINTBUF_SIZE 512
void console_printf(char *fmt, ...);
#define __xprintf console_printf
#endif //_PRINTF_H_
+1
View File
@@ -0,0 +1 @@
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
+1 -1
View File
@@ -1,6 +1,6 @@
#include "matrix.h"
#include "i2c_master.h"
#include "led_matrix.h"
#include "md_rgb_matrix.h"
#include "suspend.h"
/** \brief Suspend idle
+32
View 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
View 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) print(s)
#define uprintln(s) println(s)
#define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
+22
View 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)
+1 -1
View File
@@ -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
View 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
View 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,43 +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"
#ifndef LED_H
#define LED_H
#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
#endif
void print_set_sendchar(sendchar_func_t func) { xdev_out(func); }
+2
View File
@@ -0,0 +1,2 @@
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
+1 -1
View File
@@ -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};
+67 -45
View File
@@ -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"
@@ -24,9 +26,6 @@
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
# include "rgblight.h"
extern rgblight_config_t rgblight_config;
static bool rgblight_enabled;
static bool is_suspended;
#endif
/** \brief Suspend idle
@@ -55,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>
@@ -77,42 +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
// This sometimes disables the start-up noise, so it's been disabled
// stop_all_notes();
# endif /* AUDIO_ENABLE */
# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
rgblight_timer_disable();
if (!is_suspended) {
is_suspended = true;
rgblight_enabled = rgblight_config.enable;
rgblight_disable_noeeprom();
}
# endif
suspend_power_down_kb();
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
@@ -135,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
}
@@ -165,6 +186,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {}
* FIXME: needs doc
*/
__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
/** \brief run immediately after wakeup
*
* FIXME: needs doc
@@ -172,24 +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)
is_suspended = false;
if (rgblight_enabled) {
# ifdef BOOTLOADER_TEENSY
wait_ms(10);
# endif
rgblight_enable_noeeprom();
}
rgblight_timer_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
-28
View File
@@ -1,28 +0,0 @@
#ifndef SUSPEND_AVR_H
#define SUSPEND_AVR_H
#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
#endif
+1 -4
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TIMER_AVR_H
#define TIMER_AVR_H 1
#pragma once
#include <stdint.h>
@@ -38,5 +37,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if (TIMER_RAW_TOP > 255)
# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
#endif
#endif
+1 -3
View File
@@ -450,7 +450,7 @@ xatoi:
brcs 70f ;/
cpi r22, 10 ;if(r22 >= 10) {
brcs 53f ; r22 -= 7;
subi r22, 7 ; if(r22 < 10)
subi r22, 7 ; if(r22 < 10)
cpi r22, 10 ;
brcs 70f ;}
53: cp r22, r25 ;if(r22 >= r25) error;
@@ -496,5 +496,3 @@ xatoi:
ret
.endfunc
#endif
+1 -4
View File
@@ -2,8 +2,7 @@
Extended itoa, puts and printf (C)ChaN, 2011
-----------------------------------------------------------------------------*/
#ifndef XPRINTF_H
#define XPRINTF_H
#pragma once
#include <inttypes.h>
#include <avr/pgmspace.h>
@@ -102,5 +101,3 @@ char xatoi(char **str, long *ret);
#ifdef __cplusplus
}
#endif
#endif
+1 -4
View File
@@ -15,10 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BOOTLOADER_H
#define BOOTLOADER_H
#pragma once
/* give code for your bootloader to come up if needed */
void bootloader_jump(void);
#endif
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef BOOTMAGIC_H
#define BOOTMAGIC_H
#pragma once
/* FIXME: Add special doxygen comments for defines here. */
@@ -101,5 +100,3 @@
void bootmagic(void);
bool bootmagic_scan_keycode(uint8_t keycode);
#endif
+1 -3
View File
@@ -1,7 +1,5 @@
#include "quantum.h"
bool is_keyboard_left(void);
/** \brief Reset eeprom
*
* ...just incase someone wants to only change the eeprom behaviour
@@ -48,4 +46,4 @@ __attribute__((weak)) void bootmagic_lite(void) {
// Jump to bootloader.
bootloader_jump();
}
}
}
+37
View 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)
+7 -7
View File
@@ -1,7 +1,7 @@
#include "bootloader.h"
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
#include "wait.h"
/* This code should be checked whether it runs correctly on platforms */
@@ -32,7 +32,7 @@
extern uint32_t __ram0_end__;
void bootloader_jump(void) {
__attribute__((weak)) void bootloader_jump(void) {
// For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash
// bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do
// it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to
@@ -58,7 +58,7 @@ void enter_bootloader_mode_if_requested(void) {} // not needed at all, but if a
extern uint32_t __ram0_end__;
void bootloader_jump(void) {
__attribute__((weak)) void bootloader_jump(void) {
*MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader
NVIC_SystemReset();
}
@@ -85,8 +85,8 @@ void enter_bootloader_mode_if_requested(void) {
# if defined(BOOTLOADER_KIIBOHD)
/* Kiibohd Bootloader (MCHCK and Infinity KB) */
# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff";
void bootloader_jump(void) {
const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff";
__attribute__((weak)) void bootloader_jump(void) {
__builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
// request reset
SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
@@ -95,7 +95,7 @@ void bootloader_jump(void) {
# else /* defined(BOOTLOADER_KIIBOHD) */
/* Default for Kinetis - expecting an ARM Teensy */
# include "wait.h"
void bootloader_jump(void) {
__attribute__((weak)) void bootloader_jump(void) {
wait_ms(100);
__BKPT(0);
}
+8 -7
View File
@@ -21,11 +21,10 @@
* This library also assumes that the pages are not used by the firmware.
*/
#ifndef __EEPROM_H
#define __EEPROM_H
#pragma once
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
#include "flash_stm32.h"
// HACK ALERT. This definition may not match your processor
@@ -36,12 +35,14 @@
# define MCU_STM32F103RB
#elif defined(EEPROM_EMU_STM32F072xB)
# define MCU_STM32F072CB
#elif defined(EEPROM_EMU_STM32F042x6)
# define MCU_STM32F042K6
#else
# error "not implemented."
#endif
#ifndef EEPROM_PAGE_SIZE
# if defined(MCU_STM32F103RB)
# if defined(MCU_STM32F103RB) || defined(MCU_STM32F042K6)
# define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
# define FEE_DENSITY_PAGES 8 // How many pages are used
# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) || defined(MCU_STM32F103RD) || defined(MCU_STM32F303CC) || defined(MCU_STM32F072CB)
@@ -55,6 +56,8 @@
#ifndef EEPROM_START_ADDRESS
# if defined(MCU_STM32F103RB) || defined(MCU_STM32F072CB)
# define FEE_MCU_FLASH_SIZE 128 // Size in Kb
# elif defined(MCU_STM32F042K6)
# define FEE_MCU_FLASH_SIZE 32 // Size in Kb
# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE)
# define FEE_MCU_FLASH_SIZE 512 // Size in Kb
# elif defined(MCU_STM32F103RD)
@@ -82,5 +85,3 @@ void EEPROM_Init(void);
void EEPROM_Erase(void);
void EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte);
uint8_t EEPROM_ReadDataByte(uint16_t Address);
#endif /* __EEPROM_H */
+2 -2
View File
@@ -1,5 +1,5 @@
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
#include "eeconfig.h"
+3
View File
@@ -25,6 +25,9 @@
#elif defined(EEPROM_EMU_STM32F072xB)
# define STM32F072xB
# include "stm32f0xx.h"
#elif defined(EEPROM_EMU_STM32F042x6)
# define STM32F042x6
# include "stm32f0xx.h"
#else
# error "not implemented."
#endif
+3 -6
View File
@@ -16,15 +16,14 @@
* Modifications for QMK and STM32F303 by Yiancar
*/
#ifndef __FLASH_STM32_H
#define __FLASH_STM32_H
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_COMPLETE, FLASH_TIMEOUT, FLASH_BAD_ADDRESS } FLASH_Status;
@@ -41,5 +40,3 @@ void FLASH_ClearFlag(uint32_t FLASH_FLAG);
#ifdef __cplusplus
}
#endif
#endif /* __FLASH_STM32_H */
+34
View 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
View 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
+3 -3
View File
@@ -1,5 +1,5 @@
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
#include "led.h"
#include "sleep_led.h"
@@ -211,4 +211,4 @@ void sleep_led_toggle(void) {
// not implemented
}
#endif /* platform selection */
#endif /* platform selection */
+11 -16
View File
@@ -1,7 +1,7 @@
/* TODO */
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
#include "matrix.h"
#include "action.h"
@@ -12,15 +12,16 @@
#include "led.h"
#include "wait.h"
#ifdef AUDIO_ENABLE
# include "audio.h"
#endif /* AUDIO_ENABLE */
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
# include "rgblight.h"
extern rgblight_config_t rgblight_config;
static bool rgblight_enabled;
static bool is_suspended;
#endif
/** \brief suspend idle
@@ -66,13 +67,11 @@ void suspend_power_down(void) {
// shouldn't power down TPM/FTM if we want a breathing LED
// also shouldn't power down USB
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
rgblight_timer_disable();
if (!is_suspended) {
is_suspended = true;
rgblight_enabled = rgblight_config.enable;
rgblight_disable_noeeprom();
}
rgblight_suspend();
#endif
#ifdef AUDIO_ENABLE
stop_all_notes();
#endif /* AUDIO_ENABLE */
suspend_power_down_kb();
// on AVR, this enables the watchdog for 15ms (max), and goes to
@@ -136,11 +135,7 @@ void suspend_wakeup_init(void) {
#endif /* BACKLIGHT_ENABLE */
led_set(host_keyboard_leds());
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
is_suspended = false;
if (rgblight_enabled) {
rgblight_enable_noeeprom();
}
rgblight_timer_enable();
rgblight_wakeup();
#endif
suspend_wakeup_init_kb();
}
+104
View File
@@ -0,0 +1,104 @@
/* Copyright 2021 Nick Brassel, 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 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 <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
__attribute__((weak, used)) int _open_r(struct _reent *r, const char *path, int flag, int m) {
__errno_r(r) = ENOENT;
return -1;
}
__attribute__((weak, used)) int _lseek_r(struct _reent *r, int file, int ptr, int dir) {
__errno_r(r) = EBADF;
return -1;
}
__attribute__((weak, used)) int _read_r(struct _reent *r, int file, char *ptr, int len) {
__errno_r(r) = EBADF;
return -1;
}
__attribute__((weak, used)) int _write_r(struct _reent *r, int file, char *ptr, int len) {
__errno_r(r) = EBADF;
return -1;
}
__attribute__((weak, used)) int _close_r(struct _reent *r, int file) {
__errno_r(r) = EBADF;
return -1;
}
__attribute__((weak, used)) int _link_r(struct _reent *r, const char *oldpath, const char *newpath) {
__errno_r(r) = EPERM;
return -1;
}
__attribute__((weak, used)) int _unlink_r(struct _reent *r, const char *path) {
__errno_r(r) = EPERM;
return -1;
}
__attribute__((weak, used)) clock_t _times_r(struct _reent *r, void *t) {
__errno_r(r) = EFAULT;
return -1;
}
__attribute__((weak, used)) int _fstat_r(struct _reent *r, int file, struct stat *st) {
__errno_r(r) = EBADF;
return -1;
}
__attribute__((weak, used)) int _isatty_r(struct _reent *r, int fd) {
__errno_r(r) = EBADF;
return 0;
}
__attribute__((weak, used)) caddr_t _sbrk_r(struct _reent *r, int incr) {
__errno_r(r) = ENOMEM;
return (caddr_t)-1;
}
__attribute__((weak, used)) int _kill(int pid, int sig) {
errno = EPERM;
return -1;
}
__attribute__((weak, used)) pid_t _getpid(void) { return 1; }
__attribute__((weak, used)) void _fini(void) { return; }
__attribute__((weak, used, noreturn)) void _exit(int i) {
while (1)
;
}
__attribute__((weak, used)) int _gettimeofday_r(struct _reent *r, struct timeval *t, void *tzp) {
__errno_r(r) = EPERM;
return -1;
}
__attribute__((weak, used)) void *__dso_handle;
__attribute__((weak, used)) void __cxa_pure_virtual(void) {
while (1)
;
}
#pragma GCC diagnostic pop
+1 -1
View File
@@ -1,4 +1,4 @@
#include "ch.h"
#include <ch.h>
#include "timer.h"
-795
View File
@@ -1,795 +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 */
#ifdef VIAL_ENABLE
# include "vial.h"
#endif
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("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
"VER: " STR(DEVICE_VER) "\n");
#ifdef SKIP_VERSION
print("BUILD: (" __DATE__ ")\n");
#else
print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n");
# 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... ");
#ifdef VIAL_ENABLE
if (vial_unlocked)
#endif
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();
}
-163
View File
@@ -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)
+21 -20
View File
@@ -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 //
};
+1 -4
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEBUG_H
#define DEBUG_H 1
#pragma once
#include <stdbool.h>
#include "print.h"
@@ -168,5 +167,3 @@ extern debug_config_t debug_config;
# define debug_bin_reverse(data)
#endif /* NO_DEBUG */
#endif
+14 -1
View File
@@ -5,7 +5,7 @@
#include "action_layer.h"
#ifdef STM32_EEPROM_ENABLE
# include "hal.h"
# include <hal.h>
# include "eeprom_stm32.h"
#endif
@@ -13,6 +13,10 @@
# include "eeprom_driver.h"
#endif
#if defined(HAPTIC_ENABLE)
# include "haptic.h"
#endif
/** \brief eeconfig enable
*
* FIXME: needs doc
@@ -65,6 +69,15 @@ void eeconfig_init_quantum(void) {
eeprom_update_byte(EECONFIG_HANDEDNESS, 0);
#endif
#if defined(HAPTIC_ENABLE)
haptic_reset();
#else
// this is used in case haptic is disabled, but we still want sane defaults
// in the haptic configuration eeprom. All zero will trigger a haptic_reset
// when a haptic-enabled firmware is loaded onto the keyboard.
eeprom_update_dword(EECONFIG_HAPTIC, 0);
#endif
eeconfig_init_kb();
}
+2 -5
View File
@@ -15,14 +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/>.
*/
#ifndef EECONFIG_H
#define EECONFIG_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEC
# 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
@@ -111,5 +110,3 @@ void eeconfig_update_haptic(uint32_t val);
bool eeconfig_read_handedness(void);
void eeconfig_update_handedness(bool val);
#endif
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef TMK_CORE_COMMON_EEPROM_H_
#define TMK_CORE_COMMON_EEPROM_H_
#pragma once
#if defined(__AVR__) && !defined(EEPROM_DRIVER)
# include <avr/eeprom.h>
@@ -20,5 +19,3 @@ void eeprom_update_word(uint16_t *__p, uint16_t __value);
void eeprom_update_dword(uint32_t *__p, uint32_t __value);
void eeprom_update_block(const void *__src, void *__dst, size_t __n);
#endif
#endif /* TMK_CORE_COMMON_EEPROM_H_ */
+22
View 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
+1 -4
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HOST_DRIVER_H
#define HOST_DRIVER_H
#pragma once
#include <stdint.h>
#include "report.h"
@@ -31,5 +30,3 @@ typedef struct {
void (*send_system)(uint16_t);
void (*send_consumer)(uint16_t);
} host_driver_t;
#endif
+110 -41
View File
@@ -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,22 +97,41 @@ 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) && defined(CONSOLE_ENABLE)
static uint32_t matrix_timer = 0;
static uint32_t matrix_scan_count = 0;
#if defined(DEBUG_MATRIX_SCAN_RATE)
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) {
matrix_scan_count++;
uint32_t timer_now = timer_read32();
if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) {
dprintf("matrix scan frequency: %d\n", matrix_scan_count);
matrix_timer = timer_now;
matrix_scan_count = 0;
# if defined(CONSOLE_ENABLE)
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;
}
}
uint32_t get_matrix_scan_rate(void) { return last_matrix_scan_count; }
#else
# define matrix_scan_perf_task()
#endif
@@ -212,6 +232,7 @@ void keyboard_setup(void) {
#ifndef NO_JTAG_DISABLE
disable_jtag();
#endif
print_set_sendchar(sendchar);
matrix_setup();
keyboard_pre_init_kb();
}
@@ -222,6 +243,12 @@ void keyboard_setup(void) {
*/
__attribute__((weak)) bool is_keyboard_master(void) { return true; }
/** \brief is_keyboard_left
*
* FIXME: needs doc
*/
__attribute__((weak)) bool is_keyboard_left(void) { return true; }
/** \brief should_process_keypress
*
* Override this function if you have a condition where keypresses processing should change:
@@ -229,12 +256,27 @@ __attribute__((weak)) bool is_keyboard_master(void) { return true; }
*/
__attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master(); }
/** \brief housekeeping_task_kb
*
* Override this function if you have a need to execute code for every keyboard main loop iteration.
* This is specific to keyboard-level functionality.
*/
__attribute__((weak)) void housekeeping_task_kb(void) {}
/** \brief housekeeping_task_user
*
* Override this function if you have a need to execute code for every keyboard main loop iteration.
* This is specific to user/keymap-level functionality.
*/
__attribute__((weak)) void housekeeping_task_user(void) {}
/** \brief keyboard_init
*
* FIXME: needs doc
*/
void keyboard_init(void) {
timer_init();
sync_timer_init();
matrix_init();
#ifdef VIA_ENABLE
via_init();
@@ -271,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
@@ -285,9 +324,24 @@ void keyboard_init(void) {
dip_switch_init();
#endif
#if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
debug_enable = true;
#endif
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:
@@ -308,39 +362,45 @@ void keyboard_task(void) {
#ifdef QMK_KEYS_PER_SCAN
uint8_t keys_processed = 0;
#endif
#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT)
uint8_t ret = matrix_scan();
#else
matrix_scan();
#ifdef ENCODER_ENABLE
bool encoders_changed = false;
#endif
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) {
housekeeping_task_kb();
housekeeping_task_user();
uint8_t matrix_changed = matrix_scan();
if (matrix_changed) last_matrix_activity_trigger();
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;
}
}
}
@@ -362,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();
@@ -369,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
@@ -379,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
+17 -4
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYBOARD_H
#define KEYBOARD_H
#pragma once
#include <stdbool.h>
#include <stdint.h>
@@ -63,14 +62,28 @@ void keyboard_task(void);
void keyboard_set_leds(uint8_t leds);
/* it runs whenever code has to behave differently on a slave */
bool is_keyboard_master(void);
/* it runs whenever code has to behave differently on left vs right split */
bool is_keyboard_left(void);
void keyboard_pre_init_kb(void);
void keyboard_pre_init_user(void);
void keyboard_post_init_kb(void);
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
}
#endif
#endif
+12 -7
View File
@@ -21,8 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
* or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older)
*/
#ifndef KEYCODE_H
#define KEYCODE_H
#pragma once
/* FIXME: Add doxygen comments here */
@@ -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
@@ -521,15 +524,18 @@ enum internal_special_keycodes {
enum mouse_keys {
/* Mouse Buttons */
KC_MS_UP = 0xF0,
KC_MS_UP = 0xED,
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,
KC_MS_BTN6,
KC_MS_BTN7,
KC_MS_BTN8,
/* Mouse Wheel */
KC_MS_WH_UP,
@@ -540,6 +546,5 @@ enum mouse_keys {
/* Acceleration */
KC_MS_ACCEL0,
KC_MS_ACCEL1,
KC_MS_ACCEL2
KC_MS_ACCEL2 // 0xFF
};
#endif
+9
View 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 -4
View File
@@ -1,6 +1,3 @@
#ifndef MAGIC_H
#define MAGIC_H
#pragma once
void magic(void);
#endif
-90
View File
@@ -1,90 +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/>.
*/
#ifndef MATRIX_H
#define MATRIX_H
#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
#if (MATRIX_ROWS <= 8)
typedef uint8_t matrix_col_t;
#elif (MATRIX_ROWS <= 16)
typedef uint16_t matrix_col_t;
#elif (MATRIX_ROWS <= 32)
typedef uint32_t matrix_col_t;
#else
# error "MATRIX_ROWS: invalid value"
#endif
#define MATRIX_ROW_SHIFTER ((matrix_row_t)1)
#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1 << col))
#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
#endif
-446
View File
@@ -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");
}
-144
View File
@@ -1,144 +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/>.
*/
#ifndef MOUSEKEY_H
# define MOUSEKEY_H
#endif
#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
+1 -4
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NODEBUG_H
#define NODEBUG_H
#pragma once
#ifndef NO_DEBUG
# define NO_DEBUG
@@ -25,5 +24,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#else
# include "debug.h"
#endif
#endif
+23
View 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
+87 -225
View File
@@ -22,110 +22,81 @@
* THE SOFTWARE.
*/
#ifndef PRINT_H__
#define PRINT_H__ 1
#pragma once
#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
@@ -133,141 +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)
#endif
#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))
@@ -14,37 +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"
#ifndef UTIL_H
#define UTIL_H
// bind lib/printf to console interface - sendchar
#include <stdint.h>
static int8_t null_sendchar_func(uint8_t c) { return 0; }
static sendchar_func_t func = null_sendchar_func;
// 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
void print_set_sendchar(sendchar_func_t send) { func = send; }
#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
#endif
void _putchar(char character) { func(character); }
+1
View File
@@ -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))
+1 -4
View File
@@ -1,8 +1,5 @@
#ifndef _RAW_HID_H_
#define _RAW_HID_H_
#pragma once
void raw_hid_receive(uint8_t *data, uint8_t length);
void raw_hid_send(uint8_t *data, uint8_t length);
#endif
+13 -11
View File
@@ -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)
@@ -123,12 +127,6 @@ enum desktop_usages {
#define KEYBOARD_REPORT_KEYS 6
/* VUSB hardcodes keyboard and mouse+extrakey only */
#if defined(PROTOCOL_VUSB)
# undef KEYBOARD_SHARED_EP
# undef MOUSE_SHARED_EP
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -192,7 +190,11 @@ typedef struct {
typedef struct {
#if JOYSTICK_AXES_COUNT > 0
# if JOYSTICK_AXES_RESOLUTION > 8
int16_t axes[JOYSTICK_AXES_COUNT];
# else
int8_t axes[JOYSTICK_AXES_COUNT];
# endif
#endif
#if JOYSTICK_BUTTON_COUNT > 0
+3 -4
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SENDCHAR_H
#define SENDCHAR_H
#pragma once
#include <stdint.h>
@@ -24,11 +23,11 @@ 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);
#ifdef __cplusplus
}
#endif
#endif
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef SLEEP_LED_H
#define SLEEP_LED_H
#pragma once
#ifdef SLEEP_LED_ENABLE
@@ -16,5 +15,3 @@ void sleep_led_toggle(void);
# define sleep_led_toggle()
#endif
#endif
+3 -2
View File
@@ -1,5 +1,4 @@
#ifndef SUSPEND_H
#define SUSPEND_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -14,4 +13,6 @@ void suspend_wakeup_init_kb(void);
void suspend_power_down_user(void);
void suspend_power_down_kb(void);
#ifndef USB_SUSPEND_WAKEUP_DELAY
# define USB_SUSPEND_WAKEUP_DELAY 0
#endif
+58
View 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
View 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 -1
View File
@@ -30,4 +30,4 @@ uint32_t timer_elapsed32(uint32_t last) { return TIMER_DIFF_32(timer_read32(), l
void set_time(uint32_t t) { current_time = t; }
void advance_time(uint32_t ms) { current_time += ms; }
void wait_ms(uint32_t ms) { advance_time(ms); }
void wait_ms(uint32_t ms) { advance_time(ms); }
+3 -6
View File
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TIMER_H
#define TIMER_H 1
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -45,11 +44,9 @@ uint16_t timer_elapsed(uint16_t last);
uint32_t timer_elapsed32(uint32_t last);
// Utility functions to check if a future time has expired & autmatically handle time wrapping if checked / reset frequently (half of max value)
#define timer_expired(current, future) (((uint16_t)current - (uint16_t)future) < 0x8000)
#define timer_expired32(current, future) (((uint32_t)current - (uint32_t)future) < 0x80000000)
#define timer_expired(current, future) ((uint16_t)(current - future) < UINT16_MAX / 2)
#define timer_expired32(current, future) ((uint32_t)(current - future) < UINT32_MAX / 2)
#ifdef __cplusplus
}
#endif
#endif
-172
View File
@@ -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;
}
}
-11
View File
@@ -1,11 +0,0 @@
#ifndef _uart_included_h_
#define _uart_included_h_
#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);
#endif
-123
View File
@@ -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;
}
+1 -4
View File
@@ -1,10 +1,7 @@
#ifndef _VIRTSER_H_
#define _VIRTSER_H_
#pragma once
/* Define this function in your code to process incoming bytes */
void virtser_recv(const uint8_t ch);
/* Call this to send a character over the Virtual Serial Device */
void virtser_send(const uint8_t byte);
#endif
+81 -5
View File
@@ -1,5 +1,4 @@
#ifndef WAIT_H
#define WAIT_H
#pragma once
#include <inttypes.h>
@@ -7,12 +6,91 @@
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"
# include <ch.h>
# define wait_ms(ms) \
do { \
if (ms != 0) { \
@@ -41,5 +119,3 @@ void wait_ms(uint32_t ms);
#ifdef __cplusplus
}
#endif
#endif