~ruther/qmk_firmware

0c160e1fbafbf477c74e64fd8ab9a9121eb0f42a — Ryan 1 year, 6 months ago bf6f13a
Separate 6KRO and NKRO report structs (#22267)

M keyboards/annepro2/annepro2_ble.c => keyboards/annepro2/annepro2_ble.c +1 -1
@@ 31,7 31,7 @@ static void ap2_ble_swtich_ble_driver(void);

/* -------------------- Static Local Variables ------------------------------ */
static host_driver_t ap2_ble_driver = {
    ap2_ble_leds, ap2_ble_keyboard, ap2_ble_mouse, ap2_ble_extra
    ap2_ble_leds, ap2_ble_keyboard, NULL, ap2_ble_mouse, ap2_ble_extra
};

static uint8_t ble_mcu_wakeup[11] = {0x7b, 0x12, 0x53, 0x00, 0x03, 0x00, 0x01, 0x7d, 0x02, 0x01, 0x02};

M keyboards/horrortroll/lemon40/info.json => keyboards/horrortroll/lemon40/info.json +1 -2
@@ 19,8 19,7 @@
            "knight": true,
            "christmas": true,
            "static_gradient": true,
            "alternating": true,
            "twinkle": true
            "alternating": true
        }
    },
    "ws2812": {

M keyboards/kbdfans/kbd67/rev1/info.json => keyboards/kbdfans/kbd67/rev1/info.json +0 -1
@@ 38,7 38,6 @@
      "knight": true,
      "christmas": true,
      "static_gradient": true,
      "rgb_test": true,
      "alternating": true,
      "twinkle": true
    }

M quantum/action.c => quantum/action.c +1 -1
@@ 925,7 925,7 @@ __attribute__((weak)) void register_code(uint8_t code) {
        // Force a new key press if the key is already pressed
        // without this, keys with the same keycode, but different
        // modifiers will be reported incorrectly, see issue #1708
        if (is_key_pressed(keyboard_report, code)) {
        if (is_key_pressed(code)) {
            del_key(code);
            send_keyboard_report();
        }

M quantum/action_util.c => quantum/action_util.c +45 -12
@@ 35,6 35,9 @@ static uint8_t suppressed_mods    = 0;
// TODO: pointer variable is not needed
// report_keyboard_t keyboard_report = {};
report_keyboard_t *keyboard_report = &(report_keyboard_t){};
#ifdef NKRO_ENABLE
report_nkro_t *nkro_report = &(report_nkro_t){};
#endif

extern inline void add_key(uint8_t key);
extern inline void del_key(uint8_t key);


@@ 252,13 255,8 @@ bool is_oneshot_enabled(void) {

#endif

/** \brief Send keyboard report
 *
 * FIXME: needs doc
 */
void send_keyboard_report(void) {
    keyboard_report->mods = real_mods;
    keyboard_report->mods |= weak_mods;
static uint8_t get_mods_for_report(void) {
    uint8_t mods = real_mods | weak_mods;

#ifndef NO_ACTION_ONESHOT
    if (oneshot_mods) {


@@ 268,20 266,25 @@ void send_keyboard_report(void) {
            clear_oneshot_mods();
        }
#    endif
        keyboard_report->mods |= oneshot_mods;
        if (has_anykey(keyboard_report)) {
        mods |= oneshot_mods;
        if (has_anykey()) {
            clear_oneshot_mods();
        }
    }

#endif

#ifdef KEY_OVERRIDE_ENABLE
    // These need to be last to be able to properly control key overrides
    keyboard_report->mods &= ~suppressed_mods;
    keyboard_report->mods |= weak_override_mods;
    mods &= ~suppressed_mods;
    mods |= weak_override_mods;
#endif

    return mods;
}

void send_6kro_report(void) {
    keyboard_report->mods = get_mods_for_report();

#ifdef PROTOCOL_VUSB
    host_keyboard_send(keyboard_report);
#else


@@ 295,6 298,36 @@ void send_keyboard_report(void) {
#endif
}

#ifdef NKRO_ENABLE
void send_nkro_report(void) {
    nkro_report->mods = get_mods_for_report();

    static report_nkro_t last_report;

    /* Only send the report if there are changes to propagate to the host. */
    if (memcmp(nkro_report, &last_report, sizeof(report_nkro_t)) != 0) {
        memcpy(&last_report, nkro_report, sizeof(report_nkro_t));
        host_nkro_send(nkro_report);
    }
}
#endif

/** \brief Send keyboard report
 *
 * FIXME: needs doc
 */
void send_keyboard_report(void) {
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        send_nkro_report();
    } else {
        send_6kro_report();
    }
#else
    send_6kro_report();
#endif
}

/** \brief Get mods
 *
 * FIXME: needs doc

M quantum/action_util.h => quantum/action_util.h +6 -3
@@ 26,20 26,23 @@ extern "C" {
#endif

extern report_keyboard_t *keyboard_report;
#ifdef NKRO_ENABLE
extern report_nkro_t *nkro_report;
#endif

void send_keyboard_report(void);

/* key */
inline void add_key(uint8_t key) {
    add_key_to_report(keyboard_report, key);
    add_key_to_report(key);
}

inline void del_key(uint8_t key) {
    del_key_from_report(keyboard_report, key);
    del_key_from_report(key);
}

inline void clear_keys(void) {
    clear_keys_from_report(keyboard_report);
    clear_keys_from_report();
}

/* modifier */

M tests/test_common/keyboard_report_util.cpp => tests/test_common/keyboard_report_util.cpp +2 -2
@@ 95,12 95,12 @@ std::ostream& operator<<(std::ostream& os, const report_keyboard_t& report) {
}

KeyboardReportMatcher::KeyboardReportMatcher(const std::vector<uint8_t>& keys) {
    memset(m_report.raw, 0, sizeof(m_report.raw));
    memset(&m_report, 0, sizeof(report_keyboard_t));
    for (auto k : keys) {
        if (IS_MODIFIER_KEYCODE(k)) {
            m_report.mods |= MOD_BIT(k);
        } else {
            add_key_to_report(&m_report, k);
            add_key_byte(&m_report, k);
        }
    }
}

M tests/test_common/test_driver.cpp => tests/test_common/test_driver.cpp +5 -1
@@ 31,7 31,7 @@ uint8_t hex_digit_to_keycode(uint8_t digit) {
}
} // namespace

TestDriver::TestDriver() : m_driver{&TestDriver::keyboard_leds, &TestDriver::send_keyboard, &TestDriver::send_mouse, &TestDriver::send_extra} {
TestDriver::TestDriver() : m_driver{&TestDriver::keyboard_leds, &TestDriver::send_keyboard, &TestDriver::send_nkro, &TestDriver::send_mouse, &TestDriver::send_extra} {
    host_set_driver(&m_driver);
    m_this = this;
}


@@ 49,6 49,10 @@ void TestDriver::send_keyboard(report_keyboard_t* report) {
    m_this->send_keyboard_mock(*report);
}

void TestDriver::send_nkro(report_nkro_t* report) {
    m_this->send_nkro_mock(*report);
}

void TestDriver::send_mouse(report_mouse_t* report) {
    m_this->send_mouse_mock(*report);
}

M tests/test_common/test_driver.hpp => tests/test_common/test_driver.hpp +2 -0
@@ 32,12 32,14 @@ class TestDriver {
    }

    MOCK_METHOD1(send_keyboard_mock, void(report_keyboard_t&));
    MOCK_METHOD1(send_nkro_mock, void(report_nkro_t&));
    MOCK_METHOD1(send_mouse_mock, void(report_mouse_t&));
    MOCK_METHOD1(send_extra_mock, void(report_extra_t&));

   private:
    static uint8_t     keyboard_leds(void);
    static void        send_keyboard(report_keyboard_t* report);
    static void        send_nkro(report_nkro_t* report);
    static void        send_mouse(report_mouse_t* report);
    static void        send_extra(report_extra_t* report);
    host_driver_t      m_driver;

M tmk_core/protocol.mk => tmk_core/protocol.mk +1 -3
@@ 46,9 46,7 @@ else
endif

ifeq ($(strip $(NKRO_ENABLE)), yes)
    ifeq ($(PROTOCOL), VUSB)
        $(info NKRO is not currently supported on V-USB, and has been disabled.)
    else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
    ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
        $(info NKRO is not currently supported with Bluetooth, and has been disabled.)
    else
        OPT_DEFS += -DNKRO_ENABLE

M tmk_core/protocol/arm_atsam/main_arm_atsam.c => tmk_core/protocol/arm_atsam/main_arm_atsam.c +30 -29
@@ 36,6 36,7 @@ uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from ha
void    main_subtasks(void);
uint8_t keyboard_leds(void);
void    send_keyboard(report_keyboard_t *report);
void    send_nkro(report_nkro_t *report);
void    send_mouse(report_mouse_t *report);
void    send_extra(report_extra_t *report);



@@ 43,7 44,7 @@ void    send_extra(report_extra_t *report);
void deferred_exec_task(void);
#endif // DEFERRED_EXEC_ENABLE

host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};

uint8_t led_states;



@@ 59,41 60,41 @@ uint8_t keyboard_leds(void) {
void send_keyboard(report_keyboard_t *report) {
    uint32_t irqflags;

#ifdef NKRO_ENABLE
    if (!keymap_config.nkro) {
#endif // NKRO_ENABLE
        while (udi_hid_kbd_b_report_trans_ongoing) {
            main_subtasks();
        } // Run other tasks while waiting for USB to be free
    while (udi_hid_kbd_b_report_trans_ongoing) {
        main_subtasks();
    } // Run other tasks while waiting for USB to be free

        irqflags = __get_PRIMASK();
        __disable_irq();
        __DMB();
    irqflags = __get_PRIMASK();
    __disable_irq();
    __DMB();

        memcpy(udi_hid_kbd_report, report->raw, UDI_HID_KBD_REPORT_SIZE);
        udi_hid_kbd_b_report_valid = 1;
        udi_hid_kbd_send_report();
    memcpy(udi_hid_kbd_report, report, UDI_HID_KBD_REPORT_SIZE);
    udi_hid_kbd_b_report_valid = 1;
    udi_hid_kbd_send_report();

        __DMB();
        __set_PRIMASK(irqflags);
    __DMB();
    __set_PRIMASK(irqflags);
}

void send_nkro(report_nkro_t *report) {
#ifdef NKRO_ENABLE
    } else {
        while (udi_hid_nkro_b_report_trans_ongoing) {
            main_subtasks();
        } // Run other tasks while waiting for USB to be free
    uint32_t irqflags;

        irqflags = __get_PRIMASK();
        __disable_irq();
        __DMB();
    while (udi_hid_nkro_b_report_trans_ongoing) {
        main_subtasks();
    } // Run other tasks while waiting for USB to be free

        memcpy(udi_hid_nkro_report, report->raw, UDI_HID_NKRO_REPORT_SIZE);
        udi_hid_nkro_b_report_valid = 1;
        udi_hid_nkro_send_report();
    irqflags = __get_PRIMASK();
    __disable_irq();
    __DMB();

        __DMB();
        __set_PRIMASK(irqflags);
    }
#endif // NKRO_ENABLE
    memcpy(udi_hid_nkro_report, report, UDI_HID_NKRO_REPORT_SIZE);
    udi_hid_nkro_b_report_valid = 1;
    udi_hid_nkro_send_report();

    __DMB();
    __set_PRIMASK(irqflags);
#endif
}

void send_mouse(report_mouse_t *report) {

M tmk_core/protocol/chibios/chibios.c => tmk_core/protocol/chibios/chibios.c +2 -1
@@ 59,11 59,12 @@
/* declarations */
uint8_t keyboard_leds(void);
void    send_keyboard(report_keyboard_t *report);
void    send_nkro(report_nkro_t *report);
void    send_mouse(report_mouse_t *report);
void    send_extra(report_extra_t *report);

/* host struct */
host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};

#ifdef VIRTSER_ENABLE
void virtser_task(void);

M tmk_core/protocol/chibios/usb_main.c => tmk_core/protocol/chibios/usb_main.c +9 -13
@@ 71,7 71,7 @@ static virtual_timer_t keyboard_idle_timer;

static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg);

report_keyboard_t keyboard_report_sent = {{0}};
report_keyboard_t keyboard_report_sent = {0};
report_mouse_t    mouse_report_sent    = {0};

union {


@@ 883,26 883,22 @@ void send_report(uint8_t endpoint, void *report, size_t size) {
/* prepare and start sending a report IN
 * not callable from ISR or locked state */
void send_keyboard(report_keyboard_t *report) {
    uint8_t ep   = KEYBOARD_IN_EPNUM;
    size_t  size = KEYBOARD_REPORT_SIZE;

    /* If we're in Boot Protocol, don't send any report ID or other funky fields */
    if (!keyboard_protocol) {
        send_report(ep, &report->mods, 8);
        send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
    } else {
#ifdef NKRO_ENABLE
        if (keymap_config.nkro) {
            ep   = SHARED_IN_EPNUM;
            size = sizeof(struct nkro_report);
        }
#endif

        send_report(ep, report, size);
        send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
    }

    keyboard_report_sent = *report;
}

void send_nkro(report_nkro_t *report) {
#ifdef NKRO_ENABLE
    send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
#endif
}

/* ---------------------------------------------------------
 *                     Mouse functions
 * ---------------------------------------------------------

M tmk_core/protocol/host.c => tmk_core/protocol/host.c +18 -15
@@ 81,26 81,29 @@ void host_keyboard_send(report_keyboard_t *report) {
#endif

    if (!driver) return;
#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
    if (keyboard_protocol && keymap_config.nkro) {
        /* The callers of this function assume that report->mods is where mods go in.
         * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
         */
        report->nkro.mods      = report->mods;
        report->nkro.report_id = REPORT_ID_NKRO;
    } else
#endif
    {
#ifdef KEYBOARD_SHARED_EP
        report->report_id = REPORT_ID_KEYBOARD;
    report->report_id = REPORT_ID_KEYBOARD;
#endif
    }
    (*driver->send_keyboard)(report);

    if (debug_keyboard) {
        dprint("keyboard_report: ");
        for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
            dprintf("%02X ", report->raw[i]);
        dprintf("keyboard_report: %02X | ", report->mods);
        for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
            dprintf("%02X ", report->keys[i]);
        }
        dprint("\n");
    }
}

void host_nkro_send(report_nkro_t *report) {
    if (!driver) return;
    report->report_id = REPORT_ID_NKRO;
    (*driver->send_nkro)(report);

    if (debug_keyboard) {
        dprintf("nkro_report: %02X | ", report->mods);
        for (uint8_t i = 0; i < NKRO_REPORT_BITS; i++) {
            dprintf("%02X ", report->bits[i]);
        }
        dprint("\n");
    }

M tmk_core/protocol/host.h => tmk_core/protocol/host.h +1 -0
@@ 38,6 38,7 @@ host_driver_t *host_get_driver(void);
uint8_t host_keyboard_leds(void);
led_t   host_keyboard_led_state(void);
void    host_keyboard_send(report_keyboard_t *report);
void    host_nkro_send(report_nkro_t *report);
void    host_mouse_send(report_mouse_t *report);
void    host_system_send(uint16_t usage);
void    host_consumer_send(uint16_t usage);

M tmk_core/protocol/host_driver.h => tmk_core/protocol/host_driver.h +1 -0
@@ 26,6 26,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
typedef struct {
    uint8_t (*keyboard_leds)(void);
    void (*send_keyboard)(report_keyboard_t *);
    void (*send_nkro)(report_nkro_t *);
    void (*send_mouse)(report_mouse_t *);
    void (*send_extra)(report_extra_t *);
} host_driver_t;

M tmk_core/protocol/lufa/lufa.c => tmk_core/protocol/lufa/lufa.c +14 -20
@@ 55,12 55,6 @@
#include "usb_device_state.h"
#include <util/atomic.h>

#ifdef NKRO_ENABLE
#    include "keycode_config.h"

extern keymap_config_t keymap_config;
#endif

#ifdef VIRTSER_ENABLE
#    include "virtser.h"
#endif


@@ 83,9 77,10 @@ static report_keyboard_t keyboard_report_sent;
/* Host driver */
static uint8_t keyboard_leds(void);
static void    send_keyboard(report_keyboard_t *report);
static void    send_nkro(report_nkro_t *report);
static void    send_mouse(report_mouse_t *report);
static void    send_extra(report_extra_t *report);
host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};

void send_report(uint8_t endpoint, void *report, size_t size) {
    uint8_t timeout = 255;


@@ 559,27 554,26 @@ static uint8_t keyboard_leds(void) {
 * FIXME: Needs doc
 */
static void send_keyboard(report_keyboard_t *report) {
    /* Select the Keyboard Report Endpoint */
    uint8_t ep   = KEYBOARD_IN_EPNUM;
    uint8_t size = KEYBOARD_REPORT_SIZE;

    /* If we're in Boot Protocol, don't send any report ID or other funky fields */
    if (!keyboard_protocol) {
        send_report(ep, &report->mods, 8);
        send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
    } else {
#ifdef NKRO_ENABLE
        if (keymap_config.nkro) {
            ep   = SHARED_IN_EPNUM;
            size = sizeof(struct nkro_report);
        }
#endif

        send_report(ep, report, size);
        send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);
    }

    keyboard_report_sent = *report;
}

/** \brief Send NKRO
 *
 * FIXME: Needs doc
 */
static void send_nkro(report_nkro_t *report) {
#ifdef NKRO_ENABLE
    send_report(SHARED_IN_EPNUM, report, sizeof(report_nkro_t));
#endif
}

/** \brief Send Mouse
 *
 * FIXME: Needs doc

M tmk_core/protocol/report.c => tmk_core/protocol/report.c +19 -18
@@ 15,6 15,7 @@
 */

#include "report.h"
#include "action_util.h"
#include "host.h"
#include "keycode_config.h"
#include "debug.h"


@@ 35,14 36,14 @@ static int8_t cb_count = 0;
 *
 * FIXME: Needs doc
 */
uint8_t has_anykey(report_keyboard_t* keyboard_report) {
uint8_t has_anykey(void) {
    uint8_t  cnt = 0;
    uint8_t* p   = keyboard_report->keys;
    uint8_t  lp  = sizeof(keyboard_report->keys);
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        p  = keyboard_report->nkro.bits;
        lp = sizeof(keyboard_report->nkro.bits);
        p  = nkro_report->bits;
        lp = sizeof(nkro_report->bits);
    }
#endif
    while (lp--) {


@@ 55,13 56,13 @@ uint8_t has_anykey(report_keyboard_t* keyboard_report) {
 *
 * FIXME: Needs doc
 */
uint8_t get_first_key(report_keyboard_t* keyboard_report) {
uint8_t get_first_key(void) {
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        uint8_t i = 0;
        for (; i < NKRO_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
        for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
            ;
        return i << 3 | biton(keyboard_report->nkro.bits[i]);
        return i << 3 | biton(nkro_report->bits[i]);
    }
#endif
#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE


@@ 83,14 84,14 @@ uint8_t get_first_key(report_keyboard_t* keyboard_report) {
 * Returns true if the keyboard_report reports that the key is pressed, otherwise false
 * Note: The function doesn't support modifers currently, and it returns false for KC_NO
 */
bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) {
bool is_key_pressed(uint8_t key) {
    if (key == KC_NO) {
        return false;
    }
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        if ((key >> 3) < NKRO_REPORT_BITS) {
            return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7);
            return nkro_report->bits[key >> 3] & 1 << (key & 7);
        } else {
            return false;
        }


@@ 215,9 216,9 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
 *
 * FIXME: Needs doc
 */
void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
void add_key_bit(report_nkro_t* nkro_report, uint8_t code) {
    if ((code >> 3) < NKRO_REPORT_BITS) {
        keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7);
        nkro_report->bits[code >> 3] |= 1 << (code & 7);
    } else {
        dprintf("add_key_bit: can't add: %02X\n", code);
    }


@@ 227,9 228,9 @@ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
 *
 * FIXME: Needs doc
 */
void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
    if ((code >> 3) < NKRO_REPORT_BITS) {
        keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7));
        nkro_report->bits[code >> 3] &= ~(1 << (code & 7));
    } else {
        dprintf("del_key_bit: can't del: %02X\n", code);
    }


@@ 240,10 241,10 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
 *
 * FIXME: Needs doc
 */
void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
void add_key_to_report(uint8_t key) {
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        add_key_bit(keyboard_report, key);
        add_key_bit(nkro_report, key);
        return;
    }
#endif


@@ 254,10 255,10 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
 *
 * FIXME: Needs doc
 */
void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
void del_key_from_report(uint8_t key) {
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        del_key_bit(keyboard_report, key);
        del_key_bit(nkro_report, key);
        return;
    }
#endif


@@ 268,11 269,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
 *
 * FIXME: Needs doc
 */
void clear_keys_from_report(report_keyboard_t* keyboard_report) {
void clear_keys_from_report(void) {
    // not clear mods
#ifdef NKRO_ENABLE
    if (keyboard_protocol && keymap_config.nkro) {
        memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
        memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
        return;
    }
#endif

M tmk_core/protocol/report.h => tmk_core/protocol/report.h +20 -40
@@ 125,21 125,7 @@ enum desktop_usages {

// clang-format on

#define NKRO_SHARED_EP
/* key report size(NKRO or boot mode) */
#if defined(NKRO_ENABLE)
#    if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
#        include "protocol/usb_descriptor.h"
#        define NKRO_REPORT_BITS (SHARED_EPSIZE - 2)
#    elif defined(PROTOCOL_ARM_ATSAM)
#        include "protocol/arm_atsam/usb/udi_device_epsize.h"
#        define NKRO_REPORT_BITS (NKRO_EPSIZE - 1)
#        undef NKRO_SHARED_EP
#        undef MOUSE_SHARED_EP
#    else
#        error "NKRO not supported with this protocol"
#    endif
#endif
#define NKRO_REPORT_BITS 30

#ifdef KEYBOARD_SHARED_EP
#    define KEYBOARD_REPORT_SIZE 9


@@ 173,28 159,22 @@ extern "C" {
 * desc |Lcontrol|Lshift  |Lalt    |Lgui    |Rcontrol|Rshift  |Ralt    |Rgui
 *
 */
typedef union {
    uint8_t raw[KEYBOARD_REPORT_SIZE];
    struct {
typedef struct {
#ifdef KEYBOARD_SHARED_EP
        uint8_t report_id;
#endif
        uint8_t mods;
        uint8_t reserved;
        uint8_t keys[KEYBOARD_REPORT_KEYS];
    };
#ifdef NKRO_ENABLE
    struct nkro_report {
#    ifdef NKRO_SHARED_EP
        uint8_t report_id;
#    endif
        uint8_t mods;
        uint8_t bits[NKRO_REPORT_BITS];
    } nkro;
    uint8_t report_id;
#endif
    uint8_t mods;
    uint8_t reserved;
    uint8_t keys[KEYBOARD_REPORT_KEYS];
} PACKED report_keyboard_t;

typedef struct {
    uint8_t report_id;
    uint8_t mods;
    uint8_t bits[NKRO_REPORT_BITS];
} PACKED report_nkro_t;

typedef struct {
    uint8_t  report_id;
    uint16_t usage;
} PACKED report_extra_t;


@@ 330,20 310,20 @@ static inline uint16_t KEYCODE2CONSUMER(uint8_t key) {
    }
}

uint8_t has_anykey(report_keyboard_t* keyboard_report);
uint8_t get_first_key(report_keyboard_t* keyboard_report);
bool    is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key);
uint8_t has_anykey(void);
uint8_t get_first_key(void);
bool    is_key_pressed(uint8_t key);

void add_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
void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
void del_key_bit(report_keyboard_t* keyboard_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);
#endif

void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key);
void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
void clear_keys_from_report(report_keyboard_t* keyboard_report);
void add_key_to_report(uint8_t key);
void del_key_from_report(uint8_t key);
void clear_keys_from_report(void);

#ifdef MOUSE_ENABLE
bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report);

M tmk_core/protocol/vusb/vusb.c => tmk_core/protocol/vusb/vusb.c +7 -1
@@ 91,6 91,7 @@ enum usb_interfaces {

static uint8_t keyboard_led_state = 0;
static uint8_t vusb_idle_rate     = 0;
uint8_t        keyboard_protocol  = 1;

/* Keyboard report send buffer */
#define KBUF_SIZE 16


@@ 231,10 232,11 @@ void console_task(void) {
 *------------------------------------------------------------------*/
static uint8_t keyboard_leds(void);
static void    send_keyboard(report_keyboard_t *report);
static void    send_nkro(report_nkro_t *report);
static void    send_mouse(report_mouse_t *report);
static void    send_extra(report_extra_t *report);

static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_extra};
static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};

host_driver_t *vusb_driver(void) {
    return &driver;


@@ 259,6 261,10 @@ static void send_keyboard(report_keyboard_t *report) {
    keyboard_report_sent = *report;
}

static void send_nkro(report_nkro_t *report) {
    // TODO: Implement NKRO
}

#ifndef KEYBOARD_SHARED_EP
#    define usbInterruptIsReadyShared usbInterruptIsReady3
#    define usbSetInterruptShared usbSetInterrupt3

Do not follow this link