├── Case ├── bottom_case.stl ├── keyboard_support.stl ├── readme.md └── upper_case.stl ├── Haredware ├── Gerber │ ├── Gerber_BBQ20_USB_Keyboard.zip │ └── readme.md ├── PCB_BBQ20_USB_Keyboard.pcbdoc ├── SCH_BBQ20_USB_Keyboard.schdoc ├── Schematic_BBQ20_USBKeyboard.pdf └── ibom_BBQ20_USBKeyboard.html ├── LICENSE ├── QMK Source code └── bbq20 │ ├── config.h │ ├── halconf.h │ ├── info.json │ ├── keymaps │ ├── default │ │ ├── config.h │ │ ├── keymap.c │ │ ├── rules.mk │ │ ├── trackpad.c │ │ └── trackpad.h │ ├── test │ │ ├── config.h │ │ ├── keymap.c │ │ ├── rules.mk │ │ ├── trackpad.c │ │ └── trackpad.h │ └── via │ │ ├── config.h │ │ ├── keymap.c │ │ ├── rules.mk │ │ ├── trackpad.c │ │ ├── trackpad.h │ │ └── via.json │ ├── mcuconf.h │ ├── readme.md │ └── rules.mk ├── README.md ├── Tutorial_Refresh_Firmware ├── README.md ├── Refresh_1.0.png ├── Refresh_2.0.png └── Refresh_3.0.png ├── VIA_TUTORIAL ├── readme.md ├── tutorial_1.png ├── tutorial_2.png ├── tutorial_3.png ├── tutorial_4.png ├── tutorial_5.1.png ├── tutorial_5.png ├── tutorial_6.png └── tutorial_7.png └── compiled Firmware └── bbq20_via.uf2 /Case/bottom_case.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Case/bottom_case.stl -------------------------------------------------------------------------------- /Case/keyboard_support.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Case/keyboard_support.stl -------------------------------------------------------------------------------- /Case/readme.md: -------------------------------------------------------------------------------- 1 | # What do you need besides these 3d-printed componente: 2 | 3 | 4 pcs M2X4 nut insert 4 | 5 | 4 pcs M2X10 countersunk head hexagon socket screw 6 | -------------------------------------------------------------------------------- /Case/upper_case.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Case/upper_case.stl -------------------------------------------------------------------------------- /Haredware/Gerber/Gerber_BBQ20_USB_Keyboard.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Haredware/Gerber/Gerber_BBQ20_USB_Keyboard.zip -------------------------------------------------------------------------------- /Haredware/Gerber/readme.md: -------------------------------------------------------------------------------- 1 | PCB thickness: 1mm 2 | -------------------------------------------------------------------------------- /Haredware/Schematic_BBQ20_USBKeyboard.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Haredware/Schematic_BBQ20_USBKeyboard.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Zitao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/config.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Stefan Kerkmann 2 | // SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | #pragma once 5 | 6 | 7 | #define DEBOUNCE 15 //debounce time set to 15ms 8 | 9 | 10 | #define I2C_DRIVER I2CD1 11 | #define I2C1_SCL_PIN GP23 12 | #define I2C1_SDA_PIN GP18 13 | #define I2C1_CLOCK_SPEED 100000 14 | 15 | #define RP2040_BOOTLOADER_DOUBLE_TAP_RESET 16 | #define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP25 17 | #define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U 18 | 19 | #define BACKLIGHT_PWM_DRIVER PWMD4 20 | #define BACKLIGHT_PWM_CHANNEL RP2040_PWM_CHANNEL_B 21 | 22 | #define AUDIO_PIN GP16 23 | #define AUDIO_PWM_DRIVER PWMD0 24 | #define AUDIO_PWM_CHANNEL RP2040_PWM_CHANNEL_A 25 | 26 | #define ADC_PIN GP26 27 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/halconf.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Stefan Kerkmann 2 | // SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | #pragma once 5 | 6 | #define HAL_USE_I2C TRUE 7 | #define HAL_USE_PWM TRUE 8 | #define HAL_USE_ADC TRUE 9 | 10 | 11 | #include_next 12 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "keyboard_name": "BBQ20", 3 | "manufacturer": "dzt", 4 | "maintainer": "dzt", 5 | "bootloader": "rp2040", 6 | "diode_direction": "COL2ROW", 7 | "features": { 8 | "bootmagic": false, 9 | "mousekey": true, 10 | "extrakey": true, 11 | "console": false, 12 | "command": false, 13 | "nkro": false, 14 | "rgblight": false, 15 | "audio": false 16 | }, 17 | "backlight": { 18 | "levels": 1, 19 | "pin": "GP25" 20 | }, 21 | "matrix_pins": { 22 | "cols": ["GP8", "GP9", "GP14", "GP13", "GP12", "GP11", "GP19"], 23 | "rows": ["GP7", "GP6", "GP5", "GP4", "GP3", "GP2", "GP1", "GP20"] 24 | }, 25 | "processor": "RP2040", 26 | "usb": { 27 | "device_version": "1.0.0", 28 | "pid": "0x0003", 29 | "vid": "0x4243" 30 | }, 31 | "split": { 32 | "enabled": false 33 | }, 34 | "layouts": { 35 | "LAYOUT": { 36 | "layout": [ 37 | { "matrix": [3, 0], "x": 0, "y": 0 }, 38 | { "matrix": [1, 0], "x": 1, "y": 0 }, 39 | 40 | { "matrix": [2, 0], "x": 0, "y": 1 }, 41 | { "matrix": [4, 0], "x": 1, "y": 1 }, 42 | { "matrix": [0, 0], "x": 2, "y": 1 }, 43 | { "matrix": [5, 0], "x": 3, "y": 1 }, 44 | { "matrix": [7, 6], "x": 4, "y": 1 }, 45 | 46 | { "matrix": [1, 1], "x": 0, "y": 2 }, 47 | { "matrix": [0, 1], "x": 1, "y": 2 }, 48 | { "matrix": [1, 3], "x": 2, "y": 2 }, 49 | { "matrix": [1, 2], "x": 3, "y": 2 }, 50 | { "matrix": [4, 2], "x": 4, "y": 2 }, 51 | { "matrix": [4, 5], "x": 5, "y": 2 }, 52 | { "matrix": [1, 5], "x": 6, "y": 2 }, 53 | { "matrix": [4, 4], "x": 7, "y": 2 }, 54 | { "matrix": [1, 4], "x": 8, "y": 2 }, 55 | { "matrix": [6, 3], "x": 9, "y": 2 }, 56 | 57 | { "matrix": [6, 1], "x": 0, "y": 3 }, 58 | { "matrix": [0, 3], "x": 1, "y": 3 }, 59 | { "matrix": [4, 3], "x": 2, "y": 3 }, 60 | { "matrix": [2, 2], "x": 3, "y": 3 }, 61 | { "matrix": [0, 2], "x": 4, "y": 3 }, 62 | { "matrix": [0, 5], "x": 5, "y": 3 }, 63 | { "matrix": [2, 5], "x": 6, "y": 3 }, 64 | { "matrix": [2, 4], "x": 7, "y": 3 }, 65 | { "matrix": [0, 4], "x": 8, "y": 3 }, 66 | { "matrix": [6, 4], "x": 9, "y": 3 }, 67 | 68 | { "matrix": [5, 1], "x": 0, "y": 4 }, 69 | { "matrix": [3, 3], "x": 1, "y": 4 }, 70 | { "matrix": [5, 3], "x": 2, "y": 4 }, 71 | { "matrix": [3, 2], "x": 3, "y": 4 }, 72 | { "matrix": [5, 2], "x": 4, "y": 4 }, 73 | { "matrix": [5, 5], "x": 5, "y": 4 }, 74 | { "matrix": [3, 5], "x": 6, "y": 4 }, 75 | { "matrix": [3, 4], "x": 7, "y": 4 }, 76 | { "matrix": [5, 4], "x": 8, "y": 4 }, 77 | { "matrix": [6, 5], "x": 9, "y": 4 }, 78 | 79 | { "matrix": [2, 3], "x": 0, "y": 5 }, 80 | { "matrix": [2, 1], "x": 1, "y": 5 }, 81 | { "matrix": [3, 1], "x": 2, "y": 5 }, 82 | { "matrix": [4, 1], "x": 3, "y": 5 }, 83 | { "matrix": [6, 2], "x": 4, "y": 5 }, 84 | 85 | ] 86 | } 87 | } 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/default/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define BACKLIGHT_BREATHING 4 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/default/keymap.c: -------------------------------------------------------------------------------- 1 | #include QMK_KEYBOARD_H 2 | 3 | #define pin_BLK_KBD GP25 4 | #define pin_BLK_TP GP0 5 | 6 | enum layer_number { 7 | _QWERTY = 0, 8 | _LOWER = 1, 9 | _RAISE = 2, 10 | }; 11 | 12 | #define LOWER MO(_LOWER) 13 | #define RAISE MO(_RAISE) 14 | 15 | 16 | extern bool isScrollMode; 17 | extern bool isBoostMode; 18 | extern bool isSlowMode; 19 | 20 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 21 | 22 | [_QWERTY] = LAYOUT( 23 | 24 | KC_BTN1, KC_BTN2, 25 | KC_CAPS, KC_WSCH, KC_BTN1, KC_ESC, KC_WHOM, 26 | KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, 27 | KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_BSPC, 28 | KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_DLR, KC_ENT, 29 | KC_LCTL, KC_LALT, KC_SPC, LOWER, RAISE 30 | ), 31 | 32 | [_LOWER] = LAYOUT( 33 | 34 | KC_PGUP, KC_PGDN, 35 | KC_TAB, KC_CALC, KC_BTN2, KC_BRIU, KC_BRID, 36 | KC_HASH, KC_1, KC_2, KC_3, KC_LPRN, KC_RPRN, KC_UNDS, KC_MINS, KC_PLUS, KC_AT, 37 | KC_ASTR, KC_4, KC_5, KC_6, KC_SLSH, KC_COLN, KC_SCLN, KC_QUOT, KC_DQT, KC_DEL, 38 | KC_LSFT, KC_7, KC_8, KC_9, KC_QUES, KC_EXLM, KC_COMM, KC_DOT, KC_MUTE, KC_ENT, 39 | KC_LGUI, KC_0, KC_END, LOWER, RAISE 40 | ), 41 | 42 | [_RAISE] = LAYOUT( 43 | 44 | KC_VOLU, KC_VOLD, 45 | KC_F1, KC_F5, KC_BTN3, KC_F12, KC_SLEP, 46 | KC_NO, KC_UP, KC_NO, KC_NO, KC_LBRC, KC_RBRC, KC_LABK, KC_RABK, KC_PIPE, KC_EQL, 47 | KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_BSLS, KC_AMPR, KC_LCBR, KC_RCBR, KC_CIRC, KC_NO, 48 | KC_LSFT, KC_NO, KC_NO, KC_NO, KC_PERC, BL_TOGG, KC_GRV, KC_NO, KC_NO, KC_NO, 49 | KC_NO, KC_TILD, KC_NO, LOWER, RAISE 50 | ) 51 | 52 | 53 | }; 54 | 55 | void board_init(void){ 56 | setPinOutput(pin_BLK_KBD); 57 | setPinOutput(pin_BLK_TP); 58 | writePinHigh(pin_BLK_KBD); 59 | writePinLow(pin_BLK_TP); 60 | } 61 | 62 | bool led_update_user(led_t led_state) { 63 | if (led_state.caps_lock) { //if caps lock is on 64 | writePinHigh(pin_BLK_TP); 65 | isScrollMode = true; 66 | } else { //if caps lock is off 67 | writePinLow(pin_BLK_TP); 68 | isScrollMode = false; 69 | } 70 | return true; 71 | } 72 | 73 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { 74 | switch (keycode) { 75 | /*case KC_LSFT: 76 | if (record->event.pressed) { 77 | isScrollMode = true; 78 | tap_code(KC_LSFT); 79 | } 80 | else { 81 | isScrollMode = false; 82 | } 83 | return false; */ 84 | case KC_LCTL: 85 | if (record->event.pressed) { 86 | isBoostMode = true; 87 | register_code(KC_LCTL); 88 | } 89 | else { 90 | isBoostMode = false; 91 | unregister_code(KC_LCTL); 92 | } 93 | return false; 94 | case KC_LALT: 95 | if (record->event.pressed) { 96 | isSlowMode = true; 97 | register_code(KC_LALT); 98 | } 99 | else { 100 | isSlowMode = false; 101 | unregister_code(KC_LALT); 102 | } 103 | return false; 104 | } 105 | return true; 106 | } 107 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/default/rules.mk: -------------------------------------------------------------------------------- 1 | BACKLIGHT_ENABLE = yes 2 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/default/trackpad.c: -------------------------------------------------------------------------------- 1 | #include "trackpad.h" 2 | 3 | 4 | #define Trackpad_ADDR 0x3B 5 | 6 | 7 | #define REG_PID 0x00 8 | #define REG_REV 0x01 9 | #define REG_MOTION 0x02 10 | 11 | #define REG_DELTA_X 0x03 12 | #define REG_DELTA_Y 0x04 13 | 14 | #define pin_TP_SHUTDOWN GP24 15 | #define pin_TP_MOTION GP22 16 | #define pin_TP_RESET GP16 17 | #define pin_BLK_KBD GP25 18 | #define pin_BLK_TP GP0 19 | 20 | #define BIT_MOTION_MOT (1 << 7) 21 | 22 | #define trackpad_timeout 100 23 | 24 | 25 | void pointing_device_init(void) { 26 | i2c_init(); 27 | wait_ms(10); 28 | 29 | setPinOutput(pin_TP_SHUTDOWN); 30 | writePinLow(pin_TP_SHUTDOWN); 31 | 32 | setPinInputHigh(pin_TP_MOTION); 33 | 34 | setPinOutput(pin_TP_RESET); 35 | writePinLow(pin_TP_RESET); 36 | wait_ms(100); 37 | writePinHigh(pin_TP_RESET); 38 | } 39 | 40 | 41 | uint8_t read_register8(uint8_t reg) { 42 | uint8_t val; 43 | i2c_writeReg(TRACKPAD_WRITE, reg, NULL, 0, trackpad_timeout); 44 | i2c_readReg(TRACKPAD_READ, reg, &val, 1, trackpad_timeout); 45 | return val; 46 | } 47 | 48 | bool pointing_device_task(void) { 49 | const uint8_t ifmotion = read_register8(REG_MOTION); 50 | 51 | if ( ifmotion & BIT_MOTION_MOT) { 52 | int8_t y = read_register8(REG_DELTA_X); 53 | int8_t x = read_register8(REG_DELTA_Y); 54 | 55 | 56 | x = ((x < 127) ? x : (x - 256)) * 2.0; 57 | y = ((y < 127) ? y : (y - 256)) * 2.0; 58 | 59 | report_mouse_t currentReport = pointing_device_get_report(); 60 | currentReport.x= x; 61 | currentReport.y= y; 62 | pointing_device_set_report(currentReport); 63 | } 64 | return pointing_device_send(); 65 | } 66 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/default/trackpad.h: -------------------------------------------------------------------------------- 1 | #include "quantum.h" 2 | #include "pointing_device.h" 3 | #include "report.h" 4 | #include "stdio.h" 5 | #include "i2c_master.h" 6 | 7 | #ifndef TRACKPAD_ADDRESS 8 | # define TRACKPAD_ADDRESS 0x3B 9 | #endif 10 | #define TRACKPAD_WRITE ((TRACKPAD_ADDRESS << 1) ) 11 | #define TRACKPAD_READ ((TRACKPAD_ADDRESS << 1) ) 12 | 13 | uint8_t read_register8(uint8_t reg); 14 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/test/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/test/keymap.c: -------------------------------------------------------------------------------- 1 | #include QMK_KEYBOARD_H 2 | 3 | #define pin_BLK_KBD GP25 4 | #define pin_BLK_TP GP0 5 | 6 | enum layer_number { 7 | _QWERTY = 0, 8 | _LOWER = 1, 9 | _RAISE = 2, 10 | }; 11 | 12 | #define LOWER MO(_LOWER) 13 | #define RAISE MO(_RAISE) 14 | 15 | 16 | extern bool isScrollMode; 17 | extern bool isBoostMode; 18 | extern bool isSlowMode; 19 | 20 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 21 | 22 | [_QWERTY] = LAYOUT( 23 | 24 | KC_1, KC_2, 25 | KC_CAPS, KC_4, KC_BTN1, KC_5, KC_6, 26 | KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, 27 | KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_BSPC, 28 | KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_DLR, KC_ENT, 29 | KC_LCTL, KC_LALT, KC_SPC, KC_7, KC_8 30 | ) 31 | 32 | }; 33 | 34 | void board_init(void){ 35 | setPinOutput(pin_BLK_KBD); 36 | setPinOutput(pin_BLK_TP); 37 | writePinHigh(pin_BLK_KBD); 38 | writePinLow(pin_BLK_TP); 39 | } 40 | 41 | bool led_update_user(led_t led_state) { 42 | if (led_state.caps_lock) { //if caps lock is on 43 | writePinHigh(pin_BLK_TP); 44 | isScrollMode = true; 45 | } else { //if caps lock is off 46 | writePinLow(pin_BLK_TP); 47 | isScrollMode = false; 48 | } 49 | return true; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/test/rules.mk: -------------------------------------------------------------------------------- 1 | VIA_ENABLE = yes 2 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/test/trackpad.c: -------------------------------------------------------------------------------- 1 | #include "trackpad.h" 2 | 3 | 4 | #define Trackpad_ADDR 0x3B 5 | 6 | 7 | #define REG_PID 0x00 8 | #define REG_REV 0x01 9 | #define REG_MOTION 0x02 10 | #define REG_DELTA_X 0x03 11 | #define REG_DELTA_Y 0x04 12 | #define REG_DELTA_XY_H 0x05 13 | #define REG_CONFIG 0x11 14 | #define REG_OBSERV 0x2E 15 | #define REG_MBURST 0x42 16 | 17 | #define pin_TP_SHUTDOWN GP24 18 | #define pin_TP_MOTION GP22 19 | #define pin_TP_RESET GP16 20 | #define pin_BLK_KBD GP25 21 | #define pin_BLK_TP GP0 22 | 23 | #define BIT_MOTION_MOT (1 << 7) 24 | #define BIT_MOTION_OVF (1 << 4) 25 | 26 | 27 | #define trackpad_timeout 100 28 | #define SCROLL_SPEED_DIVIDER 6 29 | #define Boost_SPEED_Multiplyer 2 30 | #define Solw_SPEED_DIVIDER 2 31 | 32 | bool isScrollMode = false; 33 | bool isBoostMode = false; 34 | bool isSlowMode = false; 35 | 36 | void pointing_device_init(void) { 37 | i2c_init(); 38 | wait_ms(10); 39 | 40 | setPinOutput(pin_TP_SHUTDOWN); 41 | writePinLow(pin_TP_SHUTDOWN); 42 | 43 | setPinInputHigh(pin_TP_MOTION); 44 | 45 | setPinOutput(pin_TP_RESET); 46 | writePinLow(pin_TP_RESET); 47 | wait_ms(100); 48 | writePinHigh(pin_TP_RESET); 49 | } 50 | 51 | 52 | uint8_t read_register8(uint8_t reg) { 53 | uint8_t val; 54 | i2c_writeReg(TRACKPAD_WRITE, reg, NULL, 0, trackpad_timeout); 55 | i2c_readReg(TRACKPAD_READ, reg, &val, 1, trackpad_timeout); 56 | return val; 57 | } 58 | 59 | bool pointing_device_task(void) { 60 | const uint8_t ifmotion = read_register8(REG_MOTION); 61 | 62 | if ( ifmotion & BIT_MOTION_MOT) { 63 | int8_t y = read_register8(REG_DELTA_X); 64 | int8_t x = read_register8(REG_DELTA_Y); 65 | report_mouse_t currentReport = pointing_device_get_report(); 66 | if (isScrollMode) 67 | { 68 | currentReport.h = 1 * x/SCROLL_SPEED_DIVIDER; 69 | currentReport.v = -1 * y/SCROLL_SPEED_DIVIDER; 70 | } 71 | 72 | else if(isBoostMode) 73 | 74 | { 75 | x = ((x < 127) ? x : (x - 256)) * 1.5 * Boost_SPEED_Multiplyer; 76 | y = ((y < 127) ? y : (y - 256)) * 1.5 * Boost_SPEED_Multiplyer; 77 | currentReport.x= x; 78 | currentReport.y= y; 79 | } 80 | 81 | else if(isSlowMode) 82 | 83 | { 84 | x = ((x < 127) ? x : (x - 256)) * 1.5 /Solw_SPEED_DIVIDER; 85 | y = ((y < 127) ? y : (y - 256)) * 1.5 /Solw_SPEED_DIVIDER; 86 | currentReport.x= x; 87 | currentReport.y= y; 88 | } 89 | else 90 | { 91 | x = ((x < 127) ? x : (x - 256)) * 1.5; 92 | y = ((y < 127) ? y : (y - 256)) * 1.5; 93 | currentReport.x= x; 94 | currentReport.y= y; 95 | } 96 | pointing_device_set_report(currentReport); 97 | } 98 | return pointing_device_send(); 99 | } 100 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/test/trackpad.h: -------------------------------------------------------------------------------- 1 | #include "quantum.h" 2 | #include "pointing_device.h" 3 | #include "report.h" 4 | #include "stdio.h" 5 | #include "i2c_master.h" 6 | 7 | #ifndef TRACKPAD_ADDRESS 8 | # define TRACKPAD_ADDRESS 0x3B 9 | #endif 10 | #define TRACKPAD_WRITE ((TRACKPAD_ADDRESS << 1) ) 11 | #define TRACKPAD_READ ((TRACKPAD_ADDRESS << 1) ) 12 | 13 | uint8_t read_register8(uint8_t reg); 14 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/via/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define BACKLIGHT_BREATHING 4 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/via/keymap.c: -------------------------------------------------------------------------------- 1 | #include QMK_KEYBOARD_H 2 | 3 | #define pin_BLK_KBD GP25 4 | 5 | enum layer_number { 6 | _QWERTY = 0, 7 | _LOWER = 1, 8 | _RAISE = 2, 9 | }; 10 | 11 | #define LOWER MO(_LOWER) 12 | #define RAISE MO(_RAISE) 13 | 14 | 15 | extern bool isScrollMode; 16 | extern bool isBoostMode; 17 | extern bool isSlowMode; 18 | 19 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 20 | 21 | [_QWERTY] = LAYOUT( 22 | 23 | KC_BTN1, KC_BTN2, 24 | KC_CAPS, KC_WSCH, KC_BTN1, KC_ESC, KC_WHOM, 25 | KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, 26 | KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_BSPC, 27 | KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_DLR, KC_ENT, 28 | KC_LCTL, KC_LALT, KC_SPC, LOWER, RAISE 29 | ), 30 | 31 | [_LOWER] = LAYOUT( 32 | 33 | KC_PGUP, KC_PGDN, 34 | KC_TAB, KC_CALC, KC_BTN2, KC_BRIU, KC_BRID, 35 | KC_HASH, KC_1, KC_2, KC_3, KC_LPRN, KC_RPRN, KC_UNDS, KC_MINS, KC_PLUS, KC_AT, 36 | KC_ASTR, KC_4, KC_5, KC_6, KC_SLSH, KC_COLN, KC_SCLN, KC_QUOT, KC_DQT, KC_DEL, 37 | KC_LSFT, KC_7, KC_8, KC_9, KC_QUES, KC_EXLM, KC_COMM, KC_DOT, KC_MUTE, KC_ENT, 38 | KC_LGUI, KC_0, KC_END, LOWER, RAISE 39 | ), 40 | 41 | [_RAISE] = LAYOUT( 42 | KC_VOLU, KC_VOLD, 43 | KC_F1, KC_F5, KC_BTN3, KC_F12, KC_SLEP, 44 | KC_NO, KC_UP, KC_NO, KC_NO, KC_LBRC, KC_RBRC, KC_LABK, KC_RABK, KC_PIPE, KC_EQL, 45 | KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_BSLS, KC_AMPR, KC_LCBR, KC_RCBR, KC_CIRC, KC_NO, 46 | KC_LSFT, KC_NO, KC_NO, KC_NO, KC_PERC, BL_TOGG, KC_GRV, KC_NO, KC_NO, KC_NO, 47 | KC_NO, KC_TILD, KC_NO, LOWER, RAISE 48 | ) 49 | 50 | 51 | }; 52 | 53 | void board_init(void){ 54 | setPinOutput(pin_BLK_KBD); 55 | writePinHigh(pin_BLK_KBD); 56 | } 57 | 58 | bool led_update_user(led_t led_state) { 59 | if (led_state.caps_lock) { //if caps lock is on 60 | isScrollMode = true; 61 | } else { //if caps lock is off 62 | isScrollMode = false; 63 | } 64 | return true; 65 | } 66 | 67 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { 68 | switch (keycode) { 69 | /*case KC_LSFT: 70 | if (record->event.pressed) { 71 | isScrollMode = true; 72 | tap_code(KC_LSFT); 73 | } 74 | else { 75 | isScrollMode = false; 76 | } 77 | return false; */ 78 | case KC_LCTL: 79 | if (record->event.pressed) { 80 | isBoostMode = true; 81 | register_code(KC_LCTL); 82 | } 83 | else { 84 | isBoostMode = false; 85 | unregister_code(KC_LCTL); 86 | } 87 | return false; 88 | case KC_LALT: 89 | if (record->event.pressed) { 90 | isSlowMode = true; 91 | register_code(KC_LALT); 92 | } 93 | else { 94 | isSlowMode = false; 95 | unregister_code(KC_LALT); 96 | } 97 | return false; 98 | } 99 | return true; 100 | } 101 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/via/rules.mk: -------------------------------------------------------------------------------- 1 | VIA_ENABLE = yes 2 | BACKLIGHT_ENABLE = yes 3 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/via/trackpad.c: -------------------------------------------------------------------------------- 1 | #include "trackpad.h" 2 | 3 | 4 | #define Trackpad_ADDR 0x3B 5 | 6 | 7 | #define REG_PID 0x00 8 | #define REG_REV 0x01 9 | #define REG_MOTION 0x02 10 | #define REG_DELTA_X 0x03 11 | #define REG_DELTA_Y 0x04 12 | #define REG_DELTA_XY_H 0x05 13 | #define REG_CONFIG 0x11 14 | #define REG_OBSERV 0x2E 15 | #define REG_MBURST 0x42 16 | 17 | #define pin_TP_SHUTDOWN GP24 18 | #define pin_TP_MOTION GP22 19 | #define pin_TP_RESET GP16 20 | #define pin_BLK_KBD GP25 21 | #define pin_BLK_TP GP0 22 | 23 | #define BIT_MOTION_MOT (1 << 7) 24 | #define BIT_MOTION_OVF (1 << 4) 25 | 26 | 27 | #define trackpad_timeout 100 28 | #define SCROLL_SPEED_DIVIDER 6 29 | #define Boost_SPEED_Multiplyer 2 30 | #define Solw_SPEED_DIVIDER 2 31 | 32 | bool isScrollMode = false; 33 | bool isBoostMode = false; 34 | bool isSlowMode = false; 35 | 36 | void pointing_device_init(void) { 37 | i2c_init(); 38 | wait_ms(10); 39 | 40 | setPinOutput(pin_TP_SHUTDOWN); 41 | writePinLow(pin_TP_SHUTDOWN); 42 | 43 | setPinInputHigh(pin_TP_MOTION); 44 | 45 | setPinOutput(pin_TP_RESET); 46 | writePinLow(pin_TP_RESET); 47 | wait_ms(100); 48 | writePinHigh(pin_TP_RESET); 49 | } 50 | 51 | 52 | uint8_t read_register8(uint8_t reg) { 53 | uint8_t val; 54 | i2c_writeReg(TRACKPAD_WRITE, reg, NULL, 0, trackpad_timeout); 55 | i2c_readReg(TRACKPAD_READ, reg, &val, 1, trackpad_timeout); 56 | return val; 57 | } 58 | 59 | bool pointing_device_task(void) { 60 | const uint8_t ifmotion = read_register8(REG_MOTION); 61 | 62 | if ( ifmotion & BIT_MOTION_MOT) { 63 | int8_t x = read_register8(REG_DELTA_X); 64 | int8_t y = read_register8(REG_DELTA_Y); 65 | report_mouse_t currentReport = pointing_device_get_report(); 66 | if (isScrollMode) 67 | { 68 | currentReport.h = 1 * x/SCROLL_SPEED_DIVIDER; 69 | currentReport.v = -1 *y/SCROLL_SPEED_DIVIDER;; 70 | } 71 | 72 | else if(isBoostMode) 73 | 74 | { 75 | x = ((x < 127) ? x : (x - 256)) * -1.5 * Boost_SPEED_Multiplyer; 76 | y = ((y < 127) ? y : (y - 256)) * 1.5 * Boost_SPEED_Multiplyer; 77 | currentReport.x= x; 78 | currentReport.y= y; 79 | } 80 | 81 | else if(isSlowMode) 82 | 83 | { 84 | x = ((x < 127) ? x : (x - 256)) * -1.5 /Solw_SPEED_DIVIDER; 85 | y = ((y < 127) ? y : (y - 256)) * 1.5 /Solw_SPEED_DIVIDER; 86 | currentReport.x= x; 87 | currentReport.y= y; 88 | } 89 | else 90 | { 91 | x = ((x < 127) ? x : (x - 256)) * -1.5; 92 | y = ((y < 127) ? y : (y - 256)) * 1.5; 93 | currentReport.x= x; 94 | currentReport.y= y; 95 | } 96 | pointing_device_set_report(currentReport); 97 | } 98 | return pointing_device_send(); 99 | } 100 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/via/trackpad.h: -------------------------------------------------------------------------------- 1 | #include "quantum.h" 2 | #include "pointing_device.h" 3 | #include "report.h" 4 | #include "stdio.h" 5 | #include "i2c_master.h" 6 | 7 | #ifndef TRACKPAD_ADDRESS 8 | # define TRACKPAD_ADDRESS 0x3B 9 | #endif 10 | #define TRACKPAD_WRITE ((TRACKPAD_ADDRESS << 1) ) 11 | #define TRACKPAD_READ ((TRACKPAD_ADDRESS << 1) ) 12 | 13 | uint8_t read_register8(uint8_t reg); 14 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/keymaps/via/via.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BBQ20", 3 | "vendorId":"0x4243", 4 | "productId":"0x0003", 5 | "matrix":{ 6 | "rows":8, 7 | "cols":7 8 | }, 9 | "layouts":{ 10 | "keymap":[ 11 | [ 12 | {"x":1,"w":1.5},"3,0", 13 | {"x":5,"w":1.5},"1,0" 14 | ], 15 | [ 16 | {"w":2},"2,0", 17 | {"w":2},"4,0", 18 | {"x":0.5},"0,0", 19 | {"x":0.5,"w":2},"5,0", 20 | {"w":2},"7,6" 21 | ], 22 | [ 23 | "1,1", 24 | "0,1", 25 | "1,3", 26 | "1,2", 27 | "4,2", 28 | "4,5", 29 | "1,5", 30 | "4,4", 31 | "1,4", 32 | "6,3" 33 | 34 | ], 35 | [ 36 | "6,1", 37 | "0,3", 38 | "4,3", 39 | "2,2", 40 | "0,2", 41 | "0,5", 42 | "2,5", 43 | "2,4", 44 | "0,4", 45 | "6,4" 46 | 47 | ], 48 | [ 49 | "5,1", 50 | "3,3", 51 | "5,3", 52 | "3,2", 53 | "5,2", 54 | "5,5", 55 | "3,5", 56 | "3,4", 57 | "5,4", 58 | "6,5" 59 | 60 | ], 61 | [ 62 | {"x":1,"w":1.25},"2,3", 63 | {"w":1.25},"2,1", 64 | {"w":3},"3,1", 65 | {"w":1.25},"4,1", 66 | {"w":1.25},"6,2" 67 | 68 | ] 69 | ] 70 | 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/mcuconf.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Stefan Kerkmann 2 | // SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | #pragma once 5 | 6 | #include_next 7 | 8 | #undef RP_SIO_USE_UART0 9 | #define RP_SIO_USE_UART0 FALSE 10 | #undef RP_SIO_USE_UART1 11 | #define RP_SIO_USE_UART1 FALSE 12 | 13 | 14 | #undef RP_PWM_USE_PWM0 15 | #define RP_PWM_USE_PWM0 TRUE 16 | 17 | #undef RP_PWM_USE_PWM4 18 | #define RP_PWM_USE_PWM4 TRUE 19 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/readme.md: -------------------------------------------------------------------------------- 1 | # bbq20 USB Keyboard 2 | 3 | ![bbq20_USB_Keyboard](https://i.imgur.com/Ig00oQE.jpeg) 4 | 5 | bbq20-USB-Keyboard is a mini keyboard, which based on the keyboard on blackberry q20 and with the processor RP2040 resulted 6 | 7 | * Keyboard Maintainer: [ZitaoTech](https://github.com/ZitaoTech) 8 | * Hardware Supported: RP2040 9 | * Hardware Availability: [tindie](https://www.tindie.com/products/zitaotech/blackberry-bbq20-usb-keyboard-with-trackpad/) 10 | 11 | 12 | See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). 13 | 14 | 15 | ## Bootloader 16 | 17 | How to enter the Bootloader: 18 | 19 | * **boot button**: press the right2 key when the USB connection is made to a computer. The keyboard will remain in this mode until it power cycles (happens automatically after uploading a .uf2 firmware file) or the RESET button is pressed. The board will appear as a USB mass storage device under the name RPI-RP2. 20 | 21 | -------------------------------------------------------------------------------- /QMK Source code/bbq20/rules.mk: -------------------------------------------------------------------------------- 1 | OLED_ENABLE = yes # start using i2c 2 | POINTING_DEVICE_ENABLE = yes # Mouse keys 3 | POINTING_DEVICE_DRIVER = custom # customer driver for trackpad on the BB9900 keyboard 4 | 5 | 6 | OPT_DEFS += -DHAL_USE_I2C=TRUE 7 | # Add support for the BB9900 trackpad 8 | SRC += trackpad.c -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BBQ20-USB-KBD 2 | ## About this Keyboard 3 | 4 | This mini Keyboard is using the original Blackberry Q20 keyboard with Trackpad and powered by the Raspberry Pi Rp2040 Microcontroller and operates under QMK Firmware, which transforms itself into a USB HID Keyboard and Mouse combo. The device has a USB Type-C female port, allowing it to connect to a smartphone using a USB-C to USB-C cable or to a computer using a USB-A to USB-C cable. This Keyboard is universally compatible across all platforms, including Android and iOS smartphones, Windows, Linux, and macOS computers, as well as various tablets. 5 | # [How to customoze your own keymap:](https://github.com/ZitaoTech/BBQ20-USB-keyboard/tree/main/VIA_TUTORIAL) 6 | 7 | # [How to refresh the firmware:](https://github.com/ZitaoTech/BBQ20-USB-keyboard/tree/main/Tutorial_Refresh_Firmware) 8 | 9 | ![Summary](https://i.imgur.com/Ig00oQE.jpeg) 10 | 11 | If you have any questions, you are welcome to join the [Discord community](https://discord.gg/PybEghmf8F) 12 | 13 | Hareware availability: [tindie store](https://www.tindie.com/products/zitaotech/blackberry-bbq20-usb-keyboard-with-trackpad/) 14 | 15 | ## Features 16 | ### Hardware: 17 | 18 | The keyboard has not only keys but also includes an optical navigation trackpad, which located in the upper-middle area. This optical navigation sensor can function as a mouse or a scroll wheel. The whole keyboard has backlighting. In the default firmware, when the Caps Lock is enabled, the backlight for the optical navigation trackpad will be turned on; when Caps Lock is disabled, the backlight for the optical navigation will be turned off. Additionally, the keyboard backlight can be manually toggled on or off. On the side of the USB Type-C female port, there are two additional side buttons that provide extra key functions and enhance ergonomics. 19 | 20 | default keymapping: 21 | ![default_keymapping](https://cdn.tindiemedia.com/images/resize/UL2bwOICdenr7ki7yas0wzS584s=/p/fit-in/994x664/filters:fill(fff)/i/762834/products/2023-10-08T19%3A07%3A00.075Z-6.png?1696766871) 22 | 23 | ### customize your own keymap: 24 | 25 | Due to the limited number of keys on the keyboard, the default firmware has configured the two keys in the bottom right corner to serve as the second and third layer activation keys. Since everyone has its varying preferences and interpretations of their keyboard layouts, it may be necessary to customize the key layout and keycode for this keyboard. The default firmware supports online key remapping through [VIA](https://www.caniusevia.com). 26 | ![VIA](https://i.imgur.com/thJOKUr.png) 27 | 28 | ## Default Layout and Layers 29 | Layout 0: 30 | 31 | ![Layout0](https://i.imgur.com/0Pvp2nG.png) 32 | 33 | Layout Lower: 34 | 35 | ![Layout Lower](https://i.imgur.com/ZXJmXin.png) 36 | 37 | Layout Raise: 38 | 39 | ![Layout Raise](https://i.imgur.com/PozduM0.png) 40 | -------------------------------------------------------------------------------- /Tutorial_Refresh_Firmware/README.md: -------------------------------------------------------------------------------- 1 | 2 | # If you have customized your own keymapping but found it not useful and want to start all over again. You can try to refresh the firmware so that the keymapping will be set as default. 3 | 4 | Here are the steps for the refresh. 5 | 6 | Step1: Hold the “endcall” button and connect the keyboard to your windows PC, the chip will be entering the bootloader mode. 7 | ![Refresh_1 0](https://github.com/ZitaoTech/BBQ20-USB-keyboard/assets/145678024/dd6298e7-7a28-4e51-bebe-97d92b25e304) 8 | 9 | You will see a storage device found by the computer like this: 10 | ![Refresh_3 0](https://github.com/ZitaoTech/BBQ20-USB-keyboard/assets/145678024/7ac3ea7c-4d87-4766-a16e-0a60aa1ce743) 11 | 12 | Then drage the firmware (which you can download on my github page) into the storage disk. 13 | ![Refresh_2 0](https://github.com/ZitaoTech/BBQ20-USB-keyboard/assets/145678024/f626e070-e116-46ea-afd2-f310bce0ffc9) 14 | 15 | Then the firmware is already burnt into the chip. The keymapping will be set as default. 16 | 17 | -------------------------------------------------------------------------------- /Tutorial_Refresh_Firmware/Refresh_1.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Tutorial_Refresh_Firmware/Refresh_1.0.png -------------------------------------------------------------------------------- /Tutorial_Refresh_Firmware/Refresh_2.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Tutorial_Refresh_Firmware/Refresh_2.0.png -------------------------------------------------------------------------------- /Tutorial_Refresh_Firmware/Refresh_3.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/Tutorial_Refresh_Firmware/Refresh_3.0.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Recommend: Use VIA on a Windows PC and Chrome Browser 3 | 4 | Step1:open the [VIA](https://usevia.app/) web page. 5 | 6 | Step2: ![tutorial_1](https://github.com/ZitaoTech/BB9900-USB-keyboard/assets/145678024/56349ade-c6d3-4cee-9f0e-1e9e6e296b2e) Go to the Setting page of VIA. 7 | 8 | Step3: ![tutorial_2](https://github.com/ZitaoTech/BB9900-USB-keyboard/assets/145678024/05ee7332-b1ef-4ed7-b03d-2e7c029a98ca) enable Showing design Tab. 9 | 10 | And you will see the tab turned into this: ![tutorial_3](https://github.com/ZitaoTech/BB9900-USB-keyboard/assets/145678024/9fe78ab9-5e6a-455a-9df8-b55661c221c0) 11 | 12 | Step4: ![tutorial_4](https://github.com/ZitaoTech/BB9900-USB-keyboard/assets/145678024/87d7116c-b917-4f3e-af7b-a28a8b729ae9) Go to this page and upload the json file, 13 | 14 | the json file is in my github page.![tutorial_5 1](https://github.com/ZitaoTech/BBQ20-USB-keyboard/assets/145678024/4a9818f0-725b-40b9-94d1-d127065095bd) 15 | 16 | 17 | 18 | Step5: There will be a window showing that the via want to authorize to your device. Press the blue button: ![tutorial_6](https://github.com/ZitaoTech/BBQ20-USB-keyboard/assets/145678024/d71055ad-36bb-4847-bef2-f20febdf8178) 19 | 20 | 21 | Step6: Go to this page and you can see the keymapping and you can customize your kemap.![tutorial_7](https://github.com/ZitaoTech/BBQ20-USB-keyboard/assets/145678024/892de643-b2df-4d69-954e-7cde54137582) 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_1.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_2.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_3.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_4.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_5.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_5.1.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_5.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_6.png -------------------------------------------------------------------------------- /VIA_TUTORIAL/tutorial_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/VIA_TUTORIAL/tutorial_7.png -------------------------------------------------------------------------------- /compiled Firmware/bbq20_via.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZitaoTech/BBQ20-USB-keyboard/079ac6ae73dafbef7f603a0811b2f835366effe9/compiled Firmware/bbq20_via.uf2 --------------------------------------------------------------------------------