qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

host.c (9310B)


      1 /*
      2 Copyright 2011,2012 Jun Wako <wakojun@gmail.com>
      3 
      4 This program is free software: you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation, either version 2 of the License, or
      7 (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17 
     18 #include <stdint.h>
     19 #include "keyboard.h"
     20 #include "keycode.h"
     21 #include "action.h"
     22 #include "host.h"
     23 #include "util.h"
     24 #include "debug.h"
     25 #include "usb_device_state.h"
     26 
     27 #ifdef DIGITIZER_ENABLE
     28 #    include "digitizer.h"
     29 #endif
     30 
     31 #ifdef JOYSTICK_ENABLE
     32 #    include "joystick.h"
     33 #endif
     34 
     35 #ifdef CONNECTION_ENABLE
     36 #    include "connection.h"
     37 #endif
     38 
     39 #ifdef BLUETOOTH_ENABLE
     40 #    include "bluetooth.h"
     41 
     42 static void bluetooth_send_extra(report_extra_t *report) {
     43     switch (report->report_id) {
     44         case REPORT_ID_SYSTEM:
     45             bluetooth_send_system(report->usage);
     46             return;
     47         case REPORT_ID_CONSUMER:
     48             bluetooth_send_consumer(report->usage);
     49             return;
     50     }
     51 }
     52 
     53 host_driver_t bt_driver = {
     54     .keyboard_leds = bluetooth_keyboard_leds,
     55     .send_keyboard = bluetooth_send_keyboard,
     56     .send_nkro     = bluetooth_send_nkro,
     57     .send_mouse    = bluetooth_send_mouse,
     58     .send_extra    = bluetooth_send_extra,
     59 #    ifdef RAW_ENABLE
     60     .send_raw_hid = bluetooth_send_raw_hid,
     61 #    endif
     62 };
     63 #endif
     64 
     65 #ifdef NKRO_ENABLE
     66 #    include "keycode_config.h"
     67 extern keymap_config_t keymap_config;
     68 #endif
     69 
     70 static host_driver_t *driver;
     71 static uint16_t       last_system_usage   = 0;
     72 static uint16_t       last_consumer_usage = 0;
     73 
     74 void host_set_driver(host_driver_t *d) {
     75     driver = d;
     76 }
     77 
     78 host_driver_t *host_get_driver(void) {
     79     return driver;
     80 }
     81 
     82 #ifdef CONNECTION_ENABLE
     83 static connection_host_t active_host = CONNECTION_HOST_NONE;
     84 
     85 __attribute__((weak)) void host_disconnect_active_driver_user(connection_host_t host) {}
     86 __attribute__((weak)) void host_disconnect_active_driver_kb(connection_host_t host) {}
     87 
     88 __attribute__((weak)) void host_connect_active_driver_user(connection_host_t host) {}
     89 __attribute__((weak)) void host_connect_active_driver_kb(connection_host_t host) {}
     90 
     91 // TODO: Additionally have host_driver_t handle swap
     92 static void host_update_active_driver(connection_host_t current, connection_host_t next) {
     93     host_disconnect_active_driver_user(current);
     94     host_disconnect_active_driver_kb(current);
     95 
     96     if (current != CONNECTION_HOST_NONE) {
     97         clear_keyboard();
     98     }
     99 
    100     host_connect_active_driver_user(next);
    101     host_connect_active_driver_kb(next);
    102 }
    103 
    104 #endif
    105 
    106 void host_init(void) {
    107     // currently do nothing
    108 }
    109 
    110 void host_task(void) {
    111 #ifdef CONNECTION_ENABLE
    112     connection_host_t next_host = connection_get_host();
    113     if (next_host != active_host) {
    114         host_update_active_driver(active_host, next_host);
    115 
    116         active_host = next_host;
    117     }
    118 #endif
    119 }
    120 
    121 static host_driver_t *host_get_active_driver(void) {
    122 #ifdef CONNECTION_ENABLE
    123     switch (active_host) {
    124 #    ifdef BLUETOOTH_ENABLE
    125         case CONNECTION_HOST_BLUETOOTH:
    126             return &bt_driver;
    127 #    endif
    128         case CONNECTION_HOST_NONE:
    129             return NULL;
    130         default:
    131             break;
    132     }
    133 #endif
    134     return driver;
    135 }
    136 
    137 bool host_can_send_nkro(void) {
    138 #ifdef CONNECTION_ENABLE
    139     switch (active_host) {
    140 #    ifdef BLUETOOTH_ENABLE
    141         case CONNECTION_HOST_BLUETOOTH:
    142             return bluetooth_can_send_nkro();
    143 #    endif
    144         case CONNECTION_HOST_NONE:
    145             return false;
    146         default:
    147             break;
    148     }
    149 #endif
    150 
    151     return usb_device_state_get_protocol() == USB_PROTOCOL_REPORT;
    152 }
    153 
    154 #ifdef SPLIT_KEYBOARD
    155 uint8_t split_led_state = 0;
    156 void    set_split_host_keyboard_leds(uint8_t led_state) {
    157     split_led_state = led_state;
    158 }
    159 #endif
    160 
    161 uint8_t host_keyboard_leds(void) {
    162 #ifdef SPLIT_KEYBOARD
    163     if (!is_keyboard_master()) return split_led_state;
    164 #endif
    165 
    166     host_driver_t *driver = host_get_active_driver();
    167     if (!driver || !driver->keyboard_leds) return 0;
    168 
    169     return (*driver->keyboard_leds)();
    170 }
    171 
    172 led_t host_keyboard_led_state(void) {
    173     return (led_t)host_keyboard_leds();
    174 }
    175 
    176 /* send report */
    177 void host_keyboard_send(report_keyboard_t *report) {
    178     host_driver_t *driver = host_get_active_driver();
    179     if (!driver || !driver->send_keyboard) return;
    180 
    181 #ifdef KEYBOARD_SHARED_EP
    182     report->report_id = REPORT_ID_KEYBOARD;
    183 #endif
    184     (*driver->send_keyboard)(report);
    185 
    186     if (debug_keyboard) {
    187         dprintf("keyboard_report: %02X | ", report->mods);
    188         for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
    189             dprintf("%02X ", report->keys[i]);
    190         }
    191         dprint("\n");
    192     }
    193 }
    194 
    195 void host_nkro_send(report_nkro_t *report) {
    196     host_driver_t *driver = host_get_active_driver();
    197     if (!driver || !driver->send_nkro) return;
    198 
    199     report->report_id = REPORT_ID_NKRO;
    200     (*driver->send_nkro)(report);
    201 
    202     if (debug_keyboard) {
    203         dprintf("nkro_report: %02X | ", report->mods);
    204         for (uint8_t i = 0; i < NKRO_REPORT_BITS; i++) {
    205             dprintf("%02X ", report->bits[i]);
    206         }
    207         dprint("\n");
    208     }
    209 }
    210 
    211 void host_mouse_send(report_mouse_t *report) {
    212     host_driver_t *driver = host_get_active_driver();
    213     if (!driver || !driver->send_mouse) return;
    214 
    215 #ifdef MOUSE_SHARED_EP
    216     report->report_id = REPORT_ID_MOUSE;
    217 #endif
    218 #ifdef MOUSE_EXTENDED_REPORT
    219     // clip and copy to Boot protocol XY
    220     report->boot_x = (report->x > 127) ? 127 : ((report->x < -127) ? -127 : report->x);
    221     report->boot_y = (report->y > 127) ? 127 : ((report->y < -127) ? -127 : report->y);
    222 #endif
    223     (*driver->send_mouse)(report);
    224 }
    225 
    226 void host_system_send(uint16_t usage) {
    227     if (usage == last_system_usage) return;
    228     last_system_usage = usage;
    229 
    230     host_driver_t *driver = host_get_active_driver();
    231     if (!driver || !driver->send_extra) return;
    232 
    233     report_extra_t report = {
    234         .report_id = REPORT_ID_SYSTEM,
    235         .usage     = usage,
    236     };
    237     (*driver->send_extra)(&report);
    238 }
    239 
    240 void host_consumer_send(uint16_t usage) {
    241     if (usage == last_consumer_usage) return;
    242     last_consumer_usage = usage;
    243 
    244     host_driver_t *driver = host_get_active_driver();
    245     if (!driver || !driver->send_extra) return;
    246 
    247     report_extra_t report = {
    248         .report_id = REPORT_ID_CONSUMER,
    249         .usage     = usage,
    250     };
    251     (*driver->send_extra)(&report);
    252 }
    253 
    254 #ifdef JOYSTICK_ENABLE
    255 void host_joystick_send(joystick_t *joystick) {
    256     if (!driver) return;
    257 
    258     report_joystick_t report = {
    259 #    ifdef JOYSTICK_SHARED_EP
    260         .report_id = REPORT_ID_JOYSTICK,
    261 #    endif
    262 #    if JOYSTICK_AXIS_COUNT > 0
    263         .axes =
    264             {
    265                 joystick->axes[0],
    266 
    267 #        if JOYSTICK_AXIS_COUNT >= 2
    268                 joystick->axes[1],
    269 #        endif
    270 #        if JOYSTICK_AXIS_COUNT >= 3
    271                 joystick->axes[2],
    272 #        endif
    273 #        if JOYSTICK_AXIS_COUNT >= 4
    274                 joystick->axes[3],
    275 #        endif
    276 #        if JOYSTICK_AXIS_COUNT >= 5
    277                 joystick->axes[4],
    278 #        endif
    279 #        if JOYSTICK_AXIS_COUNT >= 6
    280                 joystick->axes[5],
    281 #        endif
    282             },
    283 #    endif
    284 
    285 #    ifdef JOYSTICK_HAS_HAT
    286         .hat = joystick->hat,
    287 #    endif
    288 
    289 #    if JOYSTICK_BUTTON_COUNT > 0
    290         .buttons =
    291             {
    292                 joystick->buttons[0],
    293 
    294 #        if JOYSTICK_BUTTON_COUNT > 8
    295                 joystick->buttons[1],
    296 #        endif
    297 #        if JOYSTICK_BUTTON_COUNT > 16
    298                 joystick->buttons[2],
    299 #        endif
    300 #        if JOYSTICK_BUTTON_COUNT > 24
    301                 joystick->buttons[3],
    302 #        endif
    303             },
    304 #    endif
    305     };
    306 
    307     send_joystick(&report);
    308 }
    309 #endif
    310 
    311 __attribute__((weak)) void send_joystick(report_joystick_t *report) {}
    312 
    313 #ifdef DIGITIZER_ENABLE
    314 void host_digitizer_send(digitizer_t *digitizer) {
    315     report_digitizer_t report = {
    316 #    ifdef DIGITIZER_SHARED_EP
    317         .report_id = REPORT_ID_DIGITIZER,
    318 #    endif
    319         .in_range = digitizer->in_range,
    320         .tip      = digitizer->tip,
    321         .barrel   = digitizer->barrel,
    322         .x        = (uint16_t)(digitizer->x * 0x7FFF),
    323         .y        = (uint16_t)(digitizer->y * 0x7FFF),
    324     };
    325 
    326     send_digitizer(&report);
    327 }
    328 #endif
    329 
    330 __attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
    331 
    332 #ifdef PROGRAMMABLE_BUTTON_ENABLE
    333 void host_programmable_button_send(uint32_t data) {
    334     report_programmable_button_t report = {
    335         .report_id = REPORT_ID_PROGRAMMABLE_BUTTON,
    336         .usage     = data,
    337     };
    338 
    339     send_programmable_button(&report);
    340 }
    341 #endif
    342 
    343 __attribute__((weak)) void send_programmable_button(report_programmable_button_t *report) {}
    344 
    345 #ifdef RAW_ENABLE
    346 void host_raw_hid_send(uint8_t *data, uint8_t length) {
    347     host_driver_t *driver = host_get_active_driver();
    348     if (!driver || !driver->send_raw_hid) return;
    349 
    350     (*driver->send_raw_hid)(data, length);
    351 }
    352 #endif
    353 
    354 uint16_t host_last_system_usage(void) {
    355     return last_system_usage;
    356 }
    357 
    358 uint16_t host_last_consumer_usage(void) {
    359     return last_consumer_usage;
    360 }