Add adaptive NKRO feature

This commit is contained in:
lokher 2024-04-28 11:22:33 +08:00
parent fd0426237f
commit 6aa63c3c63
4 changed files with 136 additions and 3 deletions

View file

@ -37,6 +37,11 @@ static uint8_t suppressed_mods = 0;
report_keyboard_t *keyboard_report = &(report_keyboard_t){}; report_keyboard_t *keyboard_report = &(report_keyboard_t){};
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
report_nkro_t *nkro_report = &(report_nkro_t){}; report_nkro_t *nkro_report = &(report_nkro_t){};
# ifdef APDAPTIVE_NKRO_ENABLE
uint8_t kb_report_changed;
uint8_t kb_keys_count = 0;
uint8_t nkro_bit_count = 0;
# endif
#endif #endif
extern inline void add_key(uint8_t key); extern inline void add_key(uint8_t key);
@ -295,13 +300,17 @@ void send_6kro_report(void) {
memcpy(&last_report, keyboard_report, sizeof(report_keyboard_t)); memcpy(&last_report, keyboard_report, sizeof(report_keyboard_t));
host_keyboard_send(keyboard_report); host_keyboard_send(keyboard_report);
} }
# ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed &= ~KB_RPT_STD;
# endif
#endif #endif
} }
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
void send_nkro_report(void) { void send_nkro_report(void) {
# ifndef APDAPTIVE_NKRO_ENABLE
nkro_report->mods = get_mods_for_report(); nkro_report->mods = get_mods_for_report();
# endif
static report_nkro_t last_report; static report_nkro_t last_report;
/* Only send the report if there are changes to propagate to the host. */ /* Only send the report if there are changes to propagate to the host. */
@ -309,6 +318,9 @@ void send_nkro_report(void) {
memcpy(&last_report, nkro_report, sizeof(report_nkro_t)); memcpy(&last_report, nkro_report, sizeof(report_nkro_t));
host_nkro_send(nkro_report); host_nkro_send(nkro_report);
} }
# ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed &= ~KB_RPT_NKRO;
# endif
} }
#endif #endif
@ -318,11 +330,18 @@ void send_nkro_report(void) {
*/ */
void send_keyboard_report(void) { void send_keyboard_report(void) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
if (keyboard_protocol && (kb_report_changed & KB_RPT_NKRO)) {
send_nkro_report();
}
if (kb_report_changed & KB_RPT_STD) send_6kro_report();
# else
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
send_nkro_report(); send_nkro_report();
} else { } else {
send_6kro_report(); send_6kro_report();
} }
# endif
#else #else
send_6kro_report(); send_6kro_report();
#endif #endif
@ -341,6 +360,9 @@ uint8_t get_mods(void) {
*/ */
void add_mods(uint8_t mods) { void add_mods(uint8_t mods) {
real_mods |= mods; real_mods |= mods;
#ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
#endif
} }
/** \brief del mods /** \brief del mods
* *
@ -348,19 +370,30 @@ void add_mods(uint8_t mods) {
*/ */
void del_mods(uint8_t mods) { void del_mods(uint8_t mods) {
real_mods &= ~mods; real_mods &= ~mods;
#ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
#endif
} }
/** \brief set mods /** \brief set mods
* *
* FIXME: needs doc * FIXME: needs doc
*/ */
void set_mods(uint8_t mods) { void set_mods(uint8_t mods) {
real_mods = mods; real_mods = mods;
#ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
#endif
} }
/** \brief clear mods /** \brief clear mods
* *
* FIXME: needs doc * FIXME: needs doc
*/ */
void clear_mods(void) { void clear_mods(void) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (real_mods) kb_report_changed |= KB_RPT_STD;
#endif
real_mods = 0; real_mods = 0;
} }
@ -377,19 +410,30 @@ uint8_t get_weak_mods(void) {
*/ */
void add_weak_mods(uint8_t mods) { void add_weak_mods(uint8_t mods) {
weak_mods |= mods; weak_mods |= mods;
#ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
#endif
} }
/** \brief del weak mods /** \brief del weak mods
* *
* FIXME: needs doc * FIXME: needs doc
*/ */
void del_weak_mods(uint8_t mods) { void del_weak_mods(uint8_t mods) {
weak_mods &= ~mods; weak_mods &= ~mods;
#ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
#endif
} }
/** \brief set weak mods /** \brief set weak mods
* *
* FIXME: needs doc * FIXME: needs doc
*/ */
void set_weak_mods(uint8_t mods) { void set_weak_mods(uint8_t mods) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (weak_mods != mods) kb_report_changed |= KB_RPT_STD;
#endif
weak_mods = mods; weak_mods = mods;
} }
/** \brief clear weak mods /** \brief clear weak mods
@ -397,6 +441,9 @@ void set_weak_mods(uint8_t mods) {
* FIXME: needs doc * FIXME: needs doc
*/ */
void clear_weak_mods(void) { void clear_weak_mods(void) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (weak_mods) kb_report_changed |= KB_RPT_STD;
#endif
weak_mods = 0; weak_mods = 0;
} }
@ -404,22 +451,34 @@ void clear_weak_mods(void) {
/** \brief set weak mods used by key overrides. DO not call this manually /** \brief set weak mods used by key overrides. DO not call this manually
*/ */
void set_weak_override_mods(uint8_t mods) { void set_weak_override_mods(uint8_t mods) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (weak_override_mods != mods) kb_report_changed |= KB_RPT_STD;
#endif
weak_override_mods = mods; weak_override_mods = mods;
} }
/** \brief clear weak mods used by key overrides. DO not call this manually /** \brief clear weak mods used by key overrides. DO not call this manually
*/ */
void clear_weak_override_mods(void) { void clear_weak_override_mods(void) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (weak_override_mods) kb_report_changed |= KB_RPT_STD;
#endif
weak_override_mods = 0; weak_override_mods = 0;
} }
/** \brief set suppressed mods used by key overrides. DO not call this manually /** \brief set suppressed mods used by key overrides. DO not call this manually
*/ */
void set_suppressed_override_mods(uint8_t mods) { void set_suppressed_override_mods(uint8_t mods) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (suppressed_mods != mods) kb_report_changed |= KB_RPT_STD;
#endif
suppressed_mods = mods; suppressed_mods = mods;
} }
/** \brief clear suppressed mods used by key overrides. DO not call this manually /** \brief clear suppressed mods used by key overrides. DO not call this manually
*/ */
void clear_suppressed_override_mods(void) { void clear_suppressed_override_mods(void) {
#ifdef APDAPTIVE_NKRO_ENABLE
if (suppressed_mods) kb_report_changed |= KB_RPT_STD;
#endif
suppressed_mods = 0; suppressed_mods = 0;
} }
#endif #endif

View file

@ -28,6 +28,11 @@ extern "C" {
extern report_keyboard_t *keyboard_report; extern report_keyboard_t *keyboard_report;
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
extern report_nkro_t *nkro_report; extern report_nkro_t *nkro_report;
# ifdef APDAPTIVE_NKRO_ENABLE
extern uint8_t kb_report_changed;
extern uint8_t kb_keys_count;
extern uint8_t nkro_bit_count;
# endif
#endif #endif
void send_keyboard_report(void); void send_keyboard_report(void);

View file

@ -41,6 +41,9 @@ uint8_t has_anykey(void) {
uint8_t* p = keyboard_report->keys; uint8_t* p = keyboard_report->keys;
uint8_t lp = sizeof(keyboard_report->keys); uint8_t lp = sizeof(keyboard_report->keys);
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
return kb_keys_count + nkro_bit_count;
# endif
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
p = nkro_report->bits; p = nkro_report->bits;
lp = sizeof(nkro_report->bits); lp = sizeof(nkro_report->bits);
@ -58,12 +61,16 @@ uint8_t has_anykey(void) {
*/ */
uint8_t get_first_key(void) { uint8_t get_first_key(void) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
return keyboard_report->keys[0];
# else
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
uint8_t i = 0; uint8_t i = 0;
for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++) for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
; ;
return i << 3 | biton(nkro_report->bits[i]); return i << 3 | biton(nkro_report->bits[i]);
} }
# endif
#endif #endif
#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE #ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
uint8_t i = cb_head; uint8_t i = cb_head;
@ -89,6 +96,11 @@ bool is_key_pressed(uint8_t key) {
return false; return false;
} }
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
if (keyboard_protocol && nkro_bit_count) {
if ((key >> 3) < NKRO_REPORT_BITS && (nkro_report->bits[key >> 3] & 1 << (key & 7))) return true;
}
# else
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
if ((key >> 3) < NKRO_REPORT_BITS) { if ((key >> 3) < NKRO_REPORT_BITS) {
return nkro_report->bits[key >> 3] & 1 << (key & 7); return nkro_report->bits[key >> 3] & 1 << (key & 7);
@ -96,6 +108,7 @@ bool is_key_pressed(uint8_t key) {
return false; return false;
} }
} }
#endif
#endif #endif
for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == key) { if (keyboard_report->keys[i] == key) {
@ -167,6 +180,10 @@ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
if (i == KEYBOARD_REPORT_KEYS) { if (i == KEYBOARD_REPORT_KEYS) {
if (empty != -1) { if (empty != -1) {
keyboard_report->keys[empty] = code; keyboard_report->keys[empty] = code;
# ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
++kb_keys_count;
# endif
} }
} }
#endif #endif
@ -206,6 +223,10 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) { if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0; keyboard_report->keys[i] = 0;
# ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_STD;
--kb_keys_count;
# endif
} }
} }
#endif #endif
@ -219,6 +240,10 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
void add_key_bit(report_nkro_t* nkro_report, uint8_t code) { void add_key_bit(report_nkro_t* nkro_report, uint8_t code) {
if ((code >> 3) < NKRO_REPORT_BITS) { if ((code >> 3) < NKRO_REPORT_BITS) {
nkro_report->bits[code >> 3] |= 1 << (code & 7); nkro_report->bits[code >> 3] |= 1 << (code & 7);
# ifdef APDAPTIVE_NKRO_ENABLE
kb_report_changed |= KB_RPT_NKRO;
++nkro_bit_count;
# endif
} else { } else {
dprintf("add_key_bit: can't add: %02X\n", code); dprintf("add_key_bit: can't add: %02X\n", code);
} }
@ -228,12 +253,24 @@ void add_key_bit(report_nkro_t* nkro_report, uint8_t code) {
* *
* FIXME: Needs doc * FIXME: Needs doc
*/ */
void del_key_bit(report_nkro_t* nkro_report, uint8_t code) { bool del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
if ((code >> 3) < NKRO_REPORT_BITS) { if ((code >> 3) < NKRO_REPORT_BITS) {
# ifdef APDAPTIVE_NKRO_ENABLE
if (nkro_report->bits[code >> 3] & (1 << (code & 7))) {
nkro_report->bits[code >> 3] &= ~(1 << (code & 7));
kb_report_changed |= KB_RPT_NKRO;
--nkro_bit_count;
return true;
}
# else
nkro_report->bits[code >> 3] &= ~(1 << (code & 7)); nkro_report->bits[code >> 3] &= ~(1 << (code & 7));
return true;
# endif
} else { } else {
dprintf("del_key_bit: can't del: %02X\n", code); dprintf("del_key_bit: can't del: %02X\n", code);
} }
return false;
} }
#endif #endif
@ -243,7 +280,11 @@ void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
*/ */
void add_key_to_report(uint8_t key) { void add_key_to_report(uint8_t key) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
if (keyboard_protocol && kb_keys_count == KEYBOARD_REPORT_KEYS) {
# else
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
# endif
add_key_bit(nkro_report, key); add_key_bit(nkro_report, key);
return; return;
} }
@ -257,10 +298,14 @@ void add_key_to_report(uint8_t key) {
*/ */
void del_key_from_report(uint8_t key) { void del_key_from_report(uint8_t key) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
if (keyboard_protocol && nkro_bit_count && del_key_bit(nkro_report, key)) return;
# else
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
del_key_bit(nkro_report, key); del_key_bit(nkro_report, key);
return; return;
} }
# endif
#endif #endif
del_key_byte(keyboard_report, key); del_key_byte(keyboard_report, key);
} }
@ -272,10 +317,25 @@ void del_key_from_report(uint8_t key) {
void clear_keys_from_report(void) { void clear_keys_from_report(void) {
// not clear mods // not clear mods
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
# ifdef APDAPTIVE_NKRO_ENABLE
memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
if (nkro_bit_count) {
kb_report_changed |= KB_RPT_NKRO;
nkro_bit_count = 0;
}
memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
if (kb_keys_count) {
kb_report_changed |= KB_RPT_STD;
kb_keys_count = 0;
}
return;
# else
if (keyboard_protocol && keymap_config.nkro) { if (keyboard_protocol && keymap_config.nkro) {
memset(nkro_report->bits, 0, sizeof(nkro_report->bits)); memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
return; return;
} }
# endif
#endif #endif
memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys)); memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
} }

View file

@ -36,6 +36,15 @@ enum hid_report_ids {
REPORT_ID_DIGITIZER REPORT_ID_DIGITIZER
}; };
#ifdef APDAPTIVE_NKRO_ENABLE
/* Keyboard report type */
#define KB_RPT_MASK(n) (1 << (n))
enum kb_reports {
KB_RPT_STD = KB_RPT_MASK(0),
KB_RPT_NKRO = KB_RPT_MASK(1)
};
#endif
/* Mouse buttons */ /* Mouse buttons */
#define MOUSE_BTN_MASK(n) (1 << (n)) #define MOUSE_BTN_MASK(n) (1 << (n))
enum mouse_buttons { enum mouse_buttons {
@ -321,7 +330,7 @@ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code); void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
void add_key_bit(report_nkro_t* nkro_report, uint8_t code); void add_key_bit(report_nkro_t* nkro_report, uint8_t code);
void del_key_bit(report_nkro_t* nkro_report, uint8_t code); bool del_key_bit(report_nkro_t* nkro_report, uint8_t code);
#endif #endif
void add_key_to_report(uint8_t key); void add_key_to_report(uint8_t key);