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 }